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 (37277B)


      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 <shared/bsl.h>
     11 
     12 #include <sal/core/libc.h>
     13 
     14 #include <soc/debug.h>
     15 #include <soc/util.h>
     16 #include <soc/mem.h>
     17 #include <soc/esw/portctrl.h>
     18 #include <soc/esw/portctrl_internal.h>
     19 #include <soc/tomahawk2.h>
     20 #include <soc/phy/phymod_sim.h>
     21 #include <soc/portmod/portmod.h>
     22 #include <soc/bondoptions.h>
     23 
     24 #ifdef BCM_TOMAHAWK2_SUPPORT
     25 #define SOC_TH2_PM4X10_COUNT         1
     26 #define SOC_TH2_PM4X25_COUNT         64 
     27 
     28 #define SOC_TH2_PM4X10_PORT_1        257  /* xe0 = 66, xe1 = 100 */
     29 
     30 static uint32_t _th2_pm4x10_addr[SOC_TH2_PM4X10_COUNT] = { 0x2C1 };
     31 static uint32_t _th2_pm4x10_port[SOC_TH2_PM4X10_COUNT] = { SOC_TH2_PM4X10_PORT_1};
     32 
     33 #define SOC_TH2_PM4X25_PORT_1        1
     34 #define SOC_TH2_PM4X25_PORT_2        5
     35 #define SOC_TH2_PM4X25_PORT_3        9
     36 #define SOC_TH2_PM4X25_PORT_4        13
     37 #define SOC_TH2_PM4X25_PORT_5        17
     38 #define SOC_TH2_PM4X25_PORT_6        21
     39 #define SOC_TH2_PM4X25_PORT_7        25
     40 #define SOC_TH2_PM4X25_PORT_8        29
     41 #define SOC_TH2_PM4X25_PORT_9        33
     42 #define SOC_TH2_PM4X25_PORT_10       37
     43 #define SOC_TH2_PM4X25_PORT_11       41
     44 #define SOC_TH2_PM4X25_PORT_12       45
     45 #define SOC_TH2_PM4X25_PORT_13       49
     46 #define SOC_TH2_PM4X25_PORT_14       53
     47 #define SOC_TH2_PM4X25_PORT_15       57
     48 #define SOC_TH2_PM4X25_PORT_16       61
     49 #define SOC_TH2_PM4X25_PORT_17       65
     50 #define SOC_TH2_PM4X25_PORT_18       69
     51 #define SOC_TH2_PM4X25_PORT_19       73
     52 #define SOC_TH2_PM4X25_PORT_20       77
     53 #define SOC_TH2_PM4X25_PORT_21       81
     54 #define SOC_TH2_PM4X25_PORT_22       85
     55 #define SOC_TH2_PM4X25_PORT_23       89
     56 #define SOC_TH2_PM4X25_PORT_24       93
     57 #define SOC_TH2_PM4X25_PORT_25       97
     58 #define SOC_TH2_PM4X25_PORT_26       101
     59 #define SOC_TH2_PM4X25_PORT_27       105
     60 #define SOC_TH2_PM4X25_PORT_28       109
     61 #define SOC_TH2_PM4X25_PORT_29       113
     62 #define SOC_TH2_PM4X25_PORT_30       117
     63 #define SOC_TH2_PM4X25_PORT_31       121
     64 #define SOC_TH2_PM4X25_PORT_32       125
     65 #define SOC_TH2_PM4X25_PORT_33       129
     66 #define SOC_TH2_PM4X25_PORT_34       133
     67 #define SOC_TH2_PM4X25_PORT_35       137
     68 #define SOC_TH2_PM4X25_PORT_36       141
     69 #define SOC_TH2_PM4X25_PORT_37       145
     70 #define SOC_TH2_PM4X25_PORT_38       149
     71 #define SOC_TH2_PM4X25_PORT_39       153
     72 #define SOC_TH2_PM4X25_PORT_40       157
     73 #define SOC_TH2_PM4X25_PORT_41       161
     74 #define SOC_TH2_PM4X25_PORT_42       165
     75 #define SOC_TH2_PM4X25_PORT_43       169
     76 #define SOC_TH2_PM4X25_PORT_44       173
     77 #define SOC_TH2_PM4X25_PORT_45       177
     78 #define SOC_TH2_PM4X25_PORT_46       181
     79 #define SOC_TH2_PM4X25_PORT_47       185
     80 #define SOC_TH2_PM4X25_PORT_48       189
     81 #define SOC_TH2_PM4X25_PORT_49       193
     82 #define SOC_TH2_PM4X25_PORT_50       197
     83 #define SOC_TH2_PM4X25_PORT_51       201
     84 #define SOC_TH2_PM4X25_PORT_52       205
     85 #define SOC_TH2_PM4X25_PORT_53       209
     86 #define SOC_TH2_PM4X25_PORT_54       213
     87 #define SOC_TH2_PM4X25_PORT_55       217
     88 #define SOC_TH2_PM4X25_PORT_56       221
     89 #define SOC_TH2_PM4X25_PORT_57       225
     90 #define SOC_TH2_PM4X25_PORT_58       229
     91 #define SOC_TH2_PM4X25_PORT_59       233
     92 #define SOC_TH2_PM4X25_PORT_60       237
     93 #define SOC_TH2_PM4X25_PORT_61       241
     94 #define SOC_TH2_PM4X25_PORT_62       245
     95 #define SOC_TH2_PM4X25_PORT_63       249
     96 #define SOC_TH2_PM4X25_PORT_64       253
     97 
     98 static uint32_t _th2_pm4x25_addr[SOC_TH2_PM4X25_COUNT] = {
     99     0x81,  0x85,  0x89,  0x8d,
    100     0x91,  0x95,  0x99,  0xa1,
    101     0xa5,  0xa9,  0xad,  0xb1,
    102     0xb5,  0xb9,  0xc1,  0xc5,
    103     0xc9,  0xcd,  0xe1,  0xe5,
    104     0xe9,  0xed,  0xf1,  0xf5,
    105     0xf9,  0x181, 0x185, 0x189,
    106     0x18d, 0x191, 0x195, 0x199,
    107     0x1a1, 0x1a5, 0x1a9, 0x1ad,
    108     0x1b1, 0x1b5, 0x1b9, 0x1c1,
    109     0x1c5, 0x1c9, 0x1cd, 0x1d1,
    110     0x1d5, 0x1d9, 0x1e1, 0x1e5,
    111     0x1e9, 0x1ed, 0x281, 0x285,
    112     0x289, 0x28d, 0x291, 0x295,
    113     0x299, 0x2a1, 0x2a5, 0x2a9,
    114     0x2ad, 0x2b1, 0x2b5, 0x2b9
    115 };
    116 
    117 static uint32_t _th2_pm4x25_core_num[SOC_TH2_PM4X25_COUNT] = {
    118      0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 
    119     16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
    120     32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 
    121     48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63
    122 };
    123 
    124 static uint32_t _th2_pm4x10_core_num[SOC_TH2_PM4X10_COUNT] = {64};
    125 
    126 static uint32_t _th2_pm4x25_port[SOC_TH2_PM4X25_COUNT] = {
    127     SOC_TH2_PM4X25_PORT_1,  SOC_TH2_PM4X25_PORT_2,
    128     SOC_TH2_PM4X25_PORT_3,  SOC_TH2_PM4X25_PORT_4,
    129     SOC_TH2_PM4X25_PORT_5,  SOC_TH2_PM4X25_PORT_6,
    130     SOC_TH2_PM4X25_PORT_7,  SOC_TH2_PM4X25_PORT_8,
    131     SOC_TH2_PM4X25_PORT_9,  SOC_TH2_PM4X25_PORT_10,
    132     SOC_TH2_PM4X25_PORT_11, SOC_TH2_PM4X25_PORT_12,
    133     SOC_TH2_PM4X25_PORT_13, SOC_TH2_PM4X25_PORT_14,
    134     SOC_TH2_PM4X25_PORT_15, SOC_TH2_PM4X25_PORT_16,
    135     SOC_TH2_PM4X25_PORT_17, SOC_TH2_PM4X25_PORT_18,
    136     SOC_TH2_PM4X25_PORT_19, SOC_TH2_PM4X25_PORT_20,
    137     SOC_TH2_PM4X25_PORT_21, SOC_TH2_PM4X25_PORT_22,
    138     SOC_TH2_PM4X25_PORT_23, SOC_TH2_PM4X25_PORT_24,
    139     SOC_TH2_PM4X25_PORT_25, SOC_TH2_PM4X25_PORT_26,
    140     SOC_TH2_PM4X25_PORT_27, SOC_TH2_PM4X25_PORT_28,
    141     SOC_TH2_PM4X25_PORT_29, SOC_TH2_PM4X25_PORT_30,
    142     SOC_TH2_PM4X25_PORT_31, SOC_TH2_PM4X25_PORT_32,
    143     SOC_TH2_PM4X25_PORT_33, SOC_TH2_PM4X25_PORT_34,
    144     SOC_TH2_PM4X25_PORT_35, SOC_TH2_PM4X25_PORT_36,
    145     SOC_TH2_PM4X25_PORT_37, SOC_TH2_PM4X25_PORT_38,
    146     SOC_TH2_PM4X25_PORT_39, SOC_TH2_PM4X25_PORT_40,
    147     SOC_TH2_PM4X25_PORT_41, SOC_TH2_PM4X25_PORT_42,
    148     SOC_TH2_PM4X25_PORT_43, SOC_TH2_PM4X25_PORT_44,
    149     SOC_TH2_PM4X25_PORT_45, SOC_TH2_PM4X25_PORT_46,
    150     SOC_TH2_PM4X25_PORT_47, SOC_TH2_PM4X25_PORT_48,
    151     SOC_TH2_PM4X25_PORT_49, SOC_TH2_PM4X25_PORT_50,
    152     SOC_TH2_PM4X25_PORT_51, SOC_TH2_PM4X25_PORT_52,
    153     SOC_TH2_PM4X25_PORT_53, SOC_TH2_PM4X25_PORT_54,
    154     SOC_TH2_PM4X25_PORT_55, SOC_TH2_PM4X25_PORT_56,
    155     SOC_TH2_PM4X25_PORT_57, SOC_TH2_PM4X25_PORT_58,
    156     SOC_TH2_PM4X25_PORT_59, SOC_TH2_PM4X25_PORT_60,
    157     SOC_TH2_PM4X25_PORT_61, SOC_TH2_PM4X25_PORT_62,
    158     SOC_TH2_PM4X25_PORT_63, SOC_TH2_PM4X25_PORT_64
    159 };
    160 
    161 portmod_pm_instances_t th2_pm_types[] = {
    162 #ifdef PORTMOD_PM4X10_SUPPORT
    163     {portmodDispatchTypePm4x10, SOC_TH2_PM4X10_COUNT}, 
    164 #endif
    165 #ifdef PORTMOD_PM4X25_SUPPORT
    166     {portmodDispatchTypePm4x25, SOC_TH2_PM4X25_COUNT},
    167 #endif
    168 };  
    169 
    170 portmod_pm_instances_t th2_2pipe_pm_types[] = {
    171 #ifdef PORTMOD_PM4X10_SUPPORT
    172     {portmodDispatchTypePm4x10, SOC_TH2_PM4X10_COUNT},
    173 #endif
    174 #ifdef PORTMOD_PM4X25_SUPPORT
    175     {portmodDispatchTypePm4x25, (SOC_TH2_PM4X25_COUNT / 2)},
    176 #endif
    177 };
    178 
    179 #define SOC_TH2_MAX_PHYS             (260)    /* (1x4) 4 XLMAC's, (64x4) 256 CLMAC's */
    180 
    181 #define SOC_TH2_TSC_GROUP_NONE 0
    182 #define SOC_TH2_TSC_GROUP_1    1
    183 #define SOC_TH2_TSC_GROUP_2    2
    184 
    185 /*
    186  * array index is core number and value indicates this core number belongs to which TSC group
    187  * core number from 13 to 18 belongs to TSC group 1
    188  * core number from 45 to 50 belongs to TSC group 2
    189  */
    190 static int _th2_core_tsc_group[] = {
    191     SOC_TH2_TSC_GROUP_NONE, SOC_TH2_TSC_GROUP_NONE, SOC_TH2_TSC_GROUP_NONE, SOC_TH2_TSC_GROUP_NONE, /* 0~3 */
    192     SOC_TH2_TSC_GROUP_NONE, SOC_TH2_TSC_GROUP_NONE, SOC_TH2_TSC_GROUP_NONE, SOC_TH2_TSC_GROUP_NONE, /* 4~7 */
    193     SOC_TH2_TSC_GROUP_NONE, SOC_TH2_TSC_GROUP_NONE, SOC_TH2_TSC_GROUP_NONE, SOC_TH2_TSC_GROUP_NONE, /* 8~11 */
    194     SOC_TH2_TSC_GROUP_NONE, SOC_TH2_TSC_GROUP_1,    SOC_TH2_TSC_GROUP_1,    SOC_TH2_TSC_GROUP_1,    /* 12~15 */
    195     SOC_TH2_TSC_GROUP_1,    SOC_TH2_TSC_GROUP_1,    SOC_TH2_TSC_GROUP_1,    SOC_TH2_TSC_GROUP_NONE, /* 16~19 */
    196     SOC_TH2_TSC_GROUP_NONE, SOC_TH2_TSC_GROUP_NONE, SOC_TH2_TSC_GROUP_NONE, SOC_TH2_TSC_GROUP_NONE, /* 20~23 */
    197     SOC_TH2_TSC_GROUP_NONE, SOC_TH2_TSC_GROUP_NONE, SOC_TH2_TSC_GROUP_NONE, SOC_TH2_TSC_GROUP_NONE, /* 24~27 */
    198     SOC_TH2_TSC_GROUP_NONE, SOC_TH2_TSC_GROUP_NONE, SOC_TH2_TSC_GROUP_NONE, SOC_TH2_TSC_GROUP_NONE, /* 28~31 */
    199     SOC_TH2_TSC_GROUP_NONE, SOC_TH2_TSC_GROUP_NONE, SOC_TH2_TSC_GROUP_NONE, SOC_TH2_TSC_GROUP_NONE, /* 32~35 */
    200     SOC_TH2_TSC_GROUP_NONE, SOC_TH2_TSC_GROUP_NONE, SOC_TH2_TSC_GROUP_NONE, SOC_TH2_TSC_GROUP_NONE, /* 36~39 */
    201     SOC_TH2_TSC_GROUP_NONE, SOC_TH2_TSC_GROUP_NONE, SOC_TH2_TSC_GROUP_NONE, SOC_TH2_TSC_GROUP_NONE, /* 40~43 */
    202     SOC_TH2_TSC_GROUP_NONE, SOC_TH2_TSC_GROUP_2,    SOC_TH2_TSC_GROUP_2,    SOC_TH2_TSC_GROUP_2,    /* 44~47 */
    203     SOC_TH2_TSC_GROUP_2,    SOC_TH2_TSC_GROUP_2,    SOC_TH2_TSC_GROUP_2,    SOC_TH2_TSC_GROUP_NONE, /* 48~51 */
    204     SOC_TH2_TSC_GROUP_NONE, SOC_TH2_TSC_GROUP_NONE, SOC_TH2_TSC_GROUP_NONE, SOC_TH2_TSC_GROUP_NONE, /* 52~55 */
    205     SOC_TH2_TSC_GROUP_NONE, SOC_TH2_TSC_GROUP_NONE, SOC_TH2_TSC_GROUP_NONE, SOC_TH2_TSC_GROUP_NONE, /* 56~59 */
    206     SOC_TH2_TSC_GROUP_NONE, SOC_TH2_TSC_GROUP_NONE, SOC_TH2_TSC_GROUP_NONE, SOC_TH2_TSC_GROUP_NONE, /* 60~63 */
    207     SOC_TH2_TSC_GROUP_NONE                                                                          /* 64 */
    208 };
    209 
    210 #ifdef FW_BCAST_DOWNLOAD
    211 /*
    212  * PM0-PM31(SBUS chain 15-46) belong to SBUS ring 3, PM0 ->...-> PM15 -> PM31 ->...-> PM16
    213  * PM32-PM63(SBUS chain 47-78) belong to SBUS ring 4, PM63 ->...-> PM48 -> PM32 ->...-> PM47
    214  */
    215 #define SOC_TH2_SBUS_RING_3_PM_MIN 0
    216 #define SOC_TH2_SBUS_RING_3_PM_MAX 31
    217 #define SOC_TH2_SBUS_RING_4_PM_MIN 32
    218 #define SOC_TH2_SBUS_RING_4_PM_MAX 63
    219 
    220 #define SOC_TH2_SBUS_RING_LIST_NUM 2
    221 #define SOC_TH2_SBUS_RING_MAX_PM_NUM 32
    222 #define SOC_TH2_SBUS_RING_DEFAULT_BCAST_ID 0x7f
    223 #define SOC_TH2_SBUS_RING_3_BCAST_ID (SOC_TH2_SBUS_RING_DEFAULT_BCAST_ID - 1)
    224 #define SOC_TH2_SBUS_RING_4_BCAST_ID (SOC_TH2_SBUS_RING_DEFAULT_BCAST_ID - 2)
    225 
    226 typedef struct soc_th2_sbus_ring_list_s {
    227     int core_id[SOC_TH2_SBUS_RING_MAX_PM_NUM];
    228     int sbus_ring_id;
    229     int bcast_id;
    230 } soc_th2_sbus_ring_list_t;
    231 
    232 static soc_th2_sbus_ring_list_t _th2_sbus_ring_list[SOC_TH2_SBUS_RING_LIST_NUM] = {
    233     {{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16},
    234      3, SOC_TH2_SBUS_RING_3_BCAST_ID
    235     },
    236     {{63,62,61,60,59,58,57,56,55,54,53,52,51,50,49,48,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47},
    237      4, SOC_TH2_SBUS_RING_4_BCAST_ID
    238     }
    239 };
    240 #endif
    241 
    242 #ifdef PORTMOD_PM4X10_SUPPORT
    243 static portmod_default_user_access_t *pm4x10_th2_user_acc[SOC_MAX_NUM_DEVICES];
    244 #endif /* PORTMOD_PM4X10_SUPPORT */
    245 
    246 #ifdef PORTMOD_PM4X25_SUPPORT
    247 static portmod_default_user_access_t *pm4x25_th2_user_acc[SOC_MAX_NUM_DEVICES];
    248 #endif /* PORTMOD_PM4X25_SUPPORT */
    249 
    250 soc_portctrl_functions_t soc_th2_portctrl_func = {
    251     soc_th2_portctrl_pm_portmod_init,
    252     soc_th2_portctrl_pm_portmod_deinit,
    253     soc_th2_portctrl_pm_port_config_get,
    254     soc_th2_portctrl_pm_port_phyaddr_get,
    255     soc_th2_portctrl_port_ability_update,
    256     soc_th2_portctrl_pm_type_get,
    257 #ifdef FW_BCAST_DOWNLOAD
    258     soc_th2_portctrl_sbus_ring_info_get,
    259     soc_th2_portctrl_sbus_bcast_id_get
    260 #else
    261     NULL,
    262     NULL
    263 #endif
    264 };
    265 
    266 STATIC int
    267 _soc_th2_portctrl_rescal_calculate(int unit, int *val1, int *val2)
    268 {
    269     uint32 rval, rescal0, rescal1, rescal2, rescal3;
    270     soc_reg_t reg = INVALIDr;
    271     soc_field_t field = PONf;
    272 
    273     SOC_IF_ERROR_RETURN(READ_TOP_RESCAL_0_STATUS_0r(unit,&rval));
    274     reg = TOP_RESCAL_0_STATUS_0r;
    275     rescal0 = soc_reg_field_get(unit, reg, rval, field);
    276 
    277     SOC_IF_ERROR_RETURN(READ_TOP_RESCAL_1_STATUS_0r(unit,&rval));
    278     reg = TOP_RESCAL_1_STATUS_0r;
    279     rescal1 = soc_reg_field_get(unit, reg, rval, field);
    280 
    281     SOC_IF_ERROR_RETURN(READ_TOP_RESCAL_2_STATUS_0r(unit,&rval));
    282     reg = TOP_RESCAL_2_STATUS_0r;
    283     rescal2 = soc_reg_field_get(unit, reg, rval, field);
    284 
    285     SOC_IF_ERROR_RETURN(READ_TOP_RESCAL_3_STATUS_0r(unit,&rval));
    286     reg = TOP_RESCAL_3_STATUS_0r;
    287     rescal3 = soc_reg_field_get(unit, reg, rval, field);
    288 
    289     *val1 = (rescal0 + rescal1) / 2;
    290     *val2 = (rescal2 + rescal3) / 2;
    291 
    292     return SOC_E_NONE;
    293 }
    294 
    295 STATIC int
    296 _soc_th2_portctrl_pm_init(int unit, int *max_phys,
    297                          portmod_pm_instances_t **pm_types,
    298                          int *pms_arr_len)
    299 {
    300     *max_phys = SOC_TH2_MAX_PHYS;
    301     if (NUM_PIPE(unit) == 2) {
    302         *pm_types = th2_2pipe_pm_types;
    303         *pms_arr_len = sizeof(th2_2pipe_pm_types)/sizeof(portmod_pm_instances_t);
    304     } else {
    305         *pm_types = th2_pm_types;
    306         *pms_arr_len = sizeof(th2_pm_types)/sizeof(portmod_pm_instances_t);
    307     }
    308     return SOC_E_NONE;
    309 }
    310 
    311 STATIC int
    312 _soc_th2_portctrl_device_addr_port_get(int unit, int pm_type,
    313                                       uint32_t **addr,
    314                                       uint32_t **port,
    315                                       uint32_t **core_num)
    316 {
    317     *addr     = NULL;
    318     *port     = NULL;
    319     *core_num = NULL;
    320     if (pm_type == portmodDispatchTypePm4x10) {
    321         *addr = _th2_pm4x10_addr;
    322         *port = _th2_pm4x10_port;
    323         *core_num = _th2_pm4x10_core_num;
    324     } else if (pm_type == portmodDispatchTypePm4x25){
    325         *addr = _th2_pm4x25_addr;
    326         *port = _th2_pm4x25_port;
    327         *core_num = _th2_pm4x25_core_num;
    328     }
    329 
    330     return SOC_E_NONE;
    331 }
    332 
    333 STATIC int
    334 _soc_th2_portctrl_pm_user_acc_flag_set(int unit,
    335                     portmod_default_user_access_t* pm_user_access)
    336 {
    337     PORTMOD_USER_ACCESS_FW_LOAD_REVERSE_SET((pm_user_access));
    338     PORTMOD_USER_ACCESS_REG_VAL_OFFSET_ZERO_CLR((pm_user_access));
    339     return SOC_E_NONE;
    340 }
    341 
    342 /*
    343  * Polarity get looks for physical port based config.
    344  */
    345 STATIC void
    346 _soc_th2_portctrl_pm_port_polarity_get(int unit, int logical_port, int physical_port, int lane,
    347                             uint32 *tx_pol, uint32* rx_pol)
    348 {
    349     uint32 rx_polarity, tx_polarity;
    350 
    351     rx_polarity = soc_property_phy_get(unit, physical_port, 0, 0, lane,
    352                                         spn_PHY_CHAIN_RX_POLARITY_FLIP_PHYSICAL, 0x0);
    353     *rx_pol = (rx_polarity & 0x1) << lane;
    354 
    355     tx_polarity = soc_property_phy_get(unit, physical_port, 0, 0, lane,
    356                                         spn_PHY_CHAIN_TX_POLARITY_FLIP_PHYSICAL, 0x0);
    357     *tx_pol = (tx_polarity & 0x1) << lane;
    358 
    359 }
    360 
    361 
    362 /*
    363  * lanemap get looks for physical port based config. 
    364  */
    365 STATIC 
    366 void _soc_th2_portctrl_pm_port_lanemap_get
    367             (int unit, int logical_port, int physical_port, int core_num, 
    368             uint32 *txlane_map, uint32* rxlane_map)
    369 {
    370 
    371     *rxlane_map = soc_property_phy_get(unit, physical_port, 0, 0, 0,
    372                                         spn_PHY_CHAIN_RX_LANE_MAP_PHYSICAL, 0x3210);
    373 
    374 
    375     *txlane_map = soc_property_phy_get(unit, physical_port, 0, 0, 0,
    376                                         spn_PHY_CHAIN_TX_LANE_MAP_PHYSICAL, 0x3210);
    377 
    378 }
    379 
    380 STATIC int
    381 _soc_th2_portctrl_pm4x10_portmod_init(int unit, int num_of_instances) 
    382 {
    383 #ifdef PORTMOD_PM4X10_SUPPORT
    384     int rv = SOC_E_NONE;
    385     portmod_pm_create_info_t pm_info;
    386     int pmid = 0, blk, is_sim, found;
    387     int first_port, idx, core_num, core_cnt;
    388     uint32 *pAddr, *pPort, *pCoreNum;
    389 
    390     SOC_IF_ERROR_RETURN
    391         (_soc_th2_portctrl_device_addr_port_get(unit,
    392                                                 portmodDispatchTypePm4x10,
    393                                                 &pAddr, &pPort, &pCoreNum));
    394     if (!pAddr || !pPort) {
    395         return SOC_E_INTERNAL;
    396     }
    397 
    398     /* Allocate PMs */
    399     SOC_IF_ERROR_RETURN
    400         (soc_esw_portctrl_pm_user_access_alloc(unit,
    401                                                num_of_instances,
    402                                                &pm4x10_th2_user_acc[unit]));
    403 
    404     for (pmid = 0; PORTMOD_SUCCESS(rv) && (pmid < num_of_instances); pmid++) {
    405 
    406         rv = portmod_pm_create_info_t_init(unit, &pm_info);
    407         if (PORTMOD_FAILURE(rv)) {
    408             break;
    409         }
    410         /* PM info */
    411         first_port = pPort[pmid];
    412 
    413         PORTMOD_PBMP_PORT_ADD(pm_info.phys, first_port);
    414         PORTMOD_PBMP_PORT_ADD(pm_info.phys, first_port + 1);
    415         PORTMOD_PBMP_PORT_ADD(pm_info.phys, first_port + 2);
    416         PORTMOD_PBMP_PORT_ADD(pm_info.phys, first_port + 3);
    417 
    418         found = 0;
    419         for(idx = 0; idx < SOC_DRIVER(unit)->port_num_blktype; idx++){
    420             blk = SOC_PORT_IDX_INFO(unit, first_port, idx).blk;
    421             if (SOC_BLOCK_INFO(unit, blk).type == SOC_BLK_XLPORT){
    422                 found = 1;
    423                 break;
    424             }
    425         }
    426 
    427         if (!found) {
    428             rv = SOC_E_INTERNAL;
    429             break;
    430         } 
    431 
    432         pm_info.type         = portmodDispatchTypePm4x10;
    433 
    434         /* Init user_acc for phymod access struct */
    435         rv = portmod_default_user_access_t_init(unit,
    436                                                 &(pm4x10_th2_user_acc[unit][pmid]));
    437         if (PORTMOD_FAILURE(rv)) {
    438             break;
    439         }
    440 
    441         SOC_IF_ERROR_RETURN(
    442             _soc_th2_portctrl_pm_user_acc_flag_set(unit,
    443                 &(pm4x10_th2_user_acc[unit][pmid])));
    444 
    445         pm4x10_th2_user_acc[unit][pmid].unit = unit;
    446         pm4x10_th2_user_acc[unit][pmid].blk_id = blk; 
    447         pm4x10_th2_user_acc[unit][pmid].mutex = sal_mutex_create("core mutex");
    448         if (pm4x10_th2_user_acc[unit][pmid].mutex == NULL) {
    449             rv = SOC_E_MEMORY;
    450             break;
    451         }
    452 
    453         /* Specific info for PM4x10 */
    454         rv = phymod_access_t_init(&pm_info.pm_specific_info.pm4x10.access);
    455         if (PORTMOD_FAILURE(rv)) {
    456             break;
    457         }
    458 
    459         pm_info.pm_specific_info.pm4x10.access.user_acc =
    460             &(pm4x10_th2_user_acc[unit][pmid]);
    461         pm_info.pm_specific_info.pm4x10.access.addr     = pAddr[pmid];
    462         pm_info.pm_specific_info.pm4x10.access.bus      = NULL; /* Use default bus */
    463 
    464         rv = soc_physim_check_sim(unit, phymodDispatchTypeTsce16,
    465                                   &(pm_info.pm_specific_info.pm4x10.access),
    466                                   0, &is_sim);
    467         if (PORTMOD_FAILURE(rv)) {
    468             break;
    469         }
    470 
    471         if (is_sim) {
    472             /* Firmward loader : Don't allow FW load on sim enviroment */
    473             pm_info.pm_specific_info.pm4x10.fw_load_method =
    474                 phymodFirmwareLoadMethodNone;
    475             /* TSCE sim supports CL45 mode to read/write registers. */
    476             PHYMOD_ACC_F_CLAUSE45_SET(&pm_info.pm_specific_info.pm4x10.access);
    477         }
    478 
    479         /* Use default external loader if NULL */
    480         pm_info.pm_specific_info.pm4x10.external_fw_loader = NULL;
    481 
    482         core_cnt = 1; 
    483 
    484         for (core_num = 0; core_num < core_cnt; core_num++) {
    485             pm_info.pm_specific_info.pm4x10.core_num = pCoreNum? pCoreNum[pmid] : pmid;
    486             pm_info.pm_specific_info.pm4x10.core_num_int = 0;
    487             pm_info.pm_specific_info.pm4x10.rescal = -1;
    488         }
    489 
    490         pm_info.pm_specific_info.pm4x10.portmod_phy_external_reset
    491             = soc_esw_portctrl_reset_tsc3_cb;
    492 
    493         /* 4x10 is only used in mgmt ports */
    494         pm_info.pm_specific_info.pm4x10.port_mode_aux_info = portmodModeInfoTwoDualModePorts;
    495         
    496         /* Add PM to PortMod */
    497         rv = portmod_port_macro_add(unit, &pm_info);
    498     }
    499 
    500     if (PORTMOD_FAILURE(rv)) {
    501         for (pmid = 0; pmid < num_of_instances; pmid++) {
    502             if (pm4x10_th2_user_acc[unit][pmid].mutex) {
    503                 sal_mutex_destroy(pm4x10_th2_user_acc[unit][pmid].mutex);
    504                 pm4x10_th2_user_acc[unit][pmid].mutex = NULL;
    505             }
    506         }
    507     }
    508 
    509     return rv;
    510 #else /* PORTMOD_PM4X10_SUPPORT */
    511     return SOC_E_UNAVAIL;
    512 #endif /* PORTMOD_PM4X10_SUPPORT */
    513 }
    514 
    515 STATIC int
    516 _soc_th2_portctrl_pm4x25_portmod_init(int unit, int num_of_instances) 
    517 {
    518 #ifdef PORTMOD_PM4X25_SUPPORT
    519     int rv = SOC_E_NONE;
    520     portmod_pm_create_info_t pm_info;
    521     int pmid = 0, blk, is_sim, found;
    522     int first_port, idx, core_num, core_cnt, rescal_0_1 = -1, rescal_2_3 = -1;
    523     uint32 *pAddr, *pPort,*pCoreNum;
    524     int logical_port, mode;
    525 
    526     SOC_IF_ERROR_RETURN
    527         (_soc_th2_portctrl_device_addr_port_get(unit,
    528                                                 portmodDispatchTypePm4x25,
    529                                                 &pAddr, &pPort,&pCoreNum));
    530     if (!pAddr || !pPort) {
    531         return SOC_E_INTERNAL;
    532     }
    533 
    534     /* RESCAL should be disabled by default */
    535     if (soc_feature(unit, soc_feature_rescal)) {
    536         _soc_th2_portctrl_rescal_calculate(unit, &rescal_0_1, &rescal_2_3);
    537     }
    538 
    539     /* Allocate PMs */
    540     SOC_IF_ERROR_RETURN
    541         (soc_esw_portctrl_pm_user_access_alloc(unit,
    542                                                num_of_instances,
    543                                                &pm4x25_th2_user_acc[unit]));
    544 
    545     for (pmid = 0; PORTMOD_SUCCESS(rv) && (pmid < num_of_instances); pmid++) {
    546 
    547         rv = portmod_pm_create_info_t_init(unit, &pm_info);
    548         if (PORTMOD_FAILURE(rv)) {
    549             break;
    550         }
    551         /* PM info */
    552         first_port = pPort[pmid];
    553 
    554         PORTMOD_PBMP_PORT_ADD(pm_info.phys, first_port);
    555         PORTMOD_PBMP_PORT_ADD(pm_info.phys, first_port+1); 
    556         PORTMOD_PBMP_PORT_ADD(pm_info.phys, first_port+2);
    557         PORTMOD_PBMP_PORT_ADD(pm_info.phys, first_port+3);
    558 
    559         found = 0;
    560         for(idx = 0; idx < SOC_DRIVER(unit)->port_num_blktype; idx++){ 
    561             blk = SOC_PORT_IDX_INFO(unit, first_port, idx).blk; 
    562             if (SOC_BLOCK_INFO(unit, blk).type == SOC_BLK_CLPORT){
    563                 found = 1;
    564                 break;
    565             }
    566         }
    567 
    568         if (!found) {
    569             rv = SOC_E_INTERNAL;
    570             break;
    571         } 
    572 
    573         pm_info.type         = portmodDispatchTypePm4x25;
    574 
    575         /* Init user_acc for phymod access struct */
    576         rv = portmod_default_user_access_t_init(unit,
    577                                                 &(pm4x25_th2_user_acc[unit][pmid]));
    578         if (PORTMOD_FAILURE(rv)) {
    579             break;
    580         }
    581 
    582         PORTMOD_USER_ACCESS_FW_LOAD_REVERSE_SET((&(pm4x25_th2_user_acc[unit][pmid])));
    583         PORTMOD_USER_ACCESS_REG_VAL_OFFSET_ZERO_CLR((&(pm4x25_th2_user_acc[unit][pmid])));
    584         pm4x25_th2_user_acc[unit][pmid].unit = unit;
    585         pm4x25_th2_user_acc[unit][pmid].blk_id = blk; 
    586         pm4x25_th2_user_acc[unit][pmid].mutex = sal_mutex_create("core mutex");
    587         if (pm4x25_th2_user_acc[unit][pmid].mutex == NULL) {
    588             rv = SOC_E_MEMORY;
    589             break;
    590         }
    591 
    592         /* Specific info for PM4x25 */
    593         rv = phymod_access_t_init(&pm_info.pm_specific_info.pm4x25.access);
    594         if (PORTMOD_FAILURE(rv)) {
    595             break;
    596         }
    597 
    598         pm_info.pm_specific_info.pm4x25.access.user_acc =
    599             &(pm4x25_th2_user_acc[unit][pmid]);
    600         pm_info.pm_specific_info.pm4x25.access.addr     = pAddr[pmid];
    601         pm_info.pm_specific_info.pm4x25.access.bus      = NULL; /* Use default bus */
    602 
    603         rv = soc_physim_check_sim(unit, phymodDispatchTypeTscf16, 
    604                                   &(pm_info.pm_specific_info.pm4x25.access),
    605                                   0, &is_sim);
    606 
    607         if (PORTMOD_FAILURE(rv)) {
    608             break;
    609         }
    610 
    611         if (is_sim) {
    612             /* Firmward loader : Don't allow FW load on sim enviroment */
    613             pm_info.pm_specific_info.pm4x25.fw_load_method =
    614                 phymodFirmwareLoadMethodNone;
    615             /* TSCF sim supports CL45 mode to read/write registers. */
    616             PHYMOD_ACC_F_CLAUSE45_SET(&pm_info.pm_specific_info.pm4x25.access);
    617         }
    618 
    619         /* Use default external loader if NULL */
    620         pm_info.pm_specific_info.pm4x25.external_fw_loader = NULL;
    621 
    622         core_cnt = 1; 
    623 
    624         for (core_num = 0; core_num < core_cnt; core_num++) {
    625             pm_info.pm_specific_info.pm4x25.core_num = pCoreNum? pCoreNum[pmid] : pmid;
    626             pm_info.pm_specific_info.pm4x25.core_num_int = 0;
    627             pm_info.pm_specific_info.pm4x25.rescal = -1;
    628             if (_th2_core_tsc_group[pm_info.pm_specific_info.pm4x25.core_num] == SOC_TH2_TSC_GROUP_1) {
    629                 pm_info.pm_specific_info.pm4x25.rescal = rescal_0_1;
    630             } else if (_th2_core_tsc_group[pm_info.pm_specific_info.pm4x25.core_num] == SOC_TH2_TSC_GROUP_2) {
    631                 pm_info.pm_specific_info.pm4x25.rescal = rescal_2_3;
    632             }
    633         }
    634 
    635         logical_port = SOC_INFO(unit).port_p2l_mapping[first_port];
    636         SOC_IF_ERROR_RETURN(soc_th2_port_mode_get(unit, logical_port, &mode));
    637         if (mode == portmodPortModeTri012 || mode == portmodPortModeTri023) {
    638             pm_info.pm_specific_info.pm4x25.port_mode_aux_info = portmodModeInfoThreePorts;
    639         }
    640 
    641         /* Add PM to PortMod */
    642         rv = portmod_port_macro_add(unit, &pm_info);
    643     }
    644 
    645     if (PORTMOD_FAILURE(rv)) {
    646         for (pmid = 0; pmid < num_of_instances; pmid++) {
    647             if (pm4x25_th2_user_acc[unit][pmid].mutex) {
    648                 sal_mutex_destroy(pm4x25_th2_user_acc[unit][pmid].mutex);
    649                 pm4x25_th2_user_acc[unit][pmid].mutex = NULL;
    650             }
    651         }
    652     }
    653 
    654     return rv;
    655 #else /* PORTMOD_PM4X25_SUPPORT */
    656     return SOC_E_UNAVAIL;
    657 #endif /* PORTMOD_PM4X25_SUPPORT */
    658 }
    659 
    660 /*
    661  * Function:
    662  *      soc_th2_portctrl_pm_portmod_init
    663  * Purpose:
    664  *      Initialize PortMod and PortMacro for Tomahawk2
    665  *      Add port macros (PM) to the unit's PortMod Manager (PMM).
    666  * Parameters:
    667  *      unit             - (IN) Unit number.
    668  * Returns:
    669  *      SOC_E_XXX
    670  */
    671 int
    672 soc_th2_portctrl_pm_portmod_init(int unit)
    673 {
    674     int rv = SOC_E_NONE, pms_arr_len = 0, count, max_phys= 0;
    675     portmod_pm_instances_t *pm_types = NULL;
    676     int flags = 0;
    677 
    678     /* Call PortMod library initialization */
    679     SOC_IF_ERROR_RETURN(
    680         _soc_th2_portctrl_pm_init(unit, &max_phys,
    681                                  &pm_types, &pms_arr_len));
    682     if (pms_arr_len == 0) {
    683         return SOC_E_UNAVAIL;
    684     }
    685 
    686     /*
    687      * If portmod was create - destroy and create again
    688      * Better way would be to create once and leave it.
    689      */
    690     if (SOC_E_NONE == soc_esw_portctrl_init_check(unit)) {
    691         SOC_IF_ERROR_RETURN(portmod_destroy(unit));
    692     }
    693 
    694     PORTMOD_CREATE_F_PM_NULL_SET(flags);
    695 
    696     SOC_IF_ERROR_RETURN
    697         (portmod_create(unit, flags, SOC_MAX_NUM_PORTS, max_phys,
    698                         pms_arr_len, pm_types));
    699 
    700     for (count = 0; SOC_SUCCESS(rv) && (count < pms_arr_len); count++) {
    701 #ifdef PORTMOD_PM4X10_SUPPORT
    702         if (pm_types[count].type == portmodDispatchTypePm4x10) {
    703             rv = _soc_th2_portctrl_pm4x10_portmod_init
    704                 (unit, pm_types[count].instances);
    705         } else 
    706 #endif /* PORTMOD_PM4X10_SUPPORT  */
    707 #ifdef PORTMOD_PM4X25_SUPPORT
    708         if (pm_types[count].type == portmodDispatchTypePm4x25) {
    709             rv = _soc_th2_portctrl_pm4x25_portmod_init
    710                 (unit, pm_types[count].instances);
    711         } else
    712 #endif /* PORTMOD_PM4X25_SUPPORT  */
    713         {
    714             rv = SOC_E_INTERNAL;
    715         }
    716     }
    717 
    718     return rv;
    719 }
    720 
    721 /*
    722  * Function:
    723  *      soc_th2_portctrl_pm_portmod_deinit
    724  * Purpose:
    725  *      Deinitialize PortMod and PortMacro for Tomahawk2.
    726  *      Free pm user access data.
    727  * Parameters:
    728  *      unit      - (IN) Unit number.
    729  * Returns:
    730  *      SOC_E_NONE
    731  */
    732 int
    733 soc_th2_portctrl_pm_portmod_deinit(int unit)
    734 {
    735     if (SOC_E_INIT == soc_esw_portctrl_init_check(unit)) {
    736         return SOC_E_NONE;
    737     }
    738 
    739     /* Free PMs structures */
    740 #ifdef PORTMOD_PM4X10_SUPPORT
    741     if (pm4x10_th2_user_acc[unit] != NULL) {
    742         sal_free(pm4x10_th2_user_acc[unit]);
    743         pm4x10_th2_user_acc[unit] = NULL;
    744     }
    745 #endif /* PORTMOD_PM4X10_SUPPORT */
    746 
    747 #ifdef PORTMOD_PM4X25_SUPPORT
    748     if (pm4x25_th2_user_acc[unit] != NULL) {
    749         sal_free(pm4x25_th2_user_acc[unit]);
    750         pm4x25_th2_user_acc[unit] = NULL;
    751     }
    752 #endif /* PORTMOD_PM4X25_SUPPORT */
    753 
    754     SOC_IF_ERROR_RETURN(portmod_destroy(unit));
    755 
    756     return SOC_E_NONE;
    757 }
    758 
    759 int
    760 soc_th2_portctrl_pm_port_config_get(int unit, soc_port_t port, void *port_config)
    761 {
    762 #ifdef PORTMOD_PM4X10_SUPPORT
    763     int rv = SOC_E_NONE;
    764     int pmid = 0, lane, phy, phy_port, logical_port;
    765     int first_port, core_num, core_count = 0, core_index, is_sim, type, port_mode;
    766     uint32 txlane_map, rxlane_map, rxlane_map_l, i;
    767     uint32 *pAddr = NULL, *pPort = NULL, *pCoreNum = NULL;
    768     uint32 tx_polarity, rx_polarity;
    769     portmod_port_init_config_t *port_config_info;
    770     phymod_firmware_load_method_t fw_load_method;
    771     phymod_polarity_t polarity; /**< Lanes Polarity */
    772     phymod_lane_map_t lane_map;
    773 
    774     port_config_info = (portmod_port_init_config_t *)port_config;
    775 
    776     SOC_IF_ERROR_RETURN(soc_th2_port_mode_get(unit, port, &port_mode));
    777     if (port_mode == portmodPortModeTri012 || port_mode == portmodPortModeTri023) {
    778         port_config_info->port_mode_aux_info = portmodModeInfoThreePorts;
    779     }
    780 
    781     phy = SOC_INFO(unit).port_l2p_mapping[port];
    782 
    783     /* Find the port belong to which PM. The port has its own core id, using it to compare PM. */
    784     core_num = (phy - 1) / SOC_PM4X10_NUM_LANES;
    785     for (i=0; i<SOC_TH2_PM4X10_COUNT; i++) {
    786         if (core_num == _th2_pm4x10_core_num[i]) {
    787             type = portmodDispatchTypePm4x10;
    788             SOC_IF_ERROR_RETURN
    789                 (_soc_th2_portctrl_device_addr_port_get(unit,
    790                                                  portmodDispatchTypePm4x10,
    791                                                  &pAddr, &pPort, &pCoreNum));
    792             pmid = i;
    793             core_count = 1;
    794             break;
    795         }
    796     }
    797     /* When port dones't find PM4x10, find PM4x25 again. */
    798     if (i == SOC_TH2_PM4X10_COUNT) {
    799         for (i=0; i<SOC_TH2_PM4X25_COUNT; i++) {
    800             if (core_num == _th2_pm4x25_core_num[i]) {
    801                 type = portmodDispatchTypePm4x25;
    802                 SOC_IF_ERROR_RETURN
    803                     (_soc_th2_portctrl_device_addr_port_get(unit,
    804                                                  portmodDispatchTypePm4x25,
    805                                                  &pAddr, &pPort, &pCoreNum));
    806                 /* Because one PM4x25 has three cores and one corresponding pmid. */
    807                 pmid = i;
    808                 core_count = 1;
    809                 break;
    810             }
    811         }
    812     }
    813 
    814     if (!pAddr || !pPort) {
    815         return SOC_E_INTERNAL;
    816     }
    817 
    818     /* PM info */
    819     first_port = pPort[pmid];
    820 
    821     for (core_index = 0; core_index < core_count; core_index++) {
    822         fw_load_method = phymodFirmwareLoadMethodExternal;
    823 
    824         soc_physim_enable_get(unit, &is_sim);
    825 
    826         if (is_sim) {
    827             /* Firmward loader : Don't allow FW load on sim enviroment */
    828             fw_load_method = phymodFirmwareLoadMethodNone;
    829         } else {
    830             fw_load_method = soc_property_suffix_num_get(unit, pmid,
    831                                             spn_LOAD_FIRMWARE, "quad",
    832                                             phymodFirmwareLoadMethodExternal);
    833             fw_load_method &= 0xff;
    834         }
    835 
    836         rv = phymod_polarity_t_init(&polarity);
    837         if (PORTMOD_FAILURE(rv)) {
    838             break;
    839         }
    840 
    841         /* Polarity */
    842         for (lane = 0; lane < SOC_PM4X10_NUM_LANES; lane++) {
    843             phy_port = first_port + lane + (core_index*4);
    844             logical_port = SOC_INFO(unit).port_p2l_mapping[phy_port];
    845         
    846             _soc_th2_portctrl_pm_port_polarity_get(unit, logical_port, phy_port, lane, &tx_polarity, &rx_polarity);
    847 
    848             polarity.rx_polarity |= rx_polarity;
    849             polarity.tx_polarity |= tx_polarity;
    850         }
    851 
    852         /* Lane map */
    853         rv = phymod_lane_map_t_init(&lane_map);
    854         if (PORTMOD_FAILURE(rv)) {
    855             break;
    856         }
    857 
    858         phy_port = first_port + (core_index*4);
    859         logical_port = SOC_INFO(unit).port_p2l_mapping[phy_port];
    860 
    861         _soc_th2_portctrl_pm_port_lanemap_get(unit, logical_port, phy_port, core_num, &txlane_map, &rxlane_map);
    862 
    863         rxlane_map_l = rxlane_map ;
    864         /* For TSC-E/F family, both lane_map_rx and lane_map_tx are logic lane base */
    865         /* TD2/TD2+ xgxs_rx_lane_map is phy-lane base */
    866         if (SOC_IS_TOMAHAWK2(unit)) { /* use TD2 legacy notion system */
    867             rxlane_map_l = 0 ;
    868             for (i=0; i<SOC_PM4X10_NUM_LANES; i++) {
    869                 rxlane_map_l |= i << SOC_PM4X10_NUM_LANES *((rxlane_map >> (i*SOC_PM4X10_NUM_LANES))& SOC_PM4X10_LANE_MASK) ;
    870             }
    871         }
    872 
    873         if (type == portmodDispatchTypePm4x25) {
    874             lane_map.num_of_lanes = SOC_PM4X25_NUM_LANES;
    875         } else {
    876             lane_map.num_of_lanes = SOC_PM4X10_NUM_LANES;
    877         }
    878 
    879         for(lane = 0 ; lane < SOC_PM4X10_NUM_LANES; lane++) {
    880             lane_map.lane_map_tx[lane] =
    881                 (txlane_map >> (lane * SOC_PM4X10_NUM_LANES)) &
    882                 SOC_PM4X10_LANE_MASK;
    883             lane_map.lane_map_rx[lane] =
    884                 (rxlane_map >> (lane * SOC_PM4X10_NUM_LANES)) &
    885                 SOC_PM4X10_LANE_MASK;
    886         }
    887 
    888         sal_memcpy(&port_config_info->fw_load_method[core_index], &fw_load_method,
    889                     sizeof(phymod_firmware_load_method_t));
    890         port_config_info->fw_load_method_overwrite = 1;
    891         sal_memcpy(&port_config_info->polarity[core_index], &polarity,
    892                     sizeof(phymod_polarity_t));
    893         port_config_info->polarity_overwrite = 1;
    894         sal_memcpy(&port_config_info->lane_map[core_index], &lane_map,
    895                     sizeof(phymod_lane_map_t));
    896         port_config_info->lane_map_overwrite = 1;
    897     }
    898 
    899     return rv;
    900 #else /* PORTMOD_PM4X10_SUPPORT */
    901     return SOC_E_UNAVAIL;
    902 #endif /* PORTMOD_PM4X10_SUPPORT */
    903 }
    904 
    905 int
    906 soc_th2_portctrl_pm_port_phyaddr_get(int unit, soc_port_t port)
    907 {
    908     int phy, core_index;
    909     uint32 i, *pAddr = NULL, *pPort = NULL, *pCoreNum = NULL;
    910 
    911     phy = SOC_INFO(unit).port_l2p_mapping[port];
    912 
    913     /* Find the port belong to which PM. The port has its own core id, using it to compare PM. */
    914     core_index = (phy - 1) / SOC_PM4X10_NUM_LANES;
    915 #ifdef PORTMOD_PM4X10_SUPPORT
    916     for (i=0; i<SOC_TH2_PM4X10_COUNT; i++) {
    917         if (core_index == _th2_pm4x10_core_num[i]) {
    918             SOC_IF_ERROR_RETURN
    919                 (_soc_th2_portctrl_device_addr_port_get(unit,
    920                                              portmodDispatchTypePm4x10,
    921                                              &pAddr, &pPort, &pCoreNum));
    922             return pAddr[i];
    923         }
    924     }
    925 #endif /* PORTMOD_PM4X10_SUPPORT */
    926 
    927 #ifdef PORTMOD_PM4X25_SUPPORT
    928     /* When port dones't find PM4x10, find PM4x25 again. */
    929     for (i=0; i<SOC_TH2_PM4X25_COUNT; i++) {
    930         if (core_index == _th2_pm4x25_core_num[i]) {
    931             SOC_IF_ERROR_RETURN
    932                 (_soc_th2_portctrl_device_addr_port_get(unit,
    933                                              portmodDispatchTypePm4x25,
    934                                              &pAddr, &pPort, &pCoreNum));
    935             return pAddr[i];
    936         }
    937     }
    938 #endif /* PORTMOD_PM4X25_SUPPORT */
    939 
    940     return -1;
    941 }
    942 
    943 int
    944 soc_th2_portctrl_port_ability_update(int unit, soc_port_t port, soc_port_ability_t *ability)
    945 {
    946     int phy_port, tsc_id;
    947 
    948     if (!soc_feature(unit, soc_feature_untethered_otp)) {
    949         return SOC_E_NONE;
    950     }
    951     phy_port = SOC_INFO(unit).port_l2p_mapping[port];
    952     /* Each bit in FORCE_HG bond option represents one TSC/Port Macro
    953     * 1 - All ports in specified TSC are Higig only.
    954     * 0 - No restrictions
    955     */
    956     tsc_id = (phy_port - 1) / _TH2_PORTS_PER_PBLK;
    957 
    958     if (SHR_BITGET(SOC_BOND_INFO(unit)->force_hg, tsc_id)) {
    959         ability->encap &= ~SOC_PA_ENCAP_IEEE;
    960     }
    961     return SOC_E_NONE;
    962 }
    963 
    964 int
    965 soc_th2_portctrl_pm_type_get(int unit, soc_port_t phy_port, int* pm_type)
    966 {
    967     int rv;
    968 
    969     *pm_type = -1;
    970 
    971     if (phy_port >= 1 && phy_port <= 256) {
    972 #ifdef PORTMOD_PM4X25_SUPPORT
    973         *pm_type = portmodDispatchTypePm4x25;
    974         rv = SOC_E_NONE;
    975 #else
    976         rv = SOC_E_UNAVAIL;
    977 #endif
    978     } else if (phy_port == _TH2_PHY_PORT_MNG0 ||
    979                phy_port == _TH2_PHY_PORT_MNG1) {
    980 #ifdef PORTMOD_PM4X10_SUPPORT
    981         *pm_type = portmodDispatchTypePm4x10;
    982         rv = SOC_E_NONE;
    983 #else
    984         rv = SOC_E_UNAVAIL;
    985 #endif
    986     } else {
    987         rv = SOC_E_PARAM;
    988     }
    989 
    990     return rv;
    991 }
    992 
    993 #ifdef FW_BCAST_DOWNLOAD
    994 STATIC int
    995 _soc_th2_sbus_ring_find(soc_th2_sbus_ring_list_t *sbus_ring_list, int core_num, int *pm_position)
    996 {
    997     int i;
    998 
    999     *pm_position = -1;
   1000     for (i=0; i<SOC_TH2_SBUS_RING_MAX_PM_NUM; i++) {
   1001         if (sbus_ring_list->core_id[i] == core_num) {
   1002             *pm_position = i;
   1003             return SOC_E_NONE;
   1004         }
   1005     }
   1006 
   1007     return SOC_E_NOT_FOUND;
   1008 }
   1009 
   1010 int soc_th2_portctrl_sbus_ring_info_get(int unit, soc_port_t port, int* bcast_id, int* position)
   1011 {
   1012     int phy, core_num, rv, i, j;
   1013 
   1014     phy = SOC_INFO(unit).port_l2p_mapping[port];
   1015     core_num = (phy - 1) / SOC_PM4X25_NUM_LANES;
   1016 
   1017     for (i=0; i<SOC_TH2_SBUS_RING_LIST_NUM; i++) {
   1018         rv = _soc_th2_sbus_ring_find(&_th2_sbus_ring_list[i], core_num, &j);
   1019         if (SOC_SUCCESS(rv)) {
   1020             *bcast_id = _th2_sbus_ring_list[i].bcast_id;
   1021             *position = j;
   1022 
   1023             return SOC_E_NONE;
   1024         }
   1025     }
   1026 
   1027     return SOC_E_NOT_FOUND;
   1028 }
   1029 
   1030 int soc_th2_portctrl_sbus_bcast_id_get(int unit, int sbus_ch, int* bcast_id)
   1031 {
   1032     int i, j;
   1033 
   1034     for (i=0; i<SOC_TH2_PM4X25_COUNT; i++) {
   1035         j = SOC_BLOCK2SCH(unit, pm4x25_th2_user_acc[unit][i].blk_id);
   1036         if (sbus_ch == j) {
   1037             if (_th2_pm4x25_core_num[i]>=SOC_TH2_SBUS_RING_3_PM_MIN
   1038                 && _th2_pm4x25_core_num[i]<=SOC_TH2_SBUS_RING_3_PM_MAX) {
   1039                 *bcast_id = _th2_sbus_ring_list[0].bcast_id;
   1040                 return SOC_E_NONE;
   1041             } else {
   1042                 *bcast_id = _th2_sbus_ring_list[1].bcast_id;
   1043                 return SOC_E_NONE;
   1044             }
   1045         }
   1046     }
   1047 
   1048     return SOC_E_NOT_FOUND;
   1049 }
   1050 #endif
   1051 
   1052 #endif /* BCM_TOMAHAWK2_SUPPORT */