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

pm12x10_xgs.c (27010B)


      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 <soc/drv.h>
     11 #include <soc/types.h>
     12 #include <soc/error.h>
     13 #include <soc/portmod/portmod_internal.h>
     14 #include <soc/portmod/portmod_common.h>
     15 #include <soc/portmod/portmod.h>
     16 #include <soc/portmod/portmod_dispatch.h>
     17 #include <soc/portmod/pm4x10.h>
     18 #include <soc/portmod/pm12x10.h>
     19 #include <soc/portmod/portmod_chain.h>
     20 #include <soc/portmod/pm4x25_shared.h>
     21 #include <soc/portmod/portmod_system.h>
     22 
     23 
     24         
     25 #ifdef _ERR_MSG_MODULE_NAME 
     26 #error "_ERR_MSG_MODULE_NAME redefined" 
     27 #endif
     28 #define _ERR_MSG_MODULE_NAME BSL_LS_SOC_PORT
     29 
     30 #ifdef PORTMOD_PM12X10_XGS_SUPPORT
     31 
     32 static int pm12x10_xgs_core_seq[] = {0,1,2};
     33 
     34 #define PM_12x10_INFO(pm_info) ((pm_info)->pm_data.pm12x10_db)
     35 #define PM_4X25_INFO(pm_info) (PM_12x10_INFO(pm_info)->pm4x25_info)
     36 #define PM_4x25_DB(pm_info) (PM_4X25_INFO(pm_info)->pm_data.pm4x25_db)
     37 
     38 
     39 #define PM_4X10_INFO(pm_info, i) (PM_12x10_INFO(pm_info)->pm4x10_info[pm12x10_xgs_core_seq[i]])
     40 #define PM_4X25_DRIVER(pm_info) PM_DRIVER(PM_4X25_INFO(pm_info))
     41 #define PM_4X10_DRIVER(pm_info, i) PM_DRIVER(PM_4X10_INFO(pm_info, pm12x10_xgs_core_seq[i]))
     42 
     43 
     44 #define TOP_BLK_ID_OFFSET (4)
     45 
     46 #define PM12x10_INTERNAL_4x10_CNT (3)
     47 
     48 struct pm12x10_s{
     49     int blk_id;
     50     pm_info_t pm4x25_info;
     51     pm_info_t pm4x10_info[PM12x10_INTERNAL_4x10_CNT];
     52     portmod_pbmp_t phys;
     53     uint32 external_top_mode;
     54     int    refclk_source;
     55 };
     56 
     57 
     58 
     59 STATIC int
     60 pm12x10_xgs_quad0_default_bus_write(void* user_acc, uint32_t core_addr, uint32_t reg_addr, uint32_t val)
     61 {
     62     return portmod_common_phy_sbus_reg_write(CXXPORT_WC_UCMEM_DATA0m, user_acc, core_addr, reg_addr, val);
     63 }
     64 
     65 STATIC int
     66 pm12x10_xgs_quad0_default_bus_read(void* user_acc, uint32_t core_addr, uint32_t reg_addr, uint32_t *val)
     67 {
     68     return portmod_common_phy_sbus_reg_read(CXXPORT_WC_UCMEM_DATA0m, user_acc, core_addr, reg_addr, val);
     69 }
     70 
     71 phymod_bus_t pm4x10_xgs_quad0_default_bus = {
     72     "PM12x10_xgs Quad0 Bus",
     73     pm12x10_xgs_quad0_default_bus_read,
     74     pm12x10_xgs_quad0_default_bus_write,
     75     NULL,
     76     portmod_common_mutex_take,
     77     portmod_common_mutex_give,
     78     NULL,
     79     NULL,
     80     PHYMOD_BUS_CAP_WR_MODIFY | PHYMOD_BUS_CAP_LANE_CTRL
     81 };
     82 
     83 STATIC int
     84 pm12x10_xgs_quad1_default_bus_write(void* user_acc, uint32_t core_addr, uint32_t reg_addr, uint32_t val)
     85 {
     86     return portmod_common_phy_sbus_reg_write(CXXPORT_WC_UCMEM_DATA1m, user_acc, core_addr, reg_addr, val);
     87 }
     88 
     89 STATIC int
     90 pm12x10_xgs_quad1_default_bus_read(void* user_acc, uint32_t core_addr, uint32_t reg_addr, uint32_t *val)
     91 {
     92     return portmod_common_phy_sbus_reg_read(CXXPORT_WC_UCMEM_DATA1m, user_acc, core_addr, reg_addr, val);
     93 }
     94 
     95 phymod_bus_t pm4x10_xgs_quad1_default_bus = {
     96     "PM12x10_xgs Quad1 Bus",
     97     pm12x10_xgs_quad1_default_bus_read,
     98     pm12x10_xgs_quad1_default_bus_write,
     99     NULL,
    100     portmod_common_mutex_take,
    101     portmod_common_mutex_give,
    102     NULL,
    103     NULL,
    104     PHYMOD_BUS_CAP_WR_MODIFY | PHYMOD_BUS_CAP_LANE_CTRL
    105 };
    106 
    107 STATIC int
    108 pm12x10_xgs_quad2_default_bus_write(void* user_acc, uint32_t core_addr, uint32_t reg_addr, uint32_t val)
    109 {
    110     return portmod_common_phy_sbus_reg_write(CXXPORT_WC_UCMEM_DATA2m, user_acc, core_addr, reg_addr, val);
    111 }
    112 
    113 STATIC int
    114 pm12x10_xgs_quad2_default_bus_read(void* user_acc, uint32_t core_addr, uint32_t reg_addr, uint32_t *val)
    115 {
    116     return portmod_common_phy_sbus_reg_read(CXXPORT_WC_UCMEM_DATA2m, user_acc, core_addr, reg_addr, val);
    117 }
    118 
    119 phymod_bus_t pm4x10_xgs_quad2_default_bus = {
    120     "PM12x10_xgs Quad2 Bus",
    121     pm12x10_xgs_quad2_default_bus_read,
    122     pm12x10_xgs_quad2_default_bus_write,
    123     NULL,
    124     portmod_common_mutex_take,
    125     portmod_common_mutex_give,
    126     NULL,
    127     NULL,
    128     PHYMOD_BUS_CAP_WR_MODIFY | PHYMOD_BUS_CAP_LANE_CTRL
    129 };
    130 
    131 STATIC portmod_ucode_buf_t pm12x10_xgs_ucode_buf[SOC_MAX_NUM_DEVICES]  = {{NULL, 0}};
    132 
    133 STATIC int
    134 pm4x10_xgs_quad0_default_fw_loader(const phymod_core_access_t* core, uint32_t length, const uint8_t* data)
    135 {
    136     int rv;
    137     portmod_default_user_access_t *user_data;
    138     int unit = ((portmod_default_user_access_t*)core->access.user_acc)->unit;
    139     SOC_INIT_FUNC_DEFS;
    140 
    141     user_data = (portmod_default_user_access_t*)core->access.user_acc;
    142 
    143     rv = portmod_firmware_set(unit,
    144                               user_data->blk_id,
    145                               data,
    146                               length,
    147                               portmod_ucode_buf_order_reversed,
    148                               0,
    149                               &(pm12x10_xgs_ucode_buf[unit]),
    150                               NULL,
    151                               CXXPORT_WC_UCMEM_DATA0m,
    152                               CXXPORT_WC_UCMEM_CTRL0r);
    153     _SOC_IF_ERR_EXIT(rv); 
    154 
    155 exit:
    156     SOC_FUNC_RETURN;
    157 }
    158 
    159 STATIC int
    160 pm4x10_xgs_quad1_default_fw_loader(const phymod_core_access_t* core, uint32_t length, const uint8_t* data)
    161 {
    162     int rv;
    163     portmod_default_user_access_t *user_data;
    164     int unit = ((portmod_default_user_access_t*)core->access.user_acc)->unit;
    165     SOC_INIT_FUNC_DEFS;
    166 
    167     user_data = (portmod_default_user_access_t*)core->access.user_acc;
    168 
    169     rv = portmod_firmware_set(unit,
    170                               user_data->blk_id,
    171                               data,
    172                               length,
    173                               portmod_ucode_buf_order_reversed,
    174                               0,
    175                               &(pm12x10_xgs_ucode_buf[unit]),
    176                               NULL,
    177                               CXXPORT_WC_UCMEM_DATA1m,
    178                               CXXPORT_WC_UCMEM_CTRL1r);
    179     _SOC_IF_ERR_EXIT(rv); 
    180 
    181 exit:
    182     SOC_FUNC_RETURN;
    183 }
    184 
    185 STATIC int
    186 pm4x10_xgs_quad2_default_fw_loader(const phymod_core_access_t* core, uint32_t length, const uint8_t* data)
    187 {
    188     int rv;
    189     portmod_default_user_access_t *user_data;
    190     int unit = ((portmod_default_user_access_t*)core->access.user_acc)->unit;
    191     SOC_INIT_FUNC_DEFS;
    192 
    193     user_data = (portmod_default_user_access_t*)core->access.user_acc;
    194 
    195     rv = portmod_firmware_set(unit,
    196                               user_data->blk_id,
    197                               data,
    198                               length,
    199                               portmod_ucode_buf_order_reversed,
    200                               0,
    201                               &(pm12x10_xgs_ucode_buf[unit]),
    202                               NULL,
    203                               CXXPORT_WC_UCMEM_DATA2m,
    204                               CXXPORT_WC_UCMEM_CTRL2r);
    205     _SOC_IF_ERR_EXIT(rv); 
    206 
    207 exit:
    208     SOC_FUNC_RETURN;
    209 }
    210 
    211 int pm12x10_xgs_port_core_num_get(int unit, int port, pm_info_t pm_info, int* core_num)
    212 {
    213     int rv = 0, i;
    214     SOC_INIT_FUNC_DEFS;
    215 
    216     for(i = 0 ; i < 3 ; i++)
    217     {
    218         rv = PM_4X10_DRIVER(pm_info, i)->f_portmod_port_core_num_get(unit, port,
    219                                              PM_4X10_INFO(pm_info,i), core_num);
    220         _SOC_IF_ERR_EXIT(rv);
    221     }
    222 
    223 exit:
    224     SOC_FUNC_RETURN;
    225 }
    226 
    227 int pm12x10_xgs_pm_destroy(int unit, pm_info_t pm_info)
    228 {
    229     if(pm_info->pm_data.pm12x10_db != NULL){
    230         sal_free(pm_info->pm_data.pm12x10_db);
    231         pm_info->pm_data.pm12x10_db = NULL;
    232     }
    233 
    234     /* free pm12x10_xgs_ucode_buf */
    235     if(pm12x10_xgs_ucode_buf[unit].ucode_dma_buf != NULL){
    236         portmod_sys_dma_free(unit, pm12x10_xgs_ucode_buf[unit].ucode_dma_buf);
    237         pm12x10_xgs_ucode_buf[unit].ucode_dma_buf = NULL;
    238     }
    239     pm12x10_xgs_ucode_buf[unit].ucode_alloc_size = 0;
    240 
    241     return SOC_E_NONE;
    242 }
    243 
    244 
    245 
    246 int pm12x10_xgs_pm_init(int unit, const portmod_pm_create_info_internal_t* pm_add_info, 
    247                     int wb_buffer_index, pm_info_t pm_info)
    248 {
    249     pm12x10_t pm12x10_data = NULL;
    250     int nof_phys = 0, core;
    251     portmod_bus_update_t bupdate;
    252     SOC_INIT_FUNC_DEFS;
    253 
    254     PORTMOD_PBMP_COUNT(pm_add_info->phys, nof_phys);
    255     if(nof_phys != 12){
    256         _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("number of phys should be 12")));
    257     }
    258     pm12x10_data = sal_alloc(sizeof(*(pm_info->pm_data.pm12x10_db)), "specific_db");
    259     SOC_NULL_CHECK(pm12x10_data);
    260 
    261     /*PM12x10 Top*/
    262     pm_info->type = portmodDispatchTypePm12x10_xgs;
    263     pm_info->unit = unit;
    264     pm_info->wb_buffer_id = wb_buffer_index;
    265 
    266     pm_info->pm_data.pm12x10_db = pm12x10_data;
    267     pm_info->pm_data.pm12x10_db->blk_id =  pm_add_info->pm_specific_info.pm12x10.blk_id; 
    268     PORTMOD_PBMP_ASSIGN(pm_info->pm_data.pm12x10_db->phys, pm_add_info->phys);
    269 
    270     for (core = 0; core < PM12x10_INTERNAL_4x10_CNT; core++) {
    271         pm_info->pm_data.pm12x10_db->pm4x10_info[core] = 
    272                 pm_add_info->pm_specific_info.pm12x10.pm4x10[core];
    273     }
    274 
    275     pm_info->pm_data.pm12x10_db->pm4x25_info = pm_add_info->pm_specific_info.pm12x10.pm4x25;
    276     pm_info->pm_data.pm12x10_db->refclk_source = pm_add_info->pm_specific_info.pm12x10.refclk_source;
    277     pm_info->pm_data.pm12x10_db->external_top_mode = PORTMOD_PM12x10_F_EXTERNAL_TOP_MODE_GET(pm_add_info->pm_specific_info.pm12x10.flags);
    278 
    279     if(!pm_info->pm_data.pm12x10_db->external_top_mode) {
    280         /* Update Quad 0 */
    281         bupdate.blk_id = pm_info->pm_data.pm12x10_db->blk_id;
    282         bupdate.default_bus = &pm4x10_xgs_quad0_default_bus;
    283         bupdate.external_fw_loader = pm4x10_xgs_quad0_default_fw_loader;
    284         bupdate.user_acc = NULL; /*use default user_acc */
    285         _SOC_IF_ERR_EXIT(pm4x10_default_bus_update(unit, PM_12x10_INFO(pm_info)->pm4x10_info[0], &bupdate));
    286 
    287         /* Update Quad 1 */
    288         bupdate.default_bus = &pm4x10_xgs_quad1_default_bus;
    289         bupdate.external_fw_loader = pm4x10_xgs_quad1_default_fw_loader;
    290         _SOC_IF_ERR_EXIT(pm4x10_default_bus_update(unit, PM_12x10_INFO(pm_info)->pm4x10_info[1], &bupdate));
    291 
    292         /* Update Quad 2 */
    293         bupdate.default_bus = &pm4x10_xgs_quad2_default_bus;
    294         bupdate.external_fw_loader = pm4x10_xgs_quad2_default_fw_loader;
    295         _SOC_IF_ERR_EXIT(pm4x10_default_bus_update(unit, PM_12x10_INFO(pm_info)->pm4x10_info[2], &bupdate));
    296 
    297     }
    298 
    299 exit:
    300     if(SOC_FUNC_ERROR){
    301         pm12x10_xgs_pm_destroy(unit, pm_info);
    302     }
    303     SOC_FUNC_RETURN; 
    304 }
    305 
    306 int pm12x10_xgs_port_attach (int unit, int port, pm_info_t pm_info, 
    307                          const portmod_port_add_info_t* add_info)
    308 {
    309     portmod_port_add_info_t  lcl_add_info = *add_info;
    310     uint32 nof_lanes = 0;
    311     int i = 0;
    312     int rv = 0;
    313     SOC_INIT_FUNC_DEFS;
    314 
    315     PORTMOD_PBMP_COUNT(add_info->phys, nof_lanes);
    316 
    317     if (nof_lanes == 10) {
    318         
    319     } else if(nof_lanes != 12){
    320         _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("number of lanes should be 10 or 12")));
    321     }
    322 
    323     lcl_add_info.interface_config.flags |= PHYMOD_INTF_F_SET_CORE_MAP_MODE;
    324 
    325     for(i = 0 ; i < 3 ; i++)
    326     {
    327         /* do it before pm is active only - so skip in the second pass of multi stage init */
    328         if (PORTMOD_PORT_ADD_F_INIT_CORE_PROBE_GET(add_info) || (lcl_add_info.flags == 0)) {
    329             rv = PM_4X10_DRIVER(pm_info, i)->f_portmod_pm_bypass_set(unit, PM_4X10_INFO(pm_info,i), 1);
    330             _SOC_IF_ERR_EXIT(rv);
    331         }
    332 
    333         if (i) {
    334             lcl_add_info.flags |= PORTMOD_PORT_ADD_F_PORT_ATTACH_EXT_PHY_SKIP;
    335         }
    336 
    337         rv = PM_4X10_DRIVER(pm_info, i)->f_portmod_port_attach(unit, port, PM_4X10_INFO(pm_info,i), &lcl_add_info);
    338         _SOC_IF_ERR_EXIT(rv);
    339     }
    340 
    341     if (PORTMOD_PORT_ADD_F_INIT_PASS2_GET(add_info) || (add_info->flags == 0)) {
    342 
    343         for(i = 0 ; i < 3 ; i++)
    344         {
    345             rv = PM_4X10_DRIVER(pm_info, i)->f_portmod_port_interface_config_set(unit, 
    346                                           port, PM_4X10_INFO(pm_info,i), 
    347                                           &add_info->interface_config, 
    348                                           PORTMOD_INIT_F_ALL_PHYS);
    349             _SOC_IF_ERR_EXIT(rv);
    350         }
    351 
    352          if(!pm_info->pm_data.pm12x10_db->external_top_mode) {
    353             rv = WRITE_CXXPORT_MODE_REGr(unit, port, 1); 
    354             _SOC_IF_ERR_EXIT(rv);
    355         }
    356     }
    357 
    358     /* CAUI10 port is not connected to any PHY.., so clear the phy information before adding it */
    359     lcl_add_info = *add_info;
    360     SOC_PBMP_CLEAR(lcl_add_info.phys);
    361     for(i = 0 ; i < PM4X25_LANES_PER_CORE; i++){
    362         PM_4x25_DB(pm_info)->nof_phys[i] = 0;
    363     }
    364 
    365     rv = PM_4X25_DRIVER(pm_info)->f_portmod_port_attach(unit, port, PM_4X25_INFO(pm_info), &lcl_add_info);
    366     _SOC_IF_ERR_EXIT(rv);
    367 
    368 exit:
    369     SOC_FUNC_RETURN; 
    370 }
    371 
    372 int pm12x10_xgs_port_detach(int unit, int port, pm_info_t pm_info)
    373 {
    374     int rv = 0;
    375     int i = 0;
    376     SOC_INIT_FUNC_DEFS;
    377 
    378     /* Detach MAC first since detaching PHY and resetting the TSC's first
    379      * will render CLMAC/CLPORT registers inaccessible
    380      */
    381     rv = PM_4X25_DRIVER(pm_info)->f_portmod_port_detach(unit, port, PM_4X25_INFO(pm_info));
    382     _SOC_IF_ERR_EXIT(rv);
    383 
    384     for(i = 0 ; i < 3; i++){
    385         _SOC_IF_ERR_EXIT(PM_4X10_DRIVER(pm_info, i)->f_portmod_port_detach(unit,
    386                                    port, PM_4X10_INFO(pm_info, i)));
    387     }
    388 
    389     
    390     if(!pm_info->pm_data.pm12x10_db->external_top_mode) {
    391         rv = WRITE_CXXPORT_MODE_REGr(unit, port, 0); 
    392         _SOC_IF_ERR_EXIT(rv);
    393     }
    394 
    395     for(i = 0 ; i < 3 ; i++)
    396     {
    397         PM_4X10_DRIVER(pm_info, i)->f_portmod_pm_bypass_set(unit, PM_4X10_INFO(pm_info,i), 0);
    398     }
    399     
    400 exit:
    401     SOC_FUNC_RETURN; 
    402 }
    403 
    404 
    405 int pm12x10_xgs_port_led_chain_config(int unit, int port, pm_info_t pm_info, int value)
    406 {
    407     SOC_INIT_FUNC_DEFS;
    408 
    409     _SOC_IF_ERR_EXIT(WRITE_CXXPORT_LED_CHAIN_CONFIGr (unit, port, value));
    410 
    411 exit:
    412     SOC_FUNC_RETURN;
    413 }
    414 
    415 int pm12x10_xgs_pm4x10_enable(int unit, int port, uint32 phy, uint32 enable) 
    416 {
    417     pm_info_t pm_info;
    418     int found = 0, quad, i, phy_i;
    419     int core_num;
    420     uint32 soft_reset, power_save;
    421     soc_port_if_t if_type;
    422     SOC_INIT_FUNC_DEFS;
    423 
    424     /* get PM info */
    425     _SOC_IF_ERR_EXIT(portmod_pm_info_type_get(unit, port, portmodDispatchTypePm12x10_xgs, &pm_info)); 
    426 
    427     if(!pm_info->pm_data.pm12x10_db->external_top_mode) {
    428         /* get inteface type */
    429         _SOC_IF_ERR_EXIT(portmod_port_interface_type_get(unit, port, &if_type));
    430 
    431         /* Find quad */
    432         i=0;
    433         quad=-1;
    434         PORTMOD_PBMP_ITER(PM_12x10_INFO(pm_info)->phys, phy_i) {
    435             if(i%4 == 0) {
    436                 quad++;
    437             }
    438             if(phy_i == phy) {
    439                 found = 1;
    440                 break;
    441             }
    442             i++;
    443         }
    444 
    445         if(!found) {
    446             _SOC_EXIT_WITH_ERR(SOC_E_INTERNAL, (_SOC_MSG("Phy invalid for current PM")));
    447         }
    448         
    449         _SOC_IF_ERR_EXIT(pm12x10_xgs_port_core_num_get(unit, port, pm_info, &core_num));
    450 
    451         if (!((((core_num >= 4) && (core_num <= 6))) || ((core_num >= 13) && (core_num <= 15)))) {
    452             _SOC_EXIT_WITH_ERR(SOC_E_INTERNAL, (_SOC_MSG("invalid core for current PM")));
    453         }
    454 
    455         /* Enable block */
    456         _SOC_IF_ERR_EXIT(READ_CXXPORT_SOFT_RESETr(unit, port, &soft_reset));
    457         _SOC_IF_ERR_EXIT(READ_CXXPORT_POWER_SAVEr(unit, port, &power_save));
    458 
    459         switch(quad) {
    460             case 0:
    461                 soc_reg_field_set(unit, CXXPORT_SOFT_RESETr, &soft_reset, CORE0_RSTf, enable ? 0 : 1);
    462                 soc_reg_field_set(unit, CXXPORT_POWER_SAVEr, &power_save, CORE0_PWRDWNf, enable ? 0 : 1);
    463                 break;
    464             case 1:
    465                 soc_reg_field_set(unit, CXXPORT_SOFT_RESETr, &soft_reset, CORE1_RSTf, enable ? 0 : 1);
    466                 soc_reg_field_set(unit, CXXPORT_POWER_SAVEr, &power_save, CORE1_PWRDWNf, enable ? 0 : 1);
    467                 break;
    468             case 2:
    469                 soc_reg_field_set(unit, CXXPORT_SOFT_RESETr, &soft_reset, CORE2_RSTf, enable ? 0 : 1);
    470                 soc_reg_field_set(unit, CXXPORT_POWER_SAVEr, &power_save, CORE2_PWRDWNf, enable ? 0 : 1);
    471                 break;
    472             default:
    473                 _SOC_EXIT_WITH_ERR(SOC_E_INTERNAL, (_SOC_MSG("Invalid quad")));
    474         }
    475 
    476         /* PM4x25 reset */
    477         if(if_type != SOC_PORT_IF_CAUI) {
    478             soc_reg_field_set(unit, CXXPORT_SOFT_RESETr, &soft_reset, CORE3_RSTf, 1); /* always in reset */
    479             soc_reg_field_set(unit, CXXPORT_POWER_SAVEr, &power_save, CORE3_PWRDWNf, 1); /* always power down */
    480         } else {
    481             soc_reg_field_set(unit, CXXPORT_SOFT_RESETr, &soft_reset, CORE3_RSTf, enable ? 0 : 1);
    482             soc_reg_field_set(unit, CXXPORT_POWER_SAVEr, &power_save, CORE3_PWRDWNf, enable ? 0 : 1);
    483         }
    484 
    485         if(enable) {
    486             _SOC_IF_ERR_EXIT(WRITE_CXXPORT_POWER_SAVEr(unit, port, power_save));
    487             _SOC_IF_ERR_EXIT(WRITE_CXXPORT_SOFT_RESETr(unit, port, soft_reset));
    488         } else {
    489             _SOC_IF_ERR_EXIT(WRITE_CXXPORT_SOFT_RESETr(unit, port, soft_reset));
    490             _SOC_IF_ERR_EXIT(WRITE_CXXPORT_POWER_SAVEr(unit, port, power_save));
    491         }
    492     }
    493 
    494 exit:
    495     SOC_FUNC_RETURN;
    496 }
    497 
    498 
    499 int pm12x10_xgs_pm4x10_tsc_reset(int unit, int port, uint32 phy, uint32 in_reset) 
    500 {
    501     pm_info_t pm_info;
    502     int found = 0, quad, i, phy_i;
    503     int core_num;
    504     uint32 reg_val;
    505     SOC_INIT_FUNC_DEFS;
    506 
    507     /* get PM info */
    508     _SOC_IF_ERR_EXIT(portmod_pm_info_type_get(unit, port, portmodDispatchTypePm12x10_xgs, &pm_info)); 
    509 
    510     if(!pm_info->pm_data.pm12x10_db->external_top_mode) {
    511         /* Find quad */
    512         i=0;
    513         quad=-1;
    514         PORTMOD_PBMP_ITER(PM_12x10_INFO(pm_info)->phys, phy_i) {
    515             if(i%4 == 0) {
    516                 quad++;
    517             }
    518             if(phy_i == phy) {
    519                 found = 1;
    520                 break;
    521             }
    522             i++;
    523         }
    524 
    525         if(!found) {
    526             _SOC_EXIT_WITH_ERR(SOC_E_INTERNAL, (_SOC_MSG("Phy invalid for current PM")));
    527         }
    528         
    529 
    530         _SOC_IF_ERR_EXIT(pm12x10_xgs_port_core_num_get(unit, port, pm_info, &core_num));
    531 
    532         if (!((((core_num >= 4) && (core_num <= 6))) || ((core_num >= 13) && (core_num <= 15)))) {
    533             _SOC_EXIT_WITH_ERR(SOC_E_INTERNAL, (_SOC_MSG("invalid core for current PM")));
    534         }
    535 
    536         /* Enable block */
    537         switch(quad) {
    538             case 0:
    539                 _SOC_IF_ERR_EXIT(READ_CXXPORT_XGXS0_CTRL0_REGr(unit, port, &reg_val));
    540                 soc_reg_field_set (unit, CXXPORT_XGXS0_CTRL0_REGr, &reg_val, RSTB_HWf, in_reset ? 0 : 1);
    541                 soc_reg_field_set (unit, CXXPORT_XGXS0_CTRL0_REGr, &reg_val, PWRDWNf, in_reset ? 1 : 0);
    542                 soc_reg_field_set (unit, CXXPORT_XGXS0_CTRL0_REGr, &reg_val, IDDQf, in_reset ? 1 : 0);
    543                 soc_reg_field_set (unit, CXXPORT_XGXS0_CTRL0_REGr, &reg_val, REFOUT_ENf, 0);
    544                 soc_reg_field_set (unit, CXXPORT_XGXS0_CTRL0_REGr, &reg_val, REFIN_ENf, 1);
    545                 _SOC_IF_ERR_EXIT(WRITE_CXXPORT_XGXS0_CTRL0_REGr(unit, port, reg_val));
    546                 break;
    547             case 1:
    548                 _SOC_IF_ERR_EXIT(READ_CXXPORT_XGXS0_CTRL1_REGr(unit, port, &reg_val));
    549                 soc_reg_field_set (unit, CXXPORT_XGXS0_CTRL1_REGr, &reg_val, RSTB_HWf, in_reset ? 0 : 1);
    550                 soc_reg_field_set (unit, CXXPORT_XGXS0_CTRL1_REGr, &reg_val, PWRDWNf, in_reset ? 1 : 0);
    551                 soc_reg_field_set (unit, CXXPORT_XGXS0_CTRL1_REGr, &reg_val, IDDQf, in_reset ? 1 : 0);
    552                 soc_reg_field_set (unit, CXXPORT_XGXS0_CTRL1_REGr, &reg_val, REFOUT_ENf, 0);
    553                 soc_reg_field_set (unit, CXXPORT_XGXS0_CTRL1_REGr, &reg_val, REFIN_ENf, 1);
    554                 _SOC_IF_ERR_EXIT(WRITE_CXXPORT_XGXS0_CTRL1_REGr(unit, port, reg_val));
    555                 break;
    556             case 2:
    557                 _SOC_IF_ERR_EXIT(READ_CXXPORT_XGXS0_CTRL2_REGr(unit, port, &reg_val));
    558                 soc_reg_field_set (unit, CXXPORT_XGXS0_CTRL2_REGr, &reg_val, RSTB_HWf, in_reset ? 0 : 1);
    559                 soc_reg_field_set (unit, CXXPORT_XGXS0_CTRL2_REGr, &reg_val, PWRDWNf, in_reset ? 1 : 0);
    560                 soc_reg_field_set (unit, CXXPORT_XGXS0_CTRL2_REGr, &reg_val, IDDQf, in_reset ? 1 : 0);
    561                 soc_reg_field_set (unit, CXXPORT_XGXS0_CTRL2_REGr, &reg_val, REFOUT_ENf, 0);
    562                 soc_reg_field_set (unit, CXXPORT_XGXS0_CTRL2_REGr, &reg_val, REFIN_ENf, 1);
    563                 _SOC_IF_ERR_EXIT(WRITE_CXXPORT_XGXS0_CTRL2_REGr(unit, port, reg_val));
    564                 break;
    565             default:
    566                 _SOC_EXIT_WITH_ERR(SOC_E_INTERNAL, (_SOC_MSG("Invalid quad")));
    567         }
    568     }
    569 
    570 exit:
    571     SOC_FUNC_RETURN;
    572 }
    573 
    574 
    575 /* set interrupt value. */
    576 int pm12x10_xgs_port_interrupt_enable_get (int unit, int port, pm_info_t pm_info,
    577                                     int intr_type, uint32 *val)
    578 {
    579     uint32 reg_val;
    580     SOC_INIT_FUNC_DEFS;
    581 
    582     _SOC_IF_ERR_EXIT(READ_CXXPORT_INTR_ENABLEr(unit, port, &reg_val));
    583 
    584     switch(intr_type) {
    585         case portmodIntrTypeCore0Intr:
    586              *val = soc_reg_field_get(unit, CXXPORT_INTR_ENABLEr, reg_val, CORE0_INTf);
    587              break;
    588         case portmodIntrTypeCore1Intr:
    589              *val = soc_reg_field_get(unit, CXXPORT_INTR_ENABLEr, reg_val, CORE1_INTf);
    590              break;
    591         case portmodIntrTypeCore2Intr:
    592              *val = soc_reg_field_get(unit, CXXPORT_INTR_ENABLEr, reg_val, CORE2_INTf);
    593              break;
    594         case portmodIntrTypeCore3Intr:
    595              *val = soc_reg_field_get(unit, CXXPORT_INTR_ENABLEr, reg_val, CORE3_INTf);
    596              break;
    597         case portmodIntrTypeTsc0Intr:
    598              *val = soc_reg_field_get(unit, CXXPORT_INTR_ENABLEr, reg_val, TSC_0_INTf);
    599              break;
    600         case portmodIntrTypeTsc1Intr:
    601              *val = soc_reg_field_get(unit, CXXPORT_INTR_ENABLEr, reg_val, TSC_0_INTf);
    602              break;
    603         case portmodIntrTypeTsc2Intr:
    604              *val = soc_reg_field_get(unit, CXXPORT_INTR_ENABLEr, reg_val, TSC_0_INTf);
    605              break;
    606 
    607         default:
    608             _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Invalid interrupt type")));
    609             break;
    610     }
    611 exit:
    612     SOC_FUNC_RETURN;
    613 }
    614 
    615 /* set interrupt value. */ 
    616 int pm12x10_xgs_port_interrupt_enable_set (int unit, int port, pm_info_t pm_info,
    617                                     int intr_type, uint32 val)
    618 {
    619     uint32 reg_val;
    620     SOC_INIT_FUNC_DEFS;
    621 
    622     _SOC_IF_ERR_EXIT(READ_CXXPORT_INTR_ENABLEr(unit, port, &reg_val));
    623 
    624     switch(intr_type) {
    625         case portmodIntrTypeCore0Intr:
    626              soc_reg_field_set(unit, CXXPORT_INTR_ENABLEr, &reg_val, CORE0_INTf, val);
    627              break;
    628         case portmodIntrTypeCore1Intr:
    629              soc_reg_field_set(unit, CXXPORT_INTR_ENABLEr, &reg_val, CORE1_INTf, val);
    630              break;
    631         case portmodIntrTypeCore2Intr:
    632              soc_reg_field_set(unit, CXXPORT_INTR_ENABLEr, &reg_val, CORE2_INTf, val);
    633              break;
    634         case portmodIntrTypeCore3Intr:
    635              soc_reg_field_set(unit, CXXPORT_INTR_ENABLEr, &reg_val, CORE3_INTf, val);
    636              break;
    637         case portmodIntrTypeTsc0Intr:
    638              soc_reg_field_set(unit, CXXPORT_INTR_ENABLEr, &reg_val, TSC_0_INTf, val);
    639              break;
    640         case portmodIntrTypeTsc1Intr:
    641              soc_reg_field_set(unit, CXXPORT_INTR_ENABLEr, &reg_val, TSC_0_INTf, val);
    642              break;
    643         case portmodIntrTypeTsc2Intr:
    644              soc_reg_field_set(unit, CXXPORT_INTR_ENABLEr, &reg_val, TSC_0_INTf, val);
    645              break;
    646 
    647         default:
    648             _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Invalid interrupt type")));
    649             break;
    650     }
    651     _SOC_IF_ERR_EXIT(WRITE_CXXPORT_INTR_ENABLEr(unit, port, reg_val));
    652 exit:
    653     SOC_FUNC_RETURN;
    654 }
    655 
    656 /* get interrupt value. */
    657 int pm12x10_xgs_port_interrupt_get (int unit, int port, pm_info_t pm_info,
    658                                int intr_type, uint32* val)
    659 {
    660     uint32 reg_val;
    661     SOC_INIT_FUNC_DEFS;
    662 
    663     _SOC_IF_ERR_EXIT(READ_CXXPORT_INTR_STATUSr(unit, port, &reg_val));
    664 
    665     switch(intr_type) {
    666         case portmodIntrTypeCore0Intr:
    667              *val = soc_reg_field_get(unit, CXXPORT_INTR_STATUSr, reg_val, CORE0_INTf);
    668              break;
    669         case portmodIntrTypeCore1Intr:
    670              *val = soc_reg_field_get(unit, CXXPORT_INTR_STATUSr, reg_val, CORE1_INTf);
    671              break;
    672         case portmodIntrTypeCore2Intr:
    673              *val = soc_reg_field_get(unit, CXXPORT_INTR_STATUSr, reg_val, CORE2_INTf);
    674              break;
    675         case portmodIntrTypeCore3Intr:
    676              *val = soc_reg_field_get(unit, CXXPORT_INTR_STATUSr, reg_val, CORE3_INTf);
    677              break;
    678         case portmodIntrTypeTsc0Intr:
    679              *val = soc_reg_field_get(unit, CXXPORT_INTR_STATUSr, reg_val, TSC_0_INTf);
    680              break;
    681         case portmodIntrTypeTsc1Intr:
    682              *val = soc_reg_field_get(unit, CXXPORT_INTR_STATUSr, reg_val, TSC_1_INTf);
    683              break;
    684         case portmodIntrTypeTsc2Intr:
    685              *val = soc_reg_field_get(unit, CXXPORT_INTR_STATUSr, reg_val, TSC_2_INTf);
    686              break;
    687 
    688         default:
    689             _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Invalid interrupt type")));
    690             break;
    691     }
    692 exit:
    693     SOC_FUNC_RETURN;
    694 }
    695 
    696 int pm12x10_xgs_port_interrupts_get (int unit, int port, pm_info_t pm_info,
    697                                 int arr_max_size, uint32* intr_arr, uint32* size)
    698 {
    699     uint32 reg_val, cnt = 0;
    700     SOC_INIT_FUNC_DEFS;
    701 
    702     _SOC_IF_ERR_EXIT(READ_CXXPORT_INTR_STATUSr(unit, port, &reg_val));
    703 
    704     if (soc_reg_field_get(unit, CXXPORT_INTR_STATUSr, reg_val, CORE0_INTf)) {
    705         if (cnt >= arr_max_size) {
    706             _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size")));
    707         }
    708         intr_arr[cnt++] = portmodIntrTypeCore0Intr;
    709     }
    710 
    711     if (soc_reg_field_get(unit, CXXPORT_INTR_STATUSr, reg_val, CORE1_INTf)) {
    712         if (cnt >= arr_max_size) {
    713             _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size")));
    714         }
    715         intr_arr[cnt++] = portmodIntrTypeCore1Intr;
    716     }
    717 
    718     if (soc_reg_field_get(unit, CXXPORT_INTR_STATUSr, reg_val, CORE2_INTf)) {
    719         if (cnt >= arr_max_size) {
    720             _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size")));
    721         }
    722         intr_arr[cnt++] = portmodIntrTypeCore2Intr;
    723     }
    724 
    725     if (soc_reg_field_get(unit, CXXPORT_INTR_STATUSr, reg_val, CORE3_INTf)) {
    726         if (cnt >= arr_max_size) {
    727             _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size")));
    728         }
    729         intr_arr[cnt++] = portmodIntrTypeCore3Intr;
    730     }
    731 
    732     if (soc_reg_field_get(unit, CXXPORT_INTR_STATUSr, reg_val, TSC_0_INTf)) {
    733         if (cnt >= arr_max_size) {
    734             _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size")));
    735         }
    736         intr_arr[cnt++] = portmodIntrTypeTsc0Intr;
    737     }
    738 
    739     if (soc_reg_field_get(unit, CXXPORT_INTR_STATUSr, reg_val, TSC_1_INTf)) {
    740         if (cnt >= arr_max_size) {
    741             _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size")));
    742         }
    743         intr_arr[cnt++] = portmodIntrTypeTsc1Intr;
    744     }
    745 
    746     if (soc_reg_field_get(unit, CXXPORT_INTR_STATUSr, reg_val, TSC_2_INTf)) {
    747         if (cnt >= arr_max_size) {
    748             _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size")));
    749         }
    750         intr_arr[cnt++] = portmodIntrTypeTsc2Intr;
    751     }
    752 
    753     *size = cnt;
    754 
    755 exit:
    756     SOC_FUNC_RETURN;
    757 }
    758 
    759 
    760 
    761 #endif /* PORTMOD_PM12X10_XGS_SUPPORT */
    762 
    763 #undef _ERR_MSG_MODULE_NAME