furia_cfg_seq.c (427014B)
1 /* 2 * 3 * 4 * 5 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 6 * 7 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 8 */ 9 10 /* 11 * Includes 12 */ 13 #include <phymod/phymod.h> 14 #include <phymod/phymod_system.h> 15 #include <phymod/phymod_diagnostics.h> 16 /* Implementation of the interface defined here */ 17 #include "falcon_furia_src/falcon_furia_internal.h" 18 #include "falcon_furia_src/falcon_furia_functions.h" 19 #include "falcon_furia_src/falcon_furia_enum.h" 20 #include "falcon_furia_src/public/falcon_furia_fields_public.h" 21 #include "furia_cfg_seq.h" 22 #include "furia_reg_access.h" 23 #include "furia_address_defines.h" 24 /* 25 * Defines 26 */ 27 #define PHYMOD_INTERFACE_SIDE_SHIFT 31 28 29 /* 30 * Types 31 */ 32 33 /* 34 * Macros 35 */ 36 /* 37 * Global Variables 38 */ 39 40 /* 41 * Functions 42 */ 43 int _furia_get_ref_clock_freq_in_mhz(FURIA_REF_CLK_E ref_clk_freq); 44 STATIC uint16_t _furia_get_link_type(phymod_interface_t intf, uint32_t speed, phymod_otn_type_t otn_type); 45 STATIC uint16_t _furia_get_phy_type(phymod_interface_t intf, uint32_t speed); 46 STATIC int _furia_config_clk_scaler_val(const phymod_access_t *pa, FURIA_REF_CLK_E ref_clk_freq); 47 STATIC int _furia_phymod_to_furia_type_ref_clk_freq(phymod_ref_clk_t ref_clk, FURIA_REF_CLK_E *ref_clk_freq); 48 STATIC int _furia_get_pll_mode(phymod_ref_clk_t ref_clk, uint32_t speed, uint32_t higig, FALCON_PLL_MODE_E *pll_mode); 49 STATIC int _furia_get_pll_mode_otn(phymod_ref_clk_t ref_clk, uint32_t otn_type, FALCON_PLL_MODE_E *pll_mode); 50 STATIC int furia_get_pkg_idx(uint32_t chip_id, int *pkg_idx); 51 STATIC int _furia_config_clk_scaler_without_m0_reset(const phymod_access_t *pa, FURIA_REF_CLK_E ref_clk_freq); 52 STATIC int _furia_get_pkg_lane(uint32_t phy_id, uint32_t chip_id, uint32_t die_lane, uint32_t lane_index, uint32_t *pkg_lane); 53 int _furia_fw_enable(const phymod_access_t* pa); 54 STATIC int _furia_cfg_an_master_lane_get(const phymod_access_t *pa, uint32_t *an_master_lane) ; 55 STATIC int _furia_set_intf_type(const phymod_access_t *pa, uint16_t phy_type, uint16_t link_type, 56 uint32_t phymod_interface_type, int lane_index, int otn_type, uint16_t ref_clock, uint32_t higig); 57 STATIC int _furia_get_intf_type(const phymod_access_t *pa, uint16_t phy_type, uint16_t link_type, 58 int lane_index, uint16_t *saved_intf, uint16_t *saved_intf1e2e, uint16_t *ref_clk, uint32_t *higig) ; 59 STATIC int _furia_set_module_command(const phymod_access_t *pa, uint16_t xfer_addr, 60 uint32_t slv_addr, unsigned char xfer_cnt, FURIA_I2CM_CMD_E cmd); 61 62 /* 63 * Functions for Manipulating Chip/Port Cfg Descriptors 64 */ 65 66 /* 67 * Functions for Programming the Chip 68 */ 69 70 /** Get Revision ID 71 * This function retrieves Revision ID from PHY chip 72 * 73 * @param pa Pointer to phymod access structure 74 * 75 * @param rev_id Revision ID retrieved from the chip 76 */ 77 int furia_rev_id(const phymod_access_t *pa, uint32_t *rev_id) 78 { 79 FUR_MISC_CTRL_CHIP_REVISION_t chip_revision; 80 PHYMOD_MEMSET(&chip_revision, 0 , sizeof(FUR_MISC_CTRL_CHIP_REVISION_t)); 81 82 /* Read the chip revision from register */ 83 PHYMOD_IF_ERR_RETURN 84 (READ_FURIA_PMA_PMD_REG(pa,\ 85 FUR_MISC_CTRL_chip_revision_Adr,\ 86 &chip_revision.data)); 87 *rev_id = chip_revision.fields.chip_rev; 88 return PHYMOD_E_NONE; 89 } 90 91 /** Get Chip ID 92 * This function retrieves Chip ID from PHY chip 93 * 94 * @param pa Pointer to phymod access structure 95 * 96 * @return chip_id Chip id retrieved from the chip 97 */ 98 uint32_t _furia_get_chip_id(const phymod_access_t *pa) 99 { 100 uint32_t chip_id = 0; 101 FUR_MISC_CTRL_CHIP_REVISION_t chip_revision; 102 FUR_MISC_CTRL_CHIP_ID_t chip_id_t; 103 PHYMOD_MEMSET(&chip_revision, 0 , sizeof(FUR_MISC_CTRL_CHIP_REVISION_t)); 104 PHYMOD_MEMSET(&chip_id_t, 0 , sizeof(FUR_MISC_CTRL_CHIP_ID_t)); 105 106 /* Read upper bits of chip id */ 107 PHYMOD_IF_ERR_RETURN 108 (READ_FURIA_PMA_PMD_REG(pa,\ 109 FUR_MISC_CTRL_chip_revision_Adr,\ 110 &chip_revision.data)); 111 chip_id = chip_revision.fields.chip_id_19_16; 112 /* Read lower 16 bits of chip id */ 113 PHYMOD_IF_ERR_RETURN 114 (READ_FURIA_PMA_PMD_REG(pa,\ 115 FUR_MISC_CTRL_chip_id_Adr,\ 116 &chip_id_t.data)); 117 chip_id = ( (chip_id << 16) | 118 (chip_id_t.fields.chip_id_15_0)); 119 return(chip_id); 120 } 121 122 123 /** Reset Chip 124 * This function is used to reset entire chip 125 * 126 * @param pa Pointer to phymod access structure 127 * 128 * @return PHYMOD_E_NONE successful function execution 129 */ 130 int _furia_chip_reset (const phymod_access_t *pa) 131 { 132 FUR_GEN_CNTRLS_GEN_CONTROL1_t gen_cntrl1; 133 PHYMOD_MEMSET(&gen_cntrl1, 0 , sizeof(FUR_GEN_CNTRLS_GEN_CONTROL1_t)); 134 135 /* Read General control1 Reg */ 136 PHYMOD_IF_ERR_RETURN 137 (READ_FURIA_PMA_PMD_REG(pa,\ 138 FUR_GEN_CNTRLS_gen_control1_Adr,\ 139 &gen_cntrl1.data)); 140 141 /* update bit field for hard reset */ 142 gen_cntrl1.fields.resetb = 0; 143 144 /* Write to General control1 Reg */ 145 PHYMOD_IF_ERR_RETURN 146 (WRITE_FURIA_PMA_PMD_REG(pa,\ 147 FUR_GEN_CNTRLS_gen_control1_Adr,\ 148 gen_cntrl1.data)); 149 return PHYMOD_E_NONE; 150 } 151 152 /** Reset Register 153 * This function is used to perform register reset 154 * 155 * @param pa Pointer to phymod access structure 156 * 157 * @return PHYMOD_E_NONE successful function execution 158 */ 159 int _furia_register_rst (const phymod_access_t *pa) 160 { 161 FUR_GEN_CNTRLS_GEN_CONTROL1_t gen_cntrl1; 162 PHYMOD_MEMSET(&gen_cntrl1, 0 , sizeof(FUR_GEN_CNTRLS_GEN_CONTROL1_t)); 163 164 /* Read General control1 Reg */ 165 PHYMOD_IF_ERR_RETURN 166 (READ_FURIA_PMA_PMD_REG(pa,\ 167 FUR_GEN_CNTRLS_gen_control1_Adr,\ 168 &gen_cntrl1.data)); 169 170 /* Update bit field for register reset */ 171 gen_cntrl1.fields.reg_rstb = 0; 172 173 /* Write to General control1 Reg */ 174 PHYMOD_IF_ERR_RETURN 175 (WRITE_FURIA_PMA_PMD_REG(pa,\ 176 FUR_GEN_CNTRLS_gen_control1_Adr,\ 177 gen_cntrl1.data)); 178 return PHYMOD_E_NONE; 179 } 180 181 /** Configure PRBS generator 182 * This function is used to configure PRBS generator with user provided 183 * polynomial and invert data information 184 * 185 * @param pa Pointer to phymod access structure 186 * @param flags Flags for prbs 187 * @param prbs_mode User specified polynomial 188 * 0 - PRBS7 189 * 1 - PRBS9 190 * 2 - PRBS11 191 * 3 - PRBS15 192 * 4 - PRBS23 193 * 5 - PRBS31 194 * 6 - PRBS58 195 * 196 * @param prbs_inv User specified invert data config 197 * 0 - do not invert PRBS data 198 * 1 - invert PRBS data 199 * 200 * @return PHYMOD_E_NONE successful function execution 201 */ 202 int furia_prbs_config_set(const phymod_access_t *pa, 203 uint32_t flags, 204 enum srds_prbs_polynomial_enum prbs_mode, 205 uint32_t prbs_inv) 206 { 207 int lane_map = 0; 208 int pkg_side = 0; 209 int wr_lane = 0; 210 int sys_en = 0; 211 int rd_lane = 0; 212 uint32_t chip_id = 0; 213 int num_lanes = 0; 214 int lane_index = 0; 215 uint32_t acc_flags = 0; 216 const FURIA_PKG_LANE_CFG_t* tx_pkg_ln_des = NULL; 217 const FURIA_PKG_LANE_CFG_t* rx_pkg_ln_des = NULL; 218 219 /* Get the lane map from phymod access */ 220 lane_map = PHYMOD_ACC_LANE_MASK(pa); 221 acc_flags = PHYMOD_ACC_FLAGS(pa); 222 FURIA_GET_IF_SIDE(acc_flags, pkg_side); 223 /* Get the chip id */ 224 chip_id = _furia_get_chip_id(pa); 225 FURIA_GET_NUM_LANES(chip_id, num_lanes); 226 227 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 228 if (((lane_map >> lane_index) & 1) == 0x1) { 229 /* Configure Tx side(SIDE_A) first*/ 230 if (flags == 0 || flags == PHYMOD_PRBS_DIRECTION_TX) { 231 tx_pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 0); 232 PHYMOD_NULL_CHECK(tx_pkg_ln_des); 233 /* Get sys_en, wr_lane, rd_lane using lane descriptor */ 234 if (pkg_side == SIDE_A) { 235 sys_en = tx_pkg_ln_des->sideA; 236 } else { 237 sys_en = tx_pkg_ln_des->sideB; 238 } 239 wr_lane = FURIA_IF_BCAST_SET(chip_id, lane_map) ? BROADCAST : tx_pkg_ln_des->slice_wr_val; 240 rd_lane = tx_pkg_ln_des->slice_rd_val; 241 /* Program the slice register */ 242 PHYMOD_IF_ERR_RETURN 243 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 244 if (FURIA_IF_TX_SIDE(chip_id, pkg_side)) { 245 PHYMOD_IF_ERR_RETURN(falcon_furia_config_tx_prbs(pa, prbs_mode, (uint8_t)prbs_inv)); 246 } 247 } 248 if (flags == 0 || flags == PHYMOD_PRBS_DIRECTION_RX) { 249 rx_pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 1); 250 PHYMOD_NULL_CHECK(rx_pkg_ln_des); 251 /* Get sys_en, wr_lane, rd_lane using lane descriptor */ 252 if (pkg_side == SIDE_A) { 253 sys_en = rx_pkg_ln_des->sideA; 254 } else { 255 sys_en = rx_pkg_ln_des->sideB; 256 } 257 wr_lane = FURIA_IF_BCAST_SET(chip_id, lane_map) ? BROADCAST : rx_pkg_ln_des->slice_wr_val; 258 rd_lane = rx_pkg_ln_des->slice_rd_val; 259 /* Program the slice register */ 260 PHYMOD_IF_ERR_RETURN 261 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 262 if (FURIA_IF_RX_SIDE(chip_id, pkg_side)) { 263 PHYMOD_IF_ERR_RETURN(falcon_furia_config_rx_prbs(pa, prbs_mode, PRBS_INITIAL_SEED_HYSTERESIS, (uint8_t)prbs_inv)); 264 } 265 } 266 267 if (FURIA_IF_BCAST_SET(chip_id, lane_map)) { 268 break; 269 } 270 } 271 } 272 /* Set the slice register with default values */ 273 PHYMOD_IF_ERR_RETURN 274 (WRITE_FURIA_SLICE_REG(pa, 0, 1, 0)); 275 return PHYMOD_E_NONE; 276 } 277 278 /** Get PRBS generator configuration 279 * This function is used to retrieve PRBS generator configuration from 280 * the chip 281 * 282 * @param pa Pointer to phymod access structure 283 * @param flags Flags for prbs 284 * @param prbs_mode Configured Polynomial retrieved from chip 285 * @param prbs_inv Configured invert data retrieved from chip 286 * 0 - do not invert PRBS data 287 * 1 - invert PRBS data 288 * 289 * @return PHYMOD_E_NONE successful function execution 290 */ 291 int furia_prbs_config_get(const phymod_access_t *pa, 292 uint32_t flags, 293 enum srds_prbs_polynomial_enum *prbs_mode, 294 uint32_t *prbs_inv) 295 { 296 int lane_map = 0; 297 int pkg_side = 0; 298 int wr_lane = 0; 299 int sys_en = 0; 300 int rd_lane = 0; 301 const FURIA_PKG_LANE_CFG_t* tx_pkg_ln_des = NULL; 302 const FURIA_PKG_LANE_CFG_t* rx_pkg_ln_des = NULL; 303 int num_lanes = 0; 304 int lane_index = 0; 305 uint32_t chip_id = 0; 306 uint32_t acc_flags = 0; 307 uint8_t prbs_invert = 0; 308 enum srds_prbs_checker_mode_enum prbs_checker_mode = 0; 309 *prbs_inv = 0; 310 *prbs_mode = 0; 311 312 /* Get the lane map from phymod access */ 313 lane_map = PHYMOD_ACC_LANE_MASK(pa); 314 acc_flags = PHYMOD_ACC_FLAGS(pa); 315 FURIA_GET_IF_SIDE(acc_flags, pkg_side); 316 317 /* Get the chip id */ 318 chip_id = _furia_get_chip_id(pa); 319 320 FURIA_GET_NUM_LANES(chip_id, num_lanes); 321 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 322 if (((lane_map >> lane_index) & 1) == 0x1) { 323 /* Get lane descriptor from package lane */ 324 if (flags == 0 || flags == PHYMOD_PRBS_DIRECTION_TX) { 325 tx_pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 0); 326 PHYMOD_NULL_CHECK(tx_pkg_ln_des); 327 /* Get sys_en, wr_lane, rd_lane using lane descriptor */ 328 if (pkg_side == SIDE_A) { 329 sys_en = tx_pkg_ln_des->sideA; 330 } else { 331 sys_en = tx_pkg_ln_des->sideB; 332 } 333 wr_lane = tx_pkg_ln_des->slice_wr_val; 334 rd_lane = tx_pkg_ln_des->slice_rd_val; 335 /* Program the slice register */ 336 PHYMOD_IF_ERR_RETURN 337 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 338 if (FURIA_IF_TX_SIDE(chip_id, pkg_side)) { 339 PHYMOD_IF_ERR_RETURN(falcon_furia_get_tx_prbs_config(pa, prbs_mode, &prbs_invert)); 340 *prbs_inv = prbs_invert; 341 } 342 } 343 if (flags == 0 || flags == PHYMOD_PRBS_DIRECTION_RX) { 344 rx_pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 1); 345 PHYMOD_NULL_CHECK(rx_pkg_ln_des); 346 /* Get sys_en, wr_lane, rd_lane using lane descriptor */ 347 if (pkg_side == SIDE_A) { 348 sys_en = rx_pkg_ln_des->sideA; 349 } else { 350 sys_en = rx_pkg_ln_des->sideB; 351 } 352 wr_lane = rx_pkg_ln_des->slice_wr_val; 353 rd_lane = rx_pkg_ln_des->slice_rd_val; 354 /* Program the slice register */ 355 PHYMOD_IF_ERR_RETURN 356 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 357 if (FURIA_IF_RX_SIDE(chip_id, pkg_side)) { 358 PHYMOD_IF_ERR_RETURN(falcon_furia_get_rx_prbs_config(pa, prbs_mode, &prbs_checker_mode, &prbs_invert)); 359 *prbs_inv = prbs_invert; 360 } 361 } 362 break; 363 } 364 } 365 /* Set the slice register with default values */ 366 PHYMOD_IF_ERR_RETURN 367 (WRITE_FURIA_SLICE_REG(pa, 0, 1, 0)); 368 return PHYMOD_E_NONE; 369 } 370 371 372 /** Get PRBS lock and error status 373 * This function is used to retrieve PRBS lock, loss of lock and error counts 374 * from the chip 375 * 376 * @param pa Pointer to phymod access structure 377 * @param lock_status PRBS lock status denotes PRBS generator and 378 * checker are locked to same polynomial data 379 * @param lock_loss Loss of lock denotes PRBS generator and checker 380 * are not in sync 381 * @param error_count PRBS error count retrieved from chip 382 * 383 * @return PHYMOD_E_NONE successful function execution 384 */ 385 int furia_prbs_status_get(const phymod_access_t *pa, 386 uint32_t *lock_status, 387 uint32_t *lock_loss, 388 uint32_t *error_count) 389 { 390 int lane_map = 0; 391 int pkg_side = 0; 392 int wr_lane = 0; 393 int sys_en = 0; 394 int rd_lane = 0; 395 uint32_t chip_id = 0; 396 int num_lanes = 0; 397 int lane_index = 0; 398 uint32_t acc_flags = 0; 399 uint8_t chk_lock = 0; 400 uint8_t loss_of_lock = 0; 401 const FURIA_PKG_LANE_CFG_t* pkg_ln_des = NULL; 402 uint32_t per_lane_err_count = 0; 403 *lock_status = 1; 404 *lock_loss = 1; 405 *error_count = 0; 406 407 408 /* Get the lane map from phymod access */ 409 lane_map = PHYMOD_ACC_LANE_MASK(pa); 410 acc_flags = PHYMOD_ACC_FLAGS(pa); 411 FURIA_GET_IF_SIDE(acc_flags, pkg_side); 412 413 /* Get the chip id */ 414 chip_id = _furia_get_chip_id(pa); 415 416 FURIA_GET_NUM_LANES(chip_id, num_lanes); 417 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 418 if (((lane_map >> lane_index) & 1) == 0x1) { 419 pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 1); 420 PHYMOD_NULL_CHECK(pkg_ln_des); 421 /* Get sys_en, wr_lane, rd_lane using lane descriptor */ 422 if(pkg_side == SIDE_A) { 423 sys_en = pkg_ln_des->sideA; 424 } else { 425 sys_en = pkg_ln_des->sideB; 426 } 427 wr_lane = pkg_ln_des->slice_wr_val; 428 rd_lane = pkg_ln_des->slice_rd_val; 429 430 /* Program the slice register */ 431 PHYMOD_IF_ERR_RETURN 432 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 433 434 if (FURIA_IF_RX_SIDE(chip_id, pkg_side)) { 435 PHYMOD_IF_ERR_RETURN(falcon_furia_prbs_chk_lock_state(pa, &chk_lock)); 436 *lock_status &= chk_lock; 437 PHYMOD_IF_ERR_RETURN(falcon_furia_prbs_err_count_state(pa, &per_lane_err_count, &loss_of_lock)); 438 *error_count |= per_lane_err_count; 439 *lock_loss &= loss_of_lock; 440 } 441 } 442 } 443 /* Set the slice register with default values */ 444 PHYMOD_IF_ERR_RETURN 445 (WRITE_FURIA_SLICE_REG(pa, 0, 1, 0)); 446 return PHYMOD_E_NONE; 447 } 448 449 /** Enable PRBS generator and PRBS checker 450 * This function is used to enable or disable PRBS generator and PRBS checker 451 * as requested by the user 452 * 453 * @param pa Pointer to phymod access structure 454 * @param flags Flags for prbs 455 * @param enable Enable or disable as specified by the user 456 * 1 - Enable 457 * 0 - Disable 458 * 459 * @return PHYMOD_E_NONE successful function execution 460 */ 461 int furia_prbs_enable_set(const phymod_access_t *pa, uint32_t flags, uint32_t enable) 462 { 463 int lane_map = 0; 464 int pkg_side = 0; 465 int wr_lane = 0; 466 int sys_en = 0; 467 int rd_lane = 0; 468 uint8_t ena_dis = 0; 469 uint32_t chip_id = 0; 470 int num_lanes = 0; 471 int lane_index = 0; 472 TLB_RX_PRBS_CHK_CONFIG_t prbs_chk_config; 473 const FURIA_PKG_LANE_CFG_t* tx_pkg_ln_des = NULL; 474 const FURIA_PKG_LANE_CFG_t* rx_pkg_ln_des = NULL; 475 uint32_t acc_flags = 0; 476 PHYMOD_MEMSET(&prbs_chk_config, 0 , sizeof(TLB_RX_PRBS_CHK_CONFIG_t)); 477 478 ena_dis = enable ? 1 : 0; 479 480 481 482 /* Get the lane map from phymod access */ 483 lane_map = PHYMOD_ACC_LANE_MASK(pa); 484 acc_flags = PHYMOD_ACC_FLAGS(pa); 485 FURIA_GET_IF_SIDE(acc_flags, pkg_side); 486 487 /* Get the chip id */ 488 chip_id = _furia_get_chip_id(pa); 489 490 FURIA_GET_NUM_LANES(chip_id, num_lanes); 491 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 492 if (((lane_map >> lane_index) & 1) == 0x1) { 493 if (flags == 0 || flags == PHYMOD_PRBS_DIRECTION_TX) { 494 tx_pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 0); 495 PHYMOD_NULL_CHECK(tx_pkg_ln_des); 496 /* Get sys_en, wr_lane, rd_lane using lane descriptor */ 497 if (pkg_side == SIDE_A) { 498 sys_en = tx_pkg_ln_des->sideA; 499 } else { 500 sys_en = tx_pkg_ln_des->sideB; 501 } 502 wr_lane = FURIA_IF_BCAST_SET(chip_id, lane_map) ? BROADCAST : tx_pkg_ln_des->slice_wr_val; 503 rd_lane = tx_pkg_ln_des->slice_rd_val; 504 PHYMOD_IF_ERR_RETURN 505 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 506 PHYMOD_IF_ERR_RETURN(falcon_furia_tx_prbs_en(pa, ena_dis)); 507 } 508 if (flags == 0 || flags == PHYMOD_PRBS_DIRECTION_RX) { 509 rx_pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 1); 510 PHYMOD_NULL_CHECK(rx_pkg_ln_des); 511 /* Get sys_en, wr_lane, rd_lane using lane descriptor */ 512 if (pkg_side == SIDE_A) { 513 sys_en = rx_pkg_ln_des->sideA; 514 } else { 515 sys_en = rx_pkg_ln_des->sideB; 516 } 517 wr_lane = FURIA_IF_BCAST_SET(chip_id, lane_map) ? BROADCAST : rx_pkg_ln_des->slice_wr_val; 518 rd_lane = rx_pkg_ln_des->slice_rd_val; 519 /* Program the slice register */ 520 PHYMOD_IF_ERR_RETURN 521 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 522 523 if (FURIA_IF_RX_SIDE(chip_id, pkg_side)) { 524 if(enable) { 525 /* Read PRBS Checker Control Register */ 526 PHYMOD_IF_ERR_RETURN 527 (READ_FURIA_PMA_PMD_REG(pa,\ 528 TLB_RX_prbs_chk_config_Adr,\ 529 &prbs_chk_config.data)); 530 531 /* Update the field PRBS checker clock enable. */ 532 prbs_chk_config.fields.prbs_chk_clk_en_frc_on = 1; 533 534 /* Write to PRBS Checker Control Register */ 535 PHYMOD_IF_ERR_RETURN 536 (WRITE_FURIA_PMA_PMD_REG(pa,\ 537 TLB_RX_prbs_chk_config_Adr,\ 538 prbs_chk_config.data)); 539 } 540 PHYMOD_IF_ERR_RETURN(falcon_furia_rx_prbs_en(pa, ena_dis)); 541 if(!enable) { 542 PHYMOD_IF_ERR_RETURN 543 (READ_FURIA_PMA_PMD_REG(pa,\ 544 TLB_RX_prbs_chk_config_Adr,\ 545 &prbs_chk_config.data)); 546 547 /* Update the field PRBS checker clock enable. */ 548 prbs_chk_config.fields.prbs_chk_clk_en_frc_on = 0; 549 550 /* Write to PRBS Checker Control Register */ 551 PHYMOD_IF_ERR_RETURN 552 (WRITE_FURIA_PMA_PMD_REG(pa,\ 553 TLB_RX_prbs_chk_config_Adr,\ 554 prbs_chk_config.data)); 555 } 556 } 557 } 558 559 if(FURIA_IF_BCAST_SET(chip_id, lane_map)) { 560 break; 561 } 562 } 563 } 564 /* Set the slice register with default values */ 565 PHYMOD_IF_ERR_RETURN 566 (WRITE_FURIA_SLICE_REG(pa, 0, 1, 0)); 567 return PHYMOD_E_NONE; 568 } 569 570 /** Get Enable status of PRBS generator and PRBS checker 571 * This function is used to retrieve the enable status of PRBS generator and 572 * PRBS checker 573 * 574 * @param pa Pointer to phymod access structure 575 * @param flags Flags for prbs 576 * @param enable Enable or disable read from chip 577 * 1 - Enable 578 * 0 - Disable 579 * 580 * @return PHYMOD_E_NONE successful function execution 581 */ 582 int furia_prbs_enable_get(const phymod_access_t *pa, uint32_t flags, uint32_t *enable) 583 { 584 int lane_map = 0; 585 int pkg_side = 0; 586 int wr_lane = 0; 587 int sys_en = 0; 588 int rd_lane = 0; 589 uint8_t gen_en = 0; 590 uint8_t chk_en = 0; 591 uint32_t chip_id = 0; 592 int num_lanes = 0; 593 int lane_index = 0; 594 uint32_t acc_flags = 0; 595 const FURIA_PKG_LANE_CFG_t* tx_pkg_ln_des = NULL; 596 const FURIA_PKG_LANE_CFG_t* rx_pkg_ln_des = NULL; 597 gen_en = 0; 598 chk_en = 0; 599 *enable = 0; 600 /* Get the lane map from phymod access */ 601 lane_map = PHYMOD_ACC_LANE_MASK(pa); 602 acc_flags = PHYMOD_ACC_FLAGS(pa); 603 FURIA_GET_IF_SIDE(acc_flags, pkg_side); 604 605 /* Get the chip id */ 606 chip_id = _furia_get_chip_id(pa); 607 608 FURIA_GET_NUM_LANES(chip_id, num_lanes); 609 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 610 if (((lane_map >> lane_index) & 1) == 0x1) { 611 if (flags == 0 || flags == PHYMOD_PRBS_DIRECTION_TX) { 612 tx_pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 0); 613 PHYMOD_NULL_CHECK(tx_pkg_ln_des); 614 /* Get sys_en, wr_lane, rd_lane using lane descriptor */ 615 if (pkg_side == SIDE_A) { 616 sys_en = tx_pkg_ln_des->sideA; 617 } else { 618 sys_en = tx_pkg_ln_des->sideB; 619 } 620 wr_lane = tx_pkg_ln_des->slice_wr_val; 621 rd_lane = tx_pkg_ln_des->slice_rd_val; 622 /* Program the slice register */ 623 PHYMOD_IF_ERR_RETURN 624 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 625 if (FURIA_IF_TX_SIDE(chip_id, pkg_side)) { 626 PHYMOD_IF_ERR_RETURN(falcon_furia_get_tx_prbs_en(pa, &gen_en)); 627 *enable = gen_en; 628 } 629 } 630 if (flags == 0 || flags == PHYMOD_PRBS_DIRECTION_RX) { 631 rx_pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 1); 632 PHYMOD_NULL_CHECK(rx_pkg_ln_des); 633 /* Get sys_en, wr_lane, rd_lane using lane descriptor */ 634 if (pkg_side == SIDE_A) { 635 sys_en = rx_pkg_ln_des->sideA; 636 } else { 637 sys_en = rx_pkg_ln_des->sideB; 638 } 639 wr_lane = rx_pkg_ln_des->slice_wr_val; 640 rd_lane = rx_pkg_ln_des->slice_rd_val; 641 /* Program the slice register */ 642 PHYMOD_IF_ERR_RETURN 643 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 644 if (FURIA_IF_RX_SIDE(chip_id, pkg_side)) { 645 PHYMOD_IF_ERR_RETURN(falcon_furia_get_rx_prbs_en(pa, &chk_en)); 646 *enable = chk_en; 647 } 648 } 649 break; 650 } 651 } 652 /* Set the slice register to default */ 653 PHYMOD_IF_ERR_RETURN 654 (WRITE_FURIA_SLICE_REG(pa, 0, 1, 0)); 655 if(flags == 0) { 656 if(gen_en && chk_en) { 657 *enable = 1; 658 } else { 659 *enable = 0; 660 } 661 } 662 663 return PHYMOD_E_NONE; 664 } 665 666 /** Get link status of PHY 667 * This function is used to retrieve the link status of PHY chip 668 * 669 * @param pa Pointer to phymod access structure 670 * 671 * @param link_status link status of the PHY 672 * 1 - Up 673 * 0 - Down 674 * 675 * @return PHYMOD_E_NONE successful function execution 676 */ 677 int furia_link_status(const phymod_access_t *pa, 678 uint32_t *link_status) 679 { 680 int lane_map = 0; 681 int wr_lane = 0; 682 int sys_en = 0; 683 int rd_lane = 0; 684 uint32_t chip_id = 0; 685 int num_lanes = 0; 686 int lane_index = 0; 687 uint8_t rx_pmd_lock = 0; 688 uint32_t fcpcs_lock = 1; 689 uint16_t fcpcs_chkr_mode = 0; 690 int pkg_side = 0; 691 uint32_t acc_flags = 0; 692 LINE_RX_PMA_DP_MAIN_CTRL_t line_rx_dp_main_ctrl; 693 LINE_RX_PMA_DP_MAIN_CTRL_PCS_MODE_t tmp_main_ctrl_mode; 694 SYS_RX_PMA_DP_MAIN_CTRL_t sys_rx_dp_main_ctrl; 695 LINE_RX_PMA_DP_LIVE_STATUS_FC_MODE_t line_rx_pma_dp_live_status_fc_mode; 696 LINE_RX_PMA_DP_LIVE_STATUS_PCS_MODE_t line_rx_pma_dp_live_status_pcs_mode; 697 SYS_RX_PMA_DP_LIVE_STATUS_FC_MODE_t sys_rx_pma_dp_live_status_fc_mode; 698 SYS_RX_PMA_DP_LIVE_STATUS_PCS_MODE_t sys_rx_pma_dp_live_status_pcs_mode; 699 const FURIA_PKG_LANE_CFG_t* pkg_ln_des = NULL; 700 PHYMOD_MEMSET(&line_rx_dp_main_ctrl, 0 , sizeof(LINE_RX_PMA_DP_MAIN_CTRL_t)); 701 PHYMOD_MEMSET(&tmp_main_ctrl_mode, 0 , sizeof(LINE_RX_PMA_DP_MAIN_CTRL_PCS_MODE_t)); 702 PHYMOD_MEMSET(&sys_rx_dp_main_ctrl, 0 , sizeof(SYS_RX_PMA_DP_MAIN_CTRL_t)); 703 PHYMOD_MEMSET(&line_rx_pma_dp_live_status_fc_mode, 0 , sizeof(LINE_RX_PMA_DP_LIVE_STATUS_FC_MODE_t)); 704 PHYMOD_MEMSET(&line_rx_pma_dp_live_status_pcs_mode, 0 , sizeof(LINE_RX_PMA_DP_LIVE_STATUS_PCS_MODE_t)); 705 PHYMOD_MEMSET(&sys_rx_pma_dp_live_status_fc_mode, 0 , sizeof(SYS_RX_PMA_DP_LIVE_STATUS_FC_MODE_t)); 706 PHYMOD_MEMSET(&sys_rx_pma_dp_live_status_pcs_mode, 0 , sizeof(SYS_RX_PMA_DP_LIVE_STATUS_PCS_MODE_t)); 707 708 *link_status = 1; 709 /* Get the lane map from phymod access */ 710 lane_map = PHYMOD_ACC_LANE_MASK(pa); 711 acc_flags = PHYMOD_ACC_FLAGS(pa); 712 FURIA_GET_IF_SIDE(acc_flags, pkg_side); 713 714 /* Get the chip id */ 715 chip_id = _furia_get_chip_id(pa); 716 717 FURIA_GET_NUM_LANES(chip_id, num_lanes); 718 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 719 if (((lane_map >> lane_index) & 1) == 0x1) { 720 pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 1); 721 PHYMOD_NULL_CHECK(pkg_ln_des); 722 /* Get sys_en, wr_lane, rd_lane using lane descriptor */ 723 wr_lane = pkg_ln_des->slice_wr_val; 724 rd_lane = pkg_ln_des->slice_rd_val; 725 if(pkg_side == SIDE_A) { 726 sys_en = pkg_ln_des->sideA; 727 } else { 728 sys_en = pkg_ln_des->sideB; 729 } 730 /* Program the slice register */ 731 PHYMOD_IF_ERR_RETURN 732 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 733 if (FURIA_IF_RX_SIDE(chip_id, pkg_side)) { 734 PHYMOD_IF_ERR_RETURN 735 (falcon_furia_pmd_lock_status(pa, &rx_pmd_lock)); 736 if(sys_en == LINE) { 737 PHYMOD_IF_ERR_RETURN 738 (READ_FURIA_PMA_PMD_REG(pa,\ 739 LINE_RX_PMA_DP_main_ctrl_Adr,\ 740 &line_rx_dp_main_ctrl.data)); 741 tmp_main_ctrl_mode.data = line_rx_dp_main_ctrl.data; 742 } else { 743 PHYMOD_IF_ERR_RETURN 744 (READ_FURIA_PMA_PMD_REG(pa,\ 745 SYS_RX_PMA_DP_main_ctrl_Adr,\ 746 &sys_rx_dp_main_ctrl.data)); 747 tmp_main_ctrl_mode.data = line_rx_dp_main_ctrl.data; 748 } 749 750 if(!tmp_main_ctrl_mode.fields.link_mon_en) { 751 *link_status &= rx_pmd_lock; 752 } else { 753 if(sys_en == LINE) { 754 PHYMOD_IF_ERR_RETURN 755 (READ_FURIA_PMA_PMD_REG(pa,\ 756 LINE_RX_PMA_DP_live_status_Adr,\ 757 &line_rx_pma_dp_live_status_pcs_mode.data)); 758 PHYMOD_IF_ERR_RETURN 759 (READ_FURIA_PMA_PMD_REG(pa,\ 760 LINE_RX_PMA_DP_live_status_Adr,\ 761 &line_rx_pma_dp_live_status_fc_mode.data)); 762 } else { 763 PHYMOD_IF_ERR_RETURN 764 (READ_FURIA_PMA_PMD_REG(pa,\ 765 SYS_RX_PMA_DP_live_status_Adr,\ 766 &sys_rx_pma_dp_live_status_pcs_mode.data)); 767 PHYMOD_IF_ERR_RETURN 768 (READ_FURIA_PMA_PMD_REG(pa,\ 769 SYS_RX_PMA_DP_live_status_Adr,\ 770 &sys_rx_pma_dp_live_status_fc_mode.data)); 771 } 772 773 if(tmp_main_ctrl_mode.fields.link_mon_mode_frcval == 0x0) { 774 fcpcs_chkr_mode = PCS49_1x10G; 775 } 776 if(tmp_main_ctrl_mode.fields.link_mon_mode_frcval == 0x1) { 777 if(tmp_main_ctrl_mode.fields.mode_50g) { 778 fcpcs_chkr_mode = PCS82_2x25G; 779 } else if(tmp_main_ctrl_mode.fields.mode_100g) { 780 fcpcs_chkr_mode = PCS82_4x25G; 781 } else { 782 fcpcs_chkr_mode = PCS82_4x10G; 783 } 784 } 785 if(tmp_main_ctrl_mode.fields.link_mon_mode_frcval == 0x2) { 786 fcpcs_chkr_mode = FC4; 787 } 788 if(tmp_main_ctrl_mode.fields.link_mon_mode_frcval == 0x3) { 789 fcpcs_chkr_mode = FC8; 790 } 791 792 switch (fcpcs_chkr_mode) { 793 case PCS49_1x10G : 794 case PCS82_4x10G : 795 case FC16 : 796 case FC32 : 797 case PCS82_2x25G : 798 case PCS82_4x25G : 799 if(sys_en == LINE) { 800 fcpcs_lock &= line_rx_pma_dp_live_status_pcs_mode.fields.pcs_status; 801 } else { 802 fcpcs_lock &= sys_rx_pma_dp_live_status_pcs_mode.fields.pcs_status; 803 } 804 break; 805 case FC4 : 806 case FC8 : 807 if(sys_en == LINE) { 808 fcpcs_lock = line_rx_pma_dp_live_status_fc_mode.fields.wsyn_link_fail; 809 } else { 810 fcpcs_lock = sys_rx_pma_dp_live_status_fc_mode.fields.wsyn_link_fail; 811 } 812 break; 813 } 814 *link_status &= fcpcs_lock; 815 } 816 } 817 } 818 } 819 /* Set the slice register with default values */ 820 PHYMOD_IF_ERR_RETURN 821 (WRITE_FURIA_SLICE_REG(pa, 0, 1, 0)); 822 return PHYMOD_E_NONE; 823 } 824 /* furia_single_pmd_enable 825 * For 100G and 106G the part needs to be in single_pmd mode 826 * i.e. all 4-lanes are part of the same port. 827 * So we should set rg_single_pmd_frc to 0 as this force is only needed for 50G. 828 * rg_single_pmd_frc_val is needed only for 100G SR4 as hardware doesn't set this field. 829 * Its a don't care for KR4, LR4, and CR4 interfaces as hardware programs it correctly. 830 * 831 * @param pa Pointer to phymod access structure 832 * 833 * @return PHYMOD_E_NONE successful function execution 834 */ 835 int furia_single_pmd_enable(const phymod_access_t *pa) 836 { 837 FUR_MISC_CTRL_MODE_DEC_FRC_t dec_frc; 838 FUR_MISC_CTRL_MODE_DEC_FRC_VAL_t dec_frc_val; 839 840 PHYMOD_MEMSET(&dec_frc, 0 , sizeof(FUR_MISC_CTRL_MODE_DEC_FRC_t)); 841 PHYMOD_MEMSET(&dec_frc_val, 0 , sizeof(FUR_MISC_CTRL_MODE_DEC_FRC_VAL_t)); 842 843 PHYMOD_IF_ERR_RETURN 844 (READ_FURIA_PMA_PMD_REG(pa, 845 FUR_MISC_CTRL_mode_dec_frc_val_Adr, 846 &dec_frc_val.data)); 847 dec_frc_val.fields.rg_single_pmd_frc_val = 1; 848 PHYMOD_IF_ERR_RETURN 849 (WRITE_FURIA_PMA_PMD_REG(pa, 850 FUR_MISC_CTRL_mode_dec_frc_val_Adr, 851 dec_frc_val.data)); 852 PHYMOD_IF_ERR_RETURN 853 (READ_FURIA_PMA_PMD_REG(pa, 854 FUR_MISC_CTRL_mode_dec_frc_Adr, 855 &dec_frc.data)); 856 dec_frc.fields.rg_single_pmd_frc = 0; 857 PHYMOD_IF_ERR_RETURN 858 (WRITE_FURIA_PMA_PMD_REG(pa, 859 FUR_MISC_CTRL_mode_dec_frc_Adr, 860 dec_frc.data)); 861 return PHYMOD_E_NONE; 862 } 863 864 /** Set config mode 865 * This function is used to set the operating mode of the PHY 866 * 867 * @param pa Pointer to phymod access structure 868 * @param config Pointer to phy interface config sturcuture 869 * 870 * @return PHYMOD_E_NONE successful function execution 871 */ 872 int furia_set_config_mode(const phymod_access_t *pa, 873 const phymod_phy_inf_config_t* config) 874 { 875 IEEE_AN_BLK0_AN_CONTROL_REGISTER_t an_ctrl_reg; 876 FUR_MISC_CTRL_UDMS_PHY_t udms_phy; 877 FUR_MISC_CTRL_UDMS_LINK_t udms_link; 878 FUR_GEN_CNTRLS_FIRMWARE_ENABLE_t fw_enable_reg; 879 LINE_RX_PMA_DP_MAIN_CTRL_t line_rx_dp_main_ctrl; 880 SYS_RX_PMA_DP_MAIN_CTRL_t sys_rx_dp_main_ctrl; 881 LINE_RX_PMA_DP_MAIN_CTRL_PCS_MODE_t tmp_main_ctrl_mode; 882 FUR_GEN_CNTRLS_gpreg13_t gen_ctrl_gpreg13; 883 FUR_MISC_CTRL_MODE_DEC_FRC_t dec_frc; 884 FUR_MISC_CTRL_MODE_DEC_FRC_VAL_t dec_frc_val; 885 phymod_phy_inf_config_t config_copy; 886 uint16_t phy_type, prev_phy_type = 0; 887 uint16_t link_type; 888 int lane_map = 0; 889 uint16_t lane_map_saved = 0; 890 int lane_index = 0; 891 uint32_t chip_id = 0; 892 int num_lanes = 0; 893 uint32_t acc_flags = 0; 894 int pkg_side = 0; 895 const FURIA_PKG_LANE_CFG_t* pkg_ln_des = NULL; 896 FURIA_REF_CLK_E ref_clk_freq = REF_CLK_INVALID; 897 FALCON_PLL_MODE_E pll_mode = PLL_MODE_INVALID; 898 phymod_interface_t actual_intf = 0; 899 uint32_t actual_speed = 0; 900 phymod_ref_clk_t actual_ref_clk; 901 uint32_t actual_interface_modes = 0; 902 uint8_t fw_enable = 0; 903 uint8_t retry_count = 40; 904 phymod_access_t l_pa; 905 uint32_t curr_intf[MAX_NUM_LANES] = {0,}; 906 uint32_t curr_speed[MAX_NUM_LANES] = {0,}; 907 int wr_lane = 0; 908 int rd_lane = 0; 909 int sys_en = 0; 910 uint32_t higig_mode = 0; 911 uint16_t curr_pll_mode[2] = {0,}; 912 uint16_t side_index = 0; 913 uint16_t serdes_pll_mode = 99; /*99 as invalid mode*/ 914 uint16_t otn_type = 8; 915 PLL_CAL_COM_CTL_7_t pll_ctrl_7; 916 917 PHYMOD_MEMSET(&an_ctrl_reg, 0 , sizeof(IEEE_AN_BLK0_AN_CONTROL_REGISTER_t)); 918 PHYMOD_MEMSET(&udms_phy, 0 , sizeof(FUR_MISC_CTRL_UDMS_PHY_t)); 919 PHYMOD_MEMSET(&udms_link, 0 , sizeof(FUR_MISC_CTRL_UDMS_LINK_t)); 920 PHYMOD_MEMSET(&fw_enable_reg, 0 , sizeof(FUR_GEN_CNTRLS_FIRMWARE_ENABLE_t)); 921 PHYMOD_MEMSET(&line_rx_dp_main_ctrl, 0 , sizeof(LINE_RX_PMA_DP_MAIN_CTRL_t)); 922 PHYMOD_MEMSET(&sys_rx_dp_main_ctrl, 0 , sizeof(SYS_RX_PMA_DP_MAIN_CTRL_t)); 923 PHYMOD_MEMSET(&tmp_main_ctrl_mode, 0 , sizeof(LINE_RX_PMA_DP_MAIN_CTRL_PCS_MODE_t)); 924 PHYMOD_MEMSET(&dec_frc_val, 0 , sizeof(FUR_MISC_CTRL_MODE_DEC_FRC_VAL_t)); 925 PHYMOD_MEMSET(&dec_frc, 0 , sizeof(FUR_MISC_CTRL_MODE_DEC_FRC_t)); 926 PHYMOD_MEMSET(&config_copy, 0 , sizeof(phymod_phy_inf_config_t)); 927 PHYMOD_MEMSET(&pll_ctrl_7, 0 , sizeof(PLL_CAL_COM_CTL_7_t)); 928 /* Get a copy of phymod access */ 929 PHYMOD_MEMCPY(&l_pa, pa, sizeof(phymod_access_t)); 930 PHYMOD_MEMCPY(&config_copy, config, sizeof(phymod_phy_inf_config_t)); 931 932 if (config_copy.device_aux_modes != NULL) { 933 otn_type = ((FURIA_DEVICE_OTN_MODE_T*) config_copy.device_aux_modes)->otn_type; 934 } 935 936 /* Get CHIP ID */ 937 chip_id = _furia_get_chip_id(pa); 938 /* Get the lane map from phymod access */ 939 lane_map = PHYMOD_ACC_LANE_MASK(pa); 940 lane_map_saved = lane_map; 941 acc_flags = PHYMOD_ACC_FLAGS(pa); 942 FURIA_GET_IF_SIDE(acc_flags, pkg_side); 943 944 higig_mode = PHYMOD_INTF_MODES_HIGIG_GET(config); 945 if (pkg_side == SIDE_B) { 946 if (FURIA_IS_SIMPLEX(chip_id)) { 947 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_PARAM, (_PHYMOD_MSG("Wrong Package side specified, Package side must be 0 for simplex packages(Tx side)"))); 948 } 949 PHYMOD_IF_ERR_RETURN 950 (READ_FURIA_PMA_PMD_REG(pa,\ 951 FUR_GEN_CNTRLS_gpreg13_Adr,\ 952 &gen_ctrl_gpreg13.data)); 953 if ((config_copy.interface_type == phymodInterfaceKX) || 954 (config_copy.interface_type == phymodInterfaceKR) || 955 (config_copy.interface_type == phymodInterfaceKR4) || 956 (config_copy.interface_type == phymodInterfaceSR)) { 957 gen_ctrl_gpreg13.fields.phy_type_sys = 0; /* Backplane modes */ 958 } 959 if ((config_copy.interface_type == phymodInterfaceCAUI4) || 960 (config_copy.interface_type == phymodInterfaceCAUI) || 961 (config_copy.interface_type == phymodInterfaceXLAUI) || 962 (config_copy.interface_type == phymodInterfaceXFI) || 963 (config_copy.interface_type == phymodInterfaceCAUI4_C2C)) { 964 gen_ctrl_gpreg13.fields.phy_type_sys = 1; /* PCB trace for chip to chip module */ 965 } 966 PHYMOD_IF_ERR_RETURN 967 (WRITE_FURIA_PMA_PMD_REG(pa,\ 968 FUR_GEN_CNTRLS_gpreg13_Adr,\ 969 gen_ctrl_gpreg13.data)); 970 PHYMOD_IF_ERR_RETURN(_furia_fw_enable(pa)); 971 return PHYMOD_E_NONE; 972 } 973 /*Disable the FEC in HG mode since FEC is supported only in IEEE modes 974 Disable initially for all the IEEE mode and enable FEC for 100G SR4/KR4/CR4 */ 975 if (FURIA_IS_DUPLEX(chip_id)) { 976 PHYMOD_IF_ERR_RETURN 977 (furia_fec_enable_set(pa, 0)); 978 } 979 /* Wait for firmware to ready before config to be changed */ 980 PHYMOD_IF_ERR_RETURN 981 (READ_FURIA_PMA_PMD_REG(pa,\ 982 FUR_GEN_CNTRLS_firmware_enable_Adr,\ 983 &fw_enable_reg.data)); 984 fw_enable = fw_enable_reg.fields.fw_enable_val; 985 986 987 while((fw_enable != 0) && (retry_count)) { 988 PHYMOD_IF_ERR_RETURN 989 (READ_FURIA_PMA_PMD_REG(pa,\ 990 FUR_GEN_CNTRLS_firmware_enable_Adr,\ 991 &fw_enable_reg.data)); 992 fw_enable = fw_enable_reg.fields.fw_enable_val; 993 PHYMOD_USLEEP(200); 994 retry_count--; 995 } 996 997 if(!retry_count) { 998 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("1:config failed, micro controller is busy.."))); 999 } 1000 1001 /* Read current mode configurations from registers */ 1002 FURIA_GET_NUM_LANES(chip_id, num_lanes); 1003 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 1004 l_pa.lane_mask = 0x1 << lane_index; 1005 PHYMOD_IF_ERR_RETURN 1006 (furia_get_config_mode(&l_pa, &actual_intf, &actual_speed, &actual_ref_clk, &actual_interface_modes, &config_copy ,lane_map_saved)); 1007 curr_intf[lane_index] = actual_intf; 1008 curr_speed[lane_index] = actual_speed; 1009 l_pa.lane_mask = 0x0; 1010 } 1011 1012 1013 if (FURIA_IS_DUPLEX(chip_id)) { 1014 if ((curr_speed[0] == SPEED_10G || curr_speed[0] == SPEED_20G) || 1015 (curr_speed[1] == SPEED_10G || curr_speed[1] == SPEED_20G) || 1016 (curr_speed[2] == SPEED_10G || curr_speed[2] == SPEED_20G) || 1017 (curr_speed[3] == SPEED_10G || curr_speed[3] == SPEED_20G)) { 1018 if((config->data_rate == SPEED_25G || config->data_rate == SPEED_27G || 1019 config->data_rate == SPEED_50G || config->data_rate == SPEED_53G) && (lane_map != BROADCAST)) { 1020 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("Unsupported mode"))); 1021 } 1022 } 1023 1024 if ((curr_speed[0] == SPEED_25G || curr_speed[0] == SPEED_50G) || 1025 (curr_speed[1] == SPEED_25G || curr_speed[1] == SPEED_50G) || 1026 (curr_speed[2] == SPEED_25G || curr_speed[2] == SPEED_50G) || 1027 (curr_speed[3] == SPEED_25G || curr_speed[3] == SPEED_50G)) { 1028 if((config->data_rate == SPEED_10G || config->data_rate == SPEED_20G || 1029 config->data_rate == SPEED_11G || config->data_rate == SPEED_21G) && (lane_map != BROADCAST)) { 1030 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("Unsupported mode"))); 1031 } 1032 } 1033 1034 if(((config->data_rate == SPEED_100G || config->data_rate == SPEED_106G || 1035 config->data_rate == SPEED_40G || config->data_rate == SPEED_42G) && 1036 (config->interface_type == phymodInterfaceSR4 || 1037 config->interface_type == phymodInterfaceKR4 || 1038 config->interface_type == phymodInterfaceCR4 || 1039 config->interface_type == phymodInterfaceLR4)) && (lane_map != BROADCAST)) { 1040 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_PARAM, (_PHYMOD_MSG("2:Wrong Lanemap param"))); 1041 } 1042 1043 if((config->data_rate == SPEED_50G || config->data_rate == SPEED_53G || 1044 config->data_rate == SPEED_20G || config->data_rate == SPEED_21G || 1045 config->data_rate == SPEED_40G || config->data_rate == SPEED_42G) && 1046 (config->interface_type == phymodInterfaceKR2) && 1047 (lane_map != MULTICAST01 && lane_map != MULTICAST23 && lane_map != BROADCAST)) { 1048 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_PARAM, (_PHYMOD_MSG("3:Wrong Lanemap param"))); 1049 } 1050 } 1051 1052 if (FURIA_IS_SIMPLEX(chip_id)) { 1053 if(config_copy.data_rate == SPEED_40G || 1054 config_copy.data_rate == SPEED_42G || 1055 config_copy.data_rate == SPEED_11G) { 1056 config_copy.data_rate = SPEED_10G; 1057 switch (config_copy.interface_type) { 1058 case phymodInterfaceKR4: 1059 case phymodInterfaceKR: 1060 config_copy.interface_type = phymodInterfaceKR; 1061 break; 1062 case phymodInterfaceLR4: 1063 case phymodInterfaceLR: 1064 config_copy.interface_type = phymodInterfaceLR; 1065 break; 1066 case phymodInterfaceSR4: 1067 case phymodInterfaceSR: 1068 config_copy.interface_type = phymodInterfaceSR; 1069 break; 1070 case phymodInterfaceER4: 1071 case phymodInterfaceER: 1072 config_copy.interface_type = phymodInterfaceER; 1073 break; 1074 case phymodInterfaceCX4: 1075 case phymodInterfaceCX: 1076 config_copy.interface_type = phymodInterfaceCX; 1077 break; 1078 case phymodInterfaceCR4: 1079 case phymodInterfaceCR: 1080 config_copy.interface_type = phymodInterfaceCR; 1081 break; 1082 case phymodInterfaceXLAUI: 1083 case phymodInterfaceXFI: 1084 config_copy.interface_type = phymodInterfaceXFI; 1085 break; 1086 case phymodInterfaceSFI: 1087 config_copy.interface_type = phymodInterfaceSFI; 1088 break; 1089 default: 1090 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_PARAM, (_PHYMOD_MSG("3:Unsupported speed and interface"))); 1091 break; 1092 } 1093 } 1094 if(config_copy.data_rate == SPEED_50G || config_copy.data_rate == SPEED_53G || 1095 config_copy.data_rate == SPEED_100G || config_copy.data_rate == SPEED_106G || 1096 config_copy.data_rate == SPEED_27G) { 1097 config_copy.data_rate = SPEED_25G; 1098 switch (config_copy.interface_type) { 1099 case phymodInterfaceKR4: 1100 case phymodInterfaceKR2: 1101 case phymodInterfaceKR: 1102 config_copy.interface_type = phymodInterfaceKR; 1103 break; 1104 case phymodInterfaceLR4: 1105 case phymodInterfaceLR: 1106 config_copy.interface_type = phymodInterfaceLR; 1107 break; 1108 case phymodInterfaceCR4: 1109 case phymodInterfaceCR2: 1110 case phymodInterfaceCR: 1111 config_copy.interface_type = phymodInterfaceCR; 1112 break; 1113 case phymodInterfaceSR4: 1114 case phymodInterfaceSR: 1115 config_copy.interface_type = phymodInterfaceSR; 1116 break; 1117 case phymodInterfaceER4: 1118 case phymodInterfaceER: 1119 config_copy.interface_type = phymodInterfaceER; 1120 break; 1121 case phymodInterfaceCAUI4: 1122 case phymodInterfaceCAUI: 1123 case phymodInterfaceCAUI4_C2C: 1124 case phymodInterfaceCAUI4_C2M: 1125 case phymodInterfaceVSR: 1126 config_copy.interface_type = phymodInterfaceVSR; 1127 break; 1128 default: 1129 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_PARAM, (_PHYMOD_MSG("3:Unsupported speed and interface"))); 1130 break; 1131 } 1132 } 1133 if (config_copy.data_rate == SPEED_21G) { 1134 config_copy.data_rate = SPEED_20G; 1135 switch (config_copy.interface_type) { 1136 case phymodInterfaceKR2: 1137 case phymodInterfaceKR: 1138 config_copy.interface_type = phymodInterfaceKR; 1139 break; 1140 case phymodInterfaceLR: 1141 config_copy.interface_type = phymodInterfaceLR; 1142 break; 1143 case phymodInterfaceSR: 1144 config_copy.interface_type = phymodInterfaceSR; 1145 break; 1146 case phymodInterfaceER: 1147 config_copy.interface_type = phymodInterfaceER; 1148 break; 1149 default: 1150 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_PARAM, (_PHYMOD_MSG("3:Unsupported speed and interface"))); 1151 break; 1152 } 1153 } 1154 } 1155 /*perform phymod to furia enum conversion */ 1156 PHYMOD_IF_ERR_RETURN ( 1157 _furia_phymod_to_furia_type_ref_clk_freq(config_copy.ref_clock, &ref_clk_freq)); 1158 /*Set the ref_clk freq before programming phy type and link type */ 1159 PHYMOD_IF_ERR_RETURN ( 1160 _furia_config_clk_scaler_without_m0_reset(pa, ref_clk_freq)); 1161 phy_type = _furia_get_phy_type(config_copy.interface_type, config_copy.data_rate); 1162 1163 phy_type = (config_copy.interface_modes & PHYMOD_INTF_MODES_FIBER) ? 0x3 /*fiber*/ : phy_type; 1164 link_type = _furia_get_link_type(config_copy.interface_type, config_copy.data_rate, otn_type); 1165 if( config_copy.interface_modes & PHYMOD_INTF_MODES_FIBER){ 1166 /*phy_type is 0x3 for FC interfaces*/ 1167 if( config_copy.data_rate == SPEED_8P5G){ 1168 link_type = ( config_copy.interface_type == phymodInterfaceSFI)? 0xd : 0x2; 1169 phy_type = ( config_copy.interface_type == phymodInterfaceSFI)? 0x1 : phy_type ; 1170 }else if( config_copy.data_rate == SPEED_14P025G){ 1171 link_type = ( config_copy.interface_type == phymodInterfaceSFI)? 0xd : 0x3; 1172 phy_type = ( config_copy.interface_type == phymodInterfaceSFI)? 0x1 : phy_type ; 1173 }else if( config_copy.data_rate == SPEED_28P05G){ /*FC32*/ 1174 link_type = ( config_copy.interface_type == phymodInterfaceCAUI)? 0xf : 0x4; 1175 phy_type = ( config_copy.interface_type == phymodInterfaceCAUI)? 0x1 : phy_type ; 1176 }else if( config_copy.data_rate == SPEED_10P518G){ /*FC10 missing from datasheet. same as FC16*/ 1177 link_type = ( config_copy.interface_type == phymodInterfaceSFI)? 0xd : 0x3; 1178 phy_type = ( config_copy.interface_type == phymodInterfaceSFI)? 0x1 : phy_type ; 1179 }else{ 1180 phy_type = 0x1; 1181 } 1182 } 1183 1184 if ((config_copy.interface_type == phymodInterfaceCR || config_copy.interface_type == phymodInterfaceCR2) && 1185 (config_copy.data_rate == SPEED_25G || config_copy.data_rate == SPEED_27G || 1186 config_copy.data_rate == SPEED_50G || config_copy.data_rate == SPEED_53G)) { 1187 PHYMOD_IF_ERR_RETURN 1188 (READ_FURIA_PMA_PMD_REG(pa,\ 1189 FUR_MISC_CTRL_mode_dec_frc_val_Adr,\ 1190 &dec_frc_val.data)); 1191 /* Disable FEC */ 1192 dec_frc_val.fields.rg_cl91_enabled_frc_val = 0; 1193 /* Disable single PMD */ 1194 dec_frc_val.fields.rg_single_pmd_frc_val= 0; 1195 PHYMOD_IF_ERR_RETURN 1196 (WRITE_FURIA_PMA_PMD_REG(pa,\ 1197 FUR_MISC_CTRL_mode_dec_frc_val_Adr,\ 1198 dec_frc_val.data)); 1199 PHYMOD_IF_ERR_RETURN 1200 (READ_FURIA_PMA_PMD_REG(pa,\ 1201 FUR_MISC_CTRL_mode_dec_frc_Adr,\ 1202 &dec_frc.data)); 1203 dec_frc.fields.rg_cl91_enabled_frc = 1; 1204 dec_frc.fields.rg_single_pmd_frc = 1; 1205 PHYMOD_IF_ERR_RETURN 1206 (WRITE_FURIA_PMA_PMD_REG(pa,\ 1207 FUR_MISC_CTRL_mode_dec_frc_Adr,\ 1208 dec_frc.data)); 1209 } 1210 1211 if (((config_copy.interface_type == phymodInterfaceSR4) || 1212 (config_copy.interface_type == phymodInterfaceCR4) || 1213 (config_copy.interface_type == phymodInterfaceLR4) || 1214 (config_copy.interface_type == phymodInterfaceKR4)) && 1215 ((config_copy.data_rate == SPEED_100G) || 1216 (config_copy.data_rate == SPEED_106G)) && 1217 (FURIA_IS_DUPLEX(chip_id))) { 1218 PHYMOD_IF_ERR_RETURN 1219 (furia_single_pmd_enable(pa)); 1220 } 1221 1222 if (((config_copy.interface_type == phymodInterfaceSR4) || 1223 (config_copy.interface_type == phymodInterfaceCR4) || 1224 (config_copy.interface_type == phymodInterfaceKR4)) && 1225 (config_copy.data_rate == SPEED_100G) && 1226 (FURIA_IS_DUPLEX(chip_id))&&(!higig_mode)) { 1227 PHYMOD_IF_ERR_RETURN 1228 (furia_fec_enable_set(pa, 1)); 1229 } 1230 /* Disable autonegotiation on all the PHY lanes */ 1231 FURIA_GET_LANE_MASK(chip_id, lane_map); 1232 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 1233 if (((lane_map >> lane_index) & 1) == 0x1) { 1234 /* Configure Tx side(SIDE_A) first*/ 1235 pkg_ln_des = _furia_pkg_ln_des(chip_id, pa, lane_index); 1236 PHYMOD_NULL_CHECK(pkg_ln_des); 1237 wr_lane = FURIA_IF_BCAST_SET(chip_id, lane_map) ? BROADCAST : pkg_ln_des->slice_wr_val; 1238 rd_lane = pkg_ln_des->slice_rd_val; 1239 if(pkg_side == SIDE_A) { 1240 sys_en = pkg_ln_des->sideA; 1241 } else { 1242 sys_en = pkg_ln_des->sideB; 1243 } 1244 /* Program the slice register */ 1245 PHYMOD_IF_ERR_RETURN 1246 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 1247 /* Force AN disable since mode is configured using UDMS*/ 1248 PHYMOD_IF_ERR_RETURN 1249 (READ_FURIA_PMA_PMD_REG(pa,\ 1250 IEEE_AN_BLK0_an_control_register_Adr,\ 1251 &an_ctrl_reg.data)); 1252 /* Update auto_negotiationenable bit field */ 1253 an_ctrl_reg.fields.auto_negotiationenable = 0; 1254 1255 /* Write to AN control register */ 1256 PHYMOD_IF_ERR_RETURN 1257 (WRITE_FURIA_PMA_PMD_REG(pa,\ 1258 IEEE_AN_BLK0_an_control_register_Adr,\ 1259 an_ctrl_reg.data)); 1260 PHYMOD_IF_ERR_RETURN 1261 (READ_FURIA_PMA_PMD_REG(pa,\ 1262 IEEE_AN_BLK0_an_control_register_Adr,\ 1263 &an_ctrl_reg.data)); 1264 if (FURIA_IF_BCAST_SET(chip_id, lane_map)) { 1265 break; 1266 } 1267 } 1268 } 1269 1270 /* Program udms_en=1 */ 1271 /* Read UDMS PHY Type Register */ 1272 PHYMOD_IF_ERR_RETURN 1273 (READ_FURIA_PMA_PMD_REG(pa,\ 1274 FUR_MISC_CTRL_udms_phy_Adr,\ 1275 &udms_phy.data)); 1276 1277 /* Update the field udms enable */ 1278 udms_phy.fields.udms_en = 1; 1279 /* Update udms_phy_type */ 1280 prev_phy_type = udms_phy.fields.udms_phy_type; 1281 udms_phy.fields.udms_phy_type = phy_type; 1282 1283 /* Write to UDMS PHY Type Register */ 1284 PHYMOD_IF_ERR_RETURN 1285 (WRITE_FURIA_PMA_PMD_REG(pa,\ 1286 FUR_MISC_CTRL_udms_phy_Adr,\ 1287 udms_phy.data)); 1288 1289 /* Read the link type Register*/ 1290 PHYMOD_IF_ERR_RETURN 1291 (READ_FURIA_PMA_PMD_REG(pa,\ 1292 FUR_MISC_CTRL_udms_link_Adr,\ 1293 &udms_link.data)); 1294 if( 1295 (curr_intf[0] == phymodInterfaceKR4 && 1296 curr_intf[1] == phymodInterfaceKR4 && 1297 curr_intf[2] == phymodInterfaceKR4 && 1298 curr_intf[3] == phymodInterfaceKR4) || 1299 (curr_intf[0] == phymodInterfaceCR4 && 1300 curr_intf[1] == phymodInterfaceCR4 && 1301 curr_intf[2] == phymodInterfaceCR4 && 1302 curr_intf[3] == phymodInterfaceCR4) || 1303 (curr_intf[0] == phymodInterfaceLR4 && 1304 curr_intf[1] == phymodInterfaceLR4 && 1305 curr_intf[2] == phymodInterfaceLR4 && 1306 curr_intf[3] == phymodInterfaceLR4) || 1307 (curr_intf[0] == phymodInterfaceSR4 && 1308 curr_intf[1] == phymodInterfaceSR4 && 1309 curr_intf[2] == phymodInterfaceSR4 && 1310 curr_intf[3] == phymodInterfaceSR4)) { 1311 FURIA_GET_LANE_MASK(chip_id, lane_map); 1312 } else if ((prev_phy_type != phy_type) && (prev_phy_type == FURIA_PHYTYPE_FP 1313 || prev_phy_type == FURIA_PHYTYPE_PROP || prev_phy_type == FURIA_PHYTYPE_BP) && 1314 (phy_type == FURIA_PHYTYPE_FP || phy_type == FURIA_PHYTYPE_PROP || phy_type == FURIA_PHYTYPE_BP) && 1315 (config_copy.data_rate == SPEED_10G || config_copy.data_rate == SPEED_11G || 1316 config_copy.data_rate == SPEED_25G || config_copy.data_rate == SPEED_27G || 1317 config_copy.data_rate == SPEED_50G || config_copy.data_rate == SPEED_53G)) 1318 { 1319 /* USED TO MOVE FROM CR TO SR and KR2 to CR2 PER DIE 1320 * Condition will not success for cr to cx / sr to er etc */ 1321 FURIA_GET_LANE_MASK(chip_id, lane_map); 1322 } else if (((/* link_type == FURIA_LINKTYPE_7 ||*/ 1323 link_type == FURIA_LINKTYPE_5) || 1324 (link_type == FURIA_LINKTYPE_8)) && 1325 (config_copy.data_rate == SPEED_25G || 1326 config_copy.data_rate == SPEED_27G || 1327 config_copy.data_rate == SPEED_50G || 1328 config_copy.data_rate == SPEED_53G )) { 1329 FURIA_GET_LANE_MASK(chip_id, lane_map); 1330 } else { 1331 lane_map = lane_map_saved; 1332 } 1333 1334 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 1335 if (((lane_map >> lane_index) & 1) == 0x1) { 1336 pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 1); 1337 PHYMOD_NULL_CHECK(pkg_ln_des); 1338 /* Update the field udms enable */ 1339 if (pkg_ln_des->die_lane_num == 0) { 1340 udms_link.fields.udms_ln0_lnk_type = link_type; 1341 } 1342 if (pkg_ln_des->die_lane_num == 1) { 1343 udms_link.fields.udms_ln1_lnk_type = link_type; 1344 } 1345 if (pkg_ln_des->die_lane_num == 2) { 1346 udms_link.fields.udms_ln2_lnk_type = link_type; 1347 } 1348 if (pkg_ln_des->die_lane_num == 3) { 1349 udms_link.fields.udms_ln3_lnk_type = link_type; 1350 } 1351 PHYMOD_IF_ERR_RETURN 1352 (_furia_set_intf_type(pa, phy_type, link_type, config_copy.interface_type, lane_index, otn_type,config_copy.ref_clock,higig_mode)); 1353 } 1354 } 1355 1356 1357 /* Program the Link Type Register with link type*/ 1358 PHYMOD_IF_ERR_RETURN 1359 (WRITE_FURIA_PMA_PMD_REG(pa,\ 1360 FUR_MISC_CTRL_udms_link_Adr,\ 1361 udms_link.data)); 1362 for(side_index = 0; side_index < 2; side_index ++) { 1363 /* Set PLL div */ 1364 wr_lane = 1 << 0; 1365 rd_lane = 0; 1366 if(side_index == 0) { 1367 sys_en = SIDE_A; 1368 } else { 1369 sys_en = SIDE_B; 1370 } 1371 /* Program the slice register */ 1372 PHYMOD_IF_ERR_RETURN 1373 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 1374 1375 /* Program pll_mode */ 1376 PHYMOD_IF_ERR_RETURN 1377 (READ_FURIA_PMA_PMD_REG(pa,\ 1378 PLL_CAL_COM_CTL_7_Adr,\ 1379 &pll_ctrl_7.data)); 1380 curr_pll_mode[side_index]= pll_ctrl_7.fields.pll_mode; 1381 } 1382 pll_mode = curr_pll_mode[0] & curr_pll_mode[1]; 1383 1384 /* Set the PLL value based on ref clock and speed */ 1385 if( config_copy.interface_type == phymodInterfaceOTN ) { 1386 PHYMOD_IF_ERR_RETURN( 1387 _furia_get_pll_mode_otn(config_copy.ref_clock, otn_type, &pll_mode)); 1388 }else{ 1389 PHYMOD_IF_ERR_RETURN( 1390 _furia_get_pll_mode(config_copy.ref_clock, config_copy.data_rate, higig_mode, &pll_mode)); 1391 } 1392 1393 if ((curr_pll_mode[0] != pll_mode) || (curr_pll_mode[1] != pll_mode)) { 1394 PHYMOD_IF_ERR_RETURN( 1395 _furia_get_pll_for_serdes(config_copy.ref_clock,config_copy.data_rate,pll_mode,&serdes_pll_mode)); 1396 PHYMOD_IF_ERR_RETURN( 1397 _furia_config_pll_div(pa, serdes_pll_mode)); 1398 } 1399 /*Wait for fw_enable to go low before setting fw_enable_val*/ 1400 retry_count = 40; 1401 PHYMOD_IF_ERR_RETURN 1402 (READ_FURIA_PMA_PMD_REG(pa,\ 1403 FUR_GEN_CNTRLS_firmware_enable_Adr,\ 1404 &fw_enable_reg.data)); 1405 fw_enable_reg.fields.fw_enable_val = 1; 1406 PHYMOD_IF_ERR_RETURN 1407 (WRITE_FURIA_PMA_PMD_REG(pa,\ 1408 FUR_GEN_CNTRLS_firmware_enable_Adr,\ 1409 fw_enable_reg.data)); 1410 /*Wait for fw_enable to go low */ 1411 PHYMOD_IF_ERR_RETURN 1412 (READ_FURIA_PMA_PMD_REG(pa,\ 1413 FUR_GEN_CNTRLS_firmware_enable_Adr,\ 1414 &fw_enable_reg.data)); 1415 fw_enable = fw_enable_reg.fields.fw_enable_val; 1416 1417 while((fw_enable != 0) && (retry_count)) { 1418 PHYMOD_IF_ERR_RETURN 1419 (READ_FURIA_PMA_PMD_REG(pa,\ 1420 FUR_GEN_CNTRLS_firmware_enable_Adr,\ 1421 &fw_enable_reg.data)); 1422 fw_enable = fw_enable_reg.fields.fw_enable_val; 1423 PHYMOD_USLEEP(200); 1424 retry_count--; 1425 } 1426 1427 if(!retry_count) { 1428 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("config failed, micro controller is busy.."))); 1429 } 1430 { 1431 uint32_t phy_type_1, link_type_1; 1432 PHYMOD_IF_ERR_RETURN 1433 (READ_FURIA_PMA_PMD_REG(pa,\ 1434 FUR_MISC_CTRL_phy_type_status_Adr,\ 1435 &phy_type_1)); 1436 /* Read the link type Register*/ 1437 PHYMOD_IF_ERR_RETURN 1438 (READ_FURIA_PMA_PMD_REG(pa,\ 1439 FUR_MISC_CTRL_link_type_status_Adr,\ 1440 &link_type_1)); 1441 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 1442 if (((lane_map >> lane_index) & 1) == 0x1) { 1443 l_pa.lane_mask = 0x1 << lane_index; 1444 PHYMOD_IF_ERR_RETURN 1445 (furia_get_config_mode(&l_pa, &actual_intf, &actual_speed, &actual_ref_clk, &actual_interface_modes, &config_copy,lane_map_saved)); 1446 if((config_copy.interface_type != actual_intf) || 1447 (config_copy.ref_clock != actual_ref_clk)) { 1448 PHYMOD_IF_ERR_RETURN 1449 (_furia_set_intf_type(pa, phy_type_1, link_type_1, curr_intf[lane_index], lane_index, otn_type,config_copy.ref_clock,higig_mode)); 1450 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("Set config failed"))); 1451 } 1452 } 1453 } 1454 } 1455 return PHYMOD_E_NONE; 1456 } 1457 1458 /** Get config mode 1459 * This function is used to retrieve the operating mode of the PHY 1460 * 1461 * @param pa Pointer to phymod access structure 1462 * @param intf Interface type 1463 * @param speed Speed val retrieved from PHY 1464 * @param ref_clk Reference clock 1465 * @param interface_modes Supported interface modes 1466 * @param config config structure 1467 * @param saved_lane_map lane_map passed as per the mode of config 1468 * 1469 * @return PHYMOD_E_NONE successful function execution 1470 */ 1471 int furia_get_config_mode(const phymod_access_t *pa, 1472 phymod_interface_t *intf, 1473 uint32_t *speed, 1474 phymod_ref_clk_t *ref_clk, 1475 uint32_t *interface_modes, phymod_phy_inf_config_t *config , uint16_t saved_lane_map) 1476 { 1477 IEEE_AN_BLK0_AN_CONTROL_REGISTER_t an_ctrl_reg; 1478 FUR_MISC_CTRL_PHY_TYPE_STATUS_t udms_phy; 1479 FUR_MISC_CTRL_LINK_TYPE_STATUS_t udms_link; 1480 FUR_GEN_CNTRLS_GEN_CONTROL3_t gen_ctrl_3; 1481 FUR_GEN_CNTRLS_gpreg13_t gen_ctrl_gpreg13; 1482 furia_an_ability_t an_ability; 1483 uint32_t logic_to_phy_ln0_map = 0; 1484 uint16_t master_lane_num = 0; 1485 int lane_map = 0; 1486 uint16_t phy_type = 0; 1487 uint16_t link_type = 0; 1488 uint16_t saved_intf = 0; 1489 uint16_t saved_intf1e2e = 0, saved_refclk = 0; 1490 uint16_t ref_clk_scaler_val = 0; 1491 const FURIA_PKG_LANE_CFG_t* pkg_ln_des = NULL; 1492 int lane_index = 0; 1493 uint32_t chip_id = 0; 1494 int num_lanes = 0; 1495 uint32_t acc_flags = 0; 1496 int pkg_side = 0; 1497 int wr_lane = 0; 1498 int rd_lane = 0; 1499 int sys_en = 0; 1500 uint16_t curr_pll_mode[2] = {0,}; 1501 uint16_t side_index = 0; 1502 PLL_CAL_COM_CTL_7_t pll_ctrl_7; 1503 uint16_t nototn_mode_pll_140 = 0 ; 1504 uint16_t mode_FC8 = 0 ; 1505 uint16_t mode_FC10 = 0 ; 1506 uint16_t mode_FC32 = 0 ; 1507 uint16_t mode_11p25g = 0 ; 1508 uint16_t mode_oc192 = 0 ; 1509 uint16_t otn_type = 100 ; 1510 uint16_t nonotn_mode2 = 0 ; 1511 uint32_t higig_mode = 0; 1512 uint32_t is_OTU2 = 0; 1513 1514 *speed = 0; 1515 *intf = 0; 1516 *ref_clk = 0; 1517 *interface_modes = 0; 1518 PHYMOD_MEMSET(&an_ctrl_reg, 0 , sizeof(IEEE_AN_BLK0_AN_CONTROL_REGISTER_t)); 1519 PHYMOD_MEMSET(&udms_phy, 0 , sizeof(FUR_MISC_CTRL_PHY_TYPE_STATUS_t)); 1520 PHYMOD_MEMSET(&udms_link, 0 , sizeof(FUR_MISC_CTRL_LINK_TYPE_STATUS_t)); 1521 PHYMOD_MEMSET(&gen_ctrl_3, 0 , sizeof(FUR_GEN_CNTRLS_GEN_CONTROL3_t)); 1522 PHYMOD_MEMSET(&an_ability, 0 , sizeof(furia_an_ability_t)); 1523 PHYMOD_MEMSET(&pll_ctrl_7, 0 , sizeof(PLL_CAL_COM_CTL_7_t)); 1524 1525 PHYMOD_IF_ERR_RETURN 1526 (READ_FURIA_PMA_PMD_REG(pa,\ 1527 IEEE_AN_BLK0_an_control_register_Adr,\ 1528 &an_ctrl_reg.data)); 1529 1530 /* Get the lane map from phymod access */ 1531 lane_map = PHYMOD_ACC_LANE_MASK(pa); 1532 acc_flags = PHYMOD_ACC_FLAGS(pa); 1533 FURIA_GET_IF_SIDE(acc_flags, pkg_side); 1534 1535 /* Get the chip id */ 1536 chip_id = _furia_get_chip_id(pa); 1537 FURIA_GET_NUM_LANES(chip_id, num_lanes); 1538 /* Get the link type and phy type from udms reg if AN is not on */ 1539 if (!an_ctrl_reg.fields.auto_negotiationenable) { 1540 /* Read UDMS PHY Type Register */ 1541 PHYMOD_IF_ERR_RETURN 1542 (READ_FURIA_PMA_PMD_REG(pa,\ 1543 FUR_MISC_CTRL_phy_type_status_Adr,\ 1544 &udms_phy.data)); 1545 /* Read the link type Register*/ 1546 PHYMOD_IF_ERR_RETURN 1547 (READ_FURIA_PMA_PMD_REG(pa,\ 1548 FUR_MISC_CTRL_link_type_status_Adr,\ 1549 &udms_link.data)); 1550 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 1551 if (((lane_map >> lane_index) & 1) == 0x1) { 1552 pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 1); 1553 PHYMOD_NULL_CHECK(pkg_ln_des); 1554 /* Update the field udms enable */ 1555 if (pkg_ln_des->die_lane_num == 0) { 1556 phy_type = udms_phy.fields.ln0_phy_status; 1557 link_type = udms_link.fields.ln0_lnk_status; 1558 } 1559 if (pkg_ln_des->die_lane_num == 1) { 1560 phy_type = udms_phy.fields.ln1_phy_status; 1561 link_type = udms_link.fields.ln1_lnk_status; 1562 } 1563 if (pkg_ln_des->die_lane_num == 2) { 1564 phy_type = udms_phy.fields.ln2_phy_status; 1565 link_type = udms_link.fields.ln2_lnk_status; 1566 } 1567 if (pkg_ln_des->die_lane_num == 3) { 1568 phy_type = udms_phy.fields.ln3_phy_status; 1569 link_type = udms_link.fields.ln3_lnk_status; 1570 } 1571 PHYMOD_IF_ERR_RETURN( 1572 _furia_get_intf_type(pa, phy_type, link_type, lane_index, &saved_intf, &saved_intf1e2e,&saved_refclk,&higig_mode)); 1573 } 1574 } 1575 } else { 1576 PHYMOD_IF_ERR_RETURN 1577 (_furia_autoneg_ability_get(pa, &an_ability)); 1578 1579 if((an_ability.cl73_adv.an_base_speed == FURIA_CL73_100GBASE_KR4) || 1580 (an_ability.cl73_adv.an_base_speed == FURIA_CL73_100GBASE_CR4)|| 1581 (an_ability.cl73_adv.an_base_speed == FURIA_CL73_40GBASE_KR4) || 1582 (an_ability.cl73_adv.an_base_speed == FURIA_CL73_40GBASE_CR4)) { 1583 PHYMOD_IF_ERR_RETURN 1584 (READ_FURIA_PMA_PMD_REG(pa, 0x8a08, &logic_to_phy_ln0_map)); 1585 master_lane_num = logic_to_phy_ln0_map & 0x3; 1586 switch(master_lane_num) { 1587 case 0: 1588 link_type = udms_link.fields.ln0_lnk_status; 1589 break; 1590 case 1: 1591 link_type = udms_link.fields.ln1_lnk_status; 1592 break; 1593 case 2: 1594 link_type = udms_link.fields.ln2_lnk_status; 1595 break; 1596 case 3: 1597 link_type = udms_link.fields.ln3_lnk_status; 1598 break; 1599 } 1600 } else { 1601 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 1602 if (((lane_map >> lane_index) & 1) == 0x1) { 1603 pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 1); 1604 PHYMOD_NULL_CHECK(pkg_ln_des); 1605 switch(pkg_ln_des->die_lane_num) { 1606 case 0: 1607 link_type = udms_link.fields.ln0_lnk_status; 1608 break; 1609 case 1: 1610 link_type = udms_link.fields.ln1_lnk_status; 1611 break; 1612 case 2: 1613 link_type = udms_link.fields.ln2_lnk_status; 1614 break; 1615 case 3: 1616 link_type = udms_link.fields.ln3_lnk_status; 1617 break; 1618 } 1619 PHYMOD_IF_ERR_RETURN( 1620 _furia_get_intf_type(pa, phy_type, link_type, lane_index, &saved_intf, &saved_intf1e2e,&saved_refclk,&higig_mode)); 1621 1622 } 1623 } 1624 } 1625 } 1626 1627 PHYMOD_IF_ERR_RETURN 1628 (READ_FURIA_PMA_PMD_REG(pa,\ 1629 FUR_GEN_CNTRLS_gen_control3_Adr,\ 1630 &gen_ctrl_3.data)); 1631 1632 if(gen_ctrl_3.fields.clock_scaler_frc) { 1633 ref_clk_scaler_val = gen_ctrl_3.fields.clock_scaler_frcval; 1634 } else { 1635 ref_clk_scaler_val = gen_ctrl_3.fields.clock_scaler_code; 1636 } 1637 1638 1639 for(side_index = 0; side_index < 2; side_index ++) { 1640 /* Set PLL div */ 1641 wr_lane = 1 << 0; 1642 rd_lane = 0; 1643 if(side_index == 0) { 1644 sys_en = SIDE_A; 1645 } else { 1646 sys_en = SIDE_B; 1647 } 1648 /* Program the slice register */ 1649 PHYMOD_IF_ERR_RETURN 1650 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 1651 1652 /* Program pll_mode */ 1653 PHYMOD_IF_ERR_RETURN 1654 (READ_FURIA_PMA_PMD_REG(pa,\ 1655 PLL_CAL_COM_CTL_7_Adr,\ 1656 &pll_ctrl_7.data)); 1657 curr_pll_mode[side_index]= pll_ctrl_7.fields.pll_mode; 1658 } 1659 1660 1661 switch(ref_clk_scaler_val) { 1662 case 0x0: 1663 switch (curr_pll_mode[0] & curr_pll_mode[1]) { 1664 case PLL_MODE_132: 1665 if(FURIA_IS_SIMPLEX(chip_id)){ 1666 *ref_clk = phymodRefClk168Mhz; 1667 break; 1668 } 1669 case PLL_MODE_165: 1670 case PLL_MODE_128: 1671 if(FURIA_IS_SIMPLEX(chip_id)){ 1672 *ref_clk = phymodRefClk174Mhz; 1673 }else{ 1674 *ref_clk = phymodRefClk168Mhz; 1675 nonotn_mode2 = 1; 1676 } 1677 is_OTU2 = 1 ; 1678 break; 1679 case PLL_MODE_160: 1680 *ref_clk = phymodRefClk174Mhz; 1681 break; 1682 } 1683 break; 1684 case 0x1: 1685 *ref_clk = phymodRefClk161Mhz; 1686 break; 1687 case 0x2: 1688 *ref_clk = phymodRefClk156Mhz; 1689 switch (curr_pll_mode[0] & curr_pll_mode[1]) { 1690 case PLL_MODE_140: 1691 nototn_mode_pll_140 = 1 ; 1692 break; 1693 case PLL_MODE_128: 1694 mode_oc192 = 1 ; 1695 break; 1696 case PLL_MODE_132: 1697 mode_FC10 = 1 ; 1698 break; 1699 } 1700 break; 1701 case 0x3: 1702 switch (curr_pll_mode[0] & curr_pll_mode[1]) { 1703 case PLL_MODE_180: 1704 mode_11p25g = 1 ; 1705 break; 1706 case PLL_MODE_184: 1707 mode_11p25g = 0 ; 1708 break; 1709 } 1710 *ref_clk = phymodRefClk125Mhz; 1711 break; 1712 case 0x4: 1713 *ref_clk = phymodRefClk106Mhz; 1714 if((curr_pll_mode[0] & curr_pll_mode[1]) == PLL_MODE_160 ) { 1715 mode_FC8 = 1 ; 1716 }else if((curr_pll_mode[0] & curr_pll_mode[1]) == PLL_MODE_264){ 1717 mode_FC32 = 1 ; 1718 } 1719 break; 1720 default: 1721 break; 1722 } 1723 switch(phy_type) { 1724 case FURIA_PHYTYPE_BP: 1725 switch(link_type) { 1726 case FURIA_LINKTYPE_1: 1727 *speed = SPEED_1G; 1728 *intf = phymodInterfaceKX; 1729 break; 1730 case FURIA_LINKTYPE_2: 1731 if (*ref_clk == phymodRefClk125Mhz) { 1732 *speed = ( mode_11p25g == 1)? SPEED_11P25G : SPEED_11P5G; 1733 } else { 1734 *speed = SPEED_10G; 1735 } 1736 *intf = phymodInterfaceKR; 1737 break; 1738 case FURIA_LINKTYPE_3: 1739 *speed = SPEED_40G; 1740 *intf = phymodInterfaceKR4; 1741 break; 1742 case FURIA_LINKTYPE_4: 1743 *speed = SPEED_100G; 1744 *intf = phymodInterfaceKR4; 1745 break; 1746 case FURIA_LINKTYPE_5: 1747 *speed = SPEED_20G; 1748 *intf = phymodInterfaceKR2; 1749 break; 1750 case FURIA_LINKTYPE_6: 1751 if (*ref_clk == phymodRefClk125Mhz) { 1752 *speed = SPEED_23G; 1753 } else { 1754 *speed = SPEED_20G; 1755 } 1756 *intf = phymodInterfaceKR; 1757 break; 1758 case FURIA_LINKTYPE_7: 1759 *speed = SPEED_40G; 1760 *intf = phymodInterfaceKR2; 1761 break; 1762 case FURIA_LINKTYPE_8: 1763 *speed = SPEED_25G; 1764 *intf = phymodInterfaceKR; 1765 break; 1766 case FURIA_LINKTYPE_9: 1767 *speed = SPEED_50G; 1768 *intf = phymodInterfaceKR2; 1769 break; 1770 default: 1771 break; 1772 1773 } 1774 break; 1775 case FURIA_PHYTYPE_FP: 1776 switch(link_type) { 1777 case FURIA_LINKTYPE_1: 1778 switch (saved_intf) { 1779 case 0: 1780 *intf = phymodInterfaceLR; 1781 break; 1782 case 1: 1783 *intf = phymodInterfaceSR; 1784 break; 1785 case 2: 1786 *intf = phymodInterfaceER; 1787 break; 1788 } 1789 if (*ref_clk == phymodRefClk125Mhz) { 1790 *speed = ( mode_11p25g == 1)? SPEED_11P25G : SPEED_11P5G; 1791 }else if (*ref_clk == phymodRefClk106Mhz) { 1792 *speed = ( mode_FC8 == 1 )? SPEED_8P5G : SPEED_14P025G ; 1793 *intf = phymodInterfaceSFI; 1794 } else { 1795 *speed = SPEED_10G; 1796 } 1797 break; 1798 case FURIA_LINKTYPE_2: 1799 *speed = SPEED_40G; 1800 *intf = phymodInterfaceCR4; 1801 break; 1802 case FURIA_LINKTYPE_3: 1803 switch (saved_intf) { 1804 case 0: 1805 *intf = phymodInterfaceLR4; 1806 break; 1807 case 1: 1808 *intf = phymodInterfaceSR4; 1809 break; 1810 case 2: 1811 *intf = phymodInterfaceER4; 1812 break; 1813 } 1814 *speed = SPEED_40G; 1815 break; 1816 case FURIA_LINKTYPE_4: 1817 *speed = SPEED_100G; 1818 switch (saved_intf) { 1819 case 0: 1820 *intf = phymodInterfaceLR4; 1821 break; 1822 case 1: 1823 *intf = phymodInterfaceSR4; 1824 break; 1825 case 2: 1826 *intf = phymodInterfaceER4; 1827 break; 1828 } 1829 break; 1830 case FURIA_LINKTYPE_5: 1831 if (saved_intf != FURIA_IF_CR4) { 1832 *speed = SPEED_25G; 1833 *intf = phymodInterfaceCR; 1834 } else { 1835 *speed = SPEED_100G; 1836 *intf = phymodInterfaceCR4; 1837 } 1838 if (saved_intf == FURIA_IF_CR2) { 1839 *speed = SPEED_50G; 1840 *intf = phymodInterfaceCR2; 1841 } 1842 break; 1843 case FURIA_LINKTYPE_6: 1844 if (*ref_clk == phymodRefClk125Mhz) { 1845 *speed = SPEED_23G; 1846 } else { 1847 *speed = SPEED_20G; 1848 } 1849 switch (saved_intf) { 1850 case 0: 1851 *intf = phymodInterfaceLR; 1852 break; 1853 case 1: 1854 *intf = phymodInterfaceSR; 1855 break; 1856 case 2: 1857 *intf = phymodInterfaceER; 1858 break; 1859 } 1860 break; 1861 case FURIA_LINKTYPE_7:/*50G SR2/LR2/ER2*/ 1862 *speed = (saved_lane_map == 0xc || saved_lane_map==0x3) ? SPEED_50G : SPEED_25G; 1863 switch (saved_intf) { 1864 case 0: 1865 *intf = (saved_lane_map == 0xc || saved_lane_map==0x3) ? phymodInterfaceLR2: phymodInterfaceLR; 1866 break; 1867 case 1: 1868 *intf = (saved_lane_map == 0xc || saved_lane_map==0x3) ? phymodInterfaceSR2 : phymodInterfaceSR; 1869 break; 1870 case 2: 1871 *intf = (saved_lane_map == 0xc || saved_lane_map==0x3) ? phymodInterfaceER2 : phymodInterfaceER; 1872 break; 1873 } 1874 break; 1875 case FURIA_LINKTYPE_C: 1876 *speed = (saved_lane_map == 0xc || saved_lane_map==0x3) ? SPEED_50G :SPEED_25G; 1877 *intf = (saved_lane_map == 0xc || saved_lane_map==0x3) ? phymodInterfaceCR2:phymodInterfaceCR; 1878 break; 1879 case FURIA_LINKTYPE_D: /*mixed mode*/ 1880 if (*ref_clk == phymodRefClk125Mhz) { 1881 *speed = ( mode_11p25g == 1)? SPEED_11P25G : SPEED_11P5G; 1882 }else if (saved_refclk == FURIA_CLK_159) { 1883 /*speed = SPEED_10P518G;*//*FC10*/ 1884 *speed =(nototn_mode_pll_140==1)?((saved_intf1e2e==0)? SPEED_44P57G : SPEED_44P583G) : SPEED_10P518G ; 1885 otn_type=(nototn_mode_pll_140==1)?((saved_intf1e2e==0)? phymodOTNOTU3 : phymodOTNOTU3e2) : otn_type ; 1886 }else if (*ref_clk == phymodRefClk161Mhz) { 1887 *speed = ( is_OTU2 == 1 )? SPEED_10P7G : SPEED_10G ; 1888 otn_type = ( is_OTU2 == 1 )? (phymodOTNOTU2) : otn_type ; 1889 }else if (*ref_clk == phymodRefClk168Mhz || *ref_clk == phymodRefClk174Mhz ) { 1890 *speed = (nonotn_mode2 == 1)? SPEED_10P7G : SPEED_11P18G; 1891 otn_type = ( nonotn_mode2 ==1 )? phymodOTNOTU2 : phymodOTNOTU4p10 ; 1892 }else if (*ref_clk == phymodRefClk106Mhz) { /*FC32*/ 1893 *speed = (( mode_FC8 == 1 )? SPEED_8P5G : SPEED_14P025G) ; 1894 *interface_modes = PHYMOD_INTF_MODES_FIBER ; 1895 } else { 1896 switch(saved_intf1e2e){/*158 Mhz*/ 1897 case 0: 1898 *speed = SPEED_11G; 1899 otn_type = (phymodOTNOTU1e);/*or 1e */ 1900 1901 break; 1902 case 1: 1903 *speed = SPEED_11G; 1904 otn_type = (phymodOTNOTU2e); 1905 1906 break; 1907 default: 1908 *speed = SPEED_10G; 1909 break; 1910 } 1911 *speed = ( mode_oc192 == 1)? SPEED_9P95G : *speed ; 1912 *ref_clk = ( mode_oc192 == 1)? phymodRefClk156Mhz : *ref_clk ; 1913 *interface_modes = ( mode_oc192 == 1)? PHYMOD_INTF_MODES_FIBER : *interface_modes ; 1914 } 1915 if (saved_intf == FURIA_IF_CX) { 1916 *intf = phymodInterfaceCX; 1917 } else if (saved_intf == FURIA_IF_CR) { 1918 *intf = phymodInterfaceCR; 1919 } else if (saved_intf == FURIA_IF_SFI) { 1920 *intf = phymodInterfaceSFI; 1921 } 1922 break; 1923 case FURIA_LINKTYPE_E: /*mixed mode. ok !*/ 1924 if (saved_intf == FURIA_IF_XFI) { 1925 if (*ref_clk == phymodRefClk125Mhz) { 1926 *speed = ( mode_11p25g == 1)? SPEED_11P25G : SPEED_11P5G; 1927 } else { 1928 *speed = SPEED_10G; 1929 } 1930 *intf = phymodInterfaceXFI; 1931 } else if (saved_intf == FURIA_IF_XLAUI) { 1932 if( nototn_mode_pll_140 && !higig_mode){ 1933 *speed =(saved_refclk == FURIA_CLK_159) ? ((saved_intf1e2e==0)? SPEED_44P57G : SPEED_44P583G) : SPEED_43G; 1934 otn_type = (saved_intf1e2e==0) ? phymodOTNOTU3 : phymodOTNOTU3e2 ; 1935 }else{ 1936 if (*ref_clk == phymodRefClk168Mhz || *ref_clk == phymodRefClk161Mhz) { 1937 *speed = SPEED_43G; 1938 otn_type = (phymodOTNOTU3); 1939 }else{ 1940 *speed = SPEED_40G; 1941 } 1942 } 1943 *intf = phymodInterfaceXLAUI; 1944 } 1945 break; 1946 1947 case FURIA_LINKTYPE_F:/*mixed mode. ok !*/ 1948 if (*ref_clk == phymodRefClk174Mhz || *ref_clk == phymodRefClk168Mhz) { 1949 *speed = SPEED_111G; 1950 otn_type = (phymodOTNOTU4); 1951 }else if (*ref_clk == phymodRefClk106Mhz) { /*FC32*/ 1952 *speed = ( SPEED_28P05G ); 1953 /* *interface_modes = PHYMOD_INTF_MODES_FIBER ;*/ 1954 } else if( lane_map != 0xf){ 1955 *speed = SPEED_25G; 1956 }else{ 1957 *speed = SPEED_100G; 1958 } 1959 1960 if (saved_intf == FURIA_IF_CC) { 1961 *intf = phymodInterfaceCAUI4_C2C; 1962 } else if (saved_intf == FURIA_IF_CM) { 1963 *intf = phymodInterfaceCAUI4_C2M; 1964 } else if(saved_intf == FURIA_IF_CAUI4) { 1965 *intf = phymodInterfaceCAUI4; 1966 } else if(saved_intf == FURIA_IF_CAUI) { 1967 *intf = phymodInterfaceCAUI; 1968 } 1969 default: 1970 break; 1971 } 1972 break; 1973 case FURIA_PHYTYPE_FC: 1974 *intf = phymodInterfaceSR; 1975 *interface_modes = PHYMOD_INTF_MODES_FIBER; 1976 switch (link_type) { 1977 case FURIA_LINKTYPE_2: 1978 *speed = SPEED_8P5G; 1979 break; 1980 case FURIA_LINKTYPE_3: 1981 *speed = (saved_refclk == FURIA_CLK_159) ? SPEED_10P518G : SPEED_14P025G; 1982 break; 1983 case FURIA_LINKTYPE_4: 1984 *speed = SPEED_28P05G; 1985 break; 1986 default: 1987 break; 1988 } 1989 break; 1990 case FURIA_PHYTYPE_OTN: 1991 *intf = phymodInterfaceOTN; 1992 switch (link_type) { 1993 case FURIA_LINKTYPE_1: 1994 *speed = SPEED_11G; 1995 switch (saved_intf1e2e) { 1996 case 0: 1997 otn_type = (phymodOTNOTU1e);/*or 1e */ 1998 *ref_clk = phymodRefClk157Mhz; 1999 break; 2000 case 1: 2001 otn_type = (phymodOTNOTU2e);/*or 2e */ 2002 *ref_clk = phymodRefClk158Mhz; 2003 break; 2004 default: 2005 otn_type = (phymodOTNOTU2e);/*or 2e */ 2006 *ref_clk = phymodRefClk158Mhz; 2007 break; 2008 } 2009 2010 break; 2011 case FURIA_LINKTYPE_2: 2012 switch (saved_intf1e2e) { 2013 case 0: 2014 otn_type = (phymodOTNOTU3); 2015 *speed = SPEED_44P57G; 2016 break; 2017 case 1: 2018 otn_type = (phymodOTNOTU3e2); 2019 *speed = SPEED_44P583G; 2020 break; 2021 default: 2022 break; 2023 } 2024 *speed = ( saved_refclk == FURIA_CLK_159 ) ? *speed : SPEED_43G; 2025 otn_type = ( saved_refclk == FURIA_CLK_159 ) ? otn_type : (phymodOTNOTU3);/*OTN3.4 */ 2026 break; 2027 case FURIA_LINKTYPE_3: 2028 *speed = SPEED_111G;/*OTU 4.4*/ 2029 otn_type = (phymodOTNOTU4);/*OTN4.4 */ 2030 break; 2031 case FURIA_LINKTYPE_4: 2032 *speed = SPEED_100G; 2033 break; 2034 default: 2035 break; 2036 } 2037 break; 2038 2039 case FURIA_PHYTYPE_PROP: 2040 switch(link_type) { 2041 case FURIA_LINKTYPE_5: 2042 *speed = SPEED_6G; 2043 *intf = phymodInterfaceSR; 2044 break; 2045 case FURIA_LINKTYPE_3: 2046 *speed = SPEED_25G; 2047 *intf = phymodInterfaceVSR; 2048 break; 2049 default: 2050 break; 2051 } 2052 default: 2053 break; 2054 } 2055 2056 switch(saved_refclk){ 2057 case FURIA_CLK_125: 2058 *ref_clk = phymodRefClk125Mhz; 2059 break; 2060 case FURIA_CLK_106: 2061 *ref_clk = phymodRefClk106Mhz; 2062 break; 2063 case FURIA_CLK_157: 2064 *ref_clk = phymodRefClk157Mhz; 2065 break; 2066 case FURIA_CLK_158: 2067 *ref_clk = phymodRefClk158Mhz; 2068 break; 2069 case FURIA_CLK_161: 2070 *ref_clk = phymodRefClk161Mhz; 2071 break; 2072 case FURIA_CLK_168: 2073 *ref_clk = phymodRefClk168Mhz; 2074 break; 2075 case FURIA_CLK_174: 2076 *ref_clk = phymodRefClk174Mhz; 2077 break; 2078 case FURIA_CLK_159: 2079 *ref_clk = phymodRefClk159Mhz; 2080 break; 2081 default: 2082 if(!( mode_FC10 || mode_FC32)){ 2083 *ref_clk = phymodRefClk156Mhz; 2084 } 2085 break; 2086 } 2087 2088 2089 if (pkg_side == SIDE_B) { 2090 PHYMOD_IF_ERR_RETURN 2091 (READ_FURIA_PMA_PMD_REG(pa,\ 2092 FUR_GEN_CNTRLS_gpreg13_Adr,\ 2093 &gen_ctrl_gpreg13.data)); 2094 switch (gen_ctrl_gpreg13.fields.phy_type_sys) { 2095 case 0: 2096 switch (*speed) { 2097 case SPEED_10G: 2098 case SPEED_11G: 2099 case SPEED_11P25G: 2100 case SPEED_20G: 2101 case SPEED_23G: 2102 case SPEED_25G: 2103 case SPEED_50G: 2104 case SPEED_12P5G: 2105 if (*ref_clk == phymodRefClk168Mhz) { 2106 *intf = phymodInterfaceXFI; 2107 }else { 2108 *intf = phymodInterfaceKR; 2109 break; 2110 case SPEED_40G: 2111 case SPEED_43G: 2112 case SPEED_100G: 2113 case SPEED_111G: 2114 *intf = phymodInterfaceKR4; 2115 if (*ref_clk == phymodRefClk174Mhz) { 2116 *intf = phymodInterfaceOTN; 2117 }else if (*ref_clk == phymodRefClk168Mhz) { 2118 *intf = phymodInterfaceCAUI4_C2C; 2119 } 2120 break; 2121 } 2122 break; 2123 case 1: 2124 switch (*speed) { 2125 case SPEED_10G: 2126 case SPEED_11G: 2127 case SPEED_11P25G: 2128 case SPEED_10P7G: 2129 case SPEED_11P18G: 2130 case SPEED_8P5G: 2131 case SPEED_14P025G: 2132 case SPEED_9P95G: 2133 case SPEED_10P518G:/*FC10*/ 2134 case SPEED_12P5G: 2135 *intf = phymodInterfaceXFI; 2136 break; 2137 case SPEED_23G: 2138 case SPEED_25G: 2139 *intf = phymodInterfaceCAUI; 2140 break; 2141 case SPEED_40G: 2142 case SPEED_42G: 2143 case SPEED_43G: 2144 case SPEED_44P57G: 2145 case SPEED_44P583G: 2146 *intf = phymodInterfaceXLAUI; 2147 break; 2148 case SPEED_28P05G: 2149 case SPEED_100G: 2150 case SPEED_106G: 2151 case SPEED_111G: 2152 *intf = phymodInterfaceCAUI4_C2C; 2153 break; 2154 } 2155 break; 2156 } 2157 } 2158 } 2159 2160 2161 switch (curr_pll_mode[0] & curr_pll_mode[1]) { 2162 case PLL_MODE_175: 2163 case PLL_MODE_140: 2164 if(!( *speed == SPEED_43G || *speed == SPEED_44P57G || *speed == SPEED_44P583G ||( *ref_clk == phymodRefClk157Mhz) || ( *ref_clk == phymodRefClk158Mhz)) ){ 2165 *interface_modes = 1; 2166 }else if( higig_mode){ 2167 *interface_modes = 1; 2168 } 2169 break; 2170 default: 2171 break; 2172 } 2173 2174 if (config->device_aux_modes != NULL) { 2175 ((FURIA_DEVICE_OTN_MODE_T*) config->device_aux_modes)->otn_type = otn_type ; 2176 } 2177 2178 return PHYMOD_E_NONE; 2179 } 2180 2181 2182 /** Config PLL divider 2183 * This function is used to configure PLL divider 2184 * 2185 * @param pa Pointer to phymod access structure 2186 * @param pll_mode PLL mode 2187 * @param ref_clk_freq Ref clk freq type 2188 * 2189 * @return PHYMOD_E_NONE successful function execution 2190 */ 2191 int _furia_config_pll_div(const phymod_access_t *pa, uint16_t pll_mode) 2192 { 2193 int wr_lane = 0; 2194 int sys_en = 0; 2195 int rd_lane = 0; 2196 int side_index = 0; 2197 for(side_index = 0; side_index < 2; side_index ++) { 2198 /* Set PLL div */ 2199 wr_lane = 1 << 0; 2200 rd_lane = 0; 2201 if(side_index == 0) { 2202 sys_en = SIDE_A; 2203 } else { 2204 sys_en = SIDE_B; 2205 } 2206 /* Program the slice register */ 2207 PHYMOD_IF_ERR_RETURN 2208 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 2209 2210 falcon_furia_core_pwrdn(pa,PWRDN); 2211 /* Program pll_mode */ 2212 falcon_furia_configure_pll(pa,pll_mode); 2213 falcon_furia_core_pwrdn(pa,PWR_ON); 2214 } 2215 /* Set the slice register with default values */ 2216 PHYMOD_IF_ERR_RETURN 2217 (WRITE_FURIA_SLICE_REG(pa, 0, 1, 0)); 2218 return PHYMOD_E_NONE; 2219 } 2220 2221 /** Set Tx Rx polarity 2222 * This function is used to set Tx Rx polarity of a single lane 2223 * or multiple lanes 2224 * 2225 * @param pa Pointer to phymod access structure 2226 * @param tx_polarity Tx polarity 2227 * @param rx_polarity Rx polarity 2228 * 2229 * @return PHYMOD_E_NONE successful function execution 2230 */ 2231 int furia_tx_rx_polarity_set (const phymod_access_t *pa, uint32_t tx_polarity, uint32_t rx_polarity) 2232 { 2233 int lane_map = 0; 2234 int pkg_side = 0; 2235 int wr_lane = 0; 2236 int sys_en = 0; 2237 int rd_lane = 0; 2238 uint32_t chip_id = 0; 2239 int num_lanes = 0; 2240 int lane_index = 0; 2241 uint32_t acc_flags = 0; 2242 const FURIA_PKG_LANE_CFG_t* tx_pkg_ln_des = NULL; 2243 const FURIA_PKG_LANE_CFG_t* rx_pkg_ln_des = NULL; 2244 TLB_RX_TLB_RX_MISC_CONFIG_t rx_misc_config; 2245 TLB_TX_TLB_TX_MISC_CONFIG_t tx_misc_config; 2246 PHYMOD_MEMSET(&rx_misc_config, 0 , sizeof(TLB_RX_TLB_RX_MISC_CONFIG_t)); 2247 PHYMOD_MEMSET(&tx_misc_config, 0 , sizeof(TLB_TX_TLB_TX_MISC_CONFIG_t)); 2248 2249 /* Get the lane map from phymod access */ 2250 lane_map = PHYMOD_ACC_LANE_MASK(pa); 2251 acc_flags = PHYMOD_ACC_FLAGS(pa); 2252 FURIA_GET_IF_SIDE(acc_flags, pkg_side); 2253 2254 /* Get the chip id */ 2255 chip_id = _furia_get_chip_id(pa); 2256 FURIA_GET_NUM_LANES(chip_id, num_lanes); 2257 2258 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 2259 if (((lane_map >> lane_index) & 1) == 0x1) { 2260 if (FURIA_IF_TX_SIDE(chip_id, pkg_side)) { 2261 tx_pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 0); 2262 PHYMOD_NULL_CHECK(tx_pkg_ln_des); 2263 wr_lane = FURIA_IF_BCAST_SET(chip_id, lane_map) ? BROADCAST : tx_pkg_ln_des->slice_wr_val; 2264 rd_lane = tx_pkg_ln_des->slice_rd_val; 2265 if(pkg_side == SIDE_A) { 2266 sys_en = tx_pkg_ln_des->sideA; 2267 } else { 2268 sys_en = tx_pkg_ln_des->sideB; 2269 } 2270 2271 /* Program the slice register */ 2272 PHYMOD_IF_ERR_RETURN 2273 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 2274 2275 /* Read Tx misc config register */ 2276 PHYMOD_IF_ERR_RETURN 2277 (READ_FURIA_PMA_PMD_REG(pa,\ 2278 TLB_TX_tlb_tx_misc_config_Adr,\ 2279 &tx_misc_config.data)); 2280 2281 /* Update bit fields for polarity inversion */ 2282 tx_misc_config.fields.tx_pmd_dp_invert = tx_polarity; 2283 2284 /* Write to Tx misc config register */ 2285 PHYMOD_IF_ERR_RETURN 2286 (WRITE_FURIA_PMA_PMD_REG(pa,\ 2287 TLB_TX_tlb_tx_misc_config_Adr,\ 2288 tx_misc_config.data)); 2289 } 2290 if (FURIA_IF_RX_SIDE(chip_id, pkg_side)) { 2291 rx_pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 1); 2292 PHYMOD_NULL_CHECK(rx_pkg_ln_des); 2293 wr_lane = FURIA_IF_BCAST_SET(chip_id, lane_map) ? BROADCAST : rx_pkg_ln_des->slice_wr_val; 2294 rd_lane = rx_pkg_ln_des->slice_rd_val; 2295 if(pkg_side == SIDE_A) { 2296 sys_en = rx_pkg_ln_des->sideA; 2297 } else { 2298 sys_en = rx_pkg_ln_des->sideB; 2299 } 2300 2301 /* Program the slice register */ 2302 PHYMOD_IF_ERR_RETURN 2303 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 2304 /* Read Rx misc config register */ 2305 PHYMOD_IF_ERR_RETURN 2306 (READ_FURIA_PMA_PMD_REG(pa,\ 2307 TLB_RX_tlb_rx_misc_config_Adr,\ 2308 &rx_misc_config.data)); 2309 2310 /* Update bit fields for polarity inversion */ 2311 rx_misc_config.fields.rx_pmd_dp_invert = rx_polarity; 2312 2313 /* Write to Rx misc config register */ 2314 PHYMOD_IF_ERR_RETURN 2315 (WRITE_FURIA_PMA_PMD_REG(pa,\ 2316 TLB_RX_tlb_rx_misc_config_Adr,\ 2317 rx_misc_config.data)); 2318 } 2319 if (FURIA_IF_BCAST_SET(chip_id, lane_map)) { 2320 break; 2321 } 2322 } 2323 } 2324 /* Set the slice register with default values */ 2325 PHYMOD_IF_ERR_RETURN 2326 (WRITE_FURIA_SLICE_REG(pa, 0, 1, 0)); 2327 2328 return PHYMOD_E_NONE; 2329 } 2330 2331 /** Get Tx Rx polarity 2332 * This function is used to get Tx Rx polarity of a specific lane 2333 * specified by user 2334 * 2335 * @param pa Pointer to phymod access structure 2336 * @param tx_polarity Tx polarity 2337 * @param rx_polarity Rx polarity 2338 * 2339 * @return PHYMOD_E_NONE successful function execution 2340 */ 2341 int furia_tx_rx_polarity_get (const phymod_access_t *pa, uint32_t *tx_polarity, uint32_t *rx_polarity) 2342 { 2343 int lane_map = 0; 2344 int pkg_side = 0; 2345 int wr_lane = 0; 2346 int sys_en = 0; 2347 int rd_lane = 0; 2348 uint32_t chip_id = 0; 2349 int num_lanes = 0; 2350 int lane_index = 0; 2351 uint32_t acc_flags = 0; 2352 const FURIA_PKG_LANE_CFG_t* tx_pkg_ln_des = NULL; 2353 const FURIA_PKG_LANE_CFG_t* rx_pkg_ln_des = NULL; 2354 TLB_RX_TLB_RX_MISC_CONFIG_t rx_misc_config; 2355 TLB_TX_TLB_TX_MISC_CONFIG_t tx_misc_config; 2356 PHYMOD_MEMSET(&rx_misc_config, 0 , sizeof(TLB_RX_TLB_RX_MISC_CONFIG_t)); 2357 PHYMOD_MEMSET(&tx_misc_config, 0 , sizeof(TLB_TX_TLB_TX_MISC_CONFIG_t)); 2358 2359 /* Get the lane map from phymod access */ 2360 lane_map = PHYMOD_ACC_LANE_MASK(pa); 2361 acc_flags = PHYMOD_ACC_FLAGS(pa); 2362 FURIA_GET_IF_SIDE(acc_flags, pkg_side); 2363 2364 *tx_polarity = 0; 2365 *rx_polarity = 0; 2366 2367 /* Get the chip id */ 2368 chip_id = _furia_get_chip_id(pa); 2369 FURIA_GET_NUM_LANES(chip_id, num_lanes); 2370 2371 2372 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 2373 if (((lane_map >> lane_index) & 1) == 0x1) { 2374 if (FURIA_IF_TX_SIDE(chip_id, pkg_side)) { 2375 tx_pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 0); 2376 PHYMOD_NULL_CHECK(tx_pkg_ln_des); 2377 wr_lane = tx_pkg_ln_des->slice_wr_val; 2378 rd_lane = tx_pkg_ln_des->slice_rd_val; 2379 if(pkg_side == SIDE_A) { 2380 sys_en = tx_pkg_ln_des->sideA; 2381 } else { 2382 sys_en = tx_pkg_ln_des->sideB; 2383 } 2384 2385 /* Program the slice register */ 2386 PHYMOD_IF_ERR_RETURN 2387 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 2388 /* Read Tx misc config register */ 2389 PHYMOD_IF_ERR_RETURN 2390 (READ_FURIA_PMA_PMD_REG(pa,\ 2391 TLB_TX_tlb_tx_misc_config_Adr,\ 2392 &tx_misc_config.data)); 2393 2394 /* Update bit fields for polarity inversion */ 2395 *tx_polarity = tx_misc_config.fields.tx_pmd_dp_invert ; 2396 } 2397 if (FURIA_IF_RX_SIDE(chip_id, pkg_side)) { 2398 rx_pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 1); 2399 PHYMOD_NULL_CHECK(rx_pkg_ln_des); 2400 wr_lane = rx_pkg_ln_des->slice_wr_val; 2401 rd_lane = rx_pkg_ln_des->slice_rd_val; 2402 if(pkg_side == SIDE_A) { 2403 sys_en = rx_pkg_ln_des->sideA; 2404 } else { 2405 sys_en = rx_pkg_ln_des->sideB; 2406 } 2407 2408 /* Program the slice register */ 2409 PHYMOD_IF_ERR_RETURN 2410 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 2411 /* Read Rx misc config register */ 2412 PHYMOD_IF_ERR_RETURN 2413 (READ_FURIA_PMA_PMD_REG(pa,\ 2414 TLB_RX_tlb_rx_misc_config_Adr,\ 2415 &rx_misc_config.data)); 2416 2417 /* Update bit fields for polarity inversion */ 2418 *rx_polarity = rx_misc_config.fields.rx_pmd_dp_invert; 2419 } 2420 break; 2421 } 2422 } 2423 /* Set the slice register with default values */ 2424 PHYMOD_IF_ERR_RETURN 2425 (WRITE_FURIA_SLICE_REG(pa, 0, 1, 0)); 2426 2427 return PHYMOD_E_NONE; 2428 } 2429 2430 /** PMD lock get 2431 * 2432 * @param pa Pointer to phymod access structure 2433 * @param rx_seq_done RX sew done status 2434 * 2435 * @return PHYMOD_E_NONE successful function execution 2436 */ 2437 int furia_pmd_lock_get(const phymod_access_t *pa, uint32_t *rx_seq_done) 2438 { 2439 int lane_map = 0; 2440 int pkg_side = 0; 2441 int wr_lane = 0; 2442 int sys_en = 0; 2443 int rd_lane = 0; 2444 uint32_t chip_id = 0; 2445 int num_lanes = 0; 2446 int lane_index = 0; 2447 uint8_t rx_pmd_lock = 1; 2448 uint32_t acc_flags = 0; 2449 const FURIA_PKG_LANE_CFG_t* pkg_ln_des = NULL; 2450 *rx_seq_done = 1; 2451 /* Get the lane map from phymod access */ 2452 lane_map = PHYMOD_ACC_LANE_MASK(pa); 2453 acc_flags = PHYMOD_ACC_FLAGS(pa); 2454 FURIA_GET_IF_SIDE(acc_flags, pkg_side); 2455 2456 /* Get the chip id */ 2457 chip_id = _furia_get_chip_id(pa); 2458 2459 FURIA_GET_NUM_LANES(chip_id, num_lanes); 2460 2461 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 2462 if (((lane_map >> lane_index) & 1) == 0x1) { 2463 pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 0); 2464 PHYMOD_NULL_CHECK(pkg_ln_des); 2465 /* Get sys_en, wr_lane, rd_lane using lane descriptor */ 2466 wr_lane = pkg_ln_des->slice_wr_val; 2467 rd_lane = pkg_ln_des->slice_rd_val; 2468 if(pkg_side == SIDE_A) { 2469 sys_en = pkg_ln_des->sideA; 2470 } else { 2471 sys_en = pkg_ln_des->sideB; 2472 } 2473 /* Program the slice register */ 2474 PHYMOD_IF_ERR_RETURN 2475 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 2476 2477 if (FURIA_IF_RX_SIDE(chip_id, pkg_side)) { 2478 PHYMOD_IF_ERR_RETURN 2479 (falcon_furia_pmd_lock_status(pa, &rx_pmd_lock)); 2480 *rx_seq_done &= rx_pmd_lock; 2481 } 2482 } 2483 } 2484 /* Set the slice register with default values */ 2485 PHYMOD_IF_ERR_RETURN 2486 (WRITE_FURIA_SLICE_REG(pa, 0, 1, 0)); 2487 return PHYMOD_E_NONE; 2488 } 2489 2490 2491 /** Tx Rx power get 2492 * 2493 * 2494 * @param pa Pointer to phymod access structure 2495 * @param power_tx TX Power 2496 * @param power_rx RX Power 2497 * 2498 * @return PHYMOD_E_NONE successful function execution 2499 */ 2500 int furia_tx_rx_power_get(const phymod_access_t *pa, uint32_t *power_tx, uint32_t *power_rx) 2501 { 2502 int lane_map = 0; 2503 int pkg_side = 0; 2504 int wr_lane = 0; 2505 int sys_en = 0; 2506 int rd_lane = 0; 2507 uint32_t chip_id = 0; 2508 int num_lanes = 0; 2509 int lane_index = 0; 2510 const FURIA_PKG_LANE_CFG_t* tx_pkg_ln_des = NULL; 2511 const FURIA_PKG_LANE_CFG_t* rx_pkg_ln_des = NULL; 2512 CKRST_CTRL_RPTR_LANE_CLK_RESET_N_POWERDOWN_CONTROL_t rst_pwdn_ctrl; 2513 uint32_t acc_flags = 0; 2514 *power_tx = 0; 2515 *power_rx = 0; 2516 PHYMOD_MEMSET(&rst_pwdn_ctrl, 0 , sizeof(CKRST_CTRL_RPTR_LANE_CLK_RESET_N_POWERDOWN_CONTROL_t)); 2517 2518 /* Get the lane map from phymod access */ 2519 lane_map = PHYMOD_ACC_LANE_MASK(pa); 2520 acc_flags = PHYMOD_ACC_FLAGS(pa); 2521 FURIA_GET_IF_SIDE(acc_flags, pkg_side); 2522 /* Get the chip id */ 2523 chip_id = _furia_get_chip_id(pa); 2524 FURIA_GET_NUM_LANES(chip_id, num_lanes); 2525 2526 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 2527 if (((lane_map >> lane_index) & 1) == 0x1) { 2528 if (FURIA_IF_RX_SIDE(chip_id, pkg_side)) { 2529 rx_pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 1); 2530 PHYMOD_NULL_CHECK(rx_pkg_ln_des); 2531 wr_lane = rx_pkg_ln_des->slice_wr_val; 2532 rd_lane = rx_pkg_ln_des->slice_rd_val; 2533 if(pkg_side == SIDE_A) { 2534 sys_en = rx_pkg_ln_des->sideA; 2535 } else { 2536 sys_en = rx_pkg_ln_des->sideB; 2537 } 2538 2539 /* Program the slice register */ 2540 PHYMOD_IF_ERR_RETURN 2541 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 2542 PHYMOD_IF_ERR_RETURN 2543 (READ_FURIA_PMA_PMD_REG(pa,\ 2544 CKRST_CTRL_RPTR_LANE_CLK_RESET_N_POWERDOWN_CONTROL_Adr,\ 2545 &rst_pwdn_ctrl.data)); 2546 *power_rx = rst_pwdn_ctrl.fields.ln_rx_s_pwrdn ? 0 : 1; 2547 } 2548 if (FURIA_IF_TX_SIDE(chip_id, pkg_side)) { 2549 tx_pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 0); 2550 PHYMOD_NULL_CHECK(tx_pkg_ln_des); 2551 wr_lane = tx_pkg_ln_des->slice_wr_val; 2552 rd_lane = tx_pkg_ln_des->slice_rd_val; 2553 if(pkg_side == SIDE_A) { 2554 sys_en = tx_pkg_ln_des->sideA; 2555 } else { 2556 sys_en = tx_pkg_ln_des->sideB; 2557 } 2558 2559 /* Program the slice register */ 2560 PHYMOD_IF_ERR_RETURN 2561 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 2562 PHYMOD_IF_ERR_RETURN 2563 (READ_FURIA_PMA_PMD_REG(pa,\ 2564 CKRST_CTRL_RPTR_LANE_CLK_RESET_N_POWERDOWN_CONTROL_Adr,\ 2565 &rst_pwdn_ctrl.data)); 2566 *power_tx = rst_pwdn_ctrl.fields.ln_tx_s_pwrdn ? 0 : 1 ; 2567 } 2568 break; 2569 } 2570 } 2571 /* Set the slice register with default values */ 2572 PHYMOD_IF_ERR_RETURN 2573 (WRITE_FURIA_SLICE_REG(pa, 0, 1, 0)); 2574 return PHYMOD_E_NONE; 2575 } 2576 2577 2578 /** Rx Power Set 2579 * 2580 * 2581 * @param pa Pointer to phymod access structure 2582 * @param tx_rx TX_RX Value 2583 * @param enable Set 1 to enable 2584 * 2585 * @return PHYMOD_E_NONE successful function execution 2586 */ 2587 int furia_tx_rx_power_set(const phymod_access_t *pa, uint8_t tx_rx, uint32_t enable) 2588 { 2589 int lane_map = 0; 2590 int pkg_side = 0; 2591 int wr_lane = 0; 2592 int sys_en = 0; 2593 int rd_lane = 0; 2594 uint32_t chip_id = 0; 2595 int num_lanes = 0; 2596 int lane_index = 0; 2597 const FURIA_PKG_LANE_CFG_t* tx_pkg_ln_des = NULL; 2598 const FURIA_PKG_LANE_CFG_t* rx_pkg_ln_des = NULL; 2599 CKRST_CTRL_RPTR_LANE_CLK_RESET_N_POWERDOWN_CONTROL_t rst_pwdn_ctrl; 2600 uint32_t acc_flags = 0; 2601 PHYMOD_MEMSET(&rst_pwdn_ctrl, 0 , sizeof(CKRST_CTRL_RPTR_LANE_CLK_RESET_N_POWERDOWN_CONTROL_t)); 2602 2603 /* Get the lane map from phymod access */ 2604 lane_map = PHYMOD_ACC_LANE_MASK(pa); 2605 acc_flags = PHYMOD_ACC_FLAGS(pa); 2606 FURIA_GET_IF_SIDE(acc_flags, pkg_side); 2607 /* Get the chip id */ 2608 chip_id = _furia_get_chip_id(pa); 2609 FURIA_GET_NUM_LANES(chip_id, num_lanes); 2610 2611 enable = enable ? 0 : 1; 2612 2613 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 2614 if (((lane_map >> lane_index) & 1) == 0x1) { 2615 if (FURIA_IF_TX_SIDE(chip_id, pkg_side)) { 2616 tx_pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 0); 2617 PHYMOD_NULL_CHECK(tx_pkg_ln_des); 2618 wr_lane = FURIA_IF_BCAST_SET(chip_id, lane_map) ? BROADCAST : tx_pkg_ln_des->slice_wr_val; 2619 rd_lane = tx_pkg_ln_des->slice_rd_val; 2620 if(pkg_side == SIDE_A) { 2621 sys_en = tx_pkg_ln_des->sideA; 2622 } else { 2623 sys_en = tx_pkg_ln_des->sideB; 2624 } 2625 2626 /* Program the slice register */ 2627 PHYMOD_IF_ERR_RETURN 2628 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 2629 /* power down Tx*/ 2630 if(!tx_rx) { 2631 PHYMOD_IF_ERR_RETURN 2632 (READ_FURIA_PMA_PMD_REG(pa,\ 2633 CKRST_CTRL_RPTR_LANE_CLK_RESET_N_POWERDOWN_CONTROL_Adr,\ 2634 &rst_pwdn_ctrl.data)); 2635 rst_pwdn_ctrl.fields.ln_tx_s_pwrdn = enable; 2636 2637 PHYMOD_IF_ERR_RETURN 2638 (WRITE_FURIA_PMA_PMD_REG(pa,\ 2639 CKRST_CTRL_RPTR_LANE_CLK_RESET_N_POWERDOWN_CONTROL_Adr,\ 2640 rst_pwdn_ctrl.data)); 2641 } 2642 } 2643 if (FURIA_IF_RX_SIDE(chip_id, pkg_side)) { 2644 rx_pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 1); 2645 PHYMOD_NULL_CHECK(rx_pkg_ln_des); 2646 wr_lane = FURIA_IF_BCAST_SET(chip_id, lane_map) ? BROADCAST : rx_pkg_ln_des->slice_wr_val; 2647 rd_lane = rx_pkg_ln_des->slice_rd_val; 2648 if(pkg_side == SIDE_A) { 2649 sys_en = rx_pkg_ln_des->sideA; 2650 } else { 2651 sys_en = rx_pkg_ln_des->sideB; 2652 } 2653 2654 /* Program the slice register */ 2655 PHYMOD_IF_ERR_RETURN 2656 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 2657 if(tx_rx) { 2658 PHYMOD_IF_ERR_RETURN 2659 (READ_FURIA_PMA_PMD_REG(pa,\ 2660 CKRST_CTRL_RPTR_LANE_CLK_RESET_N_POWERDOWN_CONTROL_Adr,\ 2661 &rst_pwdn_ctrl.data)); 2662 rst_pwdn_ctrl.fields.ln_rx_s_pwrdn = enable; 2663 2664 PHYMOD_IF_ERR_RETURN 2665 (WRITE_FURIA_PMA_PMD_REG(pa,\ 2666 CKRST_CTRL_RPTR_LANE_CLK_RESET_N_POWERDOWN_CONTROL_Adr,\ 2667 rst_pwdn_ctrl.data)); 2668 } 2669 } 2670 if (FURIA_IF_BCAST_SET(chip_id, lane_map)) { 2671 break; 2672 } 2673 } 2674 } 2675 /* Set the slice register with default values */ 2676 PHYMOD_IF_ERR_RETURN 2677 (WRITE_FURIA_SLICE_REG(pa, 0, 1, 0)); 2678 return PHYMOD_E_NONE; 2679 } 2680 int furia_loopback_set(const phymod_access_t *pa, 2681 phymod_loopback_mode_t loopback, 2682 uint32_t enable) 2683 { 2684 int lane_map = 0; 2685 int pkg_side = 0; 2686 int wr_lane = 0; 2687 int sys_en = 0; 2688 int other_pkg_side = 0; 2689 int other_side_wr_lane = 0; 2690 int other_side_sys_en = 0; 2691 int rd_lane = 0; 2692 int other_side_rd_lane = 0; 2693 uint32_t chip_id = 0; 2694 int num_lanes = 0; 2695 int lane_index = 0; 2696 const FURIA_PKG_LANE_CFG_t* pkg_ln_des = NULL; 2697 const FURIA_PKG_LANE_CFG_t* other_side_pkg_ln_des = NULL; 2698 uint32_t acc_flags = 0; 2699 int retry_count = 40; 2700 DSC_C_RX_PI_CONTROL_t pi_ctrl; 2701 DSC_C_CDR_CONTROL_2_t cd_ctrl_2; 2702 TX_PI_RPTR_TX_PI_CONTROL_0_t pi_ctrl_0; 2703 TX_PI_RPTR_TX_PI_CONTROL_5_t pi_ctrl_5; 2704 TLB_RX_DIG_LPBK_CONFIG_t dig_lpbk_cfg; 2705 FUR_GEN_CNTRLS_FIRMWARE_ENABLE_t fw_enable; 2706 phymod_access_t l_pa; 2707 PHYMOD_MEMSET(&pi_ctrl, 0 , sizeof(DSC_C_RX_PI_CONTROL_t)); 2708 PHYMOD_MEMSET(&cd_ctrl_2, 0 , sizeof(DSC_C_CDR_CONTROL_2_t)); 2709 PHYMOD_MEMSET(&pi_ctrl_0, 0 , sizeof(TX_PI_RPTR_TX_PI_CONTROL_0_t)); 2710 PHYMOD_MEMSET(&pi_ctrl_5, 0 , sizeof(TX_PI_RPTR_TX_PI_CONTROL_5_t)); 2711 PHYMOD_MEMSET(&dig_lpbk_cfg, 0 , sizeof(TLB_RX_DIG_LPBK_CONFIG_t)); 2712 PHYMOD_MEMSET(&fw_enable, 0 , sizeof(FUR_GEN_CNTRLS_FIRMWARE_ENABLE_t)); 2713 PHYMOD_MEMCPY(&l_pa, pa, sizeof(phymod_access_t)); 2714 /* Get the lane map from phymod access */ 2715 lane_map = PHYMOD_ACC_LANE_MASK(pa); 2716 acc_flags = PHYMOD_ACC_FLAGS(pa); 2717 FURIA_GET_IF_SIDE(acc_flags, pkg_side); 2718 /* Get the chip id */ 2719 chip_id = _furia_get_chip_id(pa); 2720 FURIA_GET_NUM_LANES(chip_id, num_lanes); 2721 2722 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 2723 if (((lane_map >> lane_index) & 1) == 0x1) { 2724 /* Configure Tx side(SIDE_A) first*/ 2725 pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 1); 2726 PHYMOD_NULL_CHECK(pkg_ln_des); 2727 if(lane_map == 0xF) { 2728 wr_lane = BROADCAST; 2729 } else { 2730 wr_lane = pkg_ln_des->slice_wr_val; 2731 } 2732 rd_lane = pkg_ln_des->slice_rd_val; 2733 if(pkg_side == SIDE_A) { 2734 sys_en = pkg_ln_des->sideA; 2735 } else { 2736 sys_en = pkg_ln_des->sideB; 2737 } 2738 other_pkg_side = (pkg_side == SIDE_A) ? SIDE_B : SIDE_A; 2739 l_pa.flags &= ~(1 << 31); 2740 if (other_pkg_side == SIDE_B) { 2741 l_pa.flags |= (1 << 31); 2742 } 2743 other_side_pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, &l_pa, lane_index, 1); 2744 PHYMOD_NULL_CHECK(other_side_pkg_ln_des); 2745 if(lane_map == 0xF) { 2746 other_side_wr_lane = BROADCAST; 2747 } else { 2748 other_side_wr_lane = other_side_pkg_ln_des->slice_wr_val; 2749 } 2750 other_side_rd_lane = other_side_pkg_ln_des->slice_rd_val; 2751 if(other_pkg_side == SIDE_A) { 2752 other_side_sys_en = other_side_pkg_ln_des->sideA; 2753 } else { 2754 other_side_sys_en = other_side_pkg_ln_des->sideB; 2755 } 2756 2757 /* Program the slice register */ 2758 PHYMOD_IF_ERR_RETURN 2759 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 2760 2761 switch (loopback) { 2762 case phymodLoopbackRemotePMD: 2763 if(enable) { 2764 PHYMOD_IF_ERR_RETURN(falcon_furia_rmt_lpbk_from_nl(pa)); 2765 } else { 2766 PHYMOD_IF_ERR_RETURN(falcon_furia_nl_from_rmt_lpbk(pa, RMT_LPBK_SIDE)); 2767 PHYMOD_IF_ERR_RETURN(wr_tx_pi_loop_timing_src_sel(1)); 2768 } 2769 break; 2770 case phymodLoopbackRemotePCS: 2771 return PHYMOD_E_UNAVAIL; 2772 break; 2773 case phymodLoopbackGlobal: 2774 case phymodLoopbackGlobalPMD: 2775 if(enable) { 2776 PHYMOD_IF_ERR_RETURN 2777 (READ_FURIA_PMA_PMD_REG(pa,\ 2778 FUR_GEN_CNTRLS_firmware_enable_Adr,\ 2779 &fw_enable.data)); 2780 2781 while(fw_enable.fields.fw_enable_val != 0 && retry_count){ 2782 PHYMOD_IF_ERR_RETURN 2783 (READ_FURIA_PMA_PMD_REG(pa,\ 2784 FUR_GEN_CNTRLS_firmware_enable_Adr,\ 2785 &fw_enable.data)); 2786 PHYMOD_USLEEP(200); 2787 retry_count--; 2788 } 2789 if(!retry_count) { 2790 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_FAIL, (_PHYMOD_MSG("Digital loopback configuration failed..."))); 2791 } 2792 2793 /* Enable digital loopback */ 2794 PHYMOD_IF_ERR_RETURN 2795 (READ_FURIA_PMA_PMD_REG(pa,\ 2796 TLB_RX_dig_lpbk_config_Adr,\ 2797 &dig_lpbk_cfg.data)); 2798 dig_lpbk_cfg.fields.dig_lpbk_en = 1; 2799 2800 PHYMOD_IF_ERR_RETURN 2801 (WRITE_FURIA_PMA_PMD_REG(pa,\ 2802 TLB_RX_dig_lpbk_config_Adr,\ 2803 dig_lpbk_cfg.data)); 2804 /* Set firmware enable */ 2805 PHYMOD_IF_ERR_RETURN 2806 (READ_FURIA_PMA_PMD_REG(pa,\ 2807 FUR_GEN_CNTRLS_firmware_enable_Adr,\ 2808 &fw_enable.data)); 2809 fw_enable.fields.fw_enable_val = 1; 2810 PHYMOD_IF_ERR_RETURN 2811 (WRITE_FURIA_PMA_PMD_REG(pa,\ 2812 FUR_GEN_CNTRLS_firmware_enable_Adr,\ 2813 fw_enable.data)); 2814 retry_count = 40; 2815 PHYMOD_IF_ERR_RETURN 2816 (READ_FURIA_PMA_PMD_REG(pa,\ 2817 FUR_GEN_CNTRLS_firmware_enable_Adr,\ 2818 &fw_enable.data)); 2819 while(fw_enable.fields.fw_enable_val != 0 && retry_count){ 2820 PHYMOD_IF_ERR_RETURN 2821 (READ_FURIA_PMA_PMD_REG(pa,\ 2822 FUR_GEN_CNTRLS_firmware_enable_Adr,\ 2823 &fw_enable.data)); 2824 PHYMOD_USLEEP(200); 2825 retry_count--; 2826 } 2827 if(!retry_count) { 2828 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_FAIL, (_PHYMOD_MSG("Digital loopback configuration failed..."))); 2829 } 2830 /* Enable digital loopback */ 2831 PHYMOD_IF_ERR_RETURN 2832 (READ_FURIA_PMA_PMD_REG(pa,\ 2833 TLB_RX_dig_lpbk_config_Adr,\ 2834 &dig_lpbk_cfg.data)); 2835 dig_lpbk_cfg.fields.dig_lpbk_en = 1; 2836 2837 PHYMOD_IF_ERR_RETURN 2838 (WRITE_FURIA_PMA_PMD_REG(pa,\ 2839 TLB_RX_dig_lpbk_config_Adr,\ 2840 dig_lpbk_cfg.data)); 2841 } else { 2842 retry_count = 40; 2843 PHYMOD_IF_ERR_RETURN 2844 (READ_FURIA_PMA_PMD_REG(pa,\ 2845 FUR_GEN_CNTRLS_firmware_enable_Adr,\ 2846 &fw_enable.data)); 2847 while(fw_enable.fields.fw_enable_val != 0 && retry_count){ 2848 PHYMOD_IF_ERR_RETURN 2849 (READ_FURIA_PMA_PMD_REG(pa,\ 2850 FUR_GEN_CNTRLS_firmware_enable_Adr,\ 2851 &fw_enable.data)); 2852 2853 PHYMOD_USLEEP(200); 2854 retry_count--; 2855 } 2856 if(!retry_count) { 2857 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_FAIL, (_PHYMOD_MSG("Digital loopback configuration failed..."))); 2858 } 2859 /* Program Other Falcon (one which is not doing digital loopback) */ 2860 /* Program the slice register */ 2861 PHYMOD_IF_ERR_RETURN 2862 (WRITE_FURIA_SLICE_REG(pa, other_side_sys_en, other_side_wr_lane, other_side_rd_lane)); 2863 PHYMOD_IF_ERR_RETURN 2864 (READ_FURIA_PMA_PMD_REG(pa,\ 2865 DSC_C_cdr_control_2_Adr,\ 2866 &cd_ctrl_2.data)); 2867 cd_ctrl_2.fields.tx_pi_loop_timing_src_sel = 0; 2868 2869 PHYMOD_IF_ERR_RETURN 2870 (WRITE_FURIA_PMA_PMD_REG(pa,\ 2871 DSC_C_cdr_control_2_Adr,\ 2872 cd_ctrl_2.data)); 2873 PHYMOD_IF_ERR_RETURN 2874 (READ_FURIA_PMA_PMD_REG(pa,\ 2875 TX_PI_RPTR_tx_pi_control_5_Adr,\ 2876 &pi_ctrl_5.data)); 2877 pi_ctrl_5.fields.tx_pi_repeater_mode_en = 0; 2878 2879 PHYMOD_IF_ERR_RETURN 2880 (WRITE_FURIA_PMA_PMD_REG(pa,\ 2881 TX_PI_RPTR_tx_pi_control_5_Adr,\ 2882 pi_ctrl_5.data)); 2883 PHYMOD_IF_ERR_RETURN 2884 (READ_FURIA_PMA_PMD_REG(pa,\ 2885 TX_PI_RPTR_tx_pi_control_0_Adr,\ 2886 &pi_ctrl_0.data)); 2887 pi_ctrl_0.fields.tx_pi_en = 0; 2888 pi_ctrl_0.fields.tx_pi_jitter_filter_en = 0; 2889 2890 PHYMOD_IF_ERR_RETURN 2891 (WRITE_FURIA_PMA_PMD_REG(pa,\ 2892 TX_PI_RPTR_tx_pi_control_0_Adr,\ 2893 pi_ctrl_0.data)); 2894 /* Program Falcon (one which is doing digital loopback) */ 2895 /* Program the slice register */ 2896 PHYMOD_IF_ERR_RETURN 2897 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 2898 PHYMOD_IF_ERR_RETURN 2899 (READ_FURIA_PMA_PMD_REG(pa,\ 2900 TX_PI_RPTR_tx_pi_control_5_Adr,\ 2901 &pi_ctrl_5.data)); 2902 pi_ctrl_5.fields.tx_pi_repeater_mode_en = 0; 2903 2904 PHYMOD_IF_ERR_RETURN 2905 (WRITE_FURIA_PMA_PMD_REG(pa,\ 2906 TX_PI_RPTR_tx_pi_control_5_Adr,\ 2907 pi_ctrl_5.data)); 2908 PHYMOD_IF_ERR_RETURN 2909 (READ_FURIA_PMA_PMD_REG(pa,\ 2910 TX_PI_RPTR_tx_pi_control_0_Adr,\ 2911 &pi_ctrl_0.data)); 2912 pi_ctrl_0.fields.tx_pi_en = 0; 2913 pi_ctrl_0.fields.tx_pi_jitter_filter_en = 0; 2914 2915 PHYMOD_IF_ERR_RETURN 2916 (WRITE_FURIA_PMA_PMD_REG(pa,\ 2917 TX_PI_RPTR_tx_pi_control_0_Adr,\ 2918 pi_ctrl_0.data)); 2919 PHYMOD_IF_ERR_RETURN 2920 (READ_FURIA_PMA_PMD_REG(pa,\ 2921 TLB_RX_dig_lpbk_config_Adr,\ 2922 &dig_lpbk_cfg.data)); 2923 dig_lpbk_cfg.fields.dig_lpbk_en = 0; 2924 2925 PHYMOD_IF_ERR_RETURN 2926 (WRITE_FURIA_PMA_PMD_REG(pa,\ 2927 TLB_RX_dig_lpbk_config_Adr,\ 2928 dig_lpbk_cfg.data)); 2929 /* Set firmware enable */ 2930 PHYMOD_IF_ERR_RETURN 2931 (READ_FURIA_PMA_PMD_REG(pa,\ 2932 FUR_GEN_CNTRLS_firmware_enable_Adr,\ 2933 &fw_enable.data)); 2934 fw_enable.fields.fw_enable_val = 1; 2935 PHYMOD_IF_ERR_RETURN 2936 (WRITE_FURIA_PMA_PMD_REG(pa,\ 2937 FUR_GEN_CNTRLS_firmware_enable_Adr,\ 2938 fw_enable.data)); 2939 } 2940 PHYMOD_IF_ERR_RETURN(wr_falcon_furia_sdk_tx_disable(enable)); 2941 break; 2942 default : 2943 break; 2944 } 2945 2946 } 2947 if(lane_map == 0xF) { 2948 break; 2949 } 2950 } 2951 2952 2953 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 2954 if (((lane_map >> lane_index) & 1) == 0x1) { 2955 /* Configure Tx side(SIDE_A) first*/ 2956 pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 1); 2957 PHYMOD_NULL_CHECK(pkg_ln_des); 2958 if(lane_map == 0xF) { 2959 wr_lane = BROADCAST; 2960 } else { 2961 wr_lane = pkg_ln_des->slice_wr_val; 2962 } 2963 rd_lane = pkg_ln_des->slice_rd_val; 2964 if(pkg_side == SIDE_A) { 2965 sys_en = pkg_ln_des->sideA; 2966 } else { 2967 sys_en = pkg_ln_des->sideB; 2968 } 2969 other_pkg_side = (pkg_side == SIDE_A) ? SIDE_B : SIDE_A; 2970 l_pa.flags &= ~(1 << 31); 2971 if (other_pkg_side == SIDE_B) { 2972 l_pa.flags |= (1 << 31); 2973 } 2974 other_side_pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, &l_pa, lane_index, 1); 2975 PHYMOD_NULL_CHECK(other_side_pkg_ln_des); 2976 if(lane_map == 0xF) { 2977 other_side_wr_lane = BROADCAST; 2978 } else { 2979 other_side_wr_lane = other_side_pkg_ln_des->slice_wr_val; 2980 } 2981 other_side_rd_lane = other_side_pkg_ln_des->slice_rd_val; 2982 if(other_pkg_side == SIDE_A) { 2983 other_side_sys_en = other_side_pkg_ln_des->sideA; 2984 } else { 2985 other_side_sys_en = other_side_pkg_ln_des->sideB; 2986 } 2987 2988 switch (loopback) { 2989 case phymodLoopbackRemotePMD: 2990 if(enable) { 2991 PHYMOD_IF_ERR_RETURN(falcon_furia_rmt_lpbk_from_nl(pa)); 2992 } else { 2993 PHYMOD_IF_ERR_RETURN(falcon_furia_nl_from_rmt_lpbk(pa, RMT_LPBK_SIDE)); 2994 PHYMOD_IF_ERR_RETURN(wr_tx_pi_loop_timing_src_sel(1)); 2995 } 2996 break; 2997 case phymodLoopbackRemotePCS: 2998 return PHYMOD_E_UNAVAIL; 2999 break; 3000 case phymodLoopbackGlobal: 3001 case phymodLoopbackGlobalPMD: 3002 if(enable) { 3003 /* Program Other Falcon (one which is not doing digital loopback) */ 3004 /* Program the slice register */ 3005 PHYMOD_IF_ERR_RETURN 3006 (WRITE_FURIA_SLICE_REG(pa, other_side_sys_en, other_side_wr_lane, other_side_rd_lane)); 3007 PHYMOD_IF_ERR_RETURN 3008 (READ_FURIA_PMA_PMD_REG(pa,\ 3009 DSC_C_rx_pi_control_Adr,\ 3010 &pi_ctrl.data)); 3011 pi_ctrl.fields.rx_pi_manual_mode = 0; 3012 3013 PHYMOD_IF_ERR_RETURN 3014 (WRITE_FURIA_PMA_PMD_REG(pa,\ 3015 DSC_C_rx_pi_control_Adr,\ 3016 pi_ctrl.data)); 3017 PHYMOD_IF_ERR_RETURN 3018 (READ_FURIA_PMA_PMD_REG(pa,\ 3019 DSC_C_cdr_control_2_Adr,\ 3020 &cd_ctrl_2.data)); 3021 cd_ctrl_2.fields.tx_pi_loop_timing_src_sel = 1; 3022 3023 PHYMOD_IF_ERR_RETURN 3024 (WRITE_FURIA_PMA_PMD_REG(pa,\ 3025 DSC_C_cdr_control_2_Adr,\ 3026 cd_ctrl_2.data)); 3027 PHYMOD_IF_ERR_RETURN 3028 (READ_FURIA_PMA_PMD_REG(pa,\ 3029 TX_PI_RPTR_tx_pi_control_0_Adr,\ 3030 &pi_ctrl_0.data)); 3031 pi_ctrl_0.fields.tx_pi_en = 0; 3032 pi_ctrl_0.fields.tx_pi_jitter_filter_en = 0; 3033 3034 PHYMOD_IF_ERR_RETURN 3035 (WRITE_FURIA_PMA_PMD_REG(pa,\ 3036 TX_PI_RPTR_tx_pi_control_0_Adr,\ 3037 pi_ctrl_0.data)); 3038 3039 PHYMOD_IF_ERR_RETURN 3040 (READ_FURIA_PMA_PMD_REG(pa,\ 3041 TX_PI_RPTR_tx_pi_control_5_Adr,\ 3042 &pi_ctrl_5.data)); 3043 pi_ctrl_5.fields.tx_pi_repeater_mode_en = 0; 3044 3045 PHYMOD_IF_ERR_RETURN 3046 (WRITE_FURIA_PMA_PMD_REG(pa,\ 3047 TX_PI_RPTR_tx_pi_control_5_Adr,\ 3048 pi_ctrl_5.data)); 3049 PHYMOD_IF_ERR_RETURN 3050 (READ_FURIA_PMA_PMD_REG(pa,\ 3051 TX_PI_RPTR_tx_pi_control_0_Adr,\ 3052 &pi_ctrl_0.data)); 3053 pi_ctrl_0.fields.tx_pi_en = 1; 3054 pi_ctrl_0.fields.tx_pi_jitter_filter_en = 1; 3055 3056 PHYMOD_IF_ERR_RETURN 3057 (WRITE_FURIA_PMA_PMD_REG(pa,\ 3058 TX_PI_RPTR_tx_pi_control_0_Adr,\ 3059 pi_ctrl_0.data)); 3060 3061 /* Program Falcon (one which is doing digital loopback) */ 3062 /* Program the slice register */ 3063 PHYMOD_IF_ERR_RETURN 3064 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 3065 PHYMOD_IF_ERR_RETURN 3066 (READ_FURIA_PMA_PMD_REG(pa,\ 3067 TX_PI_RPTR_tx_pi_control_5_Adr,\ 3068 &pi_ctrl_5.data)); 3069 pi_ctrl_5.fields.tx_pi_repeater_mode_en = 1; 3070 3071 PHYMOD_IF_ERR_RETURN 3072 (WRITE_FURIA_PMA_PMD_REG(pa,\ 3073 TX_PI_RPTR_tx_pi_control_5_Adr,\ 3074 pi_ctrl_5.data)); 3075 PHYMOD_IF_ERR_RETURN 3076 (READ_FURIA_PMA_PMD_REG(pa,\ 3077 TX_PI_RPTR_tx_pi_control_0_Adr,\ 3078 &pi_ctrl_0.data)); 3079 pi_ctrl_0.fields.tx_pi_en = 1; 3080 pi_ctrl_0.fields.tx_pi_jitter_filter_en = 1; 3081 3082 PHYMOD_IF_ERR_RETURN 3083 (WRITE_FURIA_PMA_PMD_REG(pa,\ 3084 TX_PI_RPTR_tx_pi_control_0_Adr,\ 3085 pi_ctrl_0.data)); 3086 3087 PHYMOD_IF_ERR_RETURN 3088 (READ_FURIA_PMA_PMD_REG(pa,\ 3089 TLB_RX_dig_lpbk_config_Adr,\ 3090 &dig_lpbk_cfg.data)); 3091 dig_lpbk_cfg.fields.dig_lpbk_en = 1; 3092 3093 PHYMOD_IF_ERR_RETURN 3094 (WRITE_FURIA_PMA_PMD_REG(pa,\ 3095 TLB_RX_dig_lpbk_config_Adr,\ 3096 dig_lpbk_cfg.data)); 3097 PHYMOD_USLEEP(50); 3098 } 3099 break; 3100 default : 3101 break; 3102 } 3103 3104 } 3105 if(lane_map == 0xF) { 3106 break; 3107 } 3108 } 3109 /* Set the slice register with default values */ 3110 PHYMOD_IF_ERR_RETURN 3111 (WRITE_FURIA_SLICE_REG(pa, 0, 1, 0)); 3112 return PHYMOD_E_NONE; 3113 } 3114 3115 int furia_loopback_get(const phymod_access_t *pa, 3116 phymod_loopback_mode_t loopback, 3117 uint32_t* enable) 3118 { 3119 int lane_map = 0; 3120 int pkg_side = 0; 3121 int wr_lane = 0; 3122 int sys_en = 0; 3123 int rd_lane = 0; 3124 uint32_t chip_id = 0; 3125 int num_lanes = 0; 3126 int lane_index = 0; 3127 uint32_t acc_flags = 0; 3128 const FURIA_PKG_LANE_CFG_t* pkg_ln_des = NULL; 3129 uint8_t ena_dis = 0; 3130 3131 /* Get the lane map from phymod access */ 3132 lane_map = PHYMOD_ACC_LANE_MASK(pa); 3133 acc_flags = PHYMOD_ACC_FLAGS(pa); 3134 FURIA_GET_IF_SIDE(acc_flags, pkg_side); 3135 3136 /* Get the chip id */ 3137 chip_id = _furia_get_chip_id(pa); 3138 FURIA_GET_NUM_LANES(chip_id, num_lanes); 3139 3140 3141 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 3142 if (((lane_map >> lane_index) & 1) == 0x1) { 3143 pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 1); 3144 PHYMOD_NULL_CHECK(pkg_ln_des); 3145 wr_lane = pkg_ln_des->slice_wr_val; 3146 rd_lane = pkg_ln_des->slice_rd_val; 3147 if(pkg_side == SIDE_A) { 3148 sys_en = pkg_ln_des->sideA; 3149 } else { 3150 sys_en = pkg_ln_des->sideB; 3151 } 3152 3153 /* Program the slice register */ 3154 PHYMOD_IF_ERR_RETURN 3155 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 3156 switch (loopback) { 3157 case phymodLoopbackRemotePMD : 3158 PHYMOD_IF_ERR_RETURN(falcon_furia_rmt_lpbk_get(pa, &ena_dis)); 3159 *enable = ena_dis; 3160 break; 3161 case phymodLoopbackRemotePCS : 3162 return PHYMOD_E_UNAVAIL; 3163 break; 3164 case phymodLoopbackGlobal: 3165 case phymodLoopbackGlobalPMD: 3166 PHYMOD_IF_ERR_RETURN(falcon_furia_dig_lpbk_get(pa, &ena_dis)); 3167 *enable = ena_dis; 3168 break; 3169 default : 3170 break; 3171 } 3172 break; 3173 } 3174 } 3175 /* Set the slice register with default values */ 3176 PHYMOD_IF_ERR_RETURN 3177 (WRITE_FURIA_SLICE_REG(pa, 0, 1, 0)); 3178 return PHYMOD_E_NONE; 3179 } 3180 3181 int furia_reset_set(const phymod_access_t *pa, 3182 phymod_reset_mode_t reset_mode, 3183 phymod_reset_direction_t direction) 3184 { 3185 if((reset_mode == phymodResetModeSoft) && 3186 (direction == phymodResetDirectionIn)) { 3187 PHYMOD_IF_ERR_RETURN 3188 (_furia_chip_reset(pa)); 3189 } 3190 return PHYMOD_E_NONE; 3191 } 3192 3193 int furia_tx_set(const phymod_access_t *pa, 3194 const phymod_tx_t* tx) 3195 { 3196 int lane_map = 0; 3197 int pkg_side = 0; 3198 int wr_lane = 0; 3199 int sys_en = 0; 3200 int rd_lane = 0; 3201 uint32_t chip_id = 0; 3202 int num_lanes = 0; 3203 int lane_index = 0; 3204 const FURIA_PKG_LANE_CFG_t* pkg_ln_des = NULL; 3205 uint32_t acc_flags = 0; 3206 3207 /* Get the lane map from phymod access */ 3208 lane_map = PHYMOD_ACC_LANE_MASK(pa); 3209 acc_flags = PHYMOD_ACC_FLAGS(pa); 3210 FURIA_GET_IF_SIDE(acc_flags, pkg_side); 3211 /* Get the chip id */ 3212 chip_id = _furia_get_chip_id(pa); 3213 FURIA_GET_NUM_LANES(chip_id, num_lanes); 3214 3215 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 3216 if (((lane_map >> lane_index) & 1) == 0x1) { 3217 /* Configure Tx side(SIDE_A) first*/ 3218 pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 0); 3219 PHYMOD_NULL_CHECK(pkg_ln_des); 3220 wr_lane = FURIA_IF_BCAST_SET(chip_id, lane_map) ? BROADCAST : pkg_ln_des->slice_wr_val; 3221 rd_lane = pkg_ln_des->slice_rd_val; 3222 if(pkg_side == SIDE_A) { 3223 sys_en = pkg_ln_des->sideA; 3224 } else { 3225 sys_en = pkg_ln_des->sideB; 3226 } 3227 /* Program the slice register */ 3228 PHYMOD_IF_ERR_RETURN 3229 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 3230 PHYMOD_IF_ERR_RETURN 3231 (falcon_furia_write_tx_afe(pa, TX_AFE_PRE, (int8_t)tx->pre)); 3232 PHYMOD_IF_ERR_RETURN 3233 (falcon_furia_write_tx_afe(pa, TX_AFE_MAIN, (int8_t)tx->main)); 3234 PHYMOD_IF_ERR_RETURN 3235 (falcon_furia_write_tx_afe(pa, TX_AFE_POST1, (int8_t)tx->post)); 3236 PHYMOD_IF_ERR_RETURN 3237 (falcon_furia_write_tx_afe(pa, TX_AFE_POST2, (int8_t)tx->post2)); 3238 PHYMOD_IF_ERR_RETURN 3239 (falcon_furia_write_tx_afe(pa, TX_AFE_POST3, (int8_t)tx->post3)); 3240 PHYMOD_IF_ERR_RETURN 3241 (falcon_furia_write_tx_afe(pa, TX_AFE_AMP, (int8_t)tx->amp)); 3242 } 3243 if(FURIA_IF_BCAST_SET(chip_id, lane_map)) { 3244 break; 3245 } 3246 } 3247 3248 /* Set the slice register with default values */ 3249 PHYMOD_IF_ERR_RETURN 3250 (WRITE_FURIA_SLICE_REG(pa, 0, 1, 0)); 3251 return PHYMOD_E_NONE; 3252 } 3253 3254 int furia_tx_get(const phymod_access_t *pa, 3255 phymod_tx_t* tx) 3256 { 3257 int lane_map = 0; 3258 int pkg_side = 0; 3259 int wr_lane = 0; 3260 int sys_en = 0; 3261 int rd_lane = 0; 3262 uint32_t chip_id = 0; 3263 int num_lanes = 0; 3264 int lane_index = 0; 3265 uint32_t acc_flags = 0; 3266 int8_t value = 0; 3267 const FURIA_PKG_LANE_CFG_t* pkg_ln_des = NULL; 3268 3269 /* Get the lane map from phymod access */ 3270 lane_map = PHYMOD_ACC_LANE_MASK(pa); 3271 acc_flags = PHYMOD_ACC_FLAGS(pa); 3272 FURIA_GET_IF_SIDE(acc_flags, pkg_side); 3273 3274 3275 /* Get the chip id */ 3276 chip_id = _furia_get_chip_id(pa); 3277 FURIA_GET_NUM_LANES(chip_id, num_lanes); 3278 3279 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 3280 if (((lane_map >> lane_index) & 1) == 0x1) { 3281 pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 0); 3282 PHYMOD_NULL_CHECK(pkg_ln_des); 3283 wr_lane = pkg_ln_des->slice_wr_val; 3284 rd_lane = pkg_ln_des->slice_rd_val; 3285 if(pkg_side == SIDE_A) { 3286 sys_en = pkg_ln_des->sideA; 3287 } else { 3288 sys_en = pkg_ln_des->sideB; 3289 } 3290 3291 /* Program the slice register */ 3292 PHYMOD_IF_ERR_RETURN 3293 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 3294 3295 if (FURIA_IF_TX_SIDE(chip_id, pkg_side)) { 3296 PHYMOD_IF_ERR_RETURN 3297 (falcon_furia_read_tx_afe(pa, TX_AFE_PRE, &value)); 3298 tx->pre = value; 3299 PHYMOD_IF_ERR_RETURN 3300 (falcon_furia_read_tx_afe(pa, TX_AFE_MAIN, &value)); 3301 tx->main = value; 3302 PHYMOD_IF_ERR_RETURN 3303 (falcon_furia_read_tx_afe(pa, TX_AFE_POST1, &value)); 3304 tx->post = value; 3305 PHYMOD_IF_ERR_RETURN 3306 (falcon_furia_read_tx_afe(pa, TX_AFE_POST2, &value)); 3307 tx->post2 = value; 3308 PHYMOD_IF_ERR_RETURN 3309 (falcon_furia_read_tx_afe(pa, TX_AFE_POST3, &value)); 3310 tx->post3 = value; 3311 PHYMOD_IF_ERR_RETURN 3312 (falcon_furia_read_tx_afe(pa, TX_AFE_AMP, &value)); 3313 tx->amp = value; 3314 } 3315 break; 3316 } 3317 } 3318 /* Set the slice register with default values */ 3319 PHYMOD_IF_ERR_RETURN 3320 (WRITE_FURIA_SLICE_REG(pa, 0, 1, 0)); 3321 return PHYMOD_E_NONE; 3322 } 3323 int furia_rx_set(const phymod_access_t *pa, 3324 const phymod_rx_t* rx) 3325 { 3326 int lane_map = 0; 3327 int pkg_side = 0; 3328 int wr_lane = 0; 3329 int sys_en = 0; 3330 int rd_lane = 0; 3331 uint32_t chip_id = 0; 3332 int num_lanes = 0; 3333 int lane_index = 0; 3334 const FURIA_PKG_LANE_CFG_t* pkg_ln_des = NULL; 3335 uint32_t acc_flags = 0; 3336 uint32_t i = 0; 3337 3338 /* Get the lane map from phymod access */ 3339 lane_map = PHYMOD_ACC_LANE_MASK(pa); 3340 acc_flags = PHYMOD_ACC_FLAGS(pa); 3341 FURIA_GET_IF_SIDE(acc_flags, pkg_side); 3342 /* Get the chip id */ 3343 chip_id = _furia_get_chip_id(pa); 3344 FURIA_GET_NUM_LANES(chip_id, num_lanes); 3345 3346 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 3347 if (((lane_map >> lane_index) & 1) == 0x1) { 3348 /* Configure Tx side(SIDE_A) first*/ 3349 pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 1); 3350 PHYMOD_NULL_CHECK(pkg_ln_des); 3351 wr_lane = FURIA_IF_BCAST_SET(chip_id, lane_map) ? BROADCAST : pkg_ln_des->slice_wr_val; 3352 rd_lane = pkg_ln_des->slice_rd_val; 3353 if(pkg_side == SIDE_A) { 3354 sys_en = pkg_ln_des->sideA; 3355 } else { 3356 sys_en = pkg_ln_des->sideB; 3357 } 3358 3359 /* Program the slice register */ 3360 PHYMOD_IF_ERR_RETURN 3361 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 3362 3363 /*params check*/ 3364 for (i = 0 ; i < PHYMOD_NUM_DFE_TAPS; i++){ 3365 if(rx->dfe[i].enable && (rx->num_of_dfe_taps > PHYMOD_NUM_DFE_TAPS)) { 3366 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("illegal number of DFEs to set"))); 3367 } 3368 } 3369 if (FURIA_IF_RX_SIDE(chip_id, pkg_side)) { 3370 /* first stop the rx adaption */ 3371 PHYMOD_IF_ERR_RETURN(falcon_furia_stop_rx_adaptation(pa, 1)); 3372 /*vga set*/ 3373 if (rx->vga.enable) { 3374 PHYMOD_IF_ERR_RETURN(falcon_furia_write_rx_afe(pa, RX_AFE_VGA, rx->vga.value)); 3375 } 3376 /*dfe set*/ 3377 for (i = 0 ; i < PHYMOD_NUM_DFE_TAPS; i++){ 3378 if(rx->dfe[i].enable){ 3379 PHYMOD_IF_ERR_RETURN(falcon_furia_write_rx_afe(pa, RX_AFE_DFE1+i, rx->dfe[i].value)); 3380 } 3381 } 3382 /*peaking filter set*/ 3383 if(rx->peaking_filter.enable){ 3384 PHYMOD_IF_ERR_RETURN(falcon_furia_write_rx_afe(pa, RX_AFE_PF, rx->peaking_filter.value)); 3385 } 3386 if(rx->low_freq_peaking_filter.enable){ 3387 PHYMOD_IF_ERR_RETURN(falcon_furia_write_rx_afe(pa, RX_AFE_PF2, rx->low_freq_peaking_filter.value)); 3388 } 3389 } 3390 if (FURIA_IF_BCAST_SET(chip_id, lane_map)) { 3391 break; 3392 } 3393 } 3394 } 3395 /* Set the slice register with default values */ 3396 PHYMOD_IF_ERR_RETURN 3397 (WRITE_FURIA_SLICE_REG(pa, 0, 1, 0)); 3398 return PHYMOD_E_NONE; 3399 } 3400 3401 3402 int furia_rx_get(const phymod_access_t *pa, 3403 phymod_rx_t* rx) 3404 { 3405 int lane_map = 0; 3406 int pkg_side = 0; 3407 int wr_lane = 0; 3408 int sys_en = 0; 3409 int rd_lane = 0; 3410 uint32_t chip_id = 0; 3411 int num_lanes = 0; 3412 int lane_index = 0; 3413 uint32_t acc_flags = 0; 3414 const FURIA_PKG_LANE_CFG_t* pkg_ln_des = NULL; 3415 uint32_t i = 0; 3416 int8_t dfe; 3417 int8_t vga; 3418 int8_t pf; 3419 int8_t low_freq_pf; 3420 3421 /* Get the lane map from phymod access */ 3422 lane_map = PHYMOD_ACC_LANE_MASK(pa); 3423 acc_flags = PHYMOD_ACC_FLAGS(pa); 3424 FURIA_GET_IF_SIDE(acc_flags, pkg_side); 3425 3426 3427 /* Get the chip id */ 3428 chip_id = _furia_get_chip_id(pa); 3429 FURIA_GET_NUM_LANES(chip_id, num_lanes); 3430 3431 3432 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 3433 if (((lane_map >> lane_index) & 1) == 0x1) { 3434 pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 1); 3435 PHYMOD_NULL_CHECK(pkg_ln_des); 3436 wr_lane = pkg_ln_des->slice_wr_val; 3437 rd_lane = pkg_ln_des->slice_rd_val; 3438 if(pkg_side == SIDE_A) { 3439 sys_en = pkg_ln_des->sideA; 3440 } else { 3441 sys_en = pkg_ln_des->sideB; 3442 } 3443 3444 /* Program the slice register */ 3445 PHYMOD_IF_ERR_RETURN 3446 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 3447 3448 3449 if (FURIA_IF_RX_SIDE(chip_id, pkg_side)) { 3450 rx->num_of_dfe_taps = PHYMOD_NUM_DFE_TAPS; 3451 PHYMOD_IF_ERR_RETURN(falcon_furia_read_rx_afe(pa, RX_AFE_VGA, &vga)); 3452 rx->vga.value = vga; 3453 3454 /*dfe get*/ 3455 for (i = 0 ; i < PHYMOD_NUM_DFE_TAPS; i++){ 3456 PHYMOD_IF_ERR_RETURN(falcon_furia_read_rx_afe(pa, (RX_AFE_DFE1+i), &dfe)); 3457 rx->dfe[i].value = dfe; 3458 } 3459 3460 /*peaking filter get*/ 3461 PHYMOD_IF_ERR_RETURN(falcon_furia_read_rx_afe(pa, RX_AFE_PF, &pf)); 3462 rx->peaking_filter.value = pf; 3463 PHYMOD_IF_ERR_RETURN(falcon_furia_read_rx_afe(pa, RX_AFE_PF2, &low_freq_pf)); 3464 rx->low_freq_peaking_filter.value = low_freq_pf; 3465 } 3466 break; 3467 } 3468 } 3469 /* Set the slice register with default values */ 3470 PHYMOD_IF_ERR_RETURN 3471 (WRITE_FURIA_SLICE_REG(pa, 0, 1, 0)); 3472 return PHYMOD_E_NONE; 3473 } 3474 3475 int furia_slice_reg_set(const phymod_access_t *pa) 3476 { 3477 int lane_map = 0; 3478 int pkg_side = 0; 3479 int wr_lane = 0; 3480 int sys_en = 0; 3481 int rd_lane = 0; 3482 uint32_t chip_id = 0; 3483 int num_lanes = 0; 3484 int lane_index = 0; 3485 uint32_t acc_flags = 0; 3486 const FURIA_PKG_LANE_CFG_t* pkg_ln_des = NULL; 3487 lane_map = PHYMOD_ACC_LANE_MASK(pa); 3488 acc_flags = PHYMOD_ACC_FLAGS(pa); 3489 FURIA_GET_IF_SIDE(acc_flags, pkg_side); 3490 /* Get the chip id */ 3491 chip_id = _furia_get_chip_id(pa); 3492 num_lanes = FURIA_IS_SIMPLEX(chip_id) ? 8 : 4; 3493 3494 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 3495 if (((lane_map >> lane_index) & 1) == 0x1) { 3496 pkg_ln_des = _furia_pkg_ln_des(chip_id, pa, lane_index); 3497 PHYMOD_NULL_CHECK(pkg_ln_des); 3498 wr_lane = FURIA_IF_BCAST_SET(chip_id, lane_map) ? BROADCAST : pkg_ln_des->slice_wr_val; 3499 rd_lane = pkg_ln_des->slice_rd_val; 3500 if(pkg_side == SIDE_A) { 3501 sys_en = pkg_ln_des->sideA; 3502 } else { 3503 sys_en = pkg_ln_des->sideB; 3504 } 3505 /* Program the slice register, by checking the device id */ 3506 if ((pa->devad & FURIA_DEVICE_ID_MASK) == FURIA_PMD_DEVICE_ID) { 3507 PHYMOD_IF_ERR_RETURN 3508 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 3509 } else if ((pa->devad & FURIA_DEVICE_ID_MASK) == FURIA_AN_DEVICE_ID) { 3510 PHYMOD_IF_ERR_RETURN 3511 (WRITE_FURIA_AN_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 3512 } else { 3513 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_FAIL, (_PHYMOD_MSG("Slice Reg Set" 3514 " Request for Unknown Device Type..."))); 3515 return PHYMOD_E_FAIL; 3516 } 3517 if (BROADCAST == wr_lane) 3518 return PHYMOD_E_NONE; 3519 } 3520 } 3521 3522 return PHYMOD_E_NONE; 3523 } 3524 3525 int furia_slice_reg_unset(const phymod_access_t *pa) 3526 { 3527 if ((pa->devad & FURIA_DEVICE_ID_MASK) == FURIA_PMD_DEVICE_ID) { 3528 PHYMOD_IF_ERR_RETURN 3529 (WRITE_FURIA_SLICE_REG(pa, 0, 1, 0)); 3530 } else if ((pa->devad & FURIA_DEVICE_ID_MASK) == FURIA_AN_DEVICE_ID) { 3531 PHYMOD_IF_ERR_RETURN 3532 (WRITE_FURIA_AN_SLICE_REG(pa, 0, 1, 0)); 3533 } 3534 return PHYMOD_E_NONE; 3535 3536 } 3537 3538 int furia_tx_lane_control_set(const phymod_access_t *pa, 3539 phymod_phy_tx_lane_control_t tx_control) 3540 { 3541 int lane_map = 0; 3542 int pkg_side = 0; 3543 int wr_lane = 0; 3544 int sys_en = 0; 3545 int rd_lane = 0; 3546 uint32_t chip_id = 0; 3547 int num_lanes = 0; 3548 int lane_index = 0; 3549 uint32_t acc_flags = 0; 3550 const FURIA_PKG_LANE_CFG_t* pkg_ln_des = NULL; 3551 SYS_TX_PMA_DP_SOFT_RST_t sys_tx_dp_soft_rst; 3552 LINE_TX_PMA_DP_SOFT_RST_t line_tx_dp_soft_rst; 3553 PHYMOD_MEMSET(&sys_tx_dp_soft_rst, 0 , sizeof(SYS_TX_PMA_DP_SOFT_RST_t)); 3554 PHYMOD_MEMSET(&line_tx_dp_soft_rst, 0 , sizeof(LINE_TX_PMA_DP_SOFT_RST_t)); 3555 3556 /* Get the lane map from phymod access */ 3557 lane_map = PHYMOD_ACC_LANE_MASK(pa); 3558 acc_flags = PHYMOD_ACC_FLAGS(pa); 3559 FURIA_GET_IF_SIDE(acc_flags, pkg_side); 3560 /* Get the chip id */ 3561 chip_id = _furia_get_chip_id(pa); 3562 FURIA_GET_NUM_LANES(chip_id, num_lanes); 3563 switch(tx_control) { 3564 case phymodTxReset: 3565 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 3566 if (((lane_map >> lane_index) & 1) == 0x1) { 3567 pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 0); 3568 PHYMOD_NULL_CHECK(pkg_ln_des); 3569 wr_lane = FURIA_IF_BCAST_SET(chip_id, lane_map) ? BROADCAST : pkg_ln_des->slice_wr_val; 3570 rd_lane = pkg_ln_des->slice_rd_val; 3571 if(pkg_side == SIDE_A) { 3572 sys_en = pkg_ln_des->sideA; 3573 } else { 3574 sys_en = pkg_ln_des->sideB; 3575 } 3576 /* Program the slice register */ 3577 PHYMOD_IF_ERR_RETURN 3578 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 3579 if (FURIA_IF_TX_SIDE(chip_id, pkg_side)) { 3580 /* Asserting datapath reset */ 3581 if (sys_en == LINE) { 3582 PHYMOD_IF_ERR_RETURN 3583 (READ_FURIA_PMA_PMD_REG(pa,\ 3584 LINE_TX_PMA_DP_soft_rst_Adr,\ 3585 &line_tx_dp_soft_rst.data)); 3586 line_tx_dp_soft_rst.fields.rstb_frc = 1; 3587 PHYMOD_IF_ERR_RETURN 3588 (WRITE_FURIA_PMA_PMD_REG(pa,\ 3589 LINE_TX_PMA_DP_soft_rst_Adr,\ 3590 line_tx_dp_soft_rst.data)); 3591 /* Releasing datapath reset */ 3592 PHYMOD_IF_ERR_RETURN 3593 (READ_FURIA_PMA_PMD_REG(pa,\ 3594 LINE_TX_PMA_DP_soft_rst_Adr,\ 3595 &line_tx_dp_soft_rst.data)); 3596 line_tx_dp_soft_rst.fields.rstb = 1; 3597 PHYMOD_IF_ERR_RETURN 3598 (WRITE_FURIA_PMA_PMD_REG(pa,\ 3599 LINE_TX_PMA_DP_soft_rst_Adr,\ 3600 line_tx_dp_soft_rst.data)); 3601 PHYMOD_IF_ERR_RETURN 3602 (READ_FURIA_PMA_PMD_REG(pa,\ 3603 LINE_TX_PMA_DP_soft_rst_Adr,\ 3604 &line_tx_dp_soft_rst.data)); 3605 line_tx_dp_soft_rst.fields.rstb_frc = 0; 3606 PHYMOD_IF_ERR_RETURN 3607 (WRITE_FURIA_PMA_PMD_REG(pa,\ 3608 LINE_TX_PMA_DP_soft_rst_Adr,\ 3609 line_tx_dp_soft_rst.data)); 3610 } else { 3611 PHYMOD_IF_ERR_RETURN 3612 (READ_FURIA_PMA_PMD_REG(pa,\ 3613 SYS_TX_PMA_DP_soft_rst_Adr,\ 3614 &sys_tx_dp_soft_rst.data)); 3615 sys_tx_dp_soft_rst.fields.rstb_frc = 1; 3616 PHYMOD_IF_ERR_RETURN 3617 (WRITE_FURIA_PMA_PMD_REG(pa,\ 3618 SYS_TX_PMA_DP_soft_rst_Adr,\ 3619 sys_tx_dp_soft_rst.data)); 3620 PHYMOD_IF_ERR_RETURN 3621 (READ_FURIA_PMA_PMD_REG(pa,\ 3622 SYS_TX_PMA_DP_soft_rst_Adr,\ 3623 &sys_tx_dp_soft_rst.data)); 3624 sys_tx_dp_soft_rst.fields.rstb = 1; 3625 PHYMOD_IF_ERR_RETURN 3626 (WRITE_FURIA_PMA_PMD_REG(pa,\ 3627 SYS_TX_PMA_DP_soft_rst_Adr,\ 3628 sys_tx_dp_soft_rst.data)); 3629 PHYMOD_IF_ERR_RETURN 3630 (READ_FURIA_PMA_PMD_REG(pa,\ 3631 SYS_TX_PMA_DP_soft_rst_Adr,\ 3632 &sys_tx_dp_soft_rst.data)); 3633 sys_tx_dp_soft_rst.fields.rstb_frc = 0; 3634 PHYMOD_IF_ERR_RETURN 3635 (WRITE_FURIA_PMA_PMD_REG(pa,\ 3636 SYS_TX_PMA_DP_soft_rst_Adr,\ 3637 sys_tx_dp_soft_rst.data)); 3638 } 3639 } 3640 if (FURIA_IF_BCAST_SET(chip_id, lane_map)) { 3641 break; 3642 } 3643 } 3644 } 3645 break; 3646 case phymodTxTrafficDisable: 3647 case phymodTxTrafficEnable: 3648 return PHYMOD_E_UNAVAIL; 3649 break; 3650 case phymodTxSquelchOn: 3651 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 3652 if (((lane_map >> lane_index) & 1) == 0x1) { 3653 pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 0); 3654 PHYMOD_NULL_CHECK(pkg_ln_des); 3655 wr_lane = FURIA_IF_BCAST_SET(chip_id, lane_map) ? BROADCAST : pkg_ln_des->slice_wr_val; 3656 rd_lane = pkg_ln_des->slice_rd_val; 3657 if(pkg_side == SIDE_A) { 3658 sys_en = pkg_ln_des->sideA; 3659 } else { 3660 sys_en = pkg_ln_des->sideB; 3661 } 3662 /* Program the slice register */ 3663 PHYMOD_IF_ERR_RETURN 3664 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 3665 if (FURIA_IF_TX_SIDE(chip_id, pkg_side)) { 3666 PHYMOD_IF_ERR_RETURN(falcon_furia_tx_disable(pa, 1)); 3667 } 3668 if (FURIA_IF_BCAST_SET(chip_id, lane_map)) { 3669 break;; 3670 } 3671 } 3672 } 3673 break; 3674 3675 case phymodTxSquelchOff: 3676 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 3677 if (((lane_map >> lane_index) & 1) == 0x1) { 3678 pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 0); 3679 PHYMOD_NULL_CHECK(pkg_ln_des); 3680 wr_lane = FURIA_IF_BCAST_SET(chip_id, lane_map) ? BROADCAST : pkg_ln_des->slice_wr_val; 3681 rd_lane = pkg_ln_des->slice_rd_val; 3682 if(pkg_side == SIDE_A) { 3683 sys_en = pkg_ln_des->sideA; 3684 } else { 3685 sys_en = pkg_ln_des->sideB; 3686 } 3687 /* Program the slice register */ 3688 PHYMOD_IF_ERR_RETURN 3689 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 3690 if (FURIA_IF_TX_SIDE(chip_id, pkg_side)) { 3691 PHYMOD_IF_ERR_RETURN(falcon_furia_tx_disable(pa, 0)); 3692 } 3693 if (FURIA_IF_BCAST_SET(chip_id, lane_map)) { 3694 break;; 3695 } 3696 } 3697 } 3698 break; 3699 default: 3700 break; 3701 } 3702 /* Set the slice register with default values */ 3703 PHYMOD_IF_ERR_RETURN 3704 (WRITE_FURIA_SLICE_REG(pa, 0, 1, 0)); 3705 return PHYMOD_E_NONE; 3706 } 3707 3708 int furia_tx_lane_control_get(const phymod_access_t *pa, 3709 phymod_phy_tx_lane_control_t* tx_control) 3710 { 3711 int lane_map = 0; 3712 uint32_t chip_id = 0; 3713 int num_lanes = 0; 3714 int lane_index = 0; 3715 uint32_t acc_flags = 0; 3716 int pkg_side = 0; 3717 int sys_en = 0; 3718 int wr_lane = 0; 3719 int rd_lane = 0; 3720 uint8_t tx_dis_rd_val = 0; 3721 const FURIA_PKG_LANE_CFG_t* pkg_ln_des = NULL; 3722 3723 /* Get the lane map from phymod access */ 3724 lane_map = PHYMOD_ACC_LANE_MASK(pa); 3725 acc_flags = PHYMOD_ACC_FLAGS(pa); 3726 FURIA_GET_IF_SIDE(acc_flags, pkg_side); 3727 /* Get the chip id */ 3728 chip_id = _furia_get_chip_id(pa); 3729 FURIA_GET_NUM_LANES(chip_id, num_lanes); 3730 3731 switch(*tx_control) { 3732 case phymodTxReset: 3733 case phymodTxTrafficDisable: 3734 case phymodTxTrafficEnable: 3735 return PHYMOD_E_UNAVAIL; 3736 case phymodTxSquelchOn: 3737 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 3738 if (((lane_map >> lane_index) & 1) == 0x1) { 3739 pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 0); 3740 PHYMOD_NULL_CHECK(pkg_ln_des); 3741 rd_lane = pkg_ln_des->slice_rd_val; 3742 wr_lane = pkg_ln_des->slice_wr_val; 3743 if(pkg_side == SIDE_A) { 3744 sys_en = pkg_ln_des->sideA; 3745 } else { 3746 sys_en = pkg_ln_des->sideB; 3747 } 3748 /* Program the slice register */ 3749 PHYMOD_IF_ERR_RETURN 3750 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 3751 if ((FURIA_IS_SIMPLEX(chip_id) && (pkg_side == SIDE_A)) || 3752 (FURIA_IS_DUPLEX(chip_id))) { 3753 PHYMOD_IF_ERR_RETURN(falcon_furia_tx_disable_get(pa, &tx_dis_rd_val)); 3754 *tx_control = tx_dis_rd_val ? phymodTxSquelchOn : phymodTxSquelchOff; 3755 } 3756 break; 3757 } 3758 } 3759 break; 3760 case phymodTxSquelchOff: 3761 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 3762 if (((lane_map >> lane_index) & 1) == 0x1) { 3763 pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, 3764 lane_index, 0); 3765 PHYMOD_NULL_CHECK(pkg_ln_des); 3766 if(pkg_side == SIDE_A) { 3767 sys_en = pkg_ln_des->sideA; 3768 } else { 3769 sys_en = pkg_ln_des->sideB; 3770 } 3771 /* Program the slice register */ 3772 PHYMOD_IF_ERR_RETURN 3773 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 3774 if (FURIA_IF_TX_SIDE(chip_id, pkg_side)) { 3775 PHYMOD_IF_ERR_RETURN(falcon_furia_tx_disable_get(pa, &tx_dis_rd_val)); 3776 *tx_control = (tx_dis_rd_val == 0) ? 1 : 0; 3777 } 3778 break; 3779 } 3780 } 3781 break; 3782 default: 3783 break; 3784 } 3785 return PHYMOD_E_NONE; 3786 } 3787 3788 int furia_rx_lane_control_set(const phymod_access_t *pa, 3789 phymod_phy_rx_lane_control_t rx_control) 3790 { 3791 int lane_map = 0; 3792 int pkg_side = 0; 3793 int wr_lane = 0; 3794 int sys_en = 0; 3795 int rd_lane = 0; 3796 uint32_t chip_id = 0; 3797 int num_lanes = 0; 3798 int lane_index = 0; 3799 uint32_t acc_flags = 0; 3800 const FURIA_PKG_LANE_CFG_t* pkg_ln_des = NULL; 3801 LINE_RX_PMA_DP_MAIN_CTRL_t line_rx_dp_main_ctrl; 3802 SIGDET_SIGDET_CTRL_1_t sigdet_ctrl; 3803 SYS_RX_PMA_DP_main_ctrl_t sys_rx_dp_main_ctrl; 3804 PHYMOD_MEMSET(&line_rx_dp_main_ctrl, 0 , sizeof(LINE_RX_PMA_DP_MAIN_CTRL_t)); 3805 PHYMOD_MEMSET(&sys_rx_dp_main_ctrl, 0 , sizeof(SYS_RX_PMA_DP_main_ctrl_t)); 3806 PHYMOD_MEMSET(&sigdet_ctrl, 0 , sizeof(SIGDET_SIGDET_CTRL_1_t)); 3807 3808 /* Get the lane map from phymod access */ 3809 lane_map = PHYMOD_ACC_LANE_MASK(pa); 3810 acc_flags = PHYMOD_ACC_FLAGS(pa); 3811 FURIA_GET_IF_SIDE(acc_flags, pkg_side); 3812 /* Get the chip id */ 3813 chip_id = _furia_get_chip_id(pa); 3814 FURIA_GET_NUM_LANES(chip_id, num_lanes); 3815 3816 switch(rx_control) { 3817 case phymodRxReset: 3818 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 3819 if (((lane_map >> lane_index) & 1) == 0x1) { 3820 /* Configure Tx side(SIDE_A) first*/ 3821 pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 1); 3822 PHYMOD_NULL_CHECK(pkg_ln_des); 3823 wr_lane = FURIA_IF_BCAST_SET(chip_id, lane_map) ? BROADCAST : pkg_ln_des->slice_wr_val; 3824 rd_lane = pkg_ln_des->slice_rd_val; 3825 if(pkg_side == SIDE_A) { 3826 sys_en = pkg_ln_des->sideA; 3827 } else { 3828 sys_en = pkg_ln_des->sideB; 3829 } 3830 /* Program the slice register */ 3831 PHYMOD_IF_ERR_RETURN 3832 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 3833 if (FURIA_IF_RX_SIDE(chip_id, pkg_side)) { 3834 if(sys_en == LINE) { 3835 /* Program the slice register */ 3836 PHYMOD_IF_ERR_RETURN 3837 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 3838 /* Asserting datapath reset */ 3839 PHYMOD_IF_ERR_RETURN 3840 (READ_FURIA_PMA_PMD_REG(pa,\ 3841 LINE_RX_PMA_DP_main_ctrl_Adr,\ 3842 &line_rx_dp_main_ctrl.data)); 3843 line_rx_dp_main_ctrl.fields.rstb_frc = 1; 3844 PHYMOD_IF_ERR_RETURN 3845 (WRITE_FURIA_PMA_PMD_REG(pa,\ 3846 LINE_RX_PMA_DP_main_ctrl_Adr,\ 3847 line_rx_dp_main_ctrl.data)); 3848 /* Releasing datapath reset */ 3849 PHYMOD_IF_ERR_RETURN 3850 (READ_FURIA_PMA_PMD_REG(pa,\ 3851 LINE_RX_PMA_DP_main_ctrl_Adr,\ 3852 &line_rx_dp_main_ctrl.data)); 3853 line_rx_dp_main_ctrl.fields.rstb = 1; 3854 PHYMOD_IF_ERR_RETURN 3855 (WRITE_FURIA_PMA_PMD_REG(pa,\ 3856 LINE_RX_PMA_DP_main_ctrl_Adr,\ 3857 line_rx_dp_main_ctrl.data)); 3858 PHYMOD_IF_ERR_RETURN 3859 (READ_FURIA_PMA_PMD_REG(pa,\ 3860 LINE_RX_PMA_DP_main_ctrl_Adr,\ 3861 &line_rx_dp_main_ctrl.data)); 3862 line_rx_dp_main_ctrl.fields.rstb_frc = 0; 3863 PHYMOD_IF_ERR_RETURN 3864 (WRITE_FURIA_PMA_PMD_REG(pa,\ 3865 LINE_RX_PMA_DP_main_ctrl_Adr,\ 3866 line_rx_dp_main_ctrl.data)); 3867 } else { 3868 /* Program the slice register */ 3869 PHYMOD_IF_ERR_RETURN 3870 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 3871 PHYMOD_IF_ERR_RETURN 3872 (READ_FURIA_PMA_PMD_REG(pa,\ 3873 SYS_RX_PMA_DP_main_ctrl_Adr,\ 3874 &sys_rx_dp_main_ctrl.data)); 3875 sys_rx_dp_main_ctrl.fields.rstb_frc = 1; 3876 PHYMOD_IF_ERR_RETURN 3877 (WRITE_FURIA_PMA_PMD_REG(pa,\ 3878 SYS_RX_PMA_DP_main_ctrl_Adr,\ 3879 sys_rx_dp_main_ctrl.data)); 3880 /* Releasing datapath reset */ 3881 PHYMOD_IF_ERR_RETURN 3882 (READ_FURIA_PMA_PMD_REG(pa,\ 3883 SYS_RX_PMA_DP_main_ctrl_Adr,\ 3884 &sys_rx_dp_main_ctrl.data)); 3885 sys_rx_dp_main_ctrl.fields.rstb = 1; 3886 PHYMOD_IF_ERR_RETURN 3887 (WRITE_FURIA_PMA_PMD_REG(pa,\ 3888 SYS_RX_PMA_DP_main_ctrl_Adr,\ 3889 sys_rx_dp_main_ctrl.data)); 3890 PHYMOD_IF_ERR_RETURN 3891 (READ_FURIA_PMA_PMD_REG(pa,\ 3892 SYS_RX_PMA_DP_main_ctrl_Adr,\ 3893 &sys_rx_dp_main_ctrl.data)); 3894 sys_rx_dp_main_ctrl.fields.rstb_frc = 0; 3895 PHYMOD_IF_ERR_RETURN 3896 (WRITE_FURIA_PMA_PMD_REG(pa,\ 3897 SYS_RX_PMA_DP_main_ctrl_Adr,\ 3898 sys_rx_dp_main_ctrl.data)); 3899 } 3900 } 3901 if (FURIA_IF_BCAST_SET(chip_id, lane_map)) { 3902 break; 3903 } 3904 } 3905 } 3906 break; 3907 case phymodRxSquelchOn: 3908 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 3909 if (((lane_map >> lane_index) & 1) == 0x1) { 3910 /* Configure Tx side(SIDE_A) first*/ 3911 pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 1); 3912 PHYMOD_NULL_CHECK(pkg_ln_des); 3913 wr_lane = FURIA_IF_BCAST_SET(chip_id, lane_map) ? BROADCAST : pkg_ln_des->slice_wr_val; 3914 rd_lane = pkg_ln_des->slice_rd_val; 3915 if(pkg_side == SIDE_A) { 3916 sys_en = pkg_ln_des->sideA; 3917 } else { 3918 sys_en = pkg_ln_des->sideB; 3919 } 3920 /* Program the slice register */ 3921 PHYMOD_IF_ERR_RETURN 3922 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 3923 if (FURIA_IF_RX_SIDE(chip_id, pkg_side)) { 3924 PHYMOD_IF_ERR_RETURN 3925 (READ_FURIA_PMA_PMD_REG(pa,\ 3926 SIGDET_SIGDET_CTRL_1_Adr,\ 3927 &sigdet_ctrl.data)); 3928 sigdet_ctrl.fields.signal_detect_frc = 1; 3929 sigdet_ctrl.fields.signal_detect_frc_val = 0; 3930 PHYMOD_IF_ERR_RETURN 3931 (WRITE_FURIA_PMA_PMD_REG(pa,\ 3932 SIGDET_SIGDET_CTRL_1_Adr,\ 3933 sigdet_ctrl.data)); 3934 } 3935 if (FURIA_IF_BCAST_SET(chip_id, lane_map)) { 3936 break; 3937 } 3938 } 3939 } 3940 break; 3941 case phymodRxSquelchOff: 3942 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 3943 if (((lane_map >> lane_index) & 1) == 0x1) { 3944 /* Configure Tx side(SIDE_A) first*/ 3945 pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 1); 3946 PHYMOD_NULL_CHECK(pkg_ln_des); 3947 wr_lane = FURIA_IF_BCAST_SET(chip_id, lane_map) ? BROADCAST : pkg_ln_des->slice_wr_val; 3948 rd_lane = pkg_ln_des->slice_rd_val; 3949 if(pkg_side == SIDE_A) { 3950 sys_en = pkg_ln_des->sideA; 3951 } else { 3952 sys_en = pkg_ln_des->sideB; 3953 } 3954 /* Program the slice register */ 3955 PHYMOD_IF_ERR_RETURN 3956 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 3957 if (FURIA_IF_RX_SIDE(chip_id, pkg_side)) { 3958 PHYMOD_IF_ERR_RETURN 3959 (READ_FURIA_PMA_PMD_REG(pa,\ 3960 SIGDET_SIGDET_CTRL_1_Adr,\ 3961 &sigdet_ctrl.data)); 3962 sigdet_ctrl.fields.signal_detect_frc = 0; 3963 sigdet_ctrl.fields.signal_detect_frc_val = 0; 3964 PHYMOD_IF_ERR_RETURN 3965 (WRITE_FURIA_PMA_PMD_REG(pa,\ 3966 SIGDET_SIGDET_CTRL_1_Adr,\ 3967 sigdet_ctrl.data)); 3968 } 3969 if (FURIA_IF_BCAST_SET(chip_id, lane_map)) { 3970 break; 3971 } 3972 } 3973 } 3974 break; 3975 default: 3976 break; 3977 } 3978 3979 /* Set the slice register with default values */ 3980 PHYMOD_IF_ERR_RETURN 3981 (WRITE_FURIA_SLICE_REG(pa, 0, 1, 0)); 3982 return PHYMOD_E_NONE; 3983 } 3984 3985 int furia_rx_lane_control_get(const phymod_access_t *pa, 3986 phymod_phy_rx_lane_control_t* rx_control) 3987 { 3988 int lane_map = 0; 3989 uint32_t chip_id = 0; 3990 int num_lanes = 0; 3991 int lane_index = 0; 3992 int pkg_side = 0; 3993 int wr_lane = 0; 3994 int sys_en = 0; 3995 int rd_lane = 0; 3996 uint32_t acc_flags = 0; 3997 const FURIA_PKG_LANE_CFG_t* pkg_ln_des = NULL; 3998 SIGDET_SIGDET_CTRL_1_t sigdet_ctrl; 3999 PHYMOD_MEMSET(&sigdet_ctrl, 0 , sizeof(SIGDET_SIGDET_CTRL_1_t)); 4000 4001 /* Get the lane map from phymod access */ 4002 lane_map = PHYMOD_ACC_LANE_MASK(pa); 4003 acc_flags = PHYMOD_ACC_FLAGS(pa); 4004 FURIA_GET_IF_SIDE(acc_flags, pkg_side); 4005 /* Get the chip id */ 4006 chip_id = _furia_get_chip_id(pa); 4007 FURIA_GET_NUM_LANES(chip_id, num_lanes); 4008 switch(*rx_control) { 4009 case phymodRxReset: 4010 return PHYMOD_E_UNAVAIL; 4011 case phymodRxSquelchOn: 4012 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 4013 if (((lane_map >> lane_index) & 1) == 0x1) { 4014 pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 1); 4015 PHYMOD_NULL_CHECK(pkg_ln_des); 4016 wr_lane = pkg_ln_des->slice_wr_val; 4017 rd_lane = pkg_ln_des->slice_rd_val; 4018 if(pkg_side == SIDE_A) { 4019 sys_en = pkg_ln_des->sideA; 4020 } else { 4021 sys_en = pkg_ln_des->sideB; 4022 } 4023 /* Program the slice register */ 4024 PHYMOD_IF_ERR_RETURN 4025 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 4026 if (FURIA_IF_RX_SIDE(chip_id, pkg_side)) { 4027 PHYMOD_IF_ERR_RETURN 4028 (READ_FURIA_PMA_PMD_REG(pa,\ 4029 SIGDET_SIGDET_CTRL_1_Adr,\ 4030 &sigdet_ctrl.data)); 4031 *rx_control = sigdet_ctrl.fields.signal_detect_frc ? phymodRxSquelchOn : phymodRxSquelchOff; 4032 } 4033 } 4034 } 4035 break; 4036 case phymodRxSquelchOff: 4037 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 4038 if (((lane_map >> lane_index) & 1) == 0x1) { 4039 pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 1); 4040 PHYMOD_NULL_CHECK(pkg_ln_des); 4041 wr_lane = pkg_ln_des->slice_wr_val; 4042 rd_lane = pkg_ln_des->slice_rd_val; 4043 if(pkg_side == SIDE_A) { 4044 sys_en = pkg_ln_des->sideA; 4045 } else { 4046 sys_en = pkg_ln_des->sideB; 4047 } 4048 /* Program the slice register */ 4049 PHYMOD_IF_ERR_RETURN 4050 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 4051 if (FURIA_IF_RX_SIDE(chip_id, pkg_side)) { 4052 PHYMOD_IF_ERR_RETURN 4053 (READ_FURIA_PMA_PMD_REG(pa,\ 4054 SIGDET_SIGDET_CTRL_1_Adr,\ 4055 &sigdet_ctrl.data)); 4056 *rx_control = sigdet_ctrl.fields.signal_detect_frc_val ? 1 : 0; 4057 } 4058 } 4059 } 4060 break; 4061 default: 4062 break; 4063 } 4064 return PHYMOD_E_NONE; 4065 } 4066 4067 int furia_82212_lane_cross_switch_map_set(const phymod_access_t *pa, 4068 const uint32_t *tx_source_array) 4069 { 4070 uint32_t chip_id = 0; 4071 uint32_t tx_die_lane = 0; 4072 uint32_t rx_die_lane = 0; 4073 uint32_t num_lanes = 0; 4074 uint32_t acc_flags = 0; 4075 int pkg_side = 0; 4076 int lane_index = 0; 4077 int sys_en = 0; 4078 uint32_t phy_id_idx = 0; 4079 uint32_t exist_phy = 0; 4080 const FURIA_PKG_LANE_CFG_t* tx_pkg_ln_des = NULL; 4081 const FURIA_PKG_LANE_CFG_t* rx_pkg_ln_des = NULL; 4082 SYS_RX_PMA_DP_DP_CTRL_t sys_rx_dp_ctrl; 4083 LINE_RX_PMA_DP_DP_CTRL_t line_rx_dp_ctrl; 4084 PHYMOD_MEMSET(&sys_rx_dp_ctrl, 0 , sizeof(SYS_RX_PMA_DP_DP_CTRL_t)); 4085 PHYMOD_MEMSET(&line_rx_dp_ctrl, 0 , sizeof(LINE_RX_PMA_DP_DP_CTRL_t)); 4086 4087 acc_flags = PHYMOD_ACC_FLAGS(pa); 4088 FURIA_GET_IF_SIDE(acc_flags, pkg_side); 4089 /* Get the chip id */ 4090 chip_id = _furia_get_chip_id(pa); 4091 FURIA_GET_NUM_LANES(chip_id, num_lanes); 4092 for (lane_index = 0; lane_index < num_lanes; lane_index++) { 4093 if (chip_id == FURIA_ID_82212) { 4094 if (((pa->lane_mask >> lane_index) & 1) != 0x1) { 4095 continue; 4096 } 4097 } 4098 /* Set Swap configuration with newly supplied dst_lane*/ 4099 tx_pkg_ln_des = _furia_pkg_ln_des(chip_id, pa, lane_index); 4100 PHYMOD_NULL_CHECK(tx_pkg_ln_des); 4101 tx_die_lane = tx_pkg_ln_des->die_lane_num; 4102 rx_pkg_ln_des = _furia_pkg_ln_des(chip_id, pa, tx_source_array[lane_index]); 4103 PHYMOD_NULL_CHECK(rx_pkg_ln_des); 4104 rx_die_lane = rx_pkg_ln_des->die_lane_num; 4105 if(pkg_side == SIDE_A) { 4106 sys_en = tx_pkg_ln_des->sideA; 4107 } else { 4108 sys_en = tx_pkg_ln_des->sideB; 4109 } 4110 PHYMOD_IF_ERR_RETURN 4111 (WRITE_FURIA_SLICE_REG(pa, sys_en, 1<< tx_die_lane, tx_die_lane)); 4112 if (FURIA_IF_TX_SIDE(chip_id, pkg_side)) { 4113 _furia_get_phy_id_idx(pa->addr, &phy_id_idx, &exist_phy); 4114 if (phy_id_idx >= MAX_NUM_PHYS) { 4115 return PHYMOD_E_LIMIT; 4116 } 4117 if (sys_en == LINE) { 4118 /* Select system Rx as specified in Line Tx array */ 4119 /* SYS_RX_PMA_DP_dp_ctrl */ 4120 PHYMOD_IF_ERR_RETURN 4121 (READ_FURIA_PMA_PMD_REG(pa,\ 4122 SYS_RX_PMA_DP_dp_ctrl_Adr,\ 4123 &sys_rx_dp_ctrl.data)); 4124 sys_rx_dp_ctrl.fields.out_sel = rx_die_lane; 4125 PHYMOD_IF_ERR_RETURN 4126 (WRITE_FURIA_PMA_PMD_REG(pa,\ 4127 SYS_RX_PMA_DP_dp_ctrl_Adr,\ 4128 sys_rx_dp_ctrl.data)); 4129 if (exist_phy) { 4130 if (lane_index < 2) { 4131 glb_phy_list[phy_id_idx].tx_lanes &= ~(0xF << (4 * lane_index)); 4132 glb_phy_list[phy_id_idx].tx_lanes |= ((tx_source_array[lane_index] & 0xF) << (4 * lane_index)); 4133 } else if ((lane_index >= 2) && (lane_index <= 5)) { 4134 glb_phy_list[phy_id_idx].tx_lanes &= ~(0xF << (4 * (lane_index-2))); 4135 glb_phy_list[phy_id_idx].tx_lanes |= ((tx_source_array[lane_index] & 0xF) << (4 * (lane_index-2))); 4136 } else if ((lane_index > 5) && (lane_index <= 9)) { 4137 glb_phy_list[phy_id_idx].tx_lanes &= ~(0xF << (4 * (lane_index-4))); 4138 glb_phy_list[phy_id_idx].tx_lanes |= ((tx_source_array[lane_index] & 0xF) << (4 * (lane_index-4))); 4139 } else { 4140 glb_phy_list[phy_id_idx].tx_lanes &= ~(0xF << (4 * (lane_index-6))); 4141 glb_phy_list[phy_id_idx].tx_lanes |= ((tx_source_array[lane_index] & 0xF) << (4 * (lane_index-6))); 4142 } 4143 4144 } 4145 } else { 4146 /* Select Line Rx as specified in System Tx array */ 4147 PHYMOD_IF_ERR_RETURN 4148 (READ_FURIA_PMA_PMD_REG(pa,\ 4149 LINE_RX_PMA_DP_dp_ctrl_Adr,\ 4150 &line_rx_dp_ctrl.data)); 4151 line_rx_dp_ctrl.fields.out_sel = rx_die_lane; 4152 PHYMOD_IF_ERR_RETURN 4153 (WRITE_FURIA_PMA_PMD_REG(pa,\ 4154 LINE_RX_PMA_DP_dp_ctrl_Adr,\ 4155 line_rx_dp_ctrl.data)); 4156 if (exist_phy) { 4157 if (lane_index < 2) { 4158 glb_phy_list[phy_id_idx].tx_lanes &= ~(0xF << (4 * lane_index)); 4159 glb_phy_list[phy_id_idx].tx_lanes |= ((tx_source_array[lane_index] & 0xF) << (4 * lane_index)); 4160 } else if (lane_index >= 2 && lane_index <= 5) { 4161 glb_phy_list[phy_id_idx].tx_lanes &= ~(0xF << (4 * (lane_index-2))); 4162 glb_phy_list[phy_id_idx].tx_lanes |= ((tx_source_array[lane_index] & 0xF) << (4 * (lane_index-2))); 4163 } else if (lane_index > 5 && lane_index <= 9) { 4164 glb_phy_list[phy_id_idx].tx_lanes &= ~(0xF << (4 * (lane_index-4))); 4165 glb_phy_list[phy_id_idx].tx_lanes |= ((tx_source_array[lane_index] & 0xF) << (4 * (lane_index-4))); 4166 } else { 4167 glb_phy_list[phy_id_idx].tx_lanes &= ~(0xF << (4 * (lane_index-6))); 4168 glb_phy_list[phy_id_idx].tx_lanes |= ((tx_source_array[lane_index] & 0xF) << (4 * (lane_index-6))); 4169 } 4170 } 4171 } 4172 } 4173 } 4174 /* Set firmware enable */ 4175 PHYMOD_IF_ERR_RETURN 4176 (_furia_fw_enable(pa)); 4177 /* Set the slice register with default values */ 4178 PHYMOD_IF_ERR_RETURN 4179 (WRITE_FURIA_SLICE_REG(pa, 0, 1, 0)); 4180 return PHYMOD_E_NONE; 4181 } 4182 4183 int furia_82212_lane_cross_switch_map_get(const phymod_access_t *pa, uint32_t* tx_source_array) 4184 { 4185 uint32_t chip_id = 0; 4186 uint32_t tx_die_lane = 0; 4187 uint32_t rx_die_lane = 0; 4188 uint32_t rx_pkg_lane = 0; 4189 uint32_t num_lanes = 0; 4190 uint32_t acc_flags = 0; 4191 int pkg_side = 0; 4192 int lane_index = 0, tmp_lane_index = 0; 4193 int sys_en = 0; 4194 const FURIA_PKG_LANE_CFG_t* tx_pkg_ln_des = NULL; 4195 SYS_RX_PMA_DP_DP_CTRL_t sys_rx_dp_ctrl; 4196 LINE_RX_PMA_DP_DP_CTRL_t line_rx_dp_ctrl; 4197 PHYMOD_MEMSET(&sys_rx_dp_ctrl, 0 , sizeof(SYS_RX_PMA_DP_DP_CTRL_t)); 4198 PHYMOD_MEMSET(&line_rx_dp_ctrl, 0 , sizeof(LINE_RX_PMA_DP_DP_CTRL_t)); 4199 4200 acc_flags = PHYMOD_ACC_FLAGS(pa); 4201 FURIA_GET_IF_SIDE(acc_flags, pkg_side); 4202 /* Get the chip id */ 4203 chip_id = _furia_get_chip_id(pa); 4204 FURIA_GET_NUM_LANES(chip_id, num_lanes); 4205 for (lane_index = 0; lane_index < num_lanes; lane_index++) { 4206 if (chip_id == FURIA_ID_82212) { 4207 if (((pa->lane_mask >> lane_index) & 1) != 0x1) { 4208 continue; 4209 } 4210 } 4211 /* Set Swap configuration with newly supplied dst_lane*/ 4212 tx_pkg_ln_des = _furia_pkg_ln_des(chip_id, pa, lane_index); 4213 PHYMOD_NULL_CHECK(tx_pkg_ln_des); 4214 tx_die_lane = tx_pkg_ln_des->die_lane_num; 4215 if(pkg_side == SIDE_A) { 4216 sys_en = tx_pkg_ln_des->sideA; 4217 } else { 4218 sys_en = tx_pkg_ln_des->sideB; 4219 } 4220 PHYMOD_IF_ERR_RETURN 4221 (WRITE_FURIA_SLICE_REG(pa, sys_en, 1<< tx_die_lane, tx_die_lane)); 4222 if (FURIA_IF_TX_SIDE(chip_id, pkg_side)) { 4223 if (lane_index < 2) { 4224 tmp_lane_index = lane_index; 4225 } else if (lane_index >= 2 && lane_index <= 5) { 4226 tmp_lane_index = lane_index - 2; 4227 } else if (lane_index > 5 && lane_index <= 9) { 4228 tmp_lane_index = lane_index - 4; 4229 } else { 4230 tmp_lane_index = lane_index - 6; 4231 } 4232 4233 if (sys_en == LINE) { 4234 /* Select system Rx as specified in Line Tx array */ 4235 /* SYS_RX_PMA_DP_dp_ctrl */ 4236 PHYMOD_IF_ERR_RETURN 4237 (READ_FURIA_PMA_PMD_REG(pa,\ 4238 SYS_RX_PMA_DP_dp_ctrl_Adr,\ 4239 &sys_rx_dp_ctrl.data)); 4240 rx_die_lane = sys_rx_dp_ctrl.fields.out_sel; 4241 PHYMOD_IF_ERR_RETURN 4242 (_furia_get_pkg_lane(pa->addr, chip_id, rx_die_lane, tmp_lane_index, &rx_pkg_lane)); 4243 tx_source_array[lane_index] = rx_pkg_lane; 4244 } else { 4245 /* Select Line Rx as specified in System Tx array */ 4246 PHYMOD_IF_ERR_RETURN 4247 (READ_FURIA_PMA_PMD_REG(pa,\ 4248 LINE_RX_PMA_DP_dp_ctrl_Adr,\ 4249 &line_rx_dp_ctrl.data)); 4250 rx_die_lane = line_rx_dp_ctrl.fields.out_sel; 4251 PHYMOD_IF_ERR_RETURN 4252 (_furia_get_pkg_lane(pa->addr, chip_id, rx_die_lane, tmp_lane_index, &rx_pkg_lane)); 4253 tx_source_array[lane_index] = rx_pkg_lane; 4254 } 4255 } 4256 } 4257 /* Set the slice register with default values */ 4258 PHYMOD_IF_ERR_RETURN 4259 (WRITE_FURIA_SLICE_REG(pa, 0, 1, 0)); 4260 return PHYMOD_E_NONE; 4261 } 4262 4263 int furia_lane_cross_switch_map_set(const phymod_access_t *pa, 4264 const uint32_t *tx_source_array) 4265 { 4266 uint32_t chip_id = 0; 4267 uint32_t tx_die_lane = 0; 4268 uint32_t rx_die_lane = 0; 4269 uint32_t num_lanes = 0; 4270 uint32_t acc_flags = 0; 4271 int pkg_side = 0; 4272 int lane_index = 0; 4273 int sys_en = 0; 4274 uint32_t phy_id_idx = 0; 4275 uint32_t exist_phy = 0; 4276 const FURIA_PKG_LANE_CFG_t* tx_pkg_ln_des = NULL; 4277 const FURIA_PKG_LANE_CFG_t* rx_pkg_ln_des = NULL; 4278 SYS_RX_PMA_DP_DP_CTRL_t sys_rx_dp_ctrl; 4279 LINE_RX_PMA_DP_DP_CTRL_t line_rx_dp_ctrl; 4280 PHYMOD_MEMSET(&sys_rx_dp_ctrl, 0 , sizeof(SYS_RX_PMA_DP_DP_CTRL_t)); 4281 PHYMOD_MEMSET(&line_rx_dp_ctrl, 0 , sizeof(LINE_RX_PMA_DP_DP_CTRL_t)); 4282 4283 acc_flags = PHYMOD_ACC_FLAGS(pa); 4284 FURIA_GET_IF_SIDE(acc_flags, pkg_side); 4285 /* Get the chip id */ 4286 chip_id = _furia_get_chip_id(pa); 4287 FURIA_GET_NUM_LANES(chip_id, num_lanes); 4288 for (lane_index = 0; lane_index < num_lanes; lane_index++) { 4289 if (chip_id == FURIA_ID_82212) { 4290 if (((pa->lane_mask >> lane_index) & 1) != 0x1) { 4291 continue; 4292 } else { 4293 PHYMOD_IF_ERR_RETURN( 4294 furia_82212_lane_cross_switch_map_set(pa, tx_source_array)); 4295 return PHYMOD_E_NONE; 4296 } 4297 4298 } 4299 /* Set Swap configuration with newly supplied dst_lane*/ 4300 tx_pkg_ln_des = _furia_pkg_ln_des(chip_id, pa, lane_index); 4301 PHYMOD_NULL_CHECK(tx_pkg_ln_des); 4302 tx_die_lane = tx_pkg_ln_des->die_lane_num; 4303 rx_pkg_ln_des = _furia_pkg_ln_des(chip_id, pa, tx_source_array[lane_index]); 4304 PHYMOD_NULL_CHECK(rx_pkg_ln_des); 4305 rx_die_lane = rx_pkg_ln_des->die_lane_num; 4306 if(pkg_side == SIDE_A) { 4307 sys_en = tx_pkg_ln_des->sideA; 4308 } else { 4309 sys_en = tx_pkg_ln_des->sideB; 4310 } 4311 PHYMOD_IF_ERR_RETURN 4312 (WRITE_FURIA_SLICE_REG(pa, sys_en, 1<< tx_die_lane, tx_die_lane)); 4313 if (FURIA_IF_TX_SIDE(chip_id, pkg_side)) { 4314 _furia_get_phy_id_idx(pa->addr, &phy_id_idx, &exist_phy); 4315 if (sys_en == LINE) { 4316 /* Select system Rx as specified in Line Tx array */ 4317 /* SYS_RX_PMA_DP_dp_ctrl */ 4318 PHYMOD_IF_ERR_RETURN 4319 (READ_FURIA_PMA_PMD_REG(pa,\ 4320 SYS_RX_PMA_DP_dp_ctrl_Adr,\ 4321 &sys_rx_dp_ctrl.data)); 4322 sys_rx_dp_ctrl.fields.out_sel = rx_die_lane; 4323 PHYMOD_IF_ERR_RETURN 4324 (WRITE_FURIA_PMA_PMD_REG(pa,\ 4325 SYS_RX_PMA_DP_dp_ctrl_Adr,\ 4326 sys_rx_dp_ctrl.data)); 4327 if (exist_phy) { 4328 glb_phy_list[phy_id_idx].tx_lanes &= ~(0xF << (4 * lane_index)); 4329 glb_phy_list[phy_id_idx].tx_lanes |= ((tx_source_array[lane_index] & 0xF) << (4 * lane_index)); 4330 } 4331 } else { 4332 /* Select Line Rx as specified in System Tx array */ 4333 PHYMOD_IF_ERR_RETURN 4334 (READ_FURIA_PMA_PMD_REG(pa,\ 4335 LINE_RX_PMA_DP_dp_ctrl_Adr,\ 4336 &line_rx_dp_ctrl.data)); 4337 line_rx_dp_ctrl.fields.out_sel = rx_die_lane; 4338 PHYMOD_IF_ERR_RETURN 4339 (WRITE_FURIA_PMA_PMD_REG(pa,\ 4340 LINE_RX_PMA_DP_dp_ctrl_Adr,\ 4341 line_rx_dp_ctrl.data)); 4342 if (exist_phy) { 4343 if(FURIA_IS_DUPLEX(chip_id)){ 4344 glb_phy_list[phy_id_idx].tx_lanes &= ~(0xF << (4 * (lane_index + 4))); 4345 glb_phy_list[phy_id_idx].tx_lanes |= ((tx_source_array[lane_index] & 0xF) << (4 * (lane_index + 4))); 4346 } else { 4347 glb_phy_list[phy_id_idx].tx_lanes &= ~(0xF << (4 * lane_index)); 4348 glb_phy_list[phy_id_idx].tx_lanes |= ((tx_source_array[lane_index] & 0xF) << (4 * lane_index)); 4349 } 4350 } 4351 } 4352 } 4353 } 4354 /* Set firmware enable */ 4355 PHYMOD_IF_ERR_RETURN 4356 (_furia_fw_enable(pa)); 4357 /* Set the slice register with default values */ 4358 PHYMOD_IF_ERR_RETURN 4359 (WRITE_FURIA_SLICE_REG(pa, 0, 1, 0)); 4360 return PHYMOD_E_NONE; 4361 } 4362 4363 int furia_lane_cross_switch_map_get(const phymod_access_t *pa, uint32_t* tx_source_array) 4364 { 4365 uint32_t chip_id = 0; 4366 uint32_t tx_die_lane = 0; 4367 uint32_t rx_die_lane = 0; 4368 uint32_t rx_pkg_lane = 0; 4369 uint32_t num_lanes = 0; 4370 uint32_t acc_flags = 0; 4371 int pkg_side = 0; 4372 int lane_index = 0; 4373 int sys_en = 0; 4374 const FURIA_PKG_LANE_CFG_t* tx_pkg_ln_des = NULL; 4375 SYS_RX_PMA_DP_DP_CTRL_t sys_rx_dp_ctrl; 4376 LINE_RX_PMA_DP_DP_CTRL_t line_rx_dp_ctrl; 4377 PHYMOD_MEMSET(&sys_rx_dp_ctrl, 0 , sizeof(SYS_RX_PMA_DP_DP_CTRL_t)); 4378 PHYMOD_MEMSET(&line_rx_dp_ctrl, 0 , sizeof(LINE_RX_PMA_DP_DP_CTRL_t)); 4379 4380 acc_flags = PHYMOD_ACC_FLAGS(pa); 4381 FURIA_GET_IF_SIDE(acc_flags, pkg_side); 4382 /* Get the chip id */ 4383 chip_id = _furia_get_chip_id(pa); 4384 FURIA_GET_NUM_LANES(chip_id, num_lanes); 4385 for (lane_index = 0; lane_index < num_lanes; lane_index++) { 4386 if (chip_id == FURIA_ID_82212) { 4387 if (((pa->lane_mask >> lane_index) & 1) != 0x1) { 4388 continue; 4389 } else { 4390 PHYMOD_IF_ERR_RETURN( 4391 furia_82212_lane_cross_switch_map_get(pa, tx_source_array)); 4392 return PHYMOD_E_NONE; 4393 } 4394 } 4395 /* Set Swap configuration with newly supplied dst_lane*/ 4396 tx_pkg_ln_des = _furia_pkg_ln_des(chip_id, pa, lane_index); 4397 PHYMOD_NULL_CHECK(tx_pkg_ln_des); 4398 tx_die_lane = tx_pkg_ln_des->die_lane_num; 4399 if(pkg_side == SIDE_A) { 4400 sys_en = tx_pkg_ln_des->sideA; 4401 } else { 4402 sys_en = tx_pkg_ln_des->sideB; 4403 } 4404 PHYMOD_IF_ERR_RETURN 4405 (WRITE_FURIA_SLICE_REG(pa, sys_en, 1<< tx_die_lane, tx_die_lane)); 4406 if (FURIA_IF_TX_SIDE(chip_id, pkg_side)) { 4407 if (sys_en == LINE) { 4408 /* Select system Rx as specified in Line Tx array */ 4409 /* SYS_RX_PMA_DP_dp_ctrl */ 4410 PHYMOD_IF_ERR_RETURN 4411 (READ_FURIA_PMA_PMD_REG(pa,\ 4412 SYS_RX_PMA_DP_dp_ctrl_Adr,\ 4413 &sys_rx_dp_ctrl.data)); 4414 rx_die_lane = sys_rx_dp_ctrl.fields.out_sel; 4415 PHYMOD_IF_ERR_RETURN 4416 (_furia_get_pkg_lane(pa->addr, chip_id, rx_die_lane, lane_index, &rx_pkg_lane)); 4417 tx_source_array[lane_index] = rx_pkg_lane; 4418 } else { 4419 /* Select Line Rx as specified in System Tx array */ 4420 PHYMOD_IF_ERR_RETURN 4421 (READ_FURIA_PMA_PMD_REG(pa,\ 4422 LINE_RX_PMA_DP_dp_ctrl_Adr,\ 4423 &line_rx_dp_ctrl.data)); 4424 rx_die_lane = line_rx_dp_ctrl.fields.out_sel; 4425 PHYMOD_IF_ERR_RETURN 4426 (_furia_get_pkg_lane(pa->addr, chip_id, rx_die_lane, lane_index, &rx_pkg_lane)); 4427 tx_source_array[lane_index] = rx_pkg_lane; 4428 } 4429 } 4430 } 4431 /* Set the slice register with default values */ 4432 PHYMOD_IF_ERR_RETURN 4433 (WRITE_FURIA_SLICE_REG(pa, 0, 1, 0)); 4434 return PHYMOD_E_NONE; 4435 } 4436 4437 4438 int furia_force_tx_training_set(const phymod_access_t *pa, uint32_t enable) 4439 { 4440 int lane_map = 0; 4441 int pkg_side = 0; 4442 uint32_t chip_id = 0; 4443 int num_lanes = 0; 4444 int lane_index = 0; 4445 uint32_t acc_flags = 0; 4446 uint16_t die_lane_num = 0; 4447 FUR_GEN_CNTRLS_gpreg12_t gen_ctrls_gpreg12; 4448 FUR_GEN_CNTRLS_gpreg11_t gen_ctrls_gpreg11; 4449 const FURIA_PKG_LANE_CFG_t* pkg_ln_des = NULL; 4450 PHYMOD_MEMSET(&gen_ctrls_gpreg12, 0 , sizeof(FUR_GEN_CNTRLS_gpreg12_t)); 4451 PHYMOD_MEMSET(&gen_ctrls_gpreg11, 0 , sizeof(FUR_GEN_CNTRLS_gpreg11_t)); 4452 /* Get the lane map from phymod access */ 4453 lane_map = PHYMOD_ACC_LANE_MASK(pa); 4454 acc_flags = PHYMOD_ACC_FLAGS(pa); 4455 FURIA_GET_IF_SIDE(acc_flags, pkg_side); 4456 4457 /* Get the chip id */ 4458 chip_id = _furia_get_chip_id(pa); 4459 4460 FURIA_GET_NUM_LANES(chip_id, num_lanes); 4461 if(FURIA_IS_SIMPLEX(chip_id)) { 4462 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("Force Tx training is not applicable for simplex packages"))); 4463 } 4464 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 4465 if (((lane_map >> lane_index) & 1) == 0x1) { 4466 /* Get lane descriptor from package lane */ 4467 pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 0); 4468 PHYMOD_NULL_CHECK(pkg_ln_des); 4469 die_lane_num = pkg_ln_des->die_lane_num; 4470 if(pkg_side == SIDE_A) { 4471 /* Read GPReg12 */ 4472 PHYMOD_IF_ERR_RETURN 4473 (READ_FURIA_PMA_PMD_REG(pa,\ 4474 FUR_GEN_CNTRLS_gpreg12_Adr,\ 4475 &gen_ctrls_gpreg12.data)); 4476 if(enable) { 4477 gen_ctrls_gpreg12.fields.en_frc_tx_trng_line |= (1 << die_lane_num); 4478 } else { 4479 gen_ctrls_gpreg12.fields.en_frc_tx_trng_line &= ~(1 << die_lane_num); 4480 } 4481 4482 /* Write to GPReg12 */ 4483 PHYMOD_IF_ERR_RETURN 4484 (WRITE_FURIA_PMA_PMD_REG(pa,\ 4485 FUR_GEN_CNTRLS_gpreg12_Adr,\ 4486 gen_ctrls_gpreg12.data)); 4487 } else { 4488 /* Read GPReg11 */ 4489 PHYMOD_IF_ERR_RETURN 4490 (READ_FURIA_PMA_PMD_REG(pa,\ 4491 FUR_GEN_CNTRLS_gpreg11_Adr,\ 4492 &gen_ctrls_gpreg11.data)); 4493 if(enable) { 4494 gen_ctrls_gpreg11.fields.en_frc_tx_trng_sys |= (1 << die_lane_num); 4495 } else { 4496 gen_ctrls_gpreg11.fields.en_frc_tx_trng_sys &= ~(1 << die_lane_num); 4497 } 4498 /* Write to GPReg11 */ 4499 PHYMOD_IF_ERR_RETURN 4500 (WRITE_FURIA_PMA_PMD_REG(pa,\ 4501 FUR_GEN_CNTRLS_gpreg11_Adr,\ 4502 gen_ctrls_gpreg11.data)); 4503 } 4504 } 4505 } 4506 /* Set firmware enable */ 4507 PHYMOD_IF_ERR_RETURN 4508 (_furia_fw_enable(pa)); 4509 return PHYMOD_E_NONE; 4510 } 4511 int furia_force_tx_training_get(const phymod_access_t *pa, uint32_t *enable) 4512 { 4513 int lane_map = 0; 4514 int pkg_side = 0; 4515 uint32_t chip_id = 0; 4516 int num_lanes = 0; 4517 int lane_index = 0; 4518 uint32_t acc_flags = 0; 4519 uint16_t die_lane_num = 0; 4520 FUR_GEN_CNTRLS_gpreg12_t gen_ctrls_gpreg12; 4521 FUR_GEN_CNTRLS_gpreg11_t gen_ctrls_gpreg11; 4522 const FURIA_PKG_LANE_CFG_t* pkg_ln_des = NULL; 4523 PHYMOD_MEMSET(&gen_ctrls_gpreg12, 0 , sizeof(FUR_GEN_CNTRLS_gpreg12_t)); 4524 PHYMOD_MEMSET(&gen_ctrls_gpreg11, 0 , sizeof(FUR_GEN_CNTRLS_gpreg11_t)); 4525 /* Get the lane map from phymod access */ 4526 lane_map = PHYMOD_ACC_LANE_MASK(pa); 4527 acc_flags = PHYMOD_ACC_FLAGS(pa); 4528 FURIA_GET_IF_SIDE(acc_flags, pkg_side); 4529 4530 /* Get the chip id */ 4531 chip_id = _furia_get_chip_id(pa); 4532 4533 FURIA_GET_NUM_LANES(chip_id, num_lanes); 4534 if(FURIA_IS_SIMPLEX(chip_id)) { 4535 PHYMOD_DEBUG_ERROR(("Force Tx training is not applicable for simplex packages\n")); 4536 return PHYMOD_E_UNAVAIL; 4537 } 4538 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 4539 if (((lane_map >> lane_index) & 1) == 0x1) { 4540 /* Get lane descriptor from package lane */ 4541 pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 0); 4542 PHYMOD_NULL_CHECK(pkg_ln_des); 4543 die_lane_num = pkg_ln_des->die_lane_num; 4544 if(pkg_side == SIDE_A) { 4545 /* Read GPReg12 */ 4546 PHYMOD_IF_ERR_RETURN 4547 (READ_FURIA_PMA_PMD_REG(pa,\ 4548 FUR_GEN_CNTRLS_gpreg12_Adr,\ 4549 &gen_ctrls_gpreg12.data)); 4550 *enable = (gen_ctrls_gpreg12.fields.en_frc_tx_trng_line >> die_lane_num) & 1; 4551 } else { 4552 /* Read GPReg11 */ 4553 PHYMOD_IF_ERR_RETURN 4554 (READ_FURIA_PMA_PMD_REG(pa,\ 4555 FUR_GEN_CNTRLS_gpreg11_Adr,\ 4556 &gen_ctrls_gpreg11.data)); 4557 *enable = (gen_ctrls_gpreg11.fields.en_frc_tx_trng_sys >> die_lane_num) & 1; 4558 } 4559 } 4560 } 4561 return PHYMOD_E_NONE; 4562 } 4563 4564 int furia_force_tx_training_status_get(const phymod_access_t *pa, phymod_cl72_status_t* status) 4565 { 4566 int lane_map = 0; 4567 int pkg_side = 0; 4568 int wr_lane = 0; 4569 int sys_en = 0; 4570 int rd_lane = 0; 4571 uint32_t chip_id = 0; 4572 int num_lanes = 0; 4573 int lane_index = 0; 4574 uint32_t acc_flags = 0; 4575 CL93N72_IEEE_TX_CL93N72IT_BASE_R_PMD_STATUS_REGISTER_151_t cl93_72_status; 4576 const FURIA_PKG_LANE_CFG_t* pkg_ln_des = NULL; 4577 PHYMOD_MEMSET(&cl93_72_status, 0 , sizeof(CL93N72_IEEE_TX_CL93N72IT_BASE_R_PMD_STATUS_REGISTER_151_t)); 4578 /* Get the lane map from phymod access */ 4579 lane_map = PHYMOD_ACC_LANE_MASK(pa); 4580 acc_flags = PHYMOD_ACC_FLAGS(pa); 4581 FURIA_GET_IF_SIDE(acc_flags, pkg_side); 4582 4583 /* Get the chip id */ 4584 chip_id = _furia_get_chip_id(pa); 4585 4586 FURIA_GET_NUM_LANES(chip_id, num_lanes); 4587 if(FURIA_IS_SIMPLEX(chip_id)) { 4588 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("Force Tx training is not applicable for simplex packages"))); 4589 } 4590 /* Read Tx Training enable status */ 4591 PHYMOD_IF_ERR_RETURN 4592 (furia_force_tx_training_get(pa, &status->enabled)); 4593 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 4594 if (((lane_map >> lane_index) & 1) == 0x1) { 4595 /* Get lane descriptor from package lane */ 4596 pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 0); 4597 PHYMOD_NULL_CHECK(pkg_ln_des); 4598 if(pkg_side == SIDE_A) { 4599 sys_en = pkg_ln_des->sideA; 4600 } else { 4601 sys_en = pkg_ln_des->sideB; 4602 } 4603 4604 wr_lane = pkg_ln_des->slice_wr_val; 4605 rd_lane = pkg_ln_des->slice_rd_val; 4606 4607 4608 /* Program the slice register */ 4609 PHYMOD_IF_ERR_RETURN 4610 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 4611 4612 PHYMOD_IF_ERR_RETURN 4613 (READ_FURIA_PMA_PMD_REG(pa,\ 4614 CL93n72_IEEE_TX_cl93n72it_BASE_R_PMD_status_register_151_Adr,\ 4615 &cl93_72_status.data)); 4616 /* Extract Tx training status*/ 4617 status->locked = (!cl93_72_status.fields.cl93n72_ieee_training_failure) && (cl93_72_status.fields.cl93n72_ieee_receiver_status); 4618 break; 4619 } 4620 } 4621 /* Set the slice register to default */ 4622 PHYMOD_IF_ERR_RETURN 4623 (WRITE_FURIA_SLICE_REG(pa, 0, 1, 0)); 4624 return PHYMOD_E_NONE; 4625 } 4626 4627 /** Get Package index 4628 * 4629 * 4630 * 4631 * @param chip_id Chip id of furia device 4632 * @param pkg_idx Furia package 4633 * 4634 * @return PHYMOD_E_NONE successful function execution 4635 */ 4636 STATIC int furia_get_pkg_idx(uint32_t chip_id, int *pkg_idx) 4637 { 4638 int index = 0; 4639 for (index = 0; index < MAX_NUM_PACKAGES; index ++) { 4640 if(glb_package_array[index] != NULL) { 4641 if(glb_package_array[index]->chip_id == chip_id) { 4642 *pkg_idx = index; 4643 break; 4644 } 4645 } 4646 } 4647 if(index >= MAX_NUM_PACKAGES) { 4648 return PHYMOD_E_LIMIT; 4649 } 4650 return PHYMOD_E_NONE; 4651 } 4652 4653 4654 void _furia_get_phy_id_idx(uint32_t phy_id, uint32_t *idx, uint32_t *exist_phy) 4655 { 4656 unsigned int found = 0, i; 4657 /* coverity[write_constant_to_param] */ 4658 *idx = 0xFF; 4659 for (i=0; i < MAX_NUM_PHYS; i++) { 4660 if (glb_phy_list[i].valid && (glb_phy_list[i].phy_id == phy_id)) { 4661 found = 1; 4662 *idx = i; 4663 *exist_phy = 1; 4664 break; 4665 } 4666 } 4667 if (!found) { /* New PHYID*/ 4668 for (i = 0; i < MAX_NUM_PHYS; i++) { 4669 if (!glb_phy_list[i].valid) { 4670 glb_phy_list[i].phy_id = phy_id; 4671 glb_phy_list[i].valid = 1; 4672 *exist_phy = 0; 4673 *idx = i; 4674 break; 4675 } 4676 } 4677 } 4678 } 4679 4680 /** Get lane descriptor 4681 * This function is used to retrieve lane descriptor from package lane 4682 * 4683 * @param chip_id Chip id of furia device 4684 * @param pa Pointer to phymod access structure 4685 * @param pkg_lane Package lane number 4686 * @param tx_rx Tx or Rx 4687 * 4688 * @return pkg_ln_des Lane descriptor structure contains the info 4689 * about package lane and die lane mapping 4690 */ 4691 const FURIA_PKG_LANE_CFG_t* _furia_pkg_ln_des_lane_swap(uint32_t chip_id, const phymod_access_t *pa, int pkg_lane, int tx_rx) 4692 { 4693 const FURIA_PKG_LANE_CFG_t* pkg_ln_des = NULL; 4694 int pkg_idx; 4695 uint32_t acc_flags = 0; 4696 uint32_t pkg_side = 0; 4697 int index = 0; 4698 uint32_t exist_phy = 0; 4699 uint32_t phy_id_idx = 0; 4700 4701 acc_flags = PHYMOD_ACC_FLAGS(pa); 4702 FURIA_GET_IF_SIDE(acc_flags, pkg_side); 4703 _furia_get_phy_id_idx(pa->addr, &phy_id_idx, &exist_phy); 4704 if (FURIA_IS_DUPLEX(chip_id)) { 4705 if (pkg_side == SIDE_A) { 4706 if (tx_rx) { /* Rx side */ 4707 if (exist_phy) { 4708 pkg_lane = (glb_phy_list[phy_id_idx].tx_lanes >> (4 * (pkg_lane + 4))) & 0xF; 4709 } 4710 } else { /* Tx side */ 4711 for (index = 0; index < 4; index++) { 4712 if (exist_phy) { 4713 if ((((glb_phy_list[phy_id_idx].tx_lanes) >> (4 * index)) & 0xF) == pkg_lane) { 4714 pkg_lane = index; 4715 break; 4716 } 4717 } 4718 } 4719 } 4720 } 4721 4722 if ((pa->addr & 1) == 1) { 4723 if (FURIA_IS_DUAL_DIE_DUPLEX(chip_id)) { 4724 pkg_lane = pkg_lane + 4; 4725 } 4726 } 4727 } else { /* Simplex package */ 4728 if (pkg_side == SIDE_A) { 4729 for (index = 0; index < 7; index++) { 4730 if (exist_phy) { 4731 if ((((glb_phy_list[phy_id_idx].tx_lanes) >> (4 * index)) & 0xF) == pkg_lane) { 4732 if (chip_id == FURIA_ID_82212) { 4733 const int array_82212[2] = { 0x987610, 0xba5432}; 4734 pkg_lane = (array_82212[phy_id_idx & 1] >> (index *4)) & 0xF; 4735 } else { 4736 pkg_lane = index; 4737 } 4738 break; 4739 } 4740 } 4741 } 4742 } 4743 } 4744 /* Get the package index */ 4745 if (!furia_get_pkg_idx(chip_id, &pkg_idx)) { 4746 pkg_ln_des = glb_package_array[pkg_idx] + pkg_lane; 4747 } 4748 return pkg_ln_des; 4749 } 4750 4751 const FURIA_PKG_LANE_CFG_t* _furia_pkg_ln_des(uint32_t chip_id, const phymod_access_t *pa, int pkg_lane) 4752 { 4753 const FURIA_PKG_LANE_CFG_t* pkg_ln_des = NULL; 4754 int pkg_idx; 4755 4756 if ((pa->addr & 1) == 1) { 4757 if(FURIA_IS_DUPLEX(chip_id)) { 4758 if (FURIA_IS_DUAL_DIE_DUPLEX(chip_id)) { 4759 pkg_lane = pkg_lane + 4; 4760 } 4761 } 4762 } 4763 /* Get the package index */ 4764 if (!furia_get_pkg_idx(chip_id, &pkg_idx)) { 4765 pkg_ln_des = glb_package_array[pkg_idx] + pkg_lane; 4766 } 4767 return pkg_ln_des; 4768 } 4769 STATIC int _furia_get_pkg_lane(uint32_t phy_id, uint32_t chip_id, uint32_t die_lane, uint32_t lane_index, uint32_t *pkg_lane) 4770 { 4771 const FURIA_PKG_LANE_CFG_t* pkg_ln_des = NULL; 4772 int pkg_idx = 0; 4773 uint16_t i = 0; 4774 uint16_t start_index = 0; 4775 uint16_t max_lanes = 0; 4776 uint32_t phy_id_idx = 0; 4777 uint32_t exist_phy = 0; 4778 if(!furia_get_pkg_idx(chip_id, &pkg_idx)) { 4779 if(FURIA_IS_SIMPLEX(chip_id)) { 4780 start_index = 0; 4781 max_lanes = 8; 4782 if (chip_id == FURIA_ID_82212) { 4783 max_lanes = 12; 4784 } 4785 } else { 4786 if ((phy_id & 1) == 1) { 4787 if (FURIA_IS_DUAL_DIE_DUPLEX(chip_id)) { 4788 start_index = 4; 4789 max_lanes = 4; 4790 } else { 4791 start_index = 0; 4792 max_lanes = 4; 4793 } 4794 } else { 4795 start_index = 0; 4796 max_lanes = 4; 4797 } 4798 } 4799 } 4800 for(i = start_index; i < (start_index + max_lanes); i++) { 4801 pkg_ln_des = glb_package_array[pkg_idx] + i; 4802 if(pkg_ln_des->die_lane_num == die_lane) { 4803 if (FURIA_IS_SIMPLEX(chip_id)) { 4804 if ((chip_id == FURIA_ID_82212) && (((phy_id & 1) != pkg_ln_des->die_addr))) { 4805 continue; 4806 } 4807 4808 _furia_get_phy_id_idx(phy_id, &phy_id_idx, &exist_phy); 4809 if (exist_phy) { 4810 if (pkg_ln_des->pkg_lane_num == (((glb_phy_list[phy_id_idx].tx_lanes) >> (4 *lane_index)) & 0xF)) { 4811 *pkg_lane = pkg_ln_des->pkg_lane_num; 4812 break; 4813 } else { 4814 continue; 4815 } 4816 } 4817 } else { 4818 *pkg_lane = pkg_ln_des->pkg_lane_num; 4819 if (FURIA_IS_DUAL_DIE_DUPLEX(chip_id)) { 4820 if ((phy_id & 1) == 1) { 4821 *pkg_lane -= 4; 4822 } 4823 } 4824 break; 4825 } 4826 } 4827 } 4828 if(i >= (start_index + max_lanes)) { 4829 return PHYMOD_E_FAIL; 4830 } 4831 4832 return PHYMOD_E_NONE; 4833 } 4834 4835 /** Get ref clock frequency 4836 * This function returns ref_clk_freq from ref clock freq type 4837 * 4838 * @param ref_clk_freq Ref clk type 4839 * 4840 * @return freq Ref clk freq in Mhz based on ref clk freq type 4841 */ 4842 int _furia_get_ref_clock_freq_in_mhz(FURIA_REF_CLK_E ref_clk_freq) 4843 { 4844 int freq = 0; 4845 if (ref_clk_freq == REF_CLK_106p25MHz) { 4846 freq = 10625; 4847 } else if (ref_clk_freq == REF_CLK_174p703125MHz) { /* 174.703125 Mhz */ 4848 freq = 17470; 4849 } else if (ref_clk_freq == REF_CLK_156p25Mhz) { /* 156.25 Mhz */ 4850 freq = 15625; 4851 } else if (ref_clk_freq == REF_CLK_125Mhz) { /* 125 Mhz */ 4852 freq = 12500; 4853 } else if (ref_clk_freq == REF_CLK_156p637Mhz) { /* 156.637 Mhz */ 4854 freq = 15663; 4855 } else if (ref_clk_freq == REF_CLK_161p1328125Mhz) { /* 161.1328125 Mhz */ 4856 freq = 16113; 4857 } else if (ref_clk_freq == REF_CLK_168p04Mhz) { /* 168.04 Mhz */ 4858 freq = 16804; 4859 } else if (ref_clk_freq == REF_CLK_172p64Mhz) { /* 172.64 Mhz */ 4860 freq = 17264; 4861 } else { 4862 PHYMOD_RETURN_WITH_ERR 4863 (PHYMOD_E_PARAM, 4864 (_PHYMOD_MSG(" Ref clk is not supported by furia"))); 4865 } 4866 return(freq); 4867 } 4868 4869 /** Config clk scaler 4870 * This function is used to program clk scaler 4871 * 4872 * @param pa Pointer to phymod access structure 4873 * @param ref_clk_freq Furia ref clk type 4874 * 4875 * @return PHYMOD_E_NONE successful function execution 4876 */ 4877 STATIC int _furia_config_clk_scaler_val(const phymod_access_t *pa, FURIA_REF_CLK_E ref_clk_freq) 4878 { 4879 uint16_t clock_scaler_code = 0; 4880 FUR_GEN_CNTRLS_GEN_CONTROL3_t gen_ctrl_3; 4881 PHYMOD_MEMSET(&gen_ctrl_3, 0 , sizeof(FUR_GEN_CNTRLS_GEN_CONTROL3_t)); 4882 PHYMOD_IF_ERR_RETURN 4883 (READ_FURIA_PMA_PMD_REG(pa,\ 4884 FUR_GEN_CNTRLS_gen_control3_Adr,\ 4885 &gen_ctrl_3.data)); 4886 gen_ctrl_3.fields.clock_sclr_lock = 0x1; 4887 PHYMOD_IF_ERR_RETURN 4888 (WRITE_FURIA_PMA_PMD_REG(pa,\ 4889 FUR_GEN_CNTRLS_gen_control3_Adr,\ 4890 gen_ctrl_3.data)); 4891 switch (ref_clk_freq) { 4892 case REF_CLK_106p25MHz: 4893 clock_scaler_code = 0x4; 4894 break; 4895 case REF_CLK_168p04Mhz: 4896 case REF_CLK_174p703125MHz: 4897 clock_scaler_code = 0x0; 4898 break; 4899 case REF_CLK_156p25Mhz: 4900 case REF_CLK_156p637Mhz: 4901 clock_scaler_code = 0x2; 4902 break; 4903 case REF_CLK_125Mhz: 4904 clock_scaler_code = 0x3; 4905 break; 4906 case REF_CLK_161p1328125Mhz: 4907 clock_scaler_code = 0x1; 4908 break; 4909 default: 4910 PHYMOD_RETURN_WITH_ERR 4911 (PHYMOD_E_PARAM, 4912 (_PHYMOD_MSG(" This Ref Clock is not supported by Furia"))); 4913 4914 break; 4915 4916 } 4917 PHYMOD_IF_ERR_RETURN 4918 (READ_FURIA_PMA_PMD_REG(pa,\ 4919 FUR_GEN_CNTRLS_gen_control3_Adr,\ 4920 &gen_ctrl_3.data)); 4921 4922 gen_ctrl_3.fields.clock_scaler_code = clock_scaler_code; 4923 4924 PHYMOD_IF_ERR_RETURN 4925 (WRITE_FURIA_PMA_PMD_REG(pa,\ 4926 FUR_GEN_CNTRLS_gen_control3_Adr,\ 4927 gen_ctrl_3.data)); 4928 PHYMOD_IF_ERR_RETURN 4929 (READ_FURIA_PMA_PMD_REG(pa,\ 4930 FUR_GEN_CNTRLS_gen_control3_Adr,\ 4931 &gen_ctrl_3.data)); 4932 gen_ctrl_3.fields.clock_sclr_lock = 0x0; 4933 PHYMOD_IF_ERR_RETURN 4934 (WRITE_FURIA_PMA_PMD_REG(pa,\ 4935 FUR_GEN_CNTRLS_gen_control3_Adr,\ 4936 gen_ctrl_3.data)); 4937 return PHYMOD_E_NONE; 4938 } 4939 4940 /** Get PHY type 4941 * This function is used to retrieve the PHY type 4942 * based on the interface value. 4943 * 4944 * @param intf Interface type 4945 * @param speed Data rate 4946 * 4947 * @return phy_type PHY type calculated based on interface 4948 */ 4949 STATIC uint16_t _furia_get_phy_type(phymod_interface_t intf, uint32_t speed) 4950 { 4951 uint16_t phy_type = 0; 4952 switch (intf) { 4953 case phymodInterfaceLR2: 4954 case phymodInterfaceSR2: 4955 case phymodInterfaceER2: 4956 if (speed == SPEED_50G || speed == SPEED_53G) {/* 50G SR2/LR2/ER2 */ 4957 phy_type = 0x1; 4958 } 4959 break; 4960 case phymodInterfaceSR: 4961 case phymodInterfaceCR4: 4962 case phymodInterfaceCR10: 4963 case phymodInterfaceLR4: 4964 case phymodInterfaceLR: 4965 case phymodInterfaceSR4: 4966 case phymodInterfaceER: 4967 case phymodInterfaceER4: 4968 if (speed == SPEED_6G) { 4969 phy_type = 0x4; 4970 } else { 4971 phy_type = 0x1; 4972 } 4973 4974 break; 4975 case phymodInterfaceKX: 4976 case phymodInterfaceKX4: 4977 case phymodInterfaceKR: 4978 case phymodInterfaceKR2: 4979 case phymodInterfaceKR4: 4980 phy_type = 0x0; 4981 break; 4982 case phymodInterfaceCX: 4983 case phymodInterfaceCR: 4984 case phymodInterfaceCR2: 4985 case phymodInterfaceSFI: 4986 case phymodInterfaceXFI: 4987 case phymodInterfaceCAUI4_C2C: 4988 case phymodInterfaceCAUI4_C2M: 4989 case phymodInterfaceXLAUI: 4990 case phymodInterfaceCAUI4: 4991 case phymodInterfaceCAUI: 4992 phy_type = 0x1;/*mixed mode 10G*/ 4993 break; 4994 case phymodInterfaceCX4: 4995 case phymodInterfaceVSR: 4996 phy_type = 0x4; 4997 break; 4998 default: 4999 break; 5000 } 5001 5002 return phy_type; 5003 } 5004 5005 /** Get link type 5006 * This function is used to retrieve the operating mode of the PHY 5007 * 5008 * @param intf Phymod interface type 5009 * @param speed User specified speed 5010 * @param otn_type OTN type 5011 * 5012 * @return link_type Link type calculated based on intf and speed 5013 */ 5014 STATIC uint16_t _furia_get_link_type(phymod_interface_t intf, uint32_t speed, phymod_otn_type_t otn_type) 5015 { 5016 uint16_t link_type = 0; 5017 switch (intf) { 5018 case phymodInterfaceKX: 5019 link_type = 0x1; 5020 break; 5021 case phymodInterfaceCAUI4_C2C: 5022 case phymodInterfaceCAUI4_C2M: 5023 case phymodInterfaceCAUI4: 5024 case phymodInterfaceCAUI: 5025 link_type = 0xf; 5026 break; 5027 case phymodInterfaceKR: 5028 if (speed == SPEED_10G || speed == SPEED_11G || speed == SPEED_11P5G) { 5029 link_type = 0x2; 5030 } else if (speed == SPEED_20G || speed == SPEED_21G || speed == SPEED_23G) { 5031 link_type = 0x6; 5032 } else { 5033 link_type = 0x8; 5034 } 5035 break; 5036 case phymodInterfaceSR: 5037 case phymodInterfaceLR: 5038 case phymodInterfaceER: 5039 if (speed == SPEED_10G || speed == SPEED_11G || speed == SPEED_11P5G) { 5040 link_type = 0x1; 5041 } else if (speed == SPEED_20G || speed == SPEED_21G || speed == SPEED_23G) { 5042 link_type = 0x6; 5043 } else if (speed == SPEED_6G) { 5044 link_type = 0x5; 5045 } else { 5046 link_type = 0x7; 5047 } 5048 break; 5049 case phymodInterfaceSR2: 5050 case phymodInterfaceLR2: 5051 case phymodInterfaceER2:/* 50G SR2/LR2/ER2 */ 5052 if (speed == SPEED_50G || speed == SPEED_53G) { 5053 link_type = 0x7; 5054 } 5055 break; 5056 case phymodInterfaceCR4: 5057 if (speed == SPEED_100G || speed == SPEED_106G) { 5058 link_type = 0x5; 5059 } else { 5060 link_type = 0x2; 5061 } 5062 break; 5063 case phymodInterfaceKR4: 5064 case phymodInterfaceLR4: 5065 case phymodInterfaceSR4: 5066 case phymodInterfaceER4: 5067 if (speed == SPEED_100G || speed == SPEED_106G) { 5068 link_type = 0x4; 5069 } else { 5070 link_type = 0x3; 5071 } 5072 break; 5073 case phymodInterfaceKR2: 5074 if (speed == SPEED_20G || speed == SPEED_21G) { 5075 link_type = 0x5; 5076 } else if (speed == SPEED_40G || speed == SPEED_42G) { 5077 link_type = 0x7; 5078 } else { 5079 link_type = 0x9; 5080 } 5081 break; 5082 case phymodInterfaceCX: 5083 case phymodInterfaceCR: 5084 case phymodInterfaceCR2: 5085 case phymodInterfaceSFI: 5086 case phymodInterfaceCX4: 5087 if (speed == SPEED_10G || speed == SPEED_11G || speed == SPEED_11P5G || 5088 speed == SPEED_40G || speed == SPEED_42G) { 5089 link_type = 0xd ; /*mixed mode. old 0x4*/ 5090 }else if (speed == SPEED_10G || speed == SPEED_11P18G || speed == SPEED_11P5G || speed == SPEED_11P25G || 5091 speed == SPEED_40G || speed == SPEED_42G || speed == SPEED_8P5G ) { 5092 link_type = 0x4; 5093 } else if ( speed == SPEED_25G || speed == SPEED_27G || speed == SPEED_50G || speed == SPEED_53G) { 5094 link_type = 0xc; /*mixed mode. old = 0x5*/ 5095 } 5096 break; 5097 case phymodInterfaceVSR: 5098 link_type = 0x3; 5099 break; 5100 case phymodInterfaceXFI: 5101 case phymodInterfaceXLAUI: 5102 link_type = 0xe; /*mixed mode . old = 0x2*/ 5103 break; 5104 case phymodInterfaceOTN: 5105 if(( otn_type == phymodOTNOTU1e )||( otn_type == phymodOTNOTU2e )){ 5106 link_type = 0x1; 5107 }else if( otn_type == phymodOTNOTU3 || otn_type == phymodOTNOTU3e2 ){ 5108 link_type = 0x2; 5109 }else if( otn_type == phymodOTNOTU4 ){ 5110 link_type = 0x3; 5111 } 5112 break; 5113 5114 default: 5115 break; 5116 } 5117 return link_type; 5118 } 5119 5120 /** Get furia ref clk type 5121 * This function is used to convert the phymod ref clk type to 5122 * furia ref clk type 5123 * 5124 * @param ref_clk Phymod ref clk type 5125 * @param ref_clk_freq Furia ref clk type 5126 * 5127 * @return PHYMOD_E_NONE successful function execution 5128 */ 5129 STATIC int _furia_phymod_to_furia_type_ref_clk_freq(phymod_ref_clk_t ref_clk, FURIA_REF_CLK_E *ref_clk_freq) 5130 { 5131 switch (ref_clk) { 5132 case phymodRefClk156Mhz: 5133 *ref_clk_freq = REF_CLK_156p25Mhz; 5134 break; 5135 case phymodRefClk158Mhz: 5136 case phymodRefClk157Mhz: 5137 case phymodRefClk159Mhz: 5138 *ref_clk_freq = REF_CLK_156p637Mhz; 5139 break; 5140 case phymodRefClk125Mhz: 5141 *ref_clk_freq = REF_CLK_125Mhz; 5142 break; 5143 case phymodRefClk106Mhz: 5144 *ref_clk_freq = REF_CLK_106p25MHz; 5145 break; 5146 case phymodRefClk161Mhz: 5147 *ref_clk_freq = REF_CLK_161p1328125Mhz; 5148 break; 5149 case phymodRefClk168Mhz: 5150 *ref_clk_freq = REF_CLK_168p04Mhz; 5151 break; 5152 case phymodRefClk174Mhz: 5153 *ref_clk_freq = REF_CLK_174p703125MHz; 5154 break; 5155 default: 5156 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_PARAM, 5157 (_PHYMOD_MSG(" This Ref Clock is not supported by Furia"))); 5158 break; 5159 } 5160 return PHYMOD_E_NONE; 5161 } 5162 5163 /** Get the PLL mode for OTN 5164 * This function calculates pll mode based on the refclock & speed 5165 * @param ref_clk PHYMOD ref clk frequency 5166 * @param speed speed specified by user 5167 * @param pll_mode pll mode calculated based on ref clk and speed 5168 * @param higig_mode Higig mode 5169 * 5170 * @return PHYMOD_E_NONE successful function execution 5171 */ 5172 STATIC int _furia_get_pll_mode_otn(phymod_ref_clk_t ref_clk, uint32_t otn_type, FALCON_PLL_MODE_E *pll_mode) { 5173 #ifdef DEB 5174 printf(" [ %s at %d ] \n",__FUNCTION__,__LINE__); 5175 #endif 5176 switch((int)ref_clk){ 5177 case phymodRefClk174Mhz: 5178 switch(otn_type){ 5179 case phymodOTNOTU4:/*OTU4.4*/ 5180 *pll_mode = PLL_MODE_160; 5181 break; 5182 case phymodOTNOTU3:/*OTU3.4*/ 5183 *pll_mode = PLL_MODE_128; 5184 break; 5185 default:/*OTU4.10. i.e no phymod support for 4.10 so checking it in default state*/ 5186 *pll_mode = PLL_MODE_128; 5187 break; 5188 } 5189 break; 5190 case phymodRefClk161Mhz: 5191 switch(otn_type){ 5192 case phymodOTNOTU3:/*OTU3.4*/ 5193 *pll_mode = PLL_MODE_132; 5194 break; 5195 } 5196 break; 5197 case phymodRefClk157Mhz: 5198 case phymodRefClk158Mhz: 5199 *pll_mode = PLL_MODE_140; 5200 break; 5201 case phymodRefClk159Mhz: 5202 *pll_mode = PLL_MODE_140; 5203 break; 5204 case phymodRefClk156Mhz: 5205 switch(otn_type){ 5206 case phymodOTNOTU3:/*OTU3.4*/ 5207 *pll_mode = PLL_MODE_140; 5208 break; 5209 } 5210 break; 5211 case phymodRefClk168Mhz: 5212 switch(otn_type){ 5213 case phymodOTNOTU3:/*OTU3.4*/ 5214 *pll_mode = PLL_MODE_128; 5215 break; 5216 case phymodOTNOTU4:/*OTU4.4*/ 5217 *pll_mode = PLL_MODE_165; 5218 break; 5219 case phymodOTNOTU2e:/*OTU2e*/ 5220 case phymodOTNOTU1e:/*OTU1e*/ 5221 *pll_mode = PLL_MODE_132; 5222 break; 5223 } 5224 break; 5225 5226 } 5227 return PHYMOD_E_NONE; 5228 } 5229 5230 5231 /** Get the PLL mode 5232 * This function calculates pll mode based on the refclock & speed 5233 * @param ref_clk PHYMOD ref clk frequency 5234 * @param speed speed specified by user 5235 * @param pll_mode pll mode calculated based on ref clk and speed 5236 * @param higig_mode Higig mode 5237 * 5238 * @return PHYMOD_E_NONE successful function execution 5239 */ 5240 STATIC int _furia_get_pll_mode(phymod_ref_clk_t ref_clk, uint32_t speed, uint32_t higig_mode, FALCON_PLL_MODE_E *pll_mode) { 5241 switch (ref_clk) { 5242 case phymodRefClk157Mhz: 5243 case phymodRefClk158Mhz: 5244 *pll_mode = PLL_MODE_140; 5245 break; 5246 case phymodRefClk156Mhz: 5247 switch(speed) { 5248 case SPEED_100G: 5249 case SPEED_50G: 5250 case SPEED_25G: 5251 *pll_mode = PLL_MODE_165; 5252 break; 5253 case SPEED_106G: 5254 case SPEED_53G: 5255 case SPEED_27G: 5256 if (higig_mode) { 5257 *pll_mode = PLL_MODE_175; 5258 } 5259 break; 5260 case SPEED_40G: 5261 case SPEED_20G: 5262 case SPEED_10G: 5263 *pll_mode = PLL_MODE_132; 5264 break; 5265 case SPEED_42G: 5266 case SPEED_21G: 5267 case SPEED_11G: 5268 if (higig_mode) { 5269 *pll_mode = PLL_MODE_140; 5270 } 5271 break; 5272 case SPEED_1G: 5273 if(*pll_mode != PLL_MODE_165) 5274 *pll_mode = PLL_MODE_132; 5275 break; 5276 case SPEED_14G: 5277 *pll_mode = PLL_MODE_264; 5278 break; 5279 case SPEED_8P5G: 5280 *pll_mode = PLL_MODE_160; 5281 break; 5282 case SPEED_4P25G: 5283 *pll_mode = PLL_MODE_160; 5284 break; 5285 case SPEED_9P95G: 5286 *pll_mode = PLL_MODE_128; 5287 break; 5288 5289 default: 5290 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_PARAM, 5291 (_PHYMOD_MSG(" This speed is not supported by Furia"))); 5292 break; 5293 } 5294 break; 5295 case phymodRefClk125Mhz: 5296 switch(speed) { 5297 case SPEED_23G: 5298 *pll_mode = PLL_MODE_184; 5299 break; 5300 case SPEED_15G: 5301 *pll_mode = PLL_MODE_120; 5302 break; 5303 case SPEED_12P5G: 5304 *pll_mode = PLL_MODE_200; 5305 break; 5306 case SPEED_11P5G: 5307 *pll_mode = PLL_MODE_184; 5308 break; 5309 case SPEED_11P25G: 5310 *pll_mode = PLL_MODE_180; 5311 break; 5312 5313 case SPEED_7P5G: 5314 *pll_mode = PLL_MODE_120; 5315 break; 5316 default: 5317 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_PARAM, 5318 (_PHYMOD_MSG(" This speed is not supported by Furia"))); 5319 break; 5320 } 5321 break; 5322 case phymodRefClk106Mhz: 5323 switch(speed) { 5324 case SPEED_28G: 5325 *pll_mode = PLL_MODE_264; 5326 break; 5327 case SPEED_14G: 5328 *pll_mode = PLL_MODE_264; 5329 break; 5330 case SPEED_8P5G: 5331 *pll_mode = PLL_MODE_160; 5332 break; 5333 case SPEED_4P25G: 5334 *pll_mode = PLL_MODE_160; 5335 break; 5336 default: 5337 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_PARAM, 5338 (_PHYMOD_MSG(" This speed is not supported by Furia"))); 5339 break; 5340 } 5341 break; 5342 case phymodRefClk161Mhz: 5343 switch(speed) { 5344 case SPEED_100G: 5345 case SPEED_50G: 5346 case SPEED_25G: 5347 case SPEED_12P5G: 5348 *pll_mode = PLL_MODE_160; 5349 break; 5350 case SPEED_43G: 5351 *pll_mode = PLL_MODE_132; 5352 break; 5353 5354 case SPEED_40G: 5355 case SPEED_20G: 5356 case SPEED_10G: 5357 *pll_mode = PLL_MODE_128; 5358 break; 5359 case SPEED_1G: 5360 if(*pll_mode !=PLL_MODE_160) 5361 *pll_mode = PLL_MODE_128; 5362 break; 5363 default: 5364 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_PARAM, 5365 (_PHYMOD_MSG(" This speed is not supported by Furia"))); 5366 break; 5367 } 5368 break; 5369 case phymodRefClk168Mhz: 5370 switch(speed) { 5371 case SPEED_43G: 5372 *pll_mode = PLL_MODE_128; 5373 break; 5374 case SPEED_40G: 5375 *pll_mode = PLL_MODE_128; 5376 break; 5377 case SPEED_100G: 5378 case SPEED_111G: 5379 *pll_mode = PLL_MODE_165; 5380 break; 5381 case SPEED_11P18G: 5382 *pll_mode = PLL_MODE_132; 5383 break; 5384 case SPEED_10P7G:/*for OTN2*/ 5385 *pll_mode = PLL_MODE_128; 5386 break; 5387 } 5388 break; 5389 case phymodRefClk174Mhz: 5390 switch(speed) { 5391 case SPEED_100G: 5392 case SPEED_50G: 5393 case SPEED_25G: 5394 *pll_mode = PLL_MODE_160; 5395 break; 5396 default: 5397 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_PARAM, 5398 (_PHYMOD_MSG(" This speed is not supported by Furia"))); 5399 break; 5400 } 5401 break; 5402 case phymodRefClk159Mhz: 5403 if(speed == SPEED_10P518G){ 5404 *pll_mode = PLL_MODE_132; 5405 }else if(speed == SPEED_44P57G || speed == SPEED_44P583G ){ 5406 *pll_mode = PLL_MODE_140; 5407 }else{ 5408 return PHYMOD_E_PARAM; 5409 } 5410 break; 5411 default: 5412 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_PARAM, 5413 (_PHYMOD_MSG(" This ref clock is not supported by Furia"))); 5414 break; 5415 } 5416 return PHYMOD_E_NONE; 5417 } 5418 5419 int _furia_get_pll_for_serdes(phymod_ref_clk_t ref_clk, uint32_t speed, FALCON_PLL_MODE_E pll_mode, uint16_t *serdes_pll_mode) { 5420 switch (ref_clk) { 5421 case phymodRefClk174Mhz: 5422 switch(speed) { 5423 case SPEED_11P18G: 5424 if(pll_mode == PLL_MODE_128){ 5425 *serdes_pll_mode = FALCON_FURIA_pll_div_128x; 5426 }else{ 5427 return PHYMOD_E_PARAM; 5428 } 5429 break; 5430 case SPEED_111G: 5431 if(pll_mode == PLL_MODE_160){ 5432 *serdes_pll_mode = FALCON_FURIA_pll_div_160x_refc174; 5433 }else{ 5434 return PHYMOD_E_PARAM; 5435 } 5436 5437 } 5438 break; 5439 case phymodRefClk157Mhz: 5440 case phymodRefClk158Mhz: 5441 switch(speed) { 5442 case SPEED_11G: 5443 if(pll_mode == PLL_MODE_140){ 5444 *serdes_pll_mode = FALCON_FURIA_pll_div_140x; 5445 }else{ 5446 return PHYMOD_E_PARAM; 5447 } 5448 break; 5449 5450 } 5451 break; 5452 5453 case phymodRefClk156Mhz: 5454 switch(speed) { 5455 case SPEED_43G: 5456 if(pll_mode == PLL_MODE_140){ 5457 *serdes_pll_mode = FALCON_FURIA_pll_div_140x; 5458 }else{ 5459 return PHYMOD_E_PARAM; 5460 } 5461 break; 5462 case SPEED_9P95G: 5463 if(pll_mode == PLL_MODE_128){ 5464 *serdes_pll_mode = FALCON_FURIA_pll_div_128x; 5465 }else{ 5466 return PHYMOD_E_PARAM; 5467 } 5468 break; 5469 case SPEED_40G: 5470 case SPEED_42G: 5471 case SPEED_20G: 5472 case SPEED_21G: 5473 case SPEED_11G: 5474 case SPEED_10G: 5475 case SPEED_1G: 5476 if(pll_mode == PLL_MODE_140){ 5477 *serdes_pll_mode = FALCON_FURIA_pll_div_140x; 5478 }else if(pll_mode == PLL_MODE_132){ 5479 *serdes_pll_mode = FALCON_FURIA_pll_div_132x; 5480 }else{ 5481 return PHYMOD_E_PARAM; 5482 } 5483 break; 5484 case SPEED_14G: 5485 case SPEED_8P5G: 5486 case SPEED_4P25G: 5487 if(pll_mode == PLL_MODE_264){ 5488 *serdes_pll_mode = FALCON_FURIA_pll_div_264x; 5489 }else if(pll_mode == PLL_MODE_160){ 5490 *serdes_pll_mode = FALCON_FURIA_pll_div_160x; 5491 }else{ 5492 return PHYMOD_E_PARAM; 5493 } 5494 break; 5495 5496 case SPEED_100G: 5497 case SPEED_106G: 5498 case SPEED_50G: 5499 case SPEED_53G: 5500 case SPEED_25G: 5501 case SPEED_27G: 5502 case SPEED_12P5G: 5503 if(pll_mode == PLL_MODE_160){ 5504 *serdes_pll_mode = FALCON_FURIA_pll_div_160x; 5505 }else if(pll_mode == PLL_MODE_175){ 5506 *serdes_pll_mode = FALCON_FURIA_pll_div_175x; 5507 }else if(pll_mode == PLL_MODE_165){ 5508 *serdes_pll_mode = FALCON_FURIA_pll_div_165x; 5509 }else{ 5510 return PHYMOD_E_PARAM; 5511 } 5512 break; 5513 } 5514 break; 5515 case phymodRefClk125Mhz: 5516 switch(speed) { 5517 case SPEED_23G: 5518 case SPEED_11P5G: 5519 case SPEED_11P25G: 5520 case SPEED_7P5G: 5521 case SPEED_12P5G: 5522 case SPEED_15G: 5523 if(pll_mode == PLL_MODE_184){ 5524 *serdes_pll_mode = FALCON_FURIA_pll_div_184x; 5525 }else if(pll_mode == PLL_MODE_200){ 5526 *serdes_pll_mode = FALCON_FURIA_pll_div_200x; 5527 }else if(pll_mode == PLL_MODE_120){ 5528 *serdes_pll_mode = FALCON_FURIA_pll_div_120x_refc125; 5529 }else if(pll_mode == PLL_MODE_180){ 5530 *serdes_pll_mode = FALCON_FURIA_pll_div_180x_refc125; 5531 }else{ 5532 return PHYMOD_E_PARAM; 5533 } 5534 break; 5535 } 5536 break; 5537 case phymodRefClk161Mhz: 5538 switch(speed) { 5539 case SPEED_100G: 5540 case SPEED_50G: 5541 case SPEED_25G: 5542 if(pll_mode == PLL_MODE_160){ 5543 *serdes_pll_mode = FALCON_FURIA_pll_div_160x; 5544 }else{ 5545 return PHYMOD_E_PARAM; 5546 } 5547 break; 5548 case SPEED_43G: 5549 case SPEED_40G: 5550 case SPEED_20G: 5551 case SPEED_10G: 5552 case SPEED_1G: 5553 if(pll_mode == PLL_MODE_132){ 5554 *serdes_pll_mode = FALCON_FURIA_pll_div_132x; 5555 }else if(pll_mode == PLL_MODE_128){ 5556 *serdes_pll_mode = FALCON_FURIA_pll_div_128x; 5557 }else{ 5558 return PHYMOD_E_PARAM; 5559 } 5560 break; 5561 default: 5562 break; 5563 } 5564 break; 5565 case phymodRefClk168Mhz: 5566 switch(speed) { 5567 case SPEED_111G: 5568 case SPEED_100G: 5569 if(pll_mode == PLL_MODE_165){ 5570 *serdes_pll_mode = FALCON_FURIA_pll_div_165x; 5571 }else{ 5572 return PHYMOD_E_PARAM; 5573 } 5574 break; 5575 case SPEED_11P18G: 5576 if(pll_mode == PLL_MODE_132){ 5577 *serdes_pll_mode = FALCON_FURIA_pll_div_132x; 5578 }else{ 5579 return PHYMOD_E_PARAM; 5580 } 5581 break; 5582 case SPEED_43G: 5583 case SPEED_40G: 5584 case SPEED_10P7G: 5585 if(pll_mode == PLL_MODE_128){ 5586 *serdes_pll_mode = FALCON_FURIA_pll_div_128x; 5587 }else{ 5588 return PHYMOD_E_PARAM; 5589 } 5590 break; 5591 } 5592 break; 5593 case phymodRefClk106Mhz: 5594 switch(speed) { 5595 case SPEED_8P5G: 5596 case SPEED_4P25G: 5597 if(pll_mode == PLL_MODE_160){ 5598 *serdes_pll_mode = FALCON_FURIA_pll_div_160x_vco2; 5599 }else{ 5600 return PHYMOD_E_PARAM; 5601 } 5602 break; 5603 case SPEED_14P025G: 5604 case SPEED_28P05G: 5605 if(pll_mode == PLL_MODE_264){ 5606 *serdes_pll_mode = FALCON_FURIA_pll_div_264x; 5607 }else{ 5608 return PHYMOD_E_PARAM; 5609 } 5610 break; 5611 5612 } 5613 break; 5614 case phymodRefClk159Mhz: 5615 switch(speed) { 5616 case SPEED_10P518G: 5617 case SPEED_44P57G: 5618 case SPEED_44P583G: 5619 if(pll_mode == PLL_MODE_132){ 5620 *serdes_pll_mode = FALCON_FURIA_pll_div_132x; 5621 }else if(pll_mode == PLL_MODE_140){ 5622 *serdes_pll_mode = FALCON_FURIA_pll_div_140x; 5623 }else{ 5624 return PHYMOD_E_PARAM; 5625 } 5626 break; 5627 5628 } 5629 break; 5630 5631 default: 5632 break; 5633 } 5634 #ifdef DEB 5635 printf(" [ %s at %d : clk = %d speed = %d serdespll=%d ] \n",__FUNCTION__,__LINE__,ref_clk,speed,*serdes_pll_mode); 5636 #endif 5637 return PHYMOD_E_NONE; 5638 } 5639 5640 5641 STATIC int _furia_config_clk_scaler_without_m0_reset(const phymod_access_t *pa, FURIA_REF_CLK_E ref_clk_freq) 5642 { 5643 FUR_MICRO_BOOT_BOOT_POR_t micro_boot_por; 5644 FUR_GEN_CNTRLS_BOOT_t gen_ctrl_boot; 5645 int retry_count = 40; 5646 PHYMOD_MEMSET(µ_boot_por, 0 , sizeof(FUR_MICRO_BOOT_BOOT_POR_t)); 5647 PHYMOD_MEMSET(&gen_ctrl_boot, 0 , sizeof(FUR_GEN_CNTRLS_BOOT_t)); 5648 PHYMOD_IF_ERR_RETURN 5649 (READ_FURIA_PMA_PMD_REG(pa,\ 5650 FUR_MICRO_BOOT_boot_por_Adr,\ 5651 µ_boot_por.data)); 5652 if((micro_boot_por.fields.serboot == 1) && (micro_boot_por.fields.spi_port_used == 1)) { 5653 while(((micro_boot_por.fields.mst_dwld_done == 0) || (micro_boot_por.fields.slv_dwld_done == 0)) && (retry_count)) { 5654 PHYMOD_IF_ERR_RETURN 5655 (READ_FURIA_PMA_PMD_REG(pa,\ 5656 FUR_MICRO_BOOT_boot_por_Adr,\ 5657 µ_boot_por.data)); 5658 PHYMOD_USLEEP(200); 5659 retry_count--; 5660 } 5661 if(!retry_count) { 5662 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("config failed, micro controller is busy.."))); 5663 } 5664 PHYMOD_IF_ERR_RETURN 5665 (READ_FURIA_PMA_PMD_REG(pa,\ 5666 FUR_GEN_CNTRLS_boot_Adr,\ 5667 &gen_ctrl_boot.data)); 5668 retry_count = 40; 5669 while((gen_ctrl_boot.fields.serboot_busy == 1) && (retry_count)) { 5670 PHYMOD_IF_ERR_RETURN 5671 (READ_FURIA_PMA_PMD_REG(pa,\ 5672 FUR_GEN_CNTRLS_boot_Adr,\ 5673 &gen_ctrl_boot.data)); 5674 PHYMOD_USLEEP(200); 5675 retry_count--; 5676 } 5677 if(!retry_count) { 5678 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("config failed, micro controller is busy with firmware download.."))); 5679 } 5680 } 5681 _furia_config_clk_scaler_val(pa, ref_clk_freq); 5682 return PHYMOD_E_NONE; 5683 } 5684 5685 int _furia_fw_enable(const phymod_access_t* pa) 5686 { 5687 FUR_GEN_CNTRLS_FIRMWARE_ENABLE_t fw_enable_reg; 5688 uint8_t fw_enable = 0; 5689 uint8_t retry_count = 40; 5690 PHYMOD_MEMSET(&fw_enable_reg, 0 , sizeof(FUR_GEN_CNTRLS_FIRMWARE_ENABLE_t)); 5691 /* Wait for firmware to ready before config to be changed */ 5692 PHYMOD_IF_ERR_RETURN 5693 (READ_FURIA_PMA_PMD_REG(pa,\ 5694 FUR_GEN_CNTRLS_firmware_enable_Adr,\ 5695 &fw_enable_reg.data)); 5696 fw_enable = fw_enable_reg.fields.fw_enable_val; 5697 5698 while((fw_enable != 0) && (retry_count)) { 5699 PHYMOD_IF_ERR_RETURN 5700 (READ_FURIA_PMA_PMD_REG(pa,\ 5701 FUR_GEN_CNTRLS_firmware_enable_Adr,\ 5702 &fw_enable_reg.data)); 5703 fw_enable = fw_enable_reg.fields.fw_enable_val; 5704 PHYMOD_USLEEP(200); 5705 retry_count--; 5706 } 5707 5708 if(!retry_count) { 5709 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("1:config failed, micro controller is busy.."))); 5710 } 5711 PHYMOD_IF_ERR_RETURN 5712 (READ_FURIA_PMA_PMD_REG(pa,\ 5713 FUR_GEN_CNTRLS_firmware_enable_Adr,\ 5714 &fw_enable_reg.data)); 5715 fw_enable_reg.fields.fw_enable_val = 1; 5716 PHYMOD_IF_ERR_RETURN 5717 (WRITE_FURIA_PMA_PMD_REG(pa,\ 5718 FUR_GEN_CNTRLS_firmware_enable_Adr,\ 5719 fw_enable_reg.data)); 5720 retry_count = 40; 5721 /* Wait for firmware to ready before config to be changed */ 5722 PHYMOD_IF_ERR_RETURN 5723 (READ_FURIA_PMA_PMD_REG(pa,\ 5724 FUR_GEN_CNTRLS_firmware_enable_Adr,\ 5725 &fw_enable_reg.data)); 5726 fw_enable = fw_enable_reg.fields.fw_enable_val; 5727 5728 while((fw_enable != 0) && (retry_count)) { 5729 PHYMOD_IF_ERR_RETURN 5730 (READ_FURIA_PMA_PMD_REG(pa,\ 5731 FUR_GEN_CNTRLS_firmware_enable_Adr,\ 5732 &fw_enable_reg.data)); 5733 fw_enable = fw_enable_reg.fields.fw_enable_val; 5734 PHYMOD_USLEEP(200); 5735 retry_count--; 5736 } 5737 5738 if(!retry_count) { 5739 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("1:config failed, micro controller is busy.."))); 5740 } 5741 return PHYMOD_E_NONE; 5742 } 5743 5744 int _furia_autoneg_set(const phymod_access_t* pa, const phymod_autoneg_control_t* an) 5745 { 5746 int lane_map = 0; 5747 int wr_lane = 0; 5748 int sys_en = 0; 5749 int rd_lane = 0; 5750 uint32_t chip_id = 0; 5751 int num_lanes = 0; 5752 int lane_index = 0; 5753 int an_master_lane_flag = 0; 5754 uint32_t an_master_lane = 0, pkg_lane = 0; 5755 const FURIA_PKG_LANE_CFG_t* pkg_ln_des = NULL; 5756 IEEE_AN_BLK0_AN_CONTROL_REGISTER_t an_control; 5757 FUR_MISC_CTRL_UDMS_PHY_t udms_phy; 5758 PHYMOD_MEMSET(&an_control, 0 , sizeof(IEEE_AN_BLK0_AN_CONTROL_REGISTER_t)); 5759 PHYMOD_MEMSET(&udms_phy, 0 , sizeof(FUR_MISC_CTRL_UDMS_PHY_t)); 5760 5761 /* Get the lane map from phymod access */ 5762 lane_map = PHYMOD_ACC_LANE_MASK(pa); 5763 5764 /* Get the chip id */ 5765 chip_id = _furia_get_chip_id(pa); 5766 5767 if(FURIA_IS_SIMPLEX(chip_id)) { 5768 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("Autoneg feature is not applicable for simplex packages"))); 5769 } 5770 5771 /* Program udms_en=0 */ 5772 /* Read UDMS PHY Type Register */ 5773 PHYMOD_IF_ERR_RETURN 5774 (READ_FURIA_PMA_PMD_REG(pa,\ 5775 FUR_MISC_CTRL_udms_phy_Adr,\ 5776 &udms_phy.data)); 5777 5778 /* Update the field udms disable*/ 5779 udms_phy.fields.udms_en = (an->enable) ? 0 : 1; 5780 /* Write to UDMS PHY Type Register */ 5781 PHYMOD_IF_ERR_RETURN 5782 (WRITE_FURIA_PMA_PMD_REG(pa,\ 5783 FUR_MISC_CTRL_udms_phy_Adr,\ 5784 udms_phy.data)); 5785 5786 num_lanes = 4; 5787 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 5788 if ((lane_map >> lane_index) & 1) { 5789 an_master_lane ++; 5790 } 5791 } 5792 if (an_master_lane > 1) { 5793 an_master_lane = 0; 5794 PHYMOD_IF_ERR_RETURN( 5795 _furia_cfg_an_master_lane_get(pa, &an_master_lane)); 5796 5797 /* Doing this because for 10G we need lane index not lane MAP*/ 5798 PHYMOD_IF_ERR_RETURN( 5799 _furia_get_pkg_lane(pa->addr, chip_id, an_master_lane, 0, &pkg_lane)); 5800 lane_map = (1 << pkg_lane); 5801 an_master_lane_flag = 1; 5802 } 5803 5804 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 5805 if (((lane_map >> lane_index) & 1) == 0x1) { 5806 if (an_master_lane_flag) { 5807 pkg_ln_des = _furia_pkg_ln_des(chip_id, pa, lane_index); 5808 } else { 5809 pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 1); 5810 } 5811 PHYMOD_NULL_CHECK(pkg_ln_des); 5812 /* Get sys_en, wr_lane, rd_lane using lane descriptor */ 5813 sys_en = pkg_ln_des->sideA; 5814 wr_lane = pkg_ln_des->slice_wr_val; 5815 rd_lane = pkg_ln_des->slice_rd_val; 5816 5817 /* Program the slice register */ 5818 PHYMOD_IF_ERR_RETURN 5819 (WRITE_FURIA_AN_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 5820 if (an->an_mode == phymod_AN_MODE_CL73) { 5821 PHYMOD_IF_ERR_RETURN 5822 (READ_FURIA_AN_REG(pa,\ 5823 IEEE_AN_BLK0_an_control_register_Adr,\ 5824 &an_control.data)); 5825 an_control.fields.auto_negotiationenable = an->enable; 5826 PHYMOD_IF_ERR_RETURN 5827 (WRITE_FURIA_AN_REG(pa,\ 5828 IEEE_AN_BLK0_an_control_register_Adr,\ 5829 an_control.data)); 5830 } else { 5831 return PHYMOD_E_PARAM; 5832 } 5833 break; 5834 } 5835 } 5836 PHYMOD_IF_ERR_RETURN 5837 (WRITE_FURIA_AN_SLICE_REG(pa, 0, 1, 0)); 5838 5839 PHYMOD_IF_ERR_RETURN( 5840 _furia_fw_enable(pa)); 5841 5842 return PHYMOD_E_NONE; 5843 } 5844 5845 int _furia_autoneg_get(const phymod_access_t* pa, phymod_autoneg_control_t* an, uint32_t *an_done) 5846 { 5847 int lane_map = 0; 5848 int wr_lane = 0; 5849 int sys_en = 0; 5850 int rd_lane = 0; 5851 uint32_t chip_id = 0; 5852 int num_lanes = 0; 5853 uint32_t an_master_lane =0, pkg_lane = 0; 5854 int lane_index = 0; 5855 int an_master_lane_flag = 0; 5856 const FURIA_PKG_LANE_CFG_t* pkg_ln_des = NULL; 5857 IEEE_AN_BLK0_AN_CONTROL_REGISTER_t an_control; 5858 IEEE_AN_BLK0_AN_STATUS_REGISTER_t an_sts; 5859 PHYMOD_MEMSET(&an_control, 0 , sizeof(IEEE_AN_BLK0_AN_CONTROL_REGISTER_t)); 5860 PHYMOD_MEMSET(&an_sts, 0 , sizeof(IEEE_AN_BLK0_AN_STATUS_REGISTER_t)); 5861 5862 /* Get the lane map from phymod access */ 5863 lane_map = PHYMOD_ACC_LANE_MASK(pa); 5864 5865 /* Get the chip id */ 5866 chip_id = _furia_get_chip_id(pa); 5867 5868 if(FURIA_IS_SIMPLEX(chip_id)) { 5869 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("Autoneg feature is not applicable for simplex packages"))); 5870 } 5871 5872 num_lanes = 4; 5873 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 5874 if ((lane_map >> lane_index) & 1) { 5875 an_master_lane ++; 5876 } 5877 } 5878 if (an_master_lane > 1) { 5879 an_master_lane = 0; 5880 PHYMOD_IF_ERR_RETURN( 5881 _furia_cfg_an_master_lane_get(pa, &an_master_lane)); 5882 5883 /* Doing this because for 10G we need lane index not lane MAP*/ 5884 PHYMOD_IF_ERR_RETURN( 5885 _furia_get_pkg_lane(pa->addr, chip_id, an_master_lane, 0, &pkg_lane)); 5886 lane_map = (1 << pkg_lane); 5887 an_master_lane_flag = 1; 5888 } 5889 5890 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 5891 if (((lane_map >> lane_index) & 1) == 0x1) { 5892 if (an_master_lane_flag) { 5893 pkg_ln_des = _furia_pkg_ln_des(chip_id, pa, lane_index); 5894 } else { 5895 pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 1); 5896 } 5897 PHYMOD_NULL_CHECK(pkg_ln_des); 5898 /* Get sys_en, wr_lane, rd_lane using lane descriptor */ 5899 sys_en = pkg_ln_des->sideA; 5900 wr_lane = pkg_ln_des->slice_wr_val; 5901 rd_lane = pkg_ln_des->slice_rd_val; 5902 5903 /* Program the slice register */ 5904 PHYMOD_IF_ERR_RETURN 5905 (WRITE_FURIA_AN_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 5906 PHYMOD_IF_ERR_RETURN 5907 (READ_FURIA_AN_REG(pa, IEEE_AN_BLK0_an_control_register_Adr, 5908 &an_control.data)); 5909 an->enable = an_control.fields.auto_negotiationenable; 5910 an->an_mode = phymod_AN_MODE_CL73; 5911 PHYMOD_IF_ERR_RETURN 5912 (READ_FURIA_AN_REG(pa, IEEE_AN_BLK0_an_status_register_Adr, 5913 &an_sts.data)); 5914 *an_done = an_sts.fields.auto_negotiationcomplete; 5915 break; 5916 } 5917 } 5918 PHYMOD_IF_ERR_RETURN 5919 (WRITE_FURIA_AN_SLICE_REG(pa, 0, 1, 0)); 5920 5921 return PHYMOD_E_NONE; 5922 } 5923 int _furia_autoneg_ability_get (const phymod_access_t* pa, furia_an_ability_t *an_ability) 5924 { 5925 int lane_map = 0; 5926 int wr_lane = 0; 5927 int sys_en = 0; 5928 int rd_lane = 0; 5929 uint32_t chip_id = 0; 5930 int num_lanes = 0; 5931 int lane_index = 0; 5932 uint32_t an_master_lane = 0, pkg_lane = 0; 5933 int an_master_lane_flag = 0; 5934 const FURIA_PKG_LANE_CFG_t* pkg_ln_des = NULL; 5935 IEEE_AN_BLK1_an_advertisement_1_register_t adv1; 5936 IEEE_AN_BLK1_an_advertisement_2_register_t adv2; 5937 IEEE_AN_BLK1_an_advertisement_3_register_t adv3; 5938 PHYMOD_MEMSET(&adv1, 0 , sizeof(IEEE_AN_BLK1_an_advertisement_1_register_t)); 5939 PHYMOD_MEMSET(&adv2, 0 , sizeof(IEEE_AN_BLK1_an_advertisement_2_register_t)); 5940 PHYMOD_MEMSET(&adv3, 0 , sizeof(IEEE_AN_BLK1_an_advertisement_3_register_t)); 5941 5942 /* Get the lane map from phymod access */ 5943 lane_map = PHYMOD_ACC_LANE_MASK(pa); 5944 5945 /* Get the chip id */ 5946 chip_id = _furia_get_chip_id(pa); 5947 5948 if(FURIA_IS_SIMPLEX(chip_id)) { 5949 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("Autoneg feature is not applicable for simplex packages"))); 5950 } 5951 5952 num_lanes = 4; 5953 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 5954 if ((lane_map >> lane_index) & 1) { 5955 an_master_lane ++; 5956 } 5957 } 5958 if (an_master_lane > 1) { 5959 an_master_lane = 0; 5960 PHYMOD_IF_ERR_RETURN( 5961 _furia_cfg_an_master_lane_get(pa, &an_master_lane)); 5962 5963 /* Doing this because for 10G we need lane index not lane MAP*/ 5964 PHYMOD_IF_ERR_RETURN( 5965 _furia_get_pkg_lane(pa->addr, chip_id, an_master_lane, 0, &pkg_lane)); 5966 an_ability->an_master_lane = pkg_lane; 5967 lane_map = (1 << pkg_lane); 5968 an_master_lane_flag = 1; 5969 } 5970 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 5971 if (((lane_map >> lane_index) & 1) == 0x1) { 5972 if (an_master_lane_flag) { 5973 pkg_ln_des = _furia_pkg_ln_des(chip_id, pa, lane_index); 5974 } else { 5975 pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 1); 5976 } 5977 PHYMOD_NULL_CHECK(pkg_ln_des); 5978 /* Get sys_en, wr_lane, rd_lane using lane descriptor */ 5979 sys_en = pkg_ln_des->sideA; 5980 wr_lane = pkg_ln_des->slice_wr_val; 5981 rd_lane = pkg_ln_des->slice_rd_val; 5982 5983 /* Program the slice register */ 5984 PHYMOD_IF_ERR_RETURN 5985 (WRITE_FURIA_AN_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 5986 PHYMOD_IF_ERR_RETURN 5987 (READ_FURIA_AN_REG(pa, IEEE_AN_BLK1_an_advertisement_3_register_Adr, 5988 &adv3.data)); 5989 an_ability->cl73_adv.an_fec = adv3.fields.fec_requested; 5990 PHYMOD_IF_ERR_RETURN 5991 (READ_FURIA_AN_REG(pa, IEEE_AN_BLK1_an_advertisement_2_register_Adr, 5992 &adv2.data)); 5993 an_ability->cl73_adv.an_base_speed = adv2.fields.techability; 5994 PHYMOD_IF_ERR_RETURN 5995 (READ_FURIA_AN_REG(pa, IEEE_AN_BLK1_an_advertisement_1_register_Adr, 5996 &adv1.data)); 5997 an_ability->cl73_adv.an_pause = adv1.fields.pause; 5998 break; 5999 } 6000 } 6001 PHYMOD_IF_ERR_RETURN 6002 (WRITE_FURIA_AN_SLICE_REG(pa, 0, 1, 0)); 6003 return PHYMOD_E_NONE; 6004 } 6005 6006 int _furia_autoneg_remote_ability_get (const phymod_access_t* pa, phymod_autoneg_ability_t* an_ability_get) 6007 { 6008 int lane_map = 0; 6009 int wr_lane = 0; 6010 int sys_en = 0; 6011 int rd_lane = 0; 6012 uint32_t chip_id = 0; 6013 int num_lanes = 0; 6014 int lane_index = 0; 6015 uint32_t an_master_lane = 0, pkg_lane =0; 6016 int an_master_lane_flag = 0; 6017 const FURIA_PKG_LANE_CFG_t* pkg_ln_des = NULL; 6018 6019 IEEE_AN_BLK1_an_lp_base_page_ability_2_reg_t adv2; 6020 IEEE_AN_BLK1_an_lp_base_page_ability_1_reg_t adv1; 6021 6022 PHYMOD_MEMSET(&adv1, 0 , sizeof(IEEE_AN_BLK1_an_advertisement_1_register_t)); 6023 PHYMOD_MEMSET(&adv2, 0 , sizeof(IEEE_AN_BLK1_an_advertisement_2_register_t)); 6024 6025 /* Get the lane map from phymod access */ 6026 lane_map = PHYMOD_ACC_LANE_MASK(pa); 6027 6028 /* Get the chip id */ 6029 chip_id = _furia_get_chip_id(pa); 6030 6031 if(FURIA_IS_SIMPLEX(chip_id)) { 6032 return PHYMOD_E_NONE; 6033 } 6034 6035 num_lanes = 4; 6036 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 6037 if ((lane_map >> lane_index) & 1) { 6038 an_master_lane ++; 6039 } 6040 } 6041 if (an_master_lane > 1) { 6042 an_master_lane = 0; 6043 PHYMOD_IF_ERR_RETURN( 6044 _furia_cfg_an_master_lane_get(pa, &an_master_lane)); 6045 /* Doing this because for 10G we need lane index not lane MAP*/ 6046 PHYMOD_IF_ERR_RETURN( 6047 _furia_get_pkg_lane(pa->addr, chip_id, an_master_lane, 0, &pkg_lane)); 6048 lane_map = (1 << pkg_lane); 6049 an_master_lane_flag = 1; 6050 } 6051 6052 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 6053 if (((lane_map >> lane_index) & 1) == 0x1) { 6054 if (an_master_lane_flag) { 6055 pkg_ln_des = _furia_pkg_ln_des(chip_id, pa, lane_index); 6056 } else { 6057 pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 1); 6058 } 6059 PHYMOD_NULL_CHECK(pkg_ln_des); 6060 /* Get sys_en, wr_lane, rd_lane using lane descriptor */ 6061 sys_en = pkg_ln_des->sideA; 6062 wr_lane = pkg_ln_des->slice_wr_val; 6063 rd_lane = pkg_ln_des->slice_rd_val; 6064 6065 /* Program the slice register */ 6066 PHYMOD_IF_ERR_RETURN 6067 (WRITE_FURIA_AN_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 6068 6069 PHYMOD_IF_ERR_RETURN( 6070 READ_FURIA_AN_REG(pa, IEEE_AN_BLK1_an_lp_base_page_ability_2_reg_Adr, &adv2.data)); 6071 an_ability_get->an_cap = (adv2.data & 0xFFE0) >> 5; 6072 6073 PHYMOD_IF_ERR_RETURN( 6074 READ_FURIA_AN_REG(pa, IEEE_AN_BLK1_an_lp_base_page_ability_1_reg_Adr, &adv1.data)); 6075 if (adv1.data & 0x400) { 6076 PHYMOD_AN_CAP_ASYM_PAUSE_SET(an_ability_get); 6077 } else if (adv1.data & 0x800) { 6078 PHYMOD_AN_CAP_SYMM_PAUSE_SET(an_ability_get); 6079 } 6080 break; 6081 } 6082 } 6083 6084 PHYMOD_IF_ERR_RETURN 6085 (WRITE_FURIA_AN_SLICE_REG(pa, 0, 1, 0)); 6086 6087 return PHYMOD_E_NONE; 6088 } 6089 6090 int _furia_autoneg_ability_set (const phymod_access_t* pa, furia_an_ability_t *an_ability) 6091 { 6092 int lane_map = 0; 6093 int wr_lane = 0; 6094 int sys_en = 0; 6095 int rd_lane = 0; 6096 uint32_t chip_id = 0, an_master_lane = 0, pkg_lane = 0; 6097 int num_lanes = 0; 6098 int lane_index = 0; 6099 int an_master_lane_flag = 0; 6100 const FURIA_PKG_LANE_CFG_t* pkg_ln_des = NULL; 6101 IEEE_AN_BLK1_an_advertisement_1_register_t adv1; 6102 IEEE_AN_BLK1_an_advertisement_2_register_t adv2; 6103 IEEE_AN_BLK1_an_advertisement_3_register_t adv3; 6104 FUR_GEN_CNTRLS_FIRMWARE_ENABLE_t fw_enable_reg; 6105 uint8_t fw_enable = 0; 6106 uint8_t retry_count = 40; 6107 FUR_GEN_CNTRLS_gpreg13_t gen_ctrl_gpreg13; 6108 PHYMOD_MEMSET(&adv1, 0, sizeof(IEEE_AN_BLK1_an_advertisement_1_register_t)); 6109 PHYMOD_MEMSET(&adv2, 0, sizeof(IEEE_AN_BLK1_an_advertisement_2_register_t)); 6110 PHYMOD_MEMSET(&adv3, 0, sizeof(IEEE_AN_BLK1_an_advertisement_3_register_t)); 6111 6112 /* Get the lane map from phymod access */ 6113 lane_map = PHYMOD_ACC_LANE_MASK(pa); 6114 6115 /* Get the chip id */ 6116 chip_id = _furia_get_chip_id(pa); 6117 6118 if(FURIA_IS_SIMPLEX(chip_id)) { 6119 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("Autoneg feature is not applicable for simplex packages"))); 6120 } 6121 num_lanes = 4; 6122 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 6123 if ((lane_map >> lane_index) & 1) { 6124 an_master_lane ++; 6125 } 6126 } 6127 if (an_master_lane > 1) { 6128 an_master_lane = 0; 6129 PHYMOD_IF_ERR_RETURN( 6130 _furia_cfg_an_master_lane_get(pa, &an_master_lane)); 6131 6132 /* Doing this because for 10G we need lane index not lane MAP*/ 6133 PHYMOD_IF_ERR_RETURN( 6134 _furia_get_pkg_lane(pa->addr, chip_id, an_master_lane, 0, &pkg_lane)); 6135 lane_map = (1 << pkg_lane); 6136 an_master_lane_flag = 1; 6137 } 6138 6139 for (lane_index = 0; lane_index < num_lanes; lane_index++) { 6140 if (((lane_map >> lane_index) & 1) == 0x1) { 6141 if (an_master_lane_flag) { 6142 pkg_ln_des = _furia_pkg_ln_des(chip_id, pa, lane_index); 6143 } else { 6144 pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 1); 6145 } 6146 PHYMOD_NULL_CHECK(pkg_ln_des); 6147 6148 /* Get sys_en, wr_lane, rd_lane using lane descriptor */ 6149 sys_en = pkg_ln_des->sideA; 6150 wr_lane = pkg_ln_des->slice_wr_val; 6151 rd_lane = pkg_ln_des->slice_rd_val; 6152 6153 /* Program the slice register */ 6154 PHYMOD_IF_ERR_RETURN 6155 (WRITE_FURIA_AN_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 6156 PHYMOD_IF_ERR_RETURN 6157 (READ_FURIA_AN_REG(pa,\ 6158 IEEE_AN_BLK1_an_advertisement_3_register_Adr,\ 6159 &adv3.data)); 6160 adv3.fields.fec_requested = an_ability->cl73_adv.an_fec; 6161 PHYMOD_IF_ERR_RETURN 6162 (WRITE_FURIA_AN_REG(pa,\ 6163 IEEE_AN_BLK1_an_advertisement_3_register_Adr,\ 6164 adv3.data)); 6165 PHYMOD_IF_ERR_RETURN 6166 (READ_FURIA_AN_REG(pa,\ 6167 IEEE_AN_BLK1_an_advertisement_2_register_Adr,\ 6168 &adv2.data)); 6169 adv2.fields.techability = an_ability->cl73_adv.an_base_speed; 6170 PHYMOD_IF_ERR_RETURN 6171 (WRITE_FURIA_AN_REG(pa,\ 6172 IEEE_AN_BLK1_an_advertisement_2_register_Adr,\ 6173 adv2.data)); 6174 PHYMOD_IF_ERR_RETURN 6175 (READ_FURIA_AN_REG(pa,\ 6176 IEEE_AN_BLK1_an_advertisement_1_register_Adr,\ 6177 &adv1.data)); 6178 adv1.fields.pause = an_ability->cl73_adv.an_pause; 6179 PHYMOD_IF_ERR_RETURN 6180 (WRITE_FURIA_AN_REG(pa,\ 6181 IEEE_AN_BLK1_an_advertisement_1_register_Adr,\ 6182 adv1.data)); 6183 break; 6184 } 6185 } 6186 PHYMOD_IF_ERR_RETURN 6187 (WRITE_FURIA_AN_SLICE_REG(pa, 0, 1, 0)); 6188 6189 /* GPREG13 should only be udpated when firmware_enable.fw_enable_val = 0 */ 6190 PHYMOD_IF_ERR_RETURN 6191 (READ_FURIA_PMA_PMD_REG(pa,\ 6192 FUR_GEN_CNTRLS_firmware_enable_Adr,\ 6193 &fw_enable_reg.data)); 6194 fw_enable = fw_enable_reg.fields.fw_enable_val; 6195 while((fw_enable != 0) && (retry_count)) { 6196 PHYMOD_IF_ERR_RETURN 6197 (READ_FURIA_PMA_PMD_REG(pa,\ 6198 FUR_GEN_CNTRLS_firmware_enable_Adr,\ 6199 &fw_enable_reg.data)); 6200 fw_enable = fw_enable_reg.fields.fw_enable_val; 6201 PHYMOD_USLEEP(200); 6202 retry_count--; 6203 } 6204 6205 if(!retry_count && fw_enable) { 6206 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("1:config failed, micro controller is busy.."))); 6207 }else { 6208 PHYMOD_IF_ERR_RETURN 6209 (READ_FURIA_PMA_PMD_REG(pa,\ 6210 FUR_GEN_CNTRLS_gpreg13_Adr,\ 6211 &gen_ctrl_gpreg13.data)); 6212 an_ability->cl73_adv.an_cl72 ? (gen_ctrl_gpreg13.data &= (~(0x1 << 11))) : (gen_ctrl_gpreg13.data |= (0x1 << 11)); 6213 PHYMOD_IF_ERR_RETURN 6214 (WRITE_FURIA_PMA_PMD_REG(pa,\ 6215 FUR_GEN_CNTRLS_gpreg13_Adr,\ 6216 gen_ctrl_gpreg13.data)); 6217 } 6218 PHYMOD_IF_ERR_RETURN( 6219 _furia_fw_enable(pa)); 6220 return PHYMOD_E_NONE; 6221 } 6222 6223 int furia_display_eye_scan(const phymod_access_t *pa) 6224 { 6225 int lane_map = 0; 6226 int pkg_side = 0; 6227 int wr_lane = 0; 6228 int sys_en = 0; 6229 int rd_lane = 0; 6230 uint32_t chip_id = 0; 6231 int num_lanes = 0; 6232 int lane_index = 0; 6233 uint32_t acc_flags = 0; 6234 const FURIA_PKG_LANE_CFG_t* pkg_ln_des = NULL; 6235 6236 /* Get the lane map from phymod access */ 6237 lane_map = PHYMOD_ACC_LANE_MASK(pa); 6238 acc_flags = PHYMOD_ACC_FLAGS(pa); 6239 FURIA_GET_IF_SIDE(acc_flags, pkg_side); 6240 /* Get the chip id */ 6241 chip_id = _furia_get_chip_id(pa); 6242 FURIA_GET_NUM_LANES(chip_id, num_lanes); 6243 6244 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 6245 if (((lane_map >> lane_index) & 1) == 0x1) { 6246 PHYMOD_DIAG_OUT((" eyescan for lane = %d\n", lane_index)); 6247 /* Configure Tx side(SIDE_A) first*/ 6248 pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 1); 6249 PHYMOD_NULL_CHECK(pkg_ln_des); 6250 if(pkg_side == SIDE_A) { 6251 sys_en = pkg_ln_des->sideA; 6252 } else { 6253 sys_en = pkg_ln_des->sideB; 6254 } 6255 6256 wr_lane = pkg_ln_des->slice_wr_val; 6257 rd_lane = pkg_ln_des->slice_rd_val; 6258 6259 /* Program the slice register */ 6260 PHYMOD_IF_ERR_RETURN 6261 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 6262 6263 if (FURIA_IF_RX_SIDE(chip_id, pkg_side)) { 6264 PHYMOD_IF_ERR_RETURN 6265 (falcon_furia_display_lane_state_hdr(pa)); 6266 PHYMOD_IF_ERR_RETURN 6267 (falcon_furia_display_lane_state(pa)); 6268 PHYMOD_IF_ERR_RETURN 6269 (falcon_furia_display_eye_scan(pa)); 6270 } 6271 } 6272 } 6273 return PHYMOD_E_NONE; 6274 } 6275 6276 int furia_pll_sequencer_restart(const phymod_access_t *pa, phymod_sequencer_operation_t operation) 6277 { 6278 int pkg_side = 0; 6279 uint32_t acc_flags = 0; 6280 uint32_t chip_id = 0; 6281 LINE_FALCON_IF_SOFT_MODE0_t line_falcon_soft_mode0; 6282 LINE_FALCON_IF_C_AND_R_CNTL_t line_falcon_c_and_r_ctrl; 6283 SYS_FALCON_IF_SOFT_MODE0_t sys_falcon_soft_mode0; 6284 SYS_FALCON_IF_C_AND_R_CNTL_t sys_falcon_c_and_r_ctrl; 6285 PHYMOD_MEMSET(&line_falcon_soft_mode0, 0 , sizeof(LINE_FALCON_IF_SOFT_MODE0_t)); 6286 PHYMOD_MEMSET(&line_falcon_c_and_r_ctrl, 0 , sizeof(LINE_FALCON_IF_C_AND_R_CNTL_t)); 6287 PHYMOD_MEMSET(&sys_falcon_soft_mode0, 0 , sizeof(SYS_FALCON_IF_SOFT_MODE0_t)); 6288 PHYMOD_MEMSET(&sys_falcon_c_and_r_ctrl, 0 , sizeof(SYS_FALCON_IF_C_AND_R_CNTL_t)); 6289 6290 /* Get the lane map from phymod access */ 6291 acc_flags = PHYMOD_ACC_FLAGS(pa); 6292 FURIA_GET_IF_SIDE(acc_flags, pkg_side); 6293 /* Get the chip id */ 6294 chip_id = _furia_get_chip_id(pa); 6295 6296 switch(operation) { 6297 case phymodSeqOpStop: 6298 case phymodSeqOpStart: 6299 return PHYMOD_E_UNAVAIL; 6300 case phymodSeqOpRestart: 6301 if((FURIA_IS_DUPLEX(chip_id) && pkg_side == LINE) || 6302 (FURIA_IS_SIMPLEX(chip_id))) { 6303 PHYMOD_IF_ERR_RETURN 6304 (READ_FURIA_PMA_PMD_REG(pa,\ 6305 LINE_FALCON_IF_soft_mode0_Adr,\ 6306 &line_falcon_soft_mode0.data)); 6307 line_falcon_soft_mode0.fields.software_mode_pmd_core_dp_h_rstb = 1; 6308 PHYMOD_IF_ERR_RETURN 6309 (WRITE_FURIA_PMA_PMD_REG(pa,\ 6310 LINE_FALCON_IF_soft_mode0_Adr,\ 6311 line_falcon_soft_mode0.data)); 6312 PHYMOD_IF_ERR_RETURN 6313 (READ_FURIA_PMA_PMD_REG(pa,\ 6314 LINE_FALCON_IF_c_and_r_cntl_Adr,\ 6315 &line_falcon_c_and_r_ctrl.data)); 6316 line_falcon_c_and_r_ctrl.fields.pmd_core_dp_h_rstb = 0; 6317 line_falcon_c_and_r_ctrl.fields.pmd_core_dp_h_rstb = 1; 6318 PHYMOD_IF_ERR_RETURN 6319 (WRITE_FURIA_PMA_PMD_REG(pa,\ 6320 LINE_FALCON_IF_c_and_r_cntl_Adr,\ 6321 line_falcon_c_and_r_ctrl.data)); 6322 PHYMOD_IF_ERR_RETURN 6323 (READ_FURIA_PMA_PMD_REG(pa,\ 6324 LINE_FALCON_IF_soft_mode0_Adr,\ 6325 &line_falcon_soft_mode0.data)); 6326 line_falcon_soft_mode0.fields.software_mode_pmd_core_dp_h_rstb = 0; 6327 PHYMOD_IF_ERR_RETURN 6328 (WRITE_FURIA_PMA_PMD_REG(pa,\ 6329 LINE_FALCON_IF_soft_mode0_Adr,\ 6330 line_falcon_soft_mode0.data)); 6331 } 6332 if((FURIA_IS_DUPLEX(chip_id) && pkg_side == SYS) || 6333 (FURIA_IS_SIMPLEX(chip_id))) { 6334 PHYMOD_IF_ERR_RETURN 6335 (READ_FURIA_PMA_PMD_REG(pa,\ 6336 SYS_FALCON_IF_soft_mode0_Adr,\ 6337 &sys_falcon_soft_mode0.data)); 6338 sys_falcon_soft_mode0.fields.software_mode_pmd_core_dp_h_rstb = 1; 6339 PHYMOD_IF_ERR_RETURN 6340 (WRITE_FURIA_PMA_PMD_REG(pa,\ 6341 SYS_FALCON_IF_soft_mode0_Adr,\ 6342 sys_falcon_soft_mode0.data)); 6343 PHYMOD_IF_ERR_RETURN 6344 (READ_FURIA_PMA_PMD_REG(pa,\ 6345 SYS_FALCON_IF_c_and_r_cntl_Adr,\ 6346 &sys_falcon_c_and_r_ctrl.data)); 6347 sys_falcon_c_and_r_ctrl.fields.pmd_core_dp_h_rstb = 0; 6348 sys_falcon_c_and_r_ctrl.fields.pmd_core_dp_h_rstb = 1; 6349 PHYMOD_IF_ERR_RETURN 6350 (WRITE_FURIA_PMA_PMD_REG(pa,\ 6351 SYS_FALCON_IF_c_and_r_cntl_Adr,\ 6352 sys_falcon_c_and_r_ctrl.data)); 6353 PHYMOD_IF_ERR_RETURN 6354 (READ_FURIA_PMA_PMD_REG(pa,\ 6355 SYS_FALCON_IF_soft_mode0_Adr,\ 6356 &sys_falcon_soft_mode0.data)); 6357 sys_falcon_soft_mode0.fields.software_mode_pmd_core_dp_h_rstb = 0; 6358 PHYMOD_IF_ERR_RETURN 6359 (WRITE_FURIA_PMA_PMD_REG(pa,\ 6360 SYS_FALCON_IF_soft_mode0_Adr,\ 6361 sys_falcon_soft_mode0.data)); 6362 } 6363 break; 6364 default: 6365 break; 6366 } 6367 return PHYMOD_E_NONE; 6368 } 6369 int furia_fec_enable_set(const phymod_access_t *pa, uint32_t enable) 6370 { 6371 FUR_MISC_CTRL_MODE_DEC_FRC_t dec_frc; 6372 FUR_MISC_CTRL_MODE_DEC_FRC_VAL_t dec_frc_val; 6373 uint32_t chip_id = 0; 6374 PHYMOD_MEMSET(&dec_frc, 0 , sizeof(FUR_MISC_CTRL_MODE_DEC_FRC_t)); 6375 PHYMOD_MEMSET(&dec_frc_val, 0 , sizeof(FUR_MISC_CTRL_MODE_DEC_FRC_VAL_t)); 6376 6377 chip_id = _furia_get_chip_id(pa); 6378 if(FURIA_IS_SIMPLEX(chip_id)) { 6379 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("FEC is not applicable for simplex packages"))); 6380 } 6381 6382 PHYMOD_IF_ERR_RETURN 6383 (READ_FURIA_PMA_PMD_REG(pa,\ 6384 FUR_MISC_CTRL_mode_dec_frc_val_Adr,\ 6385 &dec_frc_val.data)); 6386 dec_frc_val.fields.rg_cl91_enabled_frc_val = enable ? 1 : 0; 6387 PHYMOD_IF_ERR_RETURN 6388 (WRITE_FURIA_PMA_PMD_REG(pa,\ 6389 FUR_MISC_CTRL_mode_dec_frc_val_Adr,\ 6390 dec_frc_val.data)); 6391 PHYMOD_IF_ERR_RETURN 6392 (READ_FURIA_PMA_PMD_REG(pa,\ 6393 FUR_MISC_CTRL_mode_dec_frc_Adr,\ 6394 &dec_frc.data)); 6395 dec_frc.fields.rg_cl91_enabled_frc = 1; 6396 PHYMOD_IF_ERR_RETURN 6397 (WRITE_FURIA_PMA_PMD_REG(pa,\ 6398 FUR_MISC_CTRL_mode_dec_frc_Adr,\ 6399 dec_frc.data)); 6400 return PHYMOD_E_NONE; 6401 } 6402 int furia_fec_enable_get(const phymod_access_t *pa, uint32_t* enable) 6403 { 6404 FUR_MISC_CTRL_MODE_DEC_FRC_t dec_frc; 6405 FUR_MISC_CTRL_MODE_DEC_FRC_VAL_t dec_frc_val; 6406 uint32_t chip_id = 0; 6407 6408 PHYMOD_MEMSET(&dec_frc, 0 , sizeof(FUR_MISC_CTRL_MODE_DEC_FRC_t)); 6409 PHYMOD_MEMSET(&dec_frc_val, 0 , sizeof(FUR_MISC_CTRL_MODE_DEC_FRC_VAL_t)); 6410 6411 chip_id = _furia_get_chip_id(pa); 6412 if(FURIA_IS_SIMPLEX(chip_id)) { 6413 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("FEC is not applicable for simplex packages"))); 6414 } 6415 6416 PHYMOD_IF_ERR_RETURN 6417 (READ_FURIA_PMA_PMD_REG(pa,\ 6418 FUR_MISC_CTRL_mode_dec_frc_val_Adr,\ 6419 &dec_frc_val.data)); 6420 PHYMOD_IF_ERR_RETURN 6421 (READ_FURIA_PMA_PMD_REG(pa,\ 6422 FUR_MISC_CTRL_mode_dec_frc_Adr,\ 6423 &dec_frc.data)); 6424 if(dec_frc_val.fields.rg_cl91_enabled_frc_val && 6425 dec_frc.fields.rg_cl91_enabled_frc) { 6426 *enable = 1; 6427 } else { 6428 *enable = 0; 6429 } 6430 return PHYMOD_E_NONE; 6431 } 6432 int _furia_phy_status_dump(const phymod_access_t *pa) 6433 { 6434 int pkg_side = 0; 6435 int sys_en = 0; 6436 int wr_lane = 0; 6437 int rd_lane = 0; 6438 uint32_t chip_id = 0; 6439 int num_lanes = 0; 6440 int lane_index = 0; 6441 int lane_map = 0; 6442 uint32_t acc_flags = 0; 6443 uint8_t trace_mem[768]; 6444 const FURIA_PKG_LANE_CFG_t* pkg_ln_des = NULL; 6445 6446 /* Get the lane map from phymod access */ 6447 lane_map = PHYMOD_ACC_LANE_MASK(pa); 6448 acc_flags = PHYMOD_ACC_FLAGS(pa); 6449 FURIA_GET_IF_SIDE(acc_flags, pkg_side); 6450 6451 /* Get the chip id */ 6452 chip_id = _furia_get_chip_id(pa); 6453 FURIA_GET_NUM_LANES(chip_id, num_lanes); 6454 6455 PHYMOD_DIAG_OUT((" ***************************************\n")); 6456 PHYMOD_DIAG_OUT((" ******* PHY status dump for PHY ID:%d ********\n", pa->addr)); 6457 PHYMOD_DIAG_OUT((" ***************************************\n")); 6458 /* Program the slice register */ 6459 PHYMOD_IF_ERR_RETURN 6460 (WRITE_FURIA_SLICE_REG(pa, pkg_side, 1, 0)); 6461 PHYMOD_DIAG_OUT((" ***************************************\n")); 6462 PHYMOD_DIAG_OUT((" ******* PHY status dump for side:%d ********\n", pkg_side)); 6463 PHYMOD_DIAG_OUT((" ***************************************\n")); 6464 PHYMOD_IF_ERR_RETURN(falcon_furia_display_core_config(pa)); 6465 PHYMOD_IF_ERR_RETURN(falcon_furia_display_core_state(pa)); 6466 6467 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 6468 if (((lane_map >> lane_index) & 1) == 0x1) { 6469 /* Configure Tx side(SIDE_A) first*/ 6470 pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 1); 6471 PHYMOD_NULL_CHECK(pkg_ln_des); 6472 if(pkg_side == SIDE_A) { 6473 sys_en = pkg_ln_des->sideA; 6474 } else { 6475 sys_en = pkg_ln_des->sideB; 6476 } 6477 wr_lane = pkg_ln_des->slice_wr_val; 6478 rd_lane = pkg_ln_des->slice_rd_val; 6479 /* Program the slice register */ 6480 PHYMOD_IF_ERR_RETURN 6481 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 6482 PHYMOD_IF_ERR_RETURN 6483 (falcon_furia_display_lane_state_hdr(pa)); 6484 PHYMOD_DIAG_OUT(("%2d ", lane_index)); 6485 PHYMOD_IF_ERR_RETURN(falcon_furia_display_lane_state(pa)); 6486 PHYMOD_IF_ERR_RETURN(falcon_furia_display_lane_config(pa)); 6487 } 6488 } 6489 PHYMOD_IF_ERR_RETURN(falcon_furia_read_event_log(pa, trace_mem, 2)); 6490 return PHYMOD_E_NONE; 6491 } 6492 int _furia_phy_diagnostics_get(const phymod_access_t *pa, phymod_phy_diagnostics_t* diag) 6493 { 6494 int lane_map = 0; 6495 int pkg_side = 0; 6496 int wr_lane = 0; 6497 int sys_en = 0; 6498 int rd_lane = 0; 6499 uint32_t chip_id = 0; 6500 int num_lanes = 0; 6501 int lane_index = 0; 6502 uint32_t acc_flags = 0; 6503 const FURIA_PKG_LANE_CFG_t* pkg_ln_des = NULL; 6504 falcon_furia_lane_state_st state; 6505 6506 PHYMOD_MEMSET(&state, 0 , sizeof(falcon_furia_lane_state_st)); 6507 /* Get the lane map from phymod access */ 6508 lane_map = PHYMOD_ACC_LANE_MASK(pa); 6509 acc_flags = PHYMOD_ACC_FLAGS(pa); 6510 FURIA_GET_IF_SIDE(acc_flags, pkg_side); 6511 /* Get the chip id */ 6512 chip_id = _furia_get_chip_id(pa); 6513 FURIA_GET_NUM_LANES(chip_id, num_lanes); 6514 6515 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 6516 if (((lane_map >> lane_index) & 1) == 0x1) { 6517 /* Configure Tx side(SIDE_A) first*/ 6518 pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 1); 6519 PHYMOD_NULL_CHECK(pkg_ln_des); 6520 wr_lane = pkg_ln_des->slice_wr_val; 6521 rd_lane = pkg_ln_des->slice_rd_val; 6522 if(pkg_side == SIDE_A) { 6523 sys_en = pkg_ln_des->sideA; 6524 } else { 6525 sys_en = pkg_ln_des->sideB; 6526 } 6527 6528 /* Program the slice register */ 6529 PHYMOD_IF_ERR_RETURN 6530 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 6531 PHYMOD_IF_ERR_RETURN 6532 (_falcon_furia_read_lane_state(pa, &state)); 6533 diag->signal_detect = state.sig_det; 6534 diag->osr_mode = state.osr_mode.tx_rx; 6535 diag->rx_lock = state.rx_lock; 6536 diag->tx_ppm = state.tx_ppm; 6537 diag->clk90_offset = state.clk90; 6538 diag->clkp1_offset = state.clkp1; 6539 diag->p1_lvl = state.p1_lvl; 6540 diag->dfe1_dcd = state.dfe1_dcd; 6541 diag->dfe2_dcd = state.dfe2_dcd; 6542 diag->slicer_offset.offset_pe = state.pe; 6543 diag->slicer_offset.offset_ze = state.ze; 6544 diag->slicer_offset.offset_me = state.me; 6545 diag->slicer_offset.offset_po = state.po; 6546 diag->slicer_offset.offset_zo = state.zo; 6547 diag->slicer_offset.offset_mo = state.mo; 6548 diag->eyescan.heye_left = state.heye_left; 6549 diag->eyescan.heye_right = state.heye_right; 6550 diag->eyescan.veye_upper = state.veye_upper; 6551 diag->eyescan.veye_lower = state.veye_lower; 6552 diag->link_time = state.link_time; 6553 diag->pf_main = state.pf_main; 6554 diag->pf_hiz = state.pf_hiz; 6555 diag->pf_bst = state.pf_bst; 6556 diag->pf2_ctrl = state.pf2_ctrl; 6557 diag->vga = state.vga; 6558 diag->dc_offset = state.dc_offset; 6559 diag->p1_lvl_ctrl = state.p1_lvl_ctrl; 6560 diag->dfe1 = state.dfe1; 6561 diag->dfe2 = state.dfe2; 6562 diag->dfe3 = state.dfe3; 6563 diag->dfe4 = state.dfe4; 6564 diag->dfe5 = state.dfe5; 6565 diag->dfe6 = state.dfe6; 6566 diag->txfir_pre = state.txfir_pre; 6567 diag->txfir_main = state.txfir_main; 6568 diag->txfir_post1 = state.txfir_post1; 6569 diag->txfir_post2 = state.txfir_post2; 6570 diag->txfir_post3 = state.txfir_post3; 6571 diag->br_pd_en = state.br_pd_en; 6572 break; 6573 } 6574 } 6575 /* Set the slice register with default values */ 6576 PHYMOD_IF_ERR_RETURN 6577 (WRITE_FURIA_SLICE_REG(pa, 0, 1, 0)); 6578 return PHYMOD_E_NONE; 6579 } 6580 6581 6582 /** Get bit postion for give interrupt type. 6583 * 6584 * @param intr_type Select the interrupt type. 6585 * @param bit_pos Select bits position of interrupt 6586 * @param int_grp Select interrupt group 6587 * 6588 * Return val: [7:0] = interrupt bit postion in interrupt control register. 6589 * [31:8] = Interrupt group. 6590 * 0 - m0_type 6591 * 1 - sys falcon 6592 * 2 - line falcon 6593 * 3 - rx 6594 * 4 - tx 6595 */ 6596 6597 int _furia_get_intr_reg (const phymod_phy_access_t *phy, uint32_t intr_type, uint32_t *bit_pos, uint32_t *int_grp) { 6598 6599 uint16_t lane_mask = 0; 6600 const phymod_access_t *pa = &phy->access; 6601 uint32_t intr = -1; 6602 const FURIA_PKG_LANE_CFG_t* pkg_ln_des = NULL; 6603 int pkg_side = 0; 6604 uint32_t acc_flags = 0; 6605 uint32_t chip_id = 0; 6606 int num_lanes = 0 ,lane_index = 0; 6607 uint32_t an_master_lane = 0, pkg_lane = 0; 6608 6609 /* Get the lane map from phymod access */ 6610 lane_mask = PHYMOD_ACC_LANE_MASK(pa); 6611 acc_flags = PHYMOD_ACC_FLAGS(pa); 6612 FURIA_GET_IF_SIDE(acc_flags, pkg_side); 6613 /* Get the chip id */ 6614 chip_id = _furia_get_chip_id(pa); 6615 FURIA_GET_NUM_LANES(chip_id, num_lanes); 6616 6617 for( lane_index = 0; lane_index < num_lanes ; lane_index++){ 6618 if (((lane_mask >> lane_index) & 1) == 0x1) { 6619 break; 6620 } 6621 } 6622 switch (intr_type) { 6623 case PHYMOD_INTR_AUTONEG_EVENT: 6624 if (lane_mask == 0xF) { 6625 PHYMOD_IF_ERR_RETURN( 6626 _furia_cfg_an_master_lane_get(pa,&an_master_lane)); 6627 PHYMOD_IF_ERR_RETURN( 6628 _furia_get_pkg_lane(pa->addr, chip_id, an_master_lane, 0, &pkg_lane)); 6629 intr = INT_CL73_AN_COMPLETE_0 + pkg_lane ; 6630 }else{ 6631 pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 1); 6632 PHYMOD_NULL_CHECK(pkg_ln_des); 6633 6634 if(pkg_ln_des->die_lane_num == 0){ 6635 intr = INT_CL73_AN_COMPLETE_0; 6636 } else if(pkg_ln_des->die_lane_num == 1){ 6637 intr = INT_CL73_AN_COMPLETE_1; 6638 } else if(pkg_ln_des->die_lane_num == 2){ 6639 intr = INT_CL73_AN_COMPLETE_2; 6640 } else if(pkg_ln_des->die_lane_num == 3){ 6641 intr = INT_CL73_AN_COMPLETE_3; 6642 } 6643 } 6644 break; 6645 case PHYMOD_INTR_PLL_EVENT: 6646 intr = ( pkg_side == SIDE_A )? INT_LINE_PLL_LOCK_LOST : INT_SYS_PLL_LOCK_LOST ; 6647 break; 6648 default: 6649 return PHYMOD_E_NONE; 6650 } 6651 6652 switch (intr) { 6653 case INT_M0_SLV_SYSRESET_REQ: 6654 *bit_pos = 0; 6655 *int_grp = 0; 6656 break; 6657 case INT_M0_MST_SYSRESET_REQ: 6658 *bit_pos = 1; 6659 *int_grp = 0; 6660 break; 6661 case INT_M0_SLV_LOCKUP: 6662 *bit_pos = 2; 6663 *int_grp = 0; 6664 break; 6665 case INT_M0_MST_LOCKUP: 6666 *bit_pos = 3; 6667 *int_grp = 0; 6668 break; 6669 case INT_M0_SLV_MISC_INTR: 6670 *bit_pos = 4; 6671 *int_grp = 0; 6672 break; 6673 case INT_M0_MST_MISC_INTR: 6674 *bit_pos = 5; 6675 *int_grp = 0; 6676 break; 6677 case INT_M0_SLV_MSGOUT_INTR: 6678 *bit_pos = 6; 6679 *int_grp = 0; 6680 break; 6681 case INT_M0_MST_MSGOUT_INTR: 6682 *bit_pos = 7; 6683 *int_grp = 0; 6684 break; 6685 case INT_M0_SLV_DED: 6686 *bit_pos = 8; 6687 *int_grp = 0; 6688 break; 6689 case INT_M0_SLV_SEC: 6690 *bit_pos = 9; 6691 *int_grp = 0; 6692 break; 6693 case INT_M0_MST_DED: 6694 *bit_pos = 10; 6695 *int_grp = 0; 6696 break; 6697 case INT_M0_MST_SEC: 6698 *bit_pos = 11; 6699 *int_grp = 0; 6700 break; 6701 case INT_SYS_1GCDR_LOCK_LOST: 6702 *bit_pos = 0; 6703 *int_grp = 1; 6704 break; 6705 case INT_SYS_1GCDR_LOCK_FOUND: 6706 *bit_pos = 1; 6707 *int_grp = 1; 6708 break; 6709 case INT_SYS_PMD_LOCK_LOST: 6710 *bit_pos = 2; 6711 *int_grp = 1; 6712 break; 6713 case INT_SYS_PMD_LOCK_FOUND: 6714 *bit_pos = 3; 6715 *int_grp = 1; 6716 break; 6717 case INT_SYS_RX_SIGDET_LOST: 6718 *bit_pos = 4; 6719 *int_grp = 1; 6720 break; 6721 case INT_SYS_RX_SIGDET_FOUND: 6722 *bit_pos = 5; 6723 *int_grp = 1; 6724 break; 6725 case INT_SYS_PLL_LOCK_LOST: 6726 *bit_pos = 6; 6727 *int_grp = 1; 6728 break; 6729 case INT_SYS_PLL_LOCK_FOUND: 6730 *bit_pos = 7; 6731 *int_grp = 1; 6732 break; 6733 case INT_SYS_PMI_ARB_WDOG_EXP: 6734 *bit_pos = 8; 6735 *int_grp = 1; 6736 break; 6737 case INT_SYS_PMI_M0_WDOG_EXP: 6738 *bit_pos = 9; 6739 *int_grp = 1; 6740 break; 6741 case INT_LINE_1GCDR_LOCK_LOST: 6742 *bit_pos = 0; 6743 *int_grp = 2; 6744 break; 6745 case INT_LINE_1GCDR_LOCK_FOUND: 6746 *bit_pos = 1; 6747 *int_grp = 2; 6748 break; 6749 case INT_LINE_PMD_LOCK_LOST: 6750 *bit_pos = 2; 6751 *int_grp = 2; 6752 break; 6753 case INT_LINE_PMD_LOCK_FOUND: 6754 *bit_pos = 3; 6755 *int_grp = 2; 6756 break; 6757 case INT_LINE_RX_SIGDET_LOST: 6758 *bit_pos = 4; 6759 *int_grp = 2; 6760 break; 6761 case INT_LINE_RX_SIGDET_FOUND: 6762 *bit_pos = 5; 6763 *int_grp = 2; 6764 break; 6765 case INT_LINE_PLL_LOCK_LOST: 6766 *bit_pos = 6; 6767 *int_grp = 2; 6768 break; 6769 case INT_LINE_PLL_LOCK_FOUND: 6770 *bit_pos = 7; 6771 *int_grp = 2; 6772 break; 6773 case INT_LINE_PMI_ARB_WDOG_EXP: 6774 *bit_pos = 8; 6775 *int_grp = 2; 6776 break; 6777 case INT_LINE_PMI_M0_WDOG_EXP: 6778 *bit_pos = 9; 6779 *int_grp = 2; 6780 break; 6781 case INT_CL91_RX_ALIGN_LOST: 6782 *bit_pos = 0; 6783 *int_grp = 3; 6784 break; 6785 case INT_CL91_RX_ALIGN_FOUND: 6786 *bit_pos = 1; 6787 *int_grp = 3; 6788 break; 6789 case INT_CL73_AN_RESTARTED: 6790 *bit_pos = 2; 6791 *int_grp = 3; 6792 break; 6793 case INT_CL73_AN_COMPLETE: 6794 *bit_pos = 3; 6795 *int_grp = 3; 6796 break; 6797 case INT_LINE_RX_PCSFC_MON_LOCK_LOST: 6798 *bit_pos = 4; 6799 *int_grp = 3; 6800 break; 6801 case INT_LINE_RX_PCSFC_MON_LOCK_FOUND: 6802 *bit_pos = 5; 6803 *int_grp = 3; 6804 break; 6805 case INT_SYS_TX_FIFOERR: 6806 *bit_pos = 6; 6807 *int_grp = 3; 6808 break; 6809 case INT_LINE_RX_FIFOERR: 6810 *bit_pos = 7; 6811 *int_grp = 3; 6812 break; 6813 case INT_CL73_AN_RESTARTED_3: 6814 *bit_pos = 8; 6815 *int_grp = 3; 6816 break; 6817 case INT_CL73_AN_RESTARTED_2: 6818 *bit_pos = 9; 6819 *int_grp = 3; 6820 break; 6821 case INT_CL73_AN_RESTARTED_1: 6822 *bit_pos = 10; 6823 *int_grp = 3; 6824 break; 6825 case INT_CL73_AN_RESTARTED_0: 6826 *bit_pos = 11; 6827 *int_grp = 3; 6828 break; 6829 case INT_CL73_AN_COMPLETE_3: 6830 *bit_pos = 12; 6831 *int_grp = 3; 6832 break; 6833 case INT_CL73_AN_COMPLETE_2: 6834 *bit_pos = 13; 6835 *int_grp = 3; 6836 break; 6837 case INT_CL73_AN_COMPLETE_1: 6838 *bit_pos = 14; 6839 *int_grp = 3; 6840 break; 6841 case INT_CL73_AN_COMPLETE_0: 6842 *bit_pos = 15; 6843 *int_grp = 3; 6844 break; 6845 case INT_CL91_TX_ALIGN_LOST: 6846 *bit_pos = 16; 6847 *int_grp = 4; 6848 break; 6849 case INT_CL91_TX_ALIGN_FOUND: 6850 *bit_pos = 1; 6851 *int_grp = 4; 6852 break; 6853 case INT_ONEG_INBAND_MSG_LOST: 6854 *bit_pos = 2; 6855 *int_grp = 4; 6856 break; 6857 case INT_ONEG_INBAND_MSG_FOUND: 6858 *bit_pos = 3; 6859 *int_grp = 4; 6860 break; 6861 case INT_SYS_RX_PCSFC_MON_LOCK_LOST: 6862 *bit_pos = 4; 6863 *int_grp = 4; 6864 break; 6865 case INT_SYS_RX_PCSFC_MON_LOCK_FOUND: 6866 *bit_pos = 5; 6867 *int_grp = 4; 6868 break; 6869 case INT_LINE_TX_FIFOERR: 6870 *bit_pos = 6; 6871 *int_grp = 4; 6872 break; 6873 case INT_SYS_RX_FIFOERR: 6874 *bit_pos = 7; 6875 *int_grp = 4; 6876 break; 6877 } 6878 return PHYMOD_E_NONE; 6879 } 6880 6881 int furia_ext_intr_status_get(const phymod_phy_access_t *phy, uint32_t intr_type, uint32_t* intr_status) 6882 { 6883 uint32_t intr_grp = 0; 6884 uint32_t bit_pos = 0; 6885 uint32_t rd_data = 0; 6886 FUR_MISC_CTRL_M0_EIPR_t m0_eipr; 6887 FUR_MISC_CTRL_SF_EIPR_t sf_eipr; 6888 FUR_MISC_CTRL_LF_EIPR_t lf_eipr; 6889 FUR_MISC_CTRL_RX_EIPR_t rx_eipr; 6890 FUR_MISC_CTRL_TX_EIPR_t tx_eipr; 6891 const phymod_access_t *pa = &phy->access; 6892 6893 PHYMOD_MEMSET(&m0_eipr, 0 , sizeof(FUR_MISC_CTRL_M0_EIPR_t)); 6894 PHYMOD_MEMSET(&sf_eipr, 0 , sizeof(FUR_MISC_CTRL_SF_EIPR_t)); 6895 PHYMOD_MEMSET(&lf_eipr, 0 , sizeof(FUR_MISC_CTRL_LF_EIPR_t)); 6896 PHYMOD_MEMSET(&rx_eipr, 0 , sizeof(FUR_MISC_CTRL_RX_EIPR_t)); 6897 PHYMOD_MEMSET(&tx_eipr, 0 , sizeof(FUR_MISC_CTRL_TX_EIPR_t)); 6898 6899 _furia_get_intr_reg(phy, intr_type, &bit_pos, &intr_grp); 6900 6901 switch(intr_grp) { 6902 case 0: 6903 PHYMOD_IF_ERR_RETURN 6904 (READ_FURIA_PMA_PMD_REG(pa,\ 6905 FUR_MISC_CTRL_m0_eipr_Adr,\ 6906 &m0_eipr.data)); 6907 rd_data = m0_eipr.data; 6908 break; 6909 case 1: 6910 PHYMOD_IF_ERR_RETURN 6911 (READ_FURIA_PMA_PMD_REG(pa,\ 6912 FUR_MISC_CTRL_sf_eipr_Adr,\ 6913 &sf_eipr.data)); 6914 rd_data = sf_eipr.data; 6915 break; 6916 case 2: 6917 PHYMOD_IF_ERR_RETURN 6918 (READ_FURIA_PMA_PMD_REG(pa,\ 6919 FUR_MISC_CTRL_lf_eipr_Adr,\ 6920 &lf_eipr.data)); 6921 rd_data = lf_eipr.data; 6922 break; 6923 case 3: 6924 PHYMOD_IF_ERR_RETURN 6925 (READ_FURIA_PMA_PMD_REG(pa,\ 6926 FUR_MISC_CTRL_rx_eipr_Adr,\ 6927 &rx_eipr.data)); 6928 rd_data = rx_eipr.data; 6929 break; 6930 case 4: 6931 PHYMOD_IF_ERR_RETURN 6932 (READ_FURIA_PMA_PMD_REG(pa,\ 6933 FUR_MISC_CTRL_tx_eipr_Adr,\ 6934 &tx_eipr.data)); 6935 rd_data = tx_eipr.data; 6936 break; 6937 default: 6938 break; 6939 } 6940 6941 *intr_status = (rd_data & (0x1 << bit_pos)) ? 1 : 0; 6942 return PHYMOD_E_NONE; 6943 } 6944 6945 int furia_ext_intr_enable_set(const phymod_phy_access_t *phy, uint32_t intr_type, uint32_t enable) 6946 { 6947 FUR_MISC_CTRL_M0_EIMR_t m0_eimr; 6948 FUR_MISC_CTRL_SF_EIMR_t sf_eimr; 6949 FUR_MISC_CTRL_LF_EIMR_t lf_eimr; 6950 FUR_MISC_CTRL_RX_EIMR_t rx_eimr; 6951 FUR_MISC_CTRL_TX_EIMR_t tx_eimr; 6952 const phymod_access_t *pa = &phy->access; 6953 6954 uint32_t intr_grp = 0; 6955 uint32_t bit_pos = 0; 6956 uint32_t intr_mask = 0; 6957 PHYMOD_MEMSET(&m0_eimr, 0 , sizeof(FUR_MISC_CTRL_M0_EIMR_t)); 6958 PHYMOD_MEMSET(&sf_eimr, 0 , sizeof(FUR_MISC_CTRL_SF_EIMR_t)); 6959 PHYMOD_MEMSET(&lf_eimr, 0 , sizeof(FUR_MISC_CTRL_LF_EIMR_t)); 6960 PHYMOD_MEMSET(&rx_eimr, 0 , sizeof(FUR_MISC_CTRL_RX_EIMR_t)); 6961 PHYMOD_MEMSET(&tx_eimr, 0 , sizeof(FUR_MISC_CTRL_TX_EIMR_t)); 6962 6963 _furia_get_intr_reg(phy, intr_type, &bit_pos, &intr_grp); 6964 6965 intr_mask = enable ? (0x1 << bit_pos) : (~(0x1 << bit_pos)); 6966 switch(intr_grp) { 6967 case 0: 6968 PHYMOD_IF_ERR_RETURN 6969 (READ_FURIA_PMA_PMD_REG(pa,\ 6970 FUR_MISC_CTRL_m0_eimr_Adr,\ 6971 &m0_eimr.data)); 6972 m0_eimr.data = enable ? (intr_mask | m0_eimr.data) : (intr_mask & m0_eimr.data); 6973 PHYMOD_IF_ERR_RETURN 6974 (WRITE_FURIA_PMA_PMD_REG(pa,\ 6975 FUR_MISC_CTRL_m0_eimr_Adr,\ 6976 m0_eimr.data)); 6977 break; 6978 case 1: 6979 PHYMOD_IF_ERR_RETURN 6980 (READ_FURIA_PMA_PMD_REG(pa,\ 6981 FUR_MISC_CTRL_sf_eimr_Adr,\ 6982 &sf_eimr.data)); 6983 sf_eimr.data = enable ? (intr_mask | sf_eimr.data) : (intr_mask & sf_eimr.data); 6984 PHYMOD_IF_ERR_RETURN 6985 (WRITE_FURIA_PMA_PMD_REG(pa,\ 6986 FUR_MISC_CTRL_sf_eimr_Adr,\ 6987 sf_eimr.data)); 6988 break; 6989 case 2: 6990 PHYMOD_IF_ERR_RETURN 6991 (READ_FURIA_PMA_PMD_REG(pa,\ 6992 FUR_MISC_CTRL_lf_eimr_Adr,\ 6993 &lf_eimr.data)); 6994 lf_eimr.data = enable ? (intr_mask | lf_eimr.data) : (intr_mask & lf_eimr.data); 6995 PHYMOD_IF_ERR_RETURN 6996 (WRITE_FURIA_PMA_PMD_REG(pa,\ 6997 FUR_MISC_CTRL_lf_eimr_Adr,\ 6998 lf_eimr.data)); 6999 break; 7000 case 3: 7001 PHYMOD_IF_ERR_RETURN 7002 (READ_FURIA_PMA_PMD_REG(pa,\ 7003 FUR_MISC_CTRL_rx_eimr_Adr,\ 7004 &rx_eimr.data)); 7005 rx_eimr.data = enable ? (intr_mask | rx_eimr.data) : (intr_mask & rx_eimr.data); 7006 PHYMOD_IF_ERR_RETURN 7007 (WRITE_FURIA_PMA_PMD_REG(pa,\ 7008 FUR_MISC_CTRL_rx_eimr_Adr,\ 7009 rx_eimr.data)); 7010 break; 7011 case 4: 7012 PHYMOD_IF_ERR_RETURN 7013 (READ_FURIA_PMA_PMD_REG(pa,\ 7014 FUR_MISC_CTRL_tx_eimr_Adr,\ 7015 &tx_eimr.data)); 7016 tx_eimr.data = enable ? (intr_mask | tx_eimr.data) : (intr_mask & tx_eimr.data); 7017 PHYMOD_IF_ERR_RETURN 7018 (WRITE_FURIA_PMA_PMD_REG(pa,\ 7019 FUR_MISC_CTRL_tx_eimr_Adr,\ 7020 tx_eimr.data)); 7021 break; 7022 default: 7023 break; 7024 } 7025 return PHYMOD_E_NONE; 7026 } 7027 7028 int furia_ext_intr_enable_get(const phymod_phy_access_t *phy, uint32_t intr_type, uint32_t* enable) 7029 { 7030 FUR_MISC_CTRL_M0_EIMR_t m0_eimr; 7031 FUR_MISC_CTRL_SF_EIMR_t sf_eimr; 7032 FUR_MISC_CTRL_LF_EIMR_t lf_eimr; 7033 FUR_MISC_CTRL_RX_EIMR_t rx_eimr; 7034 FUR_MISC_CTRL_TX_EIMR_t tx_eimr; 7035 uint32_t intr_grp = 0; 7036 uint32_t bit_pos = 0; 7037 uint32_t intr_mask = 0; 7038 uint16_t rd_data = 0; 7039 const phymod_access_t *pa = &phy->access; 7040 7041 PHYMOD_MEMSET(&m0_eimr, 0 , sizeof(FUR_MISC_CTRL_M0_EIMR_t)); 7042 PHYMOD_MEMSET(&sf_eimr, 0 , sizeof(FUR_MISC_CTRL_SF_EIMR_t)); 7043 PHYMOD_MEMSET(&lf_eimr, 0 , sizeof(FUR_MISC_CTRL_LF_EIMR_t)); 7044 PHYMOD_MEMSET(&rx_eimr, 0 , sizeof(FUR_MISC_CTRL_RX_EIMR_t)); 7045 PHYMOD_MEMSET(&tx_eimr, 0 , sizeof(FUR_MISC_CTRL_TX_EIMR_t)); 7046 7047 _furia_get_intr_reg(phy,intr_type, &bit_pos, &intr_grp); 7048 intr_mask = 0x1 << bit_pos; 7049 7050 switch(intr_grp) { 7051 case 0: 7052 PHYMOD_IF_ERR_RETURN 7053 (READ_FURIA_PMA_PMD_REG(pa,\ 7054 FUR_MISC_CTRL_m0_eimr_Adr,\ 7055 &m0_eimr.data)); 7056 rd_data = m0_eimr.data; 7057 break; 7058 case 1: 7059 PHYMOD_IF_ERR_RETURN 7060 (READ_FURIA_PMA_PMD_REG(pa,\ 7061 FUR_MISC_CTRL_sf_eimr_Adr,\ 7062 &sf_eimr.data)); 7063 rd_data = sf_eimr.data; 7064 break; 7065 case 2: 7066 PHYMOD_IF_ERR_RETURN 7067 (READ_FURIA_PMA_PMD_REG(pa,\ 7068 FUR_MISC_CTRL_lf_eimr_Adr,\ 7069 &lf_eimr.data)); 7070 rd_data = lf_eimr.data; 7071 break; 7072 case 3: 7073 PHYMOD_IF_ERR_RETURN 7074 (READ_FURIA_PMA_PMD_REG(pa,\ 7075 FUR_MISC_CTRL_rx_eimr_Adr,\ 7076 &rx_eimr.data)); 7077 rd_data = rx_eimr.data; 7078 break; 7079 case 4: 7080 PHYMOD_IF_ERR_RETURN 7081 (READ_FURIA_PMA_PMD_REG(pa,\ 7082 FUR_MISC_CTRL_tx_eimr_Adr,\ 7083 &tx_eimr.data)); 7084 rd_data = tx_eimr.data; 7085 break; 7086 default: 7087 break; 7088 } 7089 *enable = (rd_data & intr_mask) ? 1 : 0; 7090 return PHYMOD_E_NONE; 7091 } 7092 7093 int furia_ext_intr_status_clear(const phymod_phy_access_t *phy, uint32_t intr_type) 7094 { 7095 uint32_t intr_grp = 0; 7096 uint32_t bit_pos = 0; 7097 uint32_t intr_mask = 0; 7098 const phymod_access_t *pa = &phy->access; 7099 7100 _furia_get_intr_reg(phy, intr_type, &bit_pos, &intr_grp); 7101 intr_mask = 0x1 << bit_pos; 7102 7103 switch(intr_grp) { 7104 case 0: 7105 PHYMOD_IF_ERR_RETURN 7106 (WRITE_FURIA_PMA_PMD_REG(pa,\ 7107 FUR_MISC_CTRL_m0_eisr_Adr,\ 7108 intr_mask)); 7109 break; 7110 case 1: 7111 PHYMOD_IF_ERR_RETURN 7112 (WRITE_FURIA_PMA_PMD_REG(pa,\ 7113 FUR_MISC_CTRL_sf_eisr_Adr,\ 7114 intr_mask)); 7115 break; 7116 case 2: 7117 PHYMOD_IF_ERR_RETURN 7118 (WRITE_FURIA_PMA_PMD_REG(pa,\ 7119 FUR_MISC_CTRL_lf_eisr_Adr,\ 7120 intr_mask)); 7121 break; 7122 case 3: 7123 PHYMOD_IF_ERR_RETURN 7124 (WRITE_FURIA_PMA_PMD_REG(pa,\ 7125 FUR_MISC_CTRL_rx_eisr_Adr,\ 7126 intr_mask)); 7127 break; 7128 case 4: 7129 PHYMOD_IF_ERR_RETURN 7130 (WRITE_FURIA_PMA_PMD_REG(pa,\ 7131 FUR_MISC_CTRL_tx_eisr_Adr,\ 7132 intr_mask)); 7133 break; 7134 default: 7135 break; 7136 } 7137 return PHYMOD_E_NONE; 7138 } 7139 int furia_fc_pcs_chkr_enable_set(const phymod_access_t *pa, uint32_t fcpcs_chkr_mode, uint32_t enable) 7140 { 7141 int lane_map = 0; 7142 int pkg_side = 0; 7143 int wr_lane = 0; 7144 int sys_en = 0; 7145 int rd_lane = 0; 7146 uint32_t chip_id = 0; 7147 int num_lanes = 0; 7148 int lane_index = 0; 7149 uint32_t acc_flags = 0; 7150 const FURIA_PKG_LANE_CFG_t* pkg_ln_des = NULL; 7151 LINE_RX_PMA_DP_MAIN_CTRL_t line_rx_dp_main_ctrl; 7152 SYS_RX_PMA_DP_MAIN_CTRL_t sys_rx_dp_main_ctrl; 7153 LINE_RX_PMA_DP_MAIN_CTRL_PCS_MODE_t tmp_main_ctrl_mode; 7154 PHYMOD_MEMSET(&line_rx_dp_main_ctrl, 0 , sizeof(LINE_RX_PMA_DP_MAIN_CTRL_t)); 7155 PHYMOD_MEMSET(&sys_rx_dp_main_ctrl, 0 , sizeof(SYS_RX_PMA_DP_MAIN_CTRL_t)); 7156 PHYMOD_MEMSET(&tmp_main_ctrl_mode, 0 , sizeof(LINE_RX_PMA_DP_MAIN_CTRL_PCS_MODE_t)); 7157 7158 /* Get the lane map from phymod access */ 7159 lane_map = PHYMOD_ACC_LANE_MASK(pa); 7160 acc_flags = PHYMOD_ACC_FLAGS(pa); 7161 FURIA_GET_IF_SIDE(acc_flags, pkg_side); 7162 /* Get the chip id */ 7163 chip_id = _furia_get_chip_id(pa); 7164 FURIA_GET_NUM_LANES(chip_id, num_lanes); 7165 7166 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 7167 if (((lane_map >> lane_index) & 1) == 0x1) { 7168 /* Configure Tx side(SIDE_A) first*/ 7169 pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 1); 7170 PHYMOD_NULL_CHECK(pkg_ln_des); 7171 wr_lane = FURIA_IF_BCAST_SET(chip_id, lane_map) ? BROADCAST : pkg_ln_des->slice_wr_val; 7172 rd_lane = pkg_ln_des->slice_rd_val; 7173 if(pkg_side == SIDE_A) { 7174 sys_en = pkg_ln_des->sideA; 7175 } else { 7176 sys_en = pkg_ln_des->sideB; 7177 } 7178 7179 /* Program the slice register */ 7180 PHYMOD_IF_ERR_RETURN 7181 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 7182 7183 if (FURIA_IF_RX_SIDE(chip_id, pkg_side)) { 7184 if(sys_en == LINE) { 7185 PHYMOD_IF_ERR_RETURN 7186 (READ_FURIA_PMA_PMD_REG(pa,\ 7187 LINE_RX_PMA_DP_main_ctrl_Adr,\ 7188 &line_rx_dp_main_ctrl.data)); 7189 tmp_main_ctrl_mode.data = line_rx_dp_main_ctrl.data; 7190 } else { 7191 PHYMOD_IF_ERR_RETURN 7192 (READ_FURIA_PMA_PMD_REG(pa,\ 7193 SYS_RX_PMA_DP_main_ctrl_Adr,\ 7194 &sys_rx_dp_main_ctrl.data)); 7195 tmp_main_ctrl_mode.data = sys_rx_dp_main_ctrl.data; 7196 } 7197 } 7198 tmp_main_ctrl_mode.fields.link_mon_en = 0; 7199 tmp_main_ctrl_mode.fields.link_mon_mode_frc = 0; 7200 tmp_main_ctrl_mode.fields.link_mon_mode_frcval = 0; 7201 tmp_main_ctrl_mode.fields.ber_dis = 0; 7202 tmp_main_ctrl_mode.fields.mode_50g = 0; 7203 tmp_main_ctrl_mode.fields.mode_100g = 0; 7204 tmp_main_ctrl_mode.fields.logic_lane = 0; 7205 tmp_main_ctrl_mode.fields.pcs_mon_frc = 0; 7206 7207 if(enable) { 7208 switch (fcpcs_chkr_mode) { 7209 case PCS49_1x10G : 7210 tmp_main_ctrl_mode.fields.link_mon_en = 1; 7211 tmp_main_ctrl_mode.fields.link_mon_mode_frc = 1; 7212 tmp_main_ctrl_mode.fields.link_mon_mode_frcval = 0x0; /* CL49 */ 7213 break; 7214 case PCS82_4x10G : 7215 case FC16 : 7216 case FC32 : 7217 tmp_main_ctrl_mode.fields.link_mon_en = 1; 7218 tmp_main_ctrl_mode.fields.link_mon_mode_frc = 1; 7219 tmp_main_ctrl_mode.fields.link_mon_mode_frcval = 0x1; /* CL82 with 1-PCS lane per 1-phy-lane */ 7220 break; 7221 case PCS82_2x25G : 7222 tmp_main_ctrl_mode.fields.link_mon_en = 1; 7223 tmp_main_ctrl_mode.fields.link_mon_mode_frc = 1; 7224 tmp_main_ctrl_mode.fields.link_mon_mode_frcval = 0x1; /* CL82 */ 7225 tmp_main_ctrl_mode.fields.mode_50g = 1; /* 2-PCS lanes per phy-lane */ 7226 tmp_main_ctrl_mode.fields.pcs_mon_frc = 1; 7227 break; 7228 case PCS82_4x25G : 7229 tmp_main_ctrl_mode.fields.link_mon_en = 1; 7230 tmp_main_ctrl_mode.fields.link_mon_mode_frc = 1; 7231 tmp_main_ctrl_mode.fields.link_mon_mode_frcval = 0x1; /* CL82 */ 7232 tmp_main_ctrl_mode.fields.mode_100g = 1; /* 5-PCS lanes per phy-lane */ 7233 tmp_main_ctrl_mode.fields.pcs_mon_frc = 1; 7234 break; 7235 case FC4 : 7236 tmp_main_ctrl_mode.fields.link_mon_en = 1; 7237 tmp_main_ctrl_mode.fields.link_mon_mode_frc = 1; 7238 tmp_main_ctrl_mode.fields.link_mon_mode_frcval = 0x2; /* FC4 */ 7239 break; 7240 case FC8 : 7241 tmp_main_ctrl_mode.fields.link_mon_en = 1; 7242 tmp_main_ctrl_mode.fields.link_mon_mode_frc = 1; 7243 tmp_main_ctrl_mode.fields.link_mon_mode_frcval = 0x3; /* FC8 */ 7244 break; 7245 default: 7246 break; 7247 } 7248 } else { 7249 tmp_main_ctrl_mode.fields.link_mon_en = 0; 7250 } 7251 if ((FURIA_IS_SIMPLEX(chip_id) && (pkg_side == SIDE_B)) || 7252 (FURIA_IS_DUPLEX(chip_id))) { 7253 if(sys_en == LINE) { 7254 PHYMOD_IF_ERR_RETURN 7255 (WRITE_FURIA_PMA_PMD_REG(pa,\ 7256 LINE_RX_PMA_DP_main_ctrl_Adr,\ 7257 tmp_main_ctrl_mode.data)); 7258 } else { 7259 PHYMOD_IF_ERR_RETURN 7260 (WRITE_FURIA_PMA_PMD_REG(pa,\ 7261 SYS_RX_PMA_DP_main_ctrl_Adr,\ 7262 tmp_main_ctrl_mode.data)); 7263 } 7264 } 7265 7266 if (FURIA_IF_BCAST_SET(chip_id, lane_map)) { 7267 break; 7268 } 7269 } 7270 } 7271 /* Set the slice register with default values */ 7272 PHYMOD_IF_ERR_RETURN 7273 (WRITE_FURIA_SLICE_REG(pa, 0, 1, 0)); 7274 return PHYMOD_E_NONE; 7275 } 7276 int furia_fc_pcs_chkr_enable_get(const phymod_access_t *pa, uint32_t fcpcs_chkr_mode, uint32_t* enable) 7277 { 7278 int lane_map = 0; 7279 int pkg_side = 0; 7280 int wr_lane = 0; 7281 int sys_en = 0; 7282 int rd_lane = 0; 7283 uint32_t chip_id = 0; 7284 int num_lanes = 0; 7285 int lane_index = 0; 7286 uint32_t acc_flags = 0; 7287 const FURIA_PKG_LANE_CFG_t* pkg_ln_des = NULL; 7288 LINE_RX_PMA_DP_MAIN_CTRL_t line_rx_dp_main_ctrl; 7289 SYS_RX_PMA_DP_MAIN_CTRL_t sys_rx_dp_main_ctrl; 7290 LINE_RX_PMA_DP_MAIN_CTRL_PCS_MODE_t tmp_main_ctrl_mode; 7291 PHYMOD_MEMSET(&line_rx_dp_main_ctrl, 0 , sizeof(LINE_RX_PMA_DP_MAIN_CTRL_t)); 7292 PHYMOD_MEMSET(&sys_rx_dp_main_ctrl, 0 , sizeof(SYS_RX_PMA_DP_MAIN_CTRL_t)); 7293 PHYMOD_MEMSET(&tmp_main_ctrl_mode, 0 , sizeof(LINE_RX_PMA_DP_MAIN_CTRL_PCS_MODE_t)); 7294 7295 7296 /* Get the lane map from phymod access */ 7297 lane_map = PHYMOD_ACC_LANE_MASK(pa); 7298 acc_flags = PHYMOD_ACC_FLAGS(pa); 7299 FURIA_GET_IF_SIDE(acc_flags, pkg_side); 7300 /* Get the chip id */ 7301 chip_id = _furia_get_chip_id(pa); 7302 FURIA_GET_NUM_LANES(chip_id, num_lanes); 7303 7304 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 7305 if (((lane_map >> lane_index) & 1) == 0x1) { 7306 /* Configure Tx side(SIDE_A) first*/ 7307 pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 1); 7308 PHYMOD_NULL_CHECK(pkg_ln_des); 7309 wr_lane = pkg_ln_des->slice_wr_val; 7310 rd_lane = pkg_ln_des->slice_rd_val; 7311 if(pkg_side == SIDE_A) { 7312 sys_en = pkg_ln_des->sideA; 7313 } else { 7314 sys_en = pkg_ln_des->sideB; 7315 } 7316 7317 /* Program the slice register */ 7318 PHYMOD_IF_ERR_RETURN 7319 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 7320 7321 if (FURIA_IS_DUPLEX(chip_id)) { 7322 if(pkg_side == SIDE_A || pkg_side == SIDE_B) { 7323 if(sys_en == LINE) { 7324 PHYMOD_IF_ERR_RETURN 7325 (READ_FURIA_PMA_PMD_REG(pa,\ 7326 LINE_RX_PMA_DP_main_ctrl_Adr,\ 7327 &line_rx_dp_main_ctrl.data)); 7328 tmp_main_ctrl_mode.data = line_rx_dp_main_ctrl.data; 7329 } else { 7330 PHYMOD_IF_ERR_RETURN 7331 (READ_FURIA_PMA_PMD_REG(pa,\ 7332 SYS_RX_PMA_DP_main_ctrl_Adr,\ 7333 &sys_rx_dp_main_ctrl.data)); 7334 tmp_main_ctrl_mode.data = sys_rx_dp_main_ctrl.data; 7335 } 7336 } 7337 } else { 7338 if(pkg_side == SIDE_B) { 7339 if(sys_en == LINE) { 7340 PHYMOD_IF_ERR_RETURN 7341 (READ_FURIA_PMA_PMD_REG(pa,\ 7342 LINE_RX_PMA_DP_main_ctrl_Adr,\ 7343 &line_rx_dp_main_ctrl.data)); 7344 tmp_main_ctrl_mode.data = line_rx_dp_main_ctrl.data; 7345 } else { 7346 PHYMOD_IF_ERR_RETURN 7347 (READ_FURIA_PMA_PMD_REG(pa,\ 7348 SYS_RX_PMA_DP_main_ctrl_Adr,\ 7349 &sys_rx_dp_main_ctrl.data)); 7350 tmp_main_ctrl_mode.data = sys_rx_dp_main_ctrl.data; 7351 } 7352 } 7353 } 7354 7355 switch (fcpcs_chkr_mode) { 7356 case PCS49_1x10G : 7357 if(tmp_main_ctrl_mode.fields.link_mon_en && 7358 tmp_main_ctrl_mode.fields.link_mon_mode_frc && 7359 tmp_main_ctrl_mode.fields.link_mon_mode_frcval == 0) { 7360 *enable = 1; 7361 } else { 7362 *enable = 0; 7363 } 7364 break; 7365 case PCS82_4x10G : 7366 case FC16 : 7367 case FC32 : 7368 if(tmp_main_ctrl_mode.fields.link_mon_en && 7369 tmp_main_ctrl_mode.fields.link_mon_mode_frc && 7370 tmp_main_ctrl_mode.fields.link_mon_mode_frcval) { 7371 *enable = 1; 7372 } else { 7373 *enable = 0; 7374 } 7375 break; 7376 case PCS82_2x25G : 7377 if(tmp_main_ctrl_mode.fields.link_mon_en && 7378 tmp_main_ctrl_mode.fields.link_mon_mode_frc && 7379 tmp_main_ctrl_mode.fields.link_mon_mode_frcval && 7380 tmp_main_ctrl_mode.fields.mode_50g && 7381 tmp_main_ctrl_mode.fields.pcs_mon_frc) { 7382 *enable = 1; 7383 } else { 7384 *enable = 0; 7385 } 7386 break; 7387 case PCS82_4x25G : 7388 if(tmp_main_ctrl_mode.fields.link_mon_en && 7389 tmp_main_ctrl_mode.fields.link_mon_mode_frc && 7390 tmp_main_ctrl_mode.fields.link_mon_mode_frcval && 7391 tmp_main_ctrl_mode.fields.mode_100g && 7392 tmp_main_ctrl_mode.fields.pcs_mon_frc) { 7393 *enable = 1; 7394 } else { 7395 *enable = 0; 7396 } 7397 break; 7398 case FC4 : 7399 if(tmp_main_ctrl_mode.fields.link_mon_en && 7400 tmp_main_ctrl_mode.fields.link_mon_mode_frc && 7401 tmp_main_ctrl_mode.fields.link_mon_mode_frcval == 0x2) { 7402 *enable = 1; 7403 } else { 7404 *enable = 0; 7405 } 7406 break; 7407 case FC8 : 7408 if(tmp_main_ctrl_mode.fields.link_mon_en && 7409 tmp_main_ctrl_mode.fields.link_mon_mode_frc && 7410 tmp_main_ctrl_mode.fields.link_mon_mode_frcval == 0x3) { 7411 *enable = 1; 7412 } else { 7413 *enable = 0; 7414 } 7415 break; 7416 default: 7417 break; 7418 } 7419 break; 7420 } 7421 } 7422 /* Set the slice register with default values */ 7423 PHYMOD_IF_ERR_RETURN 7424 (WRITE_FURIA_SLICE_REG(pa, 0, 1, 0)); 7425 return PHYMOD_E_NONE; 7426 } 7427 int furia_fc_pcs_chkr_status_get(const phymod_access_t *pa, uint32_t* lock_status, uint32_t* lock_lost_lh, uint32_t* error_count) 7428 { 7429 int lane_map = 0; 7430 int pkg_side = 0; 7431 int wr_lane = 0; 7432 int sys_en = 0; 7433 int rd_lane = 0; 7434 uint32_t chip_id = 0; 7435 int num_lanes = 0; 7436 int lane_index = 0; 7437 uint32_t acc_flags = 0; 7438 uint16_t fcpcs_chkr_mode = 0; 7439 const FURIA_PKG_LANE_CFG_t* pkg_ln_des = NULL; 7440 LINE_RX_PMA_DP_MAIN_CTRL_t line_rx_dp_main_ctrl; 7441 LINE_RX_PMA_DP_MAIN_CTRL_PCS_MODE_t tmp_main_ctrl_mode; 7442 SYS_RX_PMA_DP_MAIN_CTRL_t sys_rx_dp_main_ctrl; 7443 LINE_RX_PMA_DP_CL82_BER_COUNT_MSB_t line_rx_pma_dp_cl82_ber_cnt_msb; 7444 SYS_RX_PMA_DP_CL82_BER_COUNT_MSB_t sys_rx_pma_dp_cl82_ber_cnt_msb; 7445 LINE_RX_PMA_DP_LATCHED_STATUS_FC_MODE_t line_rx_pma_dp_latched_status_fc_mode; 7446 LINE_RX_PMA_DP_LATCHED_STATUS_PCS_MODE_t line_rx_pma_dp_latched_status_pcs_mode; 7447 LINE_RX_PMA_DP_CL49_LATCHED_STATUS_FC_MODE_t line_rx_pma_dp_cl49_latched_status_fc_mode; 7448 LINE_RX_PMA_DP_CL49_LATCHED_STATUS_PCS_MODE_t line_rx_pma_dp_cl49_latched_status_pcs_mode; 7449 LINE_RX_PMA_DP_LIVE_STATUS_FC_MODE_t line_rx_pma_dp_live_status_fc_mode; 7450 LINE_RX_PMA_DP_LIVE_STATUS_PCS_MODE_t line_rx_pma_dp_live_status_pcs_mode; 7451 SYS_RX_PMA_DP_LATCHED_STATUS_FC_MODE_t sys_rx_pma_dp_latched_status_fc_mode; 7452 SYS_RX_PMA_DP_LATCHED_STATUS_PCS_MODE_t sys_rx_pma_dp_latched_status_pcs_mode; 7453 SYS_RX_PMA_DP_CL49_LATCHED_STATUS_FC_MODE_t sys_rx_pma_dp_cl49_latched_status_fc_mode; 7454 SYS_RX_PMA_DP_CL49_LATCHED_STATUS_PCS_MODE_t sys_rx_pma_dp_cl49_latched_status_pcs_mode; 7455 SYS_RX_PMA_DP_LIVE_STATUS_FC_MODE_t sys_rx_pma_dp_live_status_fc_mode; 7456 SYS_RX_PMA_DP_LIVE_STATUS_PCS_MODE_t sys_rx_pma_dp_live_status_pcs_mode; 7457 7458 *error_count = 0; 7459 *lock_status =0xffffffff; 7460 *lock_lost_lh =0xffffffff; 7461 PHYMOD_MEMSET(&line_rx_dp_main_ctrl, 0 , sizeof(LINE_RX_PMA_DP_MAIN_CTRL_t)); 7462 PHYMOD_MEMSET(&tmp_main_ctrl_mode, 0 , sizeof(LINE_RX_PMA_DP_MAIN_CTRL_PCS_MODE_t)); 7463 PHYMOD_MEMSET(&sys_rx_dp_main_ctrl, 0 , sizeof(SYS_RX_PMA_DP_MAIN_CTRL_t)); 7464 PHYMOD_MEMSET(&line_rx_pma_dp_cl82_ber_cnt_msb, 0 , sizeof(LINE_RX_PMA_DP_CL82_BER_COUNT_MSB_t)); 7465 PHYMOD_MEMSET(&sys_rx_pma_dp_cl82_ber_cnt_msb, 0 , sizeof(SYS_RX_PMA_DP_CL82_BER_COUNT_MSB_t)); 7466 PHYMOD_MEMSET(&line_rx_pma_dp_latched_status_fc_mode, 0 , sizeof(LINE_RX_PMA_DP_LATCHED_STATUS_FC_MODE_t)); 7467 PHYMOD_MEMSET(&line_rx_pma_dp_latched_status_pcs_mode, 0 , sizeof(LINE_RX_PMA_DP_LATCHED_STATUS_PCS_MODE_t)); 7468 PHYMOD_MEMSET(&line_rx_pma_dp_cl49_latched_status_fc_mode, 0 , sizeof(LINE_RX_PMA_DP_CL49_LATCHED_STATUS_FC_MODE_t)); 7469 PHYMOD_MEMSET(&line_rx_pma_dp_cl49_latched_status_pcs_mode, 0 , sizeof(LINE_RX_PMA_DP_CL49_LATCHED_STATUS_PCS_MODE_t)); 7470 PHYMOD_MEMSET(&line_rx_pma_dp_live_status_fc_mode, 0 , sizeof(LINE_RX_PMA_DP_LIVE_STATUS_FC_MODE_t)); 7471 PHYMOD_MEMSET(&line_rx_pma_dp_live_status_pcs_mode, 0 , sizeof(LINE_RX_PMA_DP_LIVE_STATUS_PCS_MODE_t)); 7472 PHYMOD_MEMSET(&sys_rx_pma_dp_latched_status_fc_mode, 0 , sizeof(SYS_RX_PMA_DP_LATCHED_STATUS_FC_MODE_t)); 7473 PHYMOD_MEMSET(&sys_rx_pma_dp_latched_status_pcs_mode, 0 , sizeof(SYS_RX_PMA_DP_LATCHED_STATUS_PCS_MODE_t)); 7474 PHYMOD_MEMSET(&sys_rx_pma_dp_cl49_latched_status_fc_mode, 0 , sizeof(SYS_RX_PMA_DP_CL49_LATCHED_STATUS_FC_MODE_t)); 7475 PHYMOD_MEMSET(&sys_rx_pma_dp_cl49_latched_status_pcs_mode, 0 , sizeof(SYS_RX_PMA_DP_CL49_LATCHED_STATUS_PCS_MODE_t)); 7476 PHYMOD_MEMSET(&sys_rx_pma_dp_live_status_fc_mode, 0 , sizeof(SYS_RX_PMA_DP_LIVE_STATUS_FC_MODE_t)); 7477 PHYMOD_MEMSET(&sys_rx_pma_dp_live_status_pcs_mode, 0 , sizeof(SYS_RX_PMA_DP_LIVE_STATUS_PCS_MODE_t)); 7478 7479 /* Get the lane map from phymod access */ 7480 lane_map = PHYMOD_ACC_LANE_MASK(pa); 7481 acc_flags = PHYMOD_ACC_FLAGS(pa); 7482 FURIA_GET_IF_SIDE(acc_flags, pkg_side); 7483 /* Get the chip id */ 7484 chip_id = _furia_get_chip_id(pa); 7485 FURIA_GET_NUM_LANES(chip_id, num_lanes); 7486 7487 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 7488 if (((lane_map >> lane_index) & 1) == 0x1) { 7489 /* Configure Tx side(SIDE_A) first*/ 7490 pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 1); 7491 PHYMOD_NULL_CHECK(pkg_ln_des); 7492 wr_lane = pkg_ln_des->slice_wr_val; 7493 rd_lane = pkg_ln_des->slice_rd_val; 7494 if(pkg_side == SIDE_A) { 7495 sys_en = pkg_ln_des->sideA; 7496 } else { 7497 sys_en = pkg_ln_des->sideB; 7498 } 7499 7500 /* Program the slice register */ 7501 PHYMOD_IF_ERR_RETURN 7502 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 7503 7504 if (FURIA_IS_DUPLEX(chip_id)) { 7505 if(pkg_side == SIDE_A || pkg_side == SIDE_B) { 7506 if(sys_en == LINE) { 7507 PHYMOD_IF_ERR_RETURN 7508 (READ_FURIA_PMA_PMD_REG(pa,\ 7509 LINE_RX_PMA_DP_main_ctrl_Adr,\ 7510 &line_rx_dp_main_ctrl.data)); 7511 tmp_main_ctrl_mode.data = line_rx_dp_main_ctrl.data; 7512 PHYMOD_IF_ERR_RETURN 7513 (READ_FURIA_PMA_PMD_REG(pa,\ 7514 LINE_RX_PMA_DP_latched_status_Adr,\ 7515 &line_rx_pma_dp_latched_status_pcs_mode.data)); 7516 PHYMOD_IF_ERR_RETURN 7517 (READ_FURIA_PMA_PMD_REG(pa,\ 7518 LINE_RX_PMA_DP_cl49_latched_status_Adr,\ 7519 &line_rx_pma_dp_cl49_latched_status_pcs_mode.data)); 7520 PHYMOD_IF_ERR_RETURN 7521 (READ_FURIA_PMA_PMD_REG(pa,\ 7522 LINE_RX_PMA_DP_cl49_latched_status_Adr,\ 7523 &line_rx_pma_dp_cl49_latched_status_fc_mode.data)); 7524 PHYMOD_IF_ERR_RETURN 7525 (READ_FURIA_PMA_PMD_REG(pa,\ 7526 LINE_RX_PMA_DP_cl82_ber_count_MSB_Adr,\ 7527 &line_rx_pma_dp_cl82_ber_cnt_msb.data)); 7528 PHYMOD_IF_ERR_RETURN 7529 (READ_FURIA_PMA_PMD_REG(pa,\ 7530 LINE_RX_PMA_DP_live_status_Adr,\ 7531 &line_rx_pma_dp_live_status_pcs_mode.data)); 7532 PHYMOD_IF_ERR_RETURN 7533 (READ_FURIA_PMA_PMD_REG(pa,\ 7534 LINE_RX_PMA_DP_live_status_Adr,\ 7535 &line_rx_pma_dp_live_status_fc_mode.data)); 7536 } else { 7537 PHYMOD_IF_ERR_RETURN 7538 (READ_FURIA_PMA_PMD_REG(pa,\ 7539 SYS_RX_PMA_DP_main_ctrl_Adr,\ 7540 &sys_rx_dp_main_ctrl.data)); 7541 tmp_main_ctrl_mode.data = sys_rx_dp_main_ctrl.data; 7542 PHYMOD_IF_ERR_RETURN 7543 (READ_FURIA_PMA_PMD_REG(pa,\ 7544 SYS_RX_PMA_DP_latched_status_Adr,\ 7545 &sys_rx_pma_dp_latched_status_pcs_mode.data)); 7546 PHYMOD_IF_ERR_RETURN 7547 (READ_FURIA_PMA_PMD_REG(pa,\ 7548 SYS_RX_PMA_DP_cl49_latched_status_Adr,\ 7549 &sys_rx_pma_dp_cl49_latched_status_pcs_mode.data)); 7550 PHYMOD_IF_ERR_RETURN 7551 (READ_FURIA_PMA_PMD_REG(pa,\ 7552 SYS_RX_PMA_DP_cl49_latched_status_Adr,\ 7553 &sys_rx_pma_dp_cl49_latched_status_fc_mode.data)); 7554 PHYMOD_IF_ERR_RETURN 7555 (READ_FURIA_PMA_PMD_REG(pa,\ 7556 SYS_RX_PMA_DP_cl82_ber_count_MSB_Adr,\ 7557 &sys_rx_pma_dp_cl82_ber_cnt_msb.data)); 7558 PHYMOD_IF_ERR_RETURN 7559 (READ_FURIA_PMA_PMD_REG(pa,\ 7560 SYS_RX_PMA_DP_live_status_Adr,\ 7561 &sys_rx_pma_dp_live_status_pcs_mode.data)); 7562 PHYMOD_IF_ERR_RETURN 7563 (READ_FURIA_PMA_PMD_REG(pa,\ 7564 SYS_RX_PMA_DP_live_status_Adr,\ 7565 &sys_rx_pma_dp_live_status_fc_mode.data)); 7566 } 7567 } 7568 } else { 7569 if(pkg_side == SIDE_B) { 7570 if(sys_en == LINE) { 7571 PHYMOD_IF_ERR_RETURN 7572 (READ_FURIA_PMA_PMD_REG(pa,\ 7573 LINE_RX_PMA_DP_main_ctrl_Adr,\ 7574 &line_rx_dp_main_ctrl.data)); 7575 tmp_main_ctrl_mode.data = line_rx_dp_main_ctrl.data; 7576 PHYMOD_IF_ERR_RETURN 7577 (READ_FURIA_PMA_PMD_REG(pa,\ 7578 LINE_RX_PMA_DP_latched_status_Adr,\ 7579 &line_rx_pma_dp_latched_status_pcs_mode.data)); 7580 PHYMOD_IF_ERR_RETURN 7581 (READ_FURIA_PMA_PMD_REG(pa,\ 7582 LINE_RX_PMA_DP_cl49_latched_status_Adr,\ 7583 &line_rx_pma_dp_cl49_latched_status_pcs_mode.data)); 7584 PHYMOD_IF_ERR_RETURN 7585 (READ_FURIA_PMA_PMD_REG(pa,\ 7586 LINE_RX_PMA_DP_cl49_latched_status_Adr,\ 7587 &line_rx_pma_dp_cl49_latched_status_fc_mode.data)); 7588 PHYMOD_IF_ERR_RETURN 7589 (READ_FURIA_PMA_PMD_REG(pa,\ 7590 LINE_RX_PMA_DP_cl82_ber_count_MSB_Adr,\ 7591 &line_rx_pma_dp_cl82_ber_cnt_msb.data)); 7592 PHYMOD_IF_ERR_RETURN 7593 (READ_FURIA_PMA_PMD_REG(pa,\ 7594 LINE_RX_PMA_DP_live_status_Adr,\ 7595 &line_rx_pma_dp_live_status_pcs_mode.data)); 7596 PHYMOD_IF_ERR_RETURN 7597 (READ_FURIA_PMA_PMD_REG(pa,\ 7598 LINE_RX_PMA_DP_live_status_Adr,\ 7599 &line_rx_pma_dp_live_status_fc_mode.data)); 7600 } else { 7601 PHYMOD_IF_ERR_RETURN 7602 (READ_FURIA_PMA_PMD_REG(pa,\ 7603 SYS_RX_PMA_DP_main_ctrl_Adr,\ 7604 &sys_rx_dp_main_ctrl.data)); 7605 tmp_main_ctrl_mode.data = sys_rx_dp_main_ctrl.data; 7606 PHYMOD_IF_ERR_RETURN 7607 (READ_FURIA_PMA_PMD_REG(pa,\ 7608 SYS_RX_PMA_DP_latched_status_Adr,\ 7609 &sys_rx_pma_dp_latched_status_pcs_mode.data)); 7610 PHYMOD_IF_ERR_RETURN 7611 (READ_FURIA_PMA_PMD_REG(pa,\ 7612 SYS_RX_PMA_DP_cl49_latched_status_Adr,\ 7613 &sys_rx_pma_dp_cl49_latched_status_pcs_mode.data)); 7614 PHYMOD_IF_ERR_RETURN 7615 (READ_FURIA_PMA_PMD_REG(pa,\ 7616 SYS_RX_PMA_DP_cl49_latched_status_Adr,\ 7617 &sys_rx_pma_dp_cl49_latched_status_fc_mode.data)); 7618 PHYMOD_IF_ERR_RETURN 7619 (READ_FURIA_PMA_PMD_REG(pa,\ 7620 SYS_RX_PMA_DP_cl82_ber_count_MSB_Adr,\ 7621 &sys_rx_pma_dp_cl82_ber_cnt_msb.data)); 7622 PHYMOD_IF_ERR_RETURN 7623 (READ_FURIA_PMA_PMD_REG(pa,\ 7624 SYS_RX_PMA_DP_live_status_Adr,\ 7625 &sys_rx_pma_dp_live_status_pcs_mode.data)); 7626 PHYMOD_IF_ERR_RETURN 7627 (READ_FURIA_PMA_PMD_REG(pa,\ 7628 SYS_RX_PMA_DP_live_status_Adr,\ 7629 &sys_rx_pma_dp_live_status_fc_mode.data)); 7630 } 7631 } 7632 } 7633 7634 if(!tmp_main_ctrl_mode.fields.link_mon_en) { 7635 PHYMOD_DEBUG_VERBOSE(("We can't read the FC/PCS checker status since PCS monitor is not enabled\n")); 7636 return PHYMOD_E_CONFIG; 7637 } else { 7638 if(tmp_main_ctrl_mode.fields.link_mon_mode_frcval == 0x0) { 7639 fcpcs_chkr_mode = PCS49_1x10G; 7640 } 7641 if(tmp_main_ctrl_mode.fields.link_mon_mode_frcval == 0x1) { 7642 if(tmp_main_ctrl_mode.fields.mode_50g) { 7643 fcpcs_chkr_mode = PCS82_2x25G; 7644 } else if(tmp_main_ctrl_mode.fields.mode_100g) { 7645 fcpcs_chkr_mode = PCS82_4x25G; 7646 } else { 7647 fcpcs_chkr_mode = PCS82_4x10G; 7648 } 7649 } 7650 if(tmp_main_ctrl_mode.fields.link_mon_mode_frcval == 0x2) { 7651 fcpcs_chkr_mode = FC4; 7652 } 7653 if(tmp_main_ctrl_mode.fields.link_mon_mode_frcval == 0x3) { 7654 fcpcs_chkr_mode = FC8; 7655 } 7656 } 7657 7658 switch (fcpcs_chkr_mode) { 7659 case PCS49_1x10G : 7660 case PCS82_4x10G : 7661 case FC16 : 7662 case FC32 : 7663 case PCS82_2x25G : 7664 case PCS82_4x25G : 7665 if (FURIA_IS_DUPLEX(chip_id)) { 7666 if(pkg_side == SIDE_A || pkg_side == SIDE_B) { 7667 if(sys_en == LINE) { 7668 *lock_status &= line_rx_pma_dp_live_status_pcs_mode.fields.pcs_status; 7669 *lock_lost_lh &= (!line_rx_pma_dp_latched_status_pcs_mode.fields.pcs_status_ll); 7670 *error_count |= (line_rx_pma_dp_cl82_ber_cnt_msb.data << 6) + line_rx_pma_dp_cl49_latched_status_pcs_mode.fields.ber_count; 7671 } else { 7672 *lock_status &= sys_rx_pma_dp_live_status_pcs_mode.fields.pcs_status; 7673 *lock_lost_lh &= (!sys_rx_pma_dp_latched_status_pcs_mode.fields.pcs_status_ll); 7674 *error_count |= (sys_rx_pma_dp_cl82_ber_cnt_msb.data << 6) + sys_rx_pma_dp_cl49_latched_status_pcs_mode.fields.ber_count; 7675 } 7676 } 7677 } else { 7678 if(pkg_side == SIDE_B) { 7679 if(sys_en == LINE) { 7680 *lock_status &= line_rx_pma_dp_live_status_pcs_mode.fields.pcs_status; 7681 *lock_lost_lh &= (!line_rx_pma_dp_latched_status_pcs_mode.fields.pcs_status_ll); 7682 *error_count |= (line_rx_pma_dp_cl82_ber_cnt_msb.data << 6) + line_rx_pma_dp_cl49_latched_status_pcs_mode.fields.ber_count; 7683 } else { 7684 *lock_status &= sys_rx_pma_dp_live_status_pcs_mode.fields.pcs_status; 7685 *lock_lost_lh &= (!sys_rx_pma_dp_latched_status_pcs_mode.fields.pcs_status_ll); 7686 *error_count |= (sys_rx_pma_dp_cl82_ber_cnt_msb.data << 6) + sys_rx_pma_dp_cl49_latched_status_pcs_mode.fields.ber_count; 7687 } 7688 } 7689 } 7690 break; 7691 case FC4 : 7692 case FC8 : 7693 if (FURIA_IS_DUPLEX(chip_id)) { 7694 if(pkg_side == SIDE_A || pkg_side == SIDE_B) { 7695 if(sys_en == LINE) { 7696 *lock_status &= line_rx_pma_dp_live_status_fc_mode.fields.wsyn_link_fail; 7697 *lock_lost_lh &= line_rx_pma_dp_latched_status_fc_mode.fields.wsyn_link_fail_lh; 7698 *error_count |= (line_rx_pma_dp_cl82_ber_cnt_msb.data << 6) + line_rx_pma_dp_cl49_latched_status_pcs_mode.fields.ber_count; 7699 } else { 7700 *lock_status &= sys_rx_pma_dp_live_status_fc_mode.fields.wsyn_link_fail; 7701 *lock_lost_lh &= sys_rx_pma_dp_latched_status_fc_mode.fields.wsyn_link_fail_lh; 7702 *error_count |= (sys_rx_pma_dp_cl82_ber_cnt_msb.data << 6) + line_rx_pma_dp_cl49_latched_status_pcs_mode.fields.ber_count; 7703 } 7704 } 7705 } else { 7706 if(pkg_side == SIDE_B) { 7707 if(sys_en == LINE) { 7708 *lock_status &= line_rx_pma_dp_live_status_fc_mode.fields.wsyn_link_fail; 7709 *lock_lost_lh &= line_rx_pma_dp_latched_status_fc_mode.fields.wsyn_link_fail_lh; 7710 *error_count |= (line_rx_pma_dp_cl82_ber_cnt_msb.data << 6) + line_rx_pma_dp_cl49_latched_status_pcs_mode.fields.ber_count; 7711 } else { 7712 *lock_status &= sys_rx_pma_dp_live_status_fc_mode.fields.wsyn_link_fail; 7713 *lock_lost_lh &= sys_rx_pma_dp_latched_status_fc_mode.fields.wsyn_link_fail_lh; 7714 *error_count |= (sys_rx_pma_dp_cl82_ber_cnt_msb.data << 6) + line_rx_pma_dp_cl49_latched_status_pcs_mode.fields.ber_count; 7715 } 7716 } 7717 } 7718 break; 7719 default: 7720 break; 7721 } 7722 } 7723 } 7724 /* Set the slice register with default values */ 7725 PHYMOD_IF_ERR_RETURN 7726 (WRITE_FURIA_SLICE_REG(pa, 0, 1, 0)); 7727 return PHYMOD_E_NONE; 7728 } 7729 7730 int _furia_core_rptr_rtmr_mode_set(const phymod_access_t* pa, uint32_t rptr_rtmr_mode) 7731 { 7732 int lane_map = 0; 7733 uint32_t chip_id = 0; 7734 int num_lanes = 0; 7735 int lane_index = 0; 7736 uint16_t die_lane_num = 0; 7737 uint32_t enable = 0; 7738 uint8_t fw_enable = 0; 7739 uint8_t retry_count = 40; 7740 FUR_GEN_CNTRLS_gpreg12_t gen_ctrls_gpreg12; 7741 FUR_GEN_CNTRLS_gpreg11_t gen_ctrls_gpreg11; 7742 FUR_GEN_CNTRLS_FIRMWARE_ENABLE_t fw_enable_reg; 7743 const FURIA_PKG_LANE_CFG_t* pkg_ln_des = NULL; 7744 PHYMOD_MEMSET(&gen_ctrls_gpreg12, 0 , sizeof(FUR_GEN_CNTRLS_gpreg12_t)); 7745 PHYMOD_MEMSET(&gen_ctrls_gpreg11, 0 , sizeof(FUR_GEN_CNTRLS_gpreg11_t)); 7746 PHYMOD_MEMSET(&fw_enable_reg, 0 , sizeof(FUR_GEN_CNTRLS_FIRMWARE_ENABLE_t)); 7747 7748 7749 /* Get the chip id */ 7750 chip_id = _furia_get_chip_id(pa); 7751 7752 FURIA_GET_NUM_LANES(chip_id, num_lanes); 7753 7754 enable = (rptr_rtmr_mode == 1) ? 1 : 0; 7755 7756 /*Wait for fw_enable to go low before setting fw_enable_val*/ 7757 PHYMOD_IF_ERR_RETURN 7758 (READ_FURIA_PMA_PMD_REG(pa,\ 7759 FUR_GEN_CNTRLS_firmware_enable_Adr,\ 7760 &fw_enable_reg.data)); 7761 fw_enable = fw_enable_reg.fields.fw_enable_val; 7762 7763 while((fw_enable != 0) && (retry_count)) { 7764 PHYMOD_IF_ERR_RETURN 7765 (READ_FURIA_PMA_PMD_REG(pa,\ 7766 FUR_GEN_CNTRLS_firmware_enable_Adr,\ 7767 &fw_enable_reg.data)); 7768 fw_enable = fw_enable_reg.fields.fw_enable_val; 7769 PHYMOD_USLEEP(200); 7770 retry_count--; 7771 } 7772 7773 FURIA_GET_LANE_MASK(chip_id, lane_map); 7774 7775 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 7776 if (((lane_map >> lane_index) & 1) == 0x1) { 7777 /* Get lane descriptor from package lane */ 7778 pkg_ln_des = _furia_pkg_ln_des(chip_id, pa, lane_index); 7779 PHYMOD_NULL_CHECK(pkg_ln_des); 7780 die_lane_num = pkg_ln_des->die_lane_num; 7781 if(FURIA_IS_SIMPLEX(chip_id)) { 7782 if(pkg_ln_des->sideA == LINE) { 7783 /* Read GPReg12 */ 7784 PHYMOD_IF_ERR_RETURN 7785 (READ_FURIA_PMA_PMD_REG(pa,\ 7786 FUR_GEN_CNTRLS_gpreg12_Adr,\ 7787 &gen_ctrls_gpreg12.data)); 7788 if(enable) { 7789 gen_ctrls_gpreg12.fields.en_tx_rptr_mode_sys2line |= (1 << die_lane_num); 7790 } else { 7791 gen_ctrls_gpreg12.fields.en_tx_rptr_mode_sys2line &= ~(1 << die_lane_num); 7792 } 7793 /* Write GPReg12 */ 7794 PHYMOD_IF_ERR_RETURN 7795 (WRITE_FURIA_PMA_PMD_REG(pa,\ 7796 FUR_GEN_CNTRLS_gpreg12_Adr,\ 7797 gen_ctrls_gpreg12.data)); 7798 } else { 7799 /* Read GPReg11 */ 7800 PHYMOD_IF_ERR_RETURN 7801 (READ_FURIA_PMA_PMD_REG(pa,\ 7802 FUR_GEN_CNTRLS_gpreg11_Adr,\ 7803 &gen_ctrls_gpreg11.data)); 7804 if(enable) { 7805 gen_ctrls_gpreg11.fields.en_tx_rptr_mode_line2sys |= (1 << die_lane_num); 7806 } else { 7807 gen_ctrls_gpreg11.fields.en_tx_rptr_mode_line2sys &= ~(1 << die_lane_num); 7808 } 7809 /* Write GPReg11 */ 7810 PHYMOD_IF_ERR_RETURN 7811 (WRITE_FURIA_PMA_PMD_REG(pa,\ 7812 FUR_GEN_CNTRLS_gpreg11_Adr,\ 7813 gen_ctrls_gpreg11.data)); 7814 } 7815 } else { 7816 /* Read GPReg12 */ 7817 PHYMOD_IF_ERR_RETURN 7818 (READ_FURIA_PMA_PMD_REG(pa,\ 7819 FUR_GEN_CNTRLS_gpreg12_Adr,\ 7820 &gen_ctrls_gpreg12.data)); 7821 /* Read GPReg11 */ 7822 PHYMOD_IF_ERR_RETURN 7823 (READ_FURIA_PMA_PMD_REG(pa,\ 7824 FUR_GEN_CNTRLS_gpreg11_Adr,\ 7825 &gen_ctrls_gpreg11.data)); 7826 if(enable) { 7827 gen_ctrls_gpreg12.fields.en_tx_rptr_mode_sys2line |= (1 << die_lane_num); 7828 gen_ctrls_gpreg11.fields.en_tx_rptr_mode_line2sys |= (1 << die_lane_num); 7829 } else { 7830 gen_ctrls_gpreg12.fields.en_tx_rptr_mode_sys2line &= ~(1 << die_lane_num); 7831 gen_ctrls_gpreg11.fields.en_tx_rptr_mode_line2sys &= ~(1 << die_lane_num); 7832 } 7833 /* Write GPReg12 */ 7834 PHYMOD_IF_ERR_RETURN 7835 (WRITE_FURIA_PMA_PMD_REG(pa,\ 7836 FUR_GEN_CNTRLS_gpreg12_Adr,\ 7837 gen_ctrls_gpreg12.data)); 7838 /* Write GPReg11 */ 7839 PHYMOD_IF_ERR_RETURN 7840 (WRITE_FURIA_PMA_PMD_REG(pa,\ 7841 FUR_GEN_CNTRLS_gpreg11_Adr,\ 7842 gen_ctrls_gpreg11.data)); 7843 } 7844 } 7845 } 7846 /* Set firmware enable */ 7847 PHYMOD_IF_ERR_RETURN 7848 (_furia_fw_enable(pa)); 7849 return PHYMOD_E_NONE; 7850 } 7851 7852 int _furia_core_avddtxdrv_config_set(const phymod_core_access_t* core, uint32_t avdd_txdrv) 7853 { 7854 uint32_t avdd_txdrv_val = 0; 7855 uint32_t side_index = 0; 7856 LINE_FALCON_IF_c_and_r_cntl_t line_c_and_r_cntl; 7857 SYS_FALCON_IF_c_and_r_cntl_t sys_c_and_r_cntl; 7858 const phymod_access_t *pa = &core->access; 7859 7860 if (avdd_txdrv == phymodTxInputVoltageDefault) { 7861 avdd_txdrv_val = 0; 7862 } else if (avdd_txdrv == phymodTxInputVoltage1p00) { 7863 avdd_txdrv_val = 1; 7864 } else { 7865 avdd_txdrv_val = 0; 7866 } 7867 7868 PHYMOD_MEMSET(&line_c_and_r_cntl, 0 , sizeof(LINE_FALCON_IF_c_and_r_cntl_t)); 7869 PHYMOD_MEMSET(&sys_c_and_r_cntl, 0 , sizeof(SYS_FALCON_IF_c_and_r_cntl_t)); 7870 for(side_index = 0; side_index < 2; side_index ++) { 7871 PHYMOD_IF_ERR_RETURN 7872 (READ_FURIA_PMA_PMD_REG(pa,\ 7873 SYS_FALCON_IF_c_and_r_cntl_Adr,\ 7874 &sys_c_and_r_cntl.data)); 7875 sys_c_and_r_cntl.fields.tx_drv_hv_disable = avdd_txdrv_val; 7876 PHYMOD_IF_ERR_RETURN 7877 (WRITE_FURIA_PMA_PMD_REG(pa,\ 7878 SYS_FALCON_IF_c_and_r_cntl_Adr,\ 7879 sys_c_and_r_cntl.data)); 7880 PHYMOD_IF_ERR_RETURN 7881 (READ_FURIA_PMA_PMD_REG(pa,\ 7882 LINE_FALCON_IF_c_and_r_cntl_Adr,\ 7883 &line_c_and_r_cntl.data)); 7884 line_c_and_r_cntl.fields.tx_drv_hv_disable = avdd_txdrv_val; 7885 PHYMOD_IF_ERR_RETURN 7886 (WRITE_FURIA_PMA_PMD_REG(pa,\ 7887 LINE_FALCON_IF_c_and_r_cntl_Adr,\ 7888 line_c_and_r_cntl.data)); 7889 } 7890 return PHYMOD_E_NONE; 7891 } 7892 7893 int _furia_phy_reset_set(const phymod_access_t *pa, const phymod_phy_reset_t* reset) 7894 { 7895 int lane_map = 0; 7896 int pkg_side = 0; 7897 int wr_lane = 0; 7898 int sys_en = 0; 7899 int rd_lane = 0; 7900 uint32_t chip_id = 0; 7901 int num_lanes = 0; 7902 int lane_index = 0; 7903 uint32_t acc_flags = 0; 7904 const FURIA_PKG_LANE_CFG_t* tx_pkg_ln_des = NULL; 7905 const FURIA_PKG_LANE_CFG_t* rx_pkg_ln_des = NULL; 7906 TX_FED_txfir_misc_control1_t txfir_misc_ctrl1; 7907 DSC_D_DSC_CONTROL_9_t dsc_d_dsc_ctrl9; 7908 7909 /* Get the lane map from phymod access */ 7910 lane_map = PHYMOD_ACC_LANE_MASK(pa); 7911 acc_flags = PHYMOD_ACC_FLAGS(pa); 7912 FURIA_GET_IF_SIDE(acc_flags, pkg_side); 7913 /* Get the chip id */ 7914 chip_id = _furia_get_chip_id(pa); 7915 FURIA_GET_NUM_LANES(chip_id, num_lanes); 7916 7917 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 7918 if (((lane_map >> lane_index) & 1) == 0x1) { 7919 if (FURIA_IF_TX_SIDE(chip_id, pkg_side)) { 7920 tx_pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 0); 7921 PHYMOD_NULL_CHECK(tx_pkg_ln_des); 7922 wr_lane = FURIA_IF_BCAST_SET(chip_id, lane_map) ? BROADCAST : tx_pkg_ln_des->slice_wr_val; 7923 rd_lane = tx_pkg_ln_des->slice_rd_val; 7924 if(pkg_side == SIDE_A) { 7925 sys_en = tx_pkg_ln_des->sideA; 7926 } else { 7927 sys_en = tx_pkg_ln_des->sideB; 7928 } 7929 /* Program the slice register */ 7930 PHYMOD_IF_ERR_RETURN 7931 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 7932 /* TX AFE Lane Reset */ 7933 switch (reset->tx) { 7934 /* In Reset */ 7935 case phymodResetDirectionIn: 7936 PHYMOD_IF_ERR_RETURN 7937 (READ_FURIA_PMA_PMD_REG(pa,\ 7938 TX_FED_txfir_misc_control1_Adr,\ 7939 &txfir_misc_ctrl1.data)); 7940 txfir_misc_ctrl1.fields.sdk_tx_disable = 1; 7941 PHYMOD_IF_ERR_RETURN 7942 (WRITE_FURIA_PMA_PMD_REG(pa,\ 7943 TX_FED_txfir_misc_control1_Adr,\ 7944 txfir_misc_ctrl1.data)); 7945 break; 7946 /* Out Reset */ 7947 case phymodResetDirectionOut: 7948 PHYMOD_IF_ERR_RETURN 7949 (READ_FURIA_PMA_PMD_REG(pa,\ 7950 TX_FED_txfir_misc_control1_Adr,\ 7951 &txfir_misc_ctrl1.data)); 7952 txfir_misc_ctrl1.fields.sdk_tx_disable = 0; 7953 PHYMOD_IF_ERR_RETURN 7954 (WRITE_FURIA_PMA_PMD_REG(pa,\ 7955 TX_FED_txfir_misc_control1_Adr,\ 7956 txfir_misc_ctrl1.data)); 7957 break; 7958 /* Toggle Reset */ 7959 case phymodResetDirectionInOut: 7960 PHYMOD_IF_ERR_RETURN 7961 (READ_FURIA_PMA_PMD_REG(pa,\ 7962 TX_FED_txfir_misc_control1_Adr,\ 7963 &txfir_misc_ctrl1.data)); 7964 txfir_misc_ctrl1.fields.sdk_tx_disable = 1; 7965 PHYMOD_IF_ERR_RETURN 7966 (WRITE_FURIA_PMA_PMD_REG(pa,\ 7967 TX_FED_txfir_misc_control1_Adr,\ 7968 txfir_misc_ctrl1.data)); 7969 PHYMOD_USLEEP(10); 7970 PHYMOD_IF_ERR_RETURN 7971 (READ_FURIA_PMA_PMD_REG(pa,\ 7972 TX_FED_txfir_misc_control1_Adr,\ 7973 &txfir_misc_ctrl1.data)); 7974 txfir_misc_ctrl1.fields.sdk_tx_disable = 0; 7975 PHYMOD_IF_ERR_RETURN 7976 (WRITE_FURIA_PMA_PMD_REG(pa,\ 7977 TX_FED_txfir_misc_control1_Adr,\ 7978 txfir_misc_ctrl1.data)); 7979 break; 7980 default: 7981 break; 7982 } 7983 } 7984 if (FURIA_IF_RX_SIDE(chip_id, pkg_side)) { 7985 /* Program the slice register */ 7986 PHYMOD_IF_ERR_RETURN 7987 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 7988 rx_pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 1); 7989 PHYMOD_NULL_CHECK(rx_pkg_ln_des); 7990 wr_lane = FURIA_IF_BCAST_SET(chip_id, lane_map) ? BROADCAST : rx_pkg_ln_des->slice_wr_val; 7991 rd_lane = rx_pkg_ln_des->slice_rd_val; 7992 if(pkg_side == SIDE_A) { 7993 sys_en = rx_pkg_ln_des->sideA; 7994 } else { 7995 sys_en = rx_pkg_ln_des->sideB; 7996 } 7997 /* Program the slice register */ 7998 PHYMOD_IF_ERR_RETURN 7999 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 8000 /* RX AFE Lane Reset */ 8001 switch (reset->rx) { 8002 /* In Reset */ 8003 case phymodResetDirectionIn: 8004 PHYMOD_IF_ERR_RETURN 8005 (READ_FURIA_PMA_PMD_REG(pa,\ 8006 DSC_D_dsc_sm_ctrl_9_Adr,\ 8007 &dsc_d_dsc_ctrl9.data)); 8008 dsc_d_dsc_ctrl9.fields.rx_restart_pmd_hold = 1; /* now check for pmd rx lock */ 8009 PHYMOD_IF_ERR_RETURN 8010 (WRITE_FURIA_PMA_PMD_REG(pa,\ 8011 DSC_D_dsc_sm_ctrl_9_Adr,\ 8012 dsc_d_dsc_ctrl9.data)); 8013 break; 8014 /* Out Reset */ 8015 case phymodResetDirectionOut: 8016 PHYMOD_IF_ERR_RETURN 8017 (READ_FURIA_PMA_PMD_REG(pa,\ 8018 DSC_D_dsc_sm_ctrl_9_Adr,\ 8019 &dsc_d_dsc_ctrl9.data)); 8020 dsc_d_dsc_ctrl9.fields.rx_restart_pmd_hold = 0; /* now check for pmd rx lock */ 8021 PHYMOD_IF_ERR_RETURN 8022 (WRITE_FURIA_PMA_PMD_REG(pa,\ 8023 DSC_D_dsc_sm_ctrl_9_Adr,\ 8024 dsc_d_dsc_ctrl9.data)); 8025 break; 8026 /* Toggle Reset */ 8027 case phymodResetDirectionInOut: 8028 PHYMOD_IF_ERR_RETURN 8029 (READ_FURIA_PMA_PMD_REG(pa,\ 8030 DSC_D_dsc_sm_ctrl_9_Adr,\ 8031 &dsc_d_dsc_ctrl9.data)); 8032 dsc_d_dsc_ctrl9.fields.rx_restart_pmd_hold = 1; /* now check for pmd rx lock */ 8033 PHYMOD_IF_ERR_RETURN 8034 (WRITE_FURIA_PMA_PMD_REG(pa,\ 8035 DSC_D_dsc_sm_ctrl_9_Adr,\ 8036 dsc_d_dsc_ctrl9.data)); 8037 PHYMOD_USLEEP(10); 8038 PHYMOD_IF_ERR_RETURN 8039 (READ_FURIA_PMA_PMD_REG(pa,\ 8040 DSC_D_dsc_sm_ctrl_9_Adr,\ 8041 &dsc_d_dsc_ctrl9.data)); 8042 dsc_d_dsc_ctrl9.fields.rx_restart_pmd_hold = 0; /* now check for pmd rx lock */ 8043 PHYMOD_IF_ERR_RETURN 8044 (WRITE_FURIA_PMA_PMD_REG(pa,\ 8045 DSC_D_dsc_sm_ctrl_9_Adr,\ 8046 dsc_d_dsc_ctrl9.data)); 8047 break; 8048 default: 8049 break; 8050 } 8051 } 8052 if (FURIA_IF_BCAST_SET(chip_id, lane_map)) { 8053 break; 8054 } 8055 } 8056 } 8057 /* Set the slice register with default values */ 8058 PHYMOD_IF_ERR_RETURN 8059 (WRITE_FURIA_SLICE_REG(pa, 0, 1, 0)); 8060 return PHYMOD_E_NONE; 8061 } 8062 int _furia_phy_reset_get(const phymod_access_t *pa, phymod_phy_reset_t* reset) 8063 { 8064 int lane_map = 0; 8065 int pkg_side = 0; 8066 int wr_lane = 0; 8067 int sys_en = 0; 8068 int rd_lane = 0; 8069 uint32_t chip_id = 0; 8070 int num_lanes = 0; 8071 int lane_index = 0; 8072 uint32_t acc_flags = 0; 8073 const FURIA_PKG_LANE_CFG_t* tx_pkg_ln_des = NULL; 8074 const FURIA_PKG_LANE_CFG_t* rx_pkg_ln_des = NULL; 8075 TX_FED_txfir_misc_control1_t txfir_misc_ctrl1; 8076 DSC_D_DSC_CONTROL_9_t dsc_d_dsc_ctrl9; 8077 8078 /* Get the lane map from phymod access */ 8079 lane_map = PHYMOD_ACC_LANE_MASK(pa); 8080 acc_flags = PHYMOD_ACC_FLAGS(pa); 8081 FURIA_GET_IF_SIDE(acc_flags, pkg_side); 8082 /* Get the chip id */ 8083 chip_id = _furia_get_chip_id(pa); 8084 FURIA_GET_NUM_LANES(chip_id, num_lanes); 8085 8086 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 8087 if (((lane_map >> lane_index) & 1) == 0x1) { 8088 8089 if (FURIA_IF_TX_SIDE(chip_id, pkg_side)) { 8090 tx_pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 0); 8091 PHYMOD_NULL_CHECK(tx_pkg_ln_des); 8092 wr_lane = FURIA_IF_BCAST_SET(chip_id, lane_map) ? BROADCAST : tx_pkg_ln_des->slice_wr_val; 8093 rd_lane = tx_pkg_ln_des->slice_rd_val; 8094 if(pkg_side == SIDE_A) { 8095 sys_en = tx_pkg_ln_des->sideA; 8096 } else { 8097 sys_en = tx_pkg_ln_des->sideB; 8098 } 8099 /* Program the slice register */ 8100 PHYMOD_IF_ERR_RETURN 8101 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 8102 PHYMOD_IF_ERR_RETURN 8103 (READ_FURIA_PMA_PMD_REG(pa,\ 8104 TX_FED_txfir_misc_control1_Adr,\ 8105 &txfir_misc_ctrl1.data)); 8106 if (txfir_misc_ctrl1.fields.sdk_tx_disable == 0) { 8107 /* Out of Reset */ 8108 reset->tx = phymodResetDirectionOut; 8109 } else { 8110 /* In Reset */ 8111 reset->tx = phymodResetDirectionIn; 8112 } 8113 } 8114 if (FURIA_IF_RX_SIDE(chip_id, pkg_side)) { 8115 rx_pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 1); 8116 PHYMOD_NULL_CHECK(rx_pkg_ln_des); 8117 wr_lane = FURIA_IF_BCAST_SET(chip_id, lane_map) ? BROADCAST : rx_pkg_ln_des->slice_wr_val; 8118 rd_lane = rx_pkg_ln_des->slice_rd_val; 8119 if(pkg_side == SIDE_A) { 8120 sys_en = rx_pkg_ln_des->sideA; 8121 } else { 8122 sys_en = rx_pkg_ln_des->sideB; 8123 } 8124 /* Program the slice register */ 8125 PHYMOD_IF_ERR_RETURN 8126 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 8127 PHYMOD_IF_ERR_RETURN 8128 (READ_FURIA_PMA_PMD_REG(pa,\ 8129 DSC_D_dsc_sm_ctrl_9_Adr,\ 8130 &dsc_d_dsc_ctrl9.data)); 8131 if(dsc_d_dsc_ctrl9.fields.rx_restart_pmd_hold == 0) { 8132 /* Out of Reset */ 8133 reset->rx = phymodResetDirectionOut; 8134 } else { 8135 /* In Reset */ 8136 reset->rx = phymodResetDirectionIn; 8137 } 8138 } 8139 break; 8140 } 8141 } 8142 /* Set the slice register with default values */ 8143 PHYMOD_IF_ERR_RETURN 8144 (WRITE_FURIA_SLICE_REG(pa, 0, 1, 0)); 8145 return PHYMOD_E_NONE; 8146 } 8147 8148 int furia_gpio_config_set(const phymod_access_t *pa, int pin_no, phymod_gpio_mode_t gpio_mode) 8149 { 8150 FUR_PAD_CTRL_GPIO_1_CONTROL_t pad_ctrl_gpio_ctrl; 8151 8152 if (pin_no > 4) { 8153 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("Furia has only 5 GPIOs (0 - 4)"))); 8154 } 8155 PHYMOD_IF_ERR_RETURN 8156 (READ_FURIA_PMA_PMD_REG(pa,\ 8157 (pin_no*2) + FUR_PAD_CTRL_gpio_0_control_Adr,\ 8158 &pad_ctrl_gpio_ctrl.data)); 8159 switch (gpio_mode) { 8160 case phymodGpioModeDisabled: 8161 return PHYMOD_E_NONE; 8162 case phymodGpioModeOutput: 8163 pad_ctrl_gpio_ctrl.fields.oeb = 0; 8164 break; 8165 case phymodGpioModeInput: 8166 pad_ctrl_gpio_ctrl.fields.oeb = 1; 8167 break; 8168 default: 8169 return PHYMOD_E_PARAM; 8170 } 8171 PHYMOD_IF_ERR_RETURN 8172 (WRITE_FURIA_PMA_PMD_REG(pa,\ 8173 (pin_no*2) + FUR_PAD_CTRL_gpio_0_control_Adr,\ 8174 pad_ctrl_gpio_ctrl.data)); 8175 return PHYMOD_E_NONE; 8176 } 8177 8178 int furia_gpio_config_get(const phymod_access_t *pa, int pin_no, phymod_gpio_mode_t* gpio_mode) 8179 { 8180 FUR_PAD_CTRL_GPIO_1_CONTROL_t pad_ctrl_gpio_ctrl; 8181 8182 *gpio_mode = 0; 8183 if (pin_no > 4) { 8184 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("Furia has only 5 GPIOs (0 - 4)"))); 8185 } 8186 8187 PHYMOD_IF_ERR_RETURN 8188 (READ_FURIA_PMA_PMD_REG(pa,\ 8189 (pin_no*2) + FUR_PAD_CTRL_gpio_0_control_Adr,\ 8190 &pad_ctrl_gpio_ctrl.data)); 8191 8192 switch(pad_ctrl_gpio_ctrl.fields.oeb) { 8193 case 0: 8194 *gpio_mode = phymodGpioModeOutput; 8195 break; 8196 case 1: 8197 *gpio_mode = phymodGpioModeInput; 8198 break; 8199 default: 8200 break; 8201 } 8202 8203 return PHYMOD_E_NONE; 8204 } 8205 8206 int furia_gpio_pin_value_set(const phymod_access_t *pa, int pin_no, int value) 8207 { 8208 FUR_PAD_CTRL_GPIO_1_CONTROL_t pad_ctrl_gpio_ctrl; 8209 8210 if (pin_no > 4) { 8211 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("Furia has only 5 GPIOs (0 - 4)"))); 8212 } 8213 PHYMOD_IF_ERR_RETURN 8214 (READ_FURIA_PMA_PMD_REG(pa,\ 8215 (pin_no*2) + FUR_PAD_CTRL_gpio_0_control_Adr,\ 8216 &pad_ctrl_gpio_ctrl.data)); 8217 8218 pad_ctrl_gpio_ctrl.fields.ibof = 1; 8219 pad_ctrl_gpio_ctrl.fields.out_frcval = value ? 1 : 0; 8220 PHYMOD_IF_ERR_RETURN 8221 (WRITE_FURIA_PMA_PMD_REG(pa,\ 8222 (pin_no*2) + FUR_PAD_CTRL_gpio_0_control_Adr,\ 8223 pad_ctrl_gpio_ctrl.data)); 8224 return PHYMOD_E_NONE; 8225 } 8226 int furia_gpio_pin_value_get(const phymod_access_t *pa, int pin_no, int* value) 8227 { 8228 FUR_PAD_CTRL_GPIO_1_STATUS_t pad_sts_gpio; 8229 *value = 0; 8230 8231 if (pin_no > 4) { 8232 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("Furia has only 5 GPIOs (0 - 4)"))); 8233 } 8234 8235 PHYMOD_IF_ERR_RETURN 8236 (READ_FURIA_PMA_PMD_REG(pa,\ 8237 ((pin_no*2)+1) + FUR_PAD_CTRL_gpio_0_control_Adr,\ 8238 &pad_sts_gpio.data)); 8239 *value = pad_sts_gpio.fields.din; 8240 return PHYMOD_E_NONE; 8241 } 8242 8243 int furia_module_write(const phymod_access_t *pa, uint32_t slv_addr, uint32_t start_addr, 8244 uint32_t no_of_bytes, const uint8_t *write_data) 8245 { 8246 uint32_t index = 0; 8247 uint32_t lower_page_bytes = 0; 8248 uint32_t upper_page_bytes = 0; 8249 uint32_t upper_page_flag = 0; 8250 uint32_t lower_page_flag = 0; 8251 uint32_t lower_page_start_addr = 0; 8252 uint32_t upper_page_start_addr = 0; 8253 FUR_MISC_CTRL_DEBUG_CTRL_t debug_ctrl; 8254 if(start_addr > 255) { 8255 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_PARAM, (_PHYMOD_MSG("Invalid start address"))); 8256 } 8257 /* SET qsfp_mode=1 */ 8258 8259 PHYMOD_IF_ERR_RETURN 8260 (READ_FURIA_PMA_PMD_REG(pa,\ 8261 FUR_MISC_CTRL_DEBUG_CTRL_Adr,\ 8262 &debug_ctrl.data)); 8263 debug_ctrl.fields.qsfp_mode = 1; 8264 PHYMOD_IF_ERR_RETURN 8265 (WRITE_FURIA_PMA_PMD_REG(pa,\ 8266 FUR_MISC_CTRL_DEBUG_CTRL_Adr,\ 8267 debug_ctrl.data)); 8268 if(no_of_bytes == 0) { 8269 /* Perform module controller reset and FLUSH */ 8270 PHYMOD_IF_ERR_RETURN 8271 (_furia_set_module_command(pa, 0, 0, 0, FURIA_FLUSH)); 8272 return PHYMOD_E_NONE; 8273 } 8274 /* if requested number of bytes are not within the boundary (0- 255) 8275 * need to calculate what maximum number of bytes can be taken into 8276 * account for reading or writing to module 8277 */ 8278 if ((no_of_bytes+start_addr) >= 256) { 8279 no_of_bytes = 255-start_addr+ 1; 8280 } 8281 8282 /* To determine page to be written is lower page or upper page or 8283 * both lower and upper page 8284 */ 8285 if ((start_addr+no_of_bytes-1) > 127) { 8286 /* lower page */ 8287 if (start_addr <= 127) { 8288 lower_page_bytes = 127-start_addr+1; 8289 lower_page_flag = 1; 8290 lower_page_start_addr = start_addr; 8291 } 8292 /* upper page */ 8293 if ((start_addr+no_of_bytes) > 127) { 8294 upper_page_flag = 1; 8295 upper_page_bytes = no_of_bytes-lower_page_bytes; 8296 if(start_addr > 128) { 8297 upper_page_start_addr = start_addr; 8298 } else { 8299 upper_page_start_addr = 128; 8300 } 8301 } 8302 } else { /* only lower page */ 8303 lower_page_bytes = no_of_bytes; 8304 lower_page_flag = 1; 8305 lower_page_start_addr = start_addr; 8306 } 8307 8308 8309 /* Wtite data to NVRAM */ 8310 for (index = 0; index < no_of_bytes; index++) { 8311 PHYMOD_IF_ERR_RETURN 8312 (WRITE_FURIA_PMA_PMD_REG(pa,\ 8313 FUR_MODULE_CNTRL_RAM_NVR0_Adr+start_addr+index,\ 8314 write_data[index])); 8315 8316 } 8317 8318 if(lower_page_flag) { 8319 PHYMOD_IF_ERR_RETURN 8320 (_furia_set_module_command(pa, 0, 0, 0, FURIA_FLUSH)); 8321 for (index = 0; index < (lower_page_bytes/4); index ++) { 8322 PHYMOD_IF_ERR_RETURN 8323 (_furia_set_module_command(pa, FUR_MODULE_CNTRL_RAM_NVR0_Adr+lower_page_start_addr+(4*index), lower_page_start_addr+(4*index), 3, FURIA_I2C_WRITE)); 8324 } 8325 if ((lower_page_bytes%4) > 0) { 8326 PHYMOD_IF_ERR_RETURN 8327 (_furia_set_module_command(pa, FUR_MODULE_CNTRL_RAM_NVR0_Adr+lower_page_start_addr+(4*index), lower_page_start_addr+(4*index), ((lower_page_bytes%4)-1), FURIA_I2C_WRITE)); 8328 } 8329 lower_page_flag = 0; 8330 } 8331 8332 if(upper_page_flag) { 8333 PHYMOD_IF_ERR_RETURN 8334 (_furia_set_module_command(pa, 0, 0, 0, FURIA_FLUSH)); 8335 for (index = 0; index < (upper_page_bytes/4); index++) { 8336 PHYMOD_IF_ERR_RETURN 8337 (_furia_set_module_command(pa, (FUR_MODULE_CNTRL_RAM_NVR0_Adr+upper_page_start_addr+(4*index)), upper_page_start_addr+(4*index), 3, FURIA_I2C_WRITE)); 8338 } 8339 if ((upper_page_bytes%4) > 0) { 8340 PHYMOD_IF_ERR_RETURN 8341 (_furia_set_module_command(pa, (FUR_MODULE_CNTRL_RAM_NVR0_Adr+upper_page_start_addr+(4*index)), upper_page_start_addr+(4*index), ((upper_page_bytes%4)-1), FURIA_I2C_WRITE)); 8342 } 8343 upper_page_flag = 0; 8344 } 8345 8346 return PHYMOD_E_NONE; 8347 } 8348 8349 int furia_module_read(const phymod_access_t *pa, uint32_t slv_addr, uint32_t start_addr, 8350 uint32_t no_of_bytes, uint8_t *read_data) 8351 { 8352 uint32_t index = 0; 8353 uint32_t rd_data = 0; 8354 uint32_t lower_page_bytes = 0; 8355 uint32_t upper_page_bytes = 0; 8356 uint32_t upper_page_flag = 0; 8357 uint32_t lower_page_start_addr = 0; 8358 uint32_t upper_page_start_addr = 0; 8359 uint32_t lower_page_flag = 0; 8360 FUR_MISC_CTRL_DEBUG_CTRL_t debug_ctrl; 8361 /* SET qsfp_mode=1 */ 8362 8363 PHYMOD_IF_ERR_RETURN 8364 (READ_FURIA_PMA_PMD_REG(pa,\ 8365 FUR_MISC_CTRL_DEBUG_CTRL_Adr,\ 8366 &debug_ctrl.data)); 8367 debug_ctrl.fields.qsfp_mode = 1; 8368 PHYMOD_IF_ERR_RETURN 8369 (WRITE_FURIA_PMA_PMD_REG(pa,\ 8370 FUR_MISC_CTRL_DEBUG_CTRL_Adr,\ 8371 debug_ctrl.data)); 8372 if(start_addr > 255) { 8373 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_PARAM, (_PHYMOD_MSG("Invalid start address"))); 8374 } 8375 if(no_of_bytes == 0) { 8376 /* Perform module controller reset and FLUSH */ 8377 PHYMOD_IF_ERR_RETURN 8378 (_furia_set_module_command(pa, 0, 0, 0, FURIA_FLUSH)); 8379 return PHYMOD_E_NONE; 8380 } 8381 if ((no_of_bytes+start_addr) >= 256) { 8382 no_of_bytes = 255-start_addr+1; 8383 } 8384 8385 /* To determine page to be written is lower page or upper page or 8386 * both lower and upper page 8387 */ 8388 if ((start_addr+no_of_bytes-1) > 127) { 8389 /* lower page */ 8390 if (start_addr <= 127) { 8391 lower_page_bytes = 127-start_addr+1; 8392 lower_page_flag = 1; 8393 lower_page_start_addr = start_addr; 8394 } 8395 /* upper page */ 8396 if ((start_addr+no_of_bytes) > 127) { 8397 upper_page_flag = 1; 8398 upper_page_bytes = no_of_bytes-lower_page_bytes; 8399 if(start_addr > 128) { 8400 upper_page_start_addr = start_addr; 8401 } else { 8402 upper_page_start_addr = 128; 8403 } 8404 } 8405 } else { /* only lower page */ 8406 lower_page_bytes = no_of_bytes; 8407 lower_page_flag = 1; 8408 lower_page_start_addr = start_addr; 8409 } 8410 8411 8412 if (lower_page_flag) { 8413 PHYMOD_IF_ERR_RETURN 8414 (_furia_set_module_command(pa, 0, 0, 0, FURIA_FLUSH)); 8415 PHYMOD_IF_ERR_RETURN 8416 (_furia_set_module_command(pa, FUR_MODULE_CNTRL_RAM_NVR0_Adr+lower_page_start_addr, lower_page_start_addr, lower_page_bytes-1, FURIA_RANDOM_ADDRESS_READ)); 8417 lower_page_flag = 0; 8418 } 8419 8420 8421 if (upper_page_flag) { 8422 PHYMOD_IF_ERR_RETURN 8423 (_furia_set_module_command(pa, 0, 0, 0, FURIA_FLUSH)); 8424 PHYMOD_IF_ERR_RETURN 8425 (_furia_set_module_command(pa, FUR_MODULE_CNTRL_RAM_NVR0_Adr+upper_page_start_addr, upper_page_start_addr, upper_page_bytes-1, FURIA_RANDOM_ADDRESS_READ)); 8426 upper_page_flag = 0; 8427 } 8428 /* Read data from NVRAM */ 8429 for (index = 0; index < no_of_bytes; index++) { 8430 PHYMOD_IF_ERR_RETURN 8431 (READ_FURIA_PMA_PMD_REG(pa,\ 8432 FUR_MODULE_CNTRL_RAM_NVR0_Adr+start_addr+index,\ 8433 &rd_data)); 8434 read_data[index] = (unsigned char) (rd_data & 0xff); 8435 8436 } 8437 return PHYMOD_E_NONE; 8438 } 8439 8440 int _furia_set_module_command(const phymod_access_t *pa, uint16_t xfer_addr, 8441 uint32_t slv_addr, unsigned char xfer_cnt, FURIA_I2CM_CMD_E cmd) { 8442 FUR_MODULE_CNTRL_STATUS_t mctrl_status; 8443 uint16_t retry_count = 0; 8444 uint32_t wait_timeout_us = 0; 8445 /* ((2*100))/20 8446 * where 100 us is the worst case byte transfer time 8447 */ 8448 wait_timeout_us = 20; 8449 retry_count = (xfer_cnt + 1) * 20; 8450 8451 if (cmd == FURIA_FLUSH) { 8452 PHYMOD_IF_ERR_RETURN 8453 (WRITE_FURIA_PMA_PMD_REG(pa,\ 8454 FUR_MODULE_CNTRL_CONTROL_Adr,\ 8455 0xC000)); 8456 } else { 8457 PHYMOD_IF_ERR_RETURN 8458 (WRITE_FURIA_PMA_PMD_REG(pa,\ 8459 FUR_MODULE_CNTRL_XFER_ADDR_Adr,\ 8460 xfer_addr)); 8461 PHYMOD_IF_ERR_RETURN 8462 (WRITE_FURIA_PMA_PMD_REG(pa,\ 8463 FUR_MODULE_CNTRL_XFER_COUNT_Adr,\ 8464 xfer_cnt)); 8465 if (cmd == FURIA_CURRENT_ADDRESS_READ) { 8466 PHYMOD_IF_ERR_RETURN 8467 (WRITE_FURIA_PMA_PMD_REG(pa,\ 8468 FUR_MODULE_CNTRL_CONTROL_Adr,\ 8469 0x8001)); 8470 } else if (cmd == FURIA_RANDOM_ADDRESS_READ ) { 8471 PHYMOD_IF_ERR_RETURN 8472 (WRITE_FURIA_PMA_PMD_REG(pa,\ 8473 FUR_MODULE_CNTRL_ADDRESS_Adr,\ 8474 slv_addr)); 8475 PHYMOD_IF_ERR_RETURN 8476 (WRITE_FURIA_PMA_PMD_REG(pa,\ 8477 FUR_MODULE_CNTRL_CONTROL_Adr,\ 8478 0x8003)); 8479 } else { 8480 PHYMOD_IF_ERR_RETURN 8481 (WRITE_FURIA_PMA_PMD_REG(pa,\ 8482 FUR_MODULE_CNTRL_ADDRESS_Adr,\ 8483 slv_addr)); 8484 PHYMOD_IF_ERR_RETURN 8485 (WRITE_FURIA_PMA_PMD_REG(pa,\ 8486 FUR_MODULE_CNTRL_CONTROL_Adr,\ 8487 0x8022)); 8488 } 8489 } 8490 8491 if ((cmd == FURIA_CURRENT_ADDRESS_READ) || 8492 (cmd == FURIA_RANDOM_ADDRESS_READ) || 8493 (cmd == FURIA_I2C_WRITE)) { 8494 do { 8495 PHYMOD_IF_ERR_RETURN 8496 (READ_FURIA_PMA_PMD_REG(pa,\ 8497 FUR_MODULE_CNTRL_STATUS_Adr,\ 8498 &mctrl_status.data)); 8499 PHYMOD_USLEEP(wait_timeout_us); 8500 } while((mctrl_status.fields.xaction_done == 0) && --retry_count); 8501 if(!retry_count) { 8502 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("Module controller: I2C transaction failed.."))); 8503 } 8504 } 8505 return PHYMOD_E_NONE; 8506 } 8507 8508 int _furia_cfg_fw_ull_dp(const phymod_core_access_t* core, uint32_t ull_dp_enable) { 8509 int lane_map = 0; 8510 uint32_t chip_id = 0; 8511 int num_lanes = 0; 8512 int lane_index = 0; 8513 uint16_t die_lane_num = 0; 8514 uint32_t enable = 0; 8515 FUR_GEN_CNTRLS_gpreg12_t gen_ctrls_gpreg12; 8516 FUR_GEN_CNTRLS_gpreg11_t gen_ctrls_gpreg11; 8517 FUR_GEN_CNTRLS_FIRMWARE_ENABLE_t fw_enable_reg; 8518 const FURIA_PKG_LANE_CFG_t* pkg_ln_des = NULL; 8519 const phymod_access_t *pa = &core->access; 8520 8521 PHYMOD_MEMSET(&gen_ctrls_gpreg12, 0 , sizeof(FUR_GEN_CNTRLS_gpreg12_t)); 8522 PHYMOD_MEMSET(&gen_ctrls_gpreg11, 0 , sizeof(FUR_GEN_CNTRLS_gpreg11_t)); 8523 PHYMOD_MEMSET(&fw_enable_reg, 0 , sizeof(FUR_GEN_CNTRLS_FIRMWARE_ENABLE_t)); 8524 8525 8526 /* Get the chip id */ 8527 chip_id = _furia_get_chip_id(pa); 8528 8529 FURIA_GET_NUM_LANES(chip_id, num_lanes); 8530 8531 8532 enable = (ull_dp_enable == 1) ? 1 : 0; 8533 8534 FURIA_GET_LANE_MASK(chip_id, lane_map); 8535 8536 8537 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 8538 if (((lane_map >> lane_index) & 1) == 0x1) { 8539 /* Get lane descriptor from package lane */ 8540 pkg_ln_des = _furia_pkg_ln_des(chip_id, pa, lane_index); 8541 PHYMOD_NULL_CHECK(pkg_ln_des); 8542 die_lane_num = pkg_ln_des->die_lane_num; 8543 if(FURIA_IS_SIMPLEX(chip_id)) { 8544 if(pkg_ln_des->sideA == LINE) { 8545 /* Read GPReg12 */ 8546 PHYMOD_IF_ERR_RETURN 8547 (READ_FURIA_PMA_PMD_REG(pa,\ 8548 FUR_GEN_CNTRLS_gpreg12_Adr,\ 8549 &gen_ctrls_gpreg12.data)); 8550 if(enable) { 8551 gen_ctrls_gpreg12.fields.en_ull_dp_sys2line |= (1 << die_lane_num); 8552 } else { 8553 gen_ctrls_gpreg12.fields.en_ull_dp_sys2line &= ~(1 << die_lane_num); 8554 } 8555 /* Write GPReg12 */ 8556 PHYMOD_IF_ERR_RETURN 8557 (WRITE_FURIA_PMA_PMD_REG(pa,\ 8558 FUR_GEN_CNTRLS_gpreg12_Adr,\ 8559 gen_ctrls_gpreg12.data)); 8560 } else { 8561 /* Read GPReg11 */ 8562 PHYMOD_IF_ERR_RETURN 8563 (READ_FURIA_PMA_PMD_REG(pa,\ 8564 FUR_GEN_CNTRLS_gpreg11_Adr,\ 8565 &gen_ctrls_gpreg11.data)); 8566 if(enable) { 8567 gen_ctrls_gpreg11.fields.en_ull_dp_line2sys |= (1 << die_lane_num); 8568 } else { 8569 gen_ctrls_gpreg11.fields.en_ull_dp_line2sys &= ~(1 << die_lane_num); 8570 } 8571 /* Write GPReg11 */ 8572 PHYMOD_IF_ERR_RETURN 8573 (WRITE_FURIA_PMA_PMD_REG(pa,\ 8574 FUR_GEN_CNTRLS_gpreg11_Adr,\ 8575 gen_ctrls_gpreg11.data)); 8576 } 8577 } else { 8578 /* Read GPReg12 */ 8579 PHYMOD_IF_ERR_RETURN 8580 (READ_FURIA_PMA_PMD_REG(pa,\ 8581 FUR_GEN_CNTRLS_gpreg12_Adr,\ 8582 &gen_ctrls_gpreg12.data)); 8583 /* Read GPReg11 */ 8584 PHYMOD_IF_ERR_RETURN 8585 (READ_FURIA_PMA_PMD_REG(pa,\ 8586 FUR_GEN_CNTRLS_gpreg11_Adr,\ 8587 &gen_ctrls_gpreg11.data)); 8588 if(enable) { 8589 gen_ctrls_gpreg12.fields.en_ull_dp_sys2line |= (1 << die_lane_num); 8590 gen_ctrls_gpreg11.fields.en_ull_dp_line2sys |= (1 << die_lane_num); 8591 } else { 8592 gen_ctrls_gpreg12.fields.en_ull_dp_sys2line &= ~(1 << die_lane_num); 8593 gen_ctrls_gpreg11.fields.en_ull_dp_line2sys &= ~(1 << die_lane_num); 8594 } 8595 /* Write GPReg12 */ 8596 PHYMOD_IF_ERR_RETURN 8597 (WRITE_FURIA_PMA_PMD_REG(pa,\ 8598 FUR_GEN_CNTRLS_gpreg12_Adr,\ 8599 gen_ctrls_gpreg12.data)); 8600 /* Write GPReg11 */ 8601 PHYMOD_IF_ERR_RETURN 8602 (WRITE_FURIA_PMA_PMD_REG(pa,\ 8603 FUR_GEN_CNTRLS_gpreg11_Adr,\ 8604 gen_ctrls_gpreg11.data)); 8605 } 8606 } 8607 } 8608 /* Set firmware enable */ 8609 PHYMOD_IF_ERR_RETURN 8610 (_furia_fw_enable(pa)); 8611 return PHYMOD_E_NONE; 8612 } 8613 8614 int _furia_cfg_an_master_lane(const phymod_core_access_t* core, uint32_t an_master_lane) 8615 { 8616 uint16_t die_lane_num = 0; 8617 uint32_t chip_id = 0; 8618 FUR_MISC_CTRL_LOGIC_TO_PHY_LN0_MAP_t logic_to_phy_ln0_map; 8619 const FURIA_PKG_LANE_CFG_t* pkg_ln_des = NULL; 8620 const phymod_access_t *pa = &core->access; 8621 PHYMOD_MEMSET(&logic_to_phy_ln0_map, 0 , sizeof(FUR_MISC_CTRL_LOGIC_TO_PHY_LN0_MAP_t)); 8622 8623 /* Get the chip id */ 8624 chip_id = _furia_get_chip_id(pa); 8625 /* Get lane descriptor from package lane */ 8626 pkg_ln_des = _furia_pkg_ln_des(chip_id, pa, an_master_lane); 8627 PHYMOD_NULL_CHECK(pkg_ln_des); 8628 die_lane_num = pkg_ln_des->die_lane_num; 8629 PHYMOD_IF_ERR_RETURN 8630 (READ_FURIA_PMA_PMD_REG(pa,\ 8631 FUR_MISC_CTRL_logic_to_phy_ln0_map_Adr,\ 8632 &logic_to_phy_ln0_map.data)); 8633 logic_to_phy_ln0_map.fields.single_pmd_prt1_ln0_on_pl = die_lane_num; 8634 PHYMOD_IF_ERR_RETURN 8635 (WRITE_FURIA_PMA_PMD_REG(pa,\ 8636 FUR_MISC_CTRL_logic_to_phy_ln0_map_Adr,\ 8637 logic_to_phy_ln0_map.data)); 8638 return PHYMOD_E_NONE; 8639 } 8640 8641 STATIC int _furia_cfg_an_master_lane_get(const phymod_access_t *pa, uint32_t *an_master_lane) 8642 { 8643 FUR_MISC_CTRL_LOGIC_TO_PHY_LN0_MAP_t logic_to_phy_ln0_map; 8644 PHYMOD_MEMSET(&logic_to_phy_ln0_map, 0 , sizeof(FUR_MISC_CTRL_LOGIC_TO_PHY_LN0_MAP_t)); 8645 8646 /* Get the chip id */ 8647 PHYMOD_IF_ERR_RETURN 8648 (READ_FURIA_PMA_PMD_REG(pa,\ 8649 FUR_MISC_CTRL_logic_to_phy_ln0_map_Adr,\ 8650 &logic_to_phy_ln0_map.data)); 8651 *an_master_lane = logic_to_phy_ln0_map.fields.single_pmd_prt1_ln0_on_pl; 8652 8653 return PHYMOD_E_NONE; 8654 } 8655 8656 int _furia_pcs_monitor_enable_set(const phymod_core_access_t* core, int enable) { 8657 uint32_t chip_id = 0; 8658 int pkg_side = 0; 8659 int wr_lane = 0; 8660 int sys_en = 0; 8661 int rd_lane = 0; 8662 int num_lanes = 0; 8663 int lane_index = 0; 8664 LINE_RX_PMA_DP_MAIN_CTRL_t line_rx_dp_main_ctrl; 8665 SYS_RX_PMA_DP_MAIN_CTRL_t sys_rx_dp_main_ctrl; 8666 LINE_RX_PMA_DP_MAIN_CTRL_PCS_MODE_t tmp_main_ctrl_mode; 8667 const FURIA_PKG_LANE_CFG_t* pkg_ln_des = NULL; 8668 const phymod_access_t *pa = &core->access; 8669 /* Get the chip id */ 8670 chip_id = _furia_get_chip_id(pa); 8671 FURIA_GET_NUM_LANES(chip_id, num_lanes); 8672 8673 /* Disable PCS monitor on all the PHY lanes */ 8674 for(pkg_side = 0; pkg_side <= SIDE_B; pkg_side++) { 8675 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 8676 /* Configure Tx side(SIDE_A) first*/ 8677 pkg_ln_des = _furia_pkg_ln_des(chip_id, pa, lane_index); 8678 PHYMOD_NULL_CHECK(pkg_ln_des); 8679 wr_lane = pkg_ln_des->slice_wr_val; 8680 rd_lane = pkg_ln_des->slice_rd_val; 8681 if(pkg_side == SIDE_A) { 8682 sys_en = pkg_ln_des->sideA; 8683 } else { 8684 sys_en = pkg_ln_des->sideB; 8685 } 8686 /* Program the slice register */ 8687 PHYMOD_IF_ERR_RETURN 8688 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 8689 if ((FURIA_IS_SIMPLEX(chip_id) && pkg_side == SIDE_B) || 8690 (FURIA_IS_DUPLEX(chip_id))) { 8691 if(sys_en == LINE) { 8692 PHYMOD_IF_ERR_RETURN 8693 (READ_FURIA_PMA_PMD_REG(pa,\ 8694 LINE_RX_PMA_DP_main_ctrl_Adr,\ 8695 &line_rx_dp_main_ctrl.data)); 8696 tmp_main_ctrl_mode.data = line_rx_dp_main_ctrl.data; 8697 tmp_main_ctrl_mode.fields.link_mon_en = enable; 8698 PHYMOD_IF_ERR_RETURN 8699 (WRITE_FURIA_PMA_PMD_REG(pa,\ 8700 LINE_RX_PMA_DP_main_ctrl_Adr,\ 8701 tmp_main_ctrl_mode.data)); 8702 } else { 8703 PHYMOD_IF_ERR_RETURN 8704 (READ_FURIA_PMA_PMD_REG(pa,\ 8705 SYS_RX_PMA_DP_main_ctrl_Adr,\ 8706 &sys_rx_dp_main_ctrl.data)); 8707 tmp_main_ctrl_mode.data = sys_rx_dp_main_ctrl.data; 8708 tmp_main_ctrl_mode.fields.link_mon_en = enable; 8709 PHYMOD_IF_ERR_RETURN 8710 (WRITE_FURIA_PMA_PMD_REG(pa,\ 8711 SYS_RX_PMA_DP_main_ctrl_Adr,\ 8712 tmp_main_ctrl_mode.data)); 8713 } 8714 } 8715 } 8716 } 8717 /* Set the slice register with default values */ 8718 PHYMOD_IF_ERR_RETURN 8719 (WRITE_FURIA_SLICE_REG(pa, 0, 1, 0)); 8720 return PHYMOD_E_NONE; 8721 } 8722 8723 STATIC int _furia_set_intf_type(const phymod_access_t *pa, uint16_t phy_type, uint16_t link_type, 8724 uint32_t phymod_interface_type, int lane_index, int otn_type, uint16_t ref_clk, uint32_t higig_mode) 8725 { 8726 FUR_GEN_CNTRLS_micro_sync_7_t gen_ctrls_intf_type; 8727 FUR_GEN_CNTRLS_micro_sync_6_t gen_ctrls6_intf_type; 8728 uint32_t chip_id = 0, ref_clk_define = 1 /* default 156*/; 8729 PHYMOD_MEMSET(&gen_ctrls_intf_type, 0 , sizeof(FUR_GEN_CNTRLS_micro_sync_7_t)); 8730 PHYMOD_MEMSET(&gen_ctrls6_intf_type, 0 , sizeof(FUR_GEN_CNTRLS_micro_sync_6_t)); 8731 8732 PHYMOD_IF_ERR_RETURN 8733 (READ_FURIA_PMA_PMD_REG(pa, FUR_GEN_CNTRLS_micro_sync_7_Adr, 8734 &gen_ctrls_intf_type.data)); 8735 PHYMOD_IF_ERR_RETURN 8736 (READ_FURIA_PMA_PMD_REG(pa, FUR_GEN_CNTRLS_micro_sync_6_Adr, 8737 &gen_ctrls6_intf_type.data)); 8738 8739 chip_id = _furia_get_chip_id(pa); 8740 if (chip_id == FURIA_ID_82212) { 8741 const FURIA_PKG_LANE_CFG_t* pkg_ln_des = NULL; 8742 pkg_ln_des = _furia_pkg_ln_des(chip_id, pa, lane_index); 8743 PHYMOD_NULL_CHECK(pkg_ln_des); 8744 if (pkg_ln_des->sideB == LINE) { 8745 lane_index = (pkg_ln_des->die_lane_num + 4); 8746 } else { 8747 lane_index = pkg_ln_des->die_lane_num; 8748 } 8749 8750 } 8751 8752 /*save ref clock*/ 8753 switch(ref_clk){ 8754 case phymodRefClk125Mhz: 8755 ref_clk_define = FURIA_CLK_125; 8756 break ; 8757 case phymodRefClk156Mhz: 8758 ref_clk_define = FURIA_CLK_156; 8759 break ; 8760 case phymodRefClk157Mhz: 8761 ref_clk_define = FURIA_CLK_157; 8762 break ; 8763 case phymodRefClk106Mhz: 8764 ref_clk_define = FURIA_CLK_106; 8765 break ; 8766 case phymodRefClk158Mhz: 8767 ref_clk_define = FURIA_CLK_158; 8768 break ; 8769 case phymodRefClk161Mhz: 8770 ref_clk_define = FURIA_CLK_161; 8771 break ; 8772 case phymodRefClk168Mhz: 8773 ref_clk_define = FURIA_CLK_168; 8774 break ; 8775 case phymodRefClk174Mhz: 8776 ref_clk_define = FURIA_CLK_174; 8777 break ; 8778 case phymodRefClk159Mhz: 8779 ref_clk_define = FURIA_CLK_159; 8780 break ; 8781 default: 8782 ref_clk_define = FURIA_CLK_156; 8783 break; 8784 } 8785 gen_ctrls6_intf_type.fields.ref_clk = ref_clk_define ; 8786 gen_ctrls6_intf_type.fields.highgig = ( higig_mode ) ? 1 : 0 ; 8787 8788 switch (phy_type) { 8789 case FURIA_PHYTYPE_FC: 8790 case FURIA_PHYTYPE_BP: 8791 /*For future use*/ 8792 break; 8793 case FURIA_PHYTYPE_OTN: 8794 switch (link_type) { 8795 case FURIA_LINKTYPE_1: 8796 if (phymod_interface_type == phymodInterfaceCAUI4_C2C) { 8797 FURIA_REG_SET(gen_ctrls_intf_type.fields.intf_type_ln, lane_index, FURIA_IF_CC); 8798 } else if (phymod_interface_type == phymodInterfaceCAUI4_C2M) { 8799 FURIA_REG_SET(gen_ctrls_intf_type.fields.intf_type_ln, lane_index, FURIA_IF_CM); 8800 } else if (phymod_interface_type == phymodInterfaceOTN) { 8801 switch(otn_type){ 8802 case phymodOTNOTU1e: 8803 FURIA_REG_SET(gen_ctrls6_intf_type.fields.intf_type_ln, lane_index, FURIA_IF_1E); 8804 break; 8805 case phymodOTNOTU2e: 8806 FURIA_REG_SET(gen_ctrls6_intf_type.fields.intf_type_ln, lane_index, FURIA_IF_2E); 8807 break; 8808 default: 8809 break; 8810 } 8811 } 8812 break; 8813 case FURIA_LINKTYPE_2:/*for OTU 3e1 & 3e2 . Bits are shared with OTU1E & 2E*/ 8814 if (phymod_interface_type == phymodInterfaceOTN) { 8815 switch(otn_type){ 8816 case phymodOTNOTU3: 8817 FURIA_REG_SET(gen_ctrls6_intf_type.fields.intf_type_ln, lane_index, FURIA_IF_3E1); 8818 break; 8819 case phymodOTNOTU3e2: 8820 FURIA_REG_SET(gen_ctrls6_intf_type.fields.intf_type_ln, lane_index, FURIA_IF_3E2); 8821 break; 8822 default: 8823 break; 8824 } 8825 } 8826 break; 8827 case FURIA_LINKTYPE_4: 8828 case FURIA_LINKTYPE_7: 8829 if (phymod_interface_type == phymodInterfaceLR ||phymod_interface_type == phymodInterfaceLR2 || 8830 phymod_interface_type == phymodInterfaceLR4) { 8831 FURIA_REG_SET(gen_ctrls_intf_type.fields.intf_type_ln, lane_index, FURIA_IF_LR_LR4); 8832 } else if (phymod_interface_type == phymodInterfaceSR ||phymod_interface_type == phymodInterfaceSR2 || 8833 phymod_interface_type == phymodInterfaceSR4) { 8834 FURIA_REG_SET(gen_ctrls_intf_type.fields.intf_type_ln, lane_index, FURIA_IF_SR_SR4); 8835 } else if (phymod_interface_type == phymodInterfaceER ||phymod_interface_type == phymodInterfaceER2 || 8836 phymod_interface_type == phymodInterfaceER4) { 8837 FURIA_REG_SET(gen_ctrls_intf_type.fields.intf_type_ln, lane_index, FURIA_IF_ER_ER4); 8838 } else { 8839 FURIA_REG_SET(gen_ctrls_intf_type.fields.intf_type_ln, lane_index, FURIA_IF_KR_KR4); 8840 /*Nothing to do*/ 8841 /* Futhure use*/ 8842 } 8843 break; 8844 case FURIA_LINKTYPE_5: 8845 if (phymod_interface_type == phymodInterfaceCR4) { 8846 FURIA_REG_SET(gen_ctrls_intf_type.fields.intf_type_ln, lane_index, FURIA_IF_CR4); 8847 } 8848 break; 8849 default: 8850 break; 8851 } 8852 break; 8853 case FURIA_PHYTYPE_FP: 8854 { 8855 switch (link_type) { 8856 case FURIA_LINKTYPE_F: 8857 if (phymod_interface_type == phymodInterfaceCAUI4_C2C) { 8858 FURIA_REG_SET(gen_ctrls_intf_type.fields.intf_type_ln, lane_index, FURIA_IF_CC); 8859 } else if (phymod_interface_type == phymodInterfaceCAUI4_C2M) { 8860 FURIA_REG_SET(gen_ctrls_intf_type.fields.intf_type_ln, lane_index, FURIA_IF_CM); 8861 }else if (phymod_interface_type == phymodInterfaceCAUI4) { 8862 FURIA_REG_SET(gen_ctrls_intf_type.fields.intf_type_ln, lane_index, FURIA_IF_CAUI4); 8863 } else if (phymod_interface_type == phymodInterfaceCAUI) { 8864 FURIA_REG_SET(gen_ctrls_intf_type.fields.intf_type_ln, lane_index, FURIA_IF_CAUI); 8865 } 8866 break; 8867 case FURIA_LINKTYPE_3: 8868 case FURIA_LINKTYPE_1: 8869 case FURIA_LINKTYPE_4: 8870 case FURIA_LINKTYPE_6: 8871 case FURIA_LINKTYPE_7: 8872 if (phymod_interface_type == phymodInterfaceLR ||phymod_interface_type == phymodInterfaceLR2 || 8873 phymod_interface_type == phymodInterfaceLR4) { 8874 FURIA_REG_SET(gen_ctrls_intf_type.fields.intf_type_ln, lane_index, FURIA_IF_LR_LR4); 8875 } else if (phymod_interface_type == phymodInterfaceSR ||phymod_interface_type == phymodInterfaceSR2 || 8876 phymod_interface_type == phymodInterfaceSR4) { 8877 FURIA_REG_SET(gen_ctrls_intf_type.fields.intf_type_ln, lane_index, FURIA_IF_SR_SR4); 8878 } else if (phymod_interface_type == phymodInterfaceER ||phymod_interface_type == phymodInterfaceER2 || 8879 phymod_interface_type == phymodInterfaceER4) { 8880 FURIA_REG_SET(gen_ctrls_intf_type.fields.intf_type_ln, lane_index, FURIA_IF_ER_ER4); 8881 } 8882 break; 8883 case FURIA_LINKTYPE_C: 8884 if (phymod_interface_type == phymodInterfaceCR || phymod_interface_type == phymodInterfaceCR2) { 8885 FURIA_REG_SET(gen_ctrls_intf_type.fields.intf_type_ln, lane_index, FURIA_IF_CR); 8886 } 8887 break; 8888 case FURIA_LINKTYPE_D: 8889 if (phymod_interface_type == phymodInterfaceCR) { 8890 FURIA_REG_SET(gen_ctrls_intf_type.fields.intf_type_ln, lane_index, FURIA_IF_CR); 8891 } else if (phymod_interface_type == phymodInterfaceCX) { 8892 FURIA_REG_SET(gen_ctrls_intf_type.fields.intf_type_ln, lane_index, FURIA_IF_CX); 8893 } else if (phymod_interface_type == phymodInterfaceSFI) { 8894 FURIA_REG_SET(gen_ctrls_intf_type.fields.intf_type_ln, lane_index, FURIA_IF_SFI); 8895 } 8896 #ifdef DEB 8897 printf("[ (%s at %d )ptype = %d : ltype = %d : otn_type = %d\n",__FUNCTION__,__LINE__,phy_type,link_type,otn_type); 8898 #endif 8899 switch(ref_clk){ 8900 case phymodRefClk157Mhz: 8901 FURIA_REG_SET(gen_ctrls6_intf_type.fields.intf_type_ln, lane_index, FURIA_IF_1E); 8902 break; 8903 case phymodRefClk158Mhz: 8904 FURIA_REG_SET(gen_ctrls6_intf_type.fields.intf_type_ln, lane_index, FURIA_IF_2E); 8905 break; 8906 case phymodRefClk159Mhz: 8907 if ( phymod_interface_type == phymodInterfaceSFI ) { 8908 switch(otn_type){ 8909 case phymodOTNOTU3: 8910 FURIA_REG_SET(gen_ctrls6_intf_type.fields.intf_type_ln, lane_index, FURIA_IF_3E1); 8911 break; 8912 case phymodOTNOTU3e2: 8913 FURIA_REG_SET(gen_ctrls6_intf_type.fields.intf_type_ln, lane_index, FURIA_IF_3E2); 8914 break; 8915 default: 8916 break; 8917 } 8918 } 8919 break; 8920 default: 8921 break; 8922 } 8923 8924 break; 8925 case FURIA_LINKTYPE_E: 8926 if (phymod_interface_type == phymodInterfaceXLAUI) { 8927 FURIA_REG_SET(gen_ctrls_intf_type.fields.intf_type_ln, lane_index, FURIA_IF_XLAUI); 8928 } else if (phymod_interface_type == phymodInterfaceXFI) { 8929 FURIA_REG_SET(gen_ctrls_intf_type.fields.intf_type_ln, lane_index, FURIA_IF_XFI); 8930 } 8931 if (( phymod_interface_type == phymodInterfaceXLAUI )&&(ref_clk == phymodRefClk159Mhz)) { 8932 switch(otn_type){ 8933 case phymodOTNOTU3: 8934 FURIA_REG_SET(gen_ctrls6_intf_type.fields.intf_type_ln, lane_index, FURIA_IF_3E1); 8935 break; 8936 case phymodOTNOTU3e2: 8937 FURIA_REG_SET(gen_ctrls6_intf_type.fields.intf_type_ln, lane_index, FURIA_IF_3E2); 8938 break; 8939 default: 8940 break; 8941 } 8942 } 8943 8944 8945 break; 8946 case FURIA_LINKTYPE_5: 8947 if (phymod_interface_type == phymodInterfaceCR4) { 8948 FURIA_REG_SET(gen_ctrls_intf_type.fields.intf_type_ln, lane_index, FURIA_IF_CR4); 8949 } 8950 break; 8951 default: 8952 break; 8953 } 8954 } 8955 break; 8956 case FURIA_PHYTYPE_PROP: 8957 { 8958 switch (link_type) { 8959 case FURIA_LINKTYPE_1: 8960 if (phymod_interface_type == phymodInterfaceCAUI4_C2C) { 8961 FURIA_REG_SET(gen_ctrls_intf_type.fields.intf_type_ln, lane_index, FURIA_IF_CC); 8962 } else if (phymod_interface_type == phymodInterfaceCAUI4_C2M) { 8963 FURIA_REG_SET(gen_ctrls_intf_type.fields.intf_type_ln, lane_index, FURIA_IF_CM); 8964 } 8965 break; 8966 case FURIA_LINKTYPE_4: 8967 switch(ref_clk){ 8968 case phymodRefClk157Mhz: 8969 FURIA_REG_SET(gen_ctrls6_intf_type.fields.intf_type_ln, lane_index, FURIA_IF_1E); 8970 break; 8971 case phymodRefClk158Mhz: 8972 FURIA_REG_SET(gen_ctrls6_intf_type.fields.intf_type_ln, lane_index, FURIA_IF_2E); 8973 break; 8974 default: 8975 break; 8976 } 8977 break; 8978 default: 8979 break; 8980 } 8981 } 8982 break; 8983 default: 8984 break; 8985 } 8986 PHYMOD_IF_ERR_RETURN 8987 (WRITE_FURIA_PMA_PMD_REG(pa, FUR_GEN_CNTRLS_micro_sync_7_Adr, 8988 gen_ctrls_intf_type.data)); 8989 PHYMOD_IF_ERR_RETURN 8990 (WRITE_FURIA_PMA_PMD_REG(pa, FUR_GEN_CNTRLS_micro_sync_6_Adr, 8991 gen_ctrls6_intf_type.data)); 8992 8993 return PHYMOD_E_NONE; 8994 } 8995 8996 STATIC int _furia_get_intf_type(const phymod_access_t *pa, uint16_t phy_type, 8997 uint16_t link_type, int lane_index, uint16_t *saved_intf, uint16_t *saved_intf1e2e, uint16_t *saved_refclk, uint32_t *higig_mode) 8998 { 8999 FUR_GEN_CNTRLS_micro_sync_7_t gen_ctrls_intf_type; 9000 FUR_GEN_CNTRLS_micro_sync_6_t gen_ctrls6_intf_type; 9001 uint32_t chip_id = 0; 9002 *saved_intf1e2e = 3; 9003 PHYMOD_MEMSET(&gen_ctrls_intf_type, 0 , sizeof(FUR_GEN_CNTRLS_micro_sync_7_t)); 9004 PHYMOD_MEMSET(&gen_ctrls6_intf_type, 0 , sizeof(FUR_GEN_CNTRLS_micro_sync_6_t)); 9005 9006 PHYMOD_IF_ERR_RETURN 9007 (READ_FURIA_PMA_PMD_REG(pa, FUR_GEN_CNTRLS_micro_sync_7_Adr, 9008 &gen_ctrls_intf_type.data)); 9009 PHYMOD_IF_ERR_RETURN 9010 (READ_FURIA_PMA_PMD_REG(pa, FUR_GEN_CNTRLS_micro_sync_6_Adr, 9011 &gen_ctrls6_intf_type.data)); 9012 9013 chip_id = _furia_get_chip_id(pa); 9014 if (chip_id == FURIA_ID_82212) { 9015 const FURIA_PKG_LANE_CFG_t* pkg_ln_des = NULL; 9016 pkg_ln_des = _furia_pkg_ln_des(chip_id, pa, lane_index); 9017 PHYMOD_NULL_CHECK(pkg_ln_des); 9018 if (pkg_ln_des->sideB == LINE) { 9019 lane_index = (pkg_ln_des->die_lane_num + 4); 9020 } else { 9021 lane_index = pkg_ln_des->die_lane_num; 9022 } 9023 9024 } 9025 9026 *higig_mode = gen_ctrls6_intf_type.fields.highgig ; 9027 *saved_refclk = gen_ctrls6_intf_type.fields.ref_clk ; 9028 switch (phy_type) { 9029 case FURIA_PHYTYPE_FC: 9030 case FURIA_PHYTYPE_BP: 9031 /*For future use*/ 9032 break; 9033 case FURIA_PHYTYPE_OTN: 9034 FURIA_REG_GET(gen_ctrls_intf_type.fields.intf_type_ln, lane_index, *saved_intf); 9035 FURIA_REG_GET(gen_ctrls6_intf_type.fields.intf_type_ln, lane_index, *saved_intf1e2e); 9036 break; 9037 case FURIA_PHYTYPE_FP: 9038 { 9039 switch (link_type) { 9040 case FURIA_LINKTYPE_D: 9041 case FURIA_LINKTYPE_E: 9042 if( *saved_refclk != 1){ 9043 FURIA_REG_GET(gen_ctrls6_intf_type.fields.intf_type_ln, lane_index, *saved_intf1e2e); 9044 } 9045 /* coverity[fallthrough] */ 9046 case FURIA_LINKTYPE_1: 9047 case FURIA_LINKTYPE_3: 9048 case FURIA_LINKTYPE_4: 9049 case FURIA_LINKTYPE_5: 9050 case FURIA_LINKTYPE_6: 9051 case FURIA_LINKTYPE_7: 9052 case FURIA_LINKTYPE_C: 9053 case FURIA_LINKTYPE_F: 9054 FURIA_REG_GET(gen_ctrls_intf_type.fields.intf_type_ln, lane_index, *saved_intf); 9055 break; 9056 default: 9057 break; 9058 } 9059 } 9060 break; 9061 case FURIA_PHYTYPE_PROP: 9062 { 9063 switch (link_type) { 9064 case FURIA_LINKTYPE_4: 9065 case FURIA_LINKTYPE_1: 9066 case FURIA_LINKTYPE_2: 9067 FURIA_REG_GET(gen_ctrls_intf_type.fields.intf_type_ln, lane_index,*saved_intf); 9068 break; 9069 9070 default: 9071 break; 9072 } 9073 if( *saved_refclk != 1){ 9074 FURIA_REG_GET(gen_ctrls6_intf_type.fields.intf_type_ln, lane_index, *saved_intf1e2e); 9075 } 9076 9077 } 9078 break; 9079 default: 9080 break;; 9081 } 9082 return PHYMOD_E_NONE; 9083 } 9084 9085 void _furia_get_reg_val_from_sync_type(uint32_t ptr_sync, uint32_t *reg_val) 9086 { 9087 switch (ptr_sync) { 9088 case 0: 9089 *reg_val = 0; 9090 break; 9091 case 1: 9092 *reg_val = 1; 9093 break; 9094 case 2: 9095 *reg_val = 3; 9096 break; 9097 case 3: 9098 *reg_val = 2; 9099 break; 9100 case 4: 9101 *reg_val = 6; 9102 break; 9103 case 5: 9104 *reg_val = 7; 9105 break; 9106 case 6: 9107 *reg_val = 0xF; 9108 break; 9109 case 7: 9110 *reg_val = 0xe; 9111 break; 9112 case 8: 9113 *reg_val = 0xa; 9114 break; 9115 case 9: 9116 *reg_val = 0xb; 9117 break; 9118 case 10: 9119 *reg_val = 0x9; 9120 break; 9121 case 11: 9122 *reg_val = 0x8; 9123 break; 9124 default : 9125 *reg_val = 0; 9126 break; 9127 } 9128 9129 } 9130 int _furia_core_cfg_pfifo_4_max_ieee_input_skew(const phymod_access_t* pa, uint32_t tx_ptr_sync, uint32_t rx_ptr_sync) 9131 { 9132 int lane_map = 0; 9133 uint32_t chip_id = 0; 9134 int num_lanes = 0; 9135 int lane_index = 0; 9136 int wr_lane = 0; 9137 int sys_en = 0; 9138 int rd_lane = 0; 9139 int side_index = 0; 9140 LINE_RX_PMA_DP_DP_CTRL_t line_rx_pma_dp_ctrl; 9141 LINE_TX_PMA_DP_CTRL_t line_tx_pma_dp_ctrl; 9142 SYS_RX_PMA_DP_DP_CTRL_t sys_rx_pma_dp_ctrl; 9143 SYS_TX_PMA_DP_CTRL_t sys_tx_pma_dp_ctrl; 9144 const FURIA_PKG_LANE_CFG_t* pkg_ln_des = NULL; 9145 uint32_t rx_ptr_sync_reg_val = 0; 9146 uint32_t tx_ptr_sync_reg_val = 0; 9147 PHYMOD_MEMSET(&line_rx_pma_dp_ctrl, 0 , sizeof(LINE_RX_PMA_DP_DP_CTRL_t)); 9148 PHYMOD_MEMSET(&line_tx_pma_dp_ctrl, 0 , sizeof(LINE_TX_PMA_DP_CTRL_t)); 9149 PHYMOD_MEMSET(&sys_rx_pma_dp_ctrl, 0 , sizeof(SYS_RX_PMA_DP_DP_CTRL_t)); 9150 PHYMOD_MEMSET(&sys_tx_pma_dp_ctrl, 0 , sizeof(SYS_TX_PMA_DP_CTRL_t)); 9151 9152 /* Get the chip id */ 9153 chip_id = _furia_get_chip_id(pa); 9154 9155 FURIA_GET_NUM_LANES(chip_id, num_lanes); 9156 9157 FURIA_GET_LANE_MASK(chip_id, lane_map); 9158 _furia_get_reg_val_from_sync_type(tx_ptr_sync, &tx_ptr_sync_reg_val); 9159 _furia_get_reg_val_from_sync_type(rx_ptr_sync, &rx_ptr_sync_reg_val); 9160 9161 for (side_index = 0; side_index < 2; side_index++) { 9162 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 9163 if (((lane_map >> lane_index) & 1) == 0x1) { 9164 /* Get lane descriptor from package lane */ 9165 pkg_ln_des = _furia_pkg_ln_des(chip_id, pa, lane_index); 9166 PHYMOD_NULL_CHECK(pkg_ln_des); 9167 if(side_index == SIDE_A) { 9168 sys_en = pkg_ln_des->sideA; 9169 } else { 9170 sys_en = pkg_ln_des->sideB; 9171 } 9172 9173 wr_lane = pkg_ln_des->slice_wr_val; 9174 rd_lane = pkg_ln_des->slice_rd_val; 9175 9176 /* Program the slice register */ 9177 PHYMOD_IF_ERR_RETURN 9178 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 9179 9180 if(sys_en == LINE) { 9181 PHYMOD_IF_ERR_RETURN 9182 (READ_FURIA_PMA_PMD_REG(pa,\ 9183 LINE_RX_PMA_DP_dp_ctrl_Adr,\ 9184 &line_rx_pma_dp_ctrl.data)); 9185 PHYMOD_IF_ERR_RETURN 9186 (READ_FURIA_PMA_PMD_REG(pa,\ 9187 LINE_TX_PMA_DP_ctrl_Adr,\ 9188 &line_tx_pma_dp_ctrl.data)); 9189 line_rx_pma_dp_ctrl.fields.ptr_sync = rx_ptr_sync_reg_val; 9190 line_tx_pma_dp_ctrl.fields.ptr_sync = tx_ptr_sync_reg_val; 9191 PHYMOD_IF_ERR_RETURN 9192 (WRITE_FURIA_PMA_PMD_REG(pa,\ 9193 LINE_RX_PMA_DP_dp_ctrl_Adr,\ 9194 line_rx_pma_dp_ctrl.data)); 9195 PHYMOD_IF_ERR_RETURN 9196 (WRITE_FURIA_PMA_PMD_REG(pa,\ 9197 LINE_TX_PMA_DP_ctrl_Adr,\ 9198 line_tx_pma_dp_ctrl.data)); 9199 } else { 9200 PHYMOD_IF_ERR_RETURN 9201 (READ_FURIA_PMA_PMD_REG(pa,\ 9202 SYS_RX_PMA_DP_dp_ctrl_Adr,\ 9203 &sys_rx_pma_dp_ctrl.data)); 9204 PHYMOD_IF_ERR_RETURN 9205 (READ_FURIA_PMA_PMD_REG(pa,\ 9206 SYS_TX_PMA_DP_ctrl_Adr,\ 9207 &sys_tx_pma_dp_ctrl.data)); 9208 sys_rx_pma_dp_ctrl.fields.ptr_sync = rx_ptr_sync_reg_val; 9209 sys_tx_pma_dp_ctrl.fields.ptr_sync = tx_ptr_sync_reg_val; 9210 PHYMOD_IF_ERR_RETURN 9211 (WRITE_FURIA_PMA_PMD_REG(pa,\ 9212 SYS_RX_PMA_DP_dp_ctrl_Adr,\ 9213 sys_rx_pma_dp_ctrl.data)); 9214 PHYMOD_IF_ERR_RETURN 9215 (WRITE_FURIA_PMA_PMD_REG(pa,\ 9216 SYS_TX_PMA_DP_ctrl_Adr,\ 9217 sys_tx_pma_dp_ctrl.data)); 9218 9219 } 9220 } 9221 } 9222 } 9223 /* Set the slice register with default values */ 9224 PHYMOD_IF_ERR_RETURN 9225 (WRITE_FURIA_SLICE_REG(pa, 0, 1, 0)); 9226 return PHYMOD_E_NONE; 9227 } 9228 9229 9230 int _furia_core_cfg_hcd_link_status_criteria(const phymod_access_t *pa, uint32_t hcd_link_criteria) 9231 { 9232 int lane_map = 0; 9233 uint32_t chip_id = 0; 9234 int num_lanes = 0; 9235 int lane_index = 0; 9236 int wr_lane = 0; 9237 int rd_lane = 0; 9238 uint32_t an_master_lane = 0; 9239 RX_ANA_REGS_ANARXCONTROL3_t an_rx_ctrl3; 9240 FUR_MISC_CTRL_FURIA_QSFI_MISC_t qsfi_misc; 9241 const FURIA_PKG_LANE_CFG_t* pkg_ln_des = NULL; 9242 9243 PHYMOD_MEMSET(&an_rx_ctrl3, 0 , sizeof(RX_ANA_REGS_ANARXCONTROL3_t)); 9244 PHYMOD_MEMSET(&qsfi_misc, 0 , sizeof(FUR_MISC_CTRL_FURIA_QSFI_MISC_t)); 9245 9246 /* Get the chip id */ 9247 chip_id = _furia_get_chip_id(pa); 9248 9249 if (FURIA_IS_SIMPLEX(chip_id)) { 9250 return PHYMOD_E_NONE; 9251 } 9252 num_lanes = 4; 9253 lane_map = pa->lane_mask; 9254 9255 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 9256 if (((lane_map >> lane_index) & 1) == 0x1) { 9257 /* Get lane descriptor from package lane */ 9258 pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 1); 9259 PHYMOD_NULL_CHECK(pkg_ln_des); 9260 if (lane_map == 0xF) { 9261 PHYMOD_IF_ERR_RETURN( 9262 _furia_cfg_an_master_lane_get(pa, &an_master_lane)); 9263 wr_lane = 1 << an_master_lane; 9264 rd_lane = an_master_lane; 9265 } else { 9266 wr_lane = pkg_ln_des->slice_wr_val; 9267 rd_lane = pkg_ln_des->slice_rd_val; 9268 } 9269 9270 /* Program the slice register */ 9271 PHYMOD_IF_ERR_RETURN 9272 (WRITE_FURIA_SLICE_REG(pa, LINE, wr_lane, rd_lane)); 9273 9274 9275 switch(hcd_link_criteria) { 9276 case FURIA_HCD_LINK_REG_WR: 9277 PHYMOD_IF_ERR_RETURN 9278 (READ_FURIA_PMA_PMD_REG(pa,\ 9279 RX_ANA_REGS_anaRxControl3_Adr,\ 9280 &an_rx_ctrl3.data)); 9281 an_rx_ctrl3.fields.link_en_force_sm = 1; 9282 an_rx_ctrl3.fields.link_en_r= 1; 9283 PHYMOD_IF_ERR_RETURN 9284 (WRITE_FURIA_PMA_PMD_REG(pa,\ 9285 RX_ANA_REGS_anaRxControl3_Adr,\ 9286 an_rx_ctrl3.data)); 9287 break; 9288 case FURIA_HCD_LINK_KR_BLOCK_LOCK: 9289 PHYMOD_IF_ERR_RETURN 9290 (READ_FURIA_PMA_PMD_REG(pa,\ 9291 RX_ANA_REGS_anaRxControl3_Adr,\ 9292 &an_rx_ctrl3.data)); 9293 an_rx_ctrl3.fields.link_en_force_sm = 0; 9294 an_rx_ctrl3.fields.use_kr_block_lock_sm = 1; 9295 PHYMOD_IF_ERR_RETURN 9296 (WRITE_FURIA_PMA_PMD_REG(pa,\ 9297 RX_ANA_REGS_anaRxControl3_Adr,\ 9298 an_rx_ctrl3.data)); 9299 break; 9300 case FURIA_HCD_LINK_KR4_BLOCK_LOCK: 9301 PHYMOD_IF_ERR_RETURN 9302 (READ_FURIA_PMA_PMD_REG(pa,\ 9303 RX_ANA_REGS_anaRxControl3_Adr,\ 9304 &an_rx_ctrl3.data)); 9305 an_rx_ctrl3.fields.link_en_force_sm = 0; 9306 an_rx_ctrl3.fields.use_kr_block_lock_sm = 0; 9307 an_rx_ctrl3.fields.use_kr4_block_lock_sm = 1; 9308 9309 PHYMOD_IF_ERR_RETURN 9310 (WRITE_FURIA_PMA_PMD_REG(pa,\ 9311 RX_ANA_REGS_anaRxControl3_Adr,\ 9312 an_rx_ctrl3.data)); 9313 break; 9314 case FURIA_HCD_LINK_KR4_PMD_LOCK: 9315 PHYMOD_IF_ERR_RETURN 9316 (READ_FURIA_PMA_PMD_REG(pa,\ 9317 RX_ANA_REGS_anaRxControl3_Adr,\ 9318 &an_rx_ctrl3.data)); 9319 an_rx_ctrl3.fields.link_en_force_sm = 0; 9320 an_rx_ctrl3.fields.use_kr_block_lock_sm = 0; 9321 an_rx_ctrl3.fields.use_kr4_block_lock_sm = 0; 9322 an_rx_ctrl3.fields.use_kr4_pmd_lock_sm = 1; 9323 9324 PHYMOD_IF_ERR_RETURN 9325 (WRITE_FURIA_PMA_PMD_REG(pa,\ 9326 RX_ANA_REGS_anaRxControl3_Adr,\ 9327 an_rx_ctrl3.data)); 9328 break; 9329 case FURIA_HCD_LINK_EXT_PCS: 9330 PHYMOD_IF_ERR_RETURN 9331 (READ_FURIA_PMA_PMD_REG(pa,\ 9332 RX_ANA_REGS_anaRxControl3_Adr,\ 9333 &an_rx_ctrl3.data)); 9334 an_rx_ctrl3.fields.link_en_force_sm = 0; 9335 an_rx_ctrl3.fields.use_kr_block_lock_sm = 0; 9336 an_rx_ctrl3.fields.use_kr4_block_lock_sm = 0; 9337 an_rx_ctrl3.fields.use_kr4_pmd_lock_sm = 0; 9338 9339 PHYMOD_IF_ERR_RETURN 9340 (WRITE_FURIA_PMA_PMD_REG(pa,\ 9341 RX_ANA_REGS_anaRxControl3_Adr,\ 9342 an_rx_ctrl3.data)); 9343 PHYMOD_IF_ERR_RETURN 9344 (READ_FURIA_PMA_PMD_REG(pa,\ 9345 FUR_MISC_CTRL_furia_qsfi_misc_Adr,\ 9346 &qsfi_misc.data)); 9347 qsfi_misc.fields.ext_pcs_link_en = 1; 9348 PHYMOD_IF_ERR_RETURN 9349 (WRITE_FURIA_PMA_PMD_REG(pa,\ 9350 FUR_MISC_CTRL_furia_qsfi_misc_Adr,\ 9351 qsfi_misc.data)); 9352 break; 9353 default: 9354 PHYMOD_IF_ERR_RETURN 9355 (READ_FURIA_PMA_PMD_REG(pa,\ 9356 RX_ANA_REGS_anaRxControl3_Adr,\ 9357 &an_rx_ctrl3.data)); 9358 an_rx_ctrl3.fields.link_en_force_sm = 0; 9359 an_rx_ctrl3.fields.use_kr_block_lock_sm = 0; 9360 an_rx_ctrl3.fields.use_kr4_block_lock_sm = 0; 9361 an_rx_ctrl3.fields.use_kr4_pmd_lock_sm = 0; 9362 9363 PHYMOD_IF_ERR_RETURN 9364 (WRITE_FURIA_PMA_PMD_REG(pa,\ 9365 RX_ANA_REGS_anaRxControl3_Adr,\ 9366 an_rx_ctrl3.data)); 9367 PHYMOD_IF_ERR_RETURN 9368 (READ_FURIA_PMA_PMD_REG(pa,\ 9369 FUR_MISC_CTRL_furia_qsfi_misc_Adr,\ 9370 &qsfi_misc.data)); 9371 qsfi_misc.fields.ext_pcs_link_en = 0; 9372 PHYMOD_IF_ERR_RETURN 9373 (WRITE_FURIA_PMA_PMD_REG(pa,\ 9374 FUR_MISC_CTRL_furia_qsfi_misc_Adr,\ 9375 qsfi_misc.data)); 9376 break; 9377 } 9378 9379 } 9380 if (lane_map == 0xF) { 9381 break; 9382 } 9383 } 9384 /* Set the slice register with default values */ 9385 PHYMOD_IF_ERR_RETURN 9386 (WRITE_FURIA_SLICE_REG(pa, 0, 1, 0)); 9387 9388 return PHYMOD_E_NONE; 9389 } 9390 9391 int _furia_core_cfg_tx_set(const phymod_access_t *pa,const phymod_tx_t* tx) 9392 { 9393 phymod_tx_t tmp_tx; 9394 PHYMOD_MEMSET(&tmp_tx,0x0,sizeof(phymod_tx_t)); 9395 PHYMOD_IF_ERR_RETURN( 9396 furia_tx_get(pa,&tmp_tx)); 9397 if (!(((tx->main & 0x7F) == 0x7F) && ((tx->pre & 0x7F) == 0x7F) && ((tx->post & 0x7F) == 0x7F))) { 9398 tmp_tx.pre = tx->pre; 9399 tmp_tx.main = tx->main; 9400 tmp_tx.post = tx->post; 9401 9402 } 9403 tmp_tx.amp = tx->amp; 9404 PHYMOD_IF_ERR_RETURN( 9405 furia_tx_set(pa,&tmp_tx)); 9406 return PHYMOD_E_NONE; 9407 } 9408 int _furia_core_cfg_polarity_set(const phymod_access_t *pa, uint32_t rx_polarity, uint32_t tx_polarity) 9409 { 9410 uint32_t chip_id = 0; 9411 int num_lanes = 0; 9412 int lane_index = 0; 9413 phymod_access_t pa_copy; 9414 uint32_t rx_lane_polarity = 0; 9415 uint32_t tx_lane_polarity = 0; 9416 9417 if (rx_polarity == 0xFFFF && tx_polarity == 0xFFFF) { 9418 return PHYMOD_E_NONE; 9419 } 9420 9421 PHYMOD_MEMCPY(&pa_copy, pa, sizeof(phymod_access_t)); 9422 9423 /* Get the chip id */ 9424 chip_id = _furia_get_chip_id(pa); 9425 9426 FURIA_GET_NUM_LANES(chip_id, num_lanes); 9427 9428 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 9429 if (((pa->lane_mask >> lane_index) & 1) == 0x1) { 9430 pa_copy.lane_mask = (1 << lane_index); 9431 pa_copy.flags &= ~(1 << PHYMOD_INTERFACE_SIDE_SHIFT); 9432 PHYMOD_IF_ERR_RETURN 9433 (furia_tx_rx_polarity_get(&pa_copy, &tx_lane_polarity, &rx_lane_polarity)); 9434 if (rx_polarity != 0xFFFF) { 9435 rx_lane_polarity = (rx_polarity >> lane_index) & 0x1; 9436 } 9437 if (tx_polarity != 0xFFFF) { 9438 tx_lane_polarity = (tx_polarity >> lane_index) & 0x1; 9439 } 9440 PHYMOD_IF_ERR_RETURN 9441 (furia_tx_rx_polarity_set(&pa_copy, tx_lane_polarity, rx_lane_polarity)); 9442 if (FURIA_IS_SIMPLEX(chip_id)) { 9443 pa_copy.flags |= (1 << PHYMOD_INTERFACE_SIDE_SHIFT); 9444 PHYMOD_IF_ERR_RETURN 9445 (furia_tx_rx_polarity_set(&pa_copy, tx_lane_polarity, rx_lane_polarity)); 9446 pa_copy.flags &= ~(1 << PHYMOD_INTERFACE_SIDE_SHIFT); 9447 } 9448 } 9449 } 9450 return PHYMOD_E_NONE; 9451 } 9452 9453 9454 int furia_firmware_core_config_set(const phymod_access_t* pa, phymod_firmware_core_config_t fw_config) 9455 { 9456 return PHYMOD_E_NONE; 9457 } 9458 9459 9460 int furia_firmware_core_config_get(const phymod_access_t* pa, phymod_firmware_core_config_t* fw_config) 9461 { 9462 return PHYMOD_E_NONE; 9463 } 9464 9465 int furia_firmware_lane_config_set(const phymod_access_t* pa, phymod_firmware_lane_config_t fw_config) 9466 { 9467 int lane_map = 0; 9468 int pkg_side = 0; 9469 int wr_lane = 0; 9470 int sys_en = 0; 9471 int rd_lane = 0; 9472 uint32_t chip_id = 0; 9473 int num_lanes = 0; 9474 int lane_index = 0; 9475 uint32_t acc_flags = 0; 9476 const FURIA_PKG_LANE_CFG_t* pkg_ln_des = NULL; 9477 FUR_GEN_CNTRLS_gpreg13_t fw_ln_config; 9478 uint16_t die_lane_number = 0; 9479 FUR_GEN_CNTRLS_FIRMWARE_ENABLE_t fw_enable_reg; 9480 struct falcon_furia_uc_lane_config_st furia_ln_config; 9481 LINE_FALCON_IF_SOFT_MODE0_t line_falcon_soft_mode0; 9482 LINE_FALCON_IF_C_AND_R_CNTL_t line_falcon_c_and_r_ctrl; 9483 SYS_FALCON_IF_SOFT_MODE0_t sys_falcon_soft_mode0; 9484 SYS_FALCON_IF_C_AND_R_CNTL_t sys_falcon_c_and_r_ctrl; 9485 CKRST_CTRL_RPTR_LANE_RESET_N_PWRDN_PIN_KILL_CONTROL_t pwrdn_pin_kill_ctrl; 9486 PHYMOD_MEMSET(&line_falcon_soft_mode0, 0 , sizeof(LINE_FALCON_IF_SOFT_MODE0_t)); 9487 PHYMOD_MEMSET(&line_falcon_c_and_r_ctrl, 0 , sizeof(LINE_FALCON_IF_C_AND_R_CNTL_t)); 9488 PHYMOD_MEMSET(&sys_falcon_soft_mode0, 0 , sizeof(SYS_FALCON_IF_SOFT_MODE0_t)); 9489 PHYMOD_MEMSET(&sys_falcon_c_and_r_ctrl, 0 , sizeof(SYS_FALCON_IF_C_AND_R_CNTL_t)); 9490 PHYMOD_MEMSET(&fw_ln_config, 0 , sizeof(FUR_GEN_CNTRLS_gpreg13_t)); 9491 PHYMOD_MEMSET(&fw_enable_reg, 0 , sizeof(FUR_GEN_CNTRLS_FIRMWARE_ENABLE_t)); 9492 PHYMOD_MEMSET(&furia_ln_config, 0 , sizeof(struct falcon_furia_uc_lane_config_st)); 9493 PHYMOD_MEMSET(&pwrdn_pin_kill_ctrl, 0 , sizeof(CKRST_CTRL_RPTR_LANE_RESET_N_PWRDN_PIN_KILL_CONTROL_t)); 9494 9495 /* Get the lane map from phymod access */ 9496 lane_map = PHYMOD_ACC_LANE_MASK(pa); 9497 acc_flags = PHYMOD_ACC_FLAGS(pa); 9498 FURIA_GET_IF_SIDE(acc_flags, pkg_side); 9499 /* Get the chip id */ 9500 chip_id = _furia_get_chip_id(pa); 9501 FURIA_GET_NUM_LANES(chip_id, num_lanes); 9502 9503 /* update structure members */ 9504 furia_ln_config.field.lane_cfg_from_pcs = fw_config.LaneConfigFromPCS; 9505 furia_ln_config.field.an_enabled = fw_config.AnEnabled; 9506 furia_ln_config.field.dfe_on = fw_config.DfeOn; 9507 furia_ln_config.field.force_brdfe_on = fw_config.ForceBrDfe; 9508 furia_ln_config.field.dfe_lp_mode = fw_config.LpDfeOn; 9509 furia_ln_config.field.media_type = fw_config.MediaType; 9510 furia_ln_config.field.unreliable_los = fw_config.UnreliableLos; 9511 furia_ln_config.field.scrambling_dis = fw_config.ScramblingDisable; 9512 9513 if ((furia_ln_config.field.dfe_on == 0xF) && 9514 (furia_ln_config.field.dfe_lp_mode == 0xF) && 9515 (furia_ln_config.field.force_brdfe_on == 0xF)) { 9516 PHYMOD_IF_ERR_RETURN 9517 (READ_FURIA_PMA_PMD_REG(pa,\ 9518 FUR_GEN_CNTRLS_gpreg13_Adr,\ 9519 &fw_ln_config.data)); 9520 fw_ln_config.fields.lane_cfg_override_en = 0; 9521 PHYMOD_IF_ERR_RETURN 9522 (WRITE_FURIA_PMA_PMD_REG(pa,\ 9523 FUR_GEN_CNTRLS_gpreg13_Adr,\ 9524 fw_ln_config.data)); 9525 PHYMOD_IF_ERR_RETURN( 9526 _furia_fw_enable(pa)); 9527 return PHYMOD_E_NONE; 9528 } 9529 9530 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 9531 if (((lane_map >> lane_index) & 1) == 0x1) { 9532 pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 1); 9533 PHYMOD_NULL_CHECK(pkg_ln_des); 9534 if(pkg_side == SIDE_A) { 9535 sys_en = pkg_ln_des->sideA; 9536 } else { 9537 sys_en = pkg_ln_des->sideB; 9538 } 9539 wr_lane = pkg_ln_des->slice_wr_val; 9540 rd_lane = pkg_ln_des->slice_rd_val; 9541 die_lane_number = pkg_ln_des->die_lane_num; 9542 /* Program the slice register */ 9543 PHYMOD_IF_ERR_RETURN 9544 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 9545 9546 PHYMOD_IF_ERR_RETURN 9547 (READ_FURIA_PMA_PMD_REG(pa,\ 9548 FUR_GEN_CNTRLS_gpreg13_Adr,\ 9549 &fw_ln_config.data)); 9550 fw_ln_config.fields.lane_cfg_override_en = 1; 9551 PHYMOD_IF_ERR_RETURN 9552 (WRITE_FURIA_PMA_PMD_REG(pa,\ 9553 FUR_GEN_CNTRLS_gpreg13_Adr,\ 9554 fw_ln_config.data)); 9555 PHYMOD_IF_ERR_RETURN( 9556 _furia_fw_enable(pa)); 9557 9558 /* Keep the lane under reset */ 9559 if (sys_en == SYS) { 9560 PHYMOD_IF_ERR_RETURN 9561 (READ_FURIA_PMA_PMD_REG(pa,\ 9562 SYS_FALCON_IF_soft_mode0_Adr,\ 9563 &sys_falcon_soft_mode0.data)); 9564 sys_falcon_soft_mode0.fields.software_mode_pmd_ln_dp_h_rstb &= ~(1 << die_lane_number); 9565 sys_falcon_soft_mode0.fields.software_mode_pmd_ln_dp_h_rstb |= (1 << die_lane_number); 9566 PHYMOD_IF_ERR_RETURN 9567 (WRITE_FURIA_PMA_PMD_REG(pa,\ 9568 SYS_FALCON_IF_soft_mode0_Adr,\ 9569 sys_falcon_soft_mode0.data)); 9570 PHYMOD_IF_ERR_RETURN 9571 (READ_FURIA_PMA_PMD_REG(pa,\ 9572 SYS_FALCON_IF_c_and_r_cntl_Adr,\ 9573 &sys_falcon_c_and_r_ctrl.data)); 9574 sys_falcon_c_and_r_ctrl.fields.pmd_ln_dp_h_rstb &= ~(1 << die_lane_number); 9575 PHYMOD_IF_ERR_RETURN 9576 (WRITE_FURIA_PMA_PMD_REG(pa,\ 9577 SYS_FALCON_IF_c_and_r_cntl_Adr,\ 9578 sys_falcon_c_and_r_ctrl.data)); 9579 } else { 9580 PHYMOD_IF_ERR_RETURN 9581 (READ_FURIA_PMA_PMD_REG(pa,\ 9582 LINE_FALCON_IF_soft_mode0_Adr,\ 9583 &line_falcon_soft_mode0.data)); 9584 line_falcon_soft_mode0.fields.software_mode_pmd_ln_dp_h_rstb &= ~(1 << die_lane_number); 9585 line_falcon_soft_mode0.fields.software_mode_pmd_ln_dp_h_rstb |= (1 << die_lane_number); 9586 PHYMOD_IF_ERR_RETURN 9587 (WRITE_FURIA_PMA_PMD_REG(pa,\ 9588 LINE_FALCON_IF_soft_mode0_Adr,\ 9589 line_falcon_soft_mode0.data)); 9590 PHYMOD_IF_ERR_RETURN 9591 (READ_FURIA_PMA_PMD_REG(pa,\ 9592 LINE_FALCON_IF_c_and_r_cntl_Adr,\ 9593 &line_falcon_c_and_r_ctrl.data)); 9594 line_falcon_c_and_r_ctrl.fields.pmd_ln_dp_h_rstb &= ~(1 << die_lane_number); 9595 PHYMOD_IF_ERR_RETURN 9596 (WRITE_FURIA_PMA_PMD_REG(pa,\ 9597 LINE_FALCON_IF_c_and_r_cntl_Adr,\ 9598 line_falcon_c_and_r_ctrl.data)); 9599 } 9600 PHYMOD_IF_ERR_RETURN 9601 (READ_FURIA_PMA_PMD_REG(pa,\ 9602 CKRST_CTRL_RPTR_LANE_RESET_N_PWRDN_PIN_KILL_CONTROL_Adr,\ 9603 &pwrdn_pin_kill_ctrl.data)); 9604 pwrdn_pin_kill_ctrl.fields.pmd_ln_dp_h_rstb_pkill = 0; 9605 PHYMOD_IF_ERR_RETURN 9606 (WRITE_FURIA_PMA_PMD_REG(pa,\ 9607 CKRST_CTRL_RPTR_LANE_RESET_N_PWRDN_PIN_KILL_CONTROL_Adr,\ 9608 pwrdn_pin_kill_ctrl.data)); 9609 9610 PHYMOD_IF_ERR_RETURN 9611 (falcon_furia_set_uc_lane_cfg(pa, furia_ln_config)); 9612 9613 /* Bring the lane out from reset */ 9614 if (sys_en == SYS) { 9615 PHYMOD_IF_ERR_RETURN 9616 (READ_FURIA_PMA_PMD_REG(pa,\ 9617 SYS_FALCON_IF_soft_mode0_Adr,\ 9618 &sys_falcon_soft_mode0.data)); 9619 sys_falcon_soft_mode0.fields.software_mode_pmd_ln_dp_h_rstb &= ~(1 << die_lane_number); 9620 PHYMOD_IF_ERR_RETURN 9621 (WRITE_FURIA_PMA_PMD_REG(pa,\ 9622 SYS_FALCON_IF_soft_mode0_Adr,\ 9623 sys_falcon_soft_mode0.data)); 9624 PHYMOD_IF_ERR_RETURN 9625 (READ_FURIA_PMA_PMD_REG(pa,\ 9626 SYS_FALCON_IF_c_and_r_cntl_Adr,\ 9627 &sys_falcon_c_and_r_ctrl.data)); 9628 sys_falcon_c_and_r_ctrl.fields.pmd_ln_dp_h_rstb &= ~(1 << die_lane_number); 9629 sys_falcon_c_and_r_ctrl.fields.pmd_ln_dp_h_rstb |= (1 << die_lane_number); 9630 PHYMOD_IF_ERR_RETURN 9631 (WRITE_FURIA_PMA_PMD_REG(pa,\ 9632 SYS_FALCON_IF_c_and_r_cntl_Adr,\ 9633 sys_falcon_c_and_r_ctrl.data)); 9634 } else { 9635 PHYMOD_IF_ERR_RETURN 9636 (READ_FURIA_PMA_PMD_REG(pa,\ 9637 LINE_FALCON_IF_soft_mode0_Adr,\ 9638 &line_falcon_soft_mode0.data)); 9639 line_falcon_soft_mode0.fields.software_mode_pmd_ln_dp_h_rstb &= ~(1 << die_lane_number); 9640 PHYMOD_IF_ERR_RETURN 9641 (WRITE_FURIA_PMA_PMD_REG(pa,\ 9642 LINE_FALCON_IF_soft_mode0_Adr,\ 9643 line_falcon_soft_mode0.data)); 9644 PHYMOD_IF_ERR_RETURN 9645 (READ_FURIA_PMA_PMD_REG(pa,\ 9646 LINE_FALCON_IF_c_and_r_cntl_Adr,\ 9647 &line_falcon_c_and_r_ctrl.data)); 9648 line_falcon_c_and_r_ctrl.fields.pmd_ln_dp_h_rstb &= ~(1 << die_lane_number); 9649 line_falcon_c_and_r_ctrl.fields.pmd_ln_dp_h_rstb |= (1 << die_lane_number); 9650 PHYMOD_IF_ERR_RETURN 9651 (WRITE_FURIA_PMA_PMD_REG(pa,\ 9652 LINE_FALCON_IF_c_and_r_cntl_Adr,\ 9653 line_falcon_c_and_r_ctrl.data)); 9654 } 9655 PHYMOD_IF_ERR_RETURN 9656 (READ_FURIA_PMA_PMD_REG(pa,\ 9657 CKRST_CTRL_RPTR_LANE_RESET_N_PWRDN_PIN_KILL_CONTROL_Adr,\ 9658 &pwrdn_pin_kill_ctrl.data)); 9659 pwrdn_pin_kill_ctrl.fields.pmd_ln_dp_h_rstb_pkill = 1; 9660 PHYMOD_IF_ERR_RETURN 9661 (WRITE_FURIA_PMA_PMD_REG(pa,\ 9662 CKRST_CTRL_RPTR_LANE_RESET_N_PWRDN_PIN_KILL_CONTROL_Adr,\ 9663 pwrdn_pin_kill_ctrl.data)); 9664 PHYMOD_IF_ERR_RETURN( 9665 _furia_fw_enable(pa)); 9666 } 9667 } 9668 /* Set the slice register with default values */ 9669 PHYMOD_IF_ERR_RETURN 9670 (WRITE_FURIA_SLICE_REG(pa, 0, 1, 0)); 9671 return PHYMOD_E_NONE; 9672 } 9673 9674 9675 int furia_firmware_lane_config_get(const phymod_access_t* pa, phymod_firmware_lane_config_t* fw_config) 9676 { 9677 int lane_map = 0; 9678 int pkg_side = 0; 9679 int wr_lane = 0; 9680 int sys_en = 0; 9681 int rd_lane = 0; 9682 uint32_t chip_id = 0; 9683 int num_lanes = 0; 9684 int lane_index = 0; 9685 uint32_t acc_flags = 0; 9686 const FURIA_PKG_LANE_CFG_t* pkg_ln_des = NULL; 9687 struct falcon_furia_uc_lane_config_st furia_ln_config; 9688 PHYMOD_MEMSET(&furia_ln_config, 0 , sizeof(struct falcon_furia_uc_lane_config_st)); 9689 9690 /* Get the lane map from phymod access */ 9691 lane_map = PHYMOD_ACC_LANE_MASK(pa); 9692 acc_flags = PHYMOD_ACC_FLAGS(pa); 9693 FURIA_GET_IF_SIDE(acc_flags, pkg_side); 9694 9695 9696 /* Get the chip id */ 9697 chip_id = _furia_get_chip_id(pa); 9698 FURIA_GET_NUM_LANES(chip_id, num_lanes); 9699 9700 9701 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 9702 if (((lane_map >> lane_index) & 1) == 0x1) { 9703 pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 1); 9704 PHYMOD_NULL_CHECK(pkg_ln_des); 9705 wr_lane = pkg_ln_des->slice_wr_val; 9706 rd_lane = pkg_ln_des->slice_rd_val; 9707 if(pkg_side == SIDE_A) { 9708 sys_en = pkg_ln_des->sideA; 9709 } else { 9710 sys_en = pkg_ln_des->sideB; 9711 } 9712 9713 /* Program the slice register */ 9714 PHYMOD_IF_ERR_RETURN 9715 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 9716 9717 PHYMOD_IF_ERR_RETURN 9718 (falcon_furia_get_uc_lane_cfg(pa, &furia_ln_config)); 9719 9720 fw_config->LaneConfigFromPCS = furia_ln_config.field.lane_cfg_from_pcs; 9721 fw_config->AnEnabled = furia_ln_config.field.an_enabled; 9722 fw_config->DfeOn = furia_ln_config.field.dfe_on; 9723 fw_config->ForceBrDfe = furia_ln_config.field.force_brdfe_on; 9724 fw_config->LpDfeOn = furia_ln_config.field.dfe_lp_mode; 9725 fw_config->MediaType = furia_ln_config.field.media_type; 9726 fw_config->UnreliableLos = furia_ln_config.field.unreliable_los; 9727 fw_config->ScramblingDisable = furia_ln_config.field.scrambling_dis; 9728 break; 9729 } 9730 } 9731 /* Set the slice register with default values */ 9732 PHYMOD_IF_ERR_RETURN 9733 (WRITE_FURIA_SLICE_REG(pa, 0, 1, 0)); 9734 return PHYMOD_E_NONE; 9735 } 9736 9737 int _furia_ber_proj_lane_speed_get(phymod_phy_inf_config_t *config, uint32_t *speed) 9738 { 9739 if (config->data_rate == SPEED_100G || config->data_rate == SPEED_106G || 9740 config->data_rate == SPEED_25G || config->data_rate == SPEED_27G) { 9741 *speed = 25781250; 9742 if ( config->interface_type == phymodInterfaceOTN ) { 9743 *speed = 27952500; 9744 } else if (PHYMOD_INTF_MODES_HIGIG_GET(config)) { 9745 *speed = 27343750; 9746 } 9747 } else if ((config->data_rate == SPEED_40G || config->data_rate == SPEED_42G)) { 9748 *speed = 20625000; 9749 if (PHYMOD_INTF_MODES_HIGIG_GET(config)) { 9750 *speed = 21875000; 9751 } 9752 } else if ((config->data_rate == SPEED_20G || config->data_rate == SPEED_21G)) { 9753 *speed = 20625000; 9754 if (PHYMOD_INTF_MODES_HIGIG_GET(config)) { 9755 *speed = 21875000; 9756 } 9757 } else { 9758 *speed = 10312500; 9759 if ( config->interface_type == phymodInterfaceOTN ) { 9760 *speed = 10937500; 9761 } else if (PHYMOD_INTF_MODES_HIGIG_GET(config)) { 9762 *speed = 11180000; 9763 } 9764 } 9765 9766 return PHYMOD_E_NONE; 9767 } 9768 9769 int furia_ber_proj(const phymod_access_t *pa, const phymod_phy_eyescan_options_t* eyescan_options) 9770 { 9771 int lane_map = 0; 9772 int pkg_side = 0; 9773 int wr_lane = 0; 9774 int sys_en = 0; 9775 int rd_lane = 0; 9776 uint32_t chip_id = 0; 9777 int num_lanes = 0; 9778 int lane_index = 0; 9779 uint32_t acc_flags = 0; 9780 phymod_access_t l_pa; 9781 const FURIA_PKG_LANE_CFG_t* pkg_ln_des = NULL; 9782 #ifdef SERDES_API_FLOATING_POINT 9783 phymod_interface_t intf = 0; 9784 phymod_ref_clk_t ref_clk; 9785 uint32_t interface_modes = 0; 9786 uint32_t data_rate = 0; 9787 phymod_phy_inf_config_t config; 9788 uint32_t speed; 9789 uint16_t lane_map_saved = 0; 9790 USR_DOUBLE speedD; 9791 PHYMOD_MEMSET(&config, 0, sizeof(phymod_phy_inf_config_t)); 9792 #endif 9793 PHYMOD_MEMCPY(&l_pa, pa, sizeof(phymod_access_t)); 9794 /* Get the lane map from phymod access */ 9795 lane_map = PHYMOD_ACC_LANE_MASK(pa); 9796 #ifdef SERDES_API_FLOATING_POINT 9797 lane_map_saved = lane_map ; 9798 #endif 9799 acc_flags = PHYMOD_ACC_FLAGS(pa); 9800 FURIA_GET_IF_SIDE(acc_flags, pkg_side); 9801 9802 /* Get the chip id */ 9803 chip_id = _furia_get_chip_id(pa); 9804 num_lanes = FURIA_IS_SIMPLEX(chip_id) ? 8 : 4; 9805 9806 PHYMOD_IF_ERR_RETURN 9807 (falcon_furia_display_core_state_hdr(pa)); 9808 PHYMOD_IF_ERR_RETURN 9809 (falcon_furia_display_core_state_line(pa)); 9810 9811 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 9812 if (((lane_map >> lane_index) & 1) == 0x1) { 9813 PHYMOD_DIAG_OUT((" Eye margin projection for lane = %d\n", lane_index)); 9814 /* Configure Tx side(SIDE_A) first*/ 9815 pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 1); 9816 PHYMOD_NULL_CHECK(pkg_ln_des); 9817 if(pkg_side == SIDE_A) { 9818 sys_en = pkg_ln_des->sideA; 9819 } else { 9820 sys_en = pkg_ln_des->sideB; 9821 } 9822 9823 wr_lane = pkg_ln_des->slice_wr_val; 9824 rd_lane = pkg_ln_des->slice_rd_val; 9825 9826 /* Program the slice register */ 9827 PHYMOD_IF_ERR_RETURN 9828 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 9829 9830 if (FURIA_IF_RX_SIDE(chip_id, pkg_side)) { 9831 PHYMOD_IF_ERR_RETURN 9832 (falcon_furia_display_lane_state_hdr(pa)); 9833 PHYMOD_IF_ERR_RETURN 9834 (falcon_furia_display_lane_state(pa)); 9835 #ifdef SERDES_API_FLOATING_POINT 9836 l_pa.lane_mask = 0x1 << lane_index; 9837 PHYMOD_IF_ERR_RETURN 9838 (furia_get_config_mode(&l_pa, &intf, &data_rate, &ref_clk, &interface_modes,&config, lane_map_saved )); 9839 config.interface_type = intf; 9840 config.data_rate = data_rate; 9841 config.interface_modes = interface_modes; 9842 config.ref_clock = ref_clk; 9843 l_pa.lane_mask = 0x0; 9844 PHYMOD_IF_ERR_RETURN 9845 (_furia_ber_proj_lane_speed_get(&config, &speed)); 9846 speedD = speed * 1000.0; 9847 PHYMOD_IF_ERR_RETURN 9848 (falcon_furia_eye_margin_proj(pa, speedD, eyescan_options->ber_proj_scan_mode, 9849 eyescan_options->ber_proj_timer_cnt, 9850 eyescan_options->ber_proj_err_cnt)); 9851 #else 9852 PHYMOD_DIAG_OUT(("BER PROJ needs SERDES_API_FLOATING_POINT define to operate\n")); 9853 return PHYMOD_E_RESOURCE; 9854 #endif 9855 } 9856 } 9857 } 9858 return PHYMOD_E_NONE; 9859 } 9860 int furia_rx_adaptation_resume(const phymod_access_t *pa) 9861 { 9862 int lane_map = 0; 9863 int pkg_side = 0; 9864 int wr_lane = 0; 9865 int sys_en = 0; 9866 int rd_lane = 0; 9867 uint32_t chip_id = 0; 9868 int num_lanes = 0; 9869 int lane_index = 0; 9870 const FURIA_PKG_LANE_CFG_t* pkg_ln_des = NULL; 9871 uint32_t acc_flags = 0; 9872 9873 /* Get the lane map from phymod access */ 9874 lane_map = PHYMOD_ACC_LANE_MASK(pa); 9875 acc_flags = PHYMOD_ACC_FLAGS(pa); 9876 FURIA_GET_IF_SIDE(acc_flags, pkg_side); 9877 /* Get the chip id */ 9878 chip_id = _furia_get_chip_id(pa); 9879 num_lanes = FURIA_IS_SIMPLEX(chip_id) ? 8 : 4; 9880 9881 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 9882 if (((lane_map >> lane_index) & 1) == 0x1) { 9883 /* Configure Tx side(SIDE_A) first*/ 9884 pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 1); 9885 PHYMOD_NULL_CHECK(pkg_ln_des); 9886 wr_lane = FURIA_IF_BCAST_SET(chip_id, lane_map) ? BROADCAST : pkg_ln_des->slice_wr_val; 9887 rd_lane = pkg_ln_des->slice_rd_val; 9888 if(pkg_side == SIDE_A) { 9889 sys_en = pkg_ln_des->sideA; 9890 } else { 9891 sys_en = pkg_ln_des->sideB; 9892 } 9893 9894 /* Program the slice register */ 9895 PHYMOD_IF_ERR_RETURN 9896 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 9897 9898 /* Resume the rx adaption */ 9899 PHYMOD_IF_ERR_RETURN(falcon_furia_stop_rx_adaptation(pa, 0)); 9900 if (FURIA_IF_BCAST_SET(chip_id, lane_map)) { 9901 break; 9902 } 9903 } 9904 } 9905 /* Set the slice register with default values */ 9906 PHYMOD_IF_ERR_RETURN 9907 (WRITE_FURIA_SLICE_REG(pa, 0, 1, 0)); 9908 return PHYMOD_E_NONE; 9909 } 9910 9911 9912 int _furia_phy_short_channel_mode_set(const phymod_access_t *pa, uint32_t enable) 9913 { 9914 int lane_map = 0; 9915 int pkg_side = 0; 9916 int wr_lane = 0; 9917 int sys_en = 0; 9918 int rd_lane = 0; 9919 uint32_t chip_id = 0; 9920 int num_lanes = 0; 9921 int lane_index = 0; 9922 uint32_t acc_flags = 0; 9923 FUR_M0ACCESS_ADDR_MASTER_DRAM_MEM_ADD_TYPE_T mst_dram_add; 9924 FUR_M0ACCESS_DATA_MASTER_DRAM_RDATA_TYPE_T mst_dram_rdata1; 9925 FUR_M0ACCESS_DATA_MASTER_DRAM_WDATA_TYPE_T mst_dram_wdata1; 9926 FUR_M0ACCESS_ADDR_SLAVE_DRAM_MEM_ADD_TYPE_T slv_dram_add; 9927 FUR_M0ACCESS_DATA_SLAVE_DRAM_RDATA_TYPE_T slv_dram_rdata1; 9928 FUR_M0ACCESS_DATA_SLAVE_DRAM_WDATA_TYPE_T slv_dram_wdata1; 9929 9930 CKRST_CTRL_RPTR_LANE_CLK_RESET_N_POWERDOWN_CONTROL_t rst_pwdn_ctrl; 9931 const FURIA_PKG_LANE_CFG_t* pkg_ln_des = NULL; 9932 PHYMOD_MEMSET(&mst_dram_add,0,sizeof(FUR_M0ACCESS_ADDR_MASTER_DRAM_MEM_ADD_TYPE_T)); 9933 PHYMOD_MEMSET(&mst_dram_rdata1,0,sizeof(FUR_M0ACCESS_DATA_MASTER_DRAM_RDATA_TYPE_T)); 9934 PHYMOD_MEMSET(&mst_dram_wdata1,0,sizeof(FUR_M0ACCESS_DATA_MASTER_DRAM_WDATA_TYPE_T)); 9935 PHYMOD_MEMSET(&slv_dram_add,0,sizeof(FUR_M0ACCESS_ADDR_SLAVE_DRAM_MEM_ADD_TYPE_T)); 9936 PHYMOD_MEMSET(&slv_dram_rdata1,0,sizeof(FUR_M0ACCESS_DATA_SLAVE_DRAM_RDATA_TYPE_T)); 9937 PHYMOD_MEMSET(&slv_dram_wdata1,0,sizeof(FUR_M0ACCESS_DATA_SLAVE_DRAM_WDATA_TYPE_T)); 9938 PHYMOD_MEMSET(&rst_pwdn_ctrl, 0 , sizeof(CKRST_CTRL_RPTR_LANE_CLK_RESET_N_POWERDOWN_CONTROL_t)); 9939 /* Get the lane map from phymod access */ 9940 lane_map = PHYMOD_ACC_LANE_MASK(pa); 9941 acc_flags = PHYMOD_ACC_FLAGS(pa); 9942 FURIA_GET_IF_SIDE(acc_flags, pkg_side); 9943 /* Get the chip id */ 9944 chip_id = _furia_get_chip_id(pa); 9945 num_lanes = FURIA_IS_SIMPLEX(chip_id) ? 8 : 4; 9946 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 9947 if (((lane_map >> lane_index) & 1) == 0x1) { 9948 /* Configure Tx side(SIDE_A) first*/ 9949 pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 1); 9950 PHYMOD_NULL_CHECK(pkg_ln_des); 9951 if(pkg_side == SIDE_A) { 9952 sys_en = pkg_ln_des->sideA; 9953 } else { 9954 sys_en = pkg_ln_des->sideB; 9955 } 9956 9957 wr_lane = pkg_ln_des->slice_wr_val; 9958 rd_lane = pkg_ln_des->slice_rd_val; 9959 /* Program the slice register */ 9960 PHYMOD_IF_ERR_RETURN 9961 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 9962 #ifdef DEB 9963 printf(" %s,sys_en=%d wr_lan=%d rd_lan=%d pkg_ln_des->die_lane_num=%d\n",__FUNCTION__,sys_en,wr_lane,rd_lane,pkg_ln_des->die_lane_num); 9964 #endif 9965 9966 /* put the lane under dp reset */ 9967 PHYMOD_IF_ERR_RETURN 9968 (READ_FURIA_PMA_PMD_REG(pa,\ 9969 CKRST_CTRL_RPTR_LANE_CLK_RESET_N_POWERDOWN_CONTROL_Adr,\ 9970 &rst_pwdn_ctrl.data)); 9971 rst_pwdn_ctrl.fields.ln_dp_s_rstb = 0; 9972 9973 PHYMOD_IF_ERR_RETURN 9974 (WRITE_FURIA_PMA_PMD_REG(pa,\ 9975 CKRST_CTRL_RPTR_LANE_CLK_RESET_N_POWERDOWN_CONTROL_Adr,\ 9976 rst_pwdn_ctrl.data)); 9977 9978 if(sys_en){ 9979 PHYMOD_IF_ERR_RETURN 9980 (READ_FURIA_PMA_PMD_REG(pa,\ 9981 FUR_M0ACCESS_ADDR_MASTER_DRAM_MEM_ADD_ADR,\ 9982 &(mst_dram_add.data ))); 9983 mst_dram_add.fields.mst_dram_mem_add = 0x420 + (pkg_ln_des->die_lane_num * 0x130); 9984 PHYMOD_IF_ERR_RETURN 9985 (WRITE_FURIA_PMA_PMD_REG(pa,\ 9986 FUR_M0ACCESS_ADDR_MASTER_DRAM_MEM_ADD_ADR,\ 9987 mst_dram_add.data )); 9988 9989 PHYMOD_IF_ERR_RETURN 9990 (READ_FURIA_PMA_PMD_REG(pa,\ 9991 FUR_M0ACCESS_DATA_MASTER_DRAM_RDATA_ADR ,\ 9992 &(mst_dram_rdata1.data) )); 9993 enable ? (mst_dram_rdata1.data |= (0x1 << 11)): (mst_dram_rdata1.data &= (~(0x1 << 11))); 9994 mst_dram_add.fields.mst_dram_mem_add = 0x420 + (pkg_ln_des->die_lane_num * 0x130); 9995 PHYMOD_IF_ERR_RETURN 9996 (WRITE_FURIA_PMA_PMD_REG(pa,\ 9997 FUR_M0ACCESS_ADDR_MASTER_DRAM_MEM_ADD_ADR,\ 9998 mst_dram_add.data )); 9999 PHYMOD_IF_ERR_RETURN 10000 (WRITE_FURIA_PMA_PMD_REG(pa,\ 10001 FUR_M0ACCESS_DATA_MASTER_DRAM_WDATA_ADR,\ 10002 mst_dram_rdata1.data )); 10003 }else{ 10004 PHYMOD_IF_ERR_RETURN 10005 (READ_FURIA_PMA_PMD_REG(pa,\ 10006 FUR_M0ACCESS_ADDR_SLAVE_DRAM_MEM_ADD_ADR,\ 10007 &(slv_dram_add.data ))); 10008 slv_dram_add.fields.slv_dram_mem_add = 0x420 + (pkg_ln_des->die_lane_num * 0x130); 10009 PHYMOD_IF_ERR_RETURN 10010 (WRITE_FURIA_PMA_PMD_REG(pa,\ 10011 FUR_M0ACCESS_ADDR_SLAVE_DRAM_MEM_ADD_ADR,\ 10012 slv_dram_add.data )); 10013 10014 PHYMOD_IF_ERR_RETURN 10015 (READ_FURIA_PMA_PMD_REG(pa,\ 10016 FUR_M0ACCESS_DATA_SLAVE_DRAM_RDATA_ADR ,\ 10017 &(slv_dram_rdata1.data) )); 10018 enable ? (slv_dram_rdata1.data |= (0x1 << 11)): (slv_dram_rdata1.data &= (~(0x1 << 11))); 10019 slv_dram_add.fields.slv_dram_mem_add = 0x420 + (pkg_ln_des->die_lane_num * 0x130); 10020 PHYMOD_IF_ERR_RETURN 10021 (WRITE_FURIA_PMA_PMD_REG(pa,\ 10022 FUR_M0ACCESS_ADDR_SLAVE_DRAM_MEM_ADD_ADR,\ 10023 slv_dram_add.data )); 10024 10025 PHYMOD_IF_ERR_RETURN 10026 (WRITE_FURIA_PMA_PMD_REG(pa,\ 10027 FUR_M0ACCESS_DATA_SLAVE_DRAM_WDATA_ADR,\ 10028 slv_dram_rdata1.data )); 10029 10030 } 10031 10032 /* Release the lane under dp reset */ 10033 PHYMOD_IF_ERR_RETURN 10034 (READ_FURIA_PMA_PMD_REG(pa,\ 10035 CKRST_CTRL_RPTR_LANE_CLK_RESET_N_POWERDOWN_CONTROL_Adr,\ 10036 &rst_pwdn_ctrl.data)); 10037 rst_pwdn_ctrl.fields.ln_dp_s_rstb = 1; 10038 10039 PHYMOD_IF_ERR_RETURN 10040 (WRITE_FURIA_PMA_PMD_REG(pa,\ 10041 CKRST_CTRL_RPTR_LANE_CLK_RESET_N_POWERDOWN_CONTROL_Adr,\ 10042 rst_pwdn_ctrl.data)); 10043 10044 } 10045 } 10046 10047 /* Set the slice register to default */ 10048 PHYMOD_IF_ERR_RETURN 10049 (WRITE_FURIA_SLICE_REG(pa, 0, 1, 0)); 10050 return PHYMOD_E_NONE; 10051 } 10052 10053 int _furia_phy_short_channel_mode_get(const phymod_access_t *pa, uint32_t *enable, uint32_t *status) 10054 { 10055 int lane_map = 0; 10056 int pkg_side = 0; 10057 int wr_lane = 0; 10058 int sys_en = 0; 10059 int rd_lane = 0; 10060 uint32_t chip_id = 0; 10061 int num_lanes = 0; 10062 int lane_index = 0; 10063 uint32_t data; 10064 uint32_t acc_flags = 0; 10065 uint16_t lane_map_saved = 0; 10066 FUR_M0ACCESS_ADDR_MASTER_DRAM_MEM_ADD_TYPE_T mst_dram_add; 10067 FUR_M0ACCESS_DATA_MASTER_DRAM_RDATA_TYPE_T mst_dram_rdata1; 10068 FUR_M0ACCESS_ADDR_SLAVE_DRAM_MEM_ADD_TYPE_T slv_dram_add; 10069 FUR_M0ACCESS_DATA_SLAVE_DRAM_RDATA_TYPE_T slv_dram_rdata1; 10070 const FURIA_PKG_LANE_CFG_t* pkg_ln_des = NULL; 10071 phymod_interface_t intf; 10072 phymod_phy_inf_config_t config; 10073 phymod_ref_clk_t ref_clk; 10074 uint32_t interface_modes = 0; 10075 uint32_t data_rate = 0; 10076 /* Get the lane map from phymod access */ 10077 lane_map = PHYMOD_ACC_LANE_MASK(pa); 10078 lane_map_saved = lane_map ; 10079 acc_flags = PHYMOD_ACC_FLAGS(pa); 10080 FURIA_GET_IF_SIDE(acc_flags, pkg_side); 10081 PHYMOD_MEMSET(&config, 0, sizeof(phymod_phy_inf_config_t)); 10082 PHYMOD_MEMSET(&intf, 0, sizeof(phymod_interface_t)); 10083 PHYMOD_MEMSET(&mst_dram_add,0,sizeof(FUR_M0ACCESS_ADDR_MASTER_DRAM_MEM_ADD_TYPE_T)); 10084 PHYMOD_MEMSET(&mst_dram_rdata1,0,sizeof(FUR_M0ACCESS_DATA_MASTER_DRAM_RDATA_TYPE_T)); 10085 PHYMOD_MEMSET(&slv_dram_add,0,sizeof(FUR_M0ACCESS_ADDR_SLAVE_DRAM_MEM_ADD_TYPE_T)); 10086 PHYMOD_MEMSET(&slv_dram_rdata1,0,sizeof(FUR_M0ACCESS_DATA_SLAVE_DRAM_RDATA_TYPE_T)); 10087 *enable=1; 10088 *status=0; 10089 /* Get the chip id */ 10090 chip_id = _furia_get_chip_id(pa); 10091 num_lanes = FURIA_IS_SIMPLEX(chip_id) ? 8 : 4; 10092 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 10093 if (((lane_map >> lane_index) & 1) == 0x1) { 10094 /* Configure Tx side(SIDE_A) first*/ 10095 10096 pkg_ln_des = _furia_pkg_ln_des_lane_swap(chip_id, pa, lane_index, 1); 10097 PHYMOD_NULL_CHECK(pkg_ln_des); 10098 if(pkg_side == SIDE_A) { 10099 sys_en = pkg_ln_des->sideA; 10100 } else { 10101 sys_en = pkg_ln_des->sideB; 10102 } 10103 10104 wr_lane = pkg_ln_des->slice_wr_val; 10105 rd_lane = pkg_ln_des->slice_rd_val; 10106 10107 /* Program the slice register */ 10108 PHYMOD_IF_ERR_RETURN 10109 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 10110 #ifdef DEB 10111 printf(" %s,sys_en=%d wr_lan=%d rd_lan=%d pkg_ln_des->die_lane_num=%d\n",__FUNCTION__,sys_en,wr_lane,rd_lane,pkg_ln_des->die_lane_num); 10112 #endif 10113 if(sys_en){ 10114 PHYMOD_IF_ERR_RETURN 10115 (READ_FURIA_PMA_PMD_REG(pa,\ 10116 FUR_M0ACCESS_ADDR_MASTER_DRAM_MEM_ADD_ADR,\ 10117 &(mst_dram_add.data ))); 10118 mst_dram_add.fields.mst_dram_mem_add = 0x420 + (pkg_ln_des->die_lane_num * 0x130); 10119 PHYMOD_IF_ERR_RETURN 10120 (WRITE_FURIA_PMA_PMD_REG(pa,\ 10121 FUR_M0ACCESS_ADDR_MASTER_DRAM_MEM_ADD_ADR,\ 10122 mst_dram_add.data )); 10123 PHYMOD_IF_ERR_RETURN 10124 (READ_FURIA_PMA_PMD_REG(pa,\ 10125 FUR_M0ACCESS_DATA_MASTER_DRAM_RDATA_ADR ,\ 10126 &(mst_dram_rdata1.data) )); 10127 *enable &= ((mst_dram_rdata1.data >> 11) & 0x1); 10128 #ifdef DEB 10129 printf("%s short channel enable sys side= %d\n",__FUNCTION__,*enable); 10130 #endif 10131 }else { 10132 PHYMOD_IF_ERR_RETURN 10133 (READ_FURIA_PMA_PMD_REG(pa,\ 10134 FUR_M0ACCESS_ADDR_SLAVE_DRAM_MEM_ADD_ADR,\ 10135 &(slv_dram_add.data ))); 10136 slv_dram_add.fields.slv_dram_mem_add = 0x420 + (pkg_ln_des->die_lane_num * 0x130); 10137 PHYMOD_IF_ERR_RETURN 10138 (WRITE_FURIA_PMA_PMD_REG(pa,\ 10139 FUR_M0ACCESS_ADDR_SLAVE_DRAM_MEM_ADD_ADR,\ 10140 slv_dram_add.data )); 10141 PHYMOD_IF_ERR_RETURN 10142 (READ_FURIA_PMA_PMD_REG(pa,\ 10143 FUR_M0ACCESS_DATA_SLAVE_DRAM_RDATA_ADR ,\ 10144 &(slv_dram_rdata1.data) )); 10145 *enable &= ((slv_dram_rdata1.data >> 11) & 0x1); 10146 #ifdef DEB 10147 printf("%s short channel enable line side: =%d\n",__FUNCTION__,*enable); 10148 #endif 10149 } 10150 10151 PHYMOD_IF_ERR_RETURN 10152 (furia_get_config_mode(pa, &intf, &data_rate, &ref_clk, &interface_modes,&config, lane_map_saved)); 10153 #ifdef DEB 10154 printf("%s intf=%d\n",__FUNCTION__,intf); 10155 #endif 10156 if(intf == phymodInterfaceCAUI4 || intf == phymodInterfaceCAUI4_C2C || 10157 intf == phymodInterfaceCAUI || intf == phymodInterfaceCAUI4_C2M){ 10158 /* Program the slice register */ 10159 PHYMOD_IF_ERR_RETURN 10160 (WRITE_FURIA_SLICE_REG(pa, sys_en, wr_lane, rd_lane)); 10161 PHYMOD_IF_ERR_RETURN 10162 (READ_FURIA_PMA_PMD_REG(pa,\ 10163 FUR_AMS_RX_RX_CNTRL0_Adr,\ 10164 &data)); 10165 *status = ((data & (1<<9)) >> 9); 10166 10167 #ifdef DEB 10168 printf("%s short channel reg 0xd0c0 data=0x%x\n",__FUNCTION__,data); 10169 #endif 10170 } 10171 10172 10173 } 10174 } 10175 /* Set the slice register to default */ 10176 PHYMOD_IF_ERR_RETURN 10177 (WRITE_FURIA_SLICE_REG(pa, 0, 1, 0)); 10178 return PHYMOD_E_NONE; 10179 } 10180