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

portctrl.c (35140B)


      1 /*
      2  * 
      3  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      4  * 
      5  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      6  *
      7  * portctrl soc routines
      8  */
      9 
     10 #include <sal/core/libc.h>
     11 
     12 #include <soc/debug.h>
     13 #include <soc/util.h>
     14 #include <soc/bondoptions.h>
     15 #include <soc/mem.h>
     16 #include <soc/esw/portctrl.h>
     17 #include <soc/esw/portctrl_internal.h>
     18 #include <soc/helix5.h>
     19 #include <shared/bsl.h>
     20 #include <soc/phy/phymod_sim.h>
     21 #include <soc/portmod/portmod.h>
     22 
     23 #ifdef BCM_HELIX5_SUPPORT
     24 
     25 #define SOC_HX5_PM4X10_COUNT         4
     26 #define SOC_HX5_PM4X10_QTC_COUNT     3
     27 #define SOC_HX5_PM4X25_COUNT         3
     28 
     29 static uint32_t _hx5_pm4x10_addr[SOC_HX5_PM4X10_COUNT] = {
     30     0xA1, 0xA5, 0xA9, 0xAD
     31 };
     32 
     33 static uint32_t _hx5_pm4x10_core_num[SOC_HX5_PM4X10_COUNT] = {
     34     3, 4, 5, 6
     35 };
     36 
     37 static uint32_t _hx5_pm4x10_port[SOC_HX5_PM4X10_COUNT] = {
     38     49, 53, 57, 61
     39 };
     40 
     41 static uint32_t _hx5_pm4x10q_addr[SOC_HX5_PM4X10_QTC_COUNT] = {
     42     0x81, /* PM4x10Q Inst 0 */
     43     0x85, /* PM4x10Q Inst 1 */
     44     0x89  /* PM4x10Q Inst 2 */
     45 };
     46 
     47 static uint32_t _hx5_pm4x10q_core_num[SOC_HX5_PM4X10_QTC_COUNT] = {
     48     0, 1, 2
     49 };
     50 
     51 static uint32_t _hx5_pm4x10q_port[SOC_HX5_PM4X10_QTC_COUNT] = {
     52     1, 17, 33
     53 };
     54 
     55 static uint32_t _hx5_pm4x25_addr[SOC_HX5_PM4X25_COUNT] = {
     56     0xC1, 0xC5, 0xC9
     57 };
     58 
     59 static uint32_t _hx5_pm4x25_core_num[SOC_HX5_PM4X25_COUNT] = {
     60     7, 8, 9
     61 };
     62 
     63 static uint32_t _hx5_pm4x25_port[SOC_HX5_PM4X25_COUNT] = {
     64     65, 69, 73
     65 };
     66 
     67 
     68 #define SOC_HX5_MAX_PHYS            88    /*  48 GXPORTS + 28 XLPORTS + 12 CLPORTS */
     69 #define SOC_HX5_SUB_PHYS_IN_QSGMII      4
     70 
     71 static portmod_pm_instances_t hx5_pm_types[] = {
     72 #ifdef PORTMOD_PM4X10_SUPPORT
     73         {portmodDispatchTypePm4x10,  SOC_HX5_PM4X10_COUNT},
     74 #endif
     75 #ifdef PORTMOD_PM4X25_SUPPORT
     76         {portmodDispatchTypePm4x25,  SOC_HX5_PM4X25_COUNT},
     77 #endif
     78 #ifdef PORTMOD_PM4X10_QTC_SUPPORT
     79         {portmodDispatchTypePm4x10_qtc, SOC_HX5_PM4X10_QTC_COUNT},
     80 #endif
     81 };
     82 
     83 #ifdef PORTMOD_PM4X10_SUPPORT
     84 static portmod_default_user_access_t *pm4x10_hx5_user_acc[SOC_MAX_NUM_DEVICES];
     85 #endif /* PORTMOD_PM4X10_SUPPORT */
     86 
     87 #ifdef PORTMOD_PM4X10_QTC_SUPPORT
     88 static portmod_default_user_access_t *pm4x10q_hx5_user_acc[SOC_MAX_NUM_DEVICES];
     89 static portmod_default_user_access_t *pm4x10q_4x10_hx5_user_acc[SOC_MAX_NUM_DEVICES];
     90 #endif /* PORTMOD_PM4X10_QTC_SUPPORT */
     91 
     92 #ifdef PORTMOD_PM4X25_SUPPORT
     93 static portmod_default_user_access_t *pm4x25_hx5_user_acc[SOC_MAX_NUM_DEVICES];
     94 #endif /* PORTMOD_PM4X25_SUPPORT */
     95 
     96 #define SOC_HX5_CORE_FREQ_KHZ_DEFAULT 50000  /* HX5 default core freq is 50MHz*/
     97 
     98 extern int soc_hx5_portctrl_pm_portmod_init(int unit);
     99 extern int soc_hx5_portctrl_pm_portmod_deinit(int unit);
    100 extern int soc_hx5_portctrl_pm_port_config_get(int unit, soc_port_t port, void *port_config_info);
    101 extern int soc_hx5_portctrl_pm_port_phyaddr_get(int unit, soc_port_t port);
    102 extern int soc_hx5_portctrl_pm_type_get(int unit, soc_port_t phy_port, int* pm_type);
    103 
    104 soc_portctrl_functions_t soc_hx5_portctrl_func = {
    105     soc_hx5_portctrl_pm_portmod_init,
    106     soc_hx5_portctrl_pm_portmod_deinit,
    107     soc_hx5_portctrl_pm_port_config_get,
    108     soc_hx5_portctrl_pm_port_phyaddr_get,
    109     NULL /* soc_hx5_portctrl_port_ability_update*/,
    110     soc_hx5_portctrl_pm_type_get,
    111     NULL,
    112     NULL
    113 };
    114 
    115 STATIC int
    116 _soc_hx5_portctrl_pm_init(int unit, int *max_phys,
    117                            portmod_pm_instances_t **pm_types,
    118                            int *pms_arr_len)
    119 {
    120     *max_phys = SOC_HX5_MAX_PHYS;
    121     *pm_types = hx5_pm_types;
    122     *pms_arr_len = (sizeof(hx5_pm_types) / sizeof(portmod_pm_instances_t));
    123 
    124     return SOC_E_NONE;
    125 }
    126 
    127 STATIC int
    128 _soc_hx5_portctrl_device_addr_port_get(int unit, int pm_type,
    129                                         uint32_t **addr,
    130                                         uint32_t **port,
    131                                         uint32_t **core_num)
    132 {
    133     *addr     = NULL;
    134     *port     = NULL;
    135     *core_num = NULL;
    136 
    137     if (pm_type == portmodDispatchTypePm4x10) {
    138         *addr = _hx5_pm4x10_addr;
    139         *port = _hx5_pm4x10_port;
    140         *core_num = _hx5_pm4x10_core_num;
    141     } else if (pm_type == portmodDispatchTypePm4x25){
    142         *addr = _hx5_pm4x25_addr;
    143         *port = _hx5_pm4x25_port;
    144         *core_num = _hx5_pm4x25_core_num;
    145     } else if (pm_type == portmodDispatchTypePm4x10_qtc){
    146         *addr = _hx5_pm4x10q_addr;
    147         *port = _hx5_pm4x10q_port;
    148         *core_num = _hx5_pm4x10q_core_num;
    149     }
    150 
    151     return SOC_E_NONE;
    152 }
    153 
    154 STATIC int
    155 _soc_hx5_portctrl_pm_user_acc_flag_set(int unit,
    156                     portmod_default_user_access_t* pm_user_access)
    157 {
    158     return SOC_E_NONE;
    159 }
    160 
    161 /*
    162  * Polarity get looks for physical port based config first. This will enable
    163  * the user to define the polarity for all ports weather mapped to logical 
    164  * port or not.
    165  */
    166 STATIC
    167 void helix5_pm_port_polarity_get(int unit, int physical_port, int lane,
    168                                  uint32 *tx_pol, uint32* rx_pol)
    169 {
    170     uint32 rx_polarity, tx_polarity;
    171 
    172     rx_polarity = soc_property_phy_get (unit, physical_port, 0, 0, lane,
    173                      spn_PHY_CHAIN_RX_POLARITY_FLIP_PHYSICAL, 0x0);
    174     *rx_pol = (rx_polarity & 0x1) << lane;
    175 
    176     tx_polarity = soc_property_phy_get (unit, physical_port, 0, 0, lane,
    177                      spn_PHY_CHAIN_TX_POLARITY_FLIP_PHYSICAL, 0x0);
    178     *tx_pol = (tx_polarity & 0x1) << lane;
    179 }
    180 
    181 /*
    182  * lanemap get looks for physical port based config first. This will enable
    183  * the user to define the lanemap for all ports weather mapped to logical 
    184  * port or not.
    185  */
    186 STATIC 
    187 void helix5_pm_port_lanemap_get (int unit, int physical_port,
    188                                  uint32 *txlane_map, uint32* rxlane_map)
    189 {
    190 
    191     *rxlane_map = soc_property_phy_get (unit, physical_port, 0, 0, 0, 
    192                                         spn_PHY_CHAIN_RX_LANE_MAP_PHYSICAL, 0x3210);
    193 
    194 
    195     *txlane_map = soc_property_phy_get (unit, physical_port, 0, 0, 0, 
    196                                         spn_PHY_CHAIN_TX_LANE_MAP_PHYSICAL, 0x3210);
    197 
    198 }
    199 
    200 
    201 STATIC int
    202 _soc_hx5_portctrl_pm4x10_portmod_init(int unit, int num_of_instances)
    203 {
    204 #ifdef PORTMOD_PM4X10_SUPPORT
    205     int rv = SOC_E_NONE;
    206     portmod_pm_create_info_t pm_info;
    207     int pmid = 0, blk, is_sim, found;
    208     int first_port, idx, core_num, core_cnt;
    209     uint32 *pAddr, *pPort, *pCoreNum;
    210 
    211 
    212     SOC_IF_ERROR_RETURN
    213         (_soc_hx5_portctrl_device_addr_port_get(unit,
    214                                                portmodDispatchTypePm4x10,
    215                                                &pAddr, &pPort, &pCoreNum));
    216     if (!pAddr || !pPort) {
    217         return SOC_E_INTERNAL;
    218     }
    219 
    220     /* Allocate PMs */
    221     SOC_IF_ERROR_RETURN
    222         (soc_esw_portctrl_pm_user_access_alloc(unit,
    223                                            num_of_instances,
    224                                            &pm4x10_hx5_user_acc[unit]));
    225 
    226     for (pmid = 0; PORTMOD_SUCCESS(rv) && (pmid < num_of_instances); pmid++) {
    227 
    228         rv = portmod_pm_create_info_t_init(unit, &pm_info);
    229         if (PORTMOD_FAILURE(rv)) {
    230             break;
    231         }
    232         /* PM info */
    233         first_port = pPort[pmid];
    234 
    235         PORTMOD_PBMP_PORT_ADD(pm_info.phys, first_port);
    236         PORTMOD_PBMP_PORT_ADD(pm_info.phys, first_port+1);
    237         PORTMOD_PBMP_PORT_ADD(pm_info.phys, first_port+2);
    238         PORTMOD_PBMP_PORT_ADD(pm_info.phys, first_port+3);
    239 
    240         found = 0;
    241         for(idx = 0; idx < SOC_DRIVER(unit)->port_num_blktype; idx++){
    242             blk = SOC_PORT_IDX_INFO(unit, first_port, idx).blk;
    243             if (SOC_BLOCK_INFO(unit, blk).type == SOC_BLK_XLPORT) {
    244                     found = 1;
    245                     break;
    246             }
    247 
    248         }
    249         if (!found) {
    250             rv = SOC_E_INTERNAL;
    251             break;
    252         }
    253 
    254         pm_info.type         = portmodDispatchTypePm4x10;
    255 
    256         /* Init user_acc for phymod access struct */
    257         rv = portmod_default_user_access_t_init(unit,
    258                                                 &(pm4x10_hx5_user_acc[unit][pmid]));
    259         if (PORTMOD_FAILURE(rv)) {
    260             break;
    261         }
    262 
    263         SOC_IF_ERROR_RETURN(
    264             _soc_hx5_portctrl_pm_user_acc_flag_set(unit,
    265                 &(pm4x10_hx5_user_acc[unit][pmid])));
    266 
    267         PORTMOD_USER_ACCESS_FW_LOAD_REVERSE_SET((&(pm4x10_hx5_user_acc[unit][pmid])));
    268         pm4x10_hx5_user_acc[unit][pmid].unit = unit;
    269         pm4x10_hx5_user_acc[unit][pmid].blk_id = blk;
    270         pm4x10_hx5_user_acc[unit][pmid].mutex = sal_mutex_create("core mutex");
    271         if (pm4x10_hx5_user_acc[unit][pmid].mutex == NULL) {
    272             rv = SOC_E_MEMORY;
    273             break;
    274         }
    275 
    276         /* Specific info for PM4x10 */
    277         rv = phymod_access_t_init(&pm_info.pm_specific_info.pm4x10.access);
    278         if (PORTMOD_FAILURE(rv)) {
    279             break;
    280         }
    281 
    282         pm_info.pm_specific_info.pm4x10.access.user_acc =
    283             &(pm4x10_hx5_user_acc[unit][pmid]);
    284         pm_info.pm_specific_info.pm4x10.access.addr     = pAddr[pmid];
    285         pm_info.pm_specific_info.pm4x10.access.bus      = NULL; /* Use default bus */
    286         pm_info.pm_specific_info.pm4x10.lane_map.num_of_lanes              = SOC_PM4X10_NUM_LANES;
    287         pm_info.pm_specific_info.pm4x10.rescal                             = -1;
    288 
    289         rv = soc_physim_check_sim(unit, phymodDispatchTypeTsce16,
    290                                   &(pm_info.pm_specific_info.pm4x10.access),
    291                                   0, &is_sim);
    292         if (PORTMOD_FAILURE(rv)) {
    293             break;
    294         }
    295 
    296         if (is_sim) {
    297             pm_info.pm_specific_info.pm4x10.access.bus->bus_capabilities |=
    298                 (PHYMOD_BUS_CAP_WR_MODIFY | PHYMOD_BUS_CAP_LANE_CTRL);
    299 
    300             /* Firmward loader : Don't allow FW load on sim enviroment */
    301             pm_info.pm_specific_info.pm4x10.fw_load_method =
    302                 phymodFirmwareLoadMethodNone;
    303         }
    304 
    305         /* Use default external loader if NULL */
    306         pm_info.pm_specific_info.pm4x10.external_fw_loader = NULL;
    307 
    308         core_cnt = 1;
    309 
    310         for (core_num = 0; core_num < core_cnt; core_num++) {
    311             pm_info.pm_specific_info.pm4x10.core_num = pCoreNum? pCoreNum[pmid] : pmid;
    312             pm_info.pm_specific_info.pm4x10.core_num_int = 0;
    313         }
    314 
    315         /* Add PM to PortMod */
    316         rv = portmod_port_macro_add(unit, &pm_info);
    317     }
    318 
    319     if (PORTMOD_FAILURE(rv)) {
    320         for (pmid=0; pmid < num_of_instances; pmid++) {
    321             if (pm4x10_hx5_user_acc[unit][pmid].mutex) {
    322                 sal_mutex_destroy(pm4x10_hx5_user_acc[unit][pmid].mutex);
    323                 pm4x10_hx5_user_acc[unit][pmid].mutex = NULL;
    324             }
    325         }
    326     }
    327 
    328     return rv;
    329 #else /* PORTMOD_PM4X10_SUPPORT */
    330     return SOC_E_UNAVAIL;
    331 #endif /* PORTMOD_PM4X10_SUPPORT */
    332 }
    333 
    334 STATIC int
    335 _soc_hx5_portctrl_pm4x10_qtc_pm_qtc_init(int unit, int instance_id, portmod_pm_qtc_create_info_t *pm_qtc_info)
    336 {
    337 #ifdef PORTMOD_PM4X10_QTC_SUPPORT
    338     int rv = SOC_E_NONE;
    339     int blk, is_sim, found;
    340     int blktype;
    341     uint32 *pAddr, *pPort, *pCoreNum;
    342 
    343     SOC_IF_ERROR_RETURN
    344         (_soc_hx5_portctrl_device_addr_port_get(unit,
    345                                                portmodDispatchTypePm4x10_qtc,
    346                                                &pAddr, &pPort, &pCoreNum));
    347     if (!pAddr || !pPort) {
    348         return SOC_E_INTERNAL;
    349     }
    350 
    351     /* Pm_qtc information */
    352     found = 0;
    353     for (blk = 0; SOC_BLOCK_INFO(unit, blk).type >= 0; blk++) {
    354         blktype = SOC_BLOCK_INFO(unit, blk).type;
    355         if ((blktype == SOC_BLK_PMQPORT) && (SOC_BLOCK_INFO(unit, blk).number == instance_id)) {
    356             found = 1;
    357             break;
    358         }
    359     }
    360 
    361     if (!found) {
    362         return SOC_E_INTERNAL;
    363     }
    364 
    365     /* Init user_acc for phymod access struct */
    366     rv = portmod_default_user_access_t_init(unit,
    367                                             &(pm4x10q_hx5_user_acc[unit][instance_id]));
    368     if (PORTMOD_FAILURE(rv)) {
    369         return rv;
    370     }
    371 
    372     /* for Qmode.  */
    373     pm4x10q_hx5_user_acc[unit][instance_id].unit = unit;
    374     pm4x10q_hx5_user_acc[unit][instance_id].blk_id = blk;
    375     pm4x10q_hx5_user_acc[unit][instance_id].mutex = sal_mutex_create("core mutex");
    376     if (pm4x10q_hx5_user_acc[unit][instance_id].mutex == NULL) {
    377         return SOC_E_MEMORY;
    378     }
    379 
    380     /* Specific info for PM_QTC */
    381     rv = phymod_access_t_init(&pm_qtc_info->access);
    382     if (PORTMOD_FAILURE(rv)) {
    383         return rv;
    384     }
    385     PORTMOD_USER_ACCESS_FW_LOAD_REVERSE_SET((&(pm4x10q_hx5_user_acc[unit][instance_id])));
    386     pm_qtc_info->access.user_acc = &pm4x10q_hx5_user_acc[unit][instance_id];
    387     pm_qtc_info->access.addr     = pAddr[instance_id];
    388     pm_qtc_info->access.bus      = NULL;
    389     pm_qtc_info->lane_map.num_of_lanes = SOC_PM4X10_QTC_NUM_LANES;
    390     pm_qtc_info->core_num        = pCoreNum[instance_id];
    391     pm_qtc_info->core_clock_khz  = SOC_HX5_CORE_FREQ_KHZ_DEFAULT;
    392 
    393     rv = soc_physim_check_sim(unit, phymodDispatchTypeQtce16,
    394                               &(pm_qtc_info->access),
    395                               0, &is_sim);
    396     if (PORTMOD_FAILURE(rv)) {
    397         return rv;
    398     }
    399 
    400     if (is_sim) {
    401         pm_qtc_info->access.bus->bus_capabilities |=
    402             (PHYMOD_BUS_CAP_WR_MODIFY | PHYMOD_BUS_CAP_LANE_CTRL);
    403 
    404         /* Firmward loader : Don't allow FW load on sim enviroment */
    405         pm_qtc_info->fw_load_method = phymodFirmwareLoadMethodNone;
    406     }
    407 
    408     /* Use default external loader */
    409     pm_qtc_info->external_fw_loader = NULL;
    410 
    411     return rv;
    412 #else /* PORTMOD_PM4X10_QTC_SUPPORT */
    413     return SOC_E_UNAVAIL;
    414 #endif /* PORTMOD_PM4X10_QTC_SUPPORT */
    415 }
    416 
    417 STATIC int
    418 _soc_hx5_portctrl_pm4x10_qtc_pm4x10_init(int unit, int instance_id, portmod_pm4x10_create_info_t *pm4x10_info)
    419 {
    420 #ifdef PORTMOD_PM4X10_QTC_SUPPORT
    421     int rv = SOC_E_NONE;
    422     int blk, is_sim, found;
    423     int first_port, idx;
    424     uint32 *pAddr, *pPort, *pCoreNum;
    425 
    426     SOC_IF_ERROR_RETURN
    427         (_soc_hx5_portctrl_device_addr_port_get(unit,
    428                                                portmodDispatchTypePm4x10_qtc,
    429                                                &pAddr, &pPort, &pCoreNum));
    430     if (!pAddr || !pPort) {
    431         return SOC_E_INTERNAL;
    432     }
    433 
    434     first_port = pPort[instance_id];
    435 
    436     /* Pm4x10 information */
    437     found = 0;
    438     for (idx = 0; idx < SOC_DRIVER(unit)->port_num_blktype; idx++) {
    439         blk = SOC_PORT_IDX_INFO(unit, first_port , idx).blk;
    440         if (SOC_BLOCK_INFO(unit, blk).type == SOC_BLK_XLPORT) {
    441             found = 1;
    442             break;
    443         }
    444     }
    445 
    446     if (!found) {
    447         return SOC_E_INTERNAL;
    448     }
    449 
    450     /* Init user_acc for phymod access struct */
    451     rv = portmod_default_user_access_t_init(unit,
    452                                             &(pm4x10q_4x10_hx5_user_acc[unit][instance_id]));
    453     if (PORTMOD_FAILURE(rv)) {
    454         return rv;
    455     }
    456     pm4x10q_4x10_hx5_user_acc[unit][instance_id].unit = unit;
    457     pm4x10q_4x10_hx5_user_acc[unit][instance_id].blk_id = blk;
    458     pm4x10q_4x10_hx5_user_acc[unit][instance_id].mutex = sal_mutex_create("core mutex");
    459     if (pm4x10q_4x10_hx5_user_acc[unit][instance_id].mutex == NULL) {
    460         return SOC_E_MEMORY;
    461     }
    462 
    463     /* Specific info for PM4x10 */
    464     rv = phymod_access_t_init(&pm4x10_info->access);
    465     if (PORTMOD_FAILURE(rv)) {
    466         return rv;
    467     }
    468     PORTMOD_USER_ACCESS_FW_LOAD_REVERSE_SET((&(pm4x10q_4x10_hx5_user_acc[unit][instance_id])));
    469     pm4x10_info->access.user_acc = &pm4x10q_4x10_hx5_user_acc[unit][instance_id];
    470     pm4x10_info->access.addr     = pAddr[instance_id];
    471     pm4x10_info->access.bus      = NULL;
    472     pm4x10_info->lane_map.num_of_lanes = SOC_PM4X10_NUM_LANES;
    473     pm4x10_info->core_num        = pCoreNum[instance_id];
    474     pm4x10_info->core_num_int    = 0;
    475     pm4x10_info->rescal          = -1;
    476 
    477     rv = soc_physim_check_sim(unit, phymodDispatchTypeTsce16,
    478                               &(pm4x10_info->access),
    479                               2, &is_sim);
    480     if (PORTMOD_FAILURE(rv)) {
    481         return rv;
    482     }
    483 
    484     if (is_sim) {
    485         pm4x10_info->access.bus->bus_capabilities |=
    486             (PHYMOD_BUS_CAP_WR_MODIFY | PHYMOD_BUS_CAP_LANE_CTRL);
    487 
    488         /* Firmward loader : Don't allow FW load on sim enviroment */
    489         pm4x10_info->fw_load_method =
    490             phymodFirmwareLoadMethodNone;
    491     }
    492     return rv;
    493 #else /* PORTMOD_PM4X10_QTC_SUPPORT */
    494     return SOC_E_UNAVAIL;
    495 #endif /* PORTMOD_PM4X10_QTC_SUPPORT */
    496 }
    497 
    498 STATIC int
    499 _soc_hx5_portctrl_pm4x10_qtc_portmod_init(int unit, int num_of_instances)
    500 {
    501 #ifdef PORTMOD_PM4X10_QTC_SUPPORT
    502     int rv = SOC_E_NONE;
    503     portmod_pm_create_info_t pm4x10_qtc_info;
    504     int instance_id = 0;
    505     int first_port;
    506     uint32 *pAddr, *pPort, *pCoreNum;
    507 
    508     SOC_IF_ERROR_RETURN
    509         (_soc_hx5_portctrl_device_addr_port_get(unit,
    510                                                portmodDispatchTypePm4x10_qtc,
    511                                                &pAddr, &pPort, &pCoreNum));
    512     if (!pAddr || !pPort) {
    513         return SOC_E_INTERNAL;
    514     }
    515 
    516     /* Allocate PMs */
    517     SOC_IF_ERROR_RETURN
    518         (soc_esw_portctrl_pm_user_access_alloc(unit, num_of_instances,
    519                                                &pm4x10q_hx5_user_acc[unit]));
    520     /* Allocate PMs */
    521     SOC_IF_ERROR_RETURN
    522         (soc_esw_portctrl_pm_user_access_alloc(unit, num_of_instances,
    523                                                &pm4x10q_4x10_hx5_user_acc[unit]));
    524 
    525     for (instance_id = 0; PORTMOD_SUCCESS(rv) && (instance_id < num_of_instances); instance_id++) {
    526         /* Pm4x10_qtc information*/
    527         rv = portmod_pm_create_info_t_init(unit, &pm4x10_qtc_info);
    528         if (PORTMOD_FAILURE(rv)) {
    529             break;
    530         }
    531         /* PM info */
    532         first_port = pPort[instance_id];
    533 
    534         PORTMOD_PBMP_PORT_ADD(pm4x10_qtc_info.phys, first_port);
    535         PORTMOD_PBMP_PORT_ADD(pm4x10_qtc_info.phys, first_port+1);
    536         PORTMOD_PBMP_PORT_ADD(pm4x10_qtc_info.phys, first_port+2);
    537         PORTMOD_PBMP_PORT_ADD(pm4x10_qtc_info.phys, first_port+3);
    538         PORTMOD_PBMP_PORT_ADD(pm4x10_qtc_info.phys, first_port+4);
    539         PORTMOD_PBMP_PORT_ADD(pm4x10_qtc_info.phys, first_port+5);
    540         PORTMOD_PBMP_PORT_ADD(pm4x10_qtc_info.phys, first_port+6);
    541         PORTMOD_PBMP_PORT_ADD(pm4x10_qtc_info.phys, first_port+7);
    542         PORTMOD_PBMP_PORT_ADD(pm4x10_qtc_info.phys, first_port+8);
    543         PORTMOD_PBMP_PORT_ADD(pm4x10_qtc_info.phys, first_port+9);
    544         PORTMOD_PBMP_PORT_ADD(pm4x10_qtc_info.phys, first_port+10);
    545         PORTMOD_PBMP_PORT_ADD(pm4x10_qtc_info.phys, first_port+11);
    546         PORTMOD_PBMP_PORT_ADD(pm4x10_qtc_info.phys, first_port+12);
    547         PORTMOD_PBMP_PORT_ADD(pm4x10_qtc_info.phys, first_port+13);
    548         PORTMOD_PBMP_PORT_ADD(pm4x10_qtc_info.phys, first_port+14);
    549         PORTMOD_PBMP_PORT_ADD(pm4x10_qtc_info.phys, first_port+15);
    550 
    551         pm4x10_qtc_info.type         = portmodDispatchTypePm4x10_qtc;
    552 
    553         /*pm_qtc infomration*/
    554         rv = _soc_hx5_portctrl_pm4x10_qtc_pm_qtc_init(unit, instance_id,
    555                                 &pm4x10_qtc_info.pm_specific_info.pm4x10_qtc.pm_qtc_info);
    556         if (PORTMOD_FAILURE(rv)) {
    557             break;
    558         }
    559 
    560         /*pm4x10 infomration*/
    561         rv = _soc_hx5_portctrl_pm4x10_qtc_pm4x10_init(unit, instance_id,
    562                                 &pm4x10_qtc_info.pm_specific_info.pm4x10_qtc.pm4x10_info);
    563         if (PORTMOD_FAILURE(rv)) {
    564             break;
    565         }
    566 
    567         /* Add PM_QTC to PortMod */
    568         rv = portmod_port_macro_add(unit, &pm4x10_qtc_info);
    569     }
    570 
    571     if (PORTMOD_FAILURE(rv)) {
    572         for (instance_id=0; instance_id < num_of_instances; instance_id++) {
    573             if (pm4x10q_hx5_user_acc[unit][instance_id].mutex) {
    574                 sal_mutex_destroy(pm4x10q_hx5_user_acc[unit][instance_id].mutex);
    575                 pm4x10q_hx5_user_acc[unit][instance_id].mutex = NULL;
    576             }
    577        
    578             if (pm4x10q_4x10_hx5_user_acc[unit][instance_id].mutex) {
    579                 sal_mutex_destroy(pm4x10q_4x10_hx5_user_acc[unit][instance_id].mutex);
    580                 pm4x10q_4x10_hx5_user_acc[unit][instance_id].mutex = NULL;
    581             }
    582         }
    583     }
    584 
    585     return rv;
    586 #else /* PORTMOD_PM4X10_QTC_SUPPORT */
    587     return SOC_E_UNAVAIL;
    588 #endif /* PORTMOD_PM4X10_QTC_SUPPORT */
    589 }
    590 
    591 STATIC int
    592 _soc_hx5_portctrl_pm4x25_portmod_init(int unit, int num_of_instances)
    593 {
    594 #ifdef PORTMOD_PM4X25_SUPPORT
    595     int rv = SOC_E_NONE;
    596     portmod_pm_create_info_t pm_info;
    597     int pmid = 0, blk, is_sim, found;
    598     int first_port, idx, core_num, core_cnt; 
    599     uint32 *pAddr, *pPort,*pCoreNum;
    600 
    601     SOC_IF_ERROR_RETURN
    602         (_soc_hx5_portctrl_device_addr_port_get(unit,
    603                                                  portmodDispatchTypePm4x25,
    604                                                  &pAddr, &pPort,&pCoreNum));
    605     if (!pAddr || !pPort) {
    606         return SOC_E_INTERNAL;
    607     }
    608 
    609     /* Allocate PMs */
    610     SOC_IF_ERROR_RETURN
    611         (soc_esw_portctrl_pm_user_access_alloc(unit,
    612                                            num_of_instances,
    613                                            &pm4x25_hx5_user_acc[unit]));
    614 
    615     for (pmid = 0; PORTMOD_SUCCESS(rv) && (pmid < num_of_instances); pmid++) {
    616 
    617         rv = portmod_pm_create_info_t_init(unit, &pm_info);
    618         if (PORTMOD_FAILURE(rv)) {
    619             break;
    620         }
    621         /* PM info */
    622         first_port = pPort[pmid];
    623 
    624         PORTMOD_PBMP_PORT_ADD(pm_info.phys, first_port);
    625         PORTMOD_PBMP_PORT_ADD(pm_info.phys, first_port+1);
    626         PORTMOD_PBMP_PORT_ADD(pm_info.phys, first_port+2);
    627         PORTMOD_PBMP_PORT_ADD(pm_info.phys, first_port+3);
    628 
    629         found = 0;
    630         for(idx = 0; idx < SOC_DRIVER(unit)->port_num_blktype; idx++){
    631             blk = SOC_PORT_IDX_INFO(unit, first_port, idx).blk;
    632             if (SOC_BLOCK_INFO(unit, blk).type == SOC_BLK_CLPORT) {
    633                 found = 1;
    634                 break;
    635             }
    636         }
    637         if (!found) {
    638             rv = SOC_E_INTERNAL;
    639             break;
    640         }
    641 
    642         pm_info.type         = portmodDispatchTypePm4x25;
    643 
    644         /* Init user_acc for phymod access struct */
    645         rv = portmod_default_user_access_t_init(unit,
    646                                                 &(pm4x25_hx5_user_acc[unit][pmid]));
    647         if (PORTMOD_FAILURE(rv)) {
    648             break;
    649         }
    650 
    651         PORTMOD_USER_ACCESS_FW_LOAD_REVERSE_SET((&(pm4x25_hx5_user_acc[unit][pmid])));
    652         pm4x25_hx5_user_acc[unit][pmid].unit = unit;
    653         pm4x25_hx5_user_acc[unit][pmid].blk_id = blk;
    654         pm4x25_hx5_user_acc[unit][pmid].mutex = sal_mutex_create("core mutex");
    655         if (pm4x25_hx5_user_acc[unit][pmid].mutex == NULL) {
    656             rv = SOC_E_MEMORY;
    657             break;
    658         }
    659 
    660         /* Specific info for PM4x25 */
    661         rv = phymod_access_t_init(&pm_info.pm_specific_info.pm4x25.access);
    662         if (PORTMOD_FAILURE(rv)) {
    663             break;
    664         }
    665 
    666         pm_info.pm_specific_info.pm4x25.access.user_acc =
    667             &(pm4x25_hx5_user_acc[unit][pmid]);
    668         pm_info.pm_specific_info.pm4x25.access.addr     = pAddr[pmid];
    669         pm_info.pm_specific_info.pm4x25.access.bus      = NULL; /* Use default bus */
    670         pm_info.pm_specific_info.pm4x25.lane_map.num_of_lanes              = SOC_PM4X10_NUM_LANES;
    671         pm_info.pm_specific_info.pm4x25.rescal                             = -1;
    672 
    673 
    674         rv = soc_physim_check_sim(unit, phymodDispatchTypeTscf16,
    675                                   &(pm_info.pm_specific_info.pm4x25.access),
    676                                   0, &is_sim);
    677 
    678         if (PORTMOD_FAILURE(rv)) {
    679             break;
    680         }
    681 
    682         if (is_sim) {
    683             pm_info.pm_specific_info.pm4x25.access.bus->bus_capabilities |=
    684                 (PHYMOD_BUS_CAP_WR_MODIFY | PHYMOD_BUS_CAP_LANE_CTRL);
    685 
    686             /* Firmward loader : Don't allow FW load on sim enviroment */
    687             pm_info.pm_specific_info.pm4x25.fw_load_method =
    688                 phymodFirmwareLoadMethodNone;
    689         }
    690 
    691         /* Use default external loader if NULL */
    692         pm_info.pm_specific_info.pm4x25.external_fw_loader = NULL;
    693 
    694         core_cnt = 1;
    695 
    696         for (core_num = 0; core_num < core_cnt; core_num++) {
    697             pm_info.pm_specific_info.pm4x25.core_num = pCoreNum? pCoreNum[pmid] : pmid;
    698             pm_info.pm_specific_info.pm4x25.core_num_int = 0;
    699         }
    700 
    701         /* Add PM to PortMod */
    702         rv = portmod_port_macro_add(unit, &pm_info);
    703     }
    704 
    705     if (PORTMOD_FAILURE(rv)) {
    706         for (pmid=0; pmid < num_of_instances; pmid++) {
    707             if (pm4x25_hx5_user_acc[unit][pmid].mutex) {
    708                 sal_mutex_destroy(pm4x25_hx5_user_acc[unit][pmid].mutex);
    709                 pm4x25_hx5_user_acc[unit][pmid].mutex = NULL;
    710             }
    711         }
    712     }
    713 
    714     return rv;
    715 #else /* PORTMOD_PM4X25_SUPPORT */
    716     return SOC_E_UNAVAIL;
    717 #endif /* PORTMOD_PM4X25_SUPPORT */
    718 }
    719 
    720 
    721 /*
    722  * Function:
    723  *      soc_hx5_portctrl_pm_portmod_init
    724  * Purpose:
    725  *      Initialize PortMod and PortMacro for Trident2Plus
    726  *      Add port macros (PM) to the unit's PortMod Manager (PMM).
    727  * Parameters:
    728  *      unit             - (IN) Unit number.
    729  * Returns:
    730  *      SOC_E_XXX
    731  */
    732 int
    733 soc_hx5_portctrl_pm_portmod_init(int unit)
    734 {
    735     uint32 flags = 0;
    736     int rv = SOC_E_NONE, pms_arr_len = 0, count, max_phys= 0;
    737     portmod_pm_instances_t *pm_types = NULL;
    738 
    739     /* Call PortMod library initialization */
    740     SOC_IF_ERROR_RETURN(
    741         _soc_hx5_portctrl_pm_init(unit, &max_phys,
    742                                    &pm_types, &pms_arr_len));
    743     if (pms_arr_len == 0) {
    744         return SOC_E_UNAVAIL;
    745     }
    746 
    747     /*
    748      * If portmod was create - destroy and create again
    749      * Better way would be to create once and leave it.
    750      */
    751     if (SOC_E_NONE == soc_esw_portctrl_init_check(unit)) {
    752         SOC_IF_ERROR_RETURN(portmod_destroy(unit));
    753     }
    754 
    755     PORTMOD_CREATE_F_PM_NULL_SET(flags);
    756 
    757     SOC_IF_ERROR_RETURN
    758         (portmod_create(unit, flags, SOC_MAX_NUM_PORTS, max_phys,
    759                         pms_arr_len, pm_types));
    760 
    761     for (count = 0; SOC_SUCCESS(rv) && (count < pms_arr_len); count++) {
    762 #ifdef PORTMOD_PM4X10_SUPPORT
    763         if (pm_types[count].type == portmodDispatchTypePm4x10) {
    764             rv = _soc_hx5_portctrl_pm4x10_portmod_init
    765                 (unit, pm_types[count].instances);
    766         } else
    767 #endif /* PORTMOD_PM4X10_SUPPORT  */
    768 #ifdef PORTMOD_PM4X10_QTC_SUPPORT
    769         if (pm_types[count].type == portmodDispatchTypePm4x10_qtc) {
    770             rv = _soc_hx5_portctrl_pm4x10_qtc_portmod_init
    771                 (unit, pm_types[count].instances);
    772         } else
    773 #endif /* PORTMOD_PM4X10_QTC_SUPPORT  */
    774 #ifdef PORTMOD_PM4X25_SUPPORT
    775         if (pm_types[count].type == portmodDispatchTypePm4x25) {
    776             rv = _soc_hx5_portctrl_pm4x25_portmod_init
    777                 (unit, pm_types[count].instances);
    778         } else
    779 #endif /* PORTMOD_PM4X25_SUPPORT  */
    780         {
    781             rv = SOC_E_INTERNAL;
    782         }
    783     }
    784 
    785     return rv;
    786 }
    787 
    788 /*
    789  * Function:
    790  *      soc_hx5_portctrl_pm_portmod_deinit
    791  * Purpose:
    792  *      Deinitialize PortMod and PortMacro for Trident2Plus.
    793  *      Free pm user access data.
    794  * Parameters:
    795  *      unit      - (IN) Unit number.
    796  * Returns:
    797  *      SOC_E_NONE
    798  */
    799 int
    800 soc_hx5_portctrl_pm_portmod_deinit(int unit)
    801 {
    802     if (SOC_E_INIT == soc_esw_portctrl_init_check(unit)) {
    803         return SOC_E_NONE;
    804     }
    805 
    806     /* Free PMs structures */
    807 #ifdef PORTMOD_PM4X10_SUPPORT
    808     if (pm4x10_hx5_user_acc[unit] != NULL) {
    809         sal_free(pm4x10_hx5_user_acc[unit]);
    810         pm4x10_hx5_user_acc[unit] = NULL;
    811     }
    812 #endif /* PORTMOD_PM4X10_SUPPORT */
    813 
    814     /* Free PMs structures */
    815 #ifdef PORTMOD_PM4X10_QTC_SUPPORT
    816     if (pm4x10q_hx5_user_acc[unit] != NULL) {
    817         sal_free(pm4x10q_hx5_user_acc[unit]);
    818         pm4x10q_hx5_user_acc[unit] = NULL;
    819     }
    820 #endif /* PORTMOD_PM4X10_SUPPORT */
    821 
    822 #ifdef PORTMOD_PM4X25_SUPPORT
    823     if (pm4x25_hx5_user_acc[unit] != NULL) {
    824         sal_free(pm4x25_hx5_user_acc[unit]);
    825         pm4x25_hx5_user_acc[unit] = NULL;
    826     }
    827 #endif /* PORTMOD_PM4X25_SUPPORT */
    828 
    829     SOC_IF_ERROR_RETURN(portmod_destroy(unit));
    830 
    831     return SOC_E_NONE;
    832 }
    833 
    834 int
    835 soc_hx5_portctrl_pm_port_config_get(int unit, soc_port_t port, void *port_config)
    836 {
    837 #ifdef PORTMOD_PM4X10_SUPPORT
    838     int pmid = 0, lane, phy_port;
    839     int first_port, core_index, is_sim, type;
    840     uint32 txlane_map, rxlane_map, i;
    841     uint32 *pAddr = NULL, *pPort = NULL, *pCoreNum = NULL;
    842     uint32 tx_polarity, rx_polarity;
    843     portmod_port_init_config_t *port_config_info;
    844     phymod_firmware_load_method_t fw_load_method;
    845     phymod_polarity_t polarity; /**< Lanes Polarity */
    846     phymod_lane_map_t lane_map;
    847     uint8_t pm_found=0;
    848     int max_index;
    849 
    850     port_config_info = (portmod_port_init_config_t *)port_config;
    851 
    852     /* Find the port belong to which PM. The port has its own core id, using it to compare PM. */
    853     pm_found = 0;
    854     core_index = SOC_INFO(unit).port_serdes[port];
    855 
    856     for (i=0; i<SOC_HX5_PM4X10_QTC_COUNT; i++) {
    857         if (core_index == _hx5_pm4x10q_core_num[i]) {
    858             type = portmodDispatchTypePm4x10_qtc;
    859             SOC_IF_ERROR_RETURN
    860                 (_soc_hx5_portctrl_device_addr_port_get(unit, type,
    861                                              &pAddr, &pPort, &pCoreNum));
    862             pmid = i;
    863             pm_found = 1;
    864             break;
    865         }
    866     }
    867 
    868     if (!pm_found) {
    869         /* When port dones't find PM4x10Q, find PM4x10 again. */
    870         for (i=0; i<SOC_HX5_PM4X10_COUNT; i++) {
    871             if (core_index == _hx5_pm4x10_core_num[i]) {
    872                 type = portmodDispatchTypePm4x10;
    873                 SOC_IF_ERROR_RETURN
    874                     (_soc_hx5_portctrl_device_addr_port_get(unit, type,
    875                                                 &pAddr, &pPort, &pCoreNum));
    876                 pmid = i;
    877                 pm_found = 1;
    878                 break;
    879             }
    880         }
    881     }
    882 
    883     /* When port dones't find PM4x10, find PM4x25 again. */
    884     if (!pm_found) {
    885         for (i=0; i<SOC_HX5_PM4X25_COUNT; i++) {
    886             if (core_index == _hx5_pm4x25_core_num[i]) {
    887                 type = portmodDispatchTypePm4x25;
    888                 SOC_IF_ERROR_RETURN
    889                     (_soc_hx5_portctrl_device_addr_port_get(unit, type,
    890                                                  &pAddr, &pPort, &pCoreNum));
    891                 pmid = i;
    892                 pm_found = 1;
    893                 break;
    894             }
    895         }
    896     }
    897 
    898     if (!pAddr || !pPort) {
    899         return SOC_E_INTERNAL;
    900     }
    901 
    902     /* PM info */
    903     first_port = pPort[pmid];
    904 
    905     fw_load_method = phymodFirmwareLoadMethodExternal;
    906 
    907     soc_physim_enable_get(unit, &is_sim);
    908 
    909     if (is_sim) {
    910         /* Firmward loader : Don't allow FW load on sim enviroment */
    911         fw_load_method = phymodFirmwareLoadMethodNone;
    912     } else {
    913         fw_load_method = soc_property_suffix_num_get(unit, pmid,
    914                                         spn_LOAD_FIRMWARE, "quad",
    915                                         phymodFirmwareLoadMethodInternal);
    916         fw_load_method &= 0xff;
    917     }
    918 
    919     PORTMOD_IF_ERROR_RETURN(phymod_polarity_t_init(&polarity));
    920 
    921     max_index = IS_QSGMII_PORT(unit, port) ? SOC_PM_QTC_NUM_LANES : SOC_PM4X10_NUM_LANES;
    922 
    923     /* Polarity */
    924     for (lane = 0; lane < max_index; lane++) {
    925         phy_port = first_port + lane;
    926 
    927         helix5_pm_port_polarity_get(unit, phy_port, lane, &tx_polarity, &rx_polarity);
    928 
    929         polarity.rx_polarity |= rx_polarity;
    930         polarity.tx_polarity |= tx_polarity;
    931     }
    932 
    933     /* Lane map */
    934     PORTMOD_IF_ERROR_RETURN(phymod_lane_map_t_init(&lane_map));
    935 
    936     phy_port = first_port;
    937 
    938     helix5_pm_port_lanemap_get(unit, phy_port, &txlane_map, &rxlane_map);
    939 
    940     polarity.rx_polarity |= rx_polarity;
    941     polarity.tx_polarity |= tx_polarity;
    942 
    943     lane_map.num_of_lanes = SOC_PM4X10_NUM_LANES;
    944 
    945     for(lane = 0 ; lane < SOC_PM4X10_NUM_LANES; lane++) {
    946         lane_map.lane_map_tx[lane] = (txlane_map >> (lane * SOC_PM4X10_NUM_LANES)) &
    947                                      SOC_PM4X10_LANE_MASK;
    948         lane_map.lane_map_rx[lane] = (rxlane_map >> (lane * SOC_PM4X10_NUM_LANES)) &
    949                                      SOC_PM4X10_LANE_MASK;
    950     }
    951     sal_memcpy(&port_config_info->fw_load_method[0], &fw_load_method,
    952                 sizeof(phymod_firmware_load_method_t));
    953     port_config_info->fw_load_method_overwrite = 1;
    954     sal_memcpy(&port_config_info->polarity[0], &polarity,
    955                 sizeof(phymod_polarity_t));
    956     port_config_info->polarity_overwrite = 1;
    957     sal_memcpy(&port_config_info->lane_map[0], &lane_map,
    958                 sizeof(phymod_lane_map_t));
    959     port_config_info->lane_map_overwrite = 1;
    960 
    961     return SOC_E_NONE;
    962 #else /* PORTMOD_PM4X10_SUPPORT */
    963     return SOC_E_UNAVAIL;
    964 #endif /* PORTMOD_PM4X10_SUPPORT */
    965 }
    966 
    967 int
    968 soc_hx5_portctrl_pm_port_phyaddr_get(int unit, soc_port_t port)
    969 {
    970     int core_index;
    971     uint32 i, *pAddr = NULL, *pPort = NULL, *pCoreNum = NULL;
    972 
    973     /* Find the port belong to which PM. The port has its own core id, using it to compare PM. */
    974     core_index = SOC_INFO(unit).port_serdes[port];
    975 
    976 #ifdef PORTMOD_PM4X10_SUPPORT
    977     for (i=0; i<SOC_HX5_PM4X10_COUNT; i++) {
    978         if (core_index == _hx5_pm4x10_core_num[i]) {
    979             SOC_IF_ERROR_RETURN
    980                 (_soc_hx5_portctrl_device_addr_port_get(unit,
    981                                              portmodDispatchTypePm4x10,
    982                                              &pAddr, &pPort, &pCoreNum));
    983             return pAddr[i];
    984         }
    985     }
    986 #endif /* PORTMOD_PM4X10_SUPPORT */
    987 
    988 #ifdef PORTMOD_PM4X10_QTC_SUPPORT
    989     for (i=0; i<SOC_HX5_PM4X10_QTC_COUNT;  i++) {
    990         if (core_index == _hx5_pm4x10q_core_num[i]) {
    991             SOC_IF_ERROR_RETURN
    992                 (_soc_hx5_portctrl_device_addr_port_get(unit,
    993                                              portmodDispatchTypePm4x10_qtc,
    994                                              &pAddr, &pPort, &pCoreNum));
    995             return pAddr[i];
    996         }
    997     }
    998 #endif /* PORTMOD_PM4X10_SUPPORT */
    999 
   1000 #ifdef PORTMOD_PM4X25_SUPPORT
   1001     /* When port dones't find PM4x10, find PM4x25 again. */
   1002     for (i=0; i<SOC_HX5_PM4X25_COUNT; i++) {
   1003         if (core_index == _hx5_pm4x25_core_num[i]) {
   1004             SOC_IF_ERROR_RETURN
   1005                 (_soc_hx5_portctrl_device_addr_port_get(unit,
   1006                                              portmodDispatchTypePm4x25,
   1007                                              &pAddr, &pPort, &pCoreNum));
   1008             return pAddr[i];
   1009         }
   1010     }
   1011 #endif /* PORTMOD_PM4X25_SUPPORT */
   1012 
   1013     return -1;
   1014 }
   1015 
   1016 #define PORT_IS_FALCON(unit, phy_port) \
   1017         ((phy_port  >= 65) && (phy_port <= 76)) ? 1 : 0
   1018 
   1019 #define PORT_IS_PM4X10(unit, phy_port) \
   1020         ((phy_port  >= 49) && (phy_port <= 64)) ? 1 : 0
   1021 
   1022 #define PORT_IS_PM4X10_QTC(unit, phy_port) \
   1023         ((phy_port  >= 1) && (phy_port <= 48)) ? 1 : 0
   1024 
   1025 int
   1026 soc_hx5_portctrl_pm_type_get(int unit, soc_port_t phy_port,
   1027                             int* pm_type)
   1028 {
   1029     if ((phy_port < 0) || (phy_port > 76)) {
   1030         return SOC_E_PARAM;
   1031     }
   1032 
   1033     if (PORT_IS_FALCON(unit, phy_port)) {
   1034         *pm_type = portmodDispatchTypePm4x25;
   1035     } else if (PORT_IS_PM4X10(unit, phy_port)) {
   1036         *pm_type = portmodDispatchTypePm4x10;
   1037     } else if (PORT_IS_PM4X10_QTC(unit, phy_port)) {
   1038         *pm_type = portmodDispatchTypePm4x10_qtc;
   1039     } else {
   1040         *pm_type = -1;
   1041     }
   1042 
   1043     return ((*pm_type == -1) ? SOC_E_UNAVAIL : SOC_E_NONE);
   1044 }
   1045 
   1046 #endif /* BCM_HELIX5_SUPPORT */