quadra28.c (33827B)
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 * 12 * 13 * 14 * $Copyright: 15 * All Rights Reserved.$ 16 * 17 * File: quadra28.c 18 * Purpose: tier2 phymod support for Broadcom 40G Quadra28 phy 19 * note: 20 * Specifications: 21 22 * Repeater, retimer operation. 23 24 * Supports the following data speeds: 25 * 1.25 Gbps line rate (1 GbE data rate, 8x oversampled over 10 Gbps line rate) 26 * 10.3125 Gbps line rate (10 GbE data rate) 27 * 11.5 Gpbs line rate (for backplane application, proprietary data rate) 28 * 410.3125 Gbps line rate (40 GbE data rate) 29 * 30 * Supports the following line-side connections: 31 * 1 GbE and 10 GbE SFP+ SR and LR optical modules 32 * 40 GbE QSFP SR4 and LR4 optical modules 33 * 1 GbE and 10 GbE SFP+ CR (CX1) copper cable 34 * 40 GbE QSFP CR4 copper cable 35 * 10 GbE KR, 11.5 Gbps line rate and 40 GbE KR4 backplanes 36 * 37 * Operates with the following reference clocks: 38 * Single 156.25 MHz differential clock for 1.25 Gbps, 10.3125 Gpbs and 11.5 Gbps 39 * line rates 40 * 41 * Supports autonegotiation as follows: 42 * Clause 73 only for starting Clause 72 and requesting FEC 43 * No speed resolution performed 44 * No Clause 73 in 11.5 Gbps line rate, only Clause 72 supported 45 * Clause 72 may be enabled standalone for close systems 46 * Clause 37 is supported 47 48 */ 49 50 #include <phymod/phymod.h> 51 #include <phymod/phymod_system.h> 52 #include <phymod/phymod_dispatch.h> 53 54 55 #ifdef PHYMOD_QUADRA28_SUPPORT 56 #include <phymod/chip/quadra28.h> 57 58 /* To be defined */ 59 #include "../tier1/quadra28_types.h" 60 #include "../tier1/quadra28_cfg_seq.h" 61 #include "../tier1/quadra28_reg_access.h" 62 #include "../tier1/bcmi_quadra28_defs.h" 63 64 /* Microcontroller Firmware */ 65 extern unsigned char quadra28_ucode_bin[]; 66 extern uint32_t quadra28_ucode_len; 67 68 int _quadra28_core_firmware_load (const phymod_core_access_t* core, 69 const phymod_core_init_config_t *init_config); 70 71 72 /* 73 * Set Interface config 74 * This function sets interface configuration (interface, speed, frequency of 75 * operation). This is requried to put the quadra28 into specific mode specified 76 * by the user. 77 * 78 * @param phy Pointer to phymod phy access structure 79 * @param flags Currently unused and reserved for future use 80 * @param config Interface config structure where user specifies 81 * interface, speed and the frequency of operation. 82 * 83 * @return PHYMOD_E_NONE successful function execution 84 */ 85 int quadra28_phy_interface_config_set(const phymod_phy_access_t* phy, 86 uint32_t flags, 87 const phymod_phy_inf_config_t* config) 88 { 89 if (config->data_rate == 100 || config->data_rate == 10) { 90 uint32_t enable = 0; 91 PHYMOD_IF_ERR_RETURN( 92 _quadra28_phy_retimer_enable_get(&phy->access, &enable)); 93 if (!enable) { 94 return PHYMOD_E_NONE; 95 } 96 } 97 return quadra28_set_config_mode(phy, 98 config->interface_type, 99 config->data_rate, 100 config->ref_clock, 0xFFFF, 0xFFFF); 101 } 102 103 /** Get Interface config 104 * This function retrieves interface configuration(interface, speed and 105 * frequency of operation) from the device. 106 * 107 * @param phy Pointer to phymod phy access structure 108 * @param flags Currently unused and reserved for future use 109 * @param config Interface config structure where 110 * interface, speed and the frequency of operation 111 * will be populated from device . 112 * 113 * @return PHYMOD_E_NONE successful function execution 114 */ 115 int quadra28_phy_interface_config_get(const phymod_phy_access_t* phy, 116 uint32_t flags, 117 phymod_ref_clk_t ref_clock, 118 phymod_phy_inf_config_t* config) 119 { 120 return quadra28_get_config_mode(&phy->access, 121 &config->interface_type, 122 &config->data_rate, 123 &config->ref_clock, 124 &config->interface_modes); 125 } 126 127 128 /** Core Init 129 * This function initializes the quadra core and 130 * downloads the firmware. It sets the PHY in 131 * default mode. 132 * 133 * @param phy Pointer to phymod core access structure 134 * @param init_config Init configuration specified by user 135 * @param core_status Core status read from PHY chip 136 * 137 * @return PHYMOD_E_NONE successful function execution 138 */ 139 int quadra28_core_init(const phymod_core_access_t *core, 140 const phymod_core_init_config_t *init_config, 141 const phymod_core_status_t *core_status) 142 { 143 144 PHYMOD_IF_ERR_RETURN( 145 _quadra28_core_firmware_load (core, init_config)); 146 147 148 return PHYMOD_E_NONE; 149 150 } 151 152 /** Core firmware download 153 * This function downloads the firmware using either internal or external 154 * method as specified by the user. Firmware loader function supplied by user 155 * will be used for external download method. 156 * 157 * @param core Pointer to phymod core access structure 158 * @param load_method Load method will be specified by user 159 * @param fw_loader Loader function specified by user and will be 160 * used for external download method 161 * 162 * @return PHYMOD_E_NONE successful function execution 163 */ 164 int _quadra28_core_firmware_load (const phymod_core_access_t* core, 165 const phymod_core_init_config_t *init_config) 166 { 167 int ret_val = 0, dload_method = init_config->firmware_load_method; 168 const phymod_access_t *pm_acc = &core->access; 169 uint32_t chip_id; 170 uint32_t new_firmware_version=0; 171 phymod_core_firmware_info_t fw_info; 172 173 PHYMOD_MEMSET(&fw_info, 0, sizeof(phymod_core_firmware_info_t)); 174 PHYMOD_IF_ERR_RETURN( 175 quadra28_core_firmware_info_get(core, &fw_info)); 176 new_firmware_version = quadra28_ucode_bin[quadra28_ucode_len-3]; 177 chip_id = _quadra28_get_chip_id(&core->access); 178 179 switch(dload_method) 180 { 181 case phymodFirmwareLoadMethodInternal: 182 if(PHYMOD_CORE_INIT_F_FW_FORCE_DOWNLOAD_GET(init_config)){ 183 if (PHYMOD_CORE_INIT_F_UNTIL_FW_LOAD_GET(init_config)) { 184 return quadra28_before_fw_load(core, init_config, chip_id); 185 } else if (PHYMOD_CORE_INIT_F_EXECUTE_FW_LOAD_GET(init_config)) { 186 return quadra28_bcast_fw_load(core, init_config, 187 quadra28_ucode_bin, quadra28_ucode_len); 188 } else if (PHYMOD_CORE_INIT_F_RESUME_AFTER_FW_LOAD_GET(init_config)) { 189 ret_val = quadra28_bcast_after_fw_load(core, chip_id); 190 if(ret_val != 0){ 191 PHYMOD_DEBUG_ERROR(("Firmware Verification failed %d\n",ret_val)); 192 193 /* Doing Softreset to clear Broadcast*/ 194 PHYMOD_IF_ERR_RETURN( 195 quadra28_bcast_disable(core, chip_id)); 196 197 } 198 return ret_val; 199 } else if(PHYMOD_CORE_INIT_F_FW_LOAD_END_GET(init_config)){ 200 PHYMOD_DIAG_OUT(("Firmware download success\n")); 201 /* Using sratch Reg to store and retrevie later*/ 202 PHYMOD_IF_ERR_RETURN( 203 phymod_raw_iblk_write(&core->access, 0x1c91A,init_config->op_datapath)); 204 PHYMOD_IF_ERR_RETURN( 205 phymod_raw_iblk_write(&core->access, 0x1c91B,init_config->op_datapath)); 206 207 /* Doing Softreset to clear Broadcast*/ 208 PHYMOD_IF_ERR_RETURN( 209 quadra28_bcast_disable(core, chip_id)); 210 211 } 212 } else if(PHYMOD_CORE_INIT_F_FW_AUTO_DOWNLOAD_GET(init_config) && new_firmware_version != fw_info.fw_version){ 213 if (PHYMOD_CORE_INIT_F_UNTIL_FW_LOAD_GET(init_config)) { 214 return quadra28_before_fw_load(core, init_config, chip_id); 215 } else if (PHYMOD_CORE_INIT_F_EXECUTE_FW_LOAD_GET(init_config)) { 216 return quadra28_bcast_fw_load(core, init_config, 217 quadra28_ucode_bin, quadra28_ucode_len); 218 } else if (PHYMOD_CORE_INIT_F_RESUME_AFTER_FW_LOAD_GET(init_config)) { 219 ret_val = quadra28_bcast_after_fw_load(core, chip_id); 220 if(ret_val != 0){ 221 PHYMOD_DEBUG_ERROR(("Firmware Verification failed %d\n",ret_val)); 222 223 /* Doing Softreset to clear Broadcast*/ 224 PHYMOD_IF_ERR_RETURN( 225 quadra28_bcast_disable(core, chip_id)); 226 227 } 228 return ret_val; 229 } else if(PHYMOD_CORE_INIT_F_FW_LOAD_END_GET(init_config)){ 230 PHYMOD_DIAG_OUT(("Firmware download success\n")); 231 /* Using sratch Reg to store and retrevie later*/ 232 PHYMOD_IF_ERR_RETURN( 233 phymod_raw_iblk_write(&core->access, 0x1c91A,init_config->op_datapath)); 234 PHYMOD_IF_ERR_RETURN( 235 phymod_raw_iblk_write(&core->access, 0x1c91B,init_config->op_datapath)); 236 237 /* Doing Softreset to clear Broadcast*/ 238 PHYMOD_IF_ERR_RETURN( 239 quadra28_bcast_disable(core, chip_id)); 240 } 241 } else if(fw_info.fw_version == 0){ 242 if (PHYMOD_CORE_INIT_F_UNTIL_FW_LOAD_GET(init_config)) { 243 return quadra28_before_fw_load(core, init_config, chip_id); 244 } else if (PHYMOD_CORE_INIT_F_EXECUTE_FW_LOAD_GET(init_config)) { 245 return quadra28_bcast_fw_load(core, init_config, 246 quadra28_ucode_bin, quadra28_ucode_len); 247 } else if (PHYMOD_CORE_INIT_F_RESUME_AFTER_FW_LOAD_GET(init_config)) { 248 ret_val = quadra28_bcast_after_fw_load(core, chip_id); 249 if(ret_val != 0){ 250 PHYMOD_DEBUG_ERROR(("Firmware Verification failed %d\n",ret_val)); 251 252 /* Doing Softreset to clear Broadcast*/ 253 PHYMOD_IF_ERR_RETURN( 254 quadra28_bcast_disable(core, chip_id)); 255 256 } 257 return ret_val; 258 } else if(PHYMOD_CORE_INIT_F_FW_LOAD_END_GET(init_config)){ 259 PHYMOD_DIAG_OUT(("Firmware download success\n")); 260 /* Using sratch Reg to store and retrevie later*/ 261 PHYMOD_IF_ERR_RETURN( 262 phymod_raw_iblk_write(&core->access, 0x1c91A,init_config->op_datapath)); 263 PHYMOD_IF_ERR_RETURN( 264 phymod_raw_iblk_write(&core->access, 0x1c91B,init_config->op_datapath)); 265 266 /* Doing Softreset to clear Broadcast*/ 267 PHYMOD_IF_ERR_RETURN( 268 quadra28_bcast_disable(core,chip_id)); 269 } 270 } else { 271 if (fw_info.fw_version != 0) { 272 MDIO_BROADCAST_CONTROLr_t mdio_broadcast_ctrl_reg; 273 PHYMOD_IF_ERR_RETURN 274 (READ_MDIO_BROADCAST_CONTROLr(&core->access, &mdio_broadcast_ctrl_reg)); 275 if (BCMI_QUADRA28_MDIO_BROADCAST_CONTROLr_MDIO_BCAST_ENf_GET(mdio_broadcast_ctrl_reg)) { 276 /* Using sratch Reg to store and retrevie later*/ 277 PHYMOD_IF_ERR_RETURN( 278 phymod_raw_iblk_write(&core->access, 0x1c91A,init_config->op_datapath)); 279 PHYMOD_IF_ERR_RETURN( 280 phymod_raw_iblk_write(&core->access, 0x1c91B,init_config->op_datapath)); 281 /* Doing Softreset to clear Broadcast*/ 282 PHYMOD_IF_ERR_RETURN( 283 quadra28_bcast_disable(core,chip_id)); 284 } 285 } 286 } 287 break; 288 case phymodFirmwareLoadMethodExternal: 289 return PHYMOD_E_UNAVAIL; 290 break; 291 case phymodFirmwareLoadMethodNone: 292 break; 293 case phymodFirmwareLoadMethodProgEEPROM: 294 PHYMOD_DIAG_OUT(("Firmware will be downloaded first, and flashed on to EEPROM \n")); 295 PHYMOD_DIAG_OUT(("This process will take few minutes.....\n")); 296 ret_val = quadra28_rom_dload(pm_acc, quadra28_ucode_bin, 297 quadra28_ucode_len); 298 if (ret_val != PHYMOD_E_NONE) { 299 PHYMOD_RETURN_WITH_ERR 300 (PHYMOD_E_FAIL, 301 (_PHYMOD_MSG("Flashing Firmware to EEPROM failed"))); 302 } else { 303 PHYMOD_DEBUG_VERBOSE(("Firmware is flashed to EEPROM successfully\n")); 304 } 305 /* Using sratch Reg to store and retrevie later*/ 306 PHYMOD_IF_ERR_RETURN( 307 phymod_raw_iblk_write(&core->access, 0x1c91A,init_config->op_datapath)); 308 PHYMOD_IF_ERR_RETURN( 309 phymod_raw_iblk_write(&core->access, 0x1c91B,init_config->op_datapath)); 310 break; 311 default: 312 PHYMOD_RETURN_WITH_ERR 313 (PHYMOD_E_CONFIG, 314 (_PHYMOD_MSG("illegal fw load method"))); 315 } 316 return PHYMOD_E_NONE; 317 } 318 319 320 /** Get PHY link status 321 * This function retrieves PHY link status from device 322 * 323 * @param phy Pointer to phymod phy access structure 324 * @param link_status Link status retrieved from the device 325 * 326 * @return PHYMOD_E_NONE successful function execution 327 */ 328 329 330 int quadra28_phy_link_status_get(const phymod_phy_access_t* phy, 331 uint32_t* link_status) 332 { 333 return quadra28_link_status(phy, link_status); 334 } 335 336 /** PHY register read 337 * This function reads the PHY register 338 * 339 * @param phy Pointer to phymod phy access structure 340 * @param reg_addr PHY Register Address to Read 341 * @param val PHY Register content of the specified 342 * register Address to Read 343 * 344 * @return PHYMOD_E_NONE successful function execution 345 */ 346 int quadra28_phy_reg_read(const phymod_phy_access_t* phy, uint32_t reg_addr, 347 uint32_t *val) 348 { 349 return phymod_raw_iblk_read(&phy->access,\ 350 QUADRA28_CLAUSE45_ADDR((phy->access.devad), (reg_addr)),\ 351 val); 352 } 353 354 355 /** PHY register write 356 * This function is used to write content to PHY register 357 * 358 * @param phy Pointer to phymod phy access structure 359 * @param reg_addr PHY Register Address to Write 360 * @param val Content/Value to Write to the PHY Register 361 * 362 * @return PHYMOD_E_NONE successful function execution 363 */ 364 int quadra28_phy_reg_write(const phymod_phy_access_t* phy, uint32_t reg_addr, 365 uint32_t val) 366 { 367 368 return phymod_raw_iblk_write(&phy->access,\ 369 QUADRA28_CLAUSE45_ADDR((phy->access.devad), (reg_addr)),\ 370 val); 371 } 372 373 /** PHY core info get 374 * This function is used to write content to PHY register 375 * 376 * @param phy Pointer to phymod phy access structure 377 * @param info Pointer to core info structure 378 * 379 * @return PHYMOD_E_NONE successful function execution 380 */ 381 int quadra28_core_info_get(const phymod_core_access_t* phy, phymod_core_info_t* info) 382 { 383 uint32_t chip_id; 384 PMD_IDENTIFIER_0r_t id0; 385 PMD_IDENTIFIER_1r_t id1; 386 387 chip_id = _quadra28_get_chip_id(&phy->access); 388 info->serdes_id = chip_id; 389 info->core_version = phymodCoreVersionQuadra28; 390 PHYMOD_STRNCPY(info->name, "Quadra28", PHYMOD_STRLEN("Quadra28")+1); 391 392 PHYMOD_IF_ERR_RETURN ( 393 READ_PMD_IDENTIFIER_1r(&phy->access, &id1)); 394 info->phy_id1 = id1.v[0]; 395 PHYMOD_IF_ERR_RETURN ( 396 READ_PMD_IDENTIFIER_0r(&phy->access, &id0)); 397 info->phy_id0 = id0.v[0]; 398 399 return PHYMOD_E_NONE; 400 } 401 /** PHY polarity set 402 * This function is used to set the lane polarity 403 * 404 * @param phy Pointer to phymod phy access structure 405 * @param polarity Pointer to phymod_polarity_t for rx and tx 406 * 407 * @return PHYMOD_E_NONE successful function execution 408 */ 409 int quadra28_phy_polarity_set(const phymod_phy_access_t* phy, const phymod_polarity_t* polarity) 410 { 411 return quadra28_tx_rx_polarity_set(phy, polarity->tx_polarity, polarity->rx_polarity); 412 } 413 414 415 /** PHY polarity get 416 * This function is used to get the lane polarity 417 * 418 * @param phy Pointer to phymod phy access structure 419 * @param polarity Pointer to phymod_polarity_t for rx and tx 420 * 421 * @return PHYMOD_E_NONE successful function execution 422 */ 423 int quadra28_phy_polarity_get(const phymod_phy_access_t* phy, phymod_polarity_t* polarity) 424 { 425 return quadra28_tx_rx_polarity_get(phy, &polarity->tx_polarity, &polarity->rx_polarity); 426 } 427 428 /** PHY Rx PMD lock 429 * PHY Rx PMD lock This function is used to get the rx PMD lock status 430 * 431 * @param phy Pointer to phymod phy access structure 432 * @param rx_seq_done Pointer to rx sequence 433 * 434 * @return PHYMOD_E_NONE successful function execution 435 */ 436 int quadra28_phy_rx_pmd_locked_get(const phymod_phy_access_t* phy, uint32_t* rx_seq_done){ 437 438 return quadra28_pmd_lock_get(phy, rx_seq_done); 439 } 440 441 442 /** PHY power set 443 * PHY power set This function is used to set the power 444 * 445 * @param phy Pointer to phymod phy access structure 446 * @param power Pointer to phymod phy power structure 447 * 448 * @return PHYMOD_E_NONE successful function execution 449 */ 450 int quadra28_phy_power_set(const phymod_phy_access_t* phy, 451 const phymod_phy_power_t* power) 452 { 453 return _quadra28_phy_power_set(phy, power); 454 } 455 456 /* 457 * @param flags Reserved for Furtuer use 458 * @param operation Operation to perform on PLL sequencer 459 * 460 * @return PHYMOD_E_NONE successful function execution 461 */ 462 int quadra28_core_pll_sequencer_restart(const phymod_core_access_t* core, uint32_t flags, phymod_sequencer_operation_t operation) 463 { 464 465 return _quadra28_pll_seq_restart(&core->access, flags, operation); 466 467 } 468 /** FEC enable set 469 * This function is used to enable the FEC 470 * 471 * @param phy Pointer to phymod phy access structure 472 * @param enable enable or disable 473 * 1 - enable 474 * 0 - disable 475 * 476 * @return PHYMOD_E_NONE successful function execution 477 */ 478 int quadra28_phy_fec_enable_set(const phymod_phy_access_t* phy, uint32_t enable) 479 { 480 return _quadra28_phy_fec_enable_set(phy, enable); 481 } 482 /** FEC enable get 483 * This function is used to check whether or not FEC is enabled 484 * 485 * @param phy Pointer to phymod phy access structure 486 * @param enable enable or disable 487 * 1 - enable 488 * 0 - disable 489 * 490 * @return PHYMOD_E_NONE successful function execution 491 */ 492 int quadra28_phy_fec_enable_get(const phymod_phy_access_t* phy, uint32_t* enable) 493 { 494 return _quadra28_phy_fec_enable_get(phy, enable); 495 } 496 /** PHY status dump 497 * This function is used to display status dump of a core and for given lane 498 * 499 * @param phy Pointer to phymod phy access structure 500 * 501 * @return PHYMOD_E_NONE successful function execution 502 */ 503 int quadra28_phy_status_dump(const phymod_phy_access_t* phy) 504 { 505 506 PHYMOD_IF_ERR_RETURN( 507 _quadra28_phy_status_dump(phy)); 508 509 return PHYMOD_E_NONE; 510 511 } 512 513 static int _quadra28_reset_mode(const phymod_access_t *pa) 514 { 515 int speed = 0; 516 BCMI_QUADRA28_GENERAL_PURPOSE_3r_t gp_reg3_reg_val; 517 BCMI_QUADRA28_APPS_MODE_0r_t apps_mode0_reg_val; 518 PHYMOD_MEMSET(&gp_reg3_reg_val, 0, sizeof(BCMI_QUADRA28_GENERAL_PURPOSE_3r_t)); 519 PHYMOD_MEMSET(&apps_mode0_reg_val, 0, sizeof(BCMI_QUADRA28_APPS_MODE_0r_t)); 520 521 PHYMOD_IF_ERR_RETURN( 522 BCMI_QUADRA28_READ_GENERAL_PURPOSE_3r(pa, &gp_reg3_reg_val)); 523 speed = gp_reg3_reg_val.v[0] & 0xF ; 524 if (speed == 0x4 || speed == 0x7) { 525 PHYMOD_IF_ERR_RETURN( 526 quadra28_channel_select (pa, Q28_ALL_LANE)); 527 apps_mode0_reg_val.v[0] = gp_reg3_reg_val.v[0]; 528 BCMI_QUADRA28_APPS_MODE_0r_FINISH_CHANGEf_SET(apps_mode0_reg_val, 0); 529 PHYMOD_IF_ERR_RETURN( 530 BCMI_QUADRA28_WRITE_APPS_MODE_0r(pa, apps_mode0_reg_val)); 531 PHYMOD_USLEEP(100); 532 BCMI_QUADRA28_APPS_MODE_0r_SET(apps_mode0_reg_val, 0x8882); 533 PHYMOD_IF_ERR_RETURN( 534 BCMI_QUADRA28_WRITE_APPS_MODE_0r(pa, apps_mode0_reg_val)); 535 { 536 BCMI_QUADRA28_PMD_CONTROLr_t pmd_ctrl; 537 PHYMOD_MEMSET(&pmd_ctrl, 0, sizeof(BCMI_QUADRA28_PMD_CONTROLr_t)); 538 PHYMOD_IF_ERR_RETURN( 539 BCMI_QUADRA28_READ_PMD_CONTROLr(pa, &pmd_ctrl)); 540 BCMI_QUADRA28_PMD_CONTROLr_RESETf_SET(pmd_ctrl, 1); 541 PHYMOD_IF_ERR_RETURN( 542 BCMI_QUADRA28_WRITE_PMD_CONTROLr(pa, pmd_ctrl)); 543 } 544 PHYMOD_USLEEP(500); 545 PHYMOD_IF_ERR_RETURN( 546 _quadra28_intf_update_wait_check(pa,apps_mode0_reg_val.v[0], 50000)); 547 } 548 549 return PHYMOD_E_NONE; 550 } 551 552 int quadra28_core_identify(const phymod_core_access_t* core, uint32_t core_id, uint32_t* is_identified) 553 { 554 uint32_t chip_id; 555 PMD_IDENTIFIER_0r_t id0; 556 PMD_IDENTIFIER_1r_t id1; 557 const phymod_access_t *pm_acc = &core->access; 558 559 PHYMOD_MEMSET(&id0, 0, sizeof(PMD_IDENTIFIER_0r_t)); 560 PHYMOD_MEMSET(&id1, 0, sizeof(PMD_IDENTIFIER_1r_t)); 561 *is_identified = 0; 562 if (core_id == 0) { 563 PHYMOD_IF_ERR_RETURN ( 564 READ_PMD_IDENTIFIER_1r(pm_acc, &id1)); 565 PHYMOD_IF_ERR_RETURN ( 566 READ_PMD_IDENTIFIER_0r(pm_acc, &id0)); 567 } else { 568 id0.v[0] = (uint16_t) ((core_id >> 16) & 0xffff); 569 id1.v[0] = (uint16_t) core_id & 0xffff; 570 } 571 if ((id0.v[0] == QUADRA28_PMD_ID0 && 572 id1.v[0] == QUADRA28_PMD_ID1)) { 573 if (PHYMOD_ACC_F_PRECONDITION_GET(&core->access)) { 574 return _quadra28_reset_mode(&core->access); 575 } 576 chip_id = _quadra28_get_chip_id(&core->access); 577 if (chip_id == QUADRA28_82780_CHIP_ID || chip_id == QUADRA28_82752_CHIP_ID 578 || chip_id == QUADRA28_82758_CHIP_ID || chip_id == QUADRA28_8278F_CHIP_ID) { 579 /* PHY IDs match and enable Broadcast */ 580 *is_identified = 0x80000001; 581 } 582 } 583 return PHYMOD_E_NONE; 584 585 } 586 int quadra28_core_reset_set(const phymod_core_access_t* core, phymod_reset_mode_t reset_mode, phymod_reset_direction_t direction) 587 { 588 PHYMOD_IF_ERR_RETURN ( 589 quadra28_soft_reset(&core->access, reset_mode, direction)); 590 return PHYMOD_E_NONE; 591 592 } 593 594 int quadra28_core_reset_get(const phymod_core_access_t* core, phymod_reset_mode_t reset_mode, phymod_reset_direction_t* direction) 595 { 596 return PHYMOD_E_UNAVAIL; 597 598 } 599 600 int quadra28_core_firmware_info_get(const phymod_core_access_t* core, phymod_core_firmware_info_t* fw_info) 601 { 602 PHYMOD_IF_ERR_RETURN( 603 quadra28_firmware_info_get(&core->access, fw_info)); 604 return PHYMOD_E_NONE; 605 606 } 607 608 int quadra28_phy_tx_set(const phymod_phy_access_t* phy, const phymod_tx_t* tx) 609 { 610 return _quadra28_phy_tx_set(phy, tx); 611 } 612 613 int quadra28_phy_tx_get(const phymod_phy_access_t* phy, phymod_tx_t* tx) 614 { 615 PHYMOD_IF_ERR_RETURN( 616 _quadra28_phy_tx_get(phy, tx)); 617 return PHYMOD_E_NONE; 618 } 619 620 int quadra28_phy_media_type_tx_get(const phymod_phy_access_t* phy, phymod_media_typed_t media, phymod_tx_t* tx) 621 { 622 TXFIR_CONTROL1r_t txfir_ctrl1; 623 TXFIR_CONTROL2r_t txfir_ctrl2; 624 625 PHYMOD_MEMSET(tx, 0, sizeof(phymod_tx_t)); 626 PHYMOD_MEMSET(&txfir_ctrl1, 0, sizeof(TXFIR_CONTROL1r_t)); 627 PHYMOD_MEMSET(&txfir_ctrl2, 0, sizeof(TXFIR_CONTROL2r_t)); 628 PHYMOD_IF_ERR_RETURN( 629 READ_TXFIR_CONTROL1r(&phy->access, &txfir_ctrl1)); 630 PHYMOD_IF_ERR_RETURN( 631 READ_TXFIR_CONTROL2r(&phy->access, &txfir_ctrl2)); 632 633 tx->pre = TXFIR_CONTROL1r_TXFIR_PRE_OVERRIDEf_GET(txfir_ctrl1); 634 tx->post = TXFIR_CONTROL1r_TXFIR_POST_OVERRIDEf_GET(txfir_ctrl1); 635 tx->main = TXFIR_CONTROL2r_TXFIR_MAIN_OVERRIDEf_GET(txfir_ctrl2); 636 tx->post2 = TXFIR_CONTROL2r_TXFIR_POST2f_GET(txfir_ctrl2); 637 638 return PHYMOD_E_NONE; 639 } 640 int quadra28_phy_rx_set(const phymod_phy_access_t* phy, const phymod_rx_t* rx) 641 { 642 return _quadra28_phy_rx_set(phy, rx); 643 } 644 645 int quadra28_phy_rx_get(const phymod_phy_access_t* phy, phymod_rx_t* rx) 646 { 647 return _quadra28_phy_rx_get(phy, rx); 648 } 649 650 int quadra28_phy_reset_set(const phymod_phy_access_t* phy, const phymod_phy_reset_t* reset) 651 { 652 return _quadra28_phy_reset_set(phy, reset); 653 } 654 655 int quadra28_phy_reset_get(const phymod_phy_access_t* phy, phymod_phy_reset_t* reset) 656 { 657 return _quadra28_phy_reset_get(phy, reset); 658 } 659 660 int quadra28_phy_tx_lane_control_set(const phymod_phy_access_t* phy, phymod_phy_tx_lane_control_t tx_control) 661 { 662 return quadra28_tx_lane_control_set(phy, tx_control); 663 } 664 665 int quadra28_phy_tx_lane_control_get(const phymod_phy_access_t* phy, phymod_phy_tx_lane_control_t* tx_control) 666 { 667 int enable = 0; 668 *tx_control = phymodTxSquelchOn; 669 670 PHYMOD_IF_ERR_RETURN ( 671 quadra28_tx_squelch_get(phy, &enable)); 672 673 if (!enable) { 674 *tx_control = phymodTxSquelchOff; 675 } 676 return PHYMOD_E_NONE; 677 678 } 679 680 int quadra28_phy_rx_lane_control_set(const phymod_phy_access_t* phy, phymod_phy_rx_lane_control_t rx_control) 681 { 682 return quadra28_rx_lane_control_set(phy, rx_control); 683 } 684 685 int quadra28_phy_rx_lane_control_get(const phymod_phy_access_t* phy, phymod_phy_rx_lane_control_t* rx_control) 686 { 687 int enable = 0; 688 *rx_control = phymodRxSquelchOn; 689 PHYMOD_IF_ERR_RETURN ( 690 quadra28_rx_squelch_get(phy, &enable)); 691 if (!enable) { 692 *rx_control = phymodRxSquelchOff; 693 } 694 return PHYMOD_E_NONE; 695 696 } 697 698 int quadra28_phy_autoneg_ability_set(const phymod_phy_access_t* phy, const phymod_autoneg_ability_t* an_ability_set_type) 699 { 700 q28_an_ability_t an_ability; 701 an_ability.fec_ability = an_ability_set_type->an_fec; 702 703 /*next check pause */ 704 if (PHYMOD_AN_CAP_SYMM_PAUSE_GET(an_ability_set_type)) { 705 an_ability.pause_ability = Q28_SYMM_PAUSE; 706 } else if (PHYMOD_AN_CAP_ASYM_PAUSE_GET(an_ability_set_type)) { 707 an_ability.pause_ability = Q28_ASYM_PAUSE; 708 } else { 709 an_ability.pause_ability = Q28_NO_PAUSE; 710 } 711 712 /* Quadra28 FW set advertisement based on the speed, so no 713 * need to set advert*/ 714 PHYMOD_IF_ERR_RETURN(_quadra28_phy_autoneg_ability_set(&phy->access, an_ability)); 715 716 return PHYMOD_E_NONE; 717 } 718 719 int quadra28_phy_autoneg_ability_get(const phymod_phy_access_t* phy, phymod_autoneg_ability_t* an_ability_get_type) 720 { 721 return _quadra28_phy_autoneg_ability_get(&phy->access, an_ability_get_type); 722 } 723 724 int quadra28_phy_init(const phymod_phy_access_t* phy, const phymod_phy_init_config_t* init_config) 725 { 726 uint32_t datapath = 0, datapath1 = 0; 727 PHYMOD_IF_ERR_RETURN( 728 phymod_raw_iblk_read(&phy->access, 0x1c91A, &datapath)); 729 PHYMOD_IF_ERR_RETURN( 730 phymod_raw_iblk_read(&phy->access, 0x1c91B, &datapath1)); 731 datapath |= datapath1; 732 733 PHYMOD_IF_ERR_RETURN 734 (quadra28_set_config_mode(phy, 735 init_config->interface.interface_type, init_config->interface.data_rate, 736 init_config->interface.ref_clock, datapath, init_config->op_mode)); 737 738 /* 0 is the Default init value coming from portmod*/ 739 if ((init_config->polarity.tx_polarity != 0) || 740 (init_config->polarity.rx_polarity != 0)) { 741 PHYMOD_IF_ERR_RETURN( 742 quadra28_tx_rx_polarity_set (phy, 743 init_config->polarity.tx_polarity, init_config->polarity.rx_polarity)); 744 } 745 return PHYMOD_E_NONE; 746 } 747 748 int quadra28_phy_loopback_set(const phymod_phy_access_t* phy, phymod_loopback_mode_t loopback, uint32_t enable) 749 { 750 return _quadra28_loopback_set(phy, loopback, enable); 751 } 752 753 int quadra28_phy_loopback_get(const phymod_phy_access_t* phy, phymod_loopback_mode_t loopback, uint32_t* enable) 754 { 755 return _quadra28_loopback_get(phy, loopback, enable); 756 } 757 758 int quadra28_phy_power_get(const phymod_phy_access_t* phy, phymod_phy_power_t* power) 759 { 760 return _quadra28_phy_power_get(phy, power); 761 } 762 763 int quadra28_phy_autoneg_set(const phymod_phy_access_t* phy, const phymod_autoneg_control_t* an) 764 { 765 return _quadra28_phy_autoneg_set(&phy->access, an); 766 } 767 768 int quadra28_phy_autoneg_get(const phymod_phy_access_t* phy, phymod_autoneg_control_t* an, uint32_t* an_done) 769 { 770 return _quadra28_phy_autoneg_get(&phy->access, an, an_done); 771 772 } 773 774 int quadra28_phy_autoneg_remote_ability_get(const phymod_phy_access_t* phy, phymod_autoneg_ability_t* an_ability_get_type) 775 { 776 return _quadra28_phy_autoneg_remote_ability_get(&phy->access, an_ability_get_type) ; 777 } 778 779 int quadra28_phy_cl72_set(const phymod_phy_access_t* phy, uint32_t cl72_en) 780 { 781 return _quadra28_phy_cl72_set(phy, cl72_en); 782 } 783 784 int quadra28_phy_cl72_get(const phymod_phy_access_t* phy, uint32_t* cl72_en) 785 { 786 return _quadra28_phy_cl72_get(phy, cl72_en); 787 } 788 789 int quadra28_phy_cl72_status_get(const phymod_phy_access_t* phy, phymod_cl72_status_t* status) 790 { 791 return _quadra28_phy_cl72_status_get(phy, status); 792 } 793 794 int quadra28_phy_i2c_read(const phymod_phy_access_t* phy, uint32_t flags, uint32_t addr, uint32_t offset, uint32_t size, uint8_t* data) 795 { 796 797 return (_quadra28_i2c_read(&phy->access, addr, offset, size, data)); 798 799 } 800 801 802 803 int quadra28_phy_i2c_write(const phymod_phy_access_t* phy, uint32_t flags, uint32_t addr, uint32_t offset, uint32_t size, const uint8_t* data) 804 { 805 806 return(_quadra28_i2c_write(&phy->access, addr, offset, size, data)); 807 808 } 809 int quadra28_edc_config_set(const phymod_phy_access_t* phy, const phymod_edc_config_t* edc_config) 810 { 811 return _quadra28_edc_config_set(phy, edc_config); 812 } 813 int quadra28_edc_config_get(const phymod_phy_access_t* phy, phymod_edc_config_t* edc_config) 814 { 815 return _quadra28_edc_config_get(phy, edc_config); 816 } 817 818 int quadra28_phy_rx_restart(const phymod_phy_access_t* phy) 819 { 820 return _quadra28_pll_seq_restart(&phy->access, 0, phymodSeqOpRestart); 821 } 822 823 int quadra28_failover_mode_set(const phymod_phy_access_t* phy, phymod_failover_mode_t failover_mode) 824 { 825 return _quadra28_failover_mode_set(phy, failover_mode); 826 } 827 int quadra28_failover_mode_get(const phymod_phy_access_t* phy, phymod_failover_mode_t* failover_mode) 828 { 829 return _quadra28_failover_mode_get(phy, failover_mode); 830 } 831 832 int quadra28_phy_rx_adaptation_resume(const phymod_phy_access_t* phy) 833 { 834 return _quadra28_phy_rx_adaptation_resume(phy); 835 } 836 837 int quadra28_phy_gpio_config_set(const phymod_phy_access_t* phy, int pin_no, phymod_gpio_mode_t gpio_mode) 838 { 839 return _quadra28_phy_gpio_config_set(phy, pin_no, gpio_mode); 840 } 841 int quadra28_phy_gpio_config_get(const phymod_phy_access_t* phy, int pin_no, phymod_gpio_mode_t* gpio_mode) 842 { 843 return _quadra28_phy_gpio_config_get(phy, pin_no, gpio_mode); 844 } 845 int quadra28_phy_gpio_pin_value_set(const phymod_phy_access_t* phy, int pin_no, int value) 846 { 847 return _quadra28_phy_gpio_pin_value_set(phy, pin_no, value); 848 } 849 int quadra28_phy_gpio_pin_value_get(const phymod_phy_access_t* phy, int pin_no, int* value) 850 { 851 return _quadra28_phy_gpio_pin_value_get(phy, pin_no, value); 852 } 853 int quadra28_core_lane_map_set(const phymod_core_access_t* core, const phymod_lane_map_t* lane_map) 854 { 855 return PHYMOD_E_UNAVAIL; 856 } 857 int quadra28_core_lane_map_get(const phymod_core_access_t* core, phymod_lane_map_t* lane_map) 858 { 859 return PHYMOD_E_UNAVAIL; 860 } 861 int quadra28_phy_firmware_core_config_set(const phymod_phy_access_t* phy, phymod_firmware_core_config_t fw_core_config) 862 { 863 return PHYMOD_E_UNAVAIL; 864 } 865 int quadra28_phy_firmware_core_config_get(const phymod_phy_access_t* phy, phymod_firmware_core_config_t* fw_core_config) 866 { 867 return PHYMOD_E_UNAVAIL; 868 } 869 int quadra28_phy_firmware_lane_config_set(const phymod_phy_access_t* phy, phymod_firmware_lane_config_t fw_lane_config) 870 { 871 return PHYMOD_E_UNAVAIL; 872 } 873 int quadra28_phy_firmware_lane_config_get(const phymod_phy_access_t* phy, phymod_firmware_lane_config_t* fw_lane_config) 874 { 875 return PHYMOD_E_UNAVAIL; 876 } 877 int quadra28_phy_multi_get(const phymod_phy_access_t* phy, phymod_multi_data_t* multi_data) 878 { 879 return (_quadra28_i2c_read(&phy->access, multi_data->dev_addr, multi_data->offset, multi_data->max_size, multi_data->data)); 880 } 881 882 int quadra28_phy_op_mode_get(const phymod_phy_access_t* phy, phymod_operation_mode_t* op_mode) 883 { 884 uint32_t retimer = 0, speed = 0, interface_modes = 0; 885 phymod_interface_t intf; 886 phymod_ref_clk_t ref_clk; 887 888 PHYMOD_IF_ERR_RETURN( 889 _quadra28_phy_retimer_enable_get(&phy->access, &retimer)); 890 891 PHYMOD_IF_ERR_RETURN( 892 quadra28_get_config_mode(&phy->access, &intf, &speed, &ref_clk, &interface_modes)); 893 894 (void) intf; 895 (void) ref_clk; 896 (void) interface_modes; 897 if ((retimer == 0) && (speed == 1000)) { 898 *op_mode = phymodOperationModePassthru; 899 } else if(retimer == 1) { 900 *op_mode = phymodOperationModeRetimer; 901 } else { 902 *op_mode = phymodOperationModeRepeater; 903 } 904 905 return PHYMOD_E_NONE; 906 } 907 908 909 #endif