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

field_presel.c (17836B)


      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:        field_presel.c
      8  * Purpose:     Field Processor routines Specific to Preselector Module
      9  *              in Helix5.
     10  */
     11 
     12 #include <soc/defs.h>
     13 
     14 #if defined (BCM_HELIX5_SUPPORT) && defined(BCM_FIELD_SUPPORT)
     15 
     16 #include <bcm/error.h>
     17 #include <bcm/field.h>
     18 #include <shared/bsl.h>
     19 
     20 #include <bcm_int/esw/field.h>
     21 #include <bcm_int/esw/tomahawk.h>
     22 #include <bcm_int/esw/helix5.h>
     23 #include <bcm_int/esw/keygen_api.h>
     24 
     25 /*
     26  * Function:
     27  *    _field_hx5_ft_lt_entry_hw_remove
     28  *
     29  * Purpose:
     30  *    Remove preselector Entry from hardware at given index
     31  *
     32  * Parameters:
     33  *    unit       - (IN) BCM device number.
     34  *    f_presel   - (IN/OUT) Preselector entry.
     35  *    tcam_idx   - (IN) Hardware index
     36  *
     37  * Returns:
     38  *    BCM_E_XXX
     39  */
     40 STATIC int
     41 _field_hx5_ft_lt_entry_hw_remove(int unit,
     42                                  _field_presel_entry_t *f_presel,
     43                                  int tcam_idx)
     44 {
     45     int rv = BCM_E_NONE;
     46     _field_stage_t *stage_fc = NULL;
     47     soc_mem_t lt_tcam_mem = INVALIDm;
     48     soc_mem_t lt_data_mem = INVALIDm;
     49 
     50     /* Get device stage control structure. */
     51     BCM_IF_ERROR_RETURN(_field_stage_control_get(unit,
     52                             f_presel->group->stage_id, &stage_fc));
     53 
     54     /* Get TCAM/DATA memory */
     55     rv = _bcm_field_th_lt_tcam_policy_mem_get(unit, stage_fc,
     56                     f_presel->group->instance,
     57                     _BCM_FIELD_MEM_TYPE_FT_LT,
     58                     _BCM_FIELD_MEM_VIEW_TYPE_TCAM | _BCM_FIELD_MEM_VIEW_TYPE_DATA,
     59                     &lt_tcam_mem, &lt_data_mem);
     60     BCM_IF_ERROR_RETURN(rv);
     61 
     62     BCM_IF_ERROR_RETURN(soc_mem_write(unit, lt_tcam_mem, MEM_BLOCK_ALL,
     63                             tcam_idx, soc_mem_entry_null(unit, lt_tcam_mem)));
     64     BCM_IF_ERROR_RETURN(soc_mem_write(unit, lt_data_mem, MEM_BLOCK_ALL,
     65                             tcam_idx, soc_mem_entry_null(unit, lt_data_mem)));
     66 
     67     /* Keygen Remove */
     68     BCM_IF_ERROR_RETURN(_field_hx5_ft_group_keygen_remove(unit,
     69                             f_presel, tcam_idx));
     70 
     71     return rv;
     72 }
     73 /*
     74  * Function:
     75  *    _field_hx5_ft_presel_qualifiers_init
     76  *
     77  * Purpose:
     78  *    Initializes flowtracker stage presel qualifiers.
     79  *
     80  * Parameters:
     81  *    unit       - (IN) BCM device number.
     82  *    stage_fc   - (IN) Field stage control structure.
     83  *
     84  * Returns:
     85  *    BCM_E_PARAM       - Null field stage control structure.
     86  *    BCM_E_MEMORY      - Allocation failure.
     87  *    BCM_E_INTERNAL    - Invalid CAP Stage ID.
     88  *    BCM_E_NONE        - Success.
     89  */
     90 int
     91 _field_hx5_ft_presel_qualifiers_init(int unit,
     92                                      _field_stage_t *stage_fc)
     93 {
     94     uint16 key_base_off;
     95     uint16 z1_uc_bp = 0;
     96     uint16 z2_uc_bp = 0;
     97     soc_mem_t mem = INVALIDm;
     98     soc_field_info_t *field_info = NULL;
     99     _FP_QUAL_DECL;
    100 
    101     if (stage_fc->f_presel_qual_arr == 0) {
    102         return (BCM_E_INTERNAL);
    103     }
    104 
    105     mem = BSK_FTFP_LTS_LOGICAL_TBL_SEL_TCAMm;
    106 
    107     field_info = soc_mem_fieldinfo_get(unit, mem, KEYf);
    108     if (field_info == NULL) {
    109        return BCM_E_PARAM;
    110     }
    111     key_base_off = field_info->bp;
    112 
    113     /* PARSER1_L4_VALID */
    114     field_info = soc_mem_fieldinfo_get(unit, mem, PARSER1_L4_VALIDf);
    115     if (field_info != NULL) {
    116         _FP_PRESEL_QUAL_ADD(unit, stage_fc, bcmFieldQualifyL4Ports,
    117             0, _bcmFieldSliceSelDisable, 0, _bcmFieldQualifierTypePresel,
    118             field_info->bp - key_base_off , 1);
    119     }
    120 
    121     /* PARSER2_L4_VALID */
    122     field_info = soc_mem_fieldinfo_get(unit, mem, PARSER2_L4_VALIDf);
    123     if (field_info != NULL) {
    124         _FP_PRESEL_QUAL_ADD(unit, stage_fc, bcmFieldQualifyInnerL4Ports,
    125             0, _bcmFieldSliceSelDisable, 0, _bcmFieldQualifierTypePresel,
    126             field_info->bp - key_base_off , 1);
    127     }
    128 
    129     /* PARSER1_IP_FRAG_INFO */
    130     field_info = soc_mem_fieldinfo_get(unit, mem, PARSER1_IP_FRAG_INFOf);
    131     if (field_info != NULL) {
    132         _FP_PRESEL_QUAL_ADD(unit, stage_fc, bcmFieldQualifyIpFrag,
    133             0, _bcmFieldSliceSelDisable, 0, _bcmFieldQualifierTypePresel,
    134             field_info->bp - key_base_off , 2);
    135     }
    136 
    137     /* PARSER2_IP_FRAG_INFO */
    138     field_info = soc_mem_fieldinfo_get(unit, mem, PARSER2_IP_FRAG_INFOf);
    139     if (field_info != NULL) {
    140         _FP_PRESEL_QUAL_ADD(unit, stage_fc, bcmFieldQualifyInnerIpFrag,
    141             0, _bcmFieldSliceSelDisable, 0, _bcmFieldQualifierTypePresel,
    142             field_info->bp - key_base_off , 2);
    143     }
    144 
    145     /* HVE_RESULTS_1_Z1_UC */
    146     /* HVE_RESULTS_1_Z1_BC */
    147     /* HVE_RESULTS_1_Z2_UC */
    148     /* HVE_RESULTS_1_Z2_BC */
    149     field_info = soc_mem_fieldinfo_get(unit, mem, HVE_RESULTS_1_Z1_UCf);
    150     if (field_info != NULL) {
    151         z1_uc_bp = field_info->bp - key_base_off;
    152     }
    153     field_info = soc_mem_fieldinfo_get(unit, mem, HVE_RESULTS_1_Z2_UCf);
    154     if (field_info != NULL) {
    155         z2_uc_bp = field_info->bp - key_base_off;
    156     }
    157     if (z2_uc_bp != 0) {
    158         _FP_PRESEL_QUAL_TWO_ADD(unit, stage_fc, bcmFieldQualifyPktDstAddrType,
    159             0, _bcmFieldSliceSelDisable, 0, _bcmFieldQualifierTypePresel,
    160             z1_uc_bp, 2, z2_uc_bp, 2);
    161     }
    162 
    163     /* HVE_RESULTS_2_Z1_UC */
    164     /* HVE_RESULTS_2_Z1_BC */
    165     /* HVE_RESULTS_2_Z2_UC */
    166     /* HVE_RESULTS_2_Z2_BC */
    167     field_info = soc_mem_fieldinfo_get(unit, mem, HVE_RESULTS_2_Z1_UCf);
    168     if (field_info != NULL) {
    169         z1_uc_bp = field_info->bp - key_base_off;
    170     }
    171     field_info = soc_mem_fieldinfo_get(unit, mem, HVE_RESULTS_2_Z2_UCf);
    172     if (field_info != NULL) {
    173         z2_uc_bp = field_info->bp - key_base_off;
    174     }
    175     if (z2_uc_bp != 0) {
    176         _FP_PRESEL_QUAL_TWO_ADD(unit, stage_fc, bcmFieldQualifyPktInnerDstAddrType,
    177             0, _bcmFieldSliceSelDisable, 0, _bcmFieldQualifierTypePresel,
    178             z1_uc_bp, 2, z2_uc_bp, 2);
    179     }
    180 
    181     /* PARSER1_DOS_ATTACK */
    182     field_info = soc_mem_fieldinfo_get(unit, mem, PARSER1_DOS_ATTACKf);
    183     if (field_info != NULL) {
    184         _FP_PRESEL_QUAL_ADD(unit, stage_fc, bcmFieldQualifyDosAttack,
    185             0, _bcmFieldSliceSelDisable, 0, _bcmFieldQualifierTypePresel,
    186             field_info->bp - key_base_off , 1);
    187     }
    188 
    189     /* PARSER2_DOS_ATTACK */
    190     field_info = soc_mem_fieldinfo_get(unit, mem, PARSER2_DOS_ATTACKf);
    191     if (field_info != NULL) {
    192         _FP_PRESEL_QUAL_ADD(unit, stage_fc, bcmFieldQualifyInnerDosAttack,
    193             0, _bcmFieldSliceSelDisable, 0, _bcmFieldQualifierTypePresel,
    194             field_info->bp - key_base_off , 1);
    195     }
    196 
    197     return (BCM_E_NONE);
    198 }
    199 
    200 /*
    201  * Function:
    202  *    _bcm_field_hx5_ft_lt_entry_data_value_set
    203  *
    204  * Purpose:
    205  *    Set presel entry data to sw copy of entry.
    206  *
    207  * Parameters:
    208  *    unit       - (IN) BCM device number.
    209  *    stage_fc   - (IN) Stage field control structure.
    210  *    fg         - (IN) Field group structure.
    211  *    index      - (IN)
    212  *    lt_data_mem- (IN) presel sram hw table
    213  *    data       - (IN/OUT) entry data
    214  *
    215  * Returns:
    216  *    BCM_E_PARAM       - Null field stage control structure.
    217  *    BCM_E_INTERNAL    - Invalid CAP Stage ID.
    218  *    BCM_E_NONE        - Success.
    219  */
    220 int
    221 _bcm_field_hx5_ft_lt_entry_data_value_set(int unit,
    222                                           _field_stage_t *stage_fc,
    223                                           _field_group_t *fg,
    224                                           int index,
    225                                           soc_mem_t lt_data_mem,
    226                                           uint32 *data)
    227 {
    228     uint32 keytype = 0;
    229     int group_key_mode = 0;
    230 
    231     if ((fg == NULL) || (stage_fc == NULL)) {
    232         return BCM_E_PARAM;
    233     }
    234 
    235     /* Set main SRAM as in lt_data_mem */
    236     if (fg->flags & _FP_GROUP_DW_DEPTH_EXPANDED) {
    237         group_key_mode = 1;
    238     } else {
    239         group_key_mode = 0;
    240     }
    241     soc_mem_field32_set(unit, lt_data_mem,
    242         data, GROUP_KEY_MODEf, group_key_mode);
    243 
    244     soc_mem_field32_set(unit, lt_data_mem, data, GROUP_LOOKUP_ENABLEf,
    245         (fg->flags & _FP_GROUP_LOOKUP_ENABLED) ? 1 : 0);
    246 
    247     keytype = (fg->lt_id >> _FP_GROUP_FT_KEYTYPE_SHIFT) &
    248                             (_FP_GROUP_FT_KEYTYPE_MASK);
    249     soc_mem_field32_set(unit, lt_data_mem, data, GROUP_KEY_TYPEf, keytype);
    250 
    251     return BCM_E_NONE;
    252 }
    253 
    254 /*
    255  * Function:
    256  *    _bcm_field_hx5_ft_lt_entry_install
    257  *
    258  * Purpose:
    259  *    Install preselector entry for flowtracker stage in hw.
    260  *
    261  * Parameters:
    262  *    unit       - (IN) BCM device number.
    263  *    f_presel   - (IN) Preselector entry.
    264  *    lt_fs      - (IN) Logical table field slice.
    265  *
    266  * Returns:
    267  *    BCM_E_PARAM       - Null field stage control structure.
    268  *    BCM_E_INTERNAL    - Invalid CAP Stage ID.
    269  *    BCM_E_NONE        - Success.
    270  */
    271 int
    272 _bcm_field_hx5_ft_lt_entry_install(int unit,
    273                                    _field_presel_entry_t *f_presel,
    274                                    _field_lt_slice_t *lt_fs)
    275 {
    276     int rv = BCM_E_NONE;
    277     _field_stage_t *stage_fc = NULL;
    278     int valid = 0;
    279     int tcam_idx = 0;
    280     soc_mem_t lt_tcam_mem = INVALIDm;
    281     soc_mem_t lt_data_mem = INVALIDm;
    282     uint32 tcam_entry[SOC_MAX_MEM_FIELD_WORDS] = {0}; /* TCAM Entry buffer.*/
    283     uint32 data_entry[SOC_MAX_MEM_FIELD_WORDS] = {0}; /* DATA Entry buffer. */
    284 
    285     /* Validate input params */
    286     if ((f_presel == NULL) || (lt_fs == NULL)) {
    287         return BCM_E_INTERNAL;
    288     }
    289     if ((f_presel->lt_tcam.key == NULL) ||
    290         (f_presel->lt_tcam.mask == NULL) ||
    291         (f_presel->lt_data.data == NULL)) {
    292         return BCM_E_PARAM;
    293     }
    294 
    295     /* Get device stage control structure. */
    296     BCM_IF_ERROR_RETURN(_field_stage_control_get(unit,
    297                             f_presel->group->stage_id, &stage_fc));
    298 
    299     BCM_IF_ERROR_RETURN(_bcm_field_presel_entry_tcam_idx_get(unit,
    300                             f_presel, lt_fs, &tcam_idx));
    301 
    302     /* Call Group Keygen Install */
    303     BCM_IF_ERROR_RETURN(_field_hx5_ft_group_keygen_install(unit, f_presel));
    304 
    305     /* Get TCAM/DATA memory */
    306     rv = _bcm_field_th_lt_tcam_policy_mem_get(unit, stage_fc,
    307                     f_presel->group->instance,
    308                     _BCM_FIELD_MEM_TYPE_FT_LT,
    309                     _BCM_FIELD_MEM_VIEW_TYPE_TCAM | _BCM_FIELD_MEM_VIEW_TYPE_DATA,
    310                     &lt_tcam_mem, &lt_data_mem);
    311     BCM_IF_ERROR_RETURN(rv);
    312 
    313     valid = (f_presel->group->flags & _FP_GROUP_LOOKUP_ENABLED) ? 3: 0;
    314 
    315     BCM_IF_ERROR_RETURN(soc_mem_write(unit, lt_tcam_mem, MEM_BLOCK_ALL,
    316                             tcam_idx, tcam_entry));
    317     BCM_IF_ERROR_RETURN(soc_mem_write(unit, lt_data_mem, MEM_BLOCK_ALL,
    318                             tcam_idx, data_entry));
    319 
    320     BCM_IF_ERROR_RETURN(soc_mem_read(unit, lt_tcam_mem, MEM_BLOCK_ANY, tcam_idx,
    321                             tcam_entry));
    322     BCM_IF_ERROR_RETURN(soc_mem_read(unit, lt_data_mem, MEM_BLOCK_ANY, tcam_idx,
    323                             data_entry));
    324 
    325     soc_mem_field_set(unit, lt_tcam_mem, tcam_entry, KEYf,  f_presel->lt_tcam.key);
    326     soc_mem_field_set(unit, lt_tcam_mem, tcam_entry, MASKf, f_presel->lt_tcam.mask);
    327     soc_mem_field_set(unit, lt_data_mem, data_entry, DATAf, f_presel->lt_data.data);
    328 
    329     /* Set entry valid bit status. */
    330     soc_mem_field32_set(unit, lt_tcam_mem, tcam_entry, VALIDf, valid);
    331 
    332     /* Install entry in hardware. */
    333     BCM_IF_ERROR_RETURN(soc_mem_write(unit, lt_data_mem, MEM_BLOCK_ALL,
    334                 tcam_idx, data_entry));
    335     BCM_IF_ERROR_RETURN(soc_mem_write(unit, lt_tcam_mem, MEM_BLOCK_ALL,
    336                 tcam_idx, tcam_entry));
    337 
    338     f_presel->flags &= ~_FP_ENTRY_DIRTY;
    339     f_presel->flags |= _FP_ENTRY_INSTALLED;
    340     f_presel->flags |= _FP_ENTRY_ENABLED;
    341 
    342     return BCM_E_NONE;
    343 }
    344 
    345 /*
    346  * Function:
    347  *    _bcm_field_hx5_ft_lt_entry_hw_remove
    348  *
    349  * Purpose:
    350  *    Remove preselector Entry from hardware.
    351  *
    352  * Parameters:
    353  *    unit       - (IN) BCM device number.
    354  *    f_presel   - (IN/OUT) Preselector entry.
    355  *
    356  * Returns:
    357  *    BCM_E_PARAM       - Null field stage control structure.
    358  *    BCM_E_MEMORY      - Allocation failure.
    359  *    BCM_E_INTERNAL    - Invalid CAP Stage ID.
    360  *    BCM_E_NONE        - Success.
    361  */
    362 int
    363 _bcm_field_hx5_ft_lt_entry_hw_remove(int unit,
    364                                      _field_presel_entry_t *f_presel)
    365 {
    366     int rv = BCM_E_NONE;
    367     int tcam_idx = 0;
    368 
    369     /* Validate input params */
    370     if (f_presel == NULL) {
    371         return BCM_E_INTERNAL;
    372     }
    373 
    374     if ((f_presel->flags & _FP_ENTRY_INSTALLED) == 0) {
    375         /* Entry is not installed in hw */
    376         return BCM_E_NONE;
    377     }
    378 
    379     /* Get Tcam Index */
    380     BCM_IF_ERROR_RETURN(_bcm_field_presel_entry_tcam_idx_get(unit,
    381                             f_presel, f_presel->lt_fs, &tcam_idx));
    382 
    383     BCM_IF_ERROR_RETURN(_field_hx5_ft_lt_entry_hw_remove(unit,
    384                             f_presel, tcam_idx));
    385 
    386     f_presel->flags |= _FP_ENTRY_DIRTY;
    387     f_presel->flags &= ~(_FP_ENTRY_INSTALLED);
    388     f_presel->flags &= ~(_FP_ENTRY_ENABLED);
    389 
    390     return rv;
    391 }
    392 
    393 /*
    394  * Function:
    395  *    _field_hx5_ft_presel_delete_last_entry_hw
    396  *
    397  * Purpose:
    398  *    Remove preselector Entry at last index in lt slice
    399  *
    400  * Parameters:
    401  *    unit       - (IN) BCM device number.
    402  *    f_presel   - (IN/OUT) Preselector entry.
    403  *    last_hw_index   - (IN) Hardware index
    404  *
    405  * Returns:
    406  *    BCM_E_XXX
    407  */
    408 int
    409 _field_hx5_ft_presel_delete_last_entry_hw(int unit,
    410                                           _field_presel_entry_t *f_presel,
    411                                           int last_hw_index)
    412 {
    413     int rv = BCM_E_NONE;
    414     int tcam_idx = 0;
    415 
    416     tcam_idx = f_presel->lt_fs->start_tcam_idx + last_hw_index;
    417 
    418     BCM_IF_ERROR_RETURN(_field_hx5_ft_lt_entry_hw_remove(unit,
    419                             f_presel, tcam_idx));
    420 
    421     f_presel->lt_fs->p_entries[last_hw_index] = NULL;
    422 
    423     return rv;
    424 }
    425 
    426 #define _BCM_FIELD_PKT_DST_ADDR_TYPE_MAC_MASK               \
    427             (BCM_FIELD_PKT_DST_ADDR_TYPE_UCAST_MAC  |       \
    428              BCM_FIELD_PKT_DST_ADDR_TYPE_MCAST_MAC  |       \
    429              BCM_FIELD_PKT_DST_ADDR_TYPE_BCAST_MAC)
    430 
    431 #define _BCM_FIELD_PKT_DST_ADDR_TYPE_IP_MASK                \
    432             (BCM_FIELD_PKT_DST_ADDR_TYPE_UCAST_IP  |        \
    433              BCM_FIELD_PKT_DST_ADDR_TYPE_MCAST_IP  |        \
    434              BCM_FIELD_PKT_DST_ADDR_TYPE_BCAST_IP)
    435 
    436 int
    437 _bcm_field_hx5_qualify_PktDstAddrType(int unit,
    438                     bcm_field_qualify_t qual,
    439                     uint32 dst_addr_type,
    440                     uint32 *hw_data,
    441                     uint32 *hw_mask)
    442 {
    443     uint32 dst_mac_type = 0;
    444     uint32 dst_ip_type = 0;
    445     uint32 dst_mac_flags = 0;
    446     uint32 dst_ip_flags = 0;
    447     uint32 bit = 0, flag = 0;
    448     uint32 mac_hw_data = 0, mac_hw_mask = 0;
    449     uint32 ip_hw_data = 0, ip_hw_mask = 0;
    450     uint32 dst_addr_type_arr[1] = {0};
    451 
    452     /* Validate input args */
    453     if ((hw_data == NULL) || (hw_mask == NULL)) {
    454         return BCM_E_PARAM;
    455     }
    456 
    457     dst_mac_type = dst_addr_type & _BCM_FIELD_PKT_DST_ADDR_TYPE_MAC_MASK;
    458     dst_ip_type = dst_addr_type & _BCM_FIELD_PKT_DST_ADDR_TYPE_IP_MASK;
    459 
    460     dst_mac_flags = _shr_popcount(dst_mac_type);
    461     dst_ip_flags = _shr_popcount(dst_ip_type);
    462 
    463     if ((dst_mac_flags > 1) || (dst_ip_flags > 1)) {
    464         return BCM_E_PARAM;
    465     }
    466 
    467     dst_addr_type_arr[0] = dst_addr_type;
    468     SHR_BIT_ITER(dst_addr_type_arr, 32, bit) {
    469         flag = (1 << bit);
    470         switch(flag) {
    471             case BCM_FIELD_PKT_DST_ADDR_TYPE_UCAST_MAC:
    472                 mac_hw_data = 0x1;
    473                 mac_hw_mask = 0x3;
    474                 break;
    475             case BCM_FIELD_PKT_DST_ADDR_TYPE_MCAST_MAC:
    476                 mac_hw_data = 0x0;
    477                 mac_hw_mask = 0x3;
    478                 break;
    479             case BCM_FIELD_PKT_DST_ADDR_TYPE_BCAST_MAC:
    480                 mac_hw_data = 0x2;
    481                 mac_hw_mask = 0x3;
    482                 break;
    483             case BCM_FIELD_PKT_DST_ADDR_TYPE_UCAST_IP:
    484                 ip_hw_data = 0x1;
    485                 ip_hw_mask = 0x3;
    486                 break;
    487             case BCM_FIELD_PKT_DST_ADDR_TYPE_MCAST_IP:
    488                 ip_hw_data = 0x0;
    489                 ip_hw_mask = 0x3;
    490                 break;
    491             case BCM_FIELD_PKT_DST_ADDR_TYPE_BCAST_IP:
    492                 ip_hw_data = 0x2;
    493                 ip_hw_mask = 0x3;
    494                 break;
    495             default:
    496                 return BCM_E_PARAM;
    497         }
    498     }
    499 
    500     *hw_data = (ip_hw_data << 2) + mac_hw_data;
    501     *hw_mask = (ip_hw_mask << 2) + mac_hw_mask;
    502 
    503     return BCM_E_NONE;
    504 }
    505 
    506 int
    507 _bcm_field_hx5_qualify_PktDstAddrType_get(int unit,
    508                     bcm_field_qualify_t qual,
    509                     uint32 hw_data,
    510                     uint32 hw_mask,
    511                     uint32 *dst_addr_type)
    512 {
    513     uint32 ip_hw_data = 0;
    514     uint32 ip_hw_mask = 0;
    515     uint32 mac_hw_data = 0;
    516     uint32 mac_hw_mask = 0;
    517 
    518     ip_hw_data = (hw_data >> 2) & 0x3;
    519     ip_hw_mask = (hw_mask >> 2) & 0x3;
    520     mac_hw_data = hw_data & 0x3;
    521     mac_hw_mask = hw_mask & 0x3;
    522 
    523     *dst_addr_type = 0;
    524 
    525     if (mac_hw_mask != 0) {
    526         switch (mac_hw_data) {
    527             case 0:
    528                 *dst_addr_type |= BCM_FIELD_PKT_DST_ADDR_TYPE_MCAST_MAC;
    529                 break;
    530             case 1:
    531                 *dst_addr_type |= BCM_FIELD_PKT_DST_ADDR_TYPE_UCAST_MAC;
    532                 break;
    533             case 2:
    534                 *dst_addr_type |= BCM_FIELD_PKT_DST_ADDR_TYPE_BCAST_MAC;
    535                 break;
    536             default:
    537                 *dst_addr_type |= 0;
    538         }
    539     }
    540 
    541     if (ip_hw_mask != 0) {
    542         switch (ip_hw_data) {
    543             case 0:
    544                 *dst_addr_type |= BCM_FIELD_PKT_DST_ADDR_TYPE_MCAST_IP;
    545                 break;
    546             case 1:
    547                 *dst_addr_type |= BCM_FIELD_PKT_DST_ADDR_TYPE_UCAST_IP;
    548                 break;
    549             case 2:
    550                 *dst_addr_type |= BCM_FIELD_PKT_DST_ADDR_TYPE_BCAST_IP;
    551                 break;
    552             default:
    553                 *dst_addr_type |= 0;
    554         }
    555     }
    556 
    557     return BCM_E_NONE;
    558 }
    559 
    560 #endif