madura.c (34829B)
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 #include <phymod/phymod.h> 11 #include <phymod/phymod_system.h> 12 #include <phymod/phymod_reg.h> 13 #include <phymod/phymod_dispatch.h> 14 15 #ifdef PHYMOD_MADURA_SUPPORT 16 17 18 #include <phymod/chip/madura.h> 19 #include "../tier1/madura_cfg_seq.h" 20 #include "../tier1/bcmi_madura_defs.h" 21 22 /* Microcontroller Firmware */ 23 extern unsigned char madura_falcon_ucode[]; 24 extern uint32_t madura_falcon_ucode_len; 25 26 /** Core identify 27 * This function reads PMD Identifiers, Set is identified if 28 * madura identified. 29 * 30 * @param core Pointer to phymod core access structure 31 * @param core_id Core ID which is supplied by interface layer 32 * @param is_identified Flag variable to return device 33 * identification status 34 * 35 * @return PHYMOD_E_NONE successful function execution 36 */ 37 int madura_core_identify(const phymod_core_access_t* core, uint32_t core_id, uint32_t* is_identified) 38 { 39 const phymod_access_t *pm_acc = &core->access; 40 uint32_t chip_id; 41 uint32_t rev_id; 42 43 PMD_IDENTIFIER_0r_t id0; 44 PMD_IDENTIFIER_1r_t id1; 45 46 PHYMOD_MEMSET(&id0, 0, sizeof(PMD_IDENTIFIER_0r_t)); 47 PHYMOD_MEMSET(&id1, 0, sizeof(PMD_IDENTIFIER_1r_t)); 48 *is_identified = 0; 49 50 if (core_id == 0) { 51 PHYMOD_IF_ERR_RETURN ( 52 READ_PMD_IDENTIFIER_1r(pm_acc, &id1)); 53 PHYMOD_IF_ERR_RETURN ( 54 READ_PMD_IDENTIFIER_0r(pm_acc, &id0)); 55 } else { 56 id0.v[0] = (core_id >> 16) & 0xffff; 57 id1.v[0] = core_id & 0xffff; 58 /* id1=core_id & 0xffff; */ 59 } 60 /* 61 * Add support for incorrect OTP with improper IEEE IDs 62 * if (id0.v[0] == MADURA_PMD_ID0 && id1.v[0] == MADURA_PMD_ID1) 63 */ { 64 /* PHY IDs match - now check model */ 65 PHYMOD_IF_ERR_RETURN(madura_get_chipid(pm_acc, &chip_id, &rev_id)); 66 if (chip_id == MADURA_CHIP_ID_82864) { 67 *is_identified = 1; 68 } 69 } 70 71 return PHYMOD_E_NONE; 72 } 73 74 75 /** Core information 76 * This function gives the core version 77 * 78 * @param core Pointer to phymod core access structure 79 * @param info Pointer to core version 80 * 81 * @return PHYMOD_E_NONE successful function execution 82 */ 83 int madura_core_info_get(const phymod_core_access_t* core, phymod_core_info_t* info) 84 { 85 uint32_t chip_id; 86 uint32_t rev_id; 87 PMD_IDENTIFIER_0r_t id0; 88 PMD_IDENTIFIER_1r_t id1; 89 90 PHYMOD_IF_ERR_RETURN ( 91 madura_get_chipid(&core->access, &chip_id, &rev_id)); 92 info->serdes_id = chip_id; 93 info->core_version = phymodCoreVersionMadura; 94 PHYMOD_STRNCPY(info->name, "Madura", PHYMOD_STRLEN("Madura")+1); 95 96 PHYMOD_IF_ERR_RETURN ( 97 READ_PMD_IDENTIFIER_1r(&core->access, &id1)); 98 info->phy_id1 = id1.v[0]; 99 PHYMOD_IF_ERR_RETURN ( 100 READ_PMD_IDENTIFIER_0r(&core->access, &id0)); 101 info->phy_id0 = id0.v[0]; 102 103 return PHYMOD_E_NONE; 104 105 } 106 107 /** Get Firmware info 108 * This function get the firmware information such as master firmware version and master checksum 109 * 110 * @param core Pointer to phymod core access structure 111 * @param fw_info Represent firmware version and checksum. 112 * 113 * @return PHYMOD_E_NONE successful function execution 114 */ 115 int madura_core_firmware_info_get(const phymod_core_access_t* core, phymod_core_firmware_info_t* fw_info) 116 { 117 118 FIRMWARE_VERSIONr_t firmware_version; 119 MST_RUNNING_CHKSUMr_t mst_running_chksum; 120 121 /* Read the firmware version */ 122 PHYMOD_IF_ERR_RETURN( 123 READ_FIRMWARE_VERSIONr(&core->access, &firmware_version)); 124 125 fw_info->fw_version = FIRMWARE_VERSIONr_FIRMWARE_VERSION_VALf_GET(firmware_version); 126 127 PHYMOD_IF_ERR_RETURN( 128 READ_MST_RUNNING_CHKSUMr(&core->access, &mst_running_chksum)); 129 130 fw_info->fw_crc = MST_RUNNING_CHKSUMr_MST_RUNNING_CHKSUM_VALf_GET(mst_running_chksum); 131 132 return PHYMOD_E_NONE; 133 134 } 135 136 /** Core Reset 137 * This function reset madura core, it support hard and soft reset 138 * 139 * @param core Pointer to phymod core access structure 140 * @param reset_mode Represent hard/soft reset to perform 141 * @param direction Represet direction of reset. Sesto ignore this parameter 142 * 143 * @return PHYMOD_E_NONE successful function execution 144 */ 145 int madura_core_reset_set(const phymod_core_access_t* core, phymod_reset_mode_t reset_mode, phymod_reset_direction_t direction) 146 { 147 return _madura_core_reset_set(&core->access, reset_mode, direction); 148 149 } 150 151 int madura_core_reset_get(const phymod_core_access_t* core, phymod_reset_mode_t reset_mode, phymod_reset_direction_t* direction) 152 { 153 154 155 /* Place your code here */ 156 157 158 return PHYMOD_E_UNAVAIL; 159 160 } 161 162 int madura_phy_firmware_lane_config_set(const phymod_phy_access_t* phy, phymod_firmware_lane_config_t fw_config) 163 { 164 return _madura_firmware_lane_config_set(&phy->access, fw_config); 165 } 166 167 168 int madura_phy_firmware_lane_config_get(const phymod_phy_access_t* phy, phymod_firmware_lane_config_t* fw_config) 169 { 170 return _madura_firmware_lane_config_get(&phy->access, fw_config); 171 } 172 173 174 /** Restart PLL Sequecer 175 * This function is used to get restart the PLL sequencer 176 * 177 * 178 * @param core Pointer to phymod core access structure 179 * @param flags Reserved for Furtuer use 180 * @param operation Operation to perform on PLL sequencer 181 * 182 * @return PHYMOD_E_NONE successful function execution 183 */ 184 185 int madura_core_pll_sequencer_restart(const phymod_core_access_t* core, uint32_t flags, phymod_sequencer_operation_t operation) 186 { 187 return _madura_pll_sequencer_restart(core, operation); 188 } 189 190 /** Tx Rx power Set 191 * This function is used to set TX/RX power options 192 * 193 * @param phy Pointer to phymod phy access structure 194 * @param power Pointer to phymod phy power structure 195 * to set TX Power and RX Power 196 * 197 * @return PHYMOD_E_NONE successful function execution 198 */ 199 int madura_phy_power_set(const phymod_phy_access_t* phy, const phymod_phy_power_t* power) 200 { 201 PHYMOD_IF_ERR_RETURN( 202 _madura_tx_power_set(&phy->access, power->tx)); 203 PHYMOD_IF_ERR_RETURN( 204 _madura_rx_power_set(&phy->access, power->rx)); 205 return PHYMOD_E_NONE; 206 207 } 208 209 /** Tx set 210 * This function is used to set transmitter analog parameters 211 * 212 * @param phy Pointer to phymod phy access structure 213 * @param tx Pointer to tx param structure 214 * 215 * @return PHYMOD_E_NONE successful function execution 216 */ 217 218 int madura_phy_tx_set(const phymod_phy_access_t* phy, const phymod_tx_t* tx) 219 { 220 221 return _madura_tx_set(&phy->access, tx); 222 223 } 224 225 /** Tx get 226 * This function is used to get transmitter analog parameters 227 * 228 * @param phy Pointer to phymod phy access structure 229 * @param tx Pointer to tx param structure 230 * 231 * @return PHYMOD_E_NONE successful function execution 232 */ 233 int madura_phy_tx_get(const phymod_phy_access_t* phy, phymod_tx_t* tx) 234 { 235 236 return _madura_tx_get(&phy->access, tx); 237 238 } 239 240 /** Rx set 241 * This function is used to set receiver analog parameters 242 * 243 * @param phy Pointer to phymod phy access structure 244 * @param rx Pointer to rx param structure 245 * 246 * @return PHYMOD_E_NONE successful function execution 247 */ 248 249 int madura_phy_rx_set(const phymod_phy_access_t* phy, const phymod_rx_t* rx) 250 { 251 252 return _madura_rx_set(&phy->access, rx); 253 254 } 255 256 /** Rx get 257 * This function is used to get receiver analog parameters 258 * 259 * @param phy Pointer to phymod phy access structure 260 * @param rx Pointer to rx param structure 261 * 262 * @return PHYMOD_E_NONE successful function execution 263 */ 264 int madura_phy_rx_get(const phymod_phy_access_t* phy, phymod_rx_t* rx) 265 { 266 267 return _madura_rx_get(&phy->access, rx); 268 269 } 270 271 /** PHY Rx adaptation resume 272 * This function is used to perform PHY reset 273 * 274 * @param phy Pointer to phymod phy access structure 275 * 276 * @return PHYMOD_E_NONE successful function execution 277 */ 278 int madura_phy_rx_adaptation_resume(const phymod_phy_access_t* phy) 279 { 280 return _madura_rx_adaptation_resume(&phy->access); 281 } 282 283 /** Tx Rx power Get 284 * This function is used to get TX/RX power options 285 * 286 * @param phy Pointer to phymod phy access structure 287 * @param power Pointer to phymod phy power structure 288 * to get TX Power and RX Power 289 * 290 * @return PHYMOD_E_NONE successful function execution 291 */ 292 293 294 int madura_phy_power_get(const phymod_phy_access_t* phy, phymod_phy_power_t* power) 295 { 296 return _madura_tx_rx_power_get(&phy->access, power); 297 298 } 299 300 /** Tx lane control set 301 * This function is used to set the lane control for example 302 * resetting the traffic 303 * 304 * @param phy Pointer to phymod phy access structure 305 * @param tx_control Tx lane control 306 * 0 - Traffic disable, currently not available 307 * 1 - Traffic enable, currently not available 308 * 2 - Tx Datapath reset 309 * 3 - Tx Squelch on 310 * 4 - Tx Squelch off 311 * 312 * @return PHYMOD_E_NONE successful function execution 313 */ 314 315 int madura_phy_tx_lane_control_set(const phymod_phy_access_t* phy, phymod_phy_tx_lane_control_t tx_control) 316 { 317 return _madura_tx_lane_control_set(&phy->access, tx_control); 318 } 319 320 /** Tx lane control get 321 * This function is used to get the lane control for example 322 * resetting the traffic 323 * 324 * @param phy Pointer to phymod phy access structure 325 * @param tx_control 326 * 0 - Traffic disable, currently not available 327 * 1 - Traffic enable, currently not available 328 * 2 - Tx Datapath reset 329 * 3 - Tx Squelch on 330 * 4 - Tx Squelch off 331 * 332 * Return value of tx_control is enable or disable of specified lane control option 333 * 334 * @return PHYMOD_E_NONE successful function execution 335 */ 336 337 int madura_phy_tx_lane_control_get(const phymod_phy_access_t* phy, phymod_phy_tx_lane_control_t* tx_control) 338 { 339 return _madura_tx_lane_control_get(&phy->access, tx_control); 340 } 341 342 343 /** Rx lane control set 344 * This function is used to set the lane control for example 345 * resetting the traffic 346 * 347 * @param phy Pointer to phymod phy access structure 348 * @param rx_control Rx lane control 349 * 0 - Rx datapath reset 350 * 1 - Rx squelch on 351 * 2 - Rx squelch off 352 * 353 * @return PHYMOD_E_NONE successful function execution 354 */ 355 356 int madura_phy_rx_lane_control_set(const phymod_phy_access_t* phy, phymod_phy_rx_lane_control_t rx_control) 357 { 358 return _madura_rx_lane_control_set(&phy->access, rx_control); 359 } 360 361 /** Rx lane control get 362 * This function is used to set the lane control for example 363 * resetting the traffic 364 * 365 * @param phy Pointer to phymod phy access structure 366 * @param rx_control Rx lane control 367 * 0 - Rx datapath reset 368 * 1 - Rx squelch on 369 * 2 - Rx squelch off 370 * 371 * Return value of tx_control is enable or disable of specified lane control option 372 * 373 * @return PHYMOD_E_NONE successful function execution 374 */ 375 376 int madura_phy_rx_lane_control_get(const phymod_phy_access_t* phy, phymod_phy_rx_lane_control_t* rx_control) 377 { 378 return _madura_rx_lane_control_get(&phy->access, rx_control); 379 } 380 381 /** PHY polarity set 382 * This function is used to set the lane polarity 383 * 384 * @param phy Pointer to phymod phy access structure 385 * @param polarity Pointer to phymod_polarity_t for rx and tx 386 * 387 * @return PHYMOD_E_NONE successful function execution 388 */ 389 int madura_phy_polarity_set(const phymod_phy_access_t* phy, const phymod_polarity_t* polarity) 390 { 391 return _madura_tx_rx_polarity_set(&phy->access, polarity->tx_polarity, polarity->rx_polarity); 392 } 393 394 395 /** PHY polarity get 396 * This function is used to get the lane polarity 397 * 398 * @param phy Pointer to phymod phy access structure 399 * @param polarity Pointer to phymod_polarity_t for rx and tx 400 * 401 * @return PHYMOD_E_NONE successful function execution 402 */ 403 int madura_phy_polarity_get(const phymod_phy_access_t* phy, phymod_polarity_t* polarity) 404 { 405 return _madura_tx_rx_polarity_get(&phy->access, &polarity->tx_polarity, &polarity->rx_polarity); 406 } 407 408 int madura_phy_interface_config_set(const phymod_phy_access_t* phy, uint32_t flags, const phymod_phy_inf_config_t* config) 409 { 410 uint16_t retry_cnt = 5; 411 FIRMWARE_ENr_t fwe; 412 413 PHYMOD_IF_ERR_RETURN ( 414 _madura_phy_interface_config_set(phy, flags, config)); 415 416 /* Enable FW After configuring mode */ 417 PHYMOD_IF_ERR_RETURN( 418 _madura_fw_enable(&phy->access, MADURA_ENABLE)); 419 420 do { 421 PHYMOD_USLEEP(100); 422 423 PHYMOD_IF_ERR_RETURN( 424 READ_FIRMWARE_ENr(&phy->access, &fwe)); 425 } while ((FIRMWARE_ENr_FW_ENABLE_VALf_GET(fwe) != 0) && (retry_cnt --)); 426 427 if (retry_cnt == 0) { 428 PHYMOD_DEBUG_VERBOSE(("WARN:: FW Enable not cleared\n")); 429 } 430 PHYMOD_USLEEP(500000); /* sleep added for standalone prns issue */ 431 return PHYMOD_E_NONE; 432 433 } 434 435 /** Set interface config 436 * This function sets interface configuration (interface, speed, frequency of 437 * operation, PT mode, BCM84793 etc). 438 * This is requried to put the chip into specific mode specified 439 * 440 * NOTE: Default system side interface type will be IEEE mode and speed is compatible with lane side configured speed. 441 * Ex: User configured 40G speed with interface type KR4 on lane side then system side speed is 40G and interface type is IEEE mode. 442 * 443 * @param phy Pointer to phymod phy access structure 444 * @param flags Reserved for future use 445 * @param config Interface config structure where user specifies 446 * - Interface Type 447 * - Speed 448 * - Frequency. 449 * - device_aux_modes : a structure that have auxilary mode details 450 * -> pass_thru : To enable repeater on 10/40G mode of operation 451 * -> gearbox_100g_inverse_mode : Applicable only for 100G mode, 25G lanes on system side and 452 * 10G lanes on line side 453 * -> BCM84793_capablity : To enable BCM84793 compatible on lanes 454 * -> passthru_sys_side_core : When pass through is enabled user are allowed to configure system side 455 * core i.e. 25G lanes or 10G lanes 456 * -> reserved: Only for future use 457 * 458 * @return PHYMOD_E_NONE successful function execution 459 */ 460 int madura_phy_interface_config_get(const phymod_phy_access_t* phy, uint32_t flags, phymod_ref_clk_t ref_clock, phymod_phy_inf_config_t* config) 461 { 462 463 MADURA_DEVICE_AUX_MODE_T *aux_mode; 464 465 config->device_aux_modes = PHYMOD_MALLOC(sizeof(MADURA_DEVICE_AUX_MODE_T), "madura_device_aux_mode"); 466 aux_mode = (MADURA_DEVICE_AUX_MODE_T*) config->device_aux_modes; 467 if (aux_mode == NULL) { 468 PHYMOD_DEBUG_VERBOSE(("AUX MODE MEM NOT ALLOC\n")); 469 return PHYMOD_E_PARAM; 470 } 471 PHYMOD_MEMSET(aux_mode, 0, sizeof(MADURA_DEVICE_AUX_MODE_T)); 472 473 MADURA_IF_ERR_RETURN_FREE(config->device_aux_modes, ( 474 _madura_phy_interface_config_get(&phy->access, flags, config))); 475 476 PHYMOD_FREE(config->device_aux_modes); 477 return PHYMOD_E_NONE; 478 479 } 480 481 /** Madura core initialization 482 * This function initialize the madura core by downlaoding the firmware. 483 * 484 * @param core Pointer to phymod core access structure 485 * @param init_config Init configuration specified by user 486 * @param core_status PMD status read from PHY chip 487 * 488 * @return PHYMOD_E_NONE successful function execution 489 */ 490 491 492 int madura_core_init(const phymod_core_access_t* core, const phymod_core_init_config_t* init_config, const phymod_core_status_t* core_status) 493 { 494 uint32_t new_firmware_version=0; 495 phymod_core_firmware_info_t fw_info; 496 497 PHYMOD_MEMSET(&fw_info, 0, sizeof(phymod_core_firmware_info_t)); 498 PHYMOD_IF_ERR_RETURN( 499 madura_core_firmware_info_get(core, &fw_info)); 500 new_firmware_version = madura_falcon_ucode[madura_falcon_ucode_len-4]<<8 | madura_falcon_ucode[madura_falcon_ucode_len-3]; 501 502 if(PHYMOD_CORE_INIT_F_FW_AUTO_DOWNLOAD_GET(init_config)){/* for auto download*/ 503 if( new_firmware_version != fw_info.fw_version){ 504 PHYMOD_IF_ERR_RETURN( 505 _madura_core_init(core, init_config)); 506 } 507 }else{ /*rest of the cases continue like before*/ 508 PHYMOD_IF_ERR_RETURN( 509 _madura_core_init(core, init_config)); 510 } 511 512 return PHYMOD_E_NONE; 513 514 } 515 516 517 int madura_phy_init(const phymod_phy_access_t* phy, const phymod_phy_init_config_t* init_config) 518 { 519 PHYMOD_IF_ERR_RETURN( 520 madura_phy_interface_config_set(phy, 0, &init_config->interface)); 521 /*enable/disable repeater/retimer*/ 522 if (init_config->op_mode == phymodOperationModeRetimer) { 523 PHYMOD_IF_ERR_RETURN 524 (_madura_core_rptr_rtmr_mode_set(&phy->access, phymodOperationModeRetimer)); 525 } else { 526 /* By default HW set it as repeater*/ 527 (_madura_core_rptr_rtmr_mode_set(&phy->access, phymodOperationModeRepeater)); 528 } 529 return PHYMOD_E_NONE; 530 531 } 532 533 /** Set loopback 534 * This function is used to set a particular loopback mode 535 * 536 * @param phy Pointer to phymod phy access structure 537 * @param loopback Type of loopback 538 * 0 - Global loopback 539 * 1 - Global PMD loopback 540 * 2 - Remote PMD loopback 541 * 3 - Remote PCS loopback 542 * 4 - Digital PMD loopback 543 * @enable Enable or disable 544 * 0 - disable 545 * 1 - enable 546 * 547 * @return PHYMOD_E_NONE successful function execution 548 */ 549 int madura_phy_loopback_set(const phymod_phy_access_t* phy, phymod_loopback_mode_t loopback, uint32_t enable) 550 { 551 uint32_t ena_dis = 0; 552 _madura_loopback_get(&phy->access, loopback, &ena_dis); 553 if (ena_dis || enable) { 554 return _madura_loopback_set(&phy->access, loopback, enable); 555 } 556 return PHYMOD_E_NONE; 557 } 558 559 /** Get loopback 560 * This function is used to get the status of a particular loopback mode 561 * whether or not enabled 562 * 563 * @param phy Pointer to phymod phy access structure 564 * @param loopback Type of loopback 565 * 0 - Global loopback 566 * 1 - Global PMD loopback 567 * 2 - Remote PMD loopback 568 * 3 - Remote PCS loopback 569 * 4 - Digital PMD loopback 570 * @enable Enable or disable 571 * 0 - disable 572 * 1 - enable 573 * 574 * @return PHYMOD_E_NONE successful function execution 575 */ 576 int madura_phy_loopback_get(const phymod_phy_access_t* phy, phymod_loopback_mode_t loopback, uint32_t* enable) 577 { 578 return _madura_loopback_get(&phy->access, loopback, enable); 579 } 580 581 582 /** Get PHY RX PMD link status 583 * This function retrieves RX PMD lock status of madura 584 * 585 * @param phy Pointer to phymod phy access structure 586 * @param rx_pmd_locked Rx PMD Link status retrieved from Madura 587 * 588 * @return PHYMOD_E_NONE successful function execution 589 */ 590 591 int madura_phy_rx_pmd_locked_get(const phymod_phy_access_t* phy, uint32_t* rx_pmd_locked) 592 { 593 594 return (_madura_rx_pmd_lock_get(&phy->access, rx_pmd_locked)); 595 596 } 597 598 599 /** Get PCS link status 600 * This function retrieves PCS link status of madura when PCS Monitor is enabled, 601 * This function return PMD lock when PCS monitor is disabled. 602 * 603 * @param phy Pointer to phymod phy access structure 604 * @param link_status Retrives PCS Link of Madura 605 * 606 * @return PHYMOD_E_NONE successful function execution 607 */ 608 609 int madura_phy_link_status_get(const phymod_phy_access_t* phy, uint32_t* link_status) 610 { 611 return _madura_get_pcs_link_status(&phy->access, link_status); 612 613 } 614 615 616 int madura_phy_status_dump(const phymod_phy_access_t* phy) 617 { 618 return _madura_phy_status_dump(&phy->access); 619 } 620 621 622 /** Read Register 623 * This function read user specified register based on the specified Device type 624 * 625 * @param phy Pointer to phymod phy access structure. 626 * @param reg_addr Madura register address 627 * @param val Output parameter, represents the value of address specified 628 * 629 * @return PHYMOD_E_NONE successful function execution 630 */ 631 int madura_phy_reg_read(const phymod_phy_access_t* phy, uint32_t reg_addr, uint32_t* val) 632 { 633 uint16_t dev_add = 0; 634 dev_add = (phy->access.devad) ? phy->access.devad : MADURA_DEV_PMA_PMD; 635 636 if (dev_add == MADURA_DEV_PMA_PMD) { 637 READ_MADURA_PMA_PMD_REG(&phy->access, reg_addr, *val); 638 } else { 639 READ_MADURA_AN_REG(&phy->access, reg_addr, *val); 640 } 641 642 return PHYMOD_E_NONE; 643 644 } 645 646 647 /** Write Register 648 * This function write user specified value to the specified address 649 * based on the specified Device type 650 * 651 * @param phy Pointer to phymod phy access structure. 652 * @param reg_addr Madura register address 653 * @param val Represents the value to be written 654 * 655 * @return PHYMOD_E_NONE successful function execution 656 */ 657 int madura_phy_reg_write(const phymod_phy_access_t* phy, uint32_t reg_addr, uint32_t val) 658 { 659 660 uint16_t dev_add = 0; 661 dev_add = (phy->access.devad) ? phy->access.devad : MADURA_DEV_PMA_PMD; 662 PHYMOD_DEBUG_VERBOSE(("WRITE reg:%x data:%x\n", reg_addr, val)); 663 if (dev_add == MADURA_DEV_PMA_PMD) { 664 WRITE_MADURA_PMA_PMD_REG(&phy->access, reg_addr, val); 665 } else { 666 WRITE_MADURA_AN_REG(&phy->access, reg_addr, val); 667 } 668 669 return PHYMOD_E_NONE; 670 671 } 672 673 /** Tx Rx Phy Reset Set 674 * This function is used to set TX/RX Phy Reset options 675 * 676 * @param phy Pointer to phymod phy access structure 677 * @param reset Pointer to phymod phy reset structure 678 * to set TX Reset and RX Reset 679 * 680 * @return PHYMOD_E_NONE successful function execution 681 */ 682 683 int madura_phy_reset_set(const phymod_phy_access_t* phy, const phymod_phy_reset_t* reset) 684 { 685 return _madura_phy_reset_set(&phy->access, reset); 686 } 687 /** Tx Rx Phy Reset Get 688 * This function is used to get TX/RX Phy Reset options 689 * 690 * @param phy Pointer to phymod phy access structure 691 * @param reset Pointer to phymod phy reset structure 692 * to get TX Reset and RX Reset 693 * 694 * @return PHYMOD_E_NONE successful function execution 695 */ 696 int madura_phy_reset_get(const phymod_phy_access_t* phy, phymod_phy_reset_t* reset) 697 { 698 return _madura_phy_reset_get(&phy->access, reset); 699 } 700 701 702 /** FEC enable set 703 * This function is used to enable the FEC 704 * 705 * @param phy Pointer to phymod phy access structure 706 * @param enable enable or disable 707 * 1 - enable 708 * 0 - disable 709 * 710 * @return PHYMOD_E_NONE successful function execution 711 */ 712 int madura_phy_fec_enable_set(const phymod_phy_access_t* phy, uint32_t enable) 713 { 714 return _madura_fec_enable_set(&phy->access, enable); 715 } 716 /** FEC enable get 717 * This function is used to check whether or not FEC is enabled 718 * 719 * @param phy Pointer to phymod phy access structure 720 * @param enable enable or disable 721 * 1 - enable 722 * 0 - disable 723 * 724 * @return PHYMOD_E_NONE successful function execution 725 */ 726 int madura_phy_fec_enable_get(const phymod_phy_access_t* phy, uint32_t* enable) 727 { 728 return _madura_fec_enable_get(&phy->access, enable); 729 } 730 731 732 /** Set CL72 733 * This function is used to enable/disable forced Tx training 734 * 735 * @param phy Pointer to phymod phy access structure 736 * @param enable enable / disable force Tx training 737 * 1 - enable 738 * 0 - disable 739 * 740 * @return PHYMOD_E_NONE successful function execution 741 */ 742 743 int madura_phy_cl72_set(const phymod_phy_access_t* phy, uint32_t cl72_en) 744 { 745 return _madura_force_tx_training_set(&phy->access, cl72_en); 746 } 747 748 /** Get CL72 749 * This function is used to get the status whether Tx training is enabled or disabled 750 * 751 * @param phy Pointer to phymod phy access structure 752 * @param enable enable or disable 753 * 1 - enable 754 * 0 - disable 755 * 756 * @return PHYMOD_E_NONE successful function execution 757 */ 758 759 int madura_phy_cl72_get(const phymod_phy_access_t* phy, uint32_t* cl72_en) 760 { 761 return _madura_force_tx_training_get(&phy->access, cl72_en); 762 } 763 764 765 /** Get CL72 status 766 * This function is used to get the status of Tx training 767 * 768 * @param phy Pointer to phymod phy access structure 769 * @param status CL72 Training status 770 * 771 * @return PHYMOD_E_NONE successful function execution 772 */ 773 774 int madura_phy_cl72_status_get(const phymod_phy_access_t* phy, phymod_cl72_status_t* status) 775 { 776 return _madura_force_tx_training_status_get(&phy->access, status); 777 } 778 779 /** PHY CL73 ability Set 780 * This function is used to set the CL73 ability of a lane 781 * 782 * @param phy Pointer to phymod phy access structure 783 * @param an_ability Pointer to the ability of cl73 784 * 785 * @return PHYMOD_E_NONE successful function execution 786 */ 787 int madura_phy_autoneg_ability_set(const phymod_phy_access_t* phy, const phymod_autoneg_ability_t* an_ability) 788 { 789 madura_an_ability_t value; 790 int rv = PHYMOD_E_NONE; 791 792 PHYMOD_MEMSET(&value, 0, sizeof(value)); 793 value.cl73_adv.an_fec = an_ability->an_fec; 794 value.an_master_lane = an_ability->an_master_lane; 795 /*check if sgmii or not */ 796 if (PHYMOD_AN_CAP_SGMII_GET(an_ability)){ 797 return rv; 798 } 799 800 /*next check pause */ 801 if (PHYMOD_AN_CAP_SYMM_PAUSE_GET(an_ability)) { 802 value.cl73_adv.an_pause = MADURA_SYMM_PAUSE; 803 } else if (PHYMOD_AN_CAP_ASYM_PAUSE_GET(an_ability)) { 804 value.cl73_adv.an_pause = MADURA_ASYM_PAUSE; 805 } else { 806 value.cl73_adv.an_pause = MADURA_NO_PAUSE; 807 } 808 809 /*check cl73 and cl73 bam ability */ 810 if (PHYMOD_AN_CAP_40G_KR4_GET(an_ability->an_cap)) { 811 value.cl73_adv.an_base_speed = MADURA_CL73_40GBASE_KR4; 812 } else if (PHYMOD_AN_CAP_40G_CR4_GET(an_ability->an_cap)) { 813 value.cl73_adv.an_base_speed = MADURA_CL73_40GBASE_CR4; 814 } else if (PHYMOD_AN_CAP_100G_CR4_GET(an_ability->an_cap)) { 815 value.cl73_adv.an_base_speed = MADURA_CL73_100GBASE_CR4; 816 } else if (PHYMOD_AN_CAP_100G_KR4_GET(an_ability->an_cap)) { 817 value.cl73_adv.an_base_speed = MADURA_CL73_100GBASE_KR4; 818 } else if (an_ability->an_cap == 0) { 819 return rv; 820 } else { 821 return PHYMOD_E_PARAM; 822 } 823 824 PHYMOD_IF_ERR_RETURN 825 (_madura_autoneg_ability_set(&phy->access, &value)); 826 827 return rv; 828 829 } 830 831 /** PHY CL73 ability get 832 * This function is used to get the CL73 ability of a lane 833 * 834 * @param phy Pointer to phymod phy access structure 835 * @param an_ability Pointer to the ability of cl73 836 * 837 * @return PHYMOD_E_NONE successful function execution 838 */ 839 840 int madura_phy_autoneg_ability_get(const phymod_phy_access_t* phy, phymod_autoneg_ability_t* an_ability_get_type) 841 { 842 madura_an_ability_t value; 843 844 PHYMOD_IF_ERR_RETURN( 845 _madura_autoneg_ability_get(&phy->access, &value)); 846 847 an_ability_get_type->an_fec = value.cl73_adv.an_fec; 848 an_ability_get_type->an_master_lane = value.an_master_lane ; 849 switch (value.cl73_adv.an_pause) { 850 case MADURA_ASYM_PAUSE: 851 PHYMOD_AN_CAP_ASYM_PAUSE_SET(an_ability_get_type); 852 break; 853 case MADURA_SYMM_PAUSE: 854 PHYMOD_AN_CAP_SYMM_PAUSE_SET(an_ability_get_type); 855 break; 856 default: 857 break; 858 } 859 860 /*first check cl73 ability*/ 861 switch (value.cl73_adv.an_base_speed) { 862 case MADURA_CL73_40GBASE_CR4: 863 PHYMOD_AN_CAP_40G_CR4_SET(an_ability_get_type->an_cap); 864 break; 865 case MADURA_CL73_40GBASE_KR4: 866 PHYMOD_AN_CAP_40G_KR4_SET(an_ability_get_type->an_cap); 867 break; 868 case MADURA_CL73_100GBASE_CR4: 869 PHYMOD_AN_CAP_100G_CR4_SET(an_ability_get_type->an_cap); 870 break; 871 case MADURA_CL73_100GBASE_KR4: 872 PHYMOD_AN_CAP_100G_KR4_SET(an_ability_get_type->an_cap); 873 break; 874 default: 875 break; 876 } 877 878 return PHYMOD_E_NONE; 879 } 880 881 /** PHY CL73 remote ability get 882 * This function is used to get the CL73 remote ability of a lane 883 * 884 * @param phy Pointer to phymod phy access structure 885 * @param an_ability Pointer to the ability of cl73 886 * 887 * @return PHYMOD_E_NONE successful function execution 888 */ 889 int madura_phy_autoneg_remote_ability_get(const phymod_phy_access_t* phy, phymod_autoneg_ability_t* an_ability_get) 890 { 891 int rv = PHYMOD_E_NONE; 892 893 PHYMOD_IF_ERR_RETURN( 894 _madura_autoneg_remote_ability_get(&phy->access, an_ability_get)); 895 896 return rv; 897 } 898 899 /** PHY enable/Disable CL73 900 * This function is used to enable/disable CL73 of a lane 901 * 902 * @param phy Pointer to phymod phy access structure 903 * @param an Pointer to the AN control 904 * 905 * @return PHYMOD_E_NONE successful function execution 906 */ 907 int madura_phy_autoneg_set(const phymod_phy_access_t* phy, const phymod_autoneg_control_t* an) 908 { 909 return (_madura_autoneg_set(phy, an)); 910 } 911 912 /** Get CL73 completion state 913 * This function is used get CL73 completion state of a lane 914 * 915 * @param phy Pointer to phymod phy access structure 916 * @param an Pointer to the AN control 917 * @param an_done Pointer to the AN completion state 918 * 919 * @return PHYMOD_E_NONE successful function execution 920 */ 921 int madura_phy_autoneg_get(const phymod_phy_access_t* phy, phymod_autoneg_control_t* an, uint32_t* an_done) 922 { 923 return (_madura_autoneg_get(&phy->access, an, an_done)); 924 } 925 926 927 int madura_phy_autoneg_status_get(const phymod_phy_access_t* phy, phymod_autoneg_status_t* status) 928 { 929 930 /* Place your code here */ 931 return PHYMOD_E_NONE; 932 933 } 934 /** Interrupt enable set 935 * This function is used to enable or disable particular interrupt 936 * 937 * @param phy Pointer to phymod phy access structure 938 * @param enable Pending status mask 939 * 940 * @return PHYMOD_E_NONE successful function execution 941 */ 942 int madura_phy_intr_enable_set(const phymod_phy_access_t* phy, uint32_t enable) 943 { 944 uint32_t intr_index = 0; 945 946 for (intr_index = 0; intr_index < MADURA_MAX_INTRS_SUPPORT; intr_index ++) { 947 if (enable & (0x1 << intr_index)) { 948 PHYMOD_IF_ERR_RETURN(_madura_ext_intr_enable_set(phy, (0x1 << intr_index), 1)); 949 }else{ 950 PHYMOD_IF_ERR_RETURN(_madura_ext_intr_enable_set(phy, (0x1 << intr_index), 0)); 951 } 952 } 953 return PHYMOD_E_NONE; 954 } 955 956 /** Interrupt enable get 957 * This function is used to check whether or not particular interrupt is enabled 958 * 959 * @param phy Pointer to phymod phy access structure 960 * @param enable Enable mask 961 * 962 * @return PHYMOD_E_NONE successful function execution 963 */ 964 int madura_phy_intr_enable_get(const phymod_phy_access_t* phy, uint32_t* enable) 965 { 966 uint32_t intr_index = 0; 967 uint32_t value = 0; 968 969 *enable = 0; 970 for (intr_index = 0; intr_index < MADURA_MAX_INTRS_SUPPORT; intr_index ++) { 971 PHYMOD_IF_ERR_RETURN( 972 _madura_ext_intr_enable_get(phy, (0x1 << intr_index), &value)); 973 if (value) { 974 *enable |= (0x1 << intr_index); 975 } 976 } 977 return PHYMOD_E_NONE; 978 979 980 } 981 982 /** Interrupt status get 983 * This function is used to check whether or not particualr interrupt is pending 984 * 985 * @param phy Pointer to phymod phy access structure 986 * @param status Pending status mask 987 * 988 * @return PHYMOD_E_NONE successful function execution 989 */ 990 int madura_phy_intr_status_get(const phymod_phy_access_t* phy, uint32_t* intr_status) 991 { 992 993 uint32_t intr_index = 0; 994 uint32_t value = 0; 995 996 for (intr_index = 0; intr_index < MADURA_MAX_INTRS_SUPPORT; intr_index ++) { 997 PHYMOD_IF_ERR_RETURN( 998 _madura_ext_intr_status_get(phy,(0x1 << intr_index), &value)); 999 if (value) { 1000 *intr_status |= (0x1 << intr_index); 1001 } 1002 } 1003 return PHYMOD_E_NONE; 1004 } 1005 1006 /** Interrupt status clear 1007 * This function is used for clearing interrupt status 1008 * 1009 * @param phy Pointer to phymod phy access structure 1010 * @param uint32 clear mask 1011 * 1012 * @return PHYMOD_E_NONE successful function execution 1013 */ 1014 int madura_phy_intr_status_clear(const phymod_phy_access_t* phy, uint32_t intr_clear) 1015 { 1016 1017 uint32_t intr_index = 0; 1018 1019 for (intr_index = 0; intr_index < MADURA_MAX_INTRS_SUPPORT; intr_index ++) { 1020 if (intr_clear & (0x1 << intr_index)) { 1021 PHYMOD_IF_ERR_RETURN( 1022 _madura_ext_intr_status_clear(phy, (0x1 << intr_index))); 1023 } 1024 } 1025 return PHYMOD_E_NONE; 1026 } 1027 1028 1029 int madura_phy_i2c_read(const phymod_phy_access_t* phy, uint32_t flags, uint32_t addr, uint32_t offset, uint32_t size, uint8_t* data) 1030 { 1031 return _madura_module_read(&phy->access, addr, offset, size, data); 1032 } 1033 1034 1035 int madura_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) 1036 { 1037 return _madura_module_write(&phy->access, addr, offset, size, data); 1038 } 1039 1040 1041 int madura_phy_gpio_config_set(const phymod_phy_access_t* phy, int pin_no, phymod_gpio_mode_t gpio_mode) 1042 { 1043 return _madura_gpio_config_set(&phy->access, pin_no, gpio_mode); 1044 } 1045 1046 int madura_phy_gpio_config_get(const phymod_phy_access_t* phy, int pin_no, phymod_gpio_mode_t* gpio_mode) 1047 { 1048 return _madura_gpio_config_get(&phy->access, pin_no, gpio_mode); 1049 } 1050 1051 1052 int madura_phy_gpio_pin_value_set(const phymod_phy_access_t* phy, int pin_no, int value) 1053 { 1054 return _madura_gpio_pin_value_set(&phy->access, pin_no, value); 1055 1056 } 1057 1058 int madura_phy_gpio_pin_value_get(const phymod_phy_access_t* phy, int pin_no, int* value) 1059 { 1060 return _madura_gpio_pin_value_get(&phy->access, pin_no, value); 1061 } 1062 1063 int madura_phy_op_mode_get(const phymod_phy_access_t* phy, phymod_operation_mode_t* op_mode) 1064 { 1065 return PHYMOD_E_UNAVAIL; 1066 } 1067 1068 #endif /* PHYMOD_MADURA_SUPPORT */