openbcm

Git mirror of https://github.com/Broadcom-Network-Switching-Software/OpenBCM
git clone git://git.finwo.net/mirror/broadcom/openbcm
Log | Files | Refs | README

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 */