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

l3.c (99611B)


      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  * File:    l3.c
      8  * Purpose: Tomahawk3 L3 function implementations
      9  */
     10 
     11 #include <soc/defs.h>
     12 #include <shared/bsl.h>
     13 #if defined(INCLUDE_L3) && defined(BCM_TOMAHAWK3_SUPPORT)
     14 #include <soc/drv.h>
     15 #include <soc/tomahawk2.h>
     16 #include <soc/profile_mem.h>
     17 
     18 #include <bcm/vlan.h>
     19 #include <bcm/error.h>
     20 #include <bcm/l3.h>
     21 #include <bcm/debug.h>
     22 #include <bcm/error.h>
     23 #include <bcm/stack.h>
     24 
     25 #include <bcm_int/esw/firebolt.h>
     26 #include <bcm_int/esw/stack.h>
     27 #include <bcm_int/esw_dispatch.h>
     28 #include <bcm_int/esw/tomahawk2.h>
     29 #include <bcm_int/esw/tomahawk3.h>
     30 
     31 #define WRITE_DLB_MEMBER_PORT_0_15(_unit, _i, _port_ent, _val, _intf_count) {\
     32     soc_mem_field32_set(_unit, DLB_ECMP_GROUP_PORT_MEMBERS_0_TO_15m, \
     33                         _port_ent,\
     34                         MEMBER_ ## _i ## _PORTf, (_i < _intf_count)?_val:0); \
     35     soc_mem_field32_set(_unit, DLB_ECMP_GROUP_PORT_MEMBERS_0_TO_15m, \
     36                         _port_ent,\
     37                         MEMBER_ ## _i ## _PORT_VALIDf, (_i < _intf_count)); \
     38 }
     39 
     40 #define WRITE_DLB_MEMBER_PORT_16_31(_unit, _i, _port_ent, _val, _intf_count) {\
     41     soc_mem_field32_set(_unit, DLB_ECMP_GROUP_PORT_MEMBERS_16_TO_31m, \
     42                         _port_ent, \
     43                         MEMBER_ ## _i ## _PORTf, (_i < _intf_count)?_val:0); \
     44     soc_mem_field32_set(_unit, DLB_ECMP_GROUP_PORT_MEMBERS_16_TO_31m, \
     45                         _port_ent, \
     46                         MEMBER_ ## _i ## _PORT_VALIDf, (_i < _intf_count)); \
     47 }
     48 
     49 #define WRITE_DLB_MEMBER_PORT_32_47(_unit, _i, _port_ent, _val, _intf_count) {\
     50     soc_mem_field32_set(_unit, DLB_ECMP_GROUP_PORT_MEMBERS_32_TO_47m, \
     51                         _port_ent, \
     52                         MEMBER_ ## _i ## _PORTf, (_i < _intf_count)?_val:0); \
     53     soc_mem_field32_set(_unit, DLB_ECMP_GROUP_PORT_MEMBERS_32_TO_47m, \
     54                         _port_ent, \
     55                         MEMBER_ ## _i ## _PORT_VALIDf, (_i < _intf_count)); \
     56 }
     57 
     58 #define WRITE_DLB_MEMBER_PORT_48_63(_unit, _i, _port_ent, _val, _intf_count) {\
     59     soc_mem_field32_set(_unit, DLB_ECMP_GROUP_PORT_MEMBERS_48_TO_63m, \
     60                         _port_ent, \
     61                         MEMBER_ ## _i ## _PORTf, (_i < _intf_count)?_val:0); \
     62     soc_mem_field32_set(_unit, DLB_ECMP_GROUP_PORT_MEMBERS_48_TO_63m, \
     63                         _port_ent, \
     64                         MEMBER_ ## _i ## _PORT_VALIDf, (_i < _intf_count)); \
     65 }
     66 
     67 #define WRITE_DLB_MEMBER_NHI_0_12(_unit, _i, _nhi_ent, _val, _intf_count) { \
     68     soc_mem_field32_set(_unit, DLB_ECMP_GROUP_NHI_MEMBERS_0_TO_12m, _nhi_ent, \
     69                         MEMBER_ ## _i ## _NHIf, (_i < _intf_count)?_val:0); \
     70     soc_mem_field32_set(_unit, DLB_ECMP_GROUP_NHI_MEMBERS_0_TO_12m, _nhi_ent, \
     71                         MEMBER_ ## _i ## _NHI_VALIDf, (_i < _intf_count)); \
     72 }
     73 
     74 #define WRITE_DLB_MEMBER_NHI_13_25(_unit, _i, _nhi_ent, _val, _intf_count) { \
     75     soc_mem_field32_set(_unit, DLB_ECMP_GROUP_NHI_MEMBERS_13_TO_25m, _nhi_ent,\
     76                         MEMBER_ ## _i ## _NHIf, (_i < _intf_count)?_val:0); \
     77     soc_mem_field32_set(_unit, DLB_ECMP_GROUP_NHI_MEMBERS_13_TO_25m, _nhi_ent,\
     78                         MEMBER_ ## _i ## _NHI_VALIDf, (_i < _intf_count)); \
     79 }
     80 
     81 #define WRITE_DLB_MEMBER_NHI_26_38(_unit, _i, _nhi_ent, _val, _intf_count) { \
     82     soc_mem_field32_set(_unit, DLB_ECMP_GROUP_NHI_MEMBERS_26_TO_38m, _nhi_ent,\
     83                         MEMBER_ ## _i ## _NHIf, (_i < _intf_count)?_val:0); \
     84     soc_mem_field32_set(_unit, DLB_ECMP_GROUP_NHI_MEMBERS_26_TO_38m, _nhi_ent,\
     85                         MEMBER_ ## _i ## _NHI_VALIDf, (_i < _intf_count)); \
     86 }
     87 
     88 #define WRITE_DLB_MEMBER_NHI_39_51(_unit, _i, _nhi_ent, _val, _intf_count) { \
     89     soc_mem_field32_set(_unit, DLB_ECMP_GROUP_NHI_MEMBERS_39_TO_51m, _nhi_ent,\
     90                         MEMBER_ ## _i ## _NHIf, (_i < _intf_count)?_val:0); \
     91     soc_mem_field32_set(_unit, DLB_ECMP_GROUP_NHI_MEMBERS_39_TO_51m, _nhi_ent,\
     92                         MEMBER_ ## _i ## _NHI_VALIDf, (_i < _intf_count)); \
     93 }
     94 
     95 #define WRITE_DLB_MEMBER_NHI_52_63(_unit, _i, _nhi_ent, _val, _intf_count) { \
     96     soc_mem_field32_set(_unit, DLB_ECMP_GROUP_NHI_MEMBERS_52_TO_63m, _nhi_ent,\
     97                         MEMBER_ ## _i ## _NHIf, (_i < _intf_count)?_val:0); \
     98     soc_mem_field32_set(_unit, DLB_ECMP_GROUP_NHI_MEMBERS_52_TO_63m, _nhi_ent,\
     99                         MEMBER_ ## _i ## _NHI_VALIDf, (_i < _intf_count)); \
    100 }
    101 
    102 #define READ_DLB_MEMBER_PORT_0_15(_unit, _i, _port_ent, _val) {\
    103     _val = 0; \
    104     if (soc_mem_field32_get(_unit, DLB_ECMP_GROUP_PORT_MEMBERS_0_TO_15m, _port_ent,\
    105                         MEMBER_ ## _i ## _PORT_VALIDf)) { \
    106         _val = soc_mem_field32_get(_unit, DLB_ECMP_GROUP_PORT_MEMBERS_0_TO_15m, _port_ent,\
    107                             MEMBER_ ## _i ## _PORTf); \
    108     } \
    109 }
    110 
    111 #define READ_DLB_MEMBER_PORT_16_31(_unit, _i, _port_ent, _val) {\
    112     _val = 0; \
    113     if (soc_mem_field32_get(_unit, DLB_ECMP_GROUP_PORT_MEMBERS_16_TO_31m, _port_ent,\
    114                         MEMBER_ ## _i ## _PORT_VALIDf)) { \
    115         _val = soc_mem_field32_get(_unit, DLB_ECMP_GROUP_PORT_MEMBERS_16_TO_31m, _port_ent,\
    116                             MEMBER_ ## _i ## _PORTf); \
    117     } \
    118 }
    119 
    120 #define READ_DLB_MEMBER_PORT_32_47(_unit, _i, _port_ent, _val) {\
    121     _val = 0; \
    122     if (soc_mem_field32_get(_unit, DLB_ECMP_GROUP_PORT_MEMBERS_32_TO_47m, _port_ent,\
    123                         MEMBER_ ## _i ## _PORT_VALIDf)) { \
    124         _val = soc_mem_field32_get(_unit, DLB_ECMP_GROUP_PORT_MEMBERS_32_TO_47m, _port_ent,\
    125                             MEMBER_ ## _i ## _PORTf); \
    126     } \
    127 }
    128 
    129 #define READ_DLB_MEMBER_PORT_48_63(_unit, _i, _port_ent, _val) {\
    130     _val = 0; \
    131     if (soc_mem_field32_get(_unit, DLB_ECMP_GROUP_PORT_MEMBERS_48_TO_63m, _port_ent,\
    132                         MEMBER_ ## _i ## _PORT_VALIDf)) { \
    133         _val = soc_mem_field32_get(_unit, DLB_ECMP_GROUP_PORT_MEMBERS_48_TO_63m, _port_ent,\
    134                             MEMBER_ ## _i ## _PORTf); \
    135     } \
    136 }
    137 
    138 #define READ_DLB_MEMBER_ALT_PORT_0_15(_unit, _i, _port_ent, _val) {\
    139     _val = 0; \
    140     if (soc_mem_field32_get(_unit, DLB_ECMP_GROUP_ALT_PORT_MEMBERS_0_TO_15m, _port_ent,\
    141                         MEMBER_ ## _i ## _PORT_VALIDf)) { \
    142         _val = soc_mem_field32_get(_unit, DLB_ECMP_GROUP_ALT_PORT_MEMBERS_0_TO_15m, _port_ent,\
    143                             MEMBER_ ## _i ## _PORTf); \
    144     } \
    145 }
    146 
    147 #define READ_DLB_MEMBER_ALT_PORT_16_31(_unit, _i, _port_ent, _val) {\
    148     _val = 0; \
    149     if (soc_mem_field32_get(_unit, DLB_ECMP_GROUP_ALT_PORT_MEMBERS_16_TO_31m, _port_ent,\
    150                         MEMBER_ ## _i ## _PORT_VALIDf)) { \
    151         _val = soc_mem_field32_get(_unit, DLB_ECMP_GROUP_ALT_PORT_MEMBERS_16_TO_31m, _port_ent,\
    152                             MEMBER_ ## _i ## _PORTf); \
    153     } \
    154 }
    155 
    156 #define READ_DLB_MEMBER_ALT_PORT_32_47(_unit, _i, _port_ent, _val) {\
    157     _val = 0; \
    158     if (soc_mem_field32_get(_unit, DLB_ECMP_GROUP_ALT_PORT_MEMBERS_32_TO_47m, _port_ent,\
    159                         MEMBER_ ## _i ## _PORT_VALIDf)) { \
    160         _val = soc_mem_field32_get(_unit, DLB_ECMP_GROUP_ALT_PORT_MEMBERS_32_TO_47m, _port_ent,\
    161                             MEMBER_ ## _i ## _PORTf); \
    162     } \
    163 }
    164 
    165 #define READ_DLB_MEMBER_ALT_PORT_48_63(_unit, _i, _port_ent, _val) {\
    166     _val = 0; \
    167     if (soc_mem_field32_get(_unit, DLB_ECMP_GROUP_ALT_PORT_MEMBERS_48_TO_63m, _port_ent,\
    168                         MEMBER_ ## _i ## _PORT_VALIDf)) { \
    169         _val = soc_mem_field32_get(_unit, DLB_ECMP_GROUP_ALT_PORT_MEMBERS_48_TO_63m, _port_ent,\
    170                             MEMBER_ ## _i ## _PORTf); \
    171     } \
    172 }
    173 
    174 #define READ_DLB_MEMBER_NHI_0_12(_unit, _i, _nhi_ent, _val) { \
    175     _val = 0; \
    176     if (soc_mem_field32_get(_unit, DLB_ECMP_GROUP_NHI_MEMBERS_0_TO_12m, _nhi_ent,\
    177                         MEMBER_ ## _i ## _NHI_VALIDf)) { \
    178         _val = soc_mem_field32_get(_unit, DLB_ECMP_GROUP_NHI_MEMBERS_0_TO_12m, _nhi_ent,\
    179                             MEMBER_ ## _i ## _NHIf); \
    180     } \
    181 }
    182 
    183 #define READ_DLB_MEMBER_NHI_13_25(_unit, _i, _nhi_ent, _val) { \
    184     _val = 0; \
    185     if (soc_mem_field32_get(_unit, DLB_ECMP_GROUP_NHI_MEMBERS_13_TO_25m, _nhi_ent,\
    186                         MEMBER_ ## _i ## _NHI_VALIDf)) { \
    187         _val = soc_mem_field32_get(_unit, DLB_ECMP_GROUP_NHI_MEMBERS_13_TO_25m, _nhi_ent,\
    188                             MEMBER_ ## _i ## _NHIf); \
    189     } \
    190 }
    191 
    192 #define READ_DLB_MEMBER_NHI_26_38(_unit, _i, _nhi_ent, _val) { \
    193     _val = 0; \
    194     if (soc_mem_field32_get(_unit, DLB_ECMP_GROUP_NHI_MEMBERS_26_TO_38m, _nhi_ent,\
    195                         MEMBER_ ## _i ## _NHI_VALIDf)) { \
    196         _val = soc_mem_field32_get(_unit, DLB_ECMP_GROUP_NHI_MEMBERS_26_TO_38m, _nhi_ent,\
    197                             MEMBER_ ## _i ## _NHIf); \
    198     } \
    199 }
    200 
    201 #define READ_DLB_MEMBER_NHI_39_51(_unit, _i, _nhi_ent, _val) { \
    202     _val = 0; \
    203     if (soc_mem_field32_get(_unit, DLB_ECMP_GROUP_NHI_MEMBERS_39_TO_51m, _nhi_ent,\
    204                         MEMBER_ ## _i ## _NHI_VALIDf)) { \
    205         _val = soc_mem_field32_get(_unit, DLB_ECMP_GROUP_NHI_MEMBERS_39_TO_51m, _nhi_ent,\
    206                             MEMBER_ ## _i ## _NHIf); \
    207     } \
    208 }
    209 
    210 #define READ_DLB_MEMBER_NHI_52_63(_unit, _i, _nhi_ent, _val) { \
    211     _val = 0; \
    212     if (soc_mem_field32_get(_unit, DLB_ECMP_GROUP_NHI_MEMBERS_52_TO_63m, _nhi_ent,\
    213                         MEMBER_ ## _i ## _NHI_VALIDf)) { \
    214         _val = soc_mem_field32_get(_unit, DLB_ECMP_GROUP_NHI_MEMBERS_52_TO_63m, _nhi_ent,\
    215                             MEMBER_ ## _i ## _NHIf); \
    216     } \
    217 }
    218 
    219 #define READ_DLB_MEMBER_ALT_NHI_0_12(_unit, _i, _nhi_ent, _val) { \
    220     _val = 0; \
    221     if (soc_mem_field32_get(_unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_0_TO_12m, _nhi_ent,\
    222                         MEMBER_ ## _i ## _NHI_VALIDf)) { \
    223         _val = soc_mem_field32_get(_unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_0_TO_12m, _nhi_ent,\
    224                             MEMBER_ ## _i ## _NHIf); \
    225     } \
    226 }
    227 
    228 #define READ_DLB_MEMBER_ALT_NHI_13_25(_unit, _i, _nhi_ent, _val) { \
    229     _val = 0; \
    230     if (soc_mem_field32_get(_unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_13_TO_25m, _nhi_ent,\
    231                         MEMBER_ ## _i ## _NHI_VALIDf)) { \
    232         _val = soc_mem_field32_get(_unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_13_TO_25m, _nhi_ent,\
    233                             MEMBER_ ## _i ## _NHIf); \
    234     } \
    235 }
    236 
    237 #define READ_DLB_MEMBER_ALT_NHI_26_38(_unit, _i, _nhi_ent, _val) { \
    238     _val = 0; \
    239     if (soc_mem_field32_get(_unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_26_TO_38m, _nhi_ent,\
    240                         MEMBER_ ## _i ## _NHI_VALIDf)) { \
    241         _val = soc_mem_field32_get(_unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_26_TO_38m, _nhi_ent,\
    242                             MEMBER_ ## _i ## _NHIf); \
    243     } \
    244 }
    245 
    246 #define READ_DLB_MEMBER_ALT_NHI_39_51(_unit, _i, _nhi_ent, _val) { \
    247     _val = 0; \
    248     if (soc_mem_field32_get(_unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_39_TO_51m, _nhi_ent,\
    249                         MEMBER_ ## _i ## _NHI_VALIDf)) { \
    250         _val = soc_mem_field32_get(_unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_39_TO_51m, _nhi_ent,\
    251                             MEMBER_ ## _i ## _NHIf); \
    252     } \
    253 }
    254 
    255 #define READ_DLB_MEMBER_ALT_NHI_52_63(_unit, _i, _nhi_ent, _val) { \
    256     _val = 0; \
    257     if (soc_mem_field32_get(_unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_52_TO_63m, _nhi_ent,\
    258                         MEMBER_ ## _i ## _NHI_VALIDf)) { \
    259         _val = soc_mem_field32_get(_unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_52_TO_63m, _nhi_ent,\
    260                             MEMBER_ ## _i ## _NHIf); \
    261     } \
    262 }
    263 
    264 
    265 #define WRITE_DLB_MEMBER_ALT_PORT_0_15(_unit, _i, _port_ent, _val, \
    266                                                     _intf_count) { \
    267     soc_mem_field32_set(_unit, DLB_ECMP_GROUP_ALT_PORT_MEMBERS_0_TO_15m, \
    268                         _port_ent, \
    269                         MEMBER_ ## _i ## _PORTf, (_i < _intf_count)?_val:0); \
    270     soc_mem_field32_set(_unit, DLB_ECMP_GROUP_ALT_PORT_MEMBERS_0_TO_15m, \
    271                         _port_ent, \
    272                         MEMBER_ ## _i ## _PORT_VALIDf, (_i < _intf_count)); \
    273 }
    274 
    275 #define WRITE_DLB_MEMBER_ALT_PORT_16_31(_unit, _i, _port_ent, _val, \
    276                                         _intf_count) { \
    277     soc_mem_field32_set(_unit, DLB_ECMP_GROUP_ALT_PORT_MEMBERS_16_TO_31m, \
    278                         _port_ent, \
    279                         MEMBER_ ## _i ## _PORTf, (_i < _intf_count)?_val:0); \
    280     soc_mem_field32_set(_unit, DLB_ECMP_GROUP_ALT_PORT_MEMBERS_16_TO_31m, \
    281                         _port_ent, \
    282                         MEMBER_ ## _i ## _PORT_VALIDf, (_i < _intf_count)); \
    283 }
    284 
    285 #define WRITE_DLB_MEMBER_ALT_PORT_32_47(_unit, _i, _port_ent, _val, \
    286                                         _intf_count) { \
    287     soc_mem_field32_set(_unit, DLB_ECMP_GROUP_ALT_PORT_MEMBERS_32_TO_47m, \
    288                         _port_ent, \
    289                         MEMBER_ ## _i ## _PORTf, (_i < _intf_count)?_val:0); \
    290     soc_mem_field32_set(_unit, DLB_ECMP_GROUP_ALT_PORT_MEMBERS_32_TO_47m, \
    291                         _port_ent, \
    292                         MEMBER_ ## _i ## _PORT_VALIDf, (_i < _intf_count)); \
    293 }
    294 
    295 #define WRITE_DLB_MEMBER_ALT_PORT_48_63(_unit, _i, _port_ent, _val, \
    296                                         _intf_count) { \
    297     soc_mem_field32_set(_unit, DLB_ECMP_GROUP_ALT_PORT_MEMBERS_48_TO_63m, \
    298                         _port_ent, \
    299                         MEMBER_ ## _i ## _PORTf, (_i < _intf_count)?_val:0); \
    300     soc_mem_field32_set(_unit, DLB_ECMP_GROUP_ALT_PORT_MEMBERS_48_TO_63m, \
    301                         _port_ent, \
    302                         MEMBER_ ## _i ## _PORT_VALIDf, (_i < _intf_count)); \
    303 }
    304 
    305 #define WRITE_DLB_MEMBER_ALT_NHI_0_12(_unit, _i, _nhi_ent, _val, \
    306                                       _intf_count) { \
    307     soc_mem_field32_set(_unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_0_TO_12m, \
    308                         _nhi_ent, \
    309                         MEMBER_ ## _i ## _NHIf, (_i < _intf_count)?_val:0); \
    310     soc_mem_field32_set(_unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_0_TO_12m, \
    311                         _nhi_ent, \
    312                         MEMBER_ ## _i ## _NHI_VALIDf, (_i < _intf_count)); \
    313 }
    314 
    315 #define WRITE_DLB_MEMBER_ALT_NHI_13_25(_unit, _i, _nhi_ent, _val, \
    316                                        _intf_count) { \
    317     soc_mem_field32_set(_unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_13_TO_25m, \
    318                         _nhi_ent, \
    319                         MEMBER_ ## _i ## _NHIf, (_i < _intf_count)?_val:0); \
    320     soc_mem_field32_set(_unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_13_TO_25m, \
    321                         _nhi_ent, \
    322                         MEMBER_ ## _i ## _NHI_VALIDf, (_i < _intf_count)); \
    323 }
    324 
    325 #define WRITE_DLB_MEMBER_ALT_NHI_26_38(_unit, _i, _nhi_ent, _val, \
    326                                        _intf_count) { \
    327     soc_mem_field32_set(_unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_26_TO_38m, \
    328                         _nhi_ent, \
    329                         MEMBER_ ## _i ## _NHIf, (_i < _intf_count)?_val:0); \
    330     soc_mem_field32_set(_unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_26_TO_38m, \
    331                         _nhi_ent, \
    332                         MEMBER_ ## _i ## _NHI_VALIDf, (_i < _intf_count)); \
    333 }
    334 
    335 #define WRITE_DLB_MEMBER_ALT_NHI_39_51(_unit, _i, _nhi_ent, _val, \
    336                                        _intf_count) { \
    337     soc_mem_field32_set(_unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_39_TO_51m, \
    338                         _nhi_ent, \
    339                         MEMBER_ ## _i ## _NHIf, (_i < _intf_count)?_val:0); \
    340     soc_mem_field32_set(_unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_39_TO_51m, \
    341                         _nhi_ent, \
    342                         MEMBER_ ## _i ## _NHI_VALIDf, (_i < _intf_count)); \
    343 }
    344 
    345 #define WRITE_DLB_MEMBER_ALT_NHI_52_63(_unit, _i, _nhi_ent, _val, \
    346                                        _intf_count) { \
    347     soc_mem_field32_set(_unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_52_TO_63m, \
    348                         _nhi_ent, \
    349                         MEMBER_ ## _i ## _NHIf, (_i < _intf_count)?_val:0); \
    350     soc_mem_field32_set(_unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_52_TO_63m, \
    351                         _nhi_ent, \
    352                         MEMBER_ ## _i ## _NHI_VALIDf, (_i < _intf_count)); \
    353 }
    354 
    355 #define _DLB_SET_GROUP_PTR_0_12(_M_) {\
    356         int port_index = 0; \
    357         READ_DLB_MEMBER_NHI_0_12(unit, _M_, dlb_nhi_members.entry_data, nh_index); \
    358         if (nh_index) { \
    359             READ_DLB_MEMBER_PORT_0_15(unit, _M_, dlb_port_members.entry_data, port_index); \
    360             if (port_index) {\
    361                 _bcm_th3_set_port_list(unit, port_index, dlb_id, nh_index); \
    362             } \
    363         } \
    364         READ_DLB_MEMBER_ALT_NHI_0_12(unit, _M_, dlb_alt_nhi_members.entry_data, nh_index); \
    365         if (nh_index) { \
    366             READ_DLB_MEMBER_ALT_PORT_0_15(unit, _M_, dlb_alt_port_members.entry_data, port_index); \
    367             if (port_index) { \
    368                 _bcm_th3_set_port_list(unit, port_index, dlb_id, nh_index); \
    369             } \
    370         } \
    371 }
    372 
    373 #define _DLB_SET_GROUP_PTR_13_25(_M_) {\
    374         int port_index = 0; \
    375         READ_DLB_MEMBER_NHI_13_25(unit, _M_, dlb_nhi_members_13.entry_data, nh_index); \
    376         if (nh_index) { \
    377             if (_M_ <= 15) { \
    378                 READ_DLB_MEMBER_PORT_0_15(unit, _M_, dlb_port_members.entry_data, port_index); \
    379             } else { \
    380                 READ_DLB_MEMBER_PORT_16_31(unit, _M_, dlb_port_members_16.entry_data, port_index); \
    381             } \
    382             if (port_index) {\
    383                 _bcm_th3_set_port_list(unit, port_index, dlb_id, nh_index); \
    384             } \
    385         } \
    386         READ_DLB_MEMBER_ALT_NHI_13_25(unit, _M_, dlb_alt_nhi_members_13.entry_data, nh_index); \
    387         if (nh_index) { \
    388             if (_M_ <= 15) { \
    389                 READ_DLB_MEMBER_ALT_PORT_0_15(unit, _M_, dlb_alt_port_members.entry_data, port_index); \
    390             } else { \
    391                 READ_DLB_MEMBER_ALT_PORT_16_31(unit, _M_, dlb_alt_port_members_16.entry_data, port_index); \
    392             } \
    393             if (port_index) {\
    394                 _bcm_th3_set_port_list(unit, port_index, dlb_id, nh_index); \
    395             } \
    396         } \
    397 }
    398 
    399 
    400 #define _DLB_SET_GROUP_PTR_26_38(_M_) {\
    401         int port_index = 0; \
    402         READ_DLB_MEMBER_NHI_26_38(unit, _M_, dlb_nhi_members_26.entry_data, nh_index); \
    403         if (nh_index) { \
    404             if (_M_ <= 31) { \
    405                 READ_DLB_MEMBER_PORT_16_31(unit, _M_, dlb_port_members_16.entry_data, port_index); \
    406             } else { \
    407                 READ_DLB_MEMBER_PORT_32_47(unit, _M_, dlb_port_members_32.entry_data, port_index); \
    408             } \
    409             if (port_index) {\
    410                 _bcm_th3_set_port_list(unit, port_index, dlb_id, nh_index); \
    411             } \
    412         } \
    413         READ_DLB_MEMBER_ALT_NHI_26_38(unit, _M_, dlb_alt_nhi_members_26.entry_data, nh_index); \
    414         if (nh_index) { \
    415             if (_M_ <= 31) { \
    416                 READ_DLB_MEMBER_ALT_PORT_16_31(unit, _M_, dlb_alt_port_members_16.entry_data, port_index); \
    417             } else { \
    418                 READ_DLB_MEMBER_ALT_PORT_32_47(unit, _M_, dlb_alt_port_members_32.entry_data, port_index); \
    419             } \
    420             if (port_index) {\
    421                 _bcm_th3_set_port_list(unit, port_index, dlb_id, nh_index); \
    422             } \
    423         } \
    424 }
    425 
    426 
    427 #define _DLB_SET_GROUP_PTR_39_51(_M_) {\
    428         int port_index = 0; \
    429         READ_DLB_MEMBER_NHI_39_51(unit, _M_, dlb_nhi_members_39.entry_data, nh_index); \
    430         if (nh_index) { \
    431             if (_M_ <= 47) { \
    432                 READ_DLB_MEMBER_PORT_32_47(unit, _M_, dlb_port_members_32.entry_data, port_index); \
    433             } else { \
    434                 READ_DLB_MEMBER_PORT_48_63(unit, _M_, dlb_port_members_48.entry_data, port_index); \
    435             } \
    436             if (port_index) {\
    437                 _bcm_th3_set_port_list(unit, port_index, dlb_id, nh_index); \
    438             } \
    439         } \
    440         READ_DLB_MEMBER_ALT_NHI_39_51(unit, _M_, dlb_alt_nhi_members_39.entry_data, nh_index); \
    441         if (nh_index) { \
    442             if (_M_ <= 47) { \
    443                 READ_DLB_MEMBER_ALT_PORT_32_47(unit, _M_, dlb_alt_port_members_32.entry_data, port_index); \
    444             } else { \
    445                 READ_DLB_MEMBER_ALT_PORT_48_63(unit, _M_, dlb_alt_port_members_48.entry_data, port_index); \
    446             } \
    447             if (port_index) {\
    448                 _bcm_th3_set_port_list(unit, port_index, dlb_id, nh_index); \
    449             } \
    450         } \
    451 }
    452 
    453 
    454 #define _DLB_SET_GROUP_PTR_52_63(_M_) {\
    455         int port_index = 0; \
    456         READ_DLB_MEMBER_NHI_52_63(unit, _M_, dlb_nhi_members_52.entry_data, nh_index); \
    457         if (nh_index) { \
    458             READ_DLB_MEMBER_PORT_48_63(unit, _M_, dlb_port_members_48.entry_data, port_index); \
    459             if (port_index) {\
    460                 _bcm_th3_set_port_list(unit, port_index, dlb_id, nh_index); \
    461             } \
    462         } \
    463         READ_DLB_MEMBER_ALT_NHI_52_63(unit, _M_, dlb_alt_nhi_members_52.entry_data, nh_index); \
    464         if (nh_index) { \
    465             READ_DLB_MEMBER_ALT_PORT_48_63(unit, _M_, dlb_alt_port_members_48.entry_data, port_index); \
    466             if (port_index) {\
    467                 _bcm_th3_set_port_list(unit, port_index, dlb_id, nh_index); \
    468             } \
    469         } \
    470 }
    471 
    472 #define ECMP_DLB_INFO(_unit_) (_th2_ecmp_dlb_bk[_unit_])
    473 #define ECMP_DLB_PORT_INFO(_unit_, _idx_) \
    474            (_th2_ecmp_dlb_bk[_unit_]->ecmp_dlb_port_info[_idx_])
    475 #define ECMP_DLB_PORT_LIST(_unit_, _idx_) \
    476             ECMP_DLB_PORT_INFO(unit, _idx_).port_membership_list
    477 
    478 #define _BCM_ECMP_DLB_FLOWSET_BLOCK_SIZE_SHIFT      8
    479 #define _BCM_ECMP_DLB_FLOWSET_BLOCK_TEST_RANGE(_u_, _idx_, _count_, _result_) \
    480     SHR_BITTEST_RANGE(ECMP_DLB_INFO(_u_)->ecmp_dlb_flowset_block_bitmap, _idx_, _count_, _result_)
    481 
    482 extern _th2_ecmp_dlb_bookkeeping_t *_th2_ecmp_dlb_bk[BCM_MAX_NUM_UNITS];
    483 
    484 /*
    485  * Function:
    486  *      _bcm_th3_l3_ecmp_dlb_port_get
    487  * Purpose:
    488  *      Get ports for each ECMP member.
    489  * Parameters:
    490  *      unit                - (IN) SOC unit number.
    491  *      ecmp                - (IN) ECMP group info.
    492  *      dlb_id              - (IN) DLB group ID.
    493  *      primary_count       - (IN) ECMP primary count..
    494  *      intf_count          - (IN) Number of elements in intf_array.
    495  *      intf_array          - (IN) Array of Egress forwarding objects.
    496  *      port_array          - (OUT) Array of ports.
    497  *      ecmp_member_bitmap  - (IN) ECMP DLB members.
    498  * Returns:
    499  *      BCM_E_xxx
    500  */
    501 int
    502 _bcm_th3_l3_ecmp_dlb_port_get(int unit, bcm_l3_egress_ecmp_t *ecmp,
    503                                  int dlb_id, int primary_count, int intf_count,
    504                                  bcm_if_t *intf_array, int *port_array)
    505 {
    506     int rv = BCM_E_NONE;
    507     int i;
    508     ing_l3_next_hop_entry_t ing_nh_entry;
    509     int port;
    510     int nh_index;
    511 
    512     for (i = 0; i < intf_count; i++) {
    513 
    514         if (BCM_XGS3_L3_EGRESS_IDX_VALID(unit, intf_array[i])) {
    515             nh_index =  intf_array[i] - BCM_XGS3_EGRESS_IDX_MIN(unit);
    516         } else {
    517             return BCM_E_PARAM;
    518         }
    519 
    520         /* Derive port from nh_index */
    521         rv = (READ_ING_L3_NEXT_HOPm(unit, MEM_BLOCK_ANY,
    522                     nh_index, &ing_nh_entry));
    523         if (BCM_FAILURE(rv)) {
    524             return rv;
    525         }
    526         if (soc_ING_L3_NEXT_HOPm_field32_get(unit, &ing_nh_entry, Tf)) {
    527             /* Next hop should correspond to a single physical port. */
    528             return BCM_E_CONFIG;
    529         }
    530         port = soc_ING_L3_NEXT_HOPm_field32_get(unit, &ing_nh_entry,
    531                 PORT_NUMf);
    532         port_array[i] = port;
    533     }
    534     return rv;
    535 }
    536 /*
    537  *    Function:
    538  *       bcm_th3_l3_egress_ecmp_dlb_resource_validate
    539  *    Purpose:
    540  *       Checks for free resources for the Replace operation. Also,
    541  *       checks for the contiguous space based on the number of blocks
    542  *       used for the replacement ecmp dlb group.
    543  *    Parameters:
    544  *         unit       - (IN) bcm device.
    545  *         ecmp       - (IN) ECMP group info.
    546  *         dlb_id   -   (IN) ECMP DLB id.
    547  *    Returns:
    548  *         BCM_E_XXX
    549  */
    550 int _bcm_th3_l3_egress_ecmp_dlb_resource_validate(int unit, bcm_l3_egress_ecmp_t *ecmp,
    551                                   int dlb_id)
    552 {
    553     bcm_l3_egress_ecmp_t dlb_ecmp;
    554     int dlb_ecmp_count = 0;
    555     int num_blocks;
    556     int block_base_ptr;
    557     int occupied;
    558     int total_blocks;
    559     int max_block_base_ptr;
    560   
    561     bcm_l3_egress_ecmp_t_init(&dlb_ecmp);
    562     dlb_ecmp.ecmp_intf = ecmp->ecmp_intf;
    563     BCM_IF_ERROR_RETURN(
    564         _bcm_esw_l3_egress_ecmp_get(unit, &dlb_ecmp, 0, NULL,
    565                                     &dlb_ecmp_count, TRUE));
    566 
    567     num_blocks = ecmp->dynamic_size >> _BCM_ECMP_DLB_FLOWSET_BLOCK_SIZE_SHIFT;
    568     total_blocks = soc_mem_index_count(unit, DLB_ECMP_FLOWSETm) >>
    569                    _BCM_ECMP_DLB_FLOWSET_BLOCK_SIZE_SHIFT;
    570     max_block_base_ptr = total_blocks - num_blocks;
    571 
    572     /* Check if a free contiguous region of flow set table exists
    573      * starting from (dlb_id+1) to (block_base_ptr + num_blocks - 1).
    574      */
    575     for (block_base_ptr = dlb_id + 1;
    576           block_base_ptr <= max_block_base_ptr;
    577           block_base_ptr++) {
    578         _BCM_ECMP_DLB_FLOWSET_BLOCK_TEST_RANGE(unit, block_base_ptr, num_blocks,
    579                 occupied);
    580         if (!occupied) {
    581             break;
    582         }
    583     }
    584     if (block_base_ptr > max_block_base_ptr) {
    585         /* A contiguous region of the desired size could not be found in
    586          * flow set table.
    587          */
    588         return BCM_E_RESOURCE;
    589     }
    590 
    591     return BCM_E_NONE;
    592 }
    593 
    594 /*
    595  * Function:
    596  *      _bcm_th3_l3_ecmp_dlb_get_id
    597  * Purpose:
    598  *      Get ECMP dlb id from ecmp group.
    599  * Parameters:
    600  *      unit            - (IN) SOC unit number.
    601  *      ecmp_grp_idx  - (IN) ECMP group index.
    602  *                         -1: free all DLB resources,
    603  *                         others: will not disable DLB and free flowset.
    604  * Returns:
    605  *      dlb_id - DLB group id.
    606  */
    607 int
    608 _bcm_th3_l3_ecmp_dlb_get_id(int unit, int ecmp_grp_idx)
    609 {
    610     int dlb_id = 0;
    611     dlb_id = ecmp_grp_idx - BCM_TH3_L3_ECMP_DLB_START(unit);
    612 
    613     return dlb_id;
    614 }
    615 
    616 /*
    617  * Function:
    618  *      _bcm_th2_ecmp_dlb_port_member_set
    619  * Purpose:
    620  *      Set dlb port numbers corresponding to each ecmp member NH.
    621  * Parameters:
    622  *      unit            - (IN) SOC unit number.
    623  *      port_array      - (IN) port array for each NH.
    624  *      intf_count      - (IN) INTF count.
    625  *      primary_count   - (IN) Primary INTF count.
    626  *      dlb_id          - (IN) DLB group id.
    627  * Returns:
    628  *      BCM_E_xxx
    629  */
    630 int
    631 _bcm_th3_l3_ecmp_dlb_port_member_set(int unit, int *port_array,
    632                                   int primary_count, int unique_intfs, int dlb_id)
    633 {
    634     int alt_nh_start;
    635     int rv = BCM_E_NONE;
    636     int alt_count = unique_intfs - primary_count;
    637 
    638     dlb_ecmp_group_port_members_0_to_15_entry_t dlb_port_members;
    639     dlb_ecmp_group_port_members_16_to_31_entry_t dlb_port_members_16;
    640     dlb_ecmp_group_port_members_32_to_47_entry_t dlb_port_members_32;
    641     dlb_ecmp_group_port_members_48_to_63_entry_t dlb_port_members_48;
    642     dlb_ecmp_group_alt_port_members_0_to_15_entry_t dlb_alt_port_members;
    643     dlb_ecmp_group_alt_port_members_16_to_31_entry_t dlb_alt_port_members_16;
    644     dlb_ecmp_group_alt_port_members_32_to_47_entry_t dlb_alt_port_members_32;
    645     dlb_ecmp_group_alt_port_members_48_to_63_entry_t dlb_alt_port_members_48;
    646 
    647     sal_memset(&dlb_port_members, 0,
    648             sizeof(dlb_ecmp_group_port_members_0_to_15_entry_t));
    649     sal_memset(&dlb_port_members_16, 0,
    650             sizeof(dlb_ecmp_group_port_members_16_to_31_entry_t));
    651     sal_memset(&dlb_port_members_32, 0,
    652             sizeof(dlb_ecmp_group_port_members_32_to_47_entry_t));
    653     sal_memset(&dlb_port_members_48, 0,
    654             sizeof(dlb_ecmp_group_port_members_48_to_63_entry_t));
    655     WRITE_DLB_MEMBER_PORT_0_15(unit, 0, &dlb_port_members,
    656                                port_array[0], primary_count);
    657     WRITE_DLB_MEMBER_PORT_0_15(unit, 1, &dlb_port_members,
    658                                port_array[1], primary_count);
    659     WRITE_DLB_MEMBER_PORT_0_15(unit, 2, &dlb_port_members,
    660                                port_array[2], primary_count);
    661     WRITE_DLB_MEMBER_PORT_0_15(unit, 3, &dlb_port_members,
    662                                port_array[3], primary_count);
    663     WRITE_DLB_MEMBER_PORT_0_15(unit, 4, &dlb_port_members,
    664                                port_array[4], primary_count);
    665     WRITE_DLB_MEMBER_PORT_0_15(unit, 5, &dlb_port_members,
    666                                port_array[5], primary_count);
    667     WRITE_DLB_MEMBER_PORT_0_15(unit, 6, &dlb_port_members,
    668                                port_array[6], primary_count);
    669     WRITE_DLB_MEMBER_PORT_0_15(unit, 7, &dlb_port_members,
    670                                port_array[7], primary_count);
    671     WRITE_DLB_MEMBER_PORT_0_15(unit, 8, &dlb_port_members,
    672                                port_array[8], primary_count);
    673     WRITE_DLB_MEMBER_PORT_0_15(unit, 9, &dlb_port_members,
    674                                port_array[9], primary_count);
    675     WRITE_DLB_MEMBER_PORT_0_15(unit, 10, &dlb_port_members
    676                               , port_array[10], primary_count);
    677     WRITE_DLB_MEMBER_PORT_0_15(unit, 11, &dlb_port_members,
    678                                port_array[11], primary_count);
    679     WRITE_DLB_MEMBER_PORT_0_15(unit, 12, &dlb_port_members,
    680                                port_array[12], primary_count);
    681     WRITE_DLB_MEMBER_PORT_0_15(unit, 13, &dlb_port_members,
    682                                port_array[13], primary_count);
    683     WRITE_DLB_MEMBER_PORT_0_15(unit, 14, &dlb_port_members,
    684                                port_array[14], primary_count);
    685     WRITE_DLB_MEMBER_PORT_0_15(unit, 15, &dlb_port_members,
    686                                port_array[15], primary_count);
    687     rv = soc_mem_write(unit, DLB_ECMP_GROUP_PORT_MEMBERS_0_TO_15m,
    688                        MEM_BLOCK_ALL, (dlb_id), &dlb_port_members);
    689     WRITE_DLB_MEMBER_PORT_16_31(unit, 16, &dlb_port_members_16,
    690                                port_array[16], primary_count);
    691     WRITE_DLB_MEMBER_PORT_16_31(unit, 17, &dlb_port_members_16,
    692                                port_array[17], primary_count);
    693     WRITE_DLB_MEMBER_PORT_16_31(unit, 18, &dlb_port_members_16,
    694                                port_array[18], primary_count);
    695     WRITE_DLB_MEMBER_PORT_16_31(unit, 19, &dlb_port_members_16,
    696                                port_array[19], primary_count);
    697     WRITE_DLB_MEMBER_PORT_16_31(unit, 20, &dlb_port_members_16,
    698                                port_array[20], primary_count);
    699     WRITE_DLB_MEMBER_PORT_16_31(unit, 21, &dlb_port_members_16,
    700                                port_array[21], primary_count);
    701     WRITE_DLB_MEMBER_PORT_16_31(unit, 22, &dlb_port_members_16,
    702                                port_array[22], primary_count);
    703     WRITE_DLB_MEMBER_PORT_16_31(unit, 23, &dlb_port_members_16,
    704                                 port_array[23], primary_count);
    705     WRITE_DLB_MEMBER_PORT_16_31(unit, 24, &dlb_port_members_16,
    706                                 port_array[24], primary_count);
    707     WRITE_DLB_MEMBER_PORT_16_31(unit, 25, &dlb_port_members_16,
    708                                 port_array[25], primary_count);
    709     WRITE_DLB_MEMBER_PORT_16_31(unit, 26, &dlb_port_members_16,
    710                                 port_array[26], primary_count);
    711     WRITE_DLB_MEMBER_PORT_16_31(unit, 27, &dlb_port_members_16,
    712                                 port_array[27], primary_count);
    713     WRITE_DLB_MEMBER_PORT_16_31(unit, 28, &dlb_port_members_16,
    714                                 port_array[28], primary_count);
    715     WRITE_DLB_MEMBER_PORT_16_31(unit, 29, &dlb_port_members_16,
    716                                 port_array[29], primary_count);
    717     WRITE_DLB_MEMBER_PORT_16_31(unit, 30, &dlb_port_members_16,
    718                                 port_array[30], primary_count);
    719     WRITE_DLB_MEMBER_PORT_16_31(unit, 31, &dlb_port_members_16,
    720                                 port_array[31], primary_count);
    721     rv = soc_mem_write(unit, DLB_ECMP_GROUP_PORT_MEMBERS_16_TO_31m,
    722                        MEM_BLOCK_ALL, (dlb_id), &dlb_port_members_16);
    723     WRITE_DLB_MEMBER_PORT_32_47(unit, 32, &dlb_port_members_32,
    724                                 port_array[32], primary_count);
    725     WRITE_DLB_MEMBER_PORT_32_47(unit, 33, &dlb_port_members_32,
    726                                 port_array[33], primary_count);
    727     WRITE_DLB_MEMBER_PORT_32_47(unit, 34, &dlb_port_members_32,
    728                                 port_array[34], primary_count);
    729     WRITE_DLB_MEMBER_PORT_32_47(unit, 35, &dlb_port_members_32,
    730                                 port_array[35], primary_count);
    731     WRITE_DLB_MEMBER_PORT_32_47(unit, 36, &dlb_port_members_32,
    732                                 port_array[36], primary_count);
    733     WRITE_DLB_MEMBER_PORT_32_47(unit, 37, &dlb_port_members_32,
    734                                 port_array[37], primary_count);
    735     WRITE_DLB_MEMBER_PORT_32_47(unit, 38, &dlb_port_members_32,
    736                                 port_array[38], primary_count);
    737     WRITE_DLB_MEMBER_PORT_32_47(unit, 39, &dlb_port_members_32,
    738                                 port_array[39], primary_count);
    739     WRITE_DLB_MEMBER_PORT_32_47(unit, 40, &dlb_port_members_32,
    740                                 port_array[40], primary_count);
    741     WRITE_DLB_MEMBER_PORT_32_47(unit, 41, &dlb_port_members_32,
    742                                 port_array[41], primary_count);
    743     WRITE_DLB_MEMBER_PORT_32_47(unit, 42, &dlb_port_members_32,
    744                                 port_array[42], primary_count);
    745     WRITE_DLB_MEMBER_PORT_32_47(unit, 43, &dlb_port_members_32,
    746                                 port_array[43], primary_count);
    747     WRITE_DLB_MEMBER_PORT_32_47(unit, 44, &dlb_port_members_32,
    748                                 port_array[44], primary_count);
    749     WRITE_DLB_MEMBER_PORT_32_47(unit, 45, &dlb_port_members_32,
    750                                 port_array[45], primary_count);
    751     WRITE_DLB_MEMBER_PORT_32_47(unit, 46, &dlb_port_members_32,
    752                                 port_array[46], primary_count);
    753     WRITE_DLB_MEMBER_PORT_32_47(unit, 47, &dlb_port_members_32,
    754                                 port_array[47], primary_count);
    755     rv = soc_mem_write(unit, DLB_ECMP_GROUP_PORT_MEMBERS_32_TO_47m,
    756                        MEM_BLOCK_ALL, (dlb_id), &dlb_port_members_32);
    757     WRITE_DLB_MEMBER_PORT_48_63(unit, 48, &dlb_port_members_48,
    758                                 port_array[48], primary_count);
    759     WRITE_DLB_MEMBER_PORT_48_63(unit, 49, &dlb_port_members_48,
    760                                 port_array[49], primary_count);
    761     WRITE_DLB_MEMBER_PORT_48_63(unit, 50, &dlb_port_members_48,
    762                                 port_array[50], primary_count);
    763     WRITE_DLB_MEMBER_PORT_48_63(unit, 51, &dlb_port_members_48,
    764                                 port_array[51], primary_count);
    765     WRITE_DLB_MEMBER_PORT_48_63(unit, 52, &dlb_port_members_48,
    766                                 port_array[52], primary_count);
    767     WRITE_DLB_MEMBER_PORT_48_63(unit, 53, &dlb_port_members_48,
    768                                 port_array[53], primary_count);
    769     WRITE_DLB_MEMBER_PORT_48_63(unit, 54, &dlb_port_members_48,
    770                                 port_array[54], primary_count);
    771     WRITE_DLB_MEMBER_PORT_48_63(unit, 55, &dlb_port_members_48,
    772                                 port_array[55], primary_count);
    773     WRITE_DLB_MEMBER_PORT_48_63(unit, 56, &dlb_port_members_48,
    774                                 port_array[56], primary_count);
    775     WRITE_DLB_MEMBER_PORT_48_63(unit, 57, &dlb_port_members_48,
    776                                 port_array[57], primary_count);
    777     WRITE_DLB_MEMBER_PORT_48_63(unit, 58, &dlb_port_members_48,
    778                                 port_array[58], primary_count);
    779     WRITE_DLB_MEMBER_PORT_48_63(unit, 59, &dlb_port_members_48,
    780                                 port_array[59], primary_count);
    781     WRITE_DLB_MEMBER_PORT_48_63(unit, 60, &dlb_port_members_48,
    782                                 port_array[60], primary_count);
    783     WRITE_DLB_MEMBER_PORT_48_63(unit, 61, &dlb_port_members_48,
    784                                 port_array[61], primary_count);
    785     WRITE_DLB_MEMBER_PORT_48_63(unit, 62, &dlb_port_members_48,
    786                                 port_array[62], primary_count);
    787     WRITE_DLB_MEMBER_PORT_48_63(unit, 63, &dlb_port_members_48,
    788                                 port_array[63], primary_count);
    789     rv = soc_mem_write(unit, DLB_ECMP_GROUP_PORT_MEMBERS_48_TO_63m,
    790                        MEM_BLOCK_ALL, (dlb_id), &dlb_port_members_48);
    791     if (alt_count <= 0) {
    792         return rv;
    793     }
    794     alt_nh_start = primary_count;
    795     sal_memset(&dlb_alt_port_members, 0,
    796             sizeof(dlb_ecmp_group_alt_port_members_0_to_15_entry_t));
    797     sal_memset(&dlb_alt_port_members_16, 0,
    798             sizeof(dlb_ecmp_group_alt_port_members_16_to_31_entry_t));
    799     sal_memset(&dlb_alt_port_members_32, 0,
    800             sizeof(dlb_ecmp_group_alt_port_members_32_to_47_entry_t));
    801     sal_memset(&dlb_alt_port_members_48, 0,
    802             sizeof(dlb_ecmp_group_alt_port_members_48_to_63_entry_t));
    803 
    804     WRITE_DLB_MEMBER_ALT_PORT_0_15(unit, 0, &dlb_alt_port_members,
    805                                 port_array[alt_nh_start], alt_count);
    806     WRITE_DLB_MEMBER_ALT_PORT_0_15(unit, 1, &dlb_alt_port_members,
    807                                 port_array[alt_nh_start + 1], alt_count);
    808     WRITE_DLB_MEMBER_ALT_PORT_0_15(unit, 2, &dlb_alt_port_members,
    809                                 port_array[alt_nh_start + 2], alt_count);
    810     WRITE_DLB_MEMBER_ALT_PORT_0_15(unit, 3, &dlb_alt_port_members,
    811                                    port_array[alt_nh_start + 3], alt_count);
    812     WRITE_DLB_MEMBER_ALT_PORT_0_15(unit, 4, &dlb_alt_port_members,
    813                                    port_array[alt_nh_start + 4], alt_count);
    814     WRITE_DLB_MEMBER_ALT_PORT_0_15(unit, 5, &dlb_alt_port_members,
    815                                    port_array[alt_nh_start + 5], alt_count);
    816     WRITE_DLB_MEMBER_ALT_PORT_0_15(unit, 6, &dlb_alt_port_members,
    817                                    port_array[alt_nh_start + 6], alt_count);
    818     WRITE_DLB_MEMBER_ALT_PORT_0_15(unit, 7, &dlb_alt_port_members,
    819                                    port_array[alt_nh_start + 7], alt_count);
    820     WRITE_DLB_MEMBER_ALT_PORT_0_15(unit, 8, &dlb_alt_port_members,
    821                                    port_array[alt_nh_start + 8], alt_count);
    822     WRITE_DLB_MEMBER_ALT_PORT_0_15(unit, 9, &dlb_alt_port_members,
    823                                    port_array[alt_nh_start + 9], alt_count);
    824     WRITE_DLB_MEMBER_ALT_PORT_0_15(unit, 10, &dlb_alt_port_members,
    825                                    port_array[alt_nh_start + 10], alt_count);
    826     WRITE_DLB_MEMBER_ALT_PORT_0_15(unit, 11, &dlb_alt_port_members,
    827                                    port_array[alt_nh_start + 11], alt_count);
    828     WRITE_DLB_MEMBER_ALT_PORT_0_15(unit, 12, &dlb_alt_port_members,
    829                                    port_array[alt_nh_start + 12], alt_count);
    830     WRITE_DLB_MEMBER_ALT_PORT_0_15(unit, 13, &dlb_alt_port_members,
    831                                    port_array[alt_nh_start + 13], alt_count);
    832     WRITE_DLB_MEMBER_ALT_PORT_0_15(unit, 14, &dlb_alt_port_members,
    833                                    port_array[alt_nh_start + 14], alt_count);
    834     WRITE_DLB_MEMBER_ALT_PORT_0_15(unit, 15, &dlb_alt_port_members,
    835                                    port_array[alt_nh_start + 15], alt_count);
    836     rv = soc_mem_write(unit, DLB_ECMP_GROUP_ALT_PORT_MEMBERS_0_TO_15m,
    837                        MEM_BLOCK_ALL, (dlb_id), &dlb_alt_port_members);
    838     WRITE_DLB_MEMBER_ALT_PORT_16_31(unit, 16, &dlb_alt_port_members_16,
    839                                    port_array[alt_nh_start + 16], alt_count);
    840     WRITE_DLB_MEMBER_ALT_PORT_16_31(unit, 17, &dlb_alt_port_members_16,
    841                                    port_array[alt_nh_start + 17], alt_count);
    842     WRITE_DLB_MEMBER_ALT_PORT_16_31(unit, 18, &dlb_alt_port_members_16,
    843                                    port_array[alt_nh_start + 18], alt_count);
    844     WRITE_DLB_MEMBER_ALT_PORT_16_31(unit, 19, &dlb_alt_port_members_16,
    845                                    port_array[alt_nh_start + 19], alt_count);
    846     WRITE_DLB_MEMBER_ALT_PORT_16_31(unit, 20, &dlb_alt_port_members_16,
    847                                    port_array[alt_nh_start + 20], alt_count);
    848     WRITE_DLB_MEMBER_ALT_PORT_16_31(unit, 21, &dlb_alt_port_members_16,
    849                                    port_array[alt_nh_start + 21], alt_count);
    850     WRITE_DLB_MEMBER_ALT_PORT_16_31(unit, 22, &dlb_alt_port_members_16,
    851                                    port_array[alt_nh_start + 22], alt_count);
    852     WRITE_DLB_MEMBER_ALT_PORT_16_31(unit, 23, &dlb_alt_port_members_16,
    853                                    port_array[alt_nh_start + 23], alt_count);
    854     WRITE_DLB_MEMBER_ALT_PORT_16_31(unit, 24, &dlb_alt_port_members_16,
    855                                    port_array[alt_nh_start + 24], alt_count);
    856     WRITE_DLB_MEMBER_ALT_PORT_16_31(unit, 25, &dlb_alt_port_members_16,
    857                                    port_array[alt_nh_start + 25], alt_count);
    858     WRITE_DLB_MEMBER_ALT_PORT_16_31(unit, 26, &dlb_alt_port_members_16,
    859                                    port_array[alt_nh_start + 26], alt_count);
    860     WRITE_DLB_MEMBER_ALT_PORT_16_31(unit, 27, &dlb_alt_port_members_16,
    861                                    port_array[alt_nh_start + 27], alt_count);
    862     WRITE_DLB_MEMBER_ALT_PORT_16_31(unit, 28, &dlb_alt_port_members_16,
    863                                    port_array[alt_nh_start + 28], alt_count);
    864     WRITE_DLB_MEMBER_ALT_PORT_16_31(unit, 29, &dlb_alt_port_members_16,
    865                                    port_array[alt_nh_start + 29], alt_count);
    866     WRITE_DLB_MEMBER_ALT_PORT_16_31(unit, 30, &dlb_alt_port_members_16,
    867                                    port_array[alt_nh_start + 30], alt_count);
    868     WRITE_DLB_MEMBER_ALT_PORT_16_31(unit, 31, &dlb_alt_port_members_16,
    869                                    port_array[alt_nh_start + 31], alt_count);
    870     rv = soc_mem_write(unit, DLB_ECMP_GROUP_ALT_PORT_MEMBERS_16_TO_31m,
    871                        MEM_BLOCK_ALL, (dlb_id), &dlb_alt_port_members_16);
    872     WRITE_DLB_MEMBER_ALT_PORT_32_47(unit, 32, &dlb_alt_port_members_32,
    873                                    port_array[alt_nh_start + 32], alt_count);
    874     WRITE_DLB_MEMBER_ALT_PORT_32_47(unit, 33, &dlb_alt_port_members_32,
    875                                    port_array[alt_nh_start + 33], alt_count);
    876     WRITE_DLB_MEMBER_ALT_PORT_32_47(unit, 34, &dlb_alt_port_members_32,
    877                                    port_array[alt_nh_start + 34], alt_count);
    878     WRITE_DLB_MEMBER_ALT_PORT_32_47(unit, 35, &dlb_alt_port_members_32,
    879                                    port_array[alt_nh_start + 35], alt_count);
    880     WRITE_DLB_MEMBER_ALT_PORT_32_47(unit, 36, &dlb_alt_port_members_32,
    881                                    port_array[alt_nh_start + 36], alt_count);
    882     WRITE_DLB_MEMBER_ALT_PORT_32_47(unit, 37, &dlb_alt_port_members_32,
    883                                    port_array[alt_nh_start + 37], alt_count);
    884     WRITE_DLB_MEMBER_ALT_PORT_32_47(unit, 38, &dlb_alt_port_members_32,
    885                                    port_array[alt_nh_start + 38], alt_count);
    886     WRITE_DLB_MEMBER_ALT_PORT_32_47(unit, 39, &dlb_alt_port_members_32,
    887                                    port_array[alt_nh_start + 39], alt_count);
    888     WRITE_DLB_MEMBER_ALT_PORT_32_47(unit, 40, &dlb_alt_port_members_32,
    889                                    port_array[alt_nh_start + 40], alt_count);
    890     WRITE_DLB_MEMBER_ALT_PORT_32_47(unit, 41, &dlb_alt_port_members_32,
    891                                    port_array[alt_nh_start + 41], alt_count);
    892     WRITE_DLB_MEMBER_ALT_PORT_32_47(unit, 42, &dlb_alt_port_members_32,
    893                                    port_array[alt_nh_start + 42], alt_count);
    894     WRITE_DLB_MEMBER_ALT_PORT_32_47(unit, 43, &dlb_alt_port_members_32,
    895                                    port_array[alt_nh_start + 43], alt_count);
    896     WRITE_DLB_MEMBER_ALT_PORT_32_47(unit, 44, &dlb_alt_port_members_32,
    897                                    port_array[alt_nh_start + 44], alt_count);
    898     WRITE_DLB_MEMBER_ALT_PORT_32_47(unit, 45, &dlb_alt_port_members_32,
    899                                    port_array[alt_nh_start + 45], alt_count);
    900     WRITE_DLB_MEMBER_ALT_PORT_32_47(unit, 46, &dlb_alt_port_members_32,
    901                                    port_array[alt_nh_start + 46], alt_count);
    902     WRITE_DLB_MEMBER_ALT_PORT_32_47(unit, 47, &dlb_alt_port_members_32,
    903                                    port_array[alt_nh_start + 47], alt_count);
    904     rv = soc_mem_write(unit, DLB_ECMP_GROUP_ALT_PORT_MEMBERS_32_TO_47m,
    905                        MEM_BLOCK_ALL, (dlb_id), &dlb_alt_port_members_32);
    906     WRITE_DLB_MEMBER_ALT_PORT_48_63(unit, 48, &dlb_alt_port_members_48,
    907                                    port_array[alt_nh_start + 48], alt_count);
    908     WRITE_DLB_MEMBER_ALT_PORT_48_63(unit, 49, &dlb_alt_port_members_48,
    909                                    port_array[alt_nh_start + 49], alt_count);
    910     WRITE_DLB_MEMBER_ALT_PORT_48_63(unit, 50, &dlb_alt_port_members_48,
    911                                    port_array[alt_nh_start + 50], alt_count);
    912     WRITE_DLB_MEMBER_ALT_PORT_48_63(unit, 51, &dlb_alt_port_members_48,
    913                                    port_array[alt_nh_start + 51], alt_count);
    914     WRITE_DLB_MEMBER_ALT_PORT_48_63(unit, 52, &dlb_alt_port_members_48,
    915                                    port_array[alt_nh_start + 52], alt_count);
    916     WRITE_DLB_MEMBER_ALT_PORT_48_63(unit, 53, &dlb_alt_port_members_48,
    917                                    port_array[alt_nh_start + 53], alt_count);
    918     WRITE_DLB_MEMBER_ALT_PORT_48_63(unit, 54, &dlb_alt_port_members_48,
    919                                    port_array[alt_nh_start + 54], alt_count);
    920     WRITE_DLB_MEMBER_ALT_PORT_48_63(unit, 55, &dlb_alt_port_members_48,
    921                                    port_array[alt_nh_start + 55], alt_count);
    922     WRITE_DLB_MEMBER_ALT_PORT_48_63(unit, 56, &dlb_alt_port_members_48,
    923                                    port_array[alt_nh_start + 56], alt_count);
    924     WRITE_DLB_MEMBER_ALT_PORT_48_63(unit, 57, &dlb_alt_port_members_48,
    925                                    port_array[alt_nh_start + 57], alt_count);
    926     WRITE_DLB_MEMBER_ALT_PORT_48_63(unit, 58, &dlb_alt_port_members_48,
    927                                    port_array[alt_nh_start + 58], alt_count);
    928     WRITE_DLB_MEMBER_ALT_PORT_48_63(unit, 59, &dlb_alt_port_members_48,
    929                                    port_array[alt_nh_start + 59], alt_count);
    930     WRITE_DLB_MEMBER_ALT_PORT_48_63(unit, 60, &dlb_alt_port_members_48,
    931                                    port_array[alt_nh_start + 60], alt_count);
    932     WRITE_DLB_MEMBER_ALT_PORT_48_63(unit, 61, &dlb_alt_port_members_48,
    933                                    port_array[alt_nh_start + 61], alt_count);
    934     WRITE_DLB_MEMBER_ALT_PORT_48_63(unit, 62, &dlb_alt_port_members_48,
    935                                    port_array[alt_nh_start + 62], alt_count);
    936     WRITE_DLB_MEMBER_ALT_PORT_48_63(unit, 63, &dlb_alt_port_members_48,
    937                                    port_array[alt_nh_start + 63], alt_count);
    938     rv = soc_mem_write(unit, DLB_ECMP_GROUP_ALT_PORT_MEMBERS_48_TO_63m,
    939                        MEM_BLOCK_ALL, (dlb_id), &dlb_alt_port_members_48);
    940     return rv;
    941 }
    942 
    943 /*
    944  * Function:
    945  *      _bcm_th2_ecmp_dlb_nhi_member_set
    946  * Purpose:
    947  *      Set dlb port numbers corresponding to each ecmp member NH.
    948  * Parameters:
    949  *      unit            - (IN) SOC unit number.
    950  *      intf_array      - (IN) intf array for each NH.
    951  *      intf_count      - (IN) INTF count.
    952  *      primary_count   - (IN) Primary INTF count.
    953  *      dlb_id          - (IN) DLB group id.
    954  * Returns:
    955  *      BCM_E_xxx
    956  */
    957 int
    958 _bcm_th3_l3_ecmp_dlb_nhi_member_set(int unit, int *intf_array, int primary_count, int unique_intfs, int dlb_id)
    959 {
    960     int alt_nh_start;
    961     int rv = BCM_E_NONE;
    962     int alt_count = unique_intfs - primary_count;
    963 
    964     dlb_ecmp_group_nhi_members_0_to_12_entry_t dlb_nhi_members;
    965     dlb_ecmp_group_nhi_members_13_to_25_entry_t dlb_nhi_members_13;
    966     dlb_ecmp_group_nhi_members_26_to_38_entry_t dlb_nhi_members_26;
    967     dlb_ecmp_group_nhi_members_39_to_51_entry_t dlb_nhi_members_39;
    968     dlb_ecmp_group_nhi_members_52_to_63_entry_t dlb_nhi_members_52;
    969 
    970     dlb_ecmp_group_alt_nhi_members_0_to_12_entry_t dlb_alt_nhi_members;
    971     dlb_ecmp_group_alt_nhi_members_13_to_25_entry_t dlb_alt_nhi_members_13;
    972     dlb_ecmp_group_alt_nhi_members_26_to_38_entry_t dlb_alt_nhi_members_26;
    973     dlb_ecmp_group_alt_nhi_members_39_to_51_entry_t dlb_alt_nhi_members_39;
    974     dlb_ecmp_group_alt_nhi_members_52_to_63_entry_t dlb_alt_nhi_members_52;
    975 
    976     sal_memset(&dlb_nhi_members, 0,
    977             sizeof(dlb_ecmp_group_nhi_members_0_to_12_entry_t));
    978     sal_memset(&dlb_nhi_members_13, 0,
    979             sizeof(dlb_ecmp_group_nhi_members_13_to_25_entry_t));
    980     sal_memset(&dlb_nhi_members_26, 0,
    981             sizeof(dlb_ecmp_group_nhi_members_26_to_38_entry_t));
    982     sal_memset(&dlb_nhi_members_39, 0,
    983             sizeof(dlb_ecmp_group_nhi_members_39_to_51_entry_t));
    984     sal_memset(&dlb_nhi_members_52, 0,
    985             sizeof(dlb_ecmp_group_nhi_members_52_to_63_entry_t));
    986 
    987     WRITE_DLB_MEMBER_NHI_0_12(unit, 0, &dlb_nhi_members,
    988             (intf_array[0] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
    989     WRITE_DLB_MEMBER_NHI_0_12(unit, 1, &dlb_nhi_members,
    990             (intf_array[1] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
    991     WRITE_DLB_MEMBER_NHI_0_12(unit, 2, &dlb_nhi_members,
    992             (intf_array[2] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
    993     WRITE_DLB_MEMBER_NHI_0_12(unit, 3, &dlb_nhi_members,
    994             (intf_array[3] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
    995     WRITE_DLB_MEMBER_NHI_0_12(unit, 4, &dlb_nhi_members,
    996             (intf_array[4] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
    997     WRITE_DLB_MEMBER_NHI_0_12(unit, 5, &dlb_nhi_members,
    998             (intf_array[5] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
    999     WRITE_DLB_MEMBER_NHI_0_12(unit, 6, &dlb_nhi_members,
   1000             (intf_array[6] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
   1001     WRITE_DLB_MEMBER_NHI_0_12(unit, 7, &dlb_nhi_members,
   1002             (intf_array[7] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
   1003     WRITE_DLB_MEMBER_NHI_0_12(unit, 8, &dlb_nhi_members,
   1004             (intf_array[8] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
   1005     WRITE_DLB_MEMBER_NHI_0_12(unit, 9, &dlb_nhi_members,
   1006             (intf_array[9] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
   1007     WRITE_DLB_MEMBER_NHI_0_12(unit, 10, &dlb_nhi_members,
   1008             (intf_array[10] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
   1009     WRITE_DLB_MEMBER_NHI_0_12(unit, 11, &dlb_nhi_members,
   1010             (intf_array[11] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
   1011     WRITE_DLB_MEMBER_NHI_0_12(unit, 12, &dlb_nhi_members,
   1012             (intf_array[12] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
   1013     rv = soc_mem_write(unit, DLB_ECMP_GROUP_NHI_MEMBERS_0_TO_12m,
   1014                        MEM_BLOCK_ALL, (dlb_id), &dlb_nhi_members);
   1015     WRITE_DLB_MEMBER_NHI_13_25(unit, 13, &dlb_nhi_members_13,
   1016             (intf_array[13] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
   1017     WRITE_DLB_MEMBER_NHI_13_25(unit, 14, &dlb_nhi_members_13,
   1018             (intf_array[14] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
   1019     WRITE_DLB_MEMBER_NHI_13_25(unit, 15, &dlb_nhi_members_13,
   1020             (intf_array[15] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
   1021     WRITE_DLB_MEMBER_NHI_13_25(unit, 15, &dlb_nhi_members_13,
   1022             (intf_array[15] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
   1023     WRITE_DLB_MEMBER_NHI_13_25(unit, 16, &dlb_nhi_members_13,
   1024             (intf_array[16] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
   1025     WRITE_DLB_MEMBER_NHI_13_25(unit, 17, &dlb_nhi_members_13,
   1026             (intf_array[17] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
   1027     WRITE_DLB_MEMBER_NHI_13_25(unit, 18, &dlb_nhi_members_13,
   1028             (intf_array[18] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
   1029     WRITE_DLB_MEMBER_NHI_13_25(unit, 19, &dlb_nhi_members_13,
   1030             (intf_array[19] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
   1031     WRITE_DLB_MEMBER_NHI_13_25(unit, 20, &dlb_nhi_members_13,
   1032             (intf_array[20] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
   1033     WRITE_DLB_MEMBER_NHI_13_25(unit, 21, &dlb_nhi_members_13,
   1034             (intf_array[21] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
   1035     WRITE_DLB_MEMBER_NHI_13_25(unit, 22, &dlb_nhi_members_13,
   1036             (intf_array[22] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
   1037     WRITE_DLB_MEMBER_NHI_13_25(unit, 23, &dlb_nhi_members_13,
   1038             (intf_array[23] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
   1039     WRITE_DLB_MEMBER_NHI_13_25(unit, 24, &dlb_nhi_members_13,
   1040             (intf_array[24] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
   1041     WRITE_DLB_MEMBER_NHI_13_25(unit, 25, &dlb_nhi_members_13,
   1042             (intf_array[25] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
   1043     rv = soc_mem_write(unit, DLB_ECMP_GROUP_NHI_MEMBERS_13_TO_25m,
   1044                        MEM_BLOCK_ALL, (dlb_id), &dlb_nhi_members_13);
   1045     WRITE_DLB_MEMBER_NHI_26_38(unit, 26, &dlb_nhi_members_26,
   1046             (intf_array[26] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
   1047     WRITE_DLB_MEMBER_NHI_26_38(unit, 27, &dlb_nhi_members_26,
   1048             (intf_array[27] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
   1049     WRITE_DLB_MEMBER_NHI_26_38(unit, 28, &dlb_nhi_members_26,
   1050             (intf_array[28] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
   1051     WRITE_DLB_MEMBER_NHI_26_38(unit, 29, &dlb_nhi_members_26,
   1052             (intf_array[29] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
   1053     WRITE_DLB_MEMBER_NHI_26_38(unit, 30, &dlb_nhi_members_26,
   1054             (intf_array[30] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
   1055     WRITE_DLB_MEMBER_NHI_26_38(unit, 31, &dlb_nhi_members_26,
   1056             (intf_array[31] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
   1057     WRITE_DLB_MEMBER_NHI_26_38(unit, 32, &dlb_nhi_members_26,
   1058             (intf_array[32] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
   1059     WRITE_DLB_MEMBER_NHI_26_38(unit, 33, &dlb_nhi_members_26,
   1060             (intf_array[33] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
   1061     WRITE_DLB_MEMBER_NHI_26_38(unit, 34, &dlb_nhi_members_26,
   1062             (intf_array[34] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
   1063     WRITE_DLB_MEMBER_NHI_26_38(unit, 35, &dlb_nhi_members_26,
   1064             (intf_array[35] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
   1065     WRITE_DLB_MEMBER_NHI_26_38(unit, 36, &dlb_nhi_members_26,
   1066             (intf_array[36] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
   1067     WRITE_DLB_MEMBER_NHI_26_38(unit, 37, &dlb_nhi_members_26,
   1068             (intf_array[37] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
   1069     WRITE_DLB_MEMBER_NHI_26_38(unit, 38, &dlb_nhi_members_26,
   1070             (intf_array[38] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
   1071     rv = soc_mem_write(unit, DLB_ECMP_GROUP_NHI_MEMBERS_26_TO_38m,
   1072                        MEM_BLOCK_ALL, (dlb_id), &dlb_nhi_members_26);
   1073     WRITE_DLB_MEMBER_NHI_39_51(unit, 39, &dlb_nhi_members_39,
   1074             (intf_array[39] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
   1075     WRITE_DLB_MEMBER_NHI_39_51(unit, 40, &dlb_nhi_members_39,
   1076             (intf_array[40] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
   1077     WRITE_DLB_MEMBER_NHI_39_51(unit, 41, &dlb_nhi_members_39,
   1078             (intf_array[41] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
   1079     WRITE_DLB_MEMBER_NHI_39_51(unit, 42, &dlb_nhi_members_39,
   1080             (intf_array[42] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
   1081     WRITE_DLB_MEMBER_NHI_39_51(unit, 43, &dlb_nhi_members_39,
   1082             (intf_array[43] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
   1083     WRITE_DLB_MEMBER_NHI_39_51(unit, 44, &dlb_nhi_members_39,
   1084             (intf_array[44] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
   1085     WRITE_DLB_MEMBER_NHI_39_51(unit, 45, &dlb_nhi_members_39,
   1086             (intf_array[45] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
   1087     WRITE_DLB_MEMBER_NHI_39_51(unit, 46, &dlb_nhi_members_39,
   1088             (intf_array[46] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
   1089     WRITE_DLB_MEMBER_NHI_39_51(unit, 47, &dlb_nhi_members_39,
   1090             (intf_array[47] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
   1091     WRITE_DLB_MEMBER_NHI_39_51(unit, 48, &dlb_nhi_members_39,
   1092             (intf_array[48] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
   1093     WRITE_DLB_MEMBER_NHI_39_51(unit, 49, &dlb_nhi_members_39,
   1094             (intf_array[49] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
   1095     WRITE_DLB_MEMBER_NHI_39_51(unit, 50, &dlb_nhi_members_39,
   1096             (intf_array[50] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
   1097     WRITE_DLB_MEMBER_NHI_39_51(unit, 51, &dlb_nhi_members_39,
   1098             (intf_array[51] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
   1099     rv = soc_mem_write(unit, DLB_ECMP_GROUP_NHI_MEMBERS_39_TO_51m,
   1100                        MEM_BLOCK_ALL, (dlb_id), &dlb_nhi_members_39);
   1101     WRITE_DLB_MEMBER_NHI_52_63(unit, 52, &dlb_nhi_members_52,
   1102             (intf_array[52] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
   1103     WRITE_DLB_MEMBER_NHI_52_63(unit, 53, &dlb_nhi_members_52,
   1104             (intf_array[53] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
   1105     WRITE_DLB_MEMBER_NHI_52_63(unit, 54, &dlb_nhi_members_52,
   1106             (intf_array[54] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
   1107     WRITE_DLB_MEMBER_NHI_52_63(unit, 55, &dlb_nhi_members_52,
   1108             (intf_array[55] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
   1109     WRITE_DLB_MEMBER_NHI_52_63(unit, 56, &dlb_nhi_members_52,
   1110             (intf_array[56] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
   1111     WRITE_DLB_MEMBER_NHI_52_63(unit, 57, &dlb_nhi_members_52,
   1112             (intf_array[57] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
   1113     WRITE_DLB_MEMBER_NHI_52_63(unit, 58, &dlb_nhi_members_52,
   1114             (intf_array[58] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
   1115     WRITE_DLB_MEMBER_NHI_52_63(unit, 59, &dlb_nhi_members_52,
   1116             (intf_array[59] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
   1117     WRITE_DLB_MEMBER_NHI_52_63(unit, 60, &dlb_nhi_members_52,
   1118             (intf_array[60] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
   1119     WRITE_DLB_MEMBER_NHI_52_63(unit, 61, &dlb_nhi_members_52,
   1120             (intf_array[61] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
   1121     WRITE_DLB_MEMBER_NHI_52_63(unit, 62, &dlb_nhi_members_52,
   1122             (intf_array[62] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
   1123     WRITE_DLB_MEMBER_NHI_52_63(unit, 63, &dlb_nhi_members_52,
   1124             (intf_array[63] - BCM_XGS3_EGRESS_IDX_MIN(unit)), primary_count);
   1125     rv = soc_mem_write(unit, DLB_ECMP_GROUP_NHI_MEMBERS_52_TO_63m,
   1126                        MEM_BLOCK_ALL, (dlb_id), &dlb_nhi_members_52);
   1127 
   1128     if (alt_count <= 0) {
   1129         return rv;
   1130     }
   1131     alt_nh_start = primary_count;
   1132 
   1133     sal_memset(&dlb_alt_nhi_members, 0,
   1134             sizeof(dlb_ecmp_group_alt_nhi_members_0_to_12_entry_t));
   1135     sal_memset(&dlb_alt_nhi_members_13, 0,
   1136             sizeof(dlb_ecmp_group_alt_nhi_members_13_to_25_entry_t));
   1137     sal_memset(&dlb_alt_nhi_members_26, 0,
   1138             sizeof(dlb_ecmp_group_alt_nhi_members_26_to_38_entry_t));
   1139     sal_memset(&dlb_alt_nhi_members_39, 0,
   1140             sizeof(dlb_ecmp_group_alt_nhi_members_39_to_51_entry_t));
   1141     sal_memset(&dlb_alt_nhi_members_52, 0,
   1142             sizeof(dlb_ecmp_group_alt_nhi_members_52_to_63_entry_t));
   1143 
   1144     WRITE_DLB_MEMBER_ALT_NHI_0_12(unit, 0, &dlb_alt_nhi_members,
   1145        (intf_array[alt_nh_start] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1146     WRITE_DLB_MEMBER_ALT_NHI_0_12(unit, 1, &dlb_alt_nhi_members,
   1147        (intf_array[alt_nh_start + 1] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1148     WRITE_DLB_MEMBER_ALT_NHI_0_12(unit, 2, &dlb_alt_nhi_members,
   1149        (intf_array[alt_nh_start + 2] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1150     WRITE_DLB_MEMBER_ALT_NHI_0_12(unit, 3, &dlb_alt_nhi_members,
   1151        (intf_array[alt_nh_start + 3] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1152     WRITE_DLB_MEMBER_ALT_NHI_0_12(unit, 4, &dlb_alt_nhi_members,
   1153        (intf_array[alt_nh_start + 4] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1154     WRITE_DLB_MEMBER_ALT_NHI_0_12(unit, 5, &dlb_alt_nhi_members,
   1155        (intf_array[alt_nh_start + 5] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1156     WRITE_DLB_MEMBER_ALT_NHI_0_12(unit, 6, &dlb_alt_nhi_members,
   1157        (intf_array[alt_nh_start + 6] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1158     WRITE_DLB_MEMBER_ALT_NHI_0_12(unit, 7, &dlb_alt_nhi_members,
   1159        (intf_array[alt_nh_start + 7] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1160     WRITE_DLB_MEMBER_ALT_NHI_0_12(unit, 8, &dlb_alt_nhi_members,
   1161        (intf_array[alt_nh_start + 8] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1162     WRITE_DLB_MEMBER_ALT_NHI_0_12(unit, 9, &dlb_alt_nhi_members,
   1163        (intf_array[alt_nh_start + 9] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1164     WRITE_DLB_MEMBER_ALT_NHI_0_12(unit, 10, &dlb_alt_nhi_members,
   1165        (intf_array[alt_nh_start + 10] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1166     WRITE_DLB_MEMBER_ALT_NHI_0_12(unit, 11, &dlb_alt_nhi_members,
   1167        (intf_array[alt_nh_start + 11] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1168     WRITE_DLB_MEMBER_ALT_NHI_0_12(unit, 12, &dlb_alt_nhi_members,
   1169        (intf_array[alt_nh_start + 12] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1170     rv = soc_mem_write(unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_0_TO_12m,
   1171                        MEM_BLOCK_ALL, (dlb_id), &dlb_alt_nhi_members);
   1172     WRITE_DLB_MEMBER_ALT_NHI_13_25(unit, 13, &dlb_alt_nhi_members_13,
   1173        (intf_array[alt_nh_start + 13] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1174     WRITE_DLB_MEMBER_ALT_NHI_13_25(unit, 14, &dlb_alt_nhi_members_13,
   1175        (intf_array[alt_nh_start + 14] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1176     WRITE_DLB_MEMBER_ALT_NHI_13_25(unit, 15, &dlb_alt_nhi_members_13,
   1177        (intf_array[alt_nh_start + 15] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1178     WRITE_DLB_MEMBER_ALT_NHI_13_25(unit, 15, &dlb_alt_nhi_members_13,
   1179        (intf_array[alt_nh_start + 15] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1180     WRITE_DLB_MEMBER_ALT_NHI_13_25(unit, 16, &dlb_alt_nhi_members_13,
   1181        (intf_array[alt_nh_start + 16] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1182     WRITE_DLB_MEMBER_ALT_NHI_13_25(unit, 17, &dlb_alt_nhi_members_13,
   1183        (intf_array[alt_nh_start + 17] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1184     WRITE_DLB_MEMBER_ALT_NHI_13_25(unit, 18, &dlb_alt_nhi_members_13,
   1185        (intf_array[alt_nh_start + 18] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1186     WRITE_DLB_MEMBER_ALT_NHI_13_25(unit, 19, &dlb_alt_nhi_members_13,
   1187        (intf_array[alt_nh_start + 19] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1188     WRITE_DLB_MEMBER_ALT_NHI_13_25(unit, 20, &dlb_alt_nhi_members_13,
   1189        (intf_array[alt_nh_start + 20] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1190     WRITE_DLB_MEMBER_ALT_NHI_13_25(unit, 21, &dlb_alt_nhi_members_13,
   1191        (intf_array[alt_nh_start + 21] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1192     WRITE_DLB_MEMBER_ALT_NHI_13_25(unit, 22, &dlb_alt_nhi_members_13,
   1193        (intf_array[alt_nh_start + 22] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1194     WRITE_DLB_MEMBER_ALT_NHI_13_25(unit, 23, &dlb_alt_nhi_members_13,
   1195        (intf_array[alt_nh_start + 23] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1196     WRITE_DLB_MEMBER_ALT_NHI_13_25(unit, 24, &dlb_alt_nhi_members_13,
   1197        (intf_array[alt_nh_start + 24] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1198     WRITE_DLB_MEMBER_ALT_NHI_13_25(unit, 25, &dlb_alt_nhi_members_13,
   1199        (intf_array[alt_nh_start + 25] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1200     rv = soc_mem_write(unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_13_TO_25m,
   1201                        MEM_BLOCK_ALL, (dlb_id), &dlb_alt_nhi_members_13);
   1202     WRITE_DLB_MEMBER_ALT_NHI_26_38(unit, 26, &dlb_alt_nhi_members_26,
   1203        (intf_array[alt_nh_start + 26] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1204     WRITE_DLB_MEMBER_ALT_NHI_26_38(unit, 27, &dlb_alt_nhi_members_26,
   1205        (intf_array[alt_nh_start + 27] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1206     WRITE_DLB_MEMBER_ALT_NHI_26_38(unit, 28, &dlb_alt_nhi_members_26,
   1207        (intf_array[alt_nh_start + 28] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1208     WRITE_DLB_MEMBER_ALT_NHI_26_38(unit, 29, &dlb_alt_nhi_members_26,
   1209        (intf_array[alt_nh_start + 29] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1210     WRITE_DLB_MEMBER_ALT_NHI_26_38(unit, 30, &dlb_alt_nhi_members_26,
   1211        (intf_array[alt_nh_start + 30] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1212     WRITE_DLB_MEMBER_ALT_NHI_26_38(unit, 31, &dlb_alt_nhi_members_26,
   1213        (intf_array[alt_nh_start + 31] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1214     WRITE_DLB_MEMBER_ALT_NHI_26_38(unit, 32, &dlb_alt_nhi_members_26,
   1215        (intf_array[alt_nh_start + 32] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1216     WRITE_DLB_MEMBER_ALT_NHI_26_38(unit, 33, &dlb_alt_nhi_members_26,
   1217        (intf_array[alt_nh_start + 33] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1218     WRITE_DLB_MEMBER_ALT_NHI_26_38(unit, 34, &dlb_alt_nhi_members_26,
   1219        (intf_array[alt_nh_start + 34] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1220     WRITE_DLB_MEMBER_ALT_NHI_26_38(unit, 35, &dlb_alt_nhi_members_26,
   1221        (intf_array[alt_nh_start + 35] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1222     WRITE_DLB_MEMBER_ALT_NHI_26_38(unit, 36, &dlb_alt_nhi_members_26,
   1223        (intf_array[alt_nh_start + 36] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1224     WRITE_DLB_MEMBER_ALT_NHI_26_38(unit, 37, &dlb_alt_nhi_members_26,
   1225        (intf_array[alt_nh_start + 37] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1226     WRITE_DLB_MEMBER_ALT_NHI_26_38(unit, 38, &dlb_alt_nhi_members_26,
   1227        (intf_array[alt_nh_start + 38] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1228     rv = soc_mem_write(unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_26_TO_38m,
   1229                        MEM_BLOCK_ALL, (dlb_id), &dlb_alt_nhi_members_26);
   1230     WRITE_DLB_MEMBER_ALT_NHI_39_51(unit, 39, &dlb_alt_nhi_members_39,
   1231        (intf_array[alt_nh_start + 39] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1232     WRITE_DLB_MEMBER_ALT_NHI_39_51(unit, 40, &dlb_alt_nhi_members_39,
   1233        (intf_array[alt_nh_start + 40] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1234     WRITE_DLB_MEMBER_ALT_NHI_39_51(unit, 41, &dlb_alt_nhi_members_39,
   1235        (intf_array[alt_nh_start + 41] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1236     WRITE_DLB_MEMBER_ALT_NHI_39_51(unit, 42, &dlb_alt_nhi_members_39,
   1237        (intf_array[alt_nh_start + 42] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1238     WRITE_DLB_MEMBER_ALT_NHI_39_51(unit, 43, &dlb_alt_nhi_members_39,
   1239        (intf_array[alt_nh_start + 43] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1240     WRITE_DLB_MEMBER_ALT_NHI_39_51(unit, 44, &dlb_alt_nhi_members_39,
   1241        (intf_array[alt_nh_start + 44] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1242     WRITE_DLB_MEMBER_ALT_NHI_39_51(unit, 45, &dlb_alt_nhi_members_39,
   1243        (intf_array[alt_nh_start + 45] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1244     WRITE_DLB_MEMBER_ALT_NHI_39_51(unit, 46, &dlb_alt_nhi_members_39,
   1245        (intf_array[alt_nh_start + 46] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1246     WRITE_DLB_MEMBER_ALT_NHI_39_51(unit, 47, &dlb_alt_nhi_members_39,
   1247        (intf_array[alt_nh_start + 47] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1248     WRITE_DLB_MEMBER_ALT_NHI_39_51(unit, 48, &dlb_alt_nhi_members_39,
   1249        (intf_array[alt_nh_start + 48] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1250     WRITE_DLB_MEMBER_ALT_NHI_39_51(unit, 49, &dlb_alt_nhi_members_39,
   1251        (intf_array[alt_nh_start + 49] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1252     WRITE_DLB_MEMBER_ALT_NHI_39_51(unit, 50, &dlb_alt_nhi_members_39,
   1253        (intf_array[alt_nh_start + 50] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1254     WRITE_DLB_MEMBER_ALT_NHI_39_51(unit, 51, &dlb_alt_nhi_members_39,
   1255        (intf_array[alt_nh_start + 51] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1256     rv = soc_mem_write(unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_39_TO_51m,
   1257                        MEM_BLOCK_ALL, (dlb_id), &dlb_alt_nhi_members_39);
   1258     WRITE_DLB_MEMBER_ALT_NHI_52_63(unit, 52, &dlb_alt_nhi_members_52,
   1259        (intf_array[alt_nh_start + 52] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1260     WRITE_DLB_MEMBER_ALT_NHI_52_63(unit, 53, &dlb_alt_nhi_members_52,
   1261        (intf_array[alt_nh_start + 53] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1262     WRITE_DLB_MEMBER_ALT_NHI_52_63(unit, 54, &dlb_alt_nhi_members_52,
   1263        (intf_array[alt_nh_start + 54] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1264     WRITE_DLB_MEMBER_ALT_NHI_52_63(unit, 55, &dlb_alt_nhi_members_52,
   1265        (intf_array[alt_nh_start + 55] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1266     WRITE_DLB_MEMBER_ALT_NHI_52_63(unit, 56, &dlb_alt_nhi_members_52,
   1267        (intf_array[alt_nh_start + 56] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1268     WRITE_DLB_MEMBER_ALT_NHI_52_63(unit, 57, &dlb_alt_nhi_members_52,
   1269        (intf_array[alt_nh_start + 57] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1270     WRITE_DLB_MEMBER_ALT_NHI_52_63(unit, 58, &dlb_alt_nhi_members_52,
   1271        (intf_array[alt_nh_start + 58] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1272     WRITE_DLB_MEMBER_ALT_NHI_52_63(unit, 59, &dlb_alt_nhi_members_52,
   1273        (intf_array[alt_nh_start + 59] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1274     WRITE_DLB_MEMBER_ALT_NHI_52_63(unit, 60, &dlb_alt_nhi_members_52,
   1275        (intf_array[alt_nh_start + 60] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1276     WRITE_DLB_MEMBER_ALT_NHI_52_63(unit, 61, &dlb_alt_nhi_members_52,
   1277        (intf_array[alt_nh_start + 61] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1278     WRITE_DLB_MEMBER_ALT_NHI_52_63(unit, 62, &dlb_alt_nhi_members_52,
   1279        (intf_array[alt_nh_start + 62] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1280     WRITE_DLB_MEMBER_ALT_NHI_52_63(unit, 63, &dlb_alt_nhi_members_52,
   1281        (intf_array[alt_nh_start + 63] - BCM_XGS3_EGRESS_IDX_MIN(unit)), alt_count);
   1282     rv = soc_mem_write(unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_52_TO_63m,
   1283                        MEM_BLOCK_ALL, (dlb_id), &dlb_alt_nhi_members_52);
   1284 
   1285     return rv;
   1286 }
   1287 
   1288 /*
   1289  * Function:
   1290  *      _bcm_th3_l3_ecmp_dlb_scaling_factor_encode
   1291  * Purpose:
   1292  *      Check valid scaling factors, and encode them.
   1293  * Parameters:
   1294  *      unit            - (IN) SOC unit number.
   1295  *      scaling_factor  - (IN) Threshold scaling factor.
   1296  * Returns:
   1297  *      1: check success
   1298  *      0: check fail
   1299  */
   1300 int
   1301 _bcm_th3_l3_ecmp_dlb_scaling_factor_encode(int unit, int scaling_factor,
   1302                                         int *scaling_factor_hw)
   1303 {
   1304     int bcm_factors[] = {10, 25, 40, 50, 75, 100, 200, 400};
   1305     int hw_factors[]  = { 0,  1,  2,  3,  4,   5,   6,   7};
   1306     int i;
   1307 
   1308     for (i = 0; i < COUNTOF(bcm_factors); i++ ) {
   1309         if (scaling_factor == bcm_factors[i]) {
   1310             break;
   1311         }
   1312     }
   1313 
   1314     if (i < COUNTOF(hw_factors)) {
   1315         if (scaling_factor_hw) {
   1316             *scaling_factor_hw = hw_factors[i];
   1317         }
   1318         return 1;
   1319     }
   1320     return 0;
   1321 }
   1322 
   1323 
   1324 /*
   1325  * Function:
   1326  *      _bcm_th3_l3_ecmp_dlb_scaling_factor_decode
   1327  * Purpose:
   1328  *      Decode scaling factors.
   1329  * Parameters:
   1330  *      unit            - (IN) SOC unit number.
   1331  *      scaling_factor  - (IN) Threshold scaling factor.
   1332  * Returns:
   1333  *      BCM_E_xxx
   1334  */
   1335 int
   1336 _bcm_th3_l3_ecmp_dlb_scaling_factor_decode(int unit, int scaling_factor_hw,
   1337                                         int *scaling_factor)
   1338 {
   1339     int bcm_factors[] = {10, 25, 40, 50, 75, 100, 200, 400};
   1340     int hw_factors[]  = { 0,  1,  2,  3,  4,   5,   6,   7};
   1341     int i;
   1342 
   1343     for (i = 0; i < COUNTOF(hw_factors); i++ ) {
   1344         if (scaling_factor_hw == hw_factors[i]) {
   1345             break;
   1346         }
   1347     }
   1348 
   1349     if (i == COUNTOF(hw_factors)) {
   1350         return BCM_E_INTERNAL;
   1351     }
   1352 
   1353     *scaling_factor = bcm_factors[i];
   1354     return BCM_E_NONE;
   1355 }
   1356 
   1357 /*
   1358  * Function:
   1359  *      bcm_th3_l3_ecmp_dlb_mon_config_set
   1360  * Purpose:
   1361  *      This function configures DLB flow monitoring parameters for a DLB id
   1362  *      derived from ECMP group id (the second argument). Property
   1363  *      spn_DLB_FLOW_MONITOR_EN must be enabled before invoking this function.
   1364  *      See Notes.
   1365  * Parameters:
   1366  *      unit :        (IN) Device's unit number
   1367  *      ecmp_intf :   (IN) ECMP interface id obtained from bcm_l3_ecmp_create or
   1368  *                         bcm_l3_egress_ecmp_create
   1369  *      dlb_mon_cfg : (IN) DLB flow monitoring configuration
   1370  * Returns:
   1371  *      BCM_E_XXX
   1372  * Notes:
   1373  *      If 'sample_rate' is specified as 0, monitoring will not be enabled,
   1374  *      irrespective of 'enable' setting in 'dlb_mon_cfg'.
   1375  */
   1376 int
   1377 bcm_th3_l3_ecmp_dlb_mon_config_set(int unit,
   1378                                    bcm_if_t ecmp_intf,
   1379                                    bcm_l3_ecmp_dlb_mon_cfg_t *dlb_mon_cfg)
   1380 {
   1381     int dlb_id;
   1382     int dlb_mode;
   1383     uint64 dlb_en_bitmap;
   1384     uint32 dlb_enabled;
   1385     dlb_ecmp_group_control_entry_t dlb_ecmp_group_control_entry;
   1386     uint32 threshold = 0;
   1387     uint32 enable = 0;
   1388     uint32 copy_to_cpu = 0;
   1389     uint32 mirror = 0;
   1390     dlb_ecmp_group_monitor_control_entry_t mon_ctrl;
   1391     int max_val;
   1392     int ecmp_group_idx;
   1393 
   1394     /* If application has not defined this feature, or not enabled this feature,
   1395      * return error
   1396      */
   1397     if (!soc_property_get(unit, spn_DLB_FLOW_MONITOR_EN, 0)) {
   1398         return BCM_E_UNAVAIL;
   1399     }
   1400 
   1401     if (dlb_mon_cfg == NULL) {
   1402         return BCM_E_PARAM;
   1403     }
   1404 
   1405     ecmp_group_idx = ecmp_intf - BCM_XGS3_MPATH_EGRESS_IDX_MIN(unit);
   1406     if (ecmp_group_idx < BCM_TH3_L3_ECMP_DLB_START(unit)) {
   1407         return BCM_E_CONFIG;
   1408     }
   1409 
   1410     /* Get the DLB id associated with the Ecmp group */
   1411     dlb_id = _bcm_th3_l3_ecmp_dlb_get_id(unit, ecmp_group_idx);
   1412 
   1413     /* DLB id of 0 is not supported for DLB flow monitoring. If we obtained
   1414      * it (0), return error
   1415      */
   1416     if (dlb_id == 0) {
   1417         return BCM_E_INTERNAL;
   1418     }
   1419 
   1420     /* Check if the DLB obtained is in enabled state */
   1421     if (dlb_id < soc_reg_field_length(unit, DLB_ID_0_TO_63_ENABLEr, BITMAPf)) {
   1422         SOC_IF_ERROR_RETURN( \
   1423           READ_DLB_ID_0_TO_63_ENABLEr(unit, &dlb_en_bitmap));
   1424         dlb_enabled = COMPILER_64_BITTEST(dlb_en_bitmap, dlb_id);
   1425     } else {
   1426         SOC_IF_ERROR_RETURN( \
   1427           READ_DLB_ID_64_TO_127_ENABLEr(unit, &dlb_en_bitmap));
   1428          dlb_enabled = COMPILER_64_BITTEST(dlb_en_bitmap, dlb_id -
   1429                                (soc_reg_field_length(unit,
   1430                                DLB_ID_64_TO_127_ENABLEr, BITMAPf)));
   1431     }
   1432 
   1433     if (!dlb_enabled) {
   1434         return BCM_E_CONFIG;
   1435     }
   1436 
   1437     /* Get DLB operational mode */
   1438     BCM_IF_ERROR_RETURN(READ_DLB_ECMP_GROUP_CONTROLm(unit, MEM_BLOCK_ANY,
   1439                             dlb_id, &dlb_ecmp_group_control_entry));
   1440 
   1441     dlb_mode = soc_DLB_ECMP_GROUP_CONTROLm_field32_get(unit,
   1442                    &dlb_ecmp_group_control_entry, PORT_ASSIGNMENT_MODEf);
   1443 
   1444     /* If DLB group is in PACKET_SPRAY mode, return error. Refer arch doc
   1445      * for details
   1446      */
   1447     if (dlb_mode == 2) {
   1448         return BCM_E_CONFIG;
   1449     }
   1450 
   1451     /* Validate configuration info passed */
   1452     if ((dlb_mon_cfg->action < BCM_L3_ECMP_DLB_MON_COPY_TO_CPU) ||
   1453         (dlb_mon_cfg->action > BCM_L3_ECMP_DLB_MON_ACTION_NONE)) {
   1454         return BCM_E_PARAM;
   1455     }
   1456 
   1457 
   1458     max_val = (1 << soc_mem_field_length(unit, DLB_ECMP_GROUP_MONITOR_CONTROLm,
   1459                                          SAMPLE_THRESHOLDf));
   1460 
   1461     enable = dlb_mon_cfg->enable ? 1 : 0;
   1462 
   1463     /* Program h/w only if user is enabling DLB id monitoring, and a non-zero
   1464      * rate is specified. Rate of 0 means 'do not sample', which means
   1465      * effectively disabling monitoring
   1466      */
   1467     if ((enable) && (dlb_mon_cfg->sample_rate > 0)) {
   1468 
   1469         /* Calculate threshold based on sampling rate provided. We complement
   1470          * the value calculated since packet sampling happens when h/w's
   1471          * random number generator is >= the programmed threshold
   1472          * (In case of sflow, sampling happens if RNG value <= threshold)
   1473          */
   1474 
   1475         /* Rate of 1 means sample each packet. In this case we need to adjust
   1476          * value to be the max value that can be fitted in SAMPLE_THRESHOLDf
   1477          */
   1478         if (dlb_mon_cfg->sample_rate == 1) {
   1479             max_val = max_val - 1;
   1480         }
   1481 
   1482         threshold = max_val / dlb_mon_cfg->sample_rate;
   1483 
   1484         /* Complement the value */
   1485         /* Note 'max_val - 1' is used here as mask to zero out bits 31:29 */
   1486         threshold = ~threshold & (max_val - 1);
   1487     } else {
   1488         enable = 0;
   1489         threshold = 0;
   1490     }
   1491 
   1492     BCM_IF_ERROR_RETURN(READ_DLB_ECMP_GROUP_MONITOR_CONTROLm(unit,
   1493                                                              MEM_BLOCK_ANY,
   1494                                                              dlb_id,
   1495                                                              &mon_ctrl));
   1496 
   1497     /* Set Monitor enable and threshold fields */
   1498     soc_DLB_ECMP_GROUP_MONITOR_CONTROLm_field32_set(unit, &mon_ctrl,
   1499                                                     MONITOR_ENf, enable);
   1500 
   1501     soc_DLB_ECMP_GROUP_MONITOR_CONTROLm_field32_set(unit, &mon_ctrl,
   1502                                                     SAMPLE_THRESHOLDf,
   1503                                                     threshold);
   1504 
   1505     /* If application is enabling monitoring, only then program actions
   1506      * passed by the application, else reset the action
   1507      */
   1508     if (enable) {
   1509         /* Set Copy to CPU and/or Mirror bit(s) */
   1510         switch (dlb_mon_cfg->action) {
   1511             case BCM_L3_ECMP_DLB_MON_COPY_TO_CPU:
   1512                 copy_to_cpu = 1;
   1513                 mirror = 0;
   1514                 break;
   1515 
   1516             case BCM_L3_ECMP_DLB_MON_MIRROR:
   1517                 copy_to_cpu = 0;
   1518                 mirror = 1;
   1519                 break;
   1520 
   1521             case BCM_L3_ECMP_DLB_MON_COPY_TO_CPU_AND_MIRROR:
   1522                 copy_to_cpu = 1;
   1523                 mirror = 1;
   1524                 break;
   1525 
   1526             case BCM_L3_ECMP_DLB_MON_ACTION_NONE:
   1527                 copy_to_cpu = 0;
   1528                 mirror = 0;
   1529                 break;
   1530 
   1531             default:
   1532                 /* This case should not be reached */
   1533                 return BCM_E_CONFIG;
   1534                 break;
   1535         }
   1536     } else {
   1537         copy_to_cpu = 0;
   1538         mirror = 0;
   1539     }
   1540 
   1541     soc_DLB_ECMP_GROUP_MONITOR_CONTROLm_field32_set(unit, &mon_ctrl,
   1542                                                     COPY_TO_CPUf, copy_to_cpu);
   1543 
   1544     soc_DLB_ECMP_GROUP_MONITOR_CONTROLm_field32_set(unit, &mon_ctrl,
   1545                                                     MIRRORf, mirror);
   1546 
   1547     BCM_IF_ERROR_RETURN(WRITE_DLB_ECMP_GROUP_MONITOR_CONTROLm(unit,
   1548                                                               MEM_BLOCK_ANY,
   1549                                                               dlb_id,
   1550                                                               &mon_ctrl));
   1551 
   1552     return BCM_E_NONE;
   1553 }
   1554 
   1555 /*
   1556  * Function:
   1557  *    bcm_th3_l3_ecmp_dlb_mon_config_get
   1558  * Purpose:
   1559  *    This function reads DLB monitoring parameters from hardware, for a DLB id
   1560  *    derived from ECMP group id. Property spn_DLB_FLOW_MONITOR_EN must be
   1561  *    enabled before invoking this function. See Notes.
   1562  * Parameters:
   1563  *    unit :        (IN) Device's unit number
   1564  *    ecmp_intf :   (IN) ECMP interface id obtained from bcm_l3_ecmp_create or,
   1565  *                       bcm_l3_egress_ecmp_create
   1566  *    dlb_mon_cfg : (OUT) DLB flow monitoring configuration read from h/w for
   1567  *                        specified DLB
   1568  * Returns:
   1569  *    BCM_E_XXX
   1570  * Notes:
   1571  * 1. Sample rates are calculated only if MONITOR_EN is set for a DLB id.
   1572  * 2. Sample rate calculated from threshold may not exactly match the sample
   1573  *    rate programmed via config_set API. This is because we do integer division
   1574  *    to calculate the threhold in the config_set, and store the value obtained
   1575  *    in the threshold field. And in this function, we perform integer division
   1576  *    again.
   1577  */
   1578 int bcm_th3_l3_ecmp_dlb_mon_config_get(int unit,
   1579                                        bcm_if_t ecmp_intf,
   1580                                        bcm_l3_ecmp_dlb_mon_cfg_t *dlb_mon_cfg)
   1581 {
   1582     int dlb_id;
   1583     int dlb_mode;
   1584     uint64 dlb_en_bitmap;
   1585     uint32 dlb_enabled;
   1586     dlb_ecmp_group_control_entry_t dlb_ecmp_group_control_entry;
   1587     uint32 threshold = 0;
   1588     uint32 enable = 0;
   1589     uint32 copy_to_cpu = 0;
   1590     uint32 mirror = 0;
   1591     dlb_ecmp_group_monitor_control_entry_t mon_ctrl;
   1592     int max_val;
   1593     int ecmp_group_idx;
   1594 
   1595     /* If application has not defined this feature, or not enabled this feature,
   1596      * return error
   1597      */
   1598     if (!soc_property_get(unit, spn_DLB_FLOW_MONITOR_EN, 0)) {
   1599         return BCM_E_UNAVAIL;
   1600     }
   1601 
   1602     if (dlb_mon_cfg == NULL) {
   1603         return BCM_E_PARAM;
   1604     }
   1605 
   1606     ecmp_group_idx = ecmp_intf - BCM_XGS3_MPATH_EGRESS_IDX_MIN(unit);
   1607     if (ecmp_group_idx < BCM_TH3_L3_ECMP_DLB_START(unit)) {
   1608         return BCM_E_CONFIG;
   1609     }
   1610 
   1611     /* Get the DLB id associated with the Ecmp group */
   1612     dlb_id = _bcm_th3_l3_ecmp_dlb_get_id(unit, ecmp_group_idx);
   1613 
   1614     /* DLB id of 0 is not supported for DLB flow monitoring. If we obtained
   1615      * it (0), return error
   1616      */
   1617     if (dlb_id == 0) {
   1618         return BCM_E_INTERNAL;
   1619     }
   1620 
   1621     /* Check if the DLB obtained is in enabled state */
   1622     if (dlb_id < soc_reg_field_length(unit, DLB_ID_0_TO_63_ENABLEr, BITMAPf)) {
   1623         SOC_IF_ERROR_RETURN( \
   1624           READ_DLB_ID_0_TO_63_ENABLEr(unit, &dlb_en_bitmap));
   1625         dlb_enabled = COMPILER_64_BITTEST(dlb_en_bitmap, dlb_id);
   1626     } else {
   1627         SOC_IF_ERROR_RETURN( \
   1628           READ_DLB_ID_64_TO_127_ENABLEr(unit, &dlb_en_bitmap));
   1629          dlb_enabled = COMPILER_64_BITTEST(dlb_en_bitmap, dlb_id -
   1630                                (soc_reg_field_length(unit,
   1631                                DLB_ID_64_TO_127_ENABLEr, BITMAPf)));
   1632     }
   1633 
   1634     if (!dlb_enabled) {
   1635         return BCM_E_CONFIG;
   1636     }
   1637 
   1638    /* Get DLB operational mode */
   1639     BCM_IF_ERROR_RETURN(READ_DLB_ECMP_GROUP_CONTROLm(unit, MEM_BLOCK_ANY,
   1640                             dlb_id, &dlb_ecmp_group_control_entry));
   1641 
   1642     dlb_mode = soc_DLB_ECMP_GROUP_CONTROLm_field32_get(unit,
   1643                    &dlb_ecmp_group_control_entry, PORT_ASSIGNMENT_MODEf);
   1644 
   1645     /* If DLB group is in PACKET_SPRAY mode, return error. Refer arch doc
   1646      * for details
   1647      */
   1648     if (dlb_mode == 2) {
   1649         return BCM_E_CONFIG;
   1650     }
   1651 
   1652     BCM_IF_ERROR_RETURN(READ_DLB_ECMP_GROUP_MONITOR_CONTROLm(unit, MEM_BLOCK_ANY, dlb_id, &mon_ctrl));
   1653 
   1654     enable = soc_DLB_ECMP_GROUP_MONITOR_CONTROLm_field32_get(unit, &mon_ctrl, MONITOR_ENf);
   1655 
   1656     threshold = soc_DLB_ECMP_GROUP_MONITOR_CONTROLm_field32_get(unit, &mon_ctrl, SAMPLE_THRESHOLDf);
   1657 
   1658     copy_to_cpu = soc_DLB_ECMP_GROUP_MONITOR_CONTROLm_field32_get(unit, &mon_ctrl, COPY_TO_CPUf);
   1659 
   1660     mirror = soc_DLB_ECMP_GROUP_MONITOR_CONTROLm_field32_get(unit, &mon_ctrl, MIRRORf);
   1661 
   1662     dlb_mon_cfg->enable = enable;
   1663 
   1664     if (enable) {
   1665         if (copy_to_cpu && mirror) {
   1666             dlb_mon_cfg->action = BCM_L3_ECMP_DLB_MON_COPY_TO_CPU_AND_MIRROR;
   1667         } else {
   1668             if (copy_to_cpu) {
   1669                 dlb_mon_cfg->action = BCM_L3_ECMP_DLB_MON_COPY_TO_CPU;
   1670             } else {
   1671                 if (mirror) {
   1672                     dlb_mon_cfg->action = BCM_L3_ECMP_DLB_MON_MIRROR;
   1673                 } else {
   1674                     dlb_mon_cfg->action = BCM_L3_ECMP_DLB_MON_ACTION_NONE;
   1675                 }
   1676             }
   1677         }
   1678 
   1679         max_val = (1 << soc_mem_field_length(unit,
   1680                                              DLB_ECMP_GROUP_MONITOR_CONTROLm,
   1681                                              SAMPLE_THRESHOLDf));
   1682 
   1683         /* Calculate sample_rate from sample threshold */
   1684         /* 'max_val - 1' is used as mask here */
   1685         threshold = ~threshold & (max_val - 1);
   1686 
   1687         if (threshold == 0) {
   1688             dlb_mon_cfg->sample_rate = max_val;
   1689         } else {
   1690             dlb_mon_cfg->sample_rate = max_val / threshold;
   1691         }
   1692     } else {
   1693         dlb_mon_cfg->sample_rate = 0;
   1694         dlb_mon_cfg->action = BCM_L3_ECMP_DLB_MON_ACTION_NONE;
   1695     }
   1696 
   1697     return BCM_E_NONE;
   1698 }
   1699 
   1700 int _bcm_th3_set_port_list(int unit, int port, int dlb_id, int nh_index)
   1701 {
   1702 
   1703     _th2_ecmp_dlb_port_membership_t *current_ptr, *first_ptr;
   1704     _th2_ecmp_dlb_port_membership_t *membership;
   1705     /* now have nh_index (ecmp_member[k]), port (port), dlb_id  */
   1706     /* find it nexthop exists in specific port list*/
   1707     current_ptr = ECMP_DLB_PORT_LIST(unit, port);
   1708     first_ptr = NULL;
   1709     while (current_ptr) {
   1710         if (current_ptr->nh_index != nh_index) {
   1711             current_ptr = current_ptr->next;
   1712             continue;
   1713         }
   1714 
   1715         if (dlb_id == current_ptr->dlb_id) {
   1716             current_ptr->ref_count++;
   1717             break;
   1718         }
   1719         if (first_ptr == NULL) {
   1720             first_ptr = current_ptr;
   1721         }
   1722 
   1723         current_ptr = current_ptr->next;
   1724     }
   1725 
   1726     if (current_ptr == NULL) {
   1727         /* Insert member ID and group to the next hop's linked list of member
   1728          * IDs and groups.
   1729          */
   1730         membership = sal_alloc(sizeof(_th2_ecmp_dlb_port_membership_t),
   1731                 "ecmp dlb nh membership");
   1732         if (NULL == membership) {
   1733             return BCM_E_MEMORY;
   1734         }
   1735         sal_memset(membership, 0, sizeof(_th2_ecmp_dlb_port_membership_t));
   1736         membership->nh_index = nh_index;
   1737         membership->ref_count = 1;
   1738         membership->dlb_id    = dlb_id;
   1739 
   1740         if (first_ptr != NULL) {
   1741         /* didnt find exact same node(nh_index, dlb_id) ,
   1742          * but find same nh_index (A).
   1743          * create B after A.
   1744          * first_ptr points to A.
   1745          */
   1746             membership->next = first_ptr->next;
   1747             first_ptr->next = membership;
   1748             ECMP_DLB_PORT_INFO(unit, port).dlb_count++;
   1749         } else {
   1750         /* didnt find same nh_index*/
   1751         /* this is new nh_index, insert it at head */
   1752             membership->next = ECMP_DLB_PORT_LIST(unit, port);
   1753             ECMP_DLB_PORT_LIST(unit, port) = membership;
   1754             ECMP_DLB_PORT_INFO(unit, port).nh_count++;
   1755             ECMP_DLB_PORT_INFO(unit, port).dlb_count++;
   1756         }
   1757     }
   1758     return BCM_E_NONE;
   1759 }
   1760 /*
   1761  * Function:
   1762  *      _bcm_th3_ecmp_dlb_member_recover
   1763  * Purpose:
   1764  *      Recover ECMP DLB ports usage and the next hop indices associated
   1765  *      with the ports.
   1766  * Parameters:
   1767  *      unit - (IN) SOC unit number.
   1768  * Returns:
   1769  *      BCM_E_XXX
   1770  */
   1771 int
   1772 _bcm_th3_ecmp_dlb_member_recover(int unit)
   1773 {
   1774     int rv = BCM_E_NONE;
   1775     int port_map_width;
   1776     int alloc_size_port_map;
   1777     SHR_BITDCL *port_map = NULL;
   1778     SHR_BITDCL *port_map2 = NULL;
   1779     int dlb_id;
   1780     dlb_ecmp_group_membership_entry_t group_membership_entry;
   1781     int ecmp_count = 0;           /* Next hop count in the group.        */
   1782     bcm_if_t *ecmp_member = NULL; /* Ecmp group from hw.                 */
   1783     dlb_ecmp_group_control_entry_t group_control_entry;
   1784     int j;
   1785     int membership_pointer;
   1786     int offset;
   1787     int count;
   1788     int nh_index;
   1789     bcm_l3_egress_ecmp_t tmp_ecmp;
   1790     uint64 dlb_en_bitmap;
   1791 
   1792     dlb_ecmp_group_nhi_members_0_to_12_entry_t dlb_nhi_members;
   1793     dlb_ecmp_group_nhi_members_13_to_25_entry_t dlb_nhi_members_13;
   1794     dlb_ecmp_group_nhi_members_26_to_38_entry_t dlb_nhi_members_26;
   1795     dlb_ecmp_group_nhi_members_39_to_51_entry_t dlb_nhi_members_39;
   1796     dlb_ecmp_group_nhi_members_52_to_63_entry_t dlb_nhi_members_52;
   1797 
   1798     dlb_ecmp_group_alt_nhi_members_0_to_12_entry_t dlb_alt_nhi_members;
   1799     dlb_ecmp_group_alt_nhi_members_13_to_25_entry_t dlb_alt_nhi_members_13;
   1800     dlb_ecmp_group_alt_nhi_members_26_to_38_entry_t dlb_alt_nhi_members_26;
   1801     dlb_ecmp_group_alt_nhi_members_39_to_51_entry_t dlb_alt_nhi_members_39;
   1802     dlb_ecmp_group_alt_nhi_members_52_to_63_entry_t dlb_alt_nhi_members_52;
   1803 
   1804     dlb_ecmp_group_port_members_0_to_15_entry_t dlb_port_members;
   1805     dlb_ecmp_group_port_members_16_to_31_entry_t dlb_port_members_16;
   1806     dlb_ecmp_group_port_members_32_to_47_entry_t dlb_port_members_32;
   1807     dlb_ecmp_group_port_members_48_to_63_entry_t dlb_port_members_48;
   1808 
   1809     dlb_ecmp_group_alt_port_members_0_to_15_entry_t dlb_alt_port_members;
   1810     dlb_ecmp_group_alt_port_members_16_to_31_entry_t dlb_alt_port_members_16;
   1811     dlb_ecmp_group_alt_port_members_32_to_47_entry_t dlb_alt_port_members_32;
   1812     dlb_ecmp_group_alt_port_members_48_to_63_entry_t dlb_alt_port_members_48;
   1813 
   1814     /* Allocate port map */
   1815     port_map_width = soc_mem_field_length(unit,
   1816             DLB_ECMP_GROUP_MEMBERSHIPm, PORT_MAPf);
   1817     alloc_size_port_map = SHR_BITALLOCSIZE(port_map_width);
   1818     port_map = sal_alloc(alloc_size_port_map, "DLB ECMP port map");
   1819     if (NULL == port_map) {
   1820         rv = BCM_E_MEMORY;
   1821         goto cleanup;
   1822     }
   1823 
   1824     port_map2 = sal_alloc(alloc_size_port_map, "DLB ECMP port map 2");
   1825     if (NULL == port_map2) {
   1826         rv = BCM_E_MEMORY;
   1827         goto cleanup;
   1828     }
   1829 
   1830     /* Allocate ECMP group members */
   1831     ecmp_member = sal_alloc(128 * sizeof(bcm_if_t),
   1832             "ecmp member array");
   1833     if (NULL == ecmp_member) {
   1834         rv = BCM_E_MEMORY;
   1835         goto cleanup;
   1836     }
   1837 
   1838     for (dlb_id = 0; dlb_id < 128; dlb_id++) {
   1839         /* Enable bits for the first 64 groups are in
   1840            DLB_ID_0_TO_63_ENABLE register and the next 64 are in
   1841            DLB_ID_64_TO_127_ENABLE. */
   1842         if (dlb_id < soc_reg_field_length(unit,
   1843                      DLB_ID_0_TO_63_ENABLEr, BITMAPf)) {
   1844             rv = READ_DLB_ID_0_TO_63_ENABLEr(unit, &dlb_en_bitmap);
   1845             if (rv < 0) {
   1846                 goto cleanup;
   1847             }
   1848             if (!(COMPILER_64_BITTEST(dlb_en_bitmap, dlb_id))) {
   1849                 continue;
   1850             }
   1851         } else {
   1852             rv = READ_DLB_ID_64_TO_127_ENABLEr(unit, &dlb_en_bitmap);
   1853             if (rv < 0) {
   1854                 goto cleanup;
   1855             }
   1856             if (!(COMPILER_64_BITTEST(dlb_en_bitmap, dlb_id -
   1857                 soc_reg_field_length(unit, DLB_ID_0_TO_63_ENABLEr, BITMAPf)))) {
   1858                 continue;
   1859             }
   1860         }
   1861 
   1862         rv = READ_DLB_ECMP_GROUP_CONTROLm(unit, MEM_BLOCK_ANY, dlb_id,
   1863                                           &group_control_entry);
   1864         if (BCM_FAILURE(rv)) {
   1865             goto cleanup;
   1866         }
   1867         membership_pointer = soc_DLB_ECMP_GROUP_CONTROLm_field32_get(unit,
   1868                 &group_control_entry, GROUP_MEMBERSHIP_POINTERf);
   1869 
   1870         rv = READ_DLB_ECMP_GROUP_MEMBERSHIPm(unit, MEM_BLOCK_ANY,
   1871                                              membership_pointer,
   1872                                              &group_membership_entry);
   1873         if (BCM_FAILURE(rv)) {
   1874             goto cleanup;
   1875         }
   1876         /* We have the DLB_ID here,
   1877          * now there are 2 ways to recover these info from hw to sw:
   1878          * 1) Use the DLB_ID to get port_map,
   1879          *    the port map will indicate how many port2member entries are set.
   1880          *    traverse the valid port2member entries via port map.
   1881          *    Each port2member entry can be parsed to get the valid bits and then
   1882          *    the nexthops. Got the nexthop, the DLB_ID, the port. It's enough
   1883          *    to recover the sw state.
   1884          * 2) The first method has a side effect, which is traverse all valid
   1885          *    port2member entries, and then traverse the valid bits of each.
   1886          *    That's portnumber * 64 loops in total.
   1887          *    An alternative way is to get the ecmp members (64 members at most)
   1888          *    Parse the entries and then get the ports. Same as above, we got
   1889          *    all the needed info: nexthop, DLB_ID, port.
   1890          *
   1891          *    Actually, the port2member entries are not necessary, if DLB can
   1892          *    traverse the ecmp member table and get all nexthops pointing
   1893          *    to the chosen port, it's done. In fact, port2member is just another
   1894          *    angle of ecmp member table.
   1895          */
   1896 
   1897         /* Get port map */
   1898         sal_memset(port_map, 0, alloc_size_port_map);
   1899         soc_DLB_ECMP_GROUP_MEMBERSHIPm_field_get(unit,
   1900                 &group_membership_entry, PORT_MAPf, port_map);
   1901 
   1902         sal_memset(port_map2, 0, alloc_size_port_map);
   1903         soc_DLB_ECMP_GROUP_MEMBERSHIPm_field_get(unit,
   1904                 &group_membership_entry, PORT_MAP_ALTERNATEf, port_map2);
   1905 
   1906         /* Get ECMP members */
   1907         /* Check if the ECMP group is DLB enabled. */
   1908         bcm_l3_egress_ecmp_t_init(&tmp_ecmp);
   1909         tmp_ecmp.ecmp_intf = dlb_id + BCM_XGS3_MPATH_EGRESS_IDX_MIN(unit) + BCM_TH3_L3_ECMP_DLB_START(unit);
   1910         /*
   1911          * Increase entry reference count to avoid the failure of calling
   1912          * ecmp_get since the reference count of ecmp group is recovered along
   1913          * with hash value after the recovery of DLB info.
   1914          */
   1915         BCM_XGS3_L3_ENT_REF_CNT_INC(
   1916             BCM_XGS3_L3_TBL_PTR(unit, ecmp_grp), dlb_id + BCM_TH3_L3_ECMP_DLB_START(unit), _BCM_SINGLE_WIDE);
   1917         rv = _bcm_esw_l3_egress_ecmp_get(unit, &tmp_ecmp, 0,
   1918                                          NULL, &ecmp_count, TRUE);
   1919         BCM_XGS3_L3_ENT_REF_CNT_DEC(
   1920             BCM_XGS3_L3_TBL_PTR(unit, ecmp_grp), dlb_id + BCM_TH3_L3_ECMP_DLB_START(unit), _BCM_SINGLE_WIDE);
   1921         if (BCM_FAILURE(rv)) {
   1922             goto cleanup;
   1923         }
   1924         if (tmp_ecmp.dynamic_mode != BCM_L3_ECMP_DYNAMIC_MODE_NORMAL &&
   1925             tmp_ecmp.dynamic_mode != BCM_L3_ECMP_DYNAMIC_MODE_ASSIGNED &&
   1926             tmp_ecmp.dynamic_mode != BCM_L3_ECMP_DYNAMIC_MODE_OPTIMAL &&
   1927             tmp_ecmp.dynamic_mode != BCM_L3_ECMP_DYNAMIC_MODE_DGM) {
   1928             rv = BCM_E_INTERNAL;
   1929             goto cleanup;
   1930         }
   1931 
   1932         if (ecmp_count > 128) {
   1933             rv = BCM_E_INTERNAL;
   1934             goto cleanup;
   1935         }
   1936 
   1937         sal_memset(ecmp_member, 0, 128 * sizeof(bcm_if_t));
   1938         /*
   1939          * Increase entry reference count to avoid the failure of calling
   1940          * ecmp_get since the reference count of ecmp group is recovered along
   1941          * with hash value after the recovery of DLB info.
   1942          */
   1943         BCM_XGS3_L3_ENT_REF_CNT_INC(
   1944             BCM_XGS3_L3_TBL_PTR(unit, ecmp_grp), dlb_id + BCM_TH3_L3_ECMP_DLB_START(unit), _BCM_SINGLE_WIDE);
   1945         rv = _bcm_esw_l3_egress_ecmp_get(unit, &tmp_ecmp, ecmp_count,
   1946                                          ecmp_member, &count, TRUE);
   1947         BCM_XGS3_L3_ENT_REF_CNT_DEC(
   1948             BCM_XGS3_L3_TBL_PTR(unit, ecmp_grp), dlb_id + BCM_TH3_L3_ECMP_DLB_START(unit), _BCM_SINGLE_WIDE);
   1949         if (BCM_FAILURE(rv)) {
   1950             goto cleanup;
   1951         }
   1952 
   1953         for (j = 0; j < ecmp_count; j++) {
   1954             if (BCM_XGS3_L3_EGRESS_IDX_VALID(unit, ecmp_member[j])) {
   1955                 offset = BCM_XGS3_EGRESS_IDX_MIN(unit);
   1956             } else {
   1957                 rv = BCM_E_PARAM;
   1958                 goto cleanup;
   1959             }
   1960             ecmp_member[j] -= offset;
   1961         }
   1962 
   1963         SHR_BITOR_RANGE(port_map, port_map2, 0, port_map_width, port_map);
   1964 
   1965         rv = soc_mem_read(unit, DLB_ECMP_GROUP_NHI_MEMBERS_0_TO_12m,
   1966                            SOC_BLOCK_ANY, (dlb_id), &dlb_nhi_members);
   1967 
   1968         rv = soc_mem_read(unit, DLB_ECMP_GROUP_NHI_MEMBERS_13_TO_25m,
   1969                            SOC_BLOCK_ANY, (dlb_id), &dlb_nhi_members_13);
   1970 
   1971         rv = soc_mem_read(unit, DLB_ECMP_GROUP_NHI_MEMBERS_26_TO_38m,
   1972                            SOC_BLOCK_ANY, (dlb_id), &dlb_nhi_members_26);
   1973 
   1974         rv = soc_mem_read(unit, DLB_ECMP_GROUP_NHI_MEMBERS_39_TO_51m,
   1975                            SOC_BLOCK_ANY, (dlb_id), &dlb_nhi_members_39);
   1976 
   1977         rv = soc_mem_read(unit, DLB_ECMP_GROUP_NHI_MEMBERS_52_TO_63m,
   1978                            SOC_BLOCK_ANY, (dlb_id), &dlb_nhi_members_52);
   1979 
   1980         rv = soc_mem_read(unit, DLB_ECMP_GROUP_PORT_MEMBERS_0_TO_15m,
   1981                            SOC_BLOCK_ANY, (dlb_id), &dlb_port_members);
   1982 
   1983         rv = soc_mem_read(unit, DLB_ECMP_GROUP_PORT_MEMBERS_16_TO_31m,
   1984                            SOC_BLOCK_ANY, (dlb_id), &dlb_port_members_16);
   1985 
   1986         rv = soc_mem_read(unit, DLB_ECMP_GROUP_PORT_MEMBERS_32_TO_47m,
   1987                            SOC_BLOCK_ANY, (dlb_id), &dlb_port_members_32);
   1988 
   1989         rv = soc_mem_read(unit, DLB_ECMP_GROUP_PORT_MEMBERS_48_TO_63m,
   1990                            SOC_BLOCK_ANY, (dlb_id), &dlb_port_members_48);
   1991 
   1992         rv = soc_mem_read(unit, DLB_ECMP_GROUP_ALT_PORT_MEMBERS_0_TO_15m,
   1993                            SOC_BLOCK_ANY, (dlb_id), &dlb_alt_port_members);
   1994 
   1995         rv = soc_mem_read(unit, DLB_ECMP_GROUP_ALT_PORT_MEMBERS_16_TO_31m,
   1996                            SOC_BLOCK_ANY, (dlb_id), &dlb_alt_port_members_16);
   1997 
   1998         rv = soc_mem_read(unit, DLB_ECMP_GROUP_ALT_PORT_MEMBERS_32_TO_47m,
   1999                            SOC_BLOCK_ANY, (dlb_id), &dlb_alt_port_members_32);
   2000 
   2001         rv = soc_mem_read(unit, DLB_ECMP_GROUP_ALT_PORT_MEMBERS_48_TO_63m,
   2002                            SOC_BLOCK_ANY, (dlb_id), &dlb_alt_port_members_48);
   2003 
   2004         rv = soc_mem_read(unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_0_TO_12m,
   2005                            SOC_BLOCK_ANY, (dlb_id), &dlb_alt_nhi_members);
   2006 
   2007         rv = soc_mem_read(unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_13_TO_25m,
   2008                            SOC_BLOCK_ANY, (dlb_id), &dlb_alt_nhi_members_13);
   2009 
   2010         rv = soc_mem_read(unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_26_TO_38m,
   2011                            SOC_BLOCK_ANY, (dlb_id), &dlb_alt_nhi_members_26);
   2012 
   2013         rv = soc_mem_read(unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_39_TO_51m,
   2014                            SOC_BLOCK_ANY, (dlb_id), &dlb_alt_nhi_members_39);
   2015 
   2016         rv = soc_mem_read(unit, DLB_ECMP_GROUP_ALT_NHI_MEMBERS_52_TO_63m,
   2017                            SOC_BLOCK_ANY, (dlb_id), &dlb_alt_nhi_members_52);
   2018 
   2019         _DLB_SET_GROUP_PTR_0_12(0);
   2020         _DLB_SET_GROUP_PTR_0_12(1);
   2021         _DLB_SET_GROUP_PTR_0_12(2);
   2022         _DLB_SET_GROUP_PTR_0_12(3);
   2023         _DLB_SET_GROUP_PTR_0_12(4);
   2024         _DLB_SET_GROUP_PTR_0_12(5);
   2025         _DLB_SET_GROUP_PTR_0_12(6);
   2026         _DLB_SET_GROUP_PTR_0_12(7);
   2027         _DLB_SET_GROUP_PTR_0_12(8);
   2028         _DLB_SET_GROUP_PTR_0_12(9);
   2029         _DLB_SET_GROUP_PTR_0_12(10);
   2030         _DLB_SET_GROUP_PTR_0_12(11);
   2031         _DLB_SET_GROUP_PTR_0_12(12);
   2032 
   2033         _DLB_SET_GROUP_PTR_13_25(13);
   2034         _DLB_SET_GROUP_PTR_13_25(14);
   2035         _DLB_SET_GROUP_PTR_13_25(15);
   2036         _DLB_SET_GROUP_PTR_13_25(16);
   2037         _DLB_SET_GROUP_PTR_13_25(17);
   2038         _DLB_SET_GROUP_PTR_13_25(18);
   2039         _DLB_SET_GROUP_PTR_13_25(19);
   2040         _DLB_SET_GROUP_PTR_13_25(20);
   2041         _DLB_SET_GROUP_PTR_13_25(21);
   2042         _DLB_SET_GROUP_PTR_13_25(22);
   2043         _DLB_SET_GROUP_PTR_13_25(23);
   2044         _DLB_SET_GROUP_PTR_13_25(24);
   2045         _DLB_SET_GROUP_PTR_13_25(25);
   2046 
   2047         _DLB_SET_GROUP_PTR_26_38(26);
   2048         _DLB_SET_GROUP_PTR_26_38(27);
   2049         _DLB_SET_GROUP_PTR_26_38(28);
   2050         _DLB_SET_GROUP_PTR_26_38(29);
   2051         _DLB_SET_GROUP_PTR_26_38(30);
   2052         _DLB_SET_GROUP_PTR_26_38(31);
   2053         _DLB_SET_GROUP_PTR_26_38(32);
   2054         _DLB_SET_GROUP_PTR_26_38(33);
   2055         _DLB_SET_GROUP_PTR_26_38(34);
   2056         _DLB_SET_GROUP_PTR_26_38(35);
   2057         _DLB_SET_GROUP_PTR_26_38(36);
   2058         _DLB_SET_GROUP_PTR_26_38(37);
   2059         _DLB_SET_GROUP_PTR_26_38(38);
   2060 
   2061         _DLB_SET_GROUP_PTR_39_51(39);
   2062         _DLB_SET_GROUP_PTR_39_51(40);
   2063         _DLB_SET_GROUP_PTR_39_51(41);
   2064         _DLB_SET_GROUP_PTR_39_51(42);
   2065         _DLB_SET_GROUP_PTR_39_51(43);
   2066         _DLB_SET_GROUP_PTR_39_51(44);
   2067         _DLB_SET_GROUP_PTR_39_51(45);
   2068         _DLB_SET_GROUP_PTR_39_51(46);
   2069         _DLB_SET_GROUP_PTR_39_51(47);
   2070         _DLB_SET_GROUP_PTR_39_51(48);
   2071         _DLB_SET_GROUP_PTR_39_51(49);
   2072         _DLB_SET_GROUP_PTR_39_51(50);
   2073         _DLB_SET_GROUP_PTR_39_51(51);
   2074 
   2075         _DLB_SET_GROUP_PTR_52_63(52);
   2076         _DLB_SET_GROUP_PTR_52_63(53);
   2077         _DLB_SET_GROUP_PTR_52_63(54);
   2078         _DLB_SET_GROUP_PTR_52_63(55);
   2079         _DLB_SET_GROUP_PTR_52_63(56);
   2080         _DLB_SET_GROUP_PTR_52_63(57);
   2081         _DLB_SET_GROUP_PTR_52_63(58);
   2082         _DLB_SET_GROUP_PTR_52_63(59);
   2083         _DLB_SET_GROUP_PTR_52_63(60);
   2084         _DLB_SET_GROUP_PTR_52_63(61);
   2085         _DLB_SET_GROUP_PTR_52_63(62);
   2086         _DLB_SET_GROUP_PTR_52_63(63);
   2087 
   2088     }
   2089 
   2090 cleanup:
   2091     if (port_map) {
   2092         sal_free(port_map);
   2093     }
   2094     if (port_map2) {
   2095         sal_free(port_map2);
   2096     }
   2097     if (ecmp_member) {
   2098         sal_free(ecmp_member);
   2099     }
   2100     return BCM_E_NONE;
   2101 }
   2102 
   2103 
   2104 #endif