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

huracan_cfg_seq.c (39481B)


      1 /*
      2  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      3  * 
      4  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      5  * 
      6  */
      7 
      8 /*
      9  *
     10  *
     11  * This program is the proprietary software of Broadcom Corporation
     12  * and/or its licensors, and may only be used, duplicated, modified
     13  * or distributed pursuant to the terms and conditions of a separate,
     14  * written license agreement executed between you and Broadcom
     15  * (an "Authorized License").  Except as set forth in an Authorized
     16  * License, Broadcom grants no license (express or implied), right
     17  * to use, or waiver of any kind with respect to the Software, and
     18  * Broadcom expressly reserves all rights in and to the Software
     19  * and all intellectual property rights therein.  IF YOU HAVE
     20  * NO AUTHORIZED LICENSE, THEN YOU HAVE NO RIGHT TO USE THIS SOFTWARE
     21  * IN ANY WAY, AND SHOULD IMMEDIATELY NOTIFY BROADCOM AND DISCONTINUE
     22  * ALL USE OF THE SOFTWARE.
     23  *
     24  *
     25  * Except as expressly set forth in the Authorized License,
     26  *
     27  * 1.     This program, including its structure, sequence and organization,
     28  * constitutes the valuable trade secrets of Broadcom, and you shall use
     29  * all reasonable efforts to protect the confidentiality thereof,
     30  * and to use this information only in connection with your use of
     31  * Broadcom integrated circuit products.
     32  *
     33  * 2.     TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS
     34  * PROVIDED "AS IS" AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES,
     35  * REPRESENTATIONS OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY,
     36  * OR OTHERWISE, WITH RESPECT TO THE SOFTWARE.  BROADCOM SPECIFICALLY
     37  * DISCLAIMS ANY AND ALL IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY,
     38  * NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF VIRUSES,
     39  * ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
     40  * CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING
     41  * OUT OF USE OR PERFORMANCE OF THE SOFTWARE.
     42  *
     43  * 3.     TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL
     44  * BROADCOM OR ITS LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL,
     45  * INCIDENTAL, SPECIAL, INDIRECT, OR EXEMPLARY DAMAGES WHATSOEVER
     46  * ARISING OUT OF OR IN ANY WAY RELATING TO YOUR USE OF OR INABILITY
     47  * TO USE THE SOFTWARE EVEN IF BROADCOM HAS BEEN ADVISED OF THE
     48  * POSSIBILITY OF SUCH DAMAGES; OR (ii) ANY AMOUNT IN EXCESS OF
     49  * THE AMOUNT ACTUALLY PAID FOR THE SOFTWARE ITSELF OR USD 1.00,
     50  * WHICHEVER IS GREATER. THESE LIMITATIONS SHALL APPLY NOTWITHSTANDING
     51  * ANY FAILURE OF ESSENTIAL PURPOSE OF ANY LIMITED REMEDY.$
     52  */
     53 
     54 
     55 /*
     56  * Includes
     57  */
     58 #include <phymod/phymod.h>
     59 #include <phymod/phymod_system.h>
     60 #include <phymod/phymod_reg.h>
     61 #include <phymod/phymod_diagnostics.h>
     62 #include <phymod/phymod_definitions.h>
     63 #include "huracan_cfg_seq.h"
     64 #include "huracan_reg_access.h"
     65 #include "bcmi_huracan_defs.h"
     66 
     67 
     68 #ifndef PHYMOD_DIAG_OUT
     69 #define PHYMOD_DIAG_OUT(a)  printf a
     70 #endif
     71 
     72 
     73 /* Take care of Register Address mapping */
     74 #undef  PHYMOD_BUS_READ
     75 #undef  PHYMOD_BUS_WRITE
     76 
     77 #define hmr(__a) \
     78     ((__a) & 0x1ff00 ) == 0x1b000 ? (((__a) & ~(0xf000)) | 0x8000) : (__a) 
     79 
     80 #define PHYMOD_BUS_READ(pa_,r_,v_) phymod_bus_read(pa_,hmr(r_),v_)
     81 #define PHYMOD_BUS_WRITE(pa_,r_,v_) phymod_bus_write(pa_,hmr(r_),v_)
     82 /*
     83  *  Defines
     84  */
     85 
     86 /**   Get Revision ID
     87  *    This function retrieves Revision ID from PHY chip
     88  *
     89  *    @param pa                 Pointer to phymod access structure
     90  *
     91  *    @param rev_id            Revision ID retrieved from the chip
     92  */
     93 int huracan_rev_id(const phymod_access_t *pa, uint32_t *rev_id)
     94 {
     95 
     96     BCMI_HURACAN_CHIP_REVISIONr_t chip_revision;
     97     PHYMOD_MEMSET(&chip_revision, 0 ,
     98             sizeof(BCMI_HURACAN_CHIP_REVISIONr_t));
     99 
    100     /* Read the chip revision from register */
    101     PHYMOD_IF_ERR_RETURN(
    102             READ_CHIP_REVISIONr(pa, &chip_revision));
    103     *rev_id = BCMI_HURACAN_CHIP_REVISIONr_CHIP_REVf_GET(chip_revision);
    104 
    105     return PHYMOD_E_NONE;
    106 }
    107 
    108 uint32_t get_pkg_lane_num_max_limit(uint32_t chip_id)
    109 {
    110     uint32_t  pkg_lanes = 0;
    111     switch(chip_id) {
    112         case HURACAN_82109_SW_ID:
    113         case HURACAN_82181_SW_ID:
    114             pkg_lanes = EIGHT;
    115             break;
    116         default:
    117             pkg_lanes = FOUR;
    118             break;
    119     }
    120 
    121     return pkg_lanes;
    122 }
    123 
    124 /**   Get lane descriptor 
    125  *    This function is used to retrieve lane descriptor from package lane 
    126  *    
    127  *    @param chip_id            Chip id of Huracan device
    128  *    @param pa                 Pointer to phymod access structure 
    129  *    @param pkg_lane           Package lane number
    130  *
    131  *    @return pkg_ln_des        Lane descriptor structure contains the info
    132  *                              about package lane and die lane mapping 
    133  */
    134 const tx_rx_lane_info* _huracan_get_pkg_to_die_lane_info(uint32_t chip_id, const phymod_access_t *pa, int pkg_lane, int tx_rx)
    135 {
    136     const tx_rx_lane_info* lane_info = NULL;
    137     uint32_t pkg_side = 0, acc_flag = 0;
    138     int index = 0;
    139 
    140     acc_flag = PHYMOD_ACC_FLAGS(pa);
    141     HURACAN_GET_IF_SIDE(acc_flag,pkg_side);
    142 
    143     /* search the data base for this chip */
    144     for (index = 0;index < MAX_NUM_PACKAGES;index++) {
    145         if (glb_pkg_array[index] && (glb_pkg_array[index]->chip_id == chip_id)) {
    146             /* is this a valid package lane*/
    147             if ((pkg_lane >= get_pkg_lane_num_max_limit(chip_id)) || (pkg_lane < 0)) {
    148                 break;
    149             }
    150             /* line side */
    151             pkg_side = (pkg_side) ? SIDE_B:SIDE_A;
    152             /*tx lane*/
    153             if (tx_rx) {
    154                 lane_info = &((glb_pkg_array[index] + pkg_lane)->intf_l_info[pkg_side].tx_rx_l_info[TX]);
    155             } else {
    156                 /*rx_side*/
    157                 lane_info = &((glb_pkg_array[index] + pkg_lane)->intf_l_info[pkg_side].tx_rx_l_info[RX]);
    158             }
    159             break;
    160         }
    161     }
    162 
    163     return lane_info;
    164 }
    165 
    166 int huracan_channel_select (const phymod_access_t *pa, uint16_t lane)
    167 {
    168     return PHYMOD_E_NONE;
    169 }
    170 
    171 /**   read chip ID
    172  *    This function is used to set the operating mode of the PHY
    173  *
    174  *    @param pa                 Pointer to phymod access structure 
    175  *    @return PHYMOD_E_NONE     successful function execution 
    176  */
    177 uint32_t  _huracan_get_chip_id(const phymod_access_t *pa)
    178 {
    179     int32_t chipid = 0;
    180     CHIP_IDr_t chipid_lsb;
    181 
    182     PHYMOD_MEMSET(&chipid_lsb, 0, sizeof(CHIP_IDr_t));
    183 
    184 
    185     PHYMOD_IF_ERR_RETURN(
    186             READ_CHIP_IDr(pa, &chipid_lsb));
    187 
    188     chipid = CHIP_IDr_GET(chipid_lsb);
    189 
    190     return chipid;
    191 } 
    192 
    193 /**   read sw chip ID
    194  *    This function is used to set the operating mode of the PHY
    195  *
    196  *    @param pa                 Pointer to phymod access structure 
    197  *    @return PHYMOD_E_NONE     successful function execution 
    198  */
    199 uint32_t  _huracan_get_sw_chip_id(const phymod_access_t *pa)
    200 {
    201     int32_t chipid = 0;
    202 
    203     chipid = HURACAN_GET_SW_ID(_huracan_get_chip_id(pa));
    204 
    205     return chipid;
    206 } 
    207 
    208 /**   poll intf update 
    209  *    This function is used to set the operating mode of the PHY
    210  *
    211  *    @param pa                 Pointer to phymod access structure 
    212 
    213  *    @timeout                  timeout in us
    214  *    @return PHYMOD_E_NONE     successful function execution 
    215  */
    216 int _huracan_intf_update_wait_check(const phymod_access_t *pa, uint32_t apps_mode0_reg_val,
    217         int32_t timeout)          /* max wait time to check */
    218 {
    219     return PHYMOD_E_FAIL;
    220 } 
    221 
    222 /**   Set config mode 
    223  *    This function is used to set the operating mode of the PHY
    224  *
    225  *    @param pa                 Pointer to phymod access structure 
    226  *    @param intf               Interface specified by user 
    227  *    @param speed              Speed val as specified by user  
    228  *    @param ref_clk            Reference clock frequency to set 
    229  *                              the PHY into specified interface 
    230  *                              and speed
    231  * 
    232  *    @return PHYMOD_E_NONE     successful function execution 
    233  */
    234 int huracan_set_config_mode(const phymod_access_t *pa,
    235         phymod_interface_t intf,
    236         uint32_t speed,
    237         phymod_ref_clk_t ref_clk)
    238 {
    239     return PHYMOD_E_NONE;
    240 }
    241 /**   Get config mode 
    242  *    This function is used to retrieve the operating mode of the PHY
    243  *
    244  *    @param pa                 Pointer to phymod access structure 
    245  *    @param intf               Interface type 
    246  *    @param speed              Speed val retrieved from PHY 
    247  *    @param ref_clk            Reference clock 
    248  *    @param interface_modes    Supported interface modes
    249  * 
    250  *    @return PHYMOD_E_NONE     successful function execution 
    251  */
    252 int huracan_get_config_mode(const phymod_access_t *pa,
    253         phymod_interface_t *intf,
    254         uint32_t *speed,
    255         phymod_ref_clk_t *ref_clk,
    256         uint32_t *interface_modes)
    257 {
    258     return PHYMOD_E_NONE;
    259 }
    260 
    261 /**   Get  link status of PHY 
    262  *    This function is used to retrieve the link status of PHY chip
    263  *
    264  *    @param pa                 Pointer to phymod access structure 
    265  *
    266  *    @param link_status        link status of the PHY 
    267  *                              1 - Up 
    268  *                              0 - Down 
    269  * 
    270  *    @return PHYMOD_E_NONE     successful function execution 
    271  */
    272 int huracan_core_lane_link_state_get(const phymod_access_t* pa,uint32_t core_id,
    273         uint32_t lane,uint32_t pkg_side,uint32_t *linkstate)
    274 {
    275     uint32_t lane_bitmap;
    276     uint32_t reg_addr;
    277     BCMI_HURACAN_ANA_LANE_0_QUAD_A_STATUS0r_t ieee_pmd_status1_reg_val;
    278 
    279     PHYMOD_MEMSET(&ieee_pmd_status1_reg_val, 0, sizeof(BCMI_HURACAN_ANA_LANE_0_QUAD_A_STATUS0r_t)); 
    280 
    281     lane_bitmap = (0x1  <<  (lane & LANE_NUM_MASK));
    282     reg_addr = BCMI_HURACAN_ANA_LANE_0_QUAD_A_STATUS0r & ~((LANE_REG_ADDR_MASK) << LANE_NUM_POS_SHIFT); 
    283     reg_addr |= ((core_id & CORE_ID_MASK) << CORE_ID_POS_SHIFT) |
    284                 ((lane_bitmap & LANE_REG_ADDR_MASK) << LANE_NUM_POS_SHIFT);
    285 
    286     PHYMOD_IF_ERR_RETURN(
    287             PHYMOD_BUS_READ(pa, reg_addr, &ieee_pmd_status1_reg_val._ana_lane_0_quad_a_status0));
    288     *linkstate &= BCMI_HURACAN_ANA_LANE_0_QUAD_A_STATUS0r_DG_RX_SIGDETf_GET(ieee_pmd_status1_reg_val);
    289 
    290     return PHYMOD_E_NONE;
    291 
    292 }
    293 int huracan_link_status(const phymod_access_t *pa, uint32_t *link_status)
    294 {
    295 
    296     int lane_map = 0, num_lanes = 0;
    297     int lane_index = 0, pkg_side = 0;
    298     uint32_t acc_flags = 0, chip_id = 0;
    299     const tx_rx_lane_info* lane_info = NULL;
    300     *link_status = 1;
    301 
    302     lane_map = PHYMOD_ACC_LANE_MASK(pa);
    303     acc_flags = PHYMOD_ACC_FLAGS(pa);
    304     HURACAN_GET_IF_SIDE(acc_flags, pkg_side);
    305     chip_id = _huracan_get_sw_chip_id(pa);
    306     GET_SUPPORTED_LANES(chip_id,num_lanes);
    307 
    308     for (lane_index = 0; lane_index < num_lanes; lane_index++) {
    309         if (((lane_map >> lane_index) & 1) == 0x1) {
    310             lane_info = _huracan_get_pkg_to_die_lane_info(chip_id,pa,lane_index,0);
    311             PHYMOD_NULL_CHECK(lane_info);
    312             PHYMOD_IF_ERR_RETURN(
    313                     huracan_core_lane_link_state_get(pa,lane_info->die_num, lane_info->lane_num, pkg_side, link_status));
    314         }
    315     }
    316 
    317     return PHYMOD_E_NONE;
    318 }
    319 
    320 int _huracan_refclk_set(const phymod_access_t *pa, uint32_t ref_clk) 
    321 {
    322     return PHYMOD_E_NONE;
    323 }
    324 
    325 /**   Set Tx Rx polarity 
    326  *    This function is used to set Tx Rx polarity of a single lane
    327  *    or multiple lanes 
    328  *
    329  *    @param pa                 Pointer to phymod access structure 
    330  *    @param tx_polarity        Tx polarity 
    331  *    @param rx_polarity        Rx polarity 
    332  *
    333  *    @return PHYMOD_E_NONE     successful function execution 
    334  */
    335 int huracan_tx_rx_polarity_set (const phymod_access_t *pa, uint32_t tx_polarity, uint32_t rx_polarity)
    336 {
    337     return PHYMOD_E_NONE;
    338 }
    339 /**   Get Tx Rx polarity 
    340  *    This function is used to get Tx Rx polarity of a specific lane
    341  *    specified by user 
    342  *
    343  *    @param pa                 Pointer to phymod access structure 
    344  *    @param tx_polarity        Tx polarity 
    345  *    @param rx_polarity        Rx polarity 
    346  *
    347  *    @return PHYMOD_E_NONE     successful function execution 
    348  */
    349 int huracan_tx_rx_polarity_get (const phymod_access_t *pa, uint32_t *tx_polarity, uint32_t *rx_polarity)
    350 {
    351     return PHYMOD_E_NONE;
    352 }
    353 
    354 /**  PMD lock get 
    355  *    
    356  *    @param pa                 Pointer to phymod access structure
    357  *    @param rx_seq_done        RX sew done status
    358  *
    359  *    @return PHYMOD_E_NONE     successful function execution 
    360  */
    361 int huracan_pmd_lock_get(const phymod_access_t *pa, uint32_t *rx_seq_done) 
    362 {
    363     return PHYMOD_E_NONE;
    364 }
    365 
    366 
    367 /**   Set port speed  
    368  *    This function is used to set the operating mode of the PHY
    369  *
    370  *    @param reg_val            Pointer to apps mode reg 
    371  *    @param speed              Interface specified by user 
    372  *    @param mode_type          port mode (single vs multiple)
    373  * 
    374  *    @return PHYMOD_E_NONE     successful function execution 
    375  */
    376 int _huracan_config_port_speed(uint32_t speed, uint32_t* reg_val, uint16_t* mode_type)
    377 {
    378     return PHYMOD_E_NONE; 
    379 }
    380 
    381 int huracan_core_tx_lane_control_set(const phymod_access_t* pa, uint32_t chip_id, uint32_t core_id,
    382         uint32_t lane,uint32_t pkg_side,uint32_t squelch)
    383 {
    384 
    385     uint32_t lane_bitmap;
    386     uint32_t reg_addr;
    387     BCMI_HURACAN_ANA_LANE_0_QUAD_A_CTRL14r_t ieee_pmd_cmd1_reg_val;
    388 
    389     PHYMOD_MEMSET(&ieee_pmd_cmd1_reg_val, 0, sizeof(BCMI_HURACAN_ANA_LANE_0_QUAD_A_CTRL14r_t)); 
    390 
    391     lane_bitmap = (0x1  <<  (lane & LANE_NUM_MASK));
    392     reg_addr = BCMI_HURACAN_ANA_LANE_0_QUAD_A_CTRL14r & ~((LANE_REG_ADDR_MASK) << LANE_NUM_POS_SHIFT); 
    393     reg_addr |= ((core_id & CORE_ID_MASK) << CORE_ID_POS_SHIFT) | 
    394                 ((lane_bitmap & LANE_REG_ADDR_MASK) << LANE_NUM_POS_SHIFT);
    395 
    396     PHYMOD_IF_ERR_RETURN(
    397             PHYMOD_BUS_READ(pa, reg_addr, &ieee_pmd_cmd1_reg_val._ana_lane_0_quad_a_ctrl14));
    398 
    399     if (pkg_side == SIDE_A) {
    400         if (((HURACAN_IS_DUPLEX(chip_id)) && ((core_id == 1) || (core_id == 3))) ||
    401             ((HURACAN_IS_SIMPLEX(chip_id)) && ((core_id == 0) || (core_id == 1)))) {
    402             BCMI_HURACAN_ANA_LANE_0_QUAD_A_CTRL14r_TX_IDLE_FRCf_SET(ieee_pmd_cmd1_reg_val, 1);
    403             BCMI_HURACAN_ANA_LANE_0_QUAD_A_CTRL14r_TX_IDLE_FRC_VALf_SET(ieee_pmd_cmd1_reg_val, squelch ?  1 : 0);
    404         }
    405     } else {
    406         if ((HURACAN_IS_DUPLEX(chip_id)) && ((core_id == 0) || (core_id == 2))) {
    407             BCMI_HURACAN_ANA_LANE_0_QUAD_A_CTRL14r_TX_IDLE_FRCf_SET(ieee_pmd_cmd1_reg_val, 1);
    408             BCMI_HURACAN_ANA_LANE_0_QUAD_A_CTRL14r_TX_IDLE_FRC_VALf_SET(ieee_pmd_cmd1_reg_val, squelch ?  1 : 0);
    409         }
    410     }
    411     PHYMOD_IF_ERR_RETURN(
    412             PHYMOD_BUS_WRITE(pa, reg_addr, ieee_pmd_cmd1_reg_val._ana_lane_0_quad_a_ctrl14));
    413 
    414     if  (!squelch) {
    415         if (pkg_side == SIDE_A) {
    416             if (((HURACAN_IS_DUPLEX(chip_id)) && ((core_id == 1) || (core_id == 3))) ||
    417                 ((HURACAN_IS_SIMPLEX(chip_id)) && ((core_id == 0) || (core_id == 1)))) {
    418                 BCMI_HURACAN_ANA_LANE_0_QUAD_A_CTRL14r_TX_IDLE_FRCf_SET(ieee_pmd_cmd1_reg_val, 0);
    419             }
    420         } else {
    421             if ((HURACAN_IS_DUPLEX(chip_id)) && ((core_id == 0) || (core_id == 2))) {
    422                 BCMI_HURACAN_ANA_LANE_0_QUAD_A_CTRL14r_TX_IDLE_FRCf_SET(ieee_pmd_cmd1_reg_val, 0);
    423             }
    424         }
    425 
    426         PHYMOD_IF_ERR_RETURN(
    427                 PHYMOD_BUS_WRITE(pa, reg_addr, ieee_pmd_cmd1_reg_val._ana_lane_0_quad_a_ctrl14));
    428     }
    429 
    430     return PHYMOD_E_NONE;    
    431 }
    432 
    433 int huracan_tx_lane_control_set(const phymod_access_t *pa,
    434         phymod_phy_tx_lane_control_t tx_control)
    435 {
    436 
    437     int lane_map = 0, num_lanes = 0;
    438     uint32_t acc_flags = 0, chip_id = 0; 
    439     uint32_t lane_index = 0;
    440     int pkg_side = 0;
    441     uint8_t squelch = 0;
    442     const tx_rx_lane_info* lane_info = NULL;
    443 
    444     lane_map = PHYMOD_ACC_LANE_MASK(pa);
    445     acc_flags = PHYMOD_ACC_FLAGS(pa);
    446     HURACAN_GET_IF_SIDE(acc_flags, pkg_side);
    447     chip_id = _huracan_get_sw_chip_id(pa);
    448     GET_SUPPORTED_LANES(chip_id,num_lanes);
    449 
    450     switch(tx_control) {
    451         case phymodTxSquelchOn:
    452             squelch = 1;
    453             break;
    454         case phymodTxSquelchOff:
    455         default:
    456             squelch = 0;
    457             break;
    458     }
    459 
    460     for (lane_index = 0; lane_index < num_lanes; lane_index++) {
    461         if (((lane_map >> lane_index) & 1) == 0x1) {
    462             lane_info = _huracan_get_pkg_to_die_lane_info(chip_id,pa,lane_index,0);
    463             PHYMOD_NULL_CHECK(lane_info);
    464             PHYMOD_IF_ERR_RETURN(
    465                     huracan_core_tx_lane_control_set(pa, chip_id, lane_info->die_num, lane_info->lane_num, pkg_side, squelch));
    466 
    467             if (HURACAN_IS_DUPLEX(chip_id)) {
    468                 lane_info = _huracan_get_pkg_to_die_lane_info(chip_id,pa,lane_index,1);
    469                 PHYMOD_NULL_CHECK(lane_info);
    470                 PHYMOD_IF_ERR_RETURN(
    471                         huracan_core_tx_lane_control_set(pa, chip_id, lane_info->die_num, lane_info->lane_num, pkg_side, squelch));
    472             }
    473         }
    474     }
    475 
    476     return PHYMOD_E_NONE;    
    477 }
    478 
    479 int huracan_core_tx_squelch_get(const phymod_access_t* pa,uint32_t chip_id, uint32_t core_id,
    480         uint32_t lane,uint32_t pkg_side,int *tx_squelch)
    481 {
    482     uint32_t lane_bitmap;
    483     uint32_t reg_addr;
    484     BCMI_HURACAN_ANA_LANE_0_QUAD_A_CTRL14r_t ieee_pmd_cmd1_reg_val;
    485 
    486     *tx_squelch = 0;
    487     PHYMOD_MEMSET(&ieee_pmd_cmd1_reg_val, 0, sizeof(BCMI_HURACAN_ANA_LANE_0_QUAD_A_CTRL14r_t));
    488 
    489     lane_bitmap = (0x1  <<  (lane & LANE_NUM_MASK));
    490     reg_addr = (BCMI_HURACAN_ANA_LANE_0_QUAD_A_CTRL14r) & ~((LANE_REG_ADDR_MASK) << LANE_NUM_POS_SHIFT);
    491     reg_addr |= ((core_id & CORE_ID_MASK) << CORE_ID_POS_SHIFT) |
    492                 ((lane_bitmap & LANE_REG_ADDR_MASK) << LANE_NUM_POS_SHIFT) ;
    493 
    494     PHYMOD_IF_ERR_RETURN(
    495             PHYMOD_BUS_READ(pa, reg_addr, &ieee_pmd_cmd1_reg_val._ana_lane_0_quad_a_ctrl14));
    496 
    497     if (pkg_side == SIDE_A) {
    498         if (((HURACAN_IS_DUPLEX(chip_id)) && ((core_id == 1) || (core_id == 3))) ||
    499             ((HURACAN_IS_SIMPLEX(chip_id)) && ((core_id == 0) || (core_id == 1)))) {
    500             if (BCMI_HURACAN_ANA_LANE_0_QUAD_A_CTRL14r_TX_IDLE_FRCf_GET(ieee_pmd_cmd1_reg_val) &&
    501                 BCMI_HURACAN_ANA_LANE_0_QUAD_A_CTRL14r_TX_IDLE_FRC_VALf_GET(ieee_pmd_cmd1_reg_val)) {
    502                 *tx_squelch = 1;
    503             }
    504         }
    505     } else {
    506         if ((HURACAN_IS_DUPLEX(chip_id)) && ((core_id == 0) || (core_id == 2))) {
    507             if (BCMI_HURACAN_ANA_LANE_0_QUAD_A_CTRL14r_TX_IDLE_FRCf_GET(ieee_pmd_cmd1_reg_val) &&
    508                 BCMI_HURACAN_ANA_LANE_0_QUAD_A_CTRL14r_TX_IDLE_FRC_VALf_GET(ieee_pmd_cmd1_reg_val)) {
    509                 *tx_squelch = 1;
    510             }
    511         }
    512     }
    513 
    514     return PHYMOD_E_NONE;    
    515 }
    516 
    517 int huracan_tx_squelch_get(const phymod_access_t *pa, int *tx_squelch)
    518 {
    519     int lane_map = 0, num_lanes = 0;
    520     int lane_index = 0, pkg_side = 0;
    521     uint32_t chip_id = 0, acc_flags = 0;
    522     const tx_rx_lane_info* lane_info = NULL;
    523 
    524     lane_map = PHYMOD_ACC_LANE_MASK(pa);
    525     chip_id = _huracan_get_sw_chip_id(pa);
    526     GET_SUPPORTED_LANES(chip_id,num_lanes);
    527     acc_flags = PHYMOD_ACC_FLAGS(pa);
    528     HURACAN_GET_IF_SIDE(acc_flags, pkg_side);
    529 
    530     for (lane_index = 0; lane_index < num_lanes; lane_index++) {
    531         if (((lane_map >> lane_index) & 1) == 0x1) {
    532             lane_info = _huracan_get_pkg_to_die_lane_info(chip_id,pa,lane_index,0);
    533             PHYMOD_NULL_CHECK(lane_info);
    534             PHYMOD_IF_ERR_RETURN(
    535                     huracan_core_tx_squelch_get(pa, chip_id, lane_info->die_num, lane_info->lane_num, pkg_side, tx_squelch));
    536             if (HURACAN_IS_DUPLEX(chip_id)) {
    537                 lane_info = _huracan_get_pkg_to_die_lane_info(chip_id,pa,lane_index,1);
    538                 PHYMOD_NULL_CHECK(lane_info);
    539                 PHYMOD_IF_ERR_RETURN(
    540                     huracan_core_tx_squelch_get(pa, chip_id, lane_info->die_num, lane_info->lane_num, pkg_side, tx_squelch));
    541             }
    542         }
    543     }
    544 
    545     return PHYMOD_E_NONE;    
    546 }
    547 
    548 
    549 int huracan_rx_lane_control_set(const phymod_access_t *pa,
    550         phymod_phy_rx_lane_control_t rx_control)
    551 {
    552     return PHYMOD_E_UNAVAIL;
    553 }
    554 
    555 int huracan_rx_squelch_get(const phymod_access_t *pa, int *rx_squelch)
    556 {
    557     return PHYMOD_E_UNAVAIL;
    558 }
    559 
    560 
    561 int _huracan_phy_diagnostics_get(const phymod_access_t *pa, phymod_phy_diagnostics_t* diag)
    562 {
    563     return PHYMOD_E_NONE;
    564 }
    565 
    566 const chip_id_quad_info* _huracan_get_chipid_quad_info(const phymod_access_t *pa)
    567 {
    568     uint32_t i,chipid = 0;
    569     chipid = _huracan_get_sw_chip_id(pa);
    570     for (i=0;i<MAX_NUM_PACKAGES-1;i++) {
    571         if(chipid == chipid_quad_info[i].chip_id) {
    572             return (&chipid_quad_info[i]);
    573         }
    574     }
    575 
    576     return (NULL);
    577 }
    578 
    579 int hard_reset_huracan_quad(const phymod_access_t *pa, uint32_t core_id,uint32_t reset)
    580 {
    581 
    582     uint32_t reg_addr = 0;
    583     BCMI_HURACAN_GEN_CONTROL1r_t gen_control_reg_val;
    584 
    585     PHYMOD_MEMSET(&gen_control_reg_val, 0, sizeof(BCMI_HURACAN_GEN_CONTROL1r_t));
    586 
    587     reg_addr = BCMI_HURACAN_GEN_CONTROL1r;
    588     reg_addr |= ((core_id & CORE_ID_MASK) << CORE_ID_POS_SHIFT);
    589 
    590     PHYMOD_IF_ERR_RETURN(
    591             PHYMOD_BUS_READ(pa, reg_addr, &gen_control_reg_val._gen_control1));
    592     BCMI_HURACAN_GEN_CONTROL1r_RESETBf_SET(gen_control_reg_val, reset ? 0 : 1 );
    593     PHYMOD_IF_ERR_RETURN(
    594             PHYMOD_BUS_WRITE(pa, reg_addr, gen_control_reg_val._gen_control1));
    595 
    596     return PHYMOD_E_NONE;
    597 }
    598 
    599 
    600 int huracan_hard_reset(const phymod_access_t* pa, phymod_reset_mode_t reset_mode,
    601         phymod_reset_direction_t direction)
    602 {
    603     uint8_t reset = 0;
    604     uint32_t qdindex = 0;
    605     const chip_id_quad_info *qdinfo = NULL;
    606     if (reset_mode == phymodResetModeHard) {
    607         switch (direction) {
    608             case phymodResetDirectionIn:
    609                 reset = 1;
    610                 break;
    611             case phymodResetDirectionInOut:
    612                 reset = 2;
    613                 break;
    614             default:
    615                 reset = 0;
    616                 break;
    617         }
    618     } else {
    619         return PHYMOD_E_UNAVAIL;
    620     }
    621     qdinfo =  _huracan_get_chipid_quad_info(pa);
    622     for (qdindex = 0; qdindex < qdinfo->num_of_quads; qdindex++) {
    623         PHYMOD_IF_ERR_RETURN(
    624                 hard_reset_huracan_quad(pa,qdinfo->quads_in_this_chip[qdindex],reset));
    625 
    626     }
    627 
    628     return PHYMOD_E_NONE;
    629 }
    630 int _huracan_phy_reset_set(const phymod_access_t *pa,  const phymod_phy_reset_t* reset)
    631 {
    632     return PHYMOD_E_NONE;
    633 }
    634 
    635 
    636 int _huracan_phy_reset_get( const phymod_access_t *pa,  phymod_phy_reset_t* reset)
    637 {
    638     return PHYMOD_E_NONE;
    639 }
    640 
    641 
    642 int _huracan_loopback_set(const phymod_access_t *pa, phymod_loopback_mode_t loopback, uint32_t enable)
    643 {
    644     return PHYMOD_E_NONE;
    645 }
    646 
    647 int _huracan_loopback_get(const phymod_access_t *pa, phymod_loopback_mode_t loopback, uint32_t* enable)
    648 {
    649     return PHYMOD_E_NONE;
    650 }
    651 int huracan_core_phy_power_set(const phymod_access_t* pa, uint32_t chip_id, uint32_t core_id,
    652         uint32_t lane,uint32_t pkg_side, phymod_phy_power_t pwrdn)
    653 {
    654     uint32_t lane_bitmap;
    655     uint32_t reg_addr;
    656     BCMI_HURACAN_ANA_LANE_0_QUAD_A_CTRL0r_t ieee_pmd_cmd1_reg_val;
    657 
    658     PHYMOD_MEMSET(&ieee_pmd_cmd1_reg_val, 0, sizeof(BCMI_HURACAN_ANA_LANE_0_QUAD_A_CTRL0r_t));
    659 
    660     lane_bitmap = (0x1  <<  (lane & LANE_NUM_MASK));
    661     reg_addr = BCMI_HURACAN_ANA_LANE_0_QUAD_A_CTRL0r & ~((LANE_REG_ADDR_MASK) << LANE_NUM_POS_SHIFT);
    662     reg_addr |= ((core_id & CORE_ID_MASK) << CORE_ID_POS_SHIFT) |
    663                 ((lane_bitmap & LANE_REG_ADDR_MASK) << LANE_NUM_POS_SHIFT) ;
    664 
    665     PHYMOD_IF_ERR_RETURN(
    666             PHYMOD_BUS_READ(pa, reg_addr, &ieee_pmd_cmd1_reg_val._ana_lane_0_quad_a_ctrl0));
    667 
    668     if (pkg_side == SIDE_A) {
    669         if (((HURACAN_IS_DUPLEX(chip_id)) && ((core_id == 1) || (core_id == 3))) || 
    670             ((HURACAN_IS_SIMPLEX(chip_id)) && ((core_id == 0) || (core_id == 1)))) { 
    671             BCMI_HURACAN_ANA_LANE_0_QUAD_A_CTRL0r_RXTX_PWRDNf_SET(ieee_pmd_cmd1_reg_val, pwrdn.tx ? 1 : 0);
    672         }
    673         else if ((HURACAN_IS_DUPLEX(chip_id)) && ((core_id == 0) || (core_id == 2))) {
    674             BCMI_HURACAN_ANA_LANE_0_QUAD_A_CTRL0r_RX_SIGDET_PWRDNf_SET(ieee_pmd_cmd1_reg_val, pwrdn.rx ? 1 : 0);
    675             BCMI_HURACAN_ANA_LANE_0_QUAD_A_CTRL0r_RXTX_PWRDNf_SET(ieee_pmd_cmd1_reg_val, pwrdn.rx ? 1 : 0);
    676         }
    677     } else {
    678         if (((HURACAN_IS_DUPLEX(chip_id)) && ((core_id == 1) || (core_id == 3))) || 
    679             ((HURACAN_IS_SIMPLEX(chip_id)) && ((core_id == 0) || (core_id == 1)))) { 
    680             BCMI_HURACAN_ANA_LANE_0_QUAD_A_CTRL0r_RX_SIGDET_PWRDNf_SET(ieee_pmd_cmd1_reg_val, pwrdn.rx ? 1 : 0);
    681             BCMI_HURACAN_ANA_LANE_0_QUAD_A_CTRL0r_RXTX_PWRDNf_SET(ieee_pmd_cmd1_reg_val, pwrdn.rx ? 1 : 0);
    682         } else if ((HURACAN_IS_DUPLEX(chip_id)) && ((core_id == 0) || (core_id == 2))) {
    683             BCMI_HURACAN_ANA_LANE_0_QUAD_A_CTRL0r_RXTX_PWRDNf_SET(ieee_pmd_cmd1_reg_val, pwrdn.tx ? 1 : 0);
    684         }
    685     }
    686 
    687     PHYMOD_IF_ERR_RETURN(
    688             PHYMOD_BUS_WRITE(pa, reg_addr, ieee_pmd_cmd1_reg_val._ana_lane_0_quad_a_ctrl0));
    689 
    690     if (pwrdn.rx >=2) {
    691         PHYMOD_USLEEP(500);
    692         if (pkg_side == SIDE_A) {
    693             if ((HURACAN_IS_DUPLEX(chip_id)) && ((core_id == 0) || (core_id == 2))) {
    694                 BCMI_HURACAN_ANA_LANE_0_QUAD_A_CTRL0r_RX_SIGDET_PWRDNf_SET(ieee_pmd_cmd1_reg_val, 0);
    695                 BCMI_HURACAN_ANA_LANE_0_QUAD_A_CTRL0r_RXTX_PWRDNf_SET(ieee_pmd_cmd1_reg_val, 0);
    696             }
    697         } else {
    698             if (((HURACAN_IS_DUPLEX(chip_id)) && ((core_id == 1) || (core_id == 3))) ||
    699                 ((HURACAN_IS_SIMPLEX(chip_id)) && ((core_id == 0) || (core_id == 1)))) {
    700                 BCMI_HURACAN_ANA_LANE_0_QUAD_A_CTRL0r_RX_SIGDET_PWRDNf_SET(ieee_pmd_cmd1_reg_val, 0);
    701                 BCMI_HURACAN_ANA_LANE_0_QUAD_A_CTRL0r_RXTX_PWRDNf_SET(ieee_pmd_cmd1_reg_val, 0);
    702             }
    703         }
    704         PHYMOD_IF_ERR_RETURN(
    705                 PHYMOD_BUS_WRITE(pa, reg_addr, ieee_pmd_cmd1_reg_val._ana_lane_0_quad_a_ctrl0));
    706     }
    707     if (pwrdn.tx >=2) {
    708         PHYMOD_USLEEP(500);
    709         if (pkg_side == SIDE_A) {
    710             if (((HURACAN_IS_DUPLEX(chip_id)) && ((core_id == 1) || (core_id == 3))) ||
    711                 ((HURACAN_IS_SIMPLEX(chip_id)) && ((core_id == 0) || (core_id == 1)))) {
    712                 BCMI_HURACAN_ANA_LANE_0_QUAD_A_CTRL0r_RXTX_PWRDNf_SET(ieee_pmd_cmd1_reg_val, 0);
    713             }
    714         } else {
    715             if ((HURACAN_IS_DUPLEX(chip_id)) && ((core_id == 0) || (core_id == 2))) {
    716                 BCMI_HURACAN_ANA_LANE_0_QUAD_A_CTRL0r_RXTX_PWRDNf_SET(ieee_pmd_cmd1_reg_val, 0);
    717             }
    718         }
    719         PHYMOD_IF_ERR_RETURN(
    720                 PHYMOD_BUS_WRITE(pa, reg_addr, ieee_pmd_cmd1_reg_val._ana_lane_0_quad_a_ctrl0));
    721     }
    722 
    723     return PHYMOD_E_NONE;
    724 }
    725 
    726 int _huracan_phy_power_set(const phymod_access_t* pa, const phymod_phy_power_t* power)
    727 {
    728     int lane_map = 0, num_lanes = 0;
    729     int pkg_side = 0, lane_index = 0;
    730     uint32_t acc_flags = 0, chip_id = 0;
    731     const tx_rx_lane_info* lane_info = NULL;
    732     phymod_phy_power_t tpower;
    733 
    734     lane_map = PHYMOD_ACC_LANE_MASK(pa);
    735     acc_flags = PHYMOD_ACC_FLAGS(pa);
    736     HURACAN_GET_IF_SIDE(acc_flags, pkg_side);
    737     chip_id = _huracan_get_sw_chip_id(pa);
    738     GET_SUPPORTED_LANES(chip_id,num_lanes);
    739 
    740     if (power->tx == phymodPowerOff) {
    741         tpower.tx = 1;
    742     } else if (power->tx == phymodPowerOffOn) {
    743         tpower.tx = 2;
    744     } else {
    745         tpower.tx = 0;
    746     }
    747     if (power->rx == phymodPowerOff) {
    748         tpower.rx = 1;
    749     } else if (power->rx == phymodPowerOffOn) {
    750         tpower.rx = 2;
    751     } else {
    752         tpower.rx = 0;
    753     }
    754 
    755     for (lane_index = 0; lane_index < num_lanes; lane_index++) {
    756         if (((lane_map >> lane_index) & 1) == 0x1) {
    757             lane_info = _huracan_get_pkg_to_die_lane_info(chip_id,pa,lane_index,0);
    758             PHYMOD_NULL_CHECK(lane_info);
    759             PHYMOD_IF_ERR_RETURN(
    760                     huracan_core_phy_power_set(pa,chip_id, lane_info->die_num,lane_info->lane_num, pkg_side, tpower));
    761 
    762             if (HURACAN_IS_DUPLEX(chip_id)) {
    763                 lane_info = _huracan_get_pkg_to_die_lane_info(chip_id,pa,lane_index,1);
    764                 PHYMOD_NULL_CHECK(lane_info);
    765                 PHYMOD_IF_ERR_RETURN(
    766                         huracan_core_phy_power_set(pa, chip_id, lane_info->die_num,lane_info->lane_num, pkg_side, tpower));
    767             }
    768         }
    769     }
    770 
    771     return PHYMOD_E_NONE;
    772 }
    773 int huracan_core_phy_power_get(const phymod_access_t* pa, uint32_t chip_id, uint32_t core_id,
    774         uint32_t lane,uint32_t pkg_side, phymod_phy_power_t* tpower)
    775 {
    776     uint32_t lane_bitmap;
    777     uint32_t reg_addr;
    778     BCMI_HURACAN_ANA_LANE_0_QUAD_A_CTRL0r_t ieee_pmd_cmd1_reg_val;
    779 
    780     PHYMOD_MEMSET(&ieee_pmd_cmd1_reg_val, 0, sizeof(BCMI_HURACAN_ANA_LANE_0_QUAD_A_CTRL0r_t)); 
    781     tpower->tx = 1;
    782     tpower->rx = 1;
    783 
    784     lane_bitmap = (0x1  <<  (lane & LANE_NUM_MASK));
    785     reg_addr = BCMI_HURACAN_ANA_LANE_0_QUAD_A_CTRL0r & ~((LANE_REG_ADDR_MASK) << LANE_NUM_POS_SHIFT); 
    786     reg_addr |= ((core_id & CORE_ID_MASK) << CORE_ID_POS_SHIFT) |
    787                 ((lane_bitmap & LANE_REG_ADDR_MASK) << LANE_NUM_POS_SHIFT);
    788     PHYMOD_IF_ERR_RETURN(
    789             PHYMOD_BUS_READ(pa, reg_addr, &ieee_pmd_cmd1_reg_val._ana_lane_0_quad_a_ctrl0));
    790 
    791     if (pkg_side == SIDE_A) {
    792         if (((HURACAN_IS_DUPLEX(chip_id)) && ((core_id == 1) || (core_id == 3))) ||
    793             ((HURACAN_IS_SIMPLEX(chip_id)) && ((core_id == 0) || (core_id == 1)))) {
    794             tpower->tx = BCMI_HURACAN_ANA_LANE_0_QUAD_A_CTRL0r_RXTX_PWRDNf_GET(
    795                               ieee_pmd_cmd1_reg_val) != 0 ? phymodPowerOff : phymodPowerOn;
    796         } else if ((HURACAN_IS_DUPLEX(chip_id)) && ((core_id == 0) || (core_id == 2))) {
    797             tpower->rx = BCMI_HURACAN_ANA_LANE_0_QUAD_A_CTRL0r_RXTX_PWRDNf_GET(
    798                               ieee_pmd_cmd1_reg_val) != 0 ? phymodPowerOff : phymodPowerOn;
    799         }
    800     } else {
    801         if (((HURACAN_IS_DUPLEX(chip_id)) && ((core_id == 1) || (core_id == 3))) ||
    802             ((HURACAN_IS_SIMPLEX(chip_id)) && ((core_id == 0) || (core_id == 1)))) {
    803             tpower->rx = BCMI_HURACAN_ANA_LANE_0_QUAD_A_CTRL0r_RXTX_PWRDNf_GET(
    804                               ieee_pmd_cmd1_reg_val) != 0 ? phymodPowerOff : phymodPowerOn;
    805         } else if ((HURACAN_IS_DUPLEX(chip_id)) && ((core_id == 0) || (core_id == 2))) {
    806             tpower->tx = BCMI_HURACAN_ANA_LANE_0_QUAD_A_CTRL0r_RXTX_PWRDNf_GET(
    807                               ieee_pmd_cmd1_reg_val) != 0 ? phymodPowerOff : phymodPowerOn;
    808         }
    809     }
    810 
    811     return PHYMOD_E_NONE;
    812 }
    813 
    814 int _huracan_phy_power_get(const phymod_access_t* pa, phymod_phy_power_t* power)
    815 {
    816     int lane_map = 0, num_lanes = 0;
    817     phymod_phy_power_t tpower;
    818     uint32_t chip_id = 0;
    819     const tx_rx_lane_info* lane_info = NULL;
    820     int lane_index = 0, pkg_side = 0;
    821     uint32_t acc_flags = 0; 
    822 
    823     acc_flags = PHYMOD_ACC_FLAGS(pa);
    824     HURACAN_GET_IF_SIDE(acc_flags, pkg_side);
    825     chip_id = _huracan_get_sw_chip_id(pa);
    826     lane_map = PHYMOD_ACC_LANE_MASK(pa);
    827     GET_SUPPORTED_LANES(chip_id,num_lanes);
    828 
    829     for (lane_index = 0; lane_index < num_lanes; lane_index++) {
    830         if (((lane_map >> lane_index) & 1) == 0x1) {
    831             /* get the lane info, fetch the value from lane*/
    832             lane_info = _huracan_get_pkg_to_die_lane_info(chip_id,pa,lane_index,0);
    833             PHYMOD_NULL_CHECK(lane_info);
    834             PHYMOD_IF_ERR_RETURN(
    835                     huracan_core_phy_power_get(pa, chip_id, lane_info->die_num, lane_info->lane_num,pkg_side,&tpower));
    836             power->tx = tpower.tx;
    837             power->rx = tpower.rx;
    838             if (HURACAN_IS_DUPLEX(chip_id)) {
    839                 /* get the rx lane info, fetch the value from tx lane*/
    840                 lane_info = _huracan_get_pkg_to_die_lane_info(chip_id,pa,lane_index,1);
    841                 PHYMOD_NULL_CHECK(lane_info);
    842                 PHYMOD_IF_ERR_RETURN(
    843                         huracan_core_phy_power_get(pa, chip_id, lane_info->die_num, lane_info->lane_num,pkg_side,&tpower));
    844                 power->tx = tpower.tx;
    845             }
    846         }
    847     }
    848 
    849     return PHYMOD_E_NONE;
    850 }
    851 
    852 
    853 int huracan_gpio_config_set(const phymod_access_t *pa, int pin_no, phymod_gpio_mode_t gpio_mode)
    854 {
    855     BCMI_HURACAN_GPIO_0_CONTROLr_t pad_ctrl_gpio_ctrl;
    856 
    857     if (pin_no > 1) {
    858         PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("Huracan has only 2 GPIOs (0 - 1)")));
    859     }
    860 
    861     PHYMOD_IF_ERR_RETURN
    862         (PHYMOD_BUS_READ(pa, (pin_no*2) + BCMI_HURACAN_GPIO_0_CONTROLr, &pad_ctrl_gpio_ctrl._gpio_0_control));
    863 
    864     switch (gpio_mode) {
    865         case phymodGpioModeDisabled :
    866             return PHYMOD_E_UNAVAIL;
    867         case phymodGpioModeOutput :
    868             BCMI_HURACAN_GPIO_0_CONTROLr_GPIO_0_OEBf_SET(pad_ctrl_gpio_ctrl, 0);
    869             break;     
    870         case phymodGpioModeInput :
    871             BCMI_HURACAN_GPIO_0_CONTROLr_GPIO_0_OEBf_SET(pad_ctrl_gpio_ctrl, 1);
    872             break;    
    873         default:
    874             return PHYMOD_E_PARAM;
    875     }
    876 
    877     PHYMOD_IF_ERR_RETURN
    878         (PHYMOD_BUS_WRITE(pa, (pin_no*2) + BCMI_HURACAN_GPIO_0_CONTROLr, pad_ctrl_gpio_ctrl._gpio_0_control));
    879 
    880     return PHYMOD_E_NONE;
    881 }
    882 
    883 int huracan_gpio_config_get(const phymod_access_t *pa, int pin_no, phymod_gpio_mode_t* gpio_mode)
    884 {
    885     BCMI_HURACAN_GPIO_0_CONTROLr_t pad_ctrl_gpio_ctrl;
    886 
    887     *gpio_mode = 0;
    888     if (pin_no > 1) {
    889         PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("Huracan has only 2 GPIOs (0 - 1)")));
    890     }
    891 
    892     PHYMOD_IF_ERR_RETURN
    893         (PHYMOD_BUS_READ(pa, (pin_no*2) + BCMI_HURACAN_GPIO_0_CONTROLr, &pad_ctrl_gpio_ctrl._gpio_0_control));
    894 
    895     switch(BCMI_HURACAN_GPIO_0_CONTROLr_GPIO_0_OEBf_GET(pad_ctrl_gpio_ctrl)) {
    896         case 0:
    897             *gpio_mode = phymodGpioModeOutput; 
    898             break;
    899         default:
    900             *gpio_mode = phymodGpioModeInput;
    901             break;
    902     }
    903 
    904     return PHYMOD_E_NONE;
    905 }
    906 
    907 int huracan_gpio_pin_value_set(const phymod_access_t *pa, int pin_no, int value)
    908 {
    909     BCMI_HURACAN_GPIO_0_CONTROLr_t pad_ctrl_gpio_ctrl;
    910 
    911     if (pin_no > 1) {
    912         PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("Huracan has only 2 GPIOs (0 - 1)")));
    913     }
    914     PHYMOD_IF_ERR_RETURN
    915         (PHYMOD_BUS_READ(pa, (pin_no*2) + BCMI_HURACAN_GPIO_0_CONTROLr, &pad_ctrl_gpio_ctrl._gpio_0_control));
    916     BCMI_HURACAN_GPIO_0_CONTROLr_GPIO_0_IBOFf_SET( pad_ctrl_gpio_ctrl, 1);
    917     BCMI_HURACAN_GPIO_0_CONTROLr_GPIO_0_OUT_FRCVALf_SET(pad_ctrl_gpio_ctrl, (value & 1));
    918 
    919     switch(value >> 1) {
    920         case 0:
    921             BCMI_HURACAN_GPIO_0_CONTROLr_GPIO_0_PUPf_SET( pad_ctrl_gpio_ctrl, 0);
    922             BCMI_HURACAN_GPIO_0_CONTROLr_GPIO_0_PDNf_SET( pad_ctrl_gpio_ctrl, 1);
    923             break;
    924         case 1:
    925             BCMI_HURACAN_GPIO_0_CONTROLr_GPIO_0_PUPf_SET( pad_ctrl_gpio_ctrl, 1);
    926             BCMI_HURACAN_GPIO_0_CONTROLr_GPIO_0_PDNf_SET( pad_ctrl_gpio_ctrl, 0);
    927             break;
    928         case 2:
    929             BCMI_HURACAN_GPIO_0_CONTROLr_GPIO_0_PUPf_SET( pad_ctrl_gpio_ctrl, 0);
    930             BCMI_HURACAN_GPIO_0_CONTROLr_GPIO_0_PDNf_SET( pad_ctrl_gpio_ctrl, 0);
    931             break;
    932         default:
    933             return PHYMOD_E_PARAM;
    934     }
    935 
    936     PHYMOD_IF_ERR_RETURN
    937         (PHYMOD_BUS_WRITE(pa, (pin_no*2) + BCMI_HURACAN_GPIO_0_CONTROLr, pad_ctrl_gpio_ctrl._gpio_0_control));
    938 
    939     return PHYMOD_E_NONE;
    940 }
    941 
    942 int huracan_gpio_pin_value_get(const phymod_access_t *pa, int pin_no, int* value)
    943 {
    944     BCMI_HURACAN_GPIO_0_STATUSr_t pad_sts_gpio;
    945     BCMI_HURACAN_GPIO_0_CONTROLr_t pad_ctrl_gpio_ctrl;
    946     *value = 0;
    947 
    948     if (pin_no > 1) {
    949         PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("Huracan has only 2 GPIOs (0 - 1)")));
    950     }
    951 
    952     PHYMOD_IF_ERR_RETURN
    953         (PHYMOD_BUS_READ(pa, (pin_no*2) + BCMI_HURACAN_GPIO_0_STATUSr, &pad_sts_gpio._gpio_0_status));
    954 
    955     *value = BCMI_HURACAN_GPIO_0_STATUSr_GPIO_0_DINf_GET(pad_sts_gpio);
    956     PHYMOD_IF_ERR_RETURN
    957             (PHYMOD_BUS_READ(pa, (pin_no*2) + BCMI_HURACAN_GPIO_0_CONTROLr, &pad_ctrl_gpio_ctrl._gpio_0_control));
    958 
    959     if (BCMI_HURACAN_GPIO_0_CONTROLr_GPIO_0_PUPf_GET(pad_ctrl_gpio_ctrl)){
    960            *value |= (1<<1);
    961     } else 
    962            if (!BCMI_HURACAN_GPIO_0_CONTROLr_GPIO_0_PDNf_GET(pad_ctrl_gpio_ctrl)){
    963                 *value |= (2<<1);
    964     }
    965 
    966     return PHYMOD_E_NONE;
    967 }
    968 
    969 
    970 int _huracan_pll_seq_restart(const phymod_access_t *pa, uint32_t flag,
    971         phymod_sequencer_operation_t operation)
    972 {
    973     return PHYMOD_E_NONE;
    974 }
    975 
    976 int _huracan_phy_tx_set(const phymod_access_t* pa, const phymod_tx_t* tx)
    977 {
    978     return PHYMOD_E_NONE;
    979 }
    980 
    981 int _huracan_phy_tx_get(const phymod_access_t* pa, phymod_tx_t* tx) 
    982 {
    983     return PHYMOD_E_NONE;
    984 }
    985 
    986 int _huracan_phy_rx_set(const phymod_access_t* pa, const phymod_rx_t* rx)
    987 {
    988     return PHYMOD_E_NONE;
    989 }
    990 
    991 int _huracan_phy_rx_get(const phymod_access_t* pa, phymod_rx_t* rx)
    992 {
    993     return PHYMOD_E_NONE;
    994 }
    995 
    996 
    997 int _huracan_phy_status_dump(const phymod_access_t *pa)
    998 {
    999     uint32_t chip_id = 0, rev_id = 0;
   1000     uint32_t reg_addr = 0, value = 0;
   1001     int num_lanes = 0, lane_index = 0;
   1002     uint8_t lane_bitmap = 0, quad = 0;
   1003     int lane_map = 0;
   1004 
   1005     /* Get the lane map from phymod access */
   1006     lane_map = PHYMOD_ACC_LANE_MASK(pa);
   1007 
   1008     /* Get the chip id */
   1009     chip_id = _huracan_get_chip_id(pa);
   1010     huracan_rev_id(pa , &rev_id);
   1011     GET_SUPPORTED_LANES(chip_id,num_lanes);
   1012 
   1013     PHYMOD_DIAG_OUT(("**********************************************\n"));
   1014     PHYMOD_DIAG_OUT(("******* PHY status dump for PHY ID:%d ********\n",pa->addr));
   1015     PHYMOD_DIAG_OUT(("**********************************************\n"));
   1016     PHYMOD_DIAG_OUT(("*******************************************\n"));
   1017     PHYMOD_DIAG_OUT(("****** PHY status dump for chip/rev: %X  %X *********\n",chip_id, rev_id));
   1018     PHYMOD_DIAG_OUT(("***********************************************\n"));
   1019 
   1020     reg_addr = BCMI_HURACAN_GPIO_0_CONTROLr ;
   1021     PHYMOD_IF_ERR_RETURN( PHYMOD_BUS_READ(pa, reg_addr, &value));
   1022     PHYMOD_DIAG_OUT(("GPIO_0_CONTROLr       :reg%08x: value=%04x\n", hmr(reg_addr), value));
   1023 
   1024     reg_addr = BCMI_HURACAN_GPIO_0_STATUSr ;
   1025     PHYMOD_IF_ERR_RETURN( PHYMOD_BUS_READ(pa, reg_addr, &value));
   1026     PHYMOD_DIAG_OUT(("GPIO_0_STATUSr        :reg%08x: value=%04x\n", hmr(reg_addr), value));
   1027 
   1028     reg_addr = BCMI_HURACAN_GPIO_1_CONTROLr ;
   1029     PHYMOD_IF_ERR_RETURN( PHYMOD_BUS_READ(pa, reg_addr, &value));
   1030     PHYMOD_DIAG_OUT(("GPIO_1_CONTROLr       :reg%08x: value=%04x\n", hmr(reg_addr), value));
   1031 
   1032     reg_addr = BCMI_HURACAN_GPIO_1_STATUSr ;
   1033     PHYMOD_IF_ERR_RETURN( PHYMOD_BUS_READ(pa, reg_addr, &value));
   1034     PHYMOD_DIAG_OUT(("GPIO_1_STATUSr        :reg%08x: value=%04x\n", hmr(reg_addr), value));
   1035 
   1036     for(lane_index = 0; lane_index < num_lanes; lane_index++) {
   1037         if (((lane_map >> lane_index) & 1) == 0x1) {
   1038 
   1039             quad        = lane_index  >> 2 ;
   1040             lane_bitmap = (0x1  <<  (lane_index & 0x3));
   1041 
   1042             /* Power */
   1043             reg_addr = BCMI_HURACAN_ANA_LANE_0_QUAD_A_CTRL0r &  ~((0xF) << 8);
   1044             reg_addr |= ((quad & 0x7) << 12) | ((lane_bitmap & 0xF) << 8) ;
   1045 
   1046             PHYMOD_IF_ERR_RETURN( PHYMOD_BUS_READ(pa, reg_addr, &value));
   1047 
   1048             PHYMOD_DIAG_OUT(("ln%d:qd%d:reg%08x: value=%04x\n",
   1049                         lane_index, quad, hmr(reg_addr), value));
   1050 
   1051             /* Link */
   1052             reg_addr = BCMI_HURACAN_ANA_LANE_0_QUAD_A_STATUS0r &  ~((0xF) << 8);
   1053             reg_addr |= ((quad & 0x7) << 12) | ((lane_bitmap & 0xF) << 8) ;
   1054 
   1055             PHYMOD_IF_ERR_RETURN( PHYMOD_BUS_READ(pa, reg_addr, &value));
   1056 
   1057             PHYMOD_DIAG_OUT(("ln%d:qd%d:reg%08x: value=%04x\n",
   1058                         lane_index, quad, hmr(reg_addr), value));
   1059 
   1060             /* Squelch */
   1061             reg_addr = BCMI_HURACAN_ANA_LANE_0_QUAD_A_CTRL14r &  ~((0xF) << 8) ;
   1062             reg_addr |= ((quad & 0x7) << 12) | ((lane_bitmap & 0xF) << 8) ;
   1063 
   1064             PHYMOD_IF_ERR_RETURN( PHYMOD_BUS_READ(pa, reg_addr, &value));
   1065 
   1066             PHYMOD_DIAG_OUT(("ln%d:qd%d:reg%08x: value=%04x\n",
   1067                         lane_index, quad, hmr(reg_addr), value));
   1068         }
   1069     }
   1070 
   1071     return PHYMOD_E_NONE;
   1072 }