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

rx.c (21915B)


      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:        rx.c
      8  * Purpose:     XGS5 RX common driver.
      9  *
     10  * Notes:
     11  *      New RX APIs implementation.
     12  */
     13 
     14 #include <shared/bsl.h>
     15 #include <soc/defs.h>
     16 #include <soc/drv.h>
     17 
     18 #include <bcm_int/esw/xgs5.h>
     19 #include <bcm_int/esw/rx.h>
     20 #include <bcm_int/esw_dispatch.h>
     21 #include <bcm_int/esw/trunk.h>
     22 #include <bcm_int/common/rx.h>
     23 #include <bcm/error.h>
     24 
     25 
     26 #if defined (BCM_EP_REDIRECT_VERSION_2)
     27 
     28 
     29 #define BCMI_MAX_STRENGTH_VALUE (0x3E)
     30 
     31 /* Packet drop reasons */
     32 typedef enum bcmi_pkt_drop_reason_e {
     33     bcmiDropReasonEgressVxltMISSDrop = 0,
     34     bcmiDropReasonEgressTunnelSnapDrop,
     35     bcmiDropReasonEgressCfiDrop,
     36     bcmiDropReasonEgressTtlDrop,
     37     bcmiDropReasonEgressNotVlanMemberDrop,
     38     bcmiDropReasonEgressStgBlockDrop,
     39     bcmiDropReasonEgressIpmcL2SelfPort,
     40     bcmiDropReasonEgressPurgePkt,
     41     bcmiDropReasonEgressAgedPkt,
     42     bcmiDropReasonEgressBadTdip,
     43     bcmiDropReasonEgressProtectionDrop,
     44     bcmiDropReasonEgressVlanNotFound,
     45     bcmiDropReasonEgressStgDisableDrop,
     46     bcmiDropReasonEgressHigig2RsvdDrop,
     47     bcmiDropReasonEgressHigigRsvdHgi,
     48     bcmiDropReasonEgressL2MtuFailDrop,
     49     bcmiDropReasonEgressCompositeErrorDrop,
     50     bcmiDropReasonEgressIpmcL3SelfIntf,
     51     bcmiDropReasonEgressModidGrt31Drop,
     52     bcmiDropReasonEgressEfpDrop,
     53      /* The loction at 20 is not applicable */
     54     bcmiDropReasonEgressSplitHorizon = 21,
     55     bcmiDropReasonEgressSourceVirtualPortRemoval,
     56     bcmiDropReasonEgressNivPruneDrop,
     57     bcmiDropReasonEgressNonucastPruneDrop,
     58     bcmiDropReasonEgressTrillPktDrop,
     59     bcmiDropReasonEgressPacketTooSmall,
     60     bcmiDropReasonEgressNonTrillPktDrop,
     61     bcmiDropReasonEgressVplagPruning,
     62     bcmiDropReasonEgressInvalid1588PacketDrop,
     63     bcmiDropReasonEgressFcoePacketDrop,
     64     bcmiDropReasonEgressCnmPacketDrop,
     65     bcmiDropReasonEgressEpDropOrig
     66 } bcmi_pkt_drop_reason_t;
     67 
     68 /* Sync for copy-to-cpu config */
     69 sal_mutex_t  _bcmi_rx_copy_to_cpu_config_mutex[BCM_MAX_NUM_UNITS];
     70 
     71 /* Initialize the copy to cpu config data */
     72 _bcmi_rx_CopyToCpu_config_t
     73     *(_bcmi_rx_egr_drop_copy_to_cpu_config_data[BCM_MAX_NUM_UNITS]) = { 0 };
     74 
     75 SHR_BITDCL *_bcmi_rx_egr_drop_copy_to_cpu_loc_bitmap[BCM_MAX_NUM_UNITS] = { 0 };
     76 /*
     77  * Function:
     78  *      bcmi_xgs5_rx_CopyToCpu_index_check
     79  * Purpose:
     80  *      Check if a index to the ctc table is valid
     81  * Parameters:
     82  *      unit             - (IN) device id.
     83  *      index_to_verify  - (IN) Index to verify.
     84  * Returns:
     85  *      BCM_E_*
     86  */
     87 int bcmi_xgs5_rx_CopyToCpu_index_check(int unit, int index_to_verify)
     88 {
     89     int start, end;
     90     soc_mem_t mem = EP_CTC_RES_TABLEm;
     91 
     92     /* Gather the table depth */
     93     start = soc_mem_index_min(unit, mem);
     94     end = soc_mem_index_max(unit, mem);
     95 
     96     if((index_to_verify < start) || (index_to_verify > end)) {
     97         return BCM_E_PARAM;
     98     }
     99 
    100     return BCM_E_NONE;
    101 }
    102 
    103 /*
    104  * Function:
    105  *      bcmi_xgs5_rx_CopyToCpu_free_entry_get
    106  * Purpose:
    107  *      Get a free unused entry
    108  * Parameters:
    109  *      unit        - (IN) device id.
    110  *      free_index  - (OUT) Index of the free entry.
    111  * Returns:
    112  *      BCM_E_*
    113  */
    114 int bcmi_xgs5_rx_CopyToCpu_free_entry_get(int unit, int *free_index)
    115 {
    116     int index, start, end;
    117     soc_mem_t mem = EP_CTC_RES_TABLEm;
    118 
    119     if(free_index == NULL) {
    120         return BCM_E_PARAM;
    121     }
    122 
    123     /* Gather the table start and end indices */
    124     start = soc_mem_index_min(unit, mem);
    125     end = soc_mem_index_max(unit, mem);
    126 
    127     /* Look for a unused entry */
    128     for (index = start; index <= end; index++) {
    129         if(!SHR_BITGET(_bcmi_rx_egr_drop_copy_to_cpu_loc_bitmap[unit], index)) {
    130             *free_index = index;
    131             return BCM_E_NONE;
    132         }
    133     }
    134 
    135     /* If we end up here, no free entry found return error */
    136     return BCM_E_FULL;
    137 }
    138 
    139 /*
    140  * Function:
    141  *      bcmi_xgs5_rx_CopyToCpu_index_in_use_check
    142  * Purpose:
    143  *      Verify if a given index is in use
    144  * Parameters:
    145  *      unit             - (IN) device id.
    146  *      index_to_verify  - (IN) Index of the free entry.
    147  * Returns:
    148  *      BCM_E_*
    149  */
    150 int bcmi_xgs5_rx_CopyToCpu_index_in_use_check(int unit, int index_to_check)
    151 {
    152     if(SHR_BITGET(
    153         _bcmi_rx_egr_drop_copy_to_cpu_loc_bitmap[unit], index_to_check)) {
    154         /* Return 'bcm_e_exists' to indicate it is in use */
    155         return BCM_E_EXISTS;
    156     }
    157 
    158     /* Return not_found if the entry is not configured */
    159     return BCM_E_NOT_FOUND;
    160 }
    161 
    162 /*
    163  * Function:
    164  *      bcmi_rx_copyToCpu_drop_reason_hw_field_get
    165  * Purpose:
    166  *      Given a user facing drop reason, return its hardware field equivalent
    167  * Parameters:
    168  *      unit         - (IN) device id.
    169  *      drop_reason  - (IN) Drop reason field to get.
    170  *      drop_reason_field  - (OUT) Drop reason field.
    171  * Returns:
    172  *      BCM_E_*
    173  */
    174 int bcmi_rx_copyToCpu_drop_reason_hw_field_get(int unit,
    175                                     bcm_pkt_drop_reason_t drop_reason,
    176                                     bcmi_pkt_drop_reason_t *drop_reason_field)
    177 {
    178     /* Sanity check */
    179     if(drop_reason_field == NULL) {
    180         return BCM_E_PARAM;
    181     }
    182 
    183     switch (drop_reason) {
    184         case bcmPktDropReasonEgressVlanTranslateMiss:
    185             *drop_reason_field = bcmiDropReasonEgressVxltMISSDrop;
    186             break;
    187         case bcmPktDropReasonEgressTunnelSnap:
    188             *drop_reason_field = bcmiDropReasonEgressTunnelSnapDrop;
    189             break;
    190         case bcmPktDropReasonEgressColorSelect:
    191             *drop_reason_field = bcmiDropReasonEgressCfiDrop;
    192             break;
    193         case bcmPktDropReasonEgressTtlError:
    194             *drop_reason_field = bcmiDropReasonEgressTtlDrop;
    195             break;
    196         case bcmPktDropReasonEgressVlanFilter:
    197             *drop_reason_field = bcmiDropReasonEgressNotVlanMemberDrop;
    198             break;
    199         case bcmPktDropReasonEgressStgBlocked:
    200             *drop_reason_field = bcmiDropReasonEgressStgBlockDrop;
    201             break;
    202         case bcmPktDropReasonEgressIPMCSameVlanPrune:
    203             *drop_reason_field = bcmiDropReasonEgressIpmcL2SelfPort;
    204             break;
    205         case bcmPktDropReasonEgressMmuPurge:
    206             *drop_reason_field = bcmiDropReasonEgressPurgePkt;
    207             break;
    208         case bcmPktDropReasonEgressMmuAge:
    209             *drop_reason_field = bcmiDropReasonEgressAgedPkt;
    210             break;
    211         case bcmPktDropReasonEgressBadTdipDrop:
    212             *drop_reason_field = bcmiDropReasonEgressBadTdip;
    213             break;
    214         case bcmPktDropReasonEgressProtection:
    215             *drop_reason_field = bcmiDropReasonEgressProtectionDrop;
    216             break;
    217         case bcmPktDropReasonEgressUnknownVlan:
    218             *drop_reason_field = bcmiDropReasonEgressVlanNotFound;
    219             break;
    220         case bcmPktDropReasonEgressStgDisabled:
    221             *drop_reason_field = bcmiDropReasonEgressStgDisableDrop;
    222             break;
    223         case bcmPktDropReasonEgressHiGig2ReservedPPD:
    224             *drop_reason_field = bcmiDropReasonEgressHigig2RsvdDrop;
    225             break;
    226         case bcmPktDropReasonEgressHigigPlusUnknown:
    227             *drop_reason_field = bcmiDropReasonEgressHigigRsvdHgi;
    228             break;
    229         case bcmPktDropReasonEgressL2MtuExceeded:
    230             *drop_reason_field = bcmiDropReasonEgressL2MtuFailDrop;
    231             break;
    232         case bcmPktDropReasonEgressCompositeError:
    233             *drop_reason_field = bcmiDropReasonEgressCompositeErrorDrop;
    234             break;
    235         case bcmPktDropReasonEgressMulticastPruned:
    236             *drop_reason_field = bcmiDropReasonEgressIpmcL3SelfIntf;
    237             break;
    238         case bcmPktDropReasonEgressHigigPlusInvalidModuleId:
    239             *drop_reason_field = bcmiDropReasonEgressModidGrt31Drop;
    240             break;
    241         case bcmPktDropReasonEgressFieldAction:
    242             *drop_reason_field = bcmiDropReasonEgressEfpDrop;
    243             break;
    244         case bcmPktDropReasonEgressSplitHorizon:
    245             *drop_reason_field = bcmiDropReasonEgressSplitHorizon;
    246             break;
    247         case bcmPktDropReasonEgressSVPRemoval:
    248             *drop_reason_field = bcmiDropReasonEgressSourceVirtualPortRemoval;
    249             break;
    250         case bcmPktDropReasonEgressNivSrcKnockout:
    251             *drop_reason_field = bcmiDropReasonEgressNivPruneDrop;
    252             break;
    253         case bcmPktDropReasonEgressNonUCPrune:
    254             *drop_reason_field = bcmiDropReasonEgressNonucastPruneDrop;
    255             break;
    256         case bcmPktDropReasonEgressTrillPacket:
    257             *drop_reason_field = bcmiDropReasonEgressTrillPktDrop;
    258             break;
    259         case bcmPktDropReasonEgressPacketTooSmall:
    260             *drop_reason_field = bcmiDropReasonEgressPacketTooSmall;
    261             break;
    262         case bcmPktDropReasonEgressNonTrillPacket:
    263             *drop_reason_field = bcmiDropReasonEgressNonTrillPktDrop;
    264             break;
    265         case bcmPktDropReasonEgressVpLagPruned:
    266             *drop_reason_field = bcmiDropReasonEgressVplagPruning;
    267             break;
    268         case bcmPktDropReasonEgressInvalid1588Packet:
    269             *drop_reason_field = bcmiDropReasonEgressInvalid1588PacketDrop;
    270             break;
    271         case bcmPktDropReasonEgressInvalidFcoePacket:
    272             *drop_reason_field = bcmiDropReasonEgressFcoePacketDrop;
    273             break;
    274         case bcmPktDropReasonEgressInvalidCnmPacket:
    275             *drop_reason_field = bcmiDropReasonEgressCnmPacketDrop;
    276             break;
    277         case bcmPktDropReasonEgressOriginalPacket:
    278             *drop_reason_field = bcmiDropReasonEgressEpDropOrig;
    279             break;
    280         default:
    281             return BCM_E_PARAM;
    282             break;
    283     }
    284 
    285     return BCM_E_NONE;
    286 }
    287 
    288 /*
    289  * Function:
    290  *      bcmi_xgs5_rx_CopyToCpu_config_add
    291  * Purpose:
    292  *      Add a copy-to-cpu entry
    293  * Parameters:
    294  *      unit              - (IN) device id.
    295  *      options           - (IN) options.
    296  *      copyToCpu_config  - (IN) Pointer to the copy-to-cpu config structure
    297  * Returns:
    298  *      BCM_E_*
    299  */
    300 
    301 int bcmi_xgs5_rx_CopyToCpu_config_add(int unit, uint32 options,
    302                                 bcm_rx_CopyToCpu_config_t *copyToCpu_config)
    303 {
    304     ep_ctc_res_table_entry_t ep_ctc_res_table_entry;
    305     soc_mem_t mem = EP_CTC_RES_TABLEm;
    306     bcm_pkt_drop_reason_t drop_reason = 0;
    307     int table_index = 0;
    308     int buffer_priority = 0;
    309     bcmi_pkt_drop_reason_t drop_reason_field = 0;
    310     uint32 fldbuf[2];
    311 
    312     /* Sanity check */
    313     if(copyToCpu_config == NULL) {
    314         return BCM_E_PARAM;
    315     }
    316 
    317     /* Assign the index, incase we need to reuse it */
    318     table_index = copyToCpu_config->index;
    319 
    320     
    321 
    322     /* Check if the user has supplied the WITH_ID option, if has
    323        validate the same */
    324     if(options & BCM_RX_COPYTOCPU_WITH_ID) {
    325         BCM_IF_ERROR_RETURN(bcmi_xgs5_rx_CopyToCpu_index_check(unit,
    326                                                                table_index));
    327     }
    328 
    329     /* If this is a REPLACE operation, make sure the index is currently
    330        configured */
    331     if(options & BCM_RX_COPYTOCPU_REPLACE) {
    332         BCM_IF_ERROR_RETURN(bcmi_xgs5_rx_CopyToCpu_index_in_use_check(unit,
    333                                                           table_index));
    334     } else {
    335         /* For a add operation without Id supplied get a free index we
    336            need to configure */
    337         if(!(options & BCM_RX_COPYTOCPU_WITH_ID)) {
    338             BCM_IF_ERROR_RETURN(bcmi_xgs5_rx_CopyToCpu_free_entry_get(unit,
    339                                                               &table_index));
    340         }
    341     }
    342 
    343     /* Make sure the supplied drop_vector is non-null */
    344     if(BCM_PKT_DROP_REASON_IS_NULL(copyToCpu_config->drop_reason_vector)) {
    345         return BCM_E_PARAM;
    346     }
    347 
    348     /* Read the entry */
    349     SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ANY,
    350                                      table_index,
    351                                      &ep_ctc_res_table_entry));
    352 
    353     /* Set the desired drop_vector */
    354     /* Extract the current drop_vector */
    355     soc_mem_field_get(unit, mem, (uint32 *)&ep_ctc_res_table_entry,
    356                       SELECT_BITMAPf, fldbuf);
    357 
    358     /* Run through the drop reasons and set/unset based on user choice */
    359     for (drop_reason = bcmPktDropReasonEgressVlanTranslateMiss;
    360           drop_reason < bcmPktDropReasonCount;
    361           drop_reason++) {
    362 
    363         /* Map the drop_reason to relevant field in hardware */
    364         BCM_IF_ERROR_RETURN(bcmi_rx_copyToCpu_drop_reason_hw_field_get(unit,
    365                                       drop_reason, &drop_reason_field));
    366 
    367         /* Depending on the user selection, set/clear the field */
    368         if (BCM_PKT_DROP_REASON_GET(
    369             copyToCpu_config->drop_reason_vector, drop_reason)) {
    370             /* Set the drop_reason in question */
    371             fldbuf[drop_reason_field / 32] |= (1 << (drop_reason_field % 32));
    372         } else {
    373             /* Unset the group in question */
    374             fldbuf[drop_reason_field / 32] &= ~(1 << (drop_reason_field % 32));
    375         }
    376     }
    377 
    378     /* Setup the updated drop vector */
    379     soc_mem_field_set(unit, mem, (uint32 *)&ep_ctc_res_table_entry,
    380                       SELECT_BITMAPf, fldbuf);
    381 
    382     /* Set the trigger strength */
    383     if((copyToCpu_config->strength >= 0) &&
    384        (copyToCpu_config->strength < BCMI_MAX_STRENGTH_VALUE)) {
    385         soc_mem_field32_set(unit, mem, (uint32 *)&ep_ctc_res_table_entry,
    386                   STRENGTHf, copyToCpu_config->strength);
    387     } else {
    388         return BCM_E_PARAM;
    389     }
    390 
    391     /* Set the buffer priority */
    392     if(copyToCpu_config->buffer_priority &
    393        BCM_RX_COPYTOCPU_BUFFER_PRIORITY_LOW) {
    394         buffer_priority = _BCM_RX_COPYTOCPU_BUFFER_PRIORITY_LOW;
    395     } else if(copyToCpu_config->buffer_priority &
    396        BCM_RX_COPYTOCPU_BUFFER_PRIORITY_MEDIUM) {
    397         buffer_priority = _BCM_RX_COPYTOCPU_BUFFER_PRIORITY_MEDIUM;
    398     } else if(copyToCpu_config->buffer_priority &
    399        BCM_RX_COPYTOCPU_BUFFER_PRIORITY_HIGH) {
    400         buffer_priority = _BCM_RX_COPYTOCPU_BUFFER_PRIORITY_HIGH;
    401     }
    402 
    403     soc_mem_field32_set(unit, mem, (uint32 *)&ep_ctc_res_table_entry,
    404               RDB_PRIORITYf, buffer_priority);
    405 
    406     /* Set the CPU CoS Queue */
    407     if(copyToCpu_config->cpu_cosq != -1) {
    408        if(copyToCpu_config->cpu_cosq < NUM_CPU_COSQ(unit)) {
    409         soc_mem_field32_set(unit, mem, (uint32 *)&ep_ctc_res_table_entry,
    410                   CPU_COSf, copyToCpu_config->cpu_cosq);
    411        } else {
    412            return BCM_E_PARAM;
    413        }
    414     }
    415 
    416     /* Set the truncate option, if user has chosen the same */
    417     if(copyToCpu_config->flags & BCM_PORT_REDIRECT_TRUNCATE) {
    418         soc_mem_field32_set(unit, mem, (uint32 *)&ep_ctc_res_table_entry,
    419                             FIRST_CELL_ONLYf, 1);
    420     }
    421 
    422     /* Write the entry to hardware */
    423     SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem,
    424                                       MEM_BLOCK_ALL, table_index,
    425                                       &ep_ctc_res_table_entry));
    426 
    427     /* Mark that this index is now in use */
    428     SHR_BITSET(_bcmi_rx_egr_drop_copy_to_cpu_loc_bitmap[unit], table_index);
    429 
    430     /* Update the local software copy */
    431     BCMI_GET_COPY_TOCPU_FLAGS_SET(unit, table_index,
    432                                   copyToCpu_config->flags);
    433     BCMI_GET_COPY_TOCPU_DROP_REASONS_SET(unit, table_index,
    434                                          copyToCpu_config->drop_reason_vector);
    435     BCMI_GET_COPY_TOCPU_STRENGTH_SET(unit, table_index,
    436                                      copyToCpu_config->strength);
    437     BCMI_GET_COPY_TOCPU_BUFFER_PRIORITY_SET(unit, table_index,
    438                                             copyToCpu_config->buffer_priority);
    439     BCMI_GET_COPY_TOCPU_COS_Q_SET(unit, table_index,
    440                                             copyToCpu_config->cpu_cosq);
    441 
    442     return BCM_E_NONE;
    443 }
    444 
    445 /*
    446  * Function:
    447  *      bcmi_xgs5_rx_CopyToCpu_config_get
    448  * Purpose:
    449  *      Get a copy-to-cpu entry
    450  * Parameters:
    451  *      unit              - (IN) device id.
    452  *      table_index       - (IN) Index of the entry.
    453  *      copyToCpu_config  - (OUT) Pointer to the copy-to-cpu config structure
    454  * Returns:
    455  *      BCM_E_*
    456  */
    457 
    458 int bcmi_xgs5_rx_CopyToCpu_config_get(int unit, int table_index,
    459                            bcm_rx_CopyToCpu_config_t *copyToCpu_config)
    460 {
    461     /* Sanity check */
    462     if(copyToCpu_config == NULL) {
    463         return BCM_E_PARAM;
    464     }
    465 
    466     /* Validate the index */
    467     BCM_IF_ERROR_RETURN(bcmi_xgs5_rx_CopyToCpu_index_check(unit,
    468                                                            table_index));
    469 
    470     /* Check if the entry is configured, it is an invalid index if it is not */
    471     if(bcmi_xgs5_rx_CopyToCpu_index_in_use_check(unit,
    472                           table_index) != BCM_E_EXISTS) {
    473 
    474         return BCM_E_PARAM;
    475     }
    476 
    477     /* Copy the software copy to send back to user */
    478     copyToCpu_config->index = table_index;
    479     copyToCpu_config->flags =
    480                       BCMI_GET_COPY_TOCPU_FLAGS_GET(unit, table_index);
    481     copyToCpu_config->drop_reason_vector =
    482                       BCMI_GET_COPY_TOCPU_DROP_REASONS_GET(unit, table_index);
    483     copyToCpu_config->strength =
    484                       BCMI_GET_COPY_TOCPU_STRENGTH_GET(unit, table_index);
    485     copyToCpu_config->buffer_priority =
    486                       BCMI_GET_COPY_TOCPU_BUFFER_PRIORITY_GET(unit, table_index);
    487     copyToCpu_config->cpu_cosq =
    488                       BCMI_GET_COPY_TOCPU_COS_Q_GET(unit, table_index);
    489 
    490     return BCM_E_NONE;
    491 }
    492 
    493 /*
    494  * Function:
    495  *      bcmi_xgs5_rx_CopyToCpu_config_delete
    496  * Purpose:
    497  *      Delete a copy-to-cpu entry
    498  * Parameters:
    499  *      unit   - (IN) device id.
    500  *      index  - (IN) Index of the entry to delete
    501  * Returns:
    502  *      BCM_E_*
    503  */
    504 
    505 int bcmi_xgs5_rx_CopyToCpu_config_delete(int unit, int table_index)
    506 {
    507     soc_mem_t mem = EP_CTC_RES_TABLEm;
    508 
    509     /* Validate the index */
    510     BCM_IF_ERROR_RETURN(bcmi_xgs5_rx_CopyToCpu_index_check(unit,
    511                                                            table_index));
    512 
    513     /* Check if the entry is configured */
    514     if(bcmi_xgs5_rx_CopyToCpu_index_in_use_check(unit,
    515                           table_index) != BCM_E_EXISTS) {
    516         return BCM_E_PARAM;
    517     }
    518 
    519     /* Reset the entry */
    520     SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ANY, table_index,
    521                         soc_mem_entry_null(unit, mem)));
    522 
    523     /* Mark that this index is now cleared */
    524     SHR_BITCLR(_bcmi_rx_egr_drop_copy_to_cpu_loc_bitmap[unit], table_index);
    525 
    526     /* Clear out the software copy */
    527     sal_memset((_bcmi_rx_egr_drop_copy_to_cpu_config_data[unit] + table_index), 0,
    528                sizeof(bcm_rx_CopyToCpu_config_t));
    529 
    530     return BCM_E_NONE;
    531 }
    532 
    533 /*
    534  * Function:
    535  *      bcmi_xgs5_rx_CopyToCpu_config_get_all
    536  * Purpose:
    537  *      Retrieve muultiple copy-to-cpu entries
    538  * Parameters:
    539  *      unit              - (IN) device id.
    540  *      entries_max       - (IN) Max entries to retrieve
    541  *      copyToCpu_config  - (OUT) Pointer to the copy-to-cpu config structure
    542  *      entries_count     - (OUT) Number of entries actually retrieved
    543  * Returns:
    544  *      BCM_E_*
    545  */
    546 
    547 int bcmi_xgs5_rx_CopyToCpu_config_get_all(int unit, int entries_max,
    548                                  bcm_rx_CopyToCpu_config_t *copyToCpu_config,
    549                                  int *entries_count)
    550 {
    551     int index = 0, max_index = 0;
    552     soc_mem_t mem = EP_CTC_RES_TABLEm;
    553 
    554     /* Sanity check */
    555     if(entries_count) {
    556         *entries_count = 0;
    557     } else {
    558         return BCM_E_PARAM;
    559     }
    560 
    561     /* Gather the table depth */
    562     max_index = soc_mem_index_count(unit, mem);
    563 
    564     /* If the 'entries_max' is 0 and the user provided 'copyToCpu_config'
    565        in NULL, the user only wants to get a count of configured entries.
    566        Run thru the list and count configured entries.
    567 
    568        If the user has set the 'entries_max' as 0 and the data holder
    569        'copyToCpu_config' is non-NULL, send back a 'param' error */
    570     if((entries_max == 0) && (copyToCpu_config == NULL)) {
    571         /* Iterate over configured entries */
    572         SHR_BIT_ITER(_bcmi_rx_egr_drop_copy_to_cpu_loc_bitmap[unit],
    573                      max_index,
    574                      index) {
    575             /* Keep incrementing the number of entries processed */
    576             (*entries_count)++;
    577         }
    578 
    579         return BCM_E_NONE;
    580     } else if((entries_max == 0) && (copyToCpu_config != NULL)) {
    581         return BCM_E_PARAM;
    582     }
    583 
    584     /* Run through the configured list and fill in needed data of configured
    585        entries */
    586     SHR_BIT_ITER(_bcmi_rx_egr_drop_copy_to_cpu_loc_bitmap[unit],
    587                  max_index,
    588                  index) {
    589         /* Fill in the modid data if the modid_max is non-zero and the
    590            data place holder is allocated */
    591         if(entries_max && copyToCpu_config) {
    592             copyToCpu_config[*entries_count].index = index;
    593             BCM_IF_ERROR_RETURN(bcmi_xgs5_rx_CopyToCpu_config_get(unit,
    594                                     index, &copyToCpu_config[*entries_count]));
    595             /* Keep incrementing the number of entries processed */
    596             (*entries_count)++;
    597             /* Keep decrementing the number of mods requested */
    598             if(entries_max > 0) {
    599                 --entries_max;
    600             }
    601         }
    602     }
    603 
    604     return BCM_E_NONE;
    605 }
    606 
    607 /*
    608  * Function:
    609  *      bcmi_xgs5_rx_CopyToCpu_config_delete_all
    610  * Purpose:
    611  *      Delete all copy-to-cpu entries configured
    612  * Parameters:
    613  *      unit              - (IN) device id.
    614  * Returns:
    615  *      BCM_E_*
    616  */
    617 
    618 int bcmi_xgs5_rx_CopyToCpu_config_delete_all(int unit)
    619 {
    620     int index = 0, max_index = 0;
    621     soc_mem_t mem = EP_CTC_RES_TABLEm;
    622 
    623     /* Gather the table depth */
    624     max_index = soc_mem_index_count(unit, mem);
    625 
    626     /* Run thru the list delete configured entries */
    627     SHR_BIT_ITER(_bcmi_rx_egr_drop_copy_to_cpu_loc_bitmap[unit], max_index, index) {
    628         BCM_IF_ERROR_RETURN(
    629             bcmi_xgs5_rx_CopyToCpu_config_delete(unit, index));
    630     }
    631 
    632     return BCM_E_NONE;
    633 }
    634 
    635 #endif /* BCM_EP_REDIRECT_VERSION_2*/