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

hashing.c (56611B)


      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:        hashing.c
      8  * Purpose:     Hash calcualtions for trunk and ECMP packets.
      9  */
     10 
     11 #include <soc/debug.h>
     12 #include <soc/drv.h>
     13 #include <soc/hash.h>
     14 #include <bcm/switch.h>
     15 #include <bcm/debug.h>
     16 #include <bcm/error.h>
     17 
     18 #include <bcm_int/esw_dispatch.h>
     19 #include <bcm_int/esw/firebolt.h>
     20 #include <bcm_int/esw/port.h>
     21 #include <bcm_int/esw/stack.h>
     22 #include <bcm_int/esw/switch.h>
     23 
     24 typedef struct bcm_rtag7_base_hash_s {
     25     uint32 rtag7_hash16_value_a_0;      /* hash a0 result */
     26     uint32 rtag7_hash16_value_a_1;      /* hash a1 result */
     27     uint32 rtag7_hash16_value_b_0;      /* hash b0 result */
     28     uint32 rtag7_hash16_value_b_1;      /* hash b1 result */
     29     uint32 rtag7_macro_flow_id;         /* hash micro flow result */
     30     uint32 rtag7_port_lbn;     	        /* port LBN value from the port table*/
     31     uint32 rtag7_lbid_hash;             /* LBID hash calculation*/
     32     bcm_port_t dev_src_port;            /* Local source port */
     33     bcm_port_t src_port;                /* System source port */
     34     bcm_module_t src_modid;             /* System source modid */
     35     uint8 is_nonuc;                     /* Non-unicast */
     36     uint8 hash_a_valid;                 /* Hash A result use valid input */
     37     uint8 hash_b_valid;                 /* Hash B result use valid input */
     38     uint8 lbid_hash_valid;              /* LBID Hash value is valid */
     39 } bcm_rtag7_base_hash_t;
     40 
     41 #define   ETHERTYPE_IPV6 0x86dd /* ipv6 ethertype */
     42 #define   ETHERTYPE_IPV4 0x0800 /* ipv4 ethertype */
     43 #define   ETHERTYPE_MIN  0x0600 /* minimum ethertype for hashing */
     44 
     45 #define   IP_PROT_TCP 0x6  /* TCP protocol number */
     46 #define   IP_PROT_UDP 0x11 /* TCP protocol number */
     47 
     48 #define RTAG7_L2_ONLY         0x0
     49 #define RTAG7_UNKNOWN_HIGIG   0x1
     50 #define RTAG7_MPLS            0x2
     51 #define RTAG7_MIM             0x3
     52 #define RTAG7_IPV4            0x4
     53 #define RTAG7_IPV6            0x5
     54 #define RTAG7_FCOE            0x6
     55 #define RTAG7_TRILL           0x7
     56 
     57 /* fields from TRUNK_GROUPm */
     58 STATIC soc_field_t      _xgs_portf[8] = {
     59     PORT0f, PORT1f, PORT2f, PORT3f,
     60     PORT4f, PORT5f, PORT6f, PORT7f
     61 };
     62 
     63 STATIC soc_field_t      _xgs_modulef[8] = {
     64     MODULE0f, MODULE1f, MODULE2f, MODULE3f,
     65     MODULE4f, MODULE5f, MODULE6f, MODULE7f
     66 };
     67 
     68 STATIC soc_field_t      _xgs_hg_portf[4] = {
     69     HIGIG_TRUNK_PORT0f, HIGIG_TRUNK_PORT1f,
     70     HIGIG_TRUNK_PORT2f, HIGIG_TRUNK_PORT3f
     71 };
     72 
     73 STATIC int
     74 main__en_do_rtag7_hashing(int unit,
     75                        bcm_switch_pkt_info_t *pkt_info,
     76                        bcm_rtag7_base_hash_t *hash_res)
     77 {
     78     /* regular var declaration */
     79     uint32		hash_src_port;
     80     uint32		hash_src_modid;
     81     uint32		rtag7_a_sel;
     82     bcm_ip_t	        sip_a;               /* Source IPv4 address. */
     83     bcm_ip_t	        dip_a;               /* Destination IPv4 address. */
     84     uint32		rtag7_b_sel;
     85     bcm_ip_t	        sip_b;               /* Source IPv4 address. */
     86     bcm_ip_t	        dip_b;               /* Destination IPv4 address. */
     87     uint32		hash_field_bmap_a;   /* block A chosen bitmap*/
     88     uint32		hash_field_bmap_b;   /* block B chosen bitmap*/
     89 	
     90     uint32 hash_word[7];
     91     uint32 hash[13];
     92     int    elem, elem_bit;
     93     uint32 hash_element_valid_bits;
     94     /* int    ip6_addrs = FALSE, ip4_addrs = FALSE; */
     95     int    sip_valid = FALSE, dip_valid = FALSE;
     96 	
     97     uint32 hash_crc16_bisync;
     98     uint32 hash_xor8;
     99     uint32 hash_xor4;
    100     uint32 hash_xor2;
    101     uint32 hash_xor1;
    102     uint32 xor32;
    103 
    104     /* register var declaration */
    105     uint8 rtag7_disable_hash_ipv4_a;
    106     uint8 rtag7_disable_hash_ipv6_a; 
    107    
    108     uint8 rtag7_disable_hash_ipv4_b;
    109     uint8 rtag7_disable_hash_ipv6_b;
    110     uint32 rtag7_hash_seed_a;
    111     uint32 rtag7_hash_seed_b;	
    112     uint32 rtag7_hash_a0_function_select;
    113     uint32 rtag7_hash_b0_function_select;
    114 	
    115     uint64 rtag7_hash_control;
    116     uint32 rtag7_hash_seed_a_reg, rtag7_hash_seed_b_reg;
    117     soc_reg_t sc_reg;
    118     soc_field_t sc_field;
    119     uint32 sc_val;
    120 
    121     SOC_IF_ERROR_RETURN
    122         (READ_RTAG7_HASH_CONTROLr(unit, &rtag7_hash_control));
    123     SOC_IF_ERROR_RETURN
    124         (READ_RTAG7_HASH_SEED_Ar(unit, &rtag7_hash_seed_a_reg));
    125     SOC_IF_ERROR_RETURN
    126         (READ_RTAG7_HASH_SEED_Br(unit, &rtag7_hash_seed_b_reg));
    127 
    128     /* RTAG7 hash registers */
    129     rtag7_disable_hash_ipv4_a =
    130         soc_reg64_field32_get(unit, RTAG7_HASH_CONTROLr, rtag7_hash_control,
    131                           DISABLE_HASH_IPV4_Af);
    132     rtag7_disable_hash_ipv6_a =
    133         soc_reg64_field32_get(unit, RTAG7_HASH_CONTROLr, rtag7_hash_control,
    134                           DISABLE_HASH_IPV6_Af);
    135     rtag7_disable_hash_ipv4_b =
    136         soc_reg64_field32_get(unit, RTAG7_HASH_CONTROLr, rtag7_hash_control,
    137                           DISABLE_HASH_IPV4_Bf);
    138     rtag7_disable_hash_ipv6_b =
    139         soc_reg64_field32_get(unit, RTAG7_HASH_CONTROLr, rtag7_hash_control,
    140                           DISABLE_HASH_IPV6_Bf);
    141 
    142     rtag7_hash_a0_function_select =
    143         soc_reg64_field32_get(unit, RTAG7_HASH_CONTROLr, rtag7_hash_control,
    144                           HASH_MODE_Af);
    145     rtag7_hash_b0_function_select =
    146         soc_reg64_field32_get(unit, RTAG7_HASH_CONTROLr, rtag7_hash_control,
    147                           HASH_MODE_Bf);
    148 
    149     rtag7_hash_seed_a =
    150         soc_reg_field_get(unit, RTAG7_HASH_SEED_Ar, rtag7_hash_seed_a_reg,
    151                           HASH_SEED_Af);
    152     rtag7_hash_seed_b =
    153         soc_reg_field_get(unit, RTAG7_HASH_SEED_Br, rtag7_hash_seed_b_reg,
    154                           HASH_SEED_Bf);
    155 
    156     /* RTAG7 tables */
    157     /* the first step is to choose the paket type and to fold the ipv6
    158      * addresses in case of IPv6 packet*/	
    159 
    160     /* option A ip folding for rtag 7 */
    161     if ((_BCM_SWITCH_PKT_INFO_FLAG_TEST(pkt_info, ETHERTYPE) &&
    162          (pkt_info->ethertype == ETHERTYPE_IPV6)) &&
    163                (rtag7_disable_hash_ipv6_a == 0)) {
    164 
    165         /* ip6_addrs = TRUE; */
    166         rtag7_a_sel = RTAG7_IPV6;
    167         
    168         /* This section will fold the Ipv6 address to single 32 bit address
    169          * by using of of the method of xor */
    170         if (_BCM_SWITCH_PKT_INFO_FLAG_TEST(pkt_info, SRC_IPV6)) {
    171             sip_a =
    172                 ((pkt_info->sip6[12] << 24) |
    173                  (pkt_info->sip6[13] << 16) |
    174                  (pkt_info->sip6[14] << 8) |
    175                  (pkt_info->sip6[15])) ^
    176                 ((pkt_info->sip6[8] << 24) |
    177                  (pkt_info->sip6[9] << 16) |
    178                  (pkt_info->sip6[10] << 8) |
    179                  (pkt_info->sip6[11])) ^
    180                 ((pkt_info->sip6[4] << 24) |
    181                  (pkt_info->sip6[5] << 16) |
    182                  (pkt_info->sip6[6] << 8) |
    183                  (pkt_info->sip6[7])) ^
    184                 ((pkt_info->sip6[0] << 24) |
    185                  (pkt_info->sip6[1] << 16) |
    186                  (pkt_info->sip6[2] << 8) |
    187                  (pkt_info->sip6[3]));
    188             sip_valid = TRUE;
    189         } else {
    190             sip_a = 0;
    191         }
    192 
    193         if (_BCM_SWITCH_PKT_INFO_FLAG_TEST(pkt_info, DST_IPV6)) {
    194             dip_a =
    195                 ((pkt_info->dip6[12] << 24) |
    196                  (pkt_info->dip6[13] << 16) |
    197                  (pkt_info->dip6[14] << 8) |
    198                  (pkt_info->dip6[15])) ^
    199                 ((pkt_info->dip6[8] << 24) |
    200                  (pkt_info->dip6[9] << 16) |
    201                  (pkt_info->dip6[10] << 8) |
    202                  (pkt_info->dip6[11])) ^
    203                 ((pkt_info->dip6[4] << 24) |
    204                  (pkt_info->dip6[5] << 16) |
    205                  (pkt_info->dip6[6] << 8) |
    206                  (pkt_info->dip6[7])) ^
    207                 ((pkt_info->dip6[0] << 24) |
    208                  (pkt_info->dip6[1] << 16) |
    209                  (pkt_info->dip6[2] << 8) |
    210                  (pkt_info->dip6[3]));
    211             dip_valid = TRUE;
    212         } else {
    213             dip_a = 0;
    214         }
    215     } else if ((_BCM_SWITCH_PKT_INFO_FLAG_TEST(pkt_info, ETHERTYPE) &&
    216                 (pkt_info->ethertype == ETHERTYPE_IPV4)) && 
    217                (rtag7_disable_hash_ipv4_a == 0)) {
    218 
    219         /* ip4_addrs = TRUE; */
    220         rtag7_a_sel = RTAG7_IPV4;
    221 
    222         /* only one IPv4 hdr */
    223         if (_BCM_SWITCH_PKT_INFO_FLAG_TEST(pkt_info, SRC_IP)) {
    224             sip_a = pkt_info->sip;
    225             sip_valid = TRUE;
    226         } else {
    227             sip_a = 0;
    228         }
    229         if (_BCM_SWITCH_PKT_INFO_FLAG_TEST(pkt_info, DST_IP)) {
    230             dip_a = pkt_info->dip;
    231             dip_valid = TRUE;
    232         } else {
    233             dip_a = 0;
    234         }
    235     } else {
    236         rtag7_a_sel = RTAG7_L2_ONLY;
    237         sip_a = dip_a = 0;
    238     }
    239 
    240     /* End of option A ip folding for rtag 7 */
    241 
    242     /* option B ip folding for rtag 7 */
    243     if ((_BCM_SWITCH_PKT_INFO_FLAG_TEST(pkt_info, ETHERTYPE) &&
    244          (pkt_info->ethertype == ETHERTYPE_IPV6)) &&
    245                (rtag7_disable_hash_ipv6_b == 0)) {
    246 
    247         /* ip6_addrs = TRUE; */
    248         rtag7_b_sel = RTAG7_IPV6;
    249         
    250         /* This section will fold the Ipv6 address to single 32 bit address
    251          * by using of of the method of xor */
    252         if (_BCM_SWITCH_PKT_INFO_FLAG_TEST(pkt_info, SRC_IPV6)) {
    253             sip_b =
    254                 ((pkt_info->sip6[12] << 24) |
    255                  (pkt_info->sip6[13] << 16) |
    256                  (pkt_info->sip6[14] << 8) |
    257                  (pkt_info->sip6[15])) ^
    258                 ((pkt_info->sip6[8] << 24) |
    259                  (pkt_info->sip6[9] << 16) |
    260                  (pkt_info->sip6[10] << 8) |
    261                  (pkt_info->sip6[11])) ^
    262                 ((pkt_info->sip6[4] << 24) |
    263                  (pkt_info->sip6[5] << 16) |
    264                  (pkt_info->sip6[6] << 8) |
    265                  (pkt_info->sip6[7])) ^
    266                 ((pkt_info->sip6[0] << 24) |
    267                  (pkt_info->sip6[1] << 16) |
    268                  (pkt_info->sip6[2] << 8) |
    269                  (pkt_info->sip6[3]));
    270             sip_valid = TRUE;
    271         } else {
    272             sip_b = 0;
    273         }
    274 
    275         if (_BCM_SWITCH_PKT_INFO_FLAG_TEST(pkt_info, DST_IPV6)) {
    276             dip_b =
    277                 ((pkt_info->dip6[12] << 24) |
    278                  (pkt_info->dip6[13] << 16) |
    279                  (pkt_info->dip6[14] << 8) |
    280                  (pkt_info->dip6[15])) ^
    281                 ((pkt_info->dip6[8] << 24) |
    282                  (pkt_info->dip6[9] << 16) |
    283                  (pkt_info->dip6[10] << 8) |
    284                  (pkt_info->dip6[11])) ^
    285                 ((pkt_info->dip6[4] << 24) |
    286                  (pkt_info->dip6[5] << 16) |
    287                  (pkt_info->dip6[6] << 8) |
    288                  (pkt_info->dip6[7])) ^
    289                 ((pkt_info->dip6[0] << 24) |
    290                  (pkt_info->dip6[1] << 16) |
    291                  (pkt_info->dip6[2] << 8) |
    292                  (pkt_info->dip6[3]));
    293             dip_valid = TRUE;
    294         } else {
    295             dip_b = 0;
    296         }
    297     } else if ((_BCM_SWITCH_PKT_INFO_FLAG_TEST(pkt_info, ETHERTYPE) &&
    298                 (pkt_info->ethertype == ETHERTYPE_IPV4)) && 
    299                (rtag7_disable_hash_ipv4_b == 0)) {
    300 			   
    301        /* ip4_addrs = TRUE; */
    302         rtag7_b_sel = RTAG7_IPV4;
    303 
    304         /* only one IPv4 hdr */
    305         if (_BCM_SWITCH_PKT_INFO_FLAG_TEST(pkt_info, SRC_IP)) {
    306             sip_b = pkt_info->sip;
    307             sip_valid = TRUE;
    308         } else {
    309             sip_b = 0;
    310         }
    311         if (_BCM_SWITCH_PKT_INFO_FLAG_TEST(pkt_info, DST_IP)) {
    312             dip_b = pkt_info->dip;
    313             dip_valid = TRUE;
    314         } else {
    315             dip_b = 0;
    316         }
    317     } else {	
    318         rtag7_b_sel = RTAG7_L2_ONLY;
    319         sip_b = dip_b = 0;
    320     }
    321     /* End of option B ip folding for rtag 7 */
    322 
    323     /*
    324      * =============
    325      * RTAG7 HASHING 
    326      * =============
    327      */
    328 
    329     /* The inputs to the RTAG7 hash function were reduced in the begining
    330      * of this function.  
    331      * This logic takes the hash inputs and computes both A and B RTAG7
    332      * hash values.
    333      */
    334 
    335     /* Change source modid/port to PORT32 space for hashing */
    336     hash_src_port  = hash_res->src_port;
    337     hash_src_modid = hash_res->src_modid;
    338 
    339     /* Only if the packet was sourced by this chip, make sure to use
    340      * PORT32 space modid and port if dual modid is enabled
    341      * Need to do this because of front panel ports.
    342      *
    343      * Already handled by API gport resolve */
    344 
    345     /* initialize the variables */   
    346     sal_memset(hash,0x0,(sizeof(uint32))*13);
    347     sal_memset(hash_word,0x0,(sizeof(uint32))*7);
    348 	
    349     hash_crc16_bisync = 0;
    350     hash_xor8       = 0;
    351     hash_xor4       = 0;
    352     hash_xor2       = 0;
    353     hash_xor1       = 0;
    354     xor32           = 0;
    355 
    356     hash[12] = 0;	
    357     hash[3] = hash_src_port;
    358     hash[2] = hash_src_modid & 0xff;
    359     hash[1] = 0;
    360     hash[0] = 0;
    361 
    362     hash_element_valid_bits = 0x1fff; /* Init to valid fields above */
    363 
    364     /* option A hash calculation for rtag 7 */
    365     
    366     if ((rtag7_a_sel == RTAG7_IPV6) || (rtag7_a_sel == RTAG7_IPV4)) {
    367 
    368         if (sip_valid) {
    369             hash[11] = (sip_a >> 16) & 0xffff;
    370             hash[10] =  sip_a & 0xffff;
    371         } else {
    372             hash_element_valid_bits &= ~0xc00;
    373         }
    374         if (dip_valid) {
    375             hash[9]  = (dip_a >> 16) & 0xffff;
    376             hash[8]  =  dip_a & 0xffff;
    377         } else {
    378             hash_element_valid_bits &= ~0x300;
    379         }
    380 
    381         if (_BCM_SWITCH_PKT_INFO_FLAG_TEST(pkt_info, VLAN)) {
    382             hash[7]  = pkt_info->vid & 0xfff;
    383         } else {
    384             hash_element_valid_bits &= ~0x80;
    385         }
    386         if (_BCM_SWITCH_PKT_INFO_FLAG_TEST(pkt_info, SRC_L4_PORT)) {
    387             hash[6]  = pkt_info->src_l4_port;
    388         } else {
    389             hash_element_valid_bits &= ~0x40;
    390         }
    391         if (_BCM_SWITCH_PKT_INFO_FLAG_TEST(pkt_info, DST_L4_PORT)) {
    392             hash[5]  = pkt_info->dst_l4_port;
    393         } else {
    394             hash_element_valid_bits &= ~0x20;
    395         }
    396         if (_BCM_SWITCH_PKT_INFO_FLAG_TEST(pkt_info, PROTOCOL)) {
    397             hash[4]  = pkt_info->protocol;
    398         } else {
    399             hash_element_valid_bits &= ~0x10;
    400         }
    401 
    402         if (rtag7_a_sel == RTAG7_IPV4) {  /* Use IPv4 BITMAPs */
    403             sc_reg = RTAG7_HASH_FIELD_BMAP_1r;
    404             sc_field = IPV4_FIELD_BITMAP_Af;
    405             LOG_VERBOSE(BSL_LS_BCM_COMMON,
    406                             (BSL_META_U(unit,
    407                                         "Unit %d - Hash calculation: Bitmap is block A IPv4 \n"),
    408                              unit));
    409         } else { /* Use IPv6 BITMAPs */
    410             sc_reg = RTAG7_HASH_FIELD_BMAP_2r;
    411             sc_field = IPV6_FIELD_BITMAP_Af;
    412             LOG_VERBOSE(BSL_LS_BCM_COMMON,
    413                             (BSL_META_U(unit,
    414                                         "Unit %d - Hash calculation: Bitmap is block A IPv6 \n"),
    415                              unit));
    416         }
    417         
    418     } else { /* Catch-all for RTAG7_L2_ONLY */
    419 
    420         /* L2 only hash key */
    421         if (_BCM_SWITCH_PKT_INFO_FLAG_TEST(pkt_info, SRC_MAC)) {
    422             hash[11] = (pkt_info->src_mac[0] << 8) | pkt_info->src_mac[1];
    423             hash[10] = (pkt_info->src_mac[2] << 8) | pkt_info->src_mac[3];
    424             hash[9] = (pkt_info->src_mac[4] << 8) | pkt_info->src_mac[5];
    425         } else {
    426             hash_element_valid_bits &= ~0xe00;
    427         }
    428         if (_BCM_SWITCH_PKT_INFO_FLAG_TEST(pkt_info, DST_MAC)) {
    429             hash[8] = (pkt_info->dst_mac[0] << 8) | pkt_info->dst_mac[1];
    430             hash[7] = (pkt_info->dst_mac[2] << 8) | pkt_info->dst_mac[3];
    431             hash[6] = (pkt_info->dst_mac[4] << 8) | pkt_info->dst_mac[5];
    432         } else {
    433             hash_element_valid_bits &= ~0x1c0;
    434         }
    435 
    436         if (_BCM_SWITCH_PKT_INFO_FLAG_TEST(pkt_info, ETHERTYPE)) {
    437             hash[5] = (pkt_info->ethertype >= ETHERTYPE_MIN) ?
    438                 pkt_info->ethertype : 0;
    439         } else {
    440             hash_element_valid_bits &= ~0x20;
    441         }
    442 
    443         if (_BCM_SWITCH_PKT_INFO_FLAG_TEST(pkt_info, VLAN)) {
    444             hash[4] = pkt_info->vid & 0xfff;
    445         } else {
    446             hash_element_valid_bits &= ~0x10;
    447         }
    448 
    449         sc_reg = RTAG7_HASH_FIELD_BMAP_3r;
    450         sc_field = L2_FIELD_BITMAP_Af;
    451         LOG_VERBOSE(BSL_LS_BCM_COMMON,
    452                     (BSL_META_U(unit,
    453                                 "Unit %d - Hash calculation: Bitmap is block A L2\n"),
    454                      unit));
    455     }
    456 
    457     BCM_IF_ERROR_RETURN
    458         (soc_reg32_get(unit, sc_reg, REG_PORT_ANY, 0, &sc_val));
    459     hash_field_bmap_a = soc_reg_field_get(unit, sc_reg, sc_val, sc_field);
    460 
    461     hash_word[6] = rtag7_hash_seed_a;
    462 
    463     hash_res->hash_a_valid = TRUE;
    464     for (elem = 11; elem >= 0; elem--) {
    465         elem_bit = 1 << elem;
    466         if (0 != (hash_field_bmap_a & elem_bit)) {
    467             if (0 != (hash_element_valid_bits & elem_bit)) {
    468                 hash_word[elem/2] |=
    469                     ((hash[elem] & 0xffff) << (16 * (elem % 2)));
    470             } else {
    471                 hash_res->hash_a_valid = FALSE;
    472                 break;
    473             }
    474         }
    475     }
    476 
    477     /*Calculation*/
    478     xor32 = hash_word[6] ^ hash_word[5] ^ hash_word[4] ^ hash_word[3] ^
    479         hash_word[2] ^ hash_word[1] ^ hash_word[0];
    480 
    481     hash_xor8 = (xor32 & 0xff) ^ ((xor32 >> 8) & 0xff) ^ ((xor32 >> 16) & 0xff) ^ ((xor32 >> 24) & 0xff);
    482     hash_xor4 = (hash_xor8 & 0xf) ^ ((hash_xor8 >> 4) & 0xf);
    483     hash_xor2 = (hash_xor4 & 0x3) ^ ((hash_xor4 >> 2) & 0x3);
    484     hash_xor1 = (hash_xor2 & 0x1) ^ ((hash_xor2 >> 1) & 0x1);
    485 
    486 
    487     hash_crc16_bisync = _shr_crc16_draco_array(hash_word, 28);
    488 
    489     switch (rtag7_hash_a0_function_select) {
    490     case 0: /* reserved */
    491         hash_res->rtag7_hash16_value_a_0 = 0;
    492         break;
    493     case 1: /* reserved */
    494         hash_res->rtag7_hash16_value_a_0 = 0;
    495         break;
    496     case 2: /* reserved */
    497         hash_res->rtag7_hash16_value_a_0 = 0;
    498         break;
    499     case 3: /* CRC16 BISYNC */
    500         hash_res->rtag7_hash16_value_a_0 = hash_crc16_bisync;
    501         break;
    502     case 4: /* CRC16_XOR1 */ 
    503         hash_res->rtag7_hash16_value_a_0 = hash_xor1 & 0x1;
    504         hash_res->rtag7_hash16_value_a_0 |= (((hash_crc16_bisync >> 8) & 0xff) << 8);
    505         break;
    506     case 5: /* CRC16_XOR2 */
    507         hash_res->rtag7_hash16_value_a_0 = hash_xor2 & 0x3;
    508         hash_res->rtag7_hash16_value_a_0 |= (((hash_crc16_bisync >> 8) & 0xff) << 8);
    509         break;
    510     case 6: /* CRC16_XOR4 */ 
    511         hash_res->rtag7_hash16_value_a_0 = hash_xor4 & 0xf;
    512         hash_res->rtag7_hash16_value_a_0 |= (((hash_crc16_bisync >> 8) & 0xff) << 8);
    513         break;
    514     case 7: /* CRC16_XOR8 */
    515         hash_res->rtag7_hash16_value_a_0 = hash_xor8 & 0xff;
    516         hash_res->rtag7_hash16_value_a_0 |= (((hash_crc16_bisync >> 8) & 0xff) << 8);
    517         break;
    518     default: /* reserved */
    519         hash_res->rtag7_hash16_value_a_0 = 0;
    520         break;
    521     }
    522 
    523     hash_res->rtag7_hash16_value_a_1 = 0;
    524 
    525     /* End of option A hash calculation for rtag 7 */
    526 
    527     hash_res->rtag7_macro_flow_id = 0;
    528 
    529     /* option B hash calculation for rtag 7 */
    530 
    531     /* initialize the variables */   
    532 	
    533     sal_memset(hash,0x0,(sizeof(uint32))*13);
    534     sal_memset(hash_word,0x0,(sizeof(uint32))*7);
    535 	
    536     hash_crc16_bisync = 0;
    537     hash_xor8       = 0;
    538     hash_xor4       = 0;
    539     hash_xor2       = 0;
    540     hash_xor1       = 0;
    541     xor32           = 0;
    542  
    543     hash[12] = 0;	
    544     hash[3] = hash_src_port;
    545     hash[2] = hash_src_modid & 0xff;
    546     hash[1] = 0;
    547     hash[0] = 0; 
    548 
    549     hash_element_valid_bits = 0x1fff; /* Init to valid fields above */
    550 
    551     /* option B hash calculation for rtag 7 */
    552     
    553     if ((rtag7_b_sel == RTAG7_IPV6) || (rtag7_b_sel == RTAG7_IPV4)) {
    554         if (sip_valid) {
    555             hash[11] = (sip_b >> 16) & 0xffff;
    556             hash[10] =  sip_b & 0xffff;
    557         } else {
    558             hash_element_valid_bits &= ~0xc00;
    559         }
    560         if (dip_valid) {
    561             hash[9]  = (dip_b >> 16) & 0xffff;
    562             hash[8]  =  dip_b & 0xffff;
    563         } else {
    564             hash_element_valid_bits &= ~0x300;
    565         }
    566 
    567         if (_BCM_SWITCH_PKT_INFO_FLAG_TEST(pkt_info, VLAN)) {
    568             hash[7]  = pkt_info->vid & 0xfff;
    569         } else {
    570             hash_element_valid_bits &= ~0x80;
    571         }
    572         if (_BCM_SWITCH_PKT_INFO_FLAG_TEST(pkt_info, SRC_L4_PORT)) {
    573             hash[6]  = pkt_info->src_l4_port;
    574         } else {
    575             hash_element_valid_bits &= ~0x40;
    576         }
    577         if (_BCM_SWITCH_PKT_INFO_FLAG_TEST(pkt_info, DST_L4_PORT)) {
    578             hash[5]  = pkt_info->dst_l4_port;
    579         } else {
    580             hash_element_valid_bits &= ~0x20;
    581         }
    582         if (_BCM_SWITCH_PKT_INFO_FLAG_TEST(pkt_info, PROTOCOL)) {
    583             hash[4]  = pkt_info->protocol;
    584         } else {
    585             hash_element_valid_bits &= ~0x10;
    586         }
    587 
    588         if (rtag7_b_sel == RTAG7_IPV4) {  /* Use IPv4 BITMAPs */
    589             sc_reg = RTAG7_HASH_FIELD_BMAP_1r;
    590             sc_field = IPV4_FIELD_BITMAP_Bf;
    591             LOG_VERBOSE(BSL_LS_BCM_COMMON,
    592                             (BSL_META_U(unit,
    593                                         "Unit %d - Hash calculation: Bitmap is block B IPv4\n"),
    594                              unit));
    595         } else { /* Use IPv6 BITMAPs */
    596             sc_reg = RTAG7_HASH_FIELD_BMAP_2r;
    597             sc_field = IPV6_FIELD_BITMAP_Bf;
    598             LOG_VERBOSE(BSL_LS_BCM_COMMON,
    599                             (BSL_META_U(unit,
    600                                         "Unit %d - Hash calculation: Bitmap is block B IPv6\n"),
    601                              unit));
    602         }
    603     } else { /* Catch-all for RTAG7_L2_ONLY */
    604 
    605         /* L2 only hash key */
    606         if (_BCM_SWITCH_PKT_INFO_FLAG_TEST(pkt_info, SRC_MAC)) {
    607             hash[11] = (pkt_info->src_mac[0] << 8) | pkt_info->src_mac[1];
    608             hash[10] = (pkt_info->src_mac[2] << 8) | pkt_info->src_mac[3];
    609             hash[9] = (pkt_info->src_mac[4] << 8) | pkt_info->src_mac[5];
    610         } else {
    611             hash_element_valid_bits &= ~0xe00;
    612         }
    613         if (_BCM_SWITCH_PKT_INFO_FLAG_TEST(pkt_info, DST_MAC)) {
    614             hash[8] = (pkt_info->dst_mac[0] << 8) | pkt_info->dst_mac[1];
    615             hash[7] = (pkt_info->dst_mac[2] << 8) | pkt_info->dst_mac[3];
    616             hash[6] = (pkt_info->dst_mac[4] << 8) | pkt_info->dst_mac[5];
    617         } else {
    618             hash_element_valid_bits &= ~0x1c0;
    619         }
    620 
    621         if (_BCM_SWITCH_PKT_INFO_FLAG_TEST(pkt_info, ETHERTYPE)) {
    622             hash[5] = (pkt_info->ethertype >= ETHERTYPE_MIN) ?
    623                 pkt_info->ethertype : 0;
    624         } else {
    625             hash_element_valid_bits &= ~0x20;
    626         }
    627 
    628         if (_BCM_SWITCH_PKT_INFO_FLAG_TEST(pkt_info, VLAN)) {
    629             hash[4] = pkt_info->vid & 0xfff;
    630         } else {
    631             hash_element_valid_bits &= ~0x10;
    632         }
    633 
    634         sc_reg = RTAG7_HASH_FIELD_BMAP_3r;
    635         sc_field = L2_FIELD_BITMAP_Bf;
    636         LOG_VERBOSE(BSL_LS_BCM_COMMON,
    637                     (BSL_META_U(unit,
    638                                 "Unit %d - Hash calculation: Bitmap is block B L2\n"),
    639                      unit));
    640     }
    641 
    642     BCM_IF_ERROR_RETURN
    643         (soc_reg32_get(unit, sc_reg, REG_PORT_ANY, 0, &sc_val));
    644     hash_field_bmap_b = soc_reg_field_get(unit, sc_reg, sc_val, sc_field);
    645 
    646     hash_word[6] = rtag7_hash_seed_b;
    647 
    648     hash_res->hash_b_valid = TRUE;
    649     for (elem = 11; elem >= 0; elem--) {
    650         elem_bit = 1 << elem;
    651         if (0 != (hash_field_bmap_b & elem_bit)) {
    652             if (0 != (hash_element_valid_bits & elem_bit)) {
    653                 hash_word[elem/2] |=
    654                     ((hash[elem] & 0xffff) << (16 * (elem % 2)));
    655             } else {
    656                 hash_res->hash_b_valid = FALSE;
    657                 break;
    658             }
    659         }
    660     }
    661 
    662     xor32 = hash_word[6] ^ hash_word[5] ^ hash_word[4] ^ hash_word[3] ^
    663         hash_word[2] ^ hash_word[1] ^ hash_word[0];
    664 
    665     hash_xor8 = (xor32 & 0xff) ^ ((xor32 >> 8) & 0xff) ^ ((xor32 >> 16) & 0xff) ^ ((xor32 >> 24) & 0xff);
    666     hash_xor4 = (hash_xor8 & 0xf) ^ ((hash_xor8 >> 4) & 0xf);
    667     hash_xor2 = (hash_xor4 & 0x3) ^ ((hash_xor4 >> 2) & 0x3);
    668     hash_xor1 = (hash_xor2 & 0x1) ^ ((hash_xor2 >> 1) & 0x1);
    669 
    670     hash_crc16_bisync = _shr_crc16_draco_array(hash_word, 28);
    671 
    672     switch (rtag7_hash_b0_function_select) {
    673     case 0: /* reserved */
    674         hash_res->rtag7_hash16_value_b_0 = 0;
    675         break;
    676     case 1: /* reserved */
    677         hash_res->rtag7_hash16_value_b_0 = 0;
    678         break;
    679     case 2: /* reserved */
    680         hash_res->rtag7_hash16_value_b_0 = 0;
    681         break;
    682     case 3: /* CRC16 BISYNC */
    683         hash_res->rtag7_hash16_value_b_0 = hash_crc16_bisync;
    684         break;
    685     case 4: /* CRC16_XOR1 */ 
    686         hash_res->rtag7_hash16_value_b_0 = hash_xor1 & 0x1;
    687         hash_res->rtag7_hash16_value_b_0 |= (((hash_crc16_bisync >> 8) & 0xff) << 8);
    688         break;
    689     case 5: /* CRC16_XOR2 */
    690         hash_res->rtag7_hash16_value_b_0 = hash_xor2 & 0x3;
    691         hash_res->rtag7_hash16_value_b_0 |= (((hash_crc16_bisync >> 8) & 0xff) << 8);
    692         break;
    693     case 6: /* CRC16_XOR4 */ 
    694         hash_res->rtag7_hash16_value_b_0 = hash_xor4 & 0xf;
    695         hash_res->rtag7_hash16_value_b_0 |= (((hash_crc16_bisync >> 8) & 0xff) << 8);
    696         break;
    697     case 7: /* CRC16_XOR8 */
    698         hash_res->rtag7_hash16_value_b_0 = hash_xor8 & 0xff;
    699         hash_res->rtag7_hash16_value_b_0 |= (((hash_crc16_bisync >> 8) & 0xff) << 8);
    700         break;
    701     default: /* reserved */
    702         hash_res->rtag7_hash16_value_b_0 = 0;
    703         break;
    704     }
    705 
    706     hash_res->rtag7_hash16_value_b_1 = 0;
    707 
    708     /* End of option B hash calculation for rtag 7 */
    709     return BCM_E_NONE;
    710 }
    711 
    712 /*----------------------------------------------------------------*/
    713 
    714 
    715 
    716 STATIC int
    717 select_en_hash_subfield(int hash_sub_sel, uint32 *selected_subfield,
    718                      bcm_rtag7_base_hash_t *hash_Base)
    719 {
    720     int rv = BCM_E_NONE;
    721     *selected_subfield = 0;
    722 
    723     switch (hash_sub_sel) {
    724         case 0: /* select pkt hash A */
    725             *selected_subfield = hash_Base->rtag7_hash16_value_a_0;
    726             if (!hash_Base->hash_a_valid) {
    727                 /* Missing paramter in input */
    728                 rv = BCM_E_PARAM;
    729             }
    730             break;
    731 
    732         case 1: /* select pkt hash B */
    733             *selected_subfield = hash_Base->rtag7_hash16_value_b_0;
    734             if (!hash_Base->hash_b_valid) {
    735                 /* Missing paramter in input */
    736                 rv = BCM_E_PARAM;
    737             }
    738             break;
    739 
    740         case 2: /* select port LBN */
    741             *selected_subfield = hash_Base->rtag7_port_lbn;
    742             break;
    743 
    744         case 3: /* select destination port id or hash A */
    745             
    746             *selected_subfield = hash_Base->rtag7_hash16_value_a_0;
    747             if (!hash_Base->hash_a_valid) {
    748                 /* Missing paramter in input */
    749                 rv = BCM_E_PARAM;
    750             }
    751             break;
    752 
    753         case 4: /* select LBID from module header or from SW1 stage */ 
    754             *selected_subfield = hash_Base->rtag7_lbid_hash; 
    755             if (!hash_Base->lbid_hash_valid) {
    756                 /* LBID setting isn't RTAG7 */
    757                 rv = BCM_E_CONFIG;
    758             }
    759             break;
    760 
    761         case 5: /* select LBID from SW1 stage */
    762             *selected_subfield = hash_Base->rtag7_lbid_hash;
    763             if (!hash_Base->lbid_hash_valid) {
    764                 /* LBID setting isn't RTAG7 */
    765                 rv = BCM_E_CONFIG;
    766             }
    767             break;
    768 
    769         case 6:
    770         case 7:
    771             break;
    772     }
    773 
    774     return rv;
    775 }
    776 
    777 
    778 STATIC int
    779 main__en_compute_lbid(int unit, bcm_rtag7_base_hash_t *hash_Base)
    780 {
    781     /*regular var declaration*/
    782     uint32 lbid_hash_sub_sel;
    783     uint32 lbid_hash_offset;
    784     uint32 lbid_hash_value = 0;
    785 
    786     /*register var declaration*/
    787     int lbid_rtag;
    788     uint8 rtag7_hash_cfg_sel_lbid;
    789     uint32 rtag7_hash_lbid_reg;
    790     int pc_out, sc_val, lbid_idx, rv = BCM_E_NONE;
    791 	
    792     /*register read*/
    793     BCM_IF_ERROR_RETURN
    794         (bcm_esw_port_control_get(unit, hash_Base->dev_src_port,
    795                                   bcmPortControlLoadBalancingNumber,
    796                                   &pc_out)); 
    797     rtag7_hash_cfg_sel_lbid = pc_out;
    798     BCM_IF_ERROR_RETURN
    799         (bcm_esw_switch_control_get(unit, bcmSwitchLoadBalanceHashSelect,
    800                                     &sc_val));
    801     lbid_rtag = sc_val;
    802 	
    803     /* ******************* LBID computation ************************* */
    804 
    805     if (lbid_rtag == 7) {
    806         lbid_idx = (0 != rtag7_hash_cfg_sel_lbid) ? 1 : 0;
    807         SOC_IF_ERROR_RETURN
    808             (READ_RTAG7_HASH_LBIDr(unit, lbid_idx, &rtag7_hash_lbid_reg));
    809         if (hash_Base->is_nonuc) {
    810             lbid_hash_sub_sel =
    811                 soc_reg_field_get(unit, RTAG7_HASH_LBIDr,
    812                                   rtag7_hash_lbid_reg, SUB_SEL_NONUCf);
    813             lbid_hash_offset =
    814                 soc_reg_field_get(unit, RTAG7_HASH_LBIDr,
    815                                   rtag7_hash_lbid_reg, OFFSET_NONUCf);
    816         } else {
    817             lbid_hash_sub_sel =
    818                 soc_reg_field_get(unit, RTAG7_HASH_LBIDr,
    819                                   rtag7_hash_lbid_reg, SUB_SEL_UCf);
    820             lbid_hash_offset =
    821                 soc_reg_field_get(unit, RTAG7_HASH_LBIDr,
    822                                   rtag7_hash_lbid_reg, OFFSET_UCf);
    823         }		
    824         /* Only UC hash selects apply to ECMP */
    825         switch (lbid_hash_sub_sel) {
    826 		
    827         case 0: /* use pkt hash A */
    828             lbid_hash_value = hash_Base->rtag7_hash16_value_a_0;
    829             if (!hash_Base->hash_a_valid) {
    830                 /* Missing paramter in input */
    831                 rv = BCM_E_PARAM;
    832             }
    833             break;
    834 		
    835         case 1: /* use pkt hash B */
    836             lbid_hash_value = hash_Base->rtag7_hash16_value_b_0;
    837             if (!hash_Base->hash_b_valid) {
    838                 /* Missing paramter in input */
    839                 rv = BCM_E_PARAM;
    840             }
    841             break;
    842 		
    843         case 2: /* Use LBN */
    844             lbid_hash_value = hash_Base->rtag7_port_lbn;
    845             break;
    846 		
    847         case 3: /* Use Destination PORTID or hash A */
    848             lbid_hash_value = hash_Base->rtag7_hash16_value_a_0;
    849             if (!hash_Base->hash_a_valid) {
    850                 /* Missing paramter in input */
    851                 rv = BCM_E_PARAM;
    852             }
    853             break;
    854 		
    855         case 4: /* Use LBID */
    856             /* Higig lookup use mh_higig2_lbid */
    857 				
    858             lbid_hash_value = 0;
    859             break;
    860 		
    861         case 5:
    862         case 6:
    863         case 7:
    864             lbid_hash_value = 0;
    865             break;
    866         }
    867 		
    868         /*
    869          * set up the hash value so that the LSB bits are
    870          * barrel shifted in case offset > 8.
    871          */
    872         lbid_hash_value |= ((lbid_hash_value & 0xffff) << 16);
    873 		
    874         /* Only UC hash offsets apply to ECMP */
    875         lbid_hash_value = (lbid_hash_value >> lbid_hash_offset);
    876 		
    877         hash_Base->rtag7_lbid_hash = (lbid_hash_value & 0xff);
    878         hash_Base->lbid_hash_valid = TRUE;
    879 
    880     } else { /* LBID rtag is 0-6 */        
    881         /* this function not support the rtag 0-6 */
    882 		
    883         LOG_VERBOSE(BSL_LS_BCM_COMMON,
    884                     (BSL_META_U(unit,
    885                                 "Unit %d - Hash calculation: This function doesn't support rtag 0 6 pls change register ING_CONFIG.LBID_RTAG to value 7\n"),
    886                      unit));
    887         hash_Base->rtag7_lbid_hash = 0;
    888         hash_Base->lbid_hash_valid = FALSE;
    889     }
    890     return rv;
    891     /* ******************* END of LBID computation ************************* */
    892 }
    893 
    894 #ifdef INCLUDE_L3
    895 STATIC int
    896 compute_en_ecmp_hash(int unit, bcm_rtag7_base_hash_t *hash_Base,
    897                   uint32 *hash_val)
    898 {
    899     /*regular var declaration*/
    900     uint32 hash_sub_sel;
    901     uint32 hash_offset;
    902     uint32 hash_subfield;
    903     uint32 rtag7_ecmp_hash_value;
    904     uint8 rtag7_ecmp_use_macro_flow_hash;
    905     uint8 ecmp_hash_use_rtag7;
    906     uint32 rtag7_hash_ecmp;
    907     uint32 hash_control;
    908     int pc_out, ecmp_idx;
    909     rtag7_flow_based_hash_entry_t rt7_fbh_entry;
    910 
    911     /*register read*/
    912     BCM_IF_ERROR_RETURN
    913         (bcm_esw_port_control_get(unit, hash_Base->dev_src_port,
    914                                   bcmPortControlECMPHashSet,
    915                                   &pc_out));
    916     ecmp_idx = (0 != pc_out) ? 1 : 0;
    917 
    918     SOC_IF_ERROR_RETURN
    919         (READ_RTAG7_HASH_ECMPr(unit, ecmp_idx, &rtag7_hash_ecmp));
    920     if (soc_reg_field_valid(unit, RTAG7_HASH_ECMPr, USE_FLOW_HASHf)) {
    921         rtag7_ecmp_use_macro_flow_hash =
    922             soc_reg_field_get(unit, RTAG7_HASH_ECMPr,
    923                               rtag7_hash_ecmp, USE_FLOW_HASHf);
    924     } else {
    925         /* A0 bincomp value */
    926         rtag7_ecmp_use_macro_flow_hash = 0;
    927     }
    928 
    929     SOC_IF_ERROR_RETURN
    930         (READ_HASH_CONTROLr(unit, &hash_control));
    931     ecmp_hash_use_rtag7 =
    932         soc_reg_field_get(unit, HASH_CONTROLr, hash_control,
    933                           ECMP_HASH_USE_RTAG7f);
    934 
    935     /* RTAG7 hash computation */
    936 
    937     if (rtag7_ecmp_use_macro_flow_hash) {
    938         SOC_IF_ERROR_RETURN
    939             (soc_mem_read(unit, RTAG7_FLOW_BASED_HASHm, MEM_BLOCK_ANY,
    940                           (hash_Base->rtag7_macro_flow_id & 0xff),
    941                           &rt7_fbh_entry));
    942 
    943         /* Generating RTAG7 Macro Flow Based Hash Subsel and Offset for use in RSEL1 Stage */
    944         /* For future designs this logic can be placed in RSEL1 */
    945 
    946         hash_sub_sel = soc_mem_field32_get(unit, RTAG7_FLOW_BASED_HASHm,
    947                                            &rt7_fbh_entry, SUB_SEL_ECMPf);
    948         hash_offset  = soc_mem_field32_get(unit, RTAG7_FLOW_BASED_HASHm,
    949                                            &rt7_fbh_entry, OFFSET_ECMPf);
    950 
    951     } else if (SOC_REG_IS_VALID(unit, RTAG7_HASH_ECMPr)) {
    952         hash_sub_sel =
    953             soc_reg_field_get(unit, RTAG7_HASH_ECMPr,
    954                               rtag7_hash_ecmp, SUB_SELf);
    955         hash_offset =
    956             soc_reg_field_get(unit, RTAG7_HASH_ECMPr,
    957                               rtag7_hash_ecmp, OFFSETf);
    958     } else {
    959         /* A0 bincomp values */
    960         hash_sub_sel = 0;
    961         hash_offset  = 0;
    962     }
    963 
    964     BCM_IF_ERROR_RETURN
    965         (select_en_hash_subfield(hash_sub_sel, &hash_subfield, hash_Base));
    966 
    967     /* Barrel shift the hash subfield, then take the LSB 5 bits */
    968     rtag7_ecmp_hash_value = ((hash_subfield >> hash_offset) | (hash_subfield << (16 - hash_offset))) & 0x1f;
    969 	
    970     /* Select between non-RTAG7 hash value and RTAG7 hash value */
    971 
    972     if (ecmp_hash_use_rtag7 == 0) {
    973         LOG_VERBOSE(BSL_LS_BCM_COMMON,
    974                     (BSL_META_U(unit,
    975                                 "Unit %d - Hash calculation:  non rtag7 calc not supported\n"),
    976                      unit));
    977         *hash_val =  0;
    978     } else {
    979         *hash_val =  rtag7_ecmp_hash_value;
    980     }
    981 
    982     return BCM_E_NONE;
    983     /* ***************** END of ECMP HASH CALCULATIONS.  ************************ */
    984 }
    985 #endif /* INCLUDE_L3 */
    986 
    987 STATIC int
    988 compute_en_rtag7_hash_trunk(int unit , bcm_rtag7_base_hash_t *hash_Base,
    989                          uint32 *hash_value)
    990 {
    991     uint32 hash_sub_sel;
    992     uint32 hash_offset;    
    993     uint32 hash_subfield;
    994     uint32 rtag7_hash_trunk;
    995     uint32 rtag7_hash_trunk_value;
    996     int offset_shift;
    997     int pc_out, trunk_idx;
    998     uint32 hash_control;
    999     uint32 nuc_trunk_hash_use_rtag7;
   1000 
   1001     BCM_IF_ERROR_RETURN
   1002         (bcm_esw_port_control_get(unit, hash_Base->dev_src_port,
   1003                                   bcmPortControlTrunkHashSet,
   1004                                   &pc_out));
   1005     trunk_idx = (0 != pc_out) ? 1 : 0;
   1006     SOC_IF_ERROR_RETURN
   1007         (READ_RTAG7_HASH_TRUNKr(unit, trunk_idx, &rtag7_hash_trunk));
   1008 
   1009     /* Compute RTAG7 hash for trunking */
   1010     if(hash_Base->is_nonuc) {
   1011         hash_sub_sel =
   1012             soc_reg_field_get(unit, RTAG7_HASH_TRUNKr,
   1013                               rtag7_hash_trunk, SUB_SEL_NONUCf);
   1014         hash_offset =
   1015             soc_reg_field_get(unit, RTAG7_HASH_TRUNKr,
   1016                               rtag7_hash_trunk, OFFSET_NONUCf);
   1017         offset_shift = 0xff;
   1018     } else {
   1019         hash_sub_sel =
   1020             soc_reg_field_get(unit, RTAG7_HASH_TRUNKr,
   1021                               rtag7_hash_trunk, SUB_SEL_UCf);
   1022         hash_offset =
   1023             soc_reg_field_get(unit, RTAG7_HASH_TRUNKr,
   1024                               rtag7_hash_trunk, OFFSET_UCf);
   1025         offset_shift = 0xff;
   1026     }        
   1027 
   1028     BCM_IF_ERROR_RETURN
   1029         (select_en_hash_subfield(hash_sub_sel, &hash_subfield, hash_Base));
   1030 
   1031     /* Barrel shift the hash subfield, then take the LSB 8 bits */
   1032     rtag7_hash_trunk_value = ((hash_subfield >> hash_offset) | (hash_subfield << (16 - hash_offset))) & offset_shift; 
   1033 
   1034     /* Compute the trunk_member_table index
   1035      *  trunk_index = trunk_hash % (trunk_group_size + 1);
   1036      *   Irsel2_rsel2__trunk_member_table_index =
   1037      *        (trunk_base_ptr + trunk_index) & 0x7ff;
   1038      */
   1039 
   1040     *hash_value = rtag7_hash_trunk_value;
   1041 
   1042     LOG_VERBOSE(BSL_LS_BCM_COMMON,
   1043                 (BSL_META_U(unit,
   1044                             "Unit %d - Trunk hash_value=%d\n"),
   1045                  unit, *hash_value));
   1046 
   1047     BCM_IF_ERROR_RETURN
   1048         (READ_HASH_CONTROLr(unit, &hash_control));
   1049     nuc_trunk_hash_use_rtag7 =
   1050         soc_reg_field_get(unit, HASH_CONTROLr, hash_control,
   1051                           NON_UC_TRUNK_HASH_USE_RTAG7f);
   1052 
   1053     if (hash_Base->is_nonuc && nuc_trunk_hash_use_rtag7 == 0) {
   1054         LOG_VERBOSE(BSL_LS_BCM_COMMON,
   1055                     (BSL_META_U(unit,
   1056                                 "Unit %d - NonUC trunk Hash calculation:  non rtag7 calc not supported\n"),
   1057                      unit));
   1058         *hash_value = 0;
   1059     }
   1060 
   1061     return BCM_E_NONE;
   1062 }
   1063  
   1064 STATIC int
   1065 get_en_hash_trunk(int unit, int tgid, uint32 hash_index, bcm_gport_t *dst_gport)
   1066 {
   1067     uint32 trunk_group_size;    
   1068     uint32 rtag;
   1069     uint32 trunk_index;
   1070     bcm_module_t mod_id;
   1071     bcm_port_t port_id;
   1072     int mod_is_local;
   1073     trunk_group_entry_t  tg_entry;
   1074     _bcm_gport_dest_t   dest;
   1075     
   1076     BCM_IF_ERROR_RETURN
   1077         (READ_TRUNK_GROUPm(unit, MEM_BLOCK_ANY, tgid, &tg_entry));
   1078 
   1079     trunk_group_size = soc_TRUNK_GROUPm_field32_get(unit, &tg_entry,
   1080                                                     TG_SIZEf);
   1081     rtag = soc_TRUNK_GROUPm_field32_get(unit, &tg_entry, RTAGf);
   1082                 
   1083     if (rtag != 7){
   1084         LOG_VERBOSE(BSL_LS_BCM_COMMON,
   1085                      (BSL_META_U(unit,
   1086                                  "Unit %d - Hash calculation: uport only RTAG7 calc no support for rtag %d\n"),
   1087                       unit, rtag));
   1088     }
   1089 
   1090     trunk_index = hash_index % (trunk_group_size + 1);
   1091 
   1092    LOG_VERBOSE(BSL_LS_BCM_COMMON,
   1093                 (BSL_META_U(unit,
   1094                             "\tTrunk HW index 0x%08x\n"),
   1095                  trunk_index));
   1096     LOG_VERBOSE(BSL_LS_BCM_COMMON,
   1097                 (BSL_META_U(unit,
   1098                             "\tTrunk group size 0x%08x\n"),
   1099                  trunk_group_size));
   1100 
   1101     mod_id = soc_TRUNK_GROUPm_field32_get(unit, &tg_entry,
   1102                                           _xgs_modulef[trunk_index]);
   1103     port_id = soc_TRUNK_GROUPm_field32_get(unit, &tg_entry,
   1104                                            _xgs_portf[trunk_index]);
   1105 
   1106     BCM_IF_ERROR_RETURN
   1107         (_bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_GET, mod_id, port_id,
   1108                                         &(dest.modid), &(dest.port)));
   1109     dest.gport_type = _SHR_GPORT_TYPE_MODPORT;
   1110 
   1111     BCM_IF_ERROR_RETURN
   1112         (_bcm_esw_modid_is_local(unit, dest.modid,
   1113                                  &mod_is_local));
   1114     if (mod_is_local) {
   1115         if (IS_ST_PORT(unit, dest.port)) {
   1116             dest.gport_type = _SHR_GPORT_TYPE_DEVPORT;
   1117         }
   1118     }
   1119 
   1120     BCM_IF_ERROR_RETURN(_bcm_esw_gport_construct(unit, &dest, dst_gport));
   1121 
   1122     return BCM_E_NONE;  
   1123 }
   1124 
   1125 /*
   1126  * Function:
   1127  *     get_en_hash_trunk_nuc
   1128  * Description:
   1129  *     Compute non-unicast destination trunk member port 
   1130  * Parameters:
   1131  *  unit - StrataSwitch PCI device unit number (driver internal).
   1132  *  tgid - Trunk group id
   1133  *  fwd_reason - Flow foward reason. unicast, ipmc, l2mc, broadcast, dlf.
   1134  *  hash_index - Hash value calculated based on RTAG7
   1135  *  dst_gport  - Where egress member port id is stored
   1136  *
   1137  * Returns:
   1138  *      BCM_E_xxxx
   1139  */
   1140 STATIC int
   1141 get_en_hash_trunk_nuc(int unit, int tgid, 
   1142                    bcm_switch_pkt_hash_info_fwd_reason_t fwd_reason, 
   1143                    uint32 hash_index, bcm_gport_t *dst_gport)
   1144 {
   1145     int nuc_type;
   1146     int nonuc_trunk_block_mask_index;
   1147     int region_size, i, all_local;
   1148     int member_index, member_count;
   1149     int modid, modid_tmp, port, tid, id, mod_is_local;
   1150     int port_index, count;
   1151     bcm_pbmp_t pbmp, local_pbmp;
   1152     bcm_trunk_info_t   t_add_info;
   1153     bcm_trunk_member_t member_array[BCM_TRUNK_MAX_PORTCNT];
   1154     trunk_bitmap_entry_t trunk_bitmap_entry;
   1155 
   1156     switch(fwd_reason) {
   1157     case bcmSwitchPktHashInfoFwdReasonIpmc:
   1158         nuc_type = TRUNK_BLOCK_MASK_TYPE_IPMC;
   1159         break;
   1160     case bcmSwitchPktHashInfoFwdReasonL2mc:
   1161         nuc_type = TRUNK_BLOCK_MASK_TYPE_L2MC;
   1162         break;
   1163     case bcmSwitchPktHashInfoFwdReasonBcast:
   1164         nuc_type = TRUNK_BLOCK_MASK_TYPE_BCAST;
   1165         break;
   1166     case bcmSwitchPktHashInfoFwdReasonDlf:
   1167         nuc_type = TRUNK_BLOCK_MASK_TYPE_DLF;
   1168         break;
   1169     default:
   1170         return BCM_E_PARAM;
   1171     }
   1172     nonuc_trunk_block_mask_index = (nuc_type << 4) | (hash_index & 0xf);
   1173 
   1174     LOG_VERBOSE(BSL_LS_BCM_COMMON,
   1175                 (BSL_META_U(unit,
   1176                             "Unit %d - Nonuc-trunk table index = %d\n"), 
   1177                  unit, nonuc_trunk_block_mask_index));
   1178 
   1179     region_size = soc_mem_index_count(unit, NONUCAST_TRUNK_BLOCK_MASKm) / 4;
   1180 
   1181     BCM_IF_ERROR_RETURN(
   1182         bcm_esw_trunk_get(unit, tgid, &t_add_info, BCM_TRUNK_MAX_PORTCNT,
   1183             member_array, &member_count));
   1184 
   1185     BCM_IF_ERROR_RETURN(
   1186         READ_TRUNK_BITMAPm(unit, MEM_BLOCK_ANY, tgid, &trunk_bitmap_entry));
   1187     BCM_PBMP_CLEAR(pbmp);
   1188     BCM_PBMP_CLEAR(local_pbmp);
   1189     soc_mem_pbmp_field_get(unit, TRUNK_BITMAPm, &trunk_bitmap_entry,
   1190                                     TRUNK_BITMAPf, &local_pbmp);
   1191     BCM_PBMP_COUNT(local_pbmp, count);
   1192     all_local = FALSE;
   1193     if (count == member_count) {
   1194         all_local = TRUE;
   1195     }
   1196     if (all_local || member_count > BCM_SWITCH_TRUNK_MAX_PORTCNT) {
   1197         member_index = 
   1198             (nonuc_trunk_block_mask_index % region_size) % member_count;
   1199     } else {
   1200         member_index = 
   1201             (nonuc_trunk_block_mask_index % BCM_XGS3_TRUNK_MAX_PORTCNT) % member_count;
   1202     }
   1203 
   1204     BCM_IF_ERROR_RETURN
   1205         (_bcm_esw_gport_resolve(unit, member_array[member_index].gport,
   1206                                 &modid, &port, &tid, &id));
   1207     port_index = 0;
   1208     for (i = 0; i < member_count; i++) {
   1209         BCM_IF_ERROR_RETURN
   1210             (_bcm_esw_gport_resolve(unit, member_array[i].gport,
   1211                                 &modid_tmp, &port, &tid, &id));
   1212         if (modid_tmp == modid) {
   1213             if (i <= member_index) {
   1214                 port_index++;
   1215             }
   1216             BCM_PBMP_PORT_ADD(pbmp, port);
   1217         }
   1218     }
   1219 
   1220     count = 0;
   1221     BCM_PBMP_ITER(pbmp, port) {
   1222         count++;
   1223         if (count == port_index) {
   1224             break;
   1225         }
   1226     }
   1227 
   1228     if (count != port_index) {
   1229         return BCM_E_FAIL;
   1230     }
   1231     
   1232     BCM_IF_ERROR_RETURN
   1233         (_bcm_esw_modid_is_local(unit, modid, &mod_is_local));
   1234 
   1235     if (mod_is_local && IS_ST_PORT(unit, port)) {
   1236         BCM_GPORT_DEVPORT_SET(*dst_gport, unit, port);
   1237     } else {
   1238         BCM_GPORT_MODPORT_SET(*dst_gport, modid, port);
   1239     }
   1240 
   1241     return BCM_E_NONE;
   1242 }
   1243 
   1244 #ifdef INCLUDE_L3
   1245 STATIC int
   1246 get_en_hash_ecmp(int unit, int ecmp_group, uint32 hash_index, bcm_if_t *nh_id)
   1247 {
   1248     ecmp_count_entry_t ecmpc_entry;
   1249     ecmp_entry_t ecmp_entry;
   1250     uint32 ecmp_ptr = 0;
   1251     uint32 ecmp_count = 0;
   1252                 
   1253     uint32 ecmp_mask;
   1254     uint32 ecmp_offset;
   1255     uint32 ecmp_index;
   1256 
   1257     /* pick up the ecmp count */
   1258     BCM_IF_ERROR_RETURN
   1259         (READ_L3_ECMP_COUNTm(unit, MEM_BLOCK_ANY, ecmp_group, &ecmpc_entry));
   1260 
   1261     /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
   1262      * A ECMP_COUNT value of 0 implies 1 entry 
   1263      * a value of 1 implies 2 entries etc...
   1264      * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
   1265      */
   1266     ecmp_mask = 0x7ff;
   1267     ecmp_count =
   1268         soc_L3_ECMP_COUNTm_field32_get(unit, &ecmpc_entry,
   1269                                            COUNTf);
   1270     ecmp_offset = (hash_index % (ecmp_count + 1)) & 0x1F;
   1271     LOG_VERBOSE(BSL_LS_BCM_COMMON,
   1272                 (BSL_META_U(unit,
   1273                             "\tECMP offset 0x%08x\n"),
   1274                  ecmp_offset));
   1275     if (!BCM_XGS3_L3_EGRESS_MODE_ISSET(unit)) {
   1276         ecmp_group *= BCM_XGS3_L3_ECMP_MAX_PATHS(unit);
   1277     }
   1278     ecmp_ptr = (ecmp_group & ecmp_mask);
   1279     ecmp_index = (ecmp_ptr + ecmp_offset) & ecmp_mask;
   1280     BCM_IF_ERROR_RETURN
   1281         (READ_L3_ECMPm(unit, MEM_BLOCK_ANY, ecmp_index, &ecmp_entry));
   1282 
   1283     *nh_id =
   1284         soc_L3_ECMPm_field32_get(unit, &ecmp_entry,
   1285                                  NEXT_HOP_INDEXf) & 0x3fff;
   1286     LOG_VERBOSE(BSL_LS_BCM_COMMON,
   1287                 (BSL_META_U(unit,
   1288                             "\tECMP next hop HW index 0x%08x\n"),
   1289                  *nh_id));
   1290 
   1291     return BCM_E_NONE;  
   1292 }
   1293 #endif /* INCLUDE_L3 */
   1294 
   1295 /*
   1296  * Function:
   1297  *          compute_en_rtag7_hash_hg_trunk
   1298  * Description:
   1299  *     get HGT hash value from RTAG7_PORT_BASED_HASHm 
   1300  *     if unicast, SUB_SEL_TRUNK_UCf and OFFSET_TRUNK_UCf are used 
   1301  *     if not unicast, SUB_SEL_TRUNK_NONUCf and OFFSET_TRUNK_NONUCf
   1302  *     if flow hash is used, get subsel and offset from RTAG7_FLOW_BASED_HASH 
   1303  * Parameters:
   1304  *          unit - StrataSwitch PCI device unit number (driver internal).
   1305  *          hash_Base - internal data where trunk hash value is storead
   1306  *          hash_value- result param 
   1307  * Returns:
   1308  *      BCM_E_xxxx
   1309  */
   1310 STATIC int
   1311 compute_en_rtag7_hash_hg_trunk(int unit , bcm_rtag7_base_hash_t *hash_Base,
   1312                          uint32 *hash_value)
   1313 {
   1314     uint32 hash_sub_sel;
   1315     uint32 hash_offset;    
   1316     uint32 hash_subfield;
   1317     uint32 rtag7_hash_hg_trunk;
   1318     uint32 rtag7_hash_hg_trunk_value;
   1319     int offset_shift;
   1320     int pc_out, trunk_idx;
   1321 
   1322     BCM_IF_ERROR_RETURN
   1323         (bcm_esw_port_control_get(unit, hash_Base->dev_src_port,
   1324                                   bcmPortControlFabricTrunkHashSet,
   1325                                   &pc_out));
   1326     trunk_idx = (0 != pc_out) ? 1 : 0;
   1327     SOC_IF_ERROR_RETURN
   1328         (READ_RTAG7_HASH_HG_TRUNKr(unit, trunk_idx, &rtag7_hash_hg_trunk));
   1329 
   1330     /* Compute RTAG7 hash for trunking */
   1331     if(hash_Base->is_nonuc) {
   1332         hash_sub_sel =
   1333             soc_reg_field_get(unit, RTAG7_HASH_HG_TRUNKr,
   1334                               rtag7_hash_hg_trunk, SUB_SEL_NONUCf);
   1335         hash_offset =
   1336             soc_reg_field_get(unit, RTAG7_HASH_HG_TRUNKr,
   1337                               rtag7_hash_hg_trunk, OFFSET_NONUCf);
   1338         offset_shift = 0xff;
   1339     } else {
   1340         hash_sub_sel =
   1341             soc_reg_field_get(unit, RTAG7_HASH_TRUNKr,
   1342                               rtag7_hash_hg_trunk, SUB_SEL_UCf);
   1343         hash_offset =
   1344             soc_reg_field_get(unit, RTAG7_HASH_TRUNKr,
   1345                               rtag7_hash_hg_trunk, OFFSET_UCf);
   1346         offset_shift = 0xff;
   1347     } 
   1348 
   1349     BCM_IF_ERROR_RETURN
   1350         (select_en_hash_subfield(hash_sub_sel, &hash_subfield, hash_Base));
   1351 
   1352     /* Barrel shift the hash subfield, then take the LSB 8 bits */
   1353     rtag7_hash_hg_trunk_value = ((hash_subfield >> hash_offset) | (hash_subfield << (16 - hash_offset))) & offset_shift; 
   1354 
   1355     /* Compute the trunk_member_table index
   1356      *  trunk_index = trunk_hash % (trunk_group_size + 1);
   1357      *   Irsel2_rsel2__trunk_member_table_index =
   1358      *        (trunk_base_ptr + trunk_index) & 0x7ff;
   1359      */
   1360 
   1361     *hash_value = rtag7_hash_hg_trunk_value;
   1362 
   1363     LOG_VERBOSE(BSL_LS_BCM_COMMON,
   1364                 (BSL_META_U(unit,
   1365                             "Unit %d - HG Trunk hash_value=%d\n"),
   1366                  unit, *hash_value));
   1367 
   1368     return BCM_E_NONE;
   1369 }
   1370 
   1371 STATIC int
   1372 get_en_hash_hg_trunk(int unit, int tgid, uint32 hash_index, bcm_gport_t *dst_gport)
   1373 {
   1374     uint64 hg_trunk_group;
   1375     uint32 trunk_group_size;    
   1376     uint32 rtag;
   1377     uint32 trunk_index;
   1378     bcm_module_t mod_id;
   1379     bcm_port_t port_id;
   1380     _bcm_gport_dest_t   dest;
   1381 
   1382     COMPILER_64_ZERO(hg_trunk_group);
   1383     BCM_IF_ERROR_RETURN
   1384         (READ_HG_TRUNK_GROUPr(unit, tgid, &hg_trunk_group));
   1385 
   1386     trunk_group_size = soc_reg64_field32_get(unit, HG_TRUNK_GROUPr,
   1387                                              hg_trunk_group,
   1388                                              HIGIG_TRUNK_SIZEf);
   1389 
   1390     rtag = soc_reg64_field32_get(unit, HG_TRUNK_GROUPr,
   1391                                  hg_trunk_group,
   1392                                  HIGIG_TRUNK_RTAGf);
   1393 
   1394     if (rtag != 7){
   1395         LOG_VERBOSE(BSL_LS_BCM_COMMON,
   1396                      (BSL_META_U(unit,
   1397                                  "Unit %d - Hash calculation: support only RTAG7 calc no support for rtag %d\n"),
   1398                       unit, rtag));
   1399     }
   1400 
   1401     trunk_index = hash_index % (trunk_group_size + 1);
   1402 
   1403     LOG_VERBOSE(BSL_LS_BCM_COMMON,
   1404                 (BSL_META_U(unit,
   1405                             "\tTrunk HW index 0x%08x\n"),
   1406                  trunk_index));
   1407     LOG_VERBOSE(BSL_LS_BCM_COMMON,
   1408                 (BSL_META_U(unit,
   1409                             "\tTrunk group size 0x%08x\n"),
   1410                  trunk_group_size));
   1411 
   1412     port_id = soc_reg64_field32_get(unit, HG_TRUNK_GROUPr,
   1413                                     hg_trunk_group,
   1414                                     _xgs_hg_portf[trunk_index]);
   1415 
   1416     if (BCM_FAILURE(bcm_esw_stk_my_modid_get(unit, &mod_id))) {
   1417         mod_id = 0;
   1418     }
   1419 
   1420     BCM_IF_ERROR_RETURN
   1421         (_bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_GET, mod_id, port_id,
   1422                                         &(dest.modid), &(dest.port)));
   1423     dest.gport_type = _SHR_GPORT_TYPE_DEVPORT;
   1424 
   1425     BCM_IF_ERROR_RETURN(_bcm_esw_gport_construct(unit, &dest, dst_gport));
   1426 
   1427     return BCM_E_NONE;  
   1428 }
   1429 
   1430 int
   1431 _bcm_en_switch_pkt_info_hash_get(int unit,
   1432                                  bcm_switch_pkt_info_t *pkt_info,
   1433                                  bcm_gport_t *dst_gport,
   1434                                  bcm_if_t *dst_intf)
   1435 {
   1436     bcm_rtag7_base_hash_t hash_res;
   1437     int pc_out;
   1438     bcm_gport_t     port;
   1439     bcm_trunk_t     tid;
   1440     int             id;
   1441     uint32          hash_value;
   1442 
   1443     if (pkt_info == NULL) {
   1444         return BCM_E_PARAM;
   1445     }
   1446 
   1447     if (!_BCM_SWITCH_PKT_INFO_FLAG_TEST(pkt_info, SRC_GPORT)) {
   1448         LOG_VERBOSE(BSL_LS_BCM_COMMON,
   1449                     (BSL_META_U(unit,
   1450                                 "Unit %d - Hash calculation: source gport value missing\n"),
   1451                      unit));
   1452         return BCM_E_PARAM;
   1453     }
   1454 
   1455     BCM_IF_ERROR_RETURN
   1456         (_bcm_esw_gport_resolve(unit, pkt_info->src_gport,
   1457                                 &(hash_res.src_modid),
   1458                                 &(hash_res.src_port), 
   1459                                 &tid, &id));
   1460     if ((-1 != id) || (-1 != tid)) {
   1461         /* Must be single system port */
   1462         return BCM_E_PORT;
   1463     }
   1464 
   1465     /* Load balancing retrieval */
   1466     BCM_IF_ERROR_RETURN
   1467         (bcm_esw_port_local_get(unit, pkt_info->src_gport, &port));
   1468     hash_res.dev_src_port = port;
   1469     BCM_IF_ERROR_RETURN
   1470         (bcm_esw_port_control_get(unit, port,
   1471                                   bcmPortControlLoadBalancingNumber,
   1472                                   &pc_out)); 
   1473     hash_res.rtag7_port_lbn = pc_out;
   1474 
   1475     /* check if the foward reason of packet is all non-uc packet or bit 40 in the mac DA is one. */
   1476     hash_res.is_nonuc = pkt_info->fwd_reason || BCM_MAC_IS_MCAST(pkt_info->dst_mac);
   1477 
   1478     BCM_IF_ERROR_RETURN
   1479         (main__en_do_rtag7_hashing(unit, pkt_info, &hash_res));
   1480     BCM_IF_ERROR_RETURN
   1481         (main__en_compute_lbid(unit, &hash_res));
   1482 
   1483     LOG_VERBOSE(BSL_LS_BCM_COMMON,
   1484                 (BSL_META_U(unit,
   1485                             "Unit %d - Hash status: \n"),
   1486                  unit));
   1487     if (hash_res.hash_a_valid) {
   1488         LOG_VERBOSE(BSL_LS_BCM_COMMON,
   1489                     (BSL_META_U(unit,
   1490                                 "\tRTAG7 A0 0x%08x\n"),
   1491                      hash_res.rtag7_hash16_value_a_0));
   1492         LOG_VERBOSE(BSL_LS_BCM_COMMON,
   1493                     (BSL_META_U(unit,
   1494                                 "\tRTAG7 A1 0x%08x\n"),
   1495                      hash_res.rtag7_hash16_value_a_1));
   1496     } else {
   1497         LOG_VERBOSE(BSL_LS_BCM_COMMON,
   1498                     (BSL_META_U(unit,
   1499                                 "\tRTAG7 A hashes invalid due to missing packet info\n")));
   1500     }
   1501     if (hash_res.hash_b_valid) {
   1502         LOG_VERBOSE(BSL_LS_BCM_COMMON,
   1503                     (BSL_META_U(unit,
   1504                                 "\tRTAG7 B0 0x%08x\n"),
   1505                      hash_res.rtag7_hash16_value_b_0));
   1506         LOG_VERBOSE(BSL_LS_BCM_COMMON,
   1507                     (BSL_META_U(unit,
   1508                                 "\tRTAG7 B1 0x%08x\n"),
   1509                      hash_res.rtag7_hash16_value_b_1));
   1510     } else {
   1511         LOG_VERBOSE(BSL_LS_BCM_COMMON,
   1512                     (BSL_META_U(unit,
   1513                                 "\tRTAG7 B hashes invalid due to missing packet info\n")));
   1514     }
   1515     LOG_VERBOSE(BSL_LS_BCM_COMMON,
   1516                 (BSL_META_U(unit,
   1517                             "\tRTAG7 LBN 0x%08x\n"),
   1518                  hash_res.rtag7_port_lbn));
   1519     if (hash_res.lbid_hash_valid){
   1520         LOG_VERBOSE(BSL_LS_BCM_COMMON,
   1521                     (BSL_META_U(unit,
   1522                                 "\tRTAG7 LBID 0x%08x\n"),
   1523                      hash_res.rtag7_lbid_hash));
   1524     } else {
   1525         LOG_VERBOSE(BSL_LS_BCM_COMMON,
   1526                     (BSL_META_U(unit,
   1527                                 "\tRTAG7 LBID not valid due to non-RTAG7 configuration\n")));
   1528     }
   1529 
   1530 #ifdef INCLUDE_L3
   1531     if (0 != (pkt_info->flags & BCM_SWITCH_PKT_INFO_HASH_MULTIPATH)) {
   1532         bcm_if_t        nh_id;
   1533 
   1534         if (dst_intf == NULL) {
   1535             return BCM_E_PARAM;
   1536         }
   1537         
   1538         BCM_IF_ERROR_RETURN
   1539             (compute_en_ecmp_hash(unit, &hash_res, &hash_value));
   1540         LOG_VERBOSE(BSL_LS_BCM_COMMON,
   1541                     (BSL_META_U(unit,
   1542                                 "\tECMP Hash value 0x%08x\n"),
   1543                      hash_value));
   1544 
   1545         BCM_IF_ERROR_RETURN
   1546             (get_en_hash_ecmp(unit,
   1547                            pkt_info->mpintf - BCM_XGS3_MPATH_EGRESS_IDX_MIN(unit),
   1548                            hash_value, &nh_id));
   1549         /* Convert to egress object format */
   1550         *dst_intf = nh_id + BCM_XGS3_EGRESS_IDX_MIN(unit);
   1551     } else
   1552 #endif /* INCLUDE_L3 */
   1553     if (0 != (pkt_info->flags & BCM_SWITCH_PKT_INFO_HASH_TRUNK)) {
   1554         bcm_trunk_t trunk = BCM_TRUNK_INVALID;
   1555         int member_count;
   1556         bcm_trunk_chip_info_t   ti;
   1557 
   1558         if (dst_gport == NULL) {
   1559             return BCM_E_PARAM;
   1560         }
   1561         
   1562         if (!BCM_GPORT_IS_TRUNK(pkt_info->trunk_gport)) {
   1563             return BCM_E_PORT;
   1564         }
   1565         trunk = BCM_GPORT_TRUNK_GET(pkt_info->trunk_gport);
   1566         BCM_IF_ERROR_RETURN
   1567             (bcm_esw_trunk_get(unit, trunk, NULL, 0, NULL, &member_count));
   1568         if (0 == member_count) {
   1569             /* Return failure for no trunk members */
   1570             return BCM_E_FAIL;
   1571         }
   1572 
   1573         BCM_IF_ERROR_RETURN(bcm_esw_trunk_chip_info_get(unit, &ti));
   1574 
   1575         if (trunk >= ti.trunk_id_min && trunk <= ti.trunk_id_max) {
   1576             BCM_IF_ERROR_RETURN
   1577                 (compute_en_rtag7_hash_trunk(unit, &hash_res, &hash_value));
   1578             LOG_VERBOSE(BSL_LS_BCM_COMMON,
   1579                         (BSL_META_U(unit,
   1580                                     "\tTrunk Hash value 0x%08x\n"),
   1581                          hash_value));
   1582             if (hash_res.is_nonuc) {
   1583                 BCM_IF_ERROR_RETURN
   1584                     (get_en_hash_trunk_nuc(unit, trunk, pkt_info->fwd_reason, 
   1585                                 hash_value, dst_gport));
   1586             } else {
   1587                 BCM_IF_ERROR_RETURN
   1588                     (get_en_hash_trunk(unit, trunk,
   1589                                 hash_value, dst_gport));
   1590             }
   1591         } else if (trunk >= ti.trunk_fabric_id_min && trunk <= ti.trunk_fabric_id_max) {
   1592 
   1593             BCM_IF_ERROR_RETURN
   1594                 (compute_en_rtag7_hash_hg_trunk(unit, &hash_res, &hash_value));
   1595             LOG_VERBOSE(BSL_LS_BCM_COMMON,
   1596                         (BSL_META_U(unit,
   1597                                     "\tHG-Trunk Hash value 0x%08x\n"),
   1598                          hash_value));
   1599 
   1600             BCM_IF_ERROR_RETURN
   1601                 (get_en_hash_hg_trunk(unit, trunk - ti.trunk_fabric_id_min,
   1602                             hash_value, dst_gport));
   1603         } else {
   1604             return BCM_E_UNAVAIL;
   1605         }
   1606     } else if (pkt_info->flags & BCM_SWITCH_PKT_INFO_HASH_LBID) {
   1607         /* LBID hashing resolution */
   1608         if (dst_intf == NULL || hash_res.lbid_hash_valid == 0) {
   1609             return BCM_E_FAIL;
   1610         } else {
   1611             *dst_intf = hash_res.rtag7_lbid_hash;
   1612         }
   1613     } else {
   1614         return BCM_E_PARAM;
   1615     }
   1616 	
   1617     return BCM_E_NONE;
   1618 }
   1619