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

sat.c (131370B)


      1 /* 
      2  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      3  * 
      4  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      5  *
      6  * File:
      7  *  sat.c
      8  *
      9  * Purpose:
     10  *  SAT implementation for SABER2 family of devices.
     11  */
     12 
     13 #include <sal/core/libc.h>
     14 #include <shared/bsl.h>
     15 #include <soc/defs.h>
     16 #include <soc/drv.h>
     17 #include <soc/mem.h>
     18 #include <soc/debug.h>
     19 #include <soc/hash.h>
     20 #include <soc/feature.h>
     21 #include <bcm_int/esw_dispatch.h>
     22 #include <shared/idxres_fl.h>
     23 #include <shared/idxres_afl.h>
     24 #include <shared/hash_tbl.h>
     25 #include <bcm_int/esw/trunk.h>
     26 
     27 #include <bcm/sat.h>
     28 #include <bcm_int/esw/sat.h>
     29 
     30 #if defined(BCM_SABER2_SUPPORT)
     31 #include <soc/saber2.h>
     32 #include <bcm_int/esw/saber2.h>
     33 
     34 #include <bcm_int/esw/katana2.h>
     35 
     36 
     37 /* * * * * * * * * * * * * * * * * * *
     38  *            SAT MACROS             *
     39  */
     40 /*
     41  * Macro:
     42  *     _BCM_SAT_IS_INIT (internal)
     43  * Purpose:
     44  *     Check that the unit is valid and confirm that the sat functions
     45  *     are initialized.
     46  * Parameters:
     47  *     unit - BCM device number
     48  * Notes:
     49  *     Results in return(BCM_E_UNIT), return(BCM_E_UNAVAIL), or
     50  *     return(BCM_E_INIT) if fails.
     51  */
     52 #define _BCM_SAT_IS_INIT(unit)                                               \
     53             do {                                                             \
     54                 if (!soc_feature(unit, soc_feature_sat)) {                   \
     55                     return (BCM_E_UNAVAIL);                                  \
     56                 }                                                            \
     57                 if (_sb2_sat_control[unit] == NULL) {                        \
     58                     LOG_ERROR(BSL_LS_BCM_SAT,                                \
     59                     (BSL_META_U(unit,                                        \
     60                     "SAT(unit %d) Error: Module not initialized\n"),         \
     61                             unit));                                          \
     62                     return (BCM_E_INIT);                                     \
     63                 }                                                            \
     64             } while (0)
     65 
     66 /*
     67  *Macro:
     68  *     _BCM_SAT_LOCK
     69  * Purpose:
     70  *     Acquire the SAT control mutex Lock
     71  * Parameters:
     72  *     control - Pointer to SAT control structure.
     73  */
     74 #define _BCM_SAT_LOCK(control) \
     75             sal_mutex_take((control)->sat_lock, sal_mutex_FOREVER)
     76 
     77 /*
     78  * Macro:
     79  *     _BCM_SAT_UNLOCK
     80  * Purpose:
     81  *     Release the SAT control mutex Lock
     82  * Parameters:
     83  *     control - Pointer to SAT control structure.
     84  */
     85 #define _BCM_SAT_UNLOCK(control) \
     86             sal_mutex_give((control)->sat_lock);
     87 /*
     88  * Macro:
     89  *     _BCM_SAT_HASH_DATA_CLEAR
     90  * Purpose:
     91  *      Clear hash data memory occupied by one endpoint.
     92  * Parameters:
     93  *     _ptr_    - Pointer to endpoint hash data memory. 
     94  */
     95 #define _BCM_SAT_HASH_DATA_CLEAR(_ptr_) \
     96             sal_memset(_ptr_, 0, sizeof(_bcm_sat_hash_data_t));
     97 
     98 
     99 /*
    100  * Macro:
    101  *     _BCM_SAT_ALLOC
    102  * Purpose:
    103  *      Generic memory allocation routine.
    104  * Parameters:
    105  *    _ptr_     - Pointer to allocated memory.
    106  *    _ptype_   - Pointer type.
    107  *    _size_    - Size of heap memory to be allocated.
    108  *    _descr_   - Information about this memory allocation.
    109  */
    110 #define _BCM_SAT_ALLOC(_ptr_,_ptype_,_size_,_descr_)                     \
    111             do {                                                         \
    112                 if (NULL == (_ptr_)) {                                   \
    113                    (_ptr_) = (_ptype_ *) sal_alloc((_size_), (_descr_)); \
    114                 }                                                        \
    115                 if((_ptr_) != NULL) {                                    \
    116                     sal_memset((_ptr_), 0, (_size_));                    \
    117                 }  else {                                                \
    118                     LOG_ERROR(BSL_LS_BCM_SAT,                            \
    119                         (BSL_META_U(unit,                                \
    120                               "SAT Error: Allocation failure %s\n"),     \
    121                             (_descr_)));                                 \
    122                 }                                                        \
    123             } while (0)
    124 
    125 
    126 /*
    127  * Macro:
    128  *     _BCM_SAT_MEP_INDEX_VALIDATE
    129  * Purpose:
    130  *     Validate UPMEP/DOWNMEP SAT Endpoint ID value.
    131  * Parameters:
    132  *     _ep_ - Endpoint ID value.
    133  */
    134 #define _BCM_SAT_MEP_INDEX_VALIDATE(mep_count,_ep_)                       \
    135             do {                                                          \
    136                 if ((_ep_) < 0 || (_ep_) >= mep_count) {                  \
    137                     LOG_ERROR(BSL_LS_BCM_SAT,                             \
    138                              (BSL_META_U(unit,                            \
    139                              "SAT(unit %d) Error: Invalid  MEP Index"     \
    140                              " = %d.\n"), unit, _ep_));                   \
    141                     return (BCM_E_PARAM);                                 \
    142                 }                                                         \
    143             } while (0);
    144 
    145 
    146 /*
    147  * Macro:
    148  *     _BCM_SB2_SAT_MOD_PORT_TO_GLP
    149  * Purpose:
    150  *     Construct hadware GLP value from module ID, port ID and Trunk ID value.
    151  * Parameters:
    152  *     _modid_ - Module ID.
    153  *     _port_  - Port ID.
    154  *     _trunk_ - Trunk (1 - TRUE/ 0- FALSE).
    155  *     _tgid_  - Trunk ID.
    156  */
    157 #define _BCM_SB2_SAT_MOD_PORT_TO_GLP(_u_, _m_, _p_, _t_, _tgid_, _glp_)     \
    158     do {                                                                    \
    159         if ((_tgid_) != -1) {                                               \
    160             (_glp_) = (((0x1 & (_t_)) << SOC_TRUNK_BIT_POS(_u_))            \
    161                 | ((soc_mem_index_count((_u_), TRUNK_GROUPm) - 1)           \
    162                 & (_tgid_)));                                               \
    163         } else {                                                            \
    164             (_glp_) = (((0x1 & (_t_)) << SOC_TRUNK_BIT_POS(_u_))            \
    165                 | ((SOC_MODID_MAX(_u_) & (_m_))                             \
    166                 << (_shr_popcount((unsigned int) SOC_PORT_ADDR_MAX(_u_)))   \
    167                 | (SOC_PORT_ADDR_MAX(_u_) & (_p_))));                       \
    168         }                                                                   \
    169         LOG_DEBUG(BSL_LS_BCM_SAT,                                           \
    170                   (BSL_META_U(unit,                                         \
    171                      "u:%d m:%d p:%d t:%d tgid:%d glp:%x\n"),               \
    172                      _u_, _m_, _p_, _t_, _tgid_, _glp_));                   \
    173     } while (0)
    174 
    175 
    176 
    177 /*
    178  * Macro:
    179  *     _BCM_SAT_KEY_PACK
    180  * Purpose:
    181  *     Pack the hash table look up key fields.
    182  * Parameters:
    183  *     _dest_ - Hash key buffer.
    184  *     _src_  - Hash key field to be packed.
    185  *     _size_ - Hash key field size in bytes.
    186  */
    187 #define _BCM_SAT_KEY_PACK(_dest_,_src_,_size_)            \
    188             do {                                          \
    189                 sal_memcpy((_dest_), (_src_), (_size_));  \
    190                 (_dest_) += (_size_);                     \
    191             } while (0)
    192 
    193 /*
    194  * Macro:
    195  *     _BCM_SAT_CPU_OLP_HDR_SET
    196  * Purpose:
    197  *     Enable/Disable adding OLP header to SAT packet forwarded to CPU port
    198  * Parameters:
    199  *     unit - BCM device number
    200  *     olp_hdr - Enable/Disable OLP header for SAT packet forwarded to CPU port
    201  * Notes:
    202  */
    203 #define _BCM_SAT_CPU_OLP_HDR_SET(unit, olp_hdr) \
    204       do {                                          \
    205           SOC_IF_ERROR_RETURN(WRITE_EGR_OAM_RX_MODE_FOR_CPUr(unit,olp_hdr)); \
    206       } while (0)
    207 
    208 /*
    209  * Macro:
    210  *     _BCM_SAT_GLP_XXX
    211  * Purpose:
    212  *     Get components of generic logical port value.
    213  * Parameters:
    214  *     _glp_ - Generic logical port.
    215  */
    216 #define _BCM_SAT_GLP_TRUNK_BIT_GET(_u_, _glp_)        \
    217         (0x1 & ((_glp_) >> SOC_TRUNK_BIT_POS(_u_)))
    218 #define _BCM_SAT_GLP_TRUNK_ID_GET(_u_, _glp_)         \
    219         ((soc_mem_index_count((_u_), TRUNK_GROUPm)    \
    220                                    - 1) & (_glp_))
    221 #define _BCM_SAT_GLP_MODULE_ID_GET(_u_, _glp_)        \
    222         (SOC_MODID_MAX(_u_) & ((_glp_) >>             \
    223         (_shr_popcount((unsigned int)                 \
    224         SOC_PORT_ADDR_MAX(_u_)))))
    225 #define _BCM_SAT_GLP_PORT_GET(_u_, _glp_)             \
    226         (SOC_PORT_ADDR_MAX(_u_) & (_glp_))
    227 
    228 /*
    229  * Macro: _SAT_HASH_KEY_SIZE
    230  *
    231  * Purpose:
    232  *      SAT endpoint hash table key size.
    233  */
    234 
    235 /* Outer VLAN ID + Inner VLAN ID + MAC DA + MAC SA + Gport + Ether type */
    236 #define _SAT_HASH_KEY_SIZE (2 + 2 + 6 + 6 + 4 + 2 )
    237 
    238 /* Define the port used in OLP-XGS communication */
    239 #define _BCM_SAT_OLP_COMMUNICATION_PORT  0x7f
    240 
    241 /* Define the VLAN ID mask */
    242 #define _BCM_SAT_VLAN_MASK          0xfff
    243 
    244 /* Define the priority mask  */
    245 #define _BCM_SAT_VLAN_PRIO_MASK     0x07
    246 
    247 /* Define the priority bit field location  */
    248 #define _BCM_SAT_VLAN_PRI_BIT       13
    249 
    250 /* Define the CFi bit field location  */
    251 #define _BCM_SAT_VLAN_CFI_BIT       12
    252 
    253 /* Define generic enable field */
    254 #define _BCM_SAT_ENABLE             0x1
    255 
    256 /* Define generic disable field */
    257 #define _BCM_SAT_DISABLE            0x0
    258 
    259 #define _BCM_SAT_SRC_GPORT          0x0001
    260 #define _BCM_SAT_DEST_GPORT         0x0002
    261 
    262 /* SAT Entry TCAM VALID bit to be set to 3 for valid entry */
    263 #define BCM_SAT_TCAM_ENTRY_VALID    3
    264 
    265 /*
    266  * Macro:
    267  *     _BCM_SAT_VLAN_PRI_SET
    268  * Purpose:
    269  *     Set priority to VLAN tag 
    270  * Parameters:
    271  *     vlan - VLAN tag
    272  *     pri  - prioirty 
    273  *     mask - Priority field mask bits 
    274  * Notes:
    275  */
    276 #define _BCM_SAT_VLAN_PRI_SET(vlan, pri, mask) \
    277                 (vlan |= ((pri & mask ) << _BCM_SAT_VLAN_PRI_BIT))
    278 
    279 /*
    280  * Macro:
    281  *     _BCM_SAT_VLAN_PRI_GET
    282  * Purpose:
    283  *     Get priority from VLAN tag 
    284  * Parameters:
    285  *     vlan - VLAN tag
    286  *     mask - Priority field mask bits 
    287  * Notes:
    288  */
    289 #define _BCM_SAT_VLAN_PRI_GET(vlan, mask) \
    290             ((vlan & (mask << _BCM_SAT_VLAN_PRI_BIT)) >> _BCM_SAT_VLAN_PRI_BIT)
    291 
    292 /*
    293  * Macro:
    294  *     _BCM_SAT_VLAN_CFI_SET
    295  * Purpose:
    296  *     Set CFI field to VLAN tag 
    297  * Parameters:
    298  *     vlan - VLAN tag
    299  *     cfi  - CFI field 
    300  *     mask - CFI field mask bits 
    301  * Notes:
    302  */
    303 #define _BCM_SAT_VLAN_CFI_SET(vlan, cfi, mask) \
    304                 (vlan |= ((cfi & mask ) << _BCM_SAT_VLAN_CFI_BIT))
    305 
    306 /*
    307  * Macro:
    308  *     _BCM_SAT_VLAN_CFI_GET
    309  * Purpose:
    310  *     Get CFI field from VLAN tag 
    311  * Parameters:
    312  *     vlan - VLAN tag
    313  *     mask - CFI field mask bits 
    314  * Notes:
    315  */
    316 #define _BCM_SAT_VLAN_CFI_GET(vlan, mask) \
    317             ((vlan & (mask << _BCM_SAT_VLAN_CFI_BIT)) >> _BCM_SAT_VLAN_CFI_BIT)
    318 
    319 typedef uint8 _bcm_sat_hash_key_t[_SAT_HASH_KEY_SIZE];
    320 			
    321 static _bcm_sat_control_t *_sb2_sat_control[BCM_MAX_NUM_UNITS];
    322 
    323 STATIC int
    324 _bcm_sb2_sat_control_get(int unit, _bcm_sat_control_t **satc);
    325 
    326 STATIC void
    327 _bcm_sb2_sat_ep_hash_key_construct(int unit,
    328                                    _bcm_sat_control_t *satc,
    329                                    bcm_sat_endpoint_info_t *ep_info,
    330                                    _bcm_sat_hash_key_t *key);
    331 
    332 void
    333 _bcm_sb2_sat_endpoint_cleanup(int unit, int upmep, 
    334                               _bcm_sat_hash_key_t  hash_key,
    335                               _bcm_sat_hash_data_t *hash_data);
    336 
    337 STATIC int
    338 _bcm_sb2_sat_endpoint_destroy_all(int unit, uint32  flags);
    339 
    340 STATIC int
    341 _bcm_sb2_sat_mep_hw_set(int unit, bcm_sat_endpoint_info_t *ep_info_p,
    342                         uint16 sglp, uint16 dglp);
    343 
    344 STATIC int
    345 _bcm_sb2_sat_endpoint_hw_delete(int unit, _bcm_sat_hash_data_t *h_data_p);
    346 
    347 #if defined(BCM_WARM_BOOT_SUPPORT)
    348 STATIC int
    349 _bcm_sb2_sat_wb_upmep_endpoints_recover(int unit);
    350 
    351 STATIC int
    352 _bcm_sb2_sat_wb_downmep_endpoints_recover(int unit);
    353 #endif
    354 
    355 /*
    356  * Function:
    357  *     _bcm_sb2_sat_control_free
    358  * Purpose:
    359  *     Free SAT control structure resources allocated by this unit.
    360  * Parameters:
    361  *     unit -  (IN) BCM unit number.
    362  *     satc -  (IN) Pointer to SAT control structure.
    363  * Returns:
    364  *     BCM_E_XXX
    365  */
    366 STATIC int
    367 _bcm_sb2_sat_control_free(int unit, _bcm_sat_control_t *satc)
    368 {
    369     int status = 0;
    370     _sb2_sat_control[unit] = NULL;
    371 
    372     if (NULL == satc) {
    373         /* Module already un-initialized. */
    374         return (BCM_E_NONE);
    375     }
    376 
    377     /* Free protection mutex. */
    378     if (NULL != satc->sat_lock) {
    379         sal_mutex_destroy(satc->sat_lock);
    380     }
    381 
    382     /* Free UP-MEP hash data storage memory. */
    383     if (NULL != satc->upsamp_hash_data) {
    384         sal_free(satc->upsamp_hash_data);
    385     }
    386 
    387     /* Destory UP-MEP endpoint hash table. */
    388     if (NULL != satc->upsamp_htbl) {
    389         status = shr_htb_destroy(&satc->upsamp_htbl, NULL);
    390         if (BCM_FAILURE(status)) {
    391             LOG_ERROR(BSL_LS_BCM_SAT, 
    392                       (BSL_META_U(unit, "Freeing UP-MEP samp_htbl failed\n")));
    393         }
    394     }
    395 
    396     /* Free Down-MEP hash data storage memory. */
    397     if (NULL != satc->downsamp_hash_data) {
    398         sal_free(satc->downsamp_hash_data);
    399     }
    400 
    401     /* Destory Down-MEP endpoint hash table. */
    402     if (NULL != satc->downsamp_htbl) {
    403         status = shr_htb_destroy(&satc->downsamp_htbl, NULL);
    404         if (BCM_FAILURE(status)) {
    405             LOG_ERROR(BSL_LS_BCM_SAT, 
    406                       (BSL_META_U(unit,
    407                                   "Freeing Down-MEP samp_htbl failed\n")));
    408         }
    409     }
    410 
    411     /* Destroy UP MEP endpoint indices list. */
    412     if (NULL != satc->upsamp_mep_pool) {
    413         shr_idxres_list_destroy(satc->upsamp_mep_pool);
    414         satc->upsamp_mep_pool = NULL;
    415     }
    416 
    417     /* Destroy DOWN MEP endpoint indices list. */
    418     if (NULL != satc->downsamp_mep_pool) {
    419         shr_idxres_list_destroy(satc->downsamp_mep_pool);
    420         satc->downsamp_mep_pool = NULL;
    421     }
    422 
    423     /* Free SAT control structure memory. */
    424     sal_free(satc);
    425 
    426     return (BCM_E_NONE);
    427 }
    428 
    429 
    430 typedef struct _bcm_sat_olp_hdr_type_map_s {
    431    uint32  mem_index;
    432    uint32  hdr_type;
    433    uint32  hdr_subtype; 
    434 } _bcm_sat_olp_hdr_type_map_t;
    435 
    436 /*
    437  * Function:
    438  *     _bcm_sb2_sat_olp_header_type_mapping_set
    439  * Purpose:
    440  *    Set default olp header type mapping 
    441  * Parameters:
    442  *     unit - (IN) BCM device number
    443  * Retruns:
    444  *     BCM_E_XXX
    445  * MEP_TYPE      COMPRESSED_HDR_TYPE       HDR_TYPE          HDR_SUBTYPE
    446  * ==========================================================================
    447  *  Downmep/IFP      3'b000                8'd1(L2_HDR)      8'd0(NULL)
    448  *  Downmep/IFP      3'b001                8'd0(OAM_HDR)     8'd2(CCM/BHH-CCM)
    449  *  Downmep/IFP      3'b010                8'd0(OAM_HDR)     8'd3(BFD)
    450  *  Downmep/IFP      3'b011                8'd0(OAM_HDR)     8'd4(LM/DM)
    451  *  Downmep/IFP      5'b01111              8'd1(L2_HDR)      8'd15(SAT)
    452  *  Upmep            3'b000                N/A               N/A
    453  *  Upmep            3'b001                8'd0(OAM_HDR)     8'd5(CCM)
    454  *  Upmep            3'b010                N/A               N/A
    455  *  Upmep            3'b011                8'd0(OAM_HDR)     8'd6(LM/DM)
    456  *  Upmep            5'b01111              8'd1(L2_HDR)      8'd21(SAT)
    457  */
    458 STATIC int
    459 _bcm_sb2_sat_olp_header_type_mapping_set(int unit) 
    460 {
    461     int rv = BCM_E_NONE;
    462     int index = 0;
    463     int entry_mem_size;    /* Size of table entry. */
    464     int entry_count = 0;
    465 
    466     egr_olp_header_type_mapping_entry_t *entry_buf;
    467     egr_olp_header_type_mapping_entry_t *entry;
    468     _bcm_sat_olp_hdr_type_map_t olp_hdr_type;
    469 
    470     _bcm_sat_olp_hdr_type_map_t olp_hdr_type_map[] = {
    471         /* SAT DownMEP index */
    472         { BCM_SAT_DOWNMEP_OLP_HDR_COMPRESSED,  1, 0xf},
    473         /* SAT UpMEP index (5th bit set to 1 for upmep) */
    474         { (BCM_SAT_UPMEP_OLP_HDR_COMPRESSED | 0x20), 1, 0x15},
    475         { 0xff }
    476     };
    477 
    478     entry_count = soc_mem_index_count(unit, EGR_OLP_HEADER_TYPE_MAPPINGm);
    479     entry_mem_size = sizeof(egr_olp_header_type_mapping_entry_t);
    480 
    481     /* Allocate buffer to store the DMAed table entries. */
    482     entry_buf = soc_cm_salloc(unit, entry_mem_size * entry_count,
    483                               "olp header type mapping buffer");
    484     if (NULL == entry_buf) {
    485         return (BCM_E_MEMORY);
    486     }
    487     /* Initialize the entry buffer. */
    488     sal_memset(entry_buf, 0, sizeof(entry_mem_size) * entry_count);
    489 
    490     /* Read the table entries into the buffer. */
    491     rv = soc_mem_read_range(unit, EGR_OLP_HEADER_TYPE_MAPPINGm, MEM_BLOCK_ALL,
    492                             0, (entry_count-1), entry_buf);
    493     if (BCM_FAILURE(rv)) {
    494         if (entry_buf) {
    495             soc_cm_sfree(unit, entry_buf);
    496         }
    497         return rv;
    498     }
    499 
    500     for (index = 0; ;index++) { 
    501         olp_hdr_type = olp_hdr_type_map[index];
    502         if(olp_hdr_type.mem_index == 0xff) {
    503             /* End of table */
    504             break;
    505         }
    506         if (olp_hdr_type.mem_index >= entry_count) {
    507             soc_cm_sfree(unit, entry_buf);
    508             return BCM_E_INTERNAL;
    509         }
    510         entry = soc_mem_table_idx_to_pointer (unit, 
    511                                          EGR_OLP_HEADER_TYPE_MAPPINGm, 
    512                                          egr_olp_header_type_mapping_entry_t *,
    513                                          entry_buf, olp_hdr_type.mem_index);
    514         soc_mem_field_set(unit, EGR_OLP_HEADER_TYPE_MAPPINGm, 
    515                           (uint32 *)entry, HDR_TYPEf, 
    516                           &(olp_hdr_type.hdr_type));
    517         soc_mem_field_set(unit, EGR_OLP_HEADER_TYPE_MAPPINGm, 
    518                           (uint32 *)entry, HDR_SUBTYPEf, 
    519                           &(olp_hdr_type.hdr_subtype));
    520     } 
    521     rv = soc_mem_write_range(unit, EGR_OLP_HEADER_TYPE_MAPPINGm, 
    522                             MEM_BLOCK_ALL, 0, (entry_count - 1), entry_buf); 
    523     soc_cm_sfree(unit, entry_buf);
    524     return rv;
    525 }
    526 
    527 
    528 /*
    529  * Function:
    530  *     _bcm_sb2_sat_olp_magic_port_set
    531  * Purpose:
    532  *     Set Magic port used in OLP-XGS communication 
    533  * Parameters:
    534  *     unit - (IN) BCM device number
    535  * Retruns:
    536  *     BCM_E_XXX
    537  */
    538 STATIC int
    539 _bcm_sb2_sat_olp_magic_port_set(int unit)
    540 {
    541     uint64 rval, set_val;
    542     int    modid;
    543 
    544     COMPILER_64_ZERO(rval); 
    545 
    546     /* configure modid and the magic port */
    547     BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &modid));
    548     SOC_IF_ERROR_RETURN(READ_IARB_OLP_CONFIG_1r(unit, &rval));
    549 
    550     COMPILER_64_SET(set_val, 0, modid);
    551     soc_reg64_field_set(unit, IARB_OLP_CONFIG_1r, &rval, MY_MODIDf, set_val);
    552     COMPILER_64_SET(set_val, 0, _BCM_SAT_OLP_COMMUNICATION_PORT);
    553     soc_reg64_field_set(unit, IARB_OLP_CONFIG_1r, &rval, MY_PORT_NUMf, set_val);
    554 
    555     SOC_IF_ERROR_RETURN(WRITE_IARB_OLP_CONFIG_1r(unit, rval));
    556     return (BCM_E_NONE);
    557 }
    558 
    559 
    560 /*
    561  * Function:
    562  *     _bcm_sb2_sat_olp_magic_port_clear
    563  * Purpose:
    564  *     Clear Magic port used in OLP-XGS communication 
    565  * Parameters:
    566  *     unit - (IN) BCM device number
    567  * Retruns:
    568  *     BCM_E_XXX
    569  */
    570 STATIC int
    571 _bcm_sb2_sat_olp_magic_port_clear(int unit)
    572 {
    573     uint64 rval, set_val;
    574 
    575     COMPILER_64_ZERO(rval); 
    576 
    577     /* clear modid and the magic port */
    578     SOC_IF_ERROR_RETURN(READ_IARB_OLP_CONFIG_1r(unit, &rval));
    579 
    580     COMPILER_64_SET(set_val, 0, 0);
    581     soc_reg64_field_set(unit, IARB_OLP_CONFIG_1r, &rval, MY_MODIDf, set_val);
    582     soc_reg64_field_set(unit, IARB_OLP_CONFIG_1r, &rval, MY_PORT_NUMf, set_val);
    583 
    584     SOC_IF_ERROR_RETURN(WRITE_IARB_OLP_CONFIG_1r(unit, rval));
    585     return (BCM_E_NONE);
    586 }
    587 
    588 /*
    589  * Function:
    590  *     _bcm_sb2_sat_hg_olp_mode_set
    591  * Purpose:
    592  *    Enable/Disable OLP handling on HG ports 
    593  * Parameters:
    594  *     unit - (IN) BCM device number
    595  *     olp_mode - (IN) OLP enable mode
    596  * Returns:
    597  *     BCM_E_XXX
    598  */
    599 STATIC int
    600 _bcm_sb2_sat_hg_olp_mode_set(int unit, uint32 olp_mode)
    601 {
    602     bcm_pbmp_t pbmp;
    603     bcm_port_t port;
    604     iarb_ing_physical_port_entry_t entry;
    605 
    606     BCM_PBMP_ASSIGN(pbmp, PBMP_PORT_ALL(unit));
    607     PBMP_ITER(pbmp, port) {
    608         SOC_IF_ERROR_RETURN(soc_mem_read(unit, IARB_ING_PHYSICAL_PORTm, 
    609                                          MEM_BLOCK_ANY, port, &entry));
    610         if (IS_HG_PORT(unit, port)) {
    611             soc_IARB_ING_PHYSICAL_PORTm_field32_set(unit, &entry, 
    612                                                     OLP_ENABLEf, olp_mode);
    613         } else {
    614             soc_IARB_ING_PHYSICAL_PORTm_field32_set(unit, &entry, 
    615                                                     OLP_ENABLEf, 0);
    616         }
    617         SOC_IF_ERROR_RETURN(soc_mem_write(unit, IARB_ING_PHYSICAL_PORTm, 
    618                                               MEM_BLOCK_ALL, port, &entry));
    619     }
    620     return (BCM_E_NONE);
    621 }
    622 
    623 
    624 /*
    625  * Function:
    626  *     _bcm_sb2_sat_endpoint_count_init
    627  * Purpose:
    628  *     Retrieves and initializes endpoint count information for this device.
    629  * Parameters:
    630  *     unit -  (IN) BCM unit number.
    631  *     satc -  (IN) Pointer to device SAT control structure.
    632  * Returns:
    633  *     BCM_E_XXX
    634  */
    635 STATIC int
    636 _bcm_sb2_sat_endpoint_count_init(int unit, _bcm_sat_control_t *satc)
    637 {
    638 
    639     /* Input parameter check. */
    640     if (NULL == satc) {
    641         return (BCM_E_PARAM);
    642     }
    643 
    644     /*
    645      * Get endpoint hardware table index count values and
    646      * initialize device SAT control structure members variables.
    647      */
    648     satc->upsamp_ep_count   = soc_mem_index_count(unit, EGR_SAT_SAMP_TCAMm);
    649     satc->downsamp_ep_count = soc_mem_index_count(unit, ING_SAT_SAMP_TCAMm);
    650 
    651     LOG_VERBOSE(BSL_LS_BCM_SAT, 
    652                 (BSL_META_U(unit,
    653                 "SAT(unit %d) Info: Total No. UP SAMP endpoint Count = %d.\n"),
    654                 unit, satc->upsamp_ep_count));
    655 
    656     LOG_VERBOSE(BSL_LS_BCM_SAT, 
    657                 (BSL_META_U(unit,
    658                 "SAT(unit %d) Info: Total No. DOWN SAMP endpoint Count = %d.\n"),
    659                 unit, satc->downsamp_ep_count));
    660 
    661     return (BCM_E_NONE);
    662 }
    663 
    664 #if defined(BCM_WARM_BOOT_SUPPORT)
    665 /*
    666  * Function:
    667  *     _bcm_sb2_sat_reinit
    668  * Purpose:
    669  *     Reconstruct SAT module software state during warmboot.
    670  * Parameters:
    671  *     unit - (IN) BCM device number
    672  * Retruns:
    673  *     BCM_E_XXX
    674  */
    675 STATIC int
    676 _bcm_sb2_sat_reinit(int unit)
    677 {
    678     int        rv = BCM_E_NONE;     /* Operation return status. */
    679 
    680     LOG_VERBOSE(BSL_LS_BCM_SAT, 
    681                 (BSL_META_U(unit,
    682                 "SAT(unit %d) Info: SAT warm boot recovery.....\n"),unit));
    683 
    684     /* Recover SAT UP MEP endpoints */
    685     rv = _bcm_sb2_sat_wb_upmep_endpoints_recover(unit);
    686     if (BCM_FAILURE(rv)) {
    687         LOG_ERROR(BSL_LS_BCM_SAT, 
    688                   (BSL_META_U(unit,
    689                   "SAT(unit %d) Error: UP MEP Endpoint recovery failed  - %s.\n"),
    690                   unit, bcm_errmsg(rv)));
    691         return (rv);
    692     }
    693 
    694     /* Recover SAT DOWN MEP endpoints */
    695     rv = _bcm_sb2_sat_wb_downmep_endpoints_recover(unit);
    696     if (BCM_FAILURE(rv)) {
    697         LOG_ERROR(BSL_LS_BCM_SAT, 
    698                   (BSL_META_U(unit,
    699                   "SAT(unit %d) Error: DOWN MEP Endpoint recovery failed  - %s.\n"),
    700                   unit, bcm_errmsg(rv)));
    701         return (rv);
    702     }
    703     
    704     return (rv);
    705 }
    706 #endif
    707 
    708 /*
    709  * Function: bcm_sb2_sat_init
    710  *
    711  * Purpose:
    712  *     Initialize SAT module.
    713  * Parameters:
    714  *     unit - (IN) BCM device number
    715  * Returns:
    716  *     BCM_E_UNIT    - Invalid BCM unit number.
    717  *     BCM_E_UNAVAIL - SAT feature not supported on this device.
    718  *     BCM_E_MEMORY  - Allocation failure
    719  *     BCM_E_XXX     - Error code from bcm_XX_sat_init()
    720  *     BCM_E_NONE    - Success
    721  */
    722 int
    723 bcm_sb2_sat_init(int unit)
    724 {
    725     _bcm_sat_control_t *satc = NULL; /* SAT control structure.     */
    726     int             rv = BCM_E_NONE; /* Operation return value.    */
    727     uint32          size;            /* Size of memory allocation. */
    728     bcm_port_t      port = _BCM_SB2_SAT_OAMP_PHY_PORT_NUMBER;
    729     egr_enable_entry_t egr_enable_entry = {{0}};
    730     soc_info_t *si = &SOC_INFO(unit);
    731     int             oamp_enable;
    732 
    733     /* Ensure that the unit has SAT support. */
    734     if (!soc_feature(unit, soc_feature_sat)) {
    735         LOG_ERROR(BSL_LS_BCM_SAT, 
    736                   (BSL_META_U(unit,
    737                   "SAT(unit %d) Error: SAT feature not supported \n"), unit));
    738         return (BCM_E_UNAVAIL);
    739     }
    740 
    741     /* Detach first if the module has been previously initialized. */
    742     if (NULL != _sb2_sat_control[unit]) {
    743         _sb2_sat_control[unit]->init = FALSE;
    744         rv = bcm_sb2_sat_detach(unit);
    745         if (BCM_FAILURE(rv)) {
    746             LOG_ERROR(BSL_LS_BCM_SAT, 
    747                       (BSL_META_U(unit,
    748                       "SAT(unit %d) Error: SAT Module deinit - %s.\n"),
    749                       unit, bcm_errmsg(rv)));
    750             return (rv);
    751         }
    752     }
    753 
    754     /* Allocate SAT control memory for this unit. */
    755     _BCM_SAT_ALLOC(satc, _bcm_sat_control_t, 
    756                    sizeof (_bcm_sat_control_t),"SAT control");
    757 
    758     if (NULL == satc) {
    759         return (BCM_E_MEMORY);
    760     }
    761 
    762     /* Get number of endpoints supported by this unit. */
    763     rv = _bcm_sb2_sat_endpoint_count_init(unit, satc);
    764     if (BCM_FAILURE(rv)) {
    765         _bcm_sb2_sat_control_free(unit, satc);
    766         return (rv);
    767     }
    768 
    769     /* Mem_1: Allocate UP-MEP hash data memory */
    770     size = sizeof(_bcm_sat_hash_data_t) * satc->upsamp_ep_count;
    771     _BCM_SAT_ALLOC(satc->upsamp_hash_data, _bcm_sat_hash_data_t, 
    772                    size, "UP MEP Hash data");
    773 
    774     if (NULL == satc->upsamp_hash_data) {
    775         _bcm_sb2_sat_control_free(unit, satc);
    776         return (BCM_E_MEMORY);
    777     }
    778 
    779 	
    780     /* Mem_2: Create UP-MEP hash table. */
    781     rv = shr_htb_create(&satc->upsamp_htbl, satc->upsamp_ep_count,
    782                         sizeof(_bcm_sat_hash_key_t), "SAT UP-MEP Hash");
    783     if (BCM_FAILURE(rv)) {
    784         _bcm_sb2_sat_control_free(unit, satc);
    785         return (rv);
    786     }
    787 
    788     /* Mem_3: Allocate Down-MEP hash data memory */
    789      size = sizeof(_bcm_sat_hash_data_t) * satc->downsamp_ep_count;
    790      _BCM_SAT_ALLOC(satc->downsamp_hash_data, _bcm_sat_hash_data_t, 
    791                     size, "Down MEP Hash data");
    792 
    793      if (NULL == satc->downsamp_hash_data) {
    794          _bcm_sb2_sat_control_free(unit, satc);
    795          return (BCM_E_MEMORY);
    796      }
    797     
    798 
    799     /* Mem_4: Create Down-MEP hash table. */
    800     rv = shr_htb_create(&satc->downsamp_htbl, satc->downsamp_ep_count,
    801                         sizeof(_bcm_sat_hash_key_t), "SAT Down-MEP Hash");
    802     if (BCM_FAILURE(rv)) {
    803         _bcm_sb2_sat_control_free(unit, satc);
    804         return (rv);
    805     }
    806 	
    807 	/* Mem_5: Create UP MEP endpoint index list. */
    808     rv = shr_idxres_list_create(&satc->upsamp_mep_pool, 0, 
    809                                 satc->upsamp_ep_count - 1, 0, 
    810                                 satc->upsamp_ep_count -1,
    811                                 "upsamp_mep_pool");         
    812     if (BCM_FAILURE(rv)) {
    813         _bcm_sb2_sat_control_free(unit, satc);
    814         return (rv);
    815     }
    816 
    817     /* Mem_6: Create DOWN MEP endpoint index list. */
    818     rv = shr_idxres_list_create(&satc->downsamp_mep_pool, 0, 
    819                             satc->downsamp_ep_count - 1, 0, 
    820                             satc->downsamp_ep_count -1, "downsamp_mep pool");
    821     if (BCM_FAILURE(rv)) {
    822         _bcm_sb2_sat_control_free(unit, satc);
    823         return (rv);
    824     }
    825 	
    826     /* Create protection mutex. */
    827     satc->sat_lock = sal_mutex_create("sat_control.lock");
    828     if (NULL == satc->sat_lock) {
    829         _bcm_sb2_sat_control_free(unit, satc);
    830         return (BCM_E_MEMORY);
    831     }
    832 
    833     /* Set up the unit SAT control structure. */
    834     _sb2_sat_control[unit] = satc;
    835 
    836     /* WARM Boot reint support for SAT   */
    837     #if defined(BCM_WARM_BOOT_SUPPORT)
    838     if (SOC_WARM_BOOT(unit)) {
    839         rv = _bcm_sb2_sat_reinit(unit);
    840         if (BCM_FAILURE(rv)) {
    841             _bcm_sb2_sat_control_free(unit, satc);
    842             return (rv);
    843         }
    844     } 
    845     #endif
    846 
    847     /* Enable OLP handling on HG ports */
    848     rv = _bcm_sb2_sat_hg_olp_mode_set(unit, _BCM_SAT_ENABLE);
    849     if (BCM_FAILURE(rv)) {
    850         _bcm_sb2_sat_control_free(unit, satc);
    851         return (rv);
    852     }
    853 
    854     /* Set default olp header type mapping */
    855     rv = _bcm_sb2_sat_olp_header_type_mapping_set(unit); 
    856     if (BCM_FAILURE(rv)) {
    857         _bcm_sb2_sat_control_free(unit, satc);
    858         return (rv);
    859     }
    860 
    861     /* Set Magic port used in OLP-XGS communication */
    862     rv = _bcm_sb2_sat_olp_magic_port_set(unit); 
    863     if (BCM_FAILURE(rv)) {
    864         _bcm_sb2_sat_control_free(unit, satc);
    865         return (rv);
    866     }
    867 
    868     /* Set OLP header add for SAT packet forwarded to CPU port */
    869     _BCM_SAT_CPU_OLP_HDR_SET(unit, _BCM_SAT_ENABLE);
    870 
    871     if(SOC_WARM_BOOT(unit)) {
    872         (void)bcm_sb2_sat_oamp_enable_get(unit, &oamp_enable);
    873     }
    874 
    875     if((!SOC_WARM_BOOT(unit) &&
    876             (soc_property_get(unit, spn_SAT_ENABLE, FALSE) == FALSE)) ||
    877       (SOC_WARM_BOOT(unit) && (oamp_enable == FALSE))) {
    878         /* SAT initialization complete. */
    879         _sb2_sat_control[unit]->init = TRUE;
    880         return (BCM_E_NONE);
    881     }
    882 
    883     /* Enable OAMP and egress */
    884     SOC_IF_ERROR_CLEAN_RETURN((bcm_sb2_sat_oamp_enable_set(unit, TRUE)),
    885             _bcm_sb2_sat_control_free(unit, satc));
    886     /* Keep port in FWD state w.r.t OAMP engine */
    887     if(!SOC_WARM_BOOT(unit)) {
    888         BCM_IF_ERROR_RETURN(bcm_esw_port_stp_set(unit, port, 
    889                     BCM_STG_STP_FORWARD));
    890     }
    891     sal_memset(&egr_enable_entry, 0, sizeof(egr_enable_entry_t));
    892     soc_mem_field32_set(unit, EGR_ENABLEm, &egr_enable_entry, PRT_ENABLEf, 1);
    893     SOC_IF_ERROR_CLEAN_RETURN((WRITE_EGR_ENABLEm(unit, MEM_BLOCK_ALL, port,
    894                 &egr_enable_entry)),_bcm_sb2_sat_control_free(unit, satc));
    895 
    896     /* detach phy for the sat port */
    897     SOC_IF_ERROR_CLEAN_RETURN((soc_phyctrl_detach(unit, port)),
    898             _bcm_sb2_sat_control_free(unit, satc));
    899     /* Remove the port from ethernet pbmps */
    900     if (SOC_PBMP_MEMBER(si->ge.bitmap, port)) {
    901         SOC_PBMP_PORT_REMOVE(si->ge.bitmap, port);
    902         SOC_PBMP_PORT_ADD(si->ge.disabled_bitmap, port);
    903     } else {
    904         SOC_PBMP_PORT_REMOVE(si->xe.bitmap, port);
    905         SOC_PBMP_PORT_ADD(si->xe.disabled_bitmap, port);
    906     }
    907     SOC_PBMP_PORT_REMOVE(si->ether.bitmap, port);
    908     SOC_PBMP_PORT_ADD(si->ether.disabled_bitmap, port);
    909 
    910     SOC_PBMP_PORT_REMOVE(si->port.bitmap, port);
    911     SOC_PBMP_PORT_ADD(si->port.disabled_bitmap, port);
    912 
    913     SOC_PBMP_PORT_ADD(si->intp.bitmap, port);
    914     SOC_PBMP_PORT_REMOVE(si->intp.disabled_bitmap, port);
    915 
    916     soc_katana2_pbmp_all_resync(unit) ;
    917     soc_esw_dport_init(unit);
    918 
    919     /* SAT initialization complete. */
    920     _sb2_sat_control[unit]->init = TRUE;
    921     return (BCM_E_NONE);
    922 }
    923 
    924 
    925 /*
    926  * Function:
    927  *     bcm_sb2_sat_detach
    928  * Purpose:
    929  *     Shut down SAT subsystem
    930  * Parameters:
    931  *     unit - (IN) BCM device number
    932  * Returns:
    933  *     BCM_E_XXX
    934  */
    935 int
    936 bcm_sb2_sat_detach(int unit)
    937 {
    938     _bcm_sat_control_t *satc;  /* Pointer to SAT control structure. */
    939     int rv = BCM_E_NONE;
    940 
    941     /* Get the device SAT module handle. */
    942     satc = _sb2_sat_control[unit];
    943 
    944     if (NULL == satc) {
    945         /* Module already uninitialized. */
    946         return (BCM_E_NONE);
    947     }
    948 
    949     if (NULL != satc->sat_lock) {
    950         _BCM_SAT_LOCK(satc);
    951     }
    952 
    953     /* Disable OLP handling on HG ports */
    954     rv = _bcm_sb2_sat_hg_olp_mode_set(unit, _BCM_SAT_DISABLE);
    955     if (BCM_FAILURE(rv)) {
    956         LOG_ERROR(BSL_LS_BCM_SAT, 
    957                   (BSL_META_U(unit,
    958                   "SAT(unit %d) Error:Disable OLP handling on HG ports %s.\n"),
    959                   unit, bcm_errmsg(rv)));
    960     }
    961 
    962     /* Clear Magic port used in OLP-XGS communication */
    963     rv = _bcm_sb2_sat_olp_magic_port_clear(unit); 
    964     if (BCM_FAILURE(rv)) {
    965         LOG_ERROR(BSL_LS_BCM_SAT, 
    966                   (BSL_META_U(unit,
    967         "SAT(unit %d) Error:Clear Magic port used in OLP-XGS communication %s.\n"),
    968                   unit, bcm_errmsg(rv)));
    969     }
    970 
    971     /* Disable OLP header add for SAT packet forwarded to CPU port */
    972    _BCM_SAT_CPU_OLP_HDR_SET(unit, _BCM_SAT_DISABLE);
    973 
    974 
    975 	/* Destroy all UP-MEP endpoints and free the resources. */
    976     rv = bcm_sb2_sat_endpoint_destroy_all(unit, BCM_SAT_ENDPOINT_UPMEP);
    977 
    978      if (BCM_FAILURE(rv)) {
    979         /* Endpoint destroy failed. */
    980         LOG_ERROR(BSL_LS_BCM_SAT, 
    981                   (BSL_META_U(unit,
    982                   "SAT(unit %d) Error:UP-MEP Endpoint destory  %s.\n"),
    983                   unit, bcm_errmsg(rv)));
    984     }
    985 
    986    	/* Destroy all Down-MEP endpoints and free the resources. */
    987     rv = _bcm_sb2_sat_endpoint_destroy_all(unit, BCM_SAT_ENDPOINT_DOWNMEP);
    988 
    989      if (BCM_FAILURE(rv)) {
    990         /* Endpoint destroy failed. */
    991         LOG_ERROR(BSL_LS_BCM_SAT, 
    992                   (BSL_META_U(unit,
    993                   "SAT(unit %d) Error:Down-MEP Endpoint destroy %s.\n"),
    994                   unit, bcm_errmsg(rv)));
    995     }
    996 
    997      /* Release the protection mutex. */
    998     _BCM_SAT_UNLOCK(satc);
    999 
   1000     /* Free SAT module allocated resources. */
   1001     _bcm_sb2_sat_control_free(unit, satc);
   1002 
   1003     return (BCM_E_NONE);
   1004 }
   1005 
   1006 #define KEY_PRINT 0 
   1007 
   1008 #if defined(KEY_PRINT)
   1009 /*
   1010  * Function:
   1011  *     _bcm_sat_hash_key_print
   1012  * Purpose:
   1013  *     Print the contents of a hash key buffer. 
   1014  * Parameters: 
   1015  *     unit      - (IN) BCM device number
   1016  *     hash_key - (IN) Pointer to hash key buffer.
   1017  * Returns:
   1018  *     None
   1019  */
   1020 STATIC void
   1021 _bcm_sat_hash_key_print(int unit,_bcm_sat_hash_key_t *hash_key)
   1022 {
   1023     int i;
   1024     LOG_CLI((BSL_META_U(unit, 
   1025                         "SAT HASH KEY:")));
   1026     for(i = 0; i < _SAT_HASH_KEY_SIZE; i++) {
   1027         LOG_CLI((BSL_META_U(unit,
   1028                             ":%u"), *(hash_key[i])));
   1029     }
   1030     LOG_CLI((BSL_META_U(unit, 
   1031                         "\n")));
   1032 }
   1033 #endif
   1034 
   1035 
   1036 /*
   1037  * Function:
   1038  *     _bcm_sb2_sat_ep_hash_key_construct
   1039  * Purpose:
   1040  *     Construct hash table key for a given endpoint information.
   1041  * Parameters:
   1042  *     unit    - (IN) BCM device number
   1043  *     satc    - (IN) Pointer to SAT control structure.
   1044  *     ep_info - (IN) Pointer to endpoint information structure.
   1045  *     key     - (IN/OUT) Pointer to hash key buffer.
   1046  * Returns:
   1047  *     None
   1048  */
   1049 STATIC void
   1050 _bcm_sb2_sat_ep_hash_key_construct(int unit,
   1051                                    _bcm_sat_control_t *satc,
   1052                                    bcm_sat_endpoint_info_t *ep_info,
   1053                                    _bcm_sat_hash_key_t *key)
   1054 {
   1055     uint8  *loc = *key;
   1056 
   1057     sal_memset(key, 0, sizeof(_bcm_sat_hash_key_t));
   1058 
   1059     if (NULL != ep_info) {
   1060 
   1061         if (ep_info->flags & BCM_SAT_ENDPOINT_MATCH_OUTER_VLAN) {
   1062              _BCM_SAT_KEY_PACK(loc, &ep_info->outer_vlan, 
   1063                                sizeof(ep_info->outer_vlan));
   1064         }
   1065 
   1066         if (ep_info->flags & BCM_SAT_ENDPOINT_MATCH_INNER_VLAN) {
   1067              _BCM_SAT_KEY_PACK(loc, &ep_info->inner_vlan, 
   1068                                 sizeof(ep_info->inner_vlan));		
   1069         }
   1070 		
   1071         _BCM_SAT_KEY_PACK(loc, &ep_info->dst_mac_address, 
   1072                           sizeof(ep_info->dst_mac_address));
   1073 
   1074         _BCM_SAT_KEY_PACK(loc, &ep_info->src_mac_address, 
   1075                           sizeof(ep_info->src_mac_address));
   1076 
   1077         _BCM_SAT_KEY_PACK(loc, &ep_info->src_gport, sizeof(ep_info->src_gport));
   1078 
   1079         _BCM_SAT_KEY_PACK(loc, &ep_info->ether_type, sizeof(ep_info->ether_type));
   1080 
   1081     }
   1082 
   1083     /* End address should not exceed size of _bcm_sat_hash_key_t. */
   1084     assert ((int) (loc - *key) <= sizeof(_bcm_sat_hash_key_t));
   1085 }
   1086 
   1087 /*
   1088  * Function:
   1089  *     _bcm_sb2_sat_control_get
   1090  * Purpose:
   1091  *     Lookup a SAT control config from a bcm device id.
   1092  * Parameters:
   1093  *     unit -  (IN)BCM unit number.
   1094  *     satc -  (OUT) SAT control structure.
   1095  * Retruns:
   1096  *     BCM_E_XXX
   1097  */
   1098 STATIC int
   1099 _bcm_sb2_sat_control_get(int unit, _bcm_sat_control_t **satc)
   1100 {
   1101     if (NULL == satc) {
   1102         return (BCM_E_PARAM);
   1103     }
   1104 
   1105     /* Ensure sat module is initialized. */
   1106     _BCM_SAT_IS_INIT(unit);
   1107 
   1108     *satc = _sb2_sat_control[unit];
   1109 
   1110     return (BCM_E_NONE);
   1111 }
   1112 
   1113 
   1114 /*
   1115  * Function:
   1116  *     _bcm_sb2_sat_endpoint_gport_resolve
   1117  * Purpose:
   1118  *     Resolve an endpoint GPORT value to GLP value.
   1119  * Parameters:
   1120  *     unit       - (IN) BCM device number
   1121  *     ep_info_p  - (IN/OUT) Pointer to endpoint information.
   1122  *     flags      - (IN) Flag indicates gport type source/dest to resolve. 
   1123  *     glp        - (IN/OUT) Pointer to generic logical port value.
   1124  *     trunk_id   - (IN/OUT) Pointer to trunk id
   1125  * Retruns:
   1126  *     BCM_E_XXX
   1127  */
   1128 STATIC int
   1129 _bcm_sb2_sat_endpoint_gport_resolve(int unit,
   1130                                     bcm_sat_endpoint_info_t *ep_info_p,
   1131                                     uint32 flags,
   1132                                     uint32 *glp,
   1133                                     bcm_trunk_t *trunk_id)
   1134 {
   1135     bcm_module_t       module_id;            /* Module ID           */
   1136     bcm_port_t         port_id;              /* Port ID.            */
   1137     bcm_gport_t        gport;                /* Endpoint source/dest gport */
   1138     int                local_id;             /* Hardware ID.        */
   1139     int                member_count = 0;     /* Trunk Member count. */
   1140     int                rv = BCM_E_NONE;      /* Return status.      */
   1141     uint8              glp_valid = 0;        /* Logical port valid. */
   1142     int                local_member_count = 0;
   1143     int                is_local = 0;
   1144 	
   1145     if(flags & _BCM_SAT_SRC_GPORT) {
   1146         gport = ep_info_p->src_gport;
   1147     }
   1148     else if(flags & _BCM_SAT_DEST_GPORT) {
   1149         gport = ep_info_p->dest_gport;
   1150     }
   1151     else {
   1152         return BCM_E_PARAM;
   1153     }
   1154 
   1155 
   1156     /* Get Trunk ID or (Modid + Port) value from Gport */
   1157     BCM_IF_ERROR_RETURN
   1158         (_bcm_esw_gport_resolve(unit, gport, &module_id,
   1159                                 &port_id, trunk_id, &local_id));
   1160 
   1161     /*
   1162      * If Gport is Trunk type, _bcm_esw_gport_resolve()
   1163      * sets trunk_id. Using Trunk ID, get Dst Modid and Port value.
   1164      */
   1165     if (BCM_GPORT_IS_TRUNK(gport)) {
   1166 
   1167         if (BCM_TRUNK_INVALID == *trunk_id)  {
   1168             /* Has to be a valid Trunk. */
   1169             return (BCM_E_PARAM);
   1170         }
   1171 
   1172         /* Construct Hw GLP value. */
   1173         _BCM_SB2_SAT_MOD_PORT_TO_GLP(unit, module_id, port_id, 1, 
   1174                                      *trunk_id, *glp);
   1175 
   1176         /* Get a member of the trunk belonging to this module */
   1177         if (BCM_SUCCESS(_bcm_esw_trunk_local_members_get(unit, *trunk_id, 1,
   1178                                         &port_id,
   1179                                         &local_member_count))) {
   1180         }
   1181 
   1182         /* Get count of ports in this trunk. */
   1183         BCM_IF_ERROR_RETURN
   1184             (bcm_esw_trunk_get(unit, *trunk_id, NULL, 0, NULL, &member_count));
   1185         if (0 == member_count) {
   1186             /* No members have been added to the trunk group yet */
   1187             return BCM_E_PARAM;
   1188         }
   1189 
   1190         /* Construct Hw GLP value. */
   1191         _BCM_SB2_SAT_MOD_PORT_TO_GLP(unit, module_id, port_id, 0, -1, *glp);
   1192 
   1193         glp_valid = 1;
   1194     }
   1195 
   1196     /*
   1197      * Application can resolve the trunk and pass the designated
   1198      * port as Gport value. Check if the Gport belongs to a trunk.
   1199      */
   1200     if ((BCM_TRUNK_INVALID == (*trunk_id))
   1201         && (BCM_GPORT_IS_MODPORT(gport)
   1202         || BCM_GPORT_IS_LOCAL(gport)
   1203         || BCM_GPORT_IS_SUBPORT_PORT(gport)
   1204         || BCM_GPORT_IS_SUBPORT_GROUP(gport))) {
   1205 
   1206         /* When Gport is ModPort. Subport or Port type, _bcm_esw_gport_resolve()
   1207          * returns Modid and Port value. Use these values to make the DGLP
   1208          * value.
   1209          */
   1210         _BCM_SB2_SAT_MOD_PORT_TO_GLP(unit, module_id, port_id, 0, -1, *glp);
   1211 		
   1212 
   1213         /* Use the Modid, Port value and determine if the port
   1214          * belongs to a Trunk.
   1215          */
   1216         rv = bcm_esw_trunk_find(unit, module_id, port_id, trunk_id);
   1217         if (BCM_SUCCESS(rv)) {
   1218             /*
   1219              * Port is member of a valid trunk.
   1220              * Now create the SGLP value from Trunk ID.
   1221              */
   1222             /* Get a member of the trunk belonging to this module */
   1223             if (BCM_SUCCESS(_bcm_esw_trunk_local_members_get(unit, *trunk_id, 1,
   1224                                         &port_id,
   1225                                         &local_member_count))) {
   1226 
   1227                 _BCM_SB2_SAT_MOD_PORT_TO_GLP(unit, module_id, port_id, 1, 
   1228                                              *trunk_id, *glp);
   1229             }
   1230         }
   1231         glp_valid = 1;
   1232     }
   1233     if (SOC_GPORT_IS_MIM_PORT(gport)) {
   1234         rv = _bcm_esw_modid_is_local(unit, module_id, &is_local);
   1235         if(BCM_SUCCESS(rv) && (is_local)) {  
   1236             _BCM_SB2_SAT_MOD_PORT_TO_GLP(unit, module_id, port_id, 0, 
   1237                                              -1, *glp);
   1238             glp_valid = 1;
   1239         }
   1240     } 
   1241 
   1242     /*
   1243      * At this point, glp should be valid.
   1244      * Gport types other than TRUNK, MODPORT or LOCAL are not valid.
   1245      */
   1246     if (0 == glp_valid) {
   1247         return (BCM_E_PORT);
   1248     }
   1249     return (BCM_E_NONE);
   1250 }
   1251 
   1252 /*
   1253  * Function:
   1254  *      _bcm_sb2_sat_endpoint_old_hash_key_get
   1255  * Purpose:
   1256  *      Get an SAT endpoint object old hash key
   1257  * Parameters:
   1258  *      unit - (IN) Unit number.
   1259  *      endpoint - (IN) The ID of the endpoint object to get
   1260  *      flags - (IN) Endpoint flags for type of endpoint to get
   1261  *      hash_key  - (OUT) Pointer to endpoint hash key value.
   1262  * Returns:
   1263  *      BCM_E_XXX
   1264  * Notes: Internal function this API assumes that caller has aquired SAT lock 
   1265  *        before invoking this function.
   1266  */
   1267 static int 
   1268 _bcm_sb2_sat_endpoint_old_hash_key_get(int unit, 
   1269                                        bcm_sat_endpoint_t endpoint,
   1270                                        uint32 flags,
   1271                                        _bcm_sat_hash_key_t *hash_key)
   1272 {
   1273     _bcm_sat_control_t    *satc;      /* Pointer to SAT control structure. */
   1274     _bcm_sat_hash_data_t  *h_data_p;  /* Pointer to endpoint data.         */
   1275     bcm_sat_endpoint_info_t endpoint_info;
   1276 
   1277     BCM_IF_ERROR_RETURN(_bcm_sb2_sat_control_get(unit, &satc));
   1278 
   1279 
   1280     if (flags & BCM_SAT_ENDPOINT_UPMEP) {
   1281          _BCM_SAT_MEP_INDEX_VALIDATE(satc->upsamp_ep_count,endpoint);
   1282 
   1283          /* Get the hash data pointer. */
   1284          h_data_p = &satc->upsamp_hash_data[endpoint];
   1285 	}
   1286 	else if (flags & BCM_SAT_ENDPOINT_DOWNMEP) {
   1287          _BCM_SAT_MEP_INDEX_VALIDATE(satc->downsamp_ep_count,endpoint);
   1288 
   1289          /* Get the hash data pointer. */
   1290          h_data_p = &satc->downsamp_hash_data[endpoint];
   1291 	}
   1292     else {
   1293         return BCM_E_PARAM;
   1294     }
   1295 
   1296     if (!h_data_p->in_use)
   1297     {
   1298         return BCM_E_NOT_FOUND;
   1299     }
   1300 
   1301     /* Initialize endpoint info structure. */
   1302     bcm_sat_endpoint_info_t_init(&endpoint_info);
   1303 
   1304     /* Set up endpoint information for key construction. */
   1305     endpoint_info.ep_id = h_data_p->ep_info.ep_id;
   1306     endpoint_info.outer_vlan = h_data_p->ep_info.outer_vlan;
   1307     endpoint_info.inner_vlan = h_data_p->ep_info.inner_vlan;
   1308     sal_memcpy(endpoint_info.dst_mac_address, 
   1309                h_data_p->ep_info.dst_mac_address,
   1310                sizeof(bcm_mac_t));
   1311     sal_memcpy(endpoint_info.src_mac_address, 
   1312                h_data_p->ep_info.src_mac_address,
   1313                sizeof(bcm_mac_t));
   1314     endpoint_info.ether_type = h_data_p->ep_info.ether_type;
   1315     endpoint_info.flags = h_data_p->ep_info.flags;
   1316     endpoint_info.src_gport = h_data_p->ep_info.src_gport;
   1317 
   1318     endpoint_info.action_flags = h_data_p->ep_info.action_flags;
   1319     endpoint_info.pkt_pri = h_data_p->ep_info.pkt_pri;
   1320     endpoint_info.dest_gport = h_data_p->ep_info.dest_gport;
   1321     endpoint_info.timestamp_format = h_data_p->ep_info.timestamp_format;
   1322     endpoint_info.session_id = h_data_p->ep_info.session_id;
   1323 
   1324     /* Calculate the hash key for given enpoint input parameters. */
   1325     _bcm_sb2_sat_ep_hash_key_construct(unit, satc, &endpoint_info, hash_key);
   1326 
   1327     return BCM_E_NONE;
   1328 }
   1329 
   1330 /*
   1331  * Function:
   1332  *     _bcm_sb2_sat_endpoint_params_validate
   1333  * Purpose:
   1334  *     Validate an endpoint parameters.
   1335  * Parameters:
   1336  *     unit      - (IN) BCM device number
   1337  *     satc      - (IN) Pointer to SAT control structure.
   1338  *     hash_key  - (IN) Pointer to endpoint hash key value.
   1339  *     ep_info_p - (IN) Pointer to endpoint information.
   1340  * Retruns:
   1341  *     BCM_E_XXX
   1342  */
   1343 STATIC int
   1344 _bcm_sb2_sat_endpoint_params_validate(int unit,
   1345                                       _bcm_sat_control_t *satc,
   1346                                       _bcm_sat_hash_key_t *hash_key,
   1347                                       bcm_sat_endpoint_info_t *ep_info_p)
   1348 {
   1349     int                     rv = BCM_E_NONE;  /* Operation return status. */ 
   1350     _bcm_sat_hash_data_t    h_stored_data;
   1351     shr_htb_hash_table_t    samp_htbl = NULL; /* SAT endpoint hash table. */
   1352     _bcm_sat_hash_key_t     old_hash_key;     /* Hash Key buffer.         */
   1353 
   1354     LOG_DEBUG(BSL_LS_BCM_SAT, 
   1355               (BSL_META_U(unit,
   1356                  "SAT(unit %d) Info: _bcm_sb2_sat_endpoint_params_validate.\n"),
   1357                  unit));
   1358 
   1359     /* BCM_SAT_ENDPOINT_DOWNMEP and BCM_SAT_ENDPOINT_UPMEP flags are
   1360      * mutually exclusive, an endpoint can be either UP-MEP or Down-MEP 
   1361      * only.
   1362      */
   1363     if ((ep_info_p->flags & BCM_SAT_ENDPOINT_DOWNMEP) &&
   1364        (ep_info_p->flags & BCM_SAT_ENDPOINT_UPMEP)) {
   1365         return (BCM_E_PARAM);
   1366     }
   1367 
   1368     /* Check for invalid flags (use last flag value for check) */
   1369     if ( ep_info_p->flags >= (BCM_SAT_ENDPOINT_MATCH_OUTER_VLAN << 1)){
   1370         return (BCM_E_PARAM);
   1371     }
   1372 
   1373     /* Check for invalid action flags (use last action flag for check) */
   1374     if ( ep_info_p->action_flags >= (BCM_SAT_ACTION_SAMPLE_TIMESTAMP << 1)){
   1375         return (BCM_E_PARAM);
   1376     }
   1377 
   1378     /* Same SAMAC and DAMAC are not valid */
   1379     if (MAC_ADDR_EQUAL(ep_info_p->dst_mac_address, 
   1380                        ep_info_p->src_mac_address)){
   1381         return (BCM_E_PARAM);
   1382     }
   1383 
   1384     /* Check for invalid timestamp field */
   1385     if ( ep_info_p->timestamp_format > bcmSATTimestampFormatNTP ) {
   1386         return (BCM_E_PARAM);
   1387     }
   1388 
   1389     /* For replace operation, endpoint ID is required. */
   1390     if ((ep_info_p->flags & BCM_SAT_ENDPOINT_REPLACE)
   1391         && !(ep_info_p->flags & BCM_SAT_ENDPOINT_WITH_ID)) {
   1392         return (BCM_E_PARAM);
   1393     }
   1394 
   1395     /* Validate inner VLAN */
   1396     /* coverity[result_independent_of_operands] */
   1397     if (ep_info_p->flags & BCM_SAT_ENDPOINT_MATCH_INNER_VLAN) {
   1398         VLAN_CHK_ID(unit, (ep_info_p->inner_vlan & _BCM_SAT_VLAN_MASK));
   1399 
   1400         /* Validate inner VLAN priority */
   1401 	/* coverity[result_independent_of_operands] */
   1402         VLAN_CHK_PRIO(unit,
   1403          _BCM_SAT_VLAN_PRI_GET(ep_info_p->inner_vlan, _BCM_SAT_VLAN_PRIO_MASK));
   1404     }
   1405 
   1406     /* Validate outer VLAN */
   1407     /* coverity[result_independent_of_operands] */
   1408     if (ep_info_p->flags & BCM_SAT_ENDPOINT_MATCH_OUTER_VLAN) {
   1409         VLAN_CHK_ID(unit, (ep_info_p->outer_vlan & _BCM_SAT_VLAN_MASK));
   1410 
   1411         /* Validate outer VLAN priority */
   1412 	/* coverity[result_independent_of_operands] */
   1413         VLAN_CHK_PRIO(unit,
   1414          _BCM_SAT_VLAN_PRI_GET(ep_info_p->outer_vlan, _BCM_SAT_VLAN_PRIO_MASK));
   1415     }
   1416 
   1417     /* Store samp_htbl appropriately for UP-MEP endpoint. */
   1418     if(ep_info_p->flags & BCM_SAT_ENDPOINT_UPMEP ){
   1419          samp_htbl = satc->upsamp_htbl;
   1420     }
   1421 
   1422     /* Store samp_htbl appropriately for Down-MEP endpoint. */
   1423     if(ep_info_p->flags & BCM_SAT_ENDPOINT_DOWNMEP ){
   1424          samp_htbl = satc->downsamp_htbl;
   1425     }
   1426 
   1427     if (samp_htbl == NULL) {
   1428         return (BCM_E_INTERNAL);
   1429     }
   1430 
   1431     if (ep_info_p->flags & BCM_SAT_ENDPOINT_WITH_ID) {
   1432 
   1433         /* Validate UP-MEP endpoint index value. */
   1434         if(ep_info_p->flags & BCM_SAT_ENDPOINT_UPMEP ){
   1435            _BCM_SAT_MEP_INDEX_VALIDATE(satc->upsamp_ep_count,
   1436                                        ep_info_p->ep_id); 
   1437         }
   1438 
   1439         /* Validate DOWN-MEP endpoint index value. */
   1440         else if(ep_info_p->flags & BCM_SAT_ENDPOINT_DOWNMEP ){
   1441             _BCM_SAT_MEP_INDEX_VALIDATE(satc->downsamp_ep_count,
   1442                                         ep_info_p->ep_id);
   1443         }
   1444 
   1445         /* Modify the hash key */
   1446         rv = _bcm_sb2_sat_endpoint_old_hash_key_get(unit, 
   1447                                                     ep_info_p->ep_id,
   1448                                                     ep_info_p->flags,
   1449                                                     &old_hash_key);
   1450         if (rv != BCM_E_NONE) {
   1451             sal_memcpy(&old_hash_key, hash_key, sizeof(_bcm_sat_hash_key_t));
   1452         }
   1453     }
   1454     else {
   1455         sal_memcpy(&old_hash_key, hash_key, sizeof(_bcm_sat_hash_key_t));
   1456     }
   1457 
   1458 #if defined(KEY_PRINT)
   1459     /* coverity[overrun-buffer-val] */
   1460     _bcm_sat_hash_key_print(unit, &old_hash_key);
   1461 #endif
   1462 
   1463     /*
   1464      * Lookup using hash key value.
   1465      * Last param value '0' specifies keep the match entry.
   1466      * Value '1' would mean remove the entry from the table.
   1467      * Mtched Params:
   1468      *      .
   1469      */
   1470      rv = shr_htb_find(samp_htbl, old_hash_key,
   1471                   (shr_htb_data_t *)&h_stored_data, 0);
   1472 
   1473     if (BCM_SUCCESS(rv)
   1474         && !(ep_info_p->flags & BCM_SAT_ENDPOINT_REPLACE)) {
   1475 
   1476         LOG_ERROR(BSL_LS_BCM_SAT, 
   1477                   (BSL_META_U(unit,
   1478                   "SAT(unit %d) Error: Endpoint ID=%d in use %s.\n"),
   1479                   unit, ep_info_p->ep_id, bcm_errmsg(BCM_E_EXISTS)));
   1480 
   1481         /* Endpoint must not be in use expect for Replace operation. */
   1482         return (BCM_E_EXISTS);
   1483 
   1484     } else {
   1485 
   1486         LOG_DEBUG(BSL_LS_BCM_SAT, 
   1487                   (BSL_META_U(unit,
   1488                      "SAT(unit %d) Info: Endpoint ID=%d Available. %s.\n"),
   1489                      unit, ep_info_p->ep_id, bcm_errmsg(rv)));
   1490 
   1491     }
   1492 
   1493     return (BCM_E_NONE);
   1494 }
   1495 
   1496 
   1497 /*
   1498  * Function:
   1499  *     _bcm_sb2_sat_endpoint_cleanup
   1500  * Purpose:
   1501  *     Free all the counters and the indexes allocated on endpoint create
   1502  *     failure  
   1503  * Parameters:
   1504  *     unit - (IN) BCM device number
   1505  *     upmep- (IN) UpMep/DownMep
   1506  *     hash_key (IN)
   1507  *     hash_data (IN) Pointer to endpoint hash data
   1508  * Retruns:
   1509  *     BCM_E_XXX
   1510  */
   1511 void
   1512 _bcm_sb2_sat_endpoint_cleanup(int unit, int upmep, 
   1513                               _bcm_sat_hash_key_t  hash_key,
   1514                               _bcm_sat_hash_data_t *hash_data)
   1515 {
   1516     _bcm_sat_control_t   *satc;            /* Pointer to control structure.  */
   1517     int                  rv = BCM_E_NONE;
   1518     shr_htb_hash_table_t    samp_htbl;     /* SAT endpoint hash table.       */
   1519 
   1520     rv = _bcm_sb2_sat_control_get(unit, &satc);
   1521     if (BCM_FAILURE(rv)) {
   1522         return;
   1523     }
   1524 
   1525     if (upmep) {
   1526         rv = _bcm_sb2_sat_endpoint_hw_delete(unit, hash_data);
   1527         if (BCM_FAILURE(rv)) {
   1528             LOG_DEBUG(BSL_LS_BCM_SAT, 
   1529                       (BSL_META_U(unit,
   1530                          "SAT(unit %d) Error: UP-MEP clear failed EP=%d %s.\n"),
   1531                          unit, hash_data->ep_info.ep_id, bcm_errmsg(rv)));
   1532         }
   1533         samp_htbl = satc->upsamp_htbl;
   1534 	    shr_idxres_list_free(satc->upsamp_mep_pool, hash_data->ep_info.ep_id);
   1535     } else {
   1536         rv = _bcm_sb2_sat_endpoint_hw_delete(unit, hash_data);
   1537         if (BCM_FAILURE(rv)) {
   1538             LOG_DEBUG(BSL_LS_BCM_SAT, 
   1539                       (BSL_META_U(unit,
   1540                          "SAT(unit %d) Error: Down-MEP clear failed EP=%d %s.\n"),
   1541                          unit, hash_data->ep_info.ep_id, bcm_errmsg(rv)));
   1542         }
   1543         samp_htbl = satc->downsamp_htbl;
   1544 	    shr_idxres_list_free(satc->downsamp_mep_pool, hash_data->ep_info.ep_id);
   1545     }
   1546  
   1547     /* Return entry to hash data entry to free pool. */
   1548     shr_htb_find(samp_htbl, hash_key, (shr_htb_data_t *)hash_data, 1);
   1549 
   1550     /* Clear contents of hash data element. */
   1551     _BCM_SAT_HASH_DATA_CLEAR(hash_data);
   1552 }
   1553 
   1554 
   1555 /*
   1556  * Function:
   1557  *      bcm_sb2_sat_endpoint_get
   1558  * Purpose:
   1559  *      Get an SAT endpoint object
   1560  * Parameters:
   1561  *      unit - (IN) Unit number.
   1562  *      endpoint - (IN) The ID of the endpoint object to get
   1563  *      flags - (IN) Endpoint flags for type of endpoint to get
   1564  *      endpoint_info - (OUT) Pointer to an SAT endpoint structure to receive the data
   1565  * Returns:
   1566  *      BCM_E_XXX
   1567  * Notes:
   1568  */
   1569 int 
   1570 bcm_sb2_sat_endpoint_get(int unit, 
   1571                          bcm_sat_endpoint_t endpoint,
   1572                          uint32 flags,
   1573                          bcm_sat_endpoint_info_t *endpoint_info)
   1574 {
   1575     _bcm_sat_control_t    *satc;      /* Pointer to SAT control structure. */
   1576     _bcm_sat_hash_data_t  *h_data_p;  /* Pointer to endpoint data.         */
   1577 
   1578     BCM_IF_ERROR_RETURN(_bcm_sb2_sat_control_get(unit, &satc));
   1579 
   1580 
   1581     if (flags & BCM_SAT_ENDPOINT_UPMEP) {
   1582          _BCM_SAT_MEP_INDEX_VALIDATE(satc->upsamp_ep_count, endpoint);
   1583 
   1584          /* Get the hash data pointer. */
   1585          h_data_p = &satc->upsamp_hash_data[endpoint];
   1586 	}
   1587 	else {
   1588          _BCM_SAT_MEP_INDEX_VALIDATE(satc->downsamp_ep_count, endpoint);
   1589 
   1590          /* Get the hash data pointer. */
   1591          h_data_p = &satc->downsamp_hash_data[endpoint];
   1592 	}
   1593 
   1594     _BCM_SAT_LOCK(satc);
   1595 
   1596     if (!h_data_p->in_use)
   1597     {
   1598         if (NULL != satc->sat_lock) {
   1599             _BCM_SAT_UNLOCK(satc);
   1600         }
   1601         return BCM_E_NOT_FOUND;
   1602     }
   1603 
   1604     /* Initialize endpoint info structure. */
   1605     bcm_sat_endpoint_info_t_init(endpoint_info);
   1606 
   1607     /* Set up endpoint information for key construction. */
   1608     endpoint_info->ep_id = h_data_p->ep_info.ep_id;
   1609     endpoint_info->outer_vlan = h_data_p->ep_info.outer_vlan;
   1610     endpoint_info->inner_vlan = h_data_p->ep_info.inner_vlan;
   1611     sal_memcpy(endpoint_info->dst_mac_address, 
   1612                h_data_p->ep_info.dst_mac_address,
   1613                sizeof(bcm_mac_t));
   1614     sal_memcpy(endpoint_info->src_mac_address, 
   1615                h_data_p->ep_info.src_mac_address,
   1616                sizeof(bcm_mac_t));
   1617     endpoint_info->ether_type = h_data_p->ep_info.ether_type;
   1618     endpoint_info->flags = h_data_p->ep_info.flags;
   1619     endpoint_info->src_gport = h_data_p->ep_info.src_gport;
   1620 
   1621     endpoint_info->action_flags = h_data_p->ep_info.action_flags;
   1622     endpoint_info->pkt_pri = h_data_p->ep_info.pkt_pri;
   1623     endpoint_info->dest_gport = h_data_p->ep_info.dest_gport;
   1624     endpoint_info->timestamp_format = h_data_p->ep_info.timestamp_format;
   1625     endpoint_info->session_id = h_data_p->ep_info.session_id;
   1626 
   1627     _BCM_SAT_UNLOCK(satc);
   1628 
   1629     return BCM_E_NONE;
   1630 }
   1631 
   1632 
   1633 /*
   1634  * Function:
   1635  *     _bcm_sb2_sat_endpoint_destroy
   1636  * Purpose:
   1637  *     Delete an endpoint and free all its allocated resources.
   1638  * Parameters:
   1639  *     unit   - (IN) BCM device number
   1640  *     ep_id  - (IN) Endpoint ID value.
   1641  *     flags  - (IN) Endpoint flags.
   1642  * Retruns:
   1643  *     BCM_E_XXX
   1644  */
   1645 STATIC int
   1646 _bcm_sb2_sat_endpoint_destroy(int unit,
   1647                               bcm_sat_endpoint_t ep_id, 
   1648                               unsigned int flags)
   1649 {
   1650     _bcm_sat_control_t      *satc;      /* Pointer to SAT control structure. */
   1651     _bcm_sat_hash_data_t    *h_data_p;  /* Pointer to endpoint data.         */
   1652     _bcm_sat_hash_key_t     hash_key;   /* Hash key buffer for lookup.       */
   1653     bcm_sat_endpoint_info_t ep_info;    /* Endpoint information.             */
   1654     shr_idxres_list_handle_t  mep_pool; /* SAT MEP index pool                */
   1655     shr_htb_hash_table_t    samp_htbl;  /* SAT endpoint hash table.          */
   1656     int                     rv;         /* Operation return status.          */
   1657 
   1658     /* Lock already taken by the calling routine. */
   1659     BCM_IF_ERROR_RETURN(_bcm_sb2_sat_control_get(unit, &satc));
   1660 
   1661     if (flags & BCM_SAT_ENDPOINT_UPMEP) {
   1662 
   1663 	     mep_pool = satc->upsamp_mep_pool;
   1664          samp_htbl = satc->upsamp_htbl;
   1665 
   1666          /* Get the hash data pointer. */
   1667          h_data_p = &satc->upsamp_hash_data[ep_id];
   1668 
   1669          if(h_data_p->in_use != 1) {
   1670              return BCM_E_NOT_FOUND;
   1671          }
   1672 
   1673          /* Delete entry from hardware */
   1674          rv = _bcm_sb2_sat_endpoint_hw_delete(unit, h_data_p);
   1675          if (BCM_FAILURE(rv)) {
   1676              LOG_DEBUG(BSL_LS_BCM_SAT, 
   1677                        (BSL_META_U(unit,
   1678                           "SAT(unit %d) Error: UP-MEP clear failed EP=%d %s.\n"),
   1679                           unit, h_data_p->ep_info.ep_id, bcm_errmsg(rv)));
   1680              return (rv);
   1681          }
   1682 	}
   1683 	else if (flags & BCM_SAT_ENDPOINT_DOWNMEP) {
   1684 	     mep_pool = satc->downsamp_mep_pool;
   1685          samp_htbl = satc->downsamp_htbl;
   1686 
   1687          /* Get the hash data pointer. */
   1688          h_data_p = &satc->downsamp_hash_data[ep_id];
   1689 
   1690          if(h_data_p->in_use != 1) {
   1691              return BCM_E_NOT_FOUND;
   1692          }
   1693 
   1694          /* Delete entry from hardware */
   1695          rv = _bcm_sb2_sat_endpoint_hw_delete(unit, h_data_p);
   1696          if (BCM_FAILURE(rv)) {
   1697              LOG_DEBUG(BSL_LS_BCM_SAT, 
   1698                        (BSL_META_U(unit,
   1699                           "SAT(unit %d) Error: Down-MEP clear failed EP=%d %s.\n"),
   1700                           unit, h_data_p->ep_info.ep_id, bcm_errmsg(rv)));
   1701              return (rv);
   1702          }
   1703 	}
   1704     else  {
   1705          return BCM_E_PARAM;
   1706     }
   1707 
   1708     /* Check endpoint status. */
   1709     rv = shr_idxres_list_elem_state(mep_pool, ep_id);
   1710     if ((BCM_E_EXISTS != rv)) {
   1711         /* Endpoint not in use. */
   1712         LOG_ERROR(BSL_LS_BCM_SAT, 
   1713                   (BSL_META_U(unit,
   1714                   "SAT(unit %d) Error: Endpoint EP=%d %s.\n"),
   1715                   unit, ep_id, bcm_errmsg(rv)));
   1716         return (rv);
   1717     }
   1718 
   1719     /* Initialize endpoint info structure. */
   1720     bcm_sat_endpoint_info_t_init(&ep_info);
   1721 
   1722     /* Set up endpoint information for key construction. */
   1723     ep_info.ep_id = h_data_p->ep_info.ep_id;
   1724     ep_info.outer_vlan = h_data_p->ep_info.outer_vlan;
   1725     ep_info.inner_vlan = h_data_p->ep_info.inner_vlan;
   1726     sal_memcpy(ep_info.dst_mac_address, h_data_p->ep_info.dst_mac_address,
   1727                sizeof(bcm_mac_t));
   1728     sal_memcpy(ep_info.src_mac_address, h_data_p->ep_info.src_mac_address,
   1729                sizeof(bcm_mac_t));
   1730     ep_info.ether_type = h_data_p->ep_info.ether_type;
   1731     ep_info.flags = h_data_p->ep_info.flags;
   1732     ep_info.src_gport = h_data_p->ep_info.src_gport;
   1733 
   1734     /* Construct hash key for lookup + delete operation. */
   1735     _bcm_sb2_sat_ep_hash_key_construct(unit, satc, &ep_info, &hash_key);
   1736 
   1737     /* Remove entry from hash table. */
   1738     BCM_IF_ERROR_RETURN(shr_htb_find(samp_htbl, hash_key,
   1739                                      (shr_htb_data_t *)h_data_p,
   1740                                      1));
   1741 
   1742     /* Return ID back to free MEP ID pool.*/
   1743     BCM_IF_ERROR_RETURN(shr_idxres_list_free(mep_pool, ep_id));
   1744 
   1745     /* Clear the hash data memory previously occupied by this endpoint. */
   1746     _BCM_SAT_HASH_DATA_CLEAR(h_data_p);
   1747 
   1748     return (BCM_E_NONE);
   1749 }
   1750 
   1751 
   1752 /*
   1753  * Function:
   1754  *     bcm_sb2_sat_endpoint_create
   1755  * Purpose:
   1756  *     Create or replace an SAT endpoint object
   1757  * Parameters:
   1758  *     unit          - (IN) BCM device number
   1759  *     endpoint_info - (IN/OUT) Pointer to endpoint information buffer.
   1760  * Returns:
   1761  *      BCM_E_XXX
   1762  */
   1763 int
   1764 bcm_sb2_sat_endpoint_create(int unit, bcm_sat_endpoint_info_t *endpoint_info)
   1765 {
   1766     _bcm_sat_hash_data_t *hash_data = NULL; /* Endpoint hash data pointer.  */
   1767     _bcm_sat_hash_key_t  hash_key;          /* Hash Key buffer.             */
   1768     int                  ep_req_index;      /* Requested endpoint index.    */
   1769     int                  rv;                /* Operation return status.     */
   1770     _bcm_sat_control_t   *satc;             /* Pointer to SAT control       */
   1771                                             /* structure.  
   1772 											*/
   1773     shr_idxres_list_handle_t  mep_pool;     /* SAT MEP index pool */
   1774     shr_htb_hash_table_t      samp_htbl;    /* SAT endpoint hash table.      */
   1775     uint32               sglp = 0;          /* Source global logical port.  */
   1776     uint32               dglp = 0;          /* Dest global logical port.    */
   1777     bcm_trunk_t          trunk_id = BCM_TRUNK_INVALID;
   1778     int                  up_mep = 0;        /* Endpoint is an upMep         */
   1779 
   1780     /* Validate input parameter. */
   1781     if (NULL == endpoint_info) {
   1782         return (BCM_E_PARAM);
   1783     }
   1784 
   1785     LOG_DEBUG(BSL_LS_BCM_SAT, 
   1786               (BSL_META_U(unit,
   1787             "SAT(unit %d) Info: bcm_sb2_sat_endpoint_create Endpoint ID=%d.\n"),
   1788                  unit, endpoint_info->ep_id));
   1789 
   1790     /* Get SAT Control Structure. */
   1791     BCM_IF_ERROR_RETURN(_bcm_sb2_sat_control_get(unit, &satc));
   1792 
   1793     _BCM_SAT_LOCK(satc);
   1794 
   1795 
   1796    /* Calculate the hash key for given enpoint input parameters. */
   1797     _bcm_sb2_sat_ep_hash_key_construct(unit, satc, endpoint_info, &hash_key);
   1798 
   1799 #if defined(KEY_PRINT)
   1800     /* coverity[overrun-buffer-val] */
   1801     _bcm_sat_hash_key_print(unit, &hash_key);
   1802 #endif
   1803 
   1804     /* Validate endpoint input parameters. */
   1805     rv = _bcm_sb2_sat_endpoint_params_validate(unit, satc, &hash_key,
   1806                                                endpoint_info);
   1807     if (BCM_FAILURE(rv)) {
   1808         LOG_ERROR(BSL_LS_BCM_SAT, 
   1809                   (BSL_META_U(unit,
   1810                   "SAT(unit %d) Error: (EP=%d) - %s.\n"),
   1811                   unit, endpoint_info->ep_id, bcm_errmsg(rv)));
   1812         _BCM_SAT_UNLOCK(satc);
   1813         return (rv);
   1814     }
   1815 
   1816 
   1817     /* Resolve given endpoint gport value to Source GLP value. */
   1818     rv = _bcm_sb2_sat_endpoint_gport_resolve(unit, endpoint_info,
   1819                                              _BCM_SAT_SRC_GPORT, 
   1820                                              &sglp, &trunk_id);
   1821 
   1822     if (BCM_FAILURE(rv)) {
   1823         LOG_ERROR(BSL_LS_BCM_SAT, 
   1824                   (BSL_META_U(unit,
   1825                   "SAT(unit %d) Error: Source Gport resolve (EP=%d) - %s.\n"),
   1826                   unit, endpoint_info->ep_id, bcm_errmsg(rv)));
   1827         _BCM_SAT_UNLOCK(satc);
   1828         return (rv);
   1829     }
   1830 
   1831     if( endpoint_info->action_flags & BCM_SAT_ACTION_FWD_ACTION_REDIRECT) {
   1832         /* Resolve given endpoint gport value to Dest GLP value. */
   1833         rv = _bcm_sb2_sat_endpoint_gport_resolve(unit, endpoint_info, 
   1834                 _BCM_SAT_DEST_GPORT,
   1835                 &dglp, &trunk_id);
   1836 
   1837         if (BCM_FAILURE(rv)) {
   1838             LOG_ERROR(BSL_LS_BCM_SAT, 
   1839                     (BSL_META_U(unit,
   1840                                 "SAT(unit %d) Error: Dest Gport resolve (EP=%d) - %s.\n"),
   1841                      unit, endpoint_info->ep_id, bcm_errmsg(rv)));
   1842             _BCM_SAT_UNLOCK(satc);
   1843             return (rv);
   1844         }
   1845     }
   1846     /* Replace an existing endpoint. */
   1847     if (endpoint_info->flags & BCM_SAT_ENDPOINT_REPLACE) {
   1848         /*
   1849          * For replace operation, first delete the existing endpoint
   1850          * and recreate a new endpoint with new parameters.
   1851          */
   1852         rv = _bcm_sb2_sat_endpoint_destroy(unit, endpoint_info->ep_id, 
   1853                                            endpoint_info->flags);
   1854         if (BCM_FAILURE(rv)) {
   1855             LOG_ERROR(BSL_LS_BCM_SAT, 
   1856                       (BSL_META_U(unit,
   1857                       "SAT(unit %d) Error: Endpoint destroy (EP=%d) - %s.\n"),
   1858                       unit, endpoint_info->ep_id, bcm_errmsg(rv)));
   1859             _BCM_SAT_UNLOCK(satc);
   1860             return (rv);
   1861         }
   1862     }
   1863 
   1864 	/* Get appropriate index pool handle for the MEP */
   1865 	if (endpoint_info->flags & BCM_SAT_ENDPOINT_UPMEP) {
   1866 	     mep_pool = satc->upsamp_mep_pool;
   1867          up_mep = 1;
   1868 	}
   1869 	else  {
   1870 	     mep_pool = satc->downsamp_mep_pool;
   1871          up_mep = 0;
   1872 	}
   1873 	
   1874     /* Create a new endpoint with the requested ID. */
   1875     if (endpoint_info->flags & BCM_SAT_ENDPOINT_WITH_ID) {
   1876         ep_req_index = endpoint_info->ep_id;
   1877         rv = shr_idxres_list_reserve(mep_pool, ep_req_index,
   1878                                      ep_req_index);
   1879         if (BCM_FAILURE(rv)) {
   1880             LOG_ERROR(BSL_LS_BCM_SAT, 
   1881                       (BSL_META_U(unit,
   1882                 "SAT(unit %d) Error: Endpoint (EP=%d) reserve failed - %s.\n"),
   1883                       unit, endpoint_info->ep_id, bcm_errmsg(rv)));
   1884             _BCM_SAT_UNLOCK(satc);
   1885             return ((rv == BCM_E_RESOURCE) ? BCM_E_EXISTS : rv);
   1886         }
   1887     } else {
   1888         /* Allocate the next available endpoint index. */
   1889         rv = shr_idxres_list_alloc(mep_pool,
   1890                                    (shr_idxres_element_t *)&ep_req_index);
   1891         if (BCM_FAILURE(rv)) {
   1892             LOG_ERROR(BSL_LS_BCM_SAT, 
   1893                       (BSL_META_U(unit,
   1894                 "SAT(unit %d) Error: Endpoint (EP=%d) alloc failed - %s.\n"),
   1895                       unit, endpoint_info->ep_id, bcm_errmsg(rv)));
   1896             _BCM_SAT_UNLOCK(satc);
   1897             return (rv);
   1898         }
   1899         /* Set the allocated endpoint id value. */
   1900         endpoint_info->ep_id =  ep_req_index;
   1901     }
   1902 	
   1903     /* Get appropriate hash data pool handle for the MEP */
   1904 	if (up_mep) {
   1905 	     /* Get the hash data pointer where the data is to be stored. */
   1906          hash_data = &satc->upsamp_hash_data[ep_req_index];
   1907          samp_htbl = satc->upsamp_htbl;
   1908 	}
   1909 	else  {
   1910 	     /* Get the hash data pointer where the data is to be stored. */
   1911          hash_data = &satc->downsamp_hash_data[ep_req_index];
   1912          samp_htbl = satc->downsamp_htbl;
   1913 	}
   1914 
   1915     /* Clear the hash data element contents before storing the values. */
   1916     _BCM_SAT_HASH_DATA_CLEAR(hash_data);
   1917     hash_data->in_use = 1;
   1918     hash_data->ep_info.ep_id = endpoint_info->ep_id;
   1919     if (endpoint_info->flags & BCM_SAT_ENDPOINT_MATCH_OUTER_VLAN) {
   1920         hash_data->ep_info.outer_vlan = endpoint_info->outer_vlan;
   1921     }
   1922     if (endpoint_info->flags & BCM_SAT_ENDPOINT_MATCH_INNER_VLAN) {
   1923         hash_data->ep_info.inner_vlan = endpoint_info->inner_vlan;
   1924     }
   1925     sal_memcpy(hash_data->ep_info.dst_mac_address, 
   1926                endpoint_info->dst_mac_address,
   1927                sizeof(bcm_mac_t));
   1928     sal_memcpy(hash_data->ep_info.src_mac_address, 
   1929                endpoint_info->src_mac_address,
   1930                sizeof(bcm_mac_t));
   1931     hash_data->ep_info.src_gport = endpoint_info->src_gport;
   1932     hash_data->sglp   = (sglp & 0xFFFFFFFF);
   1933     hash_data->ep_info.ether_type = endpoint_info->ether_type;
   1934     hash_data->ep_info.flags = endpoint_info->flags;
   1935 
   1936 
   1937     /* TCAM data */
   1938     hash_data->ep_info.action_flags = endpoint_info->action_flags;
   1939     hash_data->ep_info.dest_gport = endpoint_info->dest_gport;
   1940     hash_data->dglp   = (dglp & 0xFFFFFFFF);
   1941     hash_data->ep_info.pkt_pri = endpoint_info->pkt_pri;
   1942     hash_data->ep_info.timestamp_format = endpoint_info->timestamp_format;
   1943     hash_data->ep_info.session_id = endpoint_info->session_id;
   1944 
   1945     /* Insert entry into hash table */
   1946     rv = shr_htb_insert(samp_htbl, hash_key, hash_data);
   1947     if (BCM_FAILURE(rv)) {
   1948         LOG_ERROR(BSL_LS_BCM_SAT, 
   1949                   (BSL_META_U(unit,
   1950                   "SAT(unit %d) Error: Hash table insert failed EP=%d %s.\n"),
   1951                   unit, endpoint_info->ep_id, bcm_errmsg(rv)));
   1952         _bcm_sb2_sat_endpoint_cleanup(unit, up_mep, hash_key, hash_data);
   1953         _BCM_SAT_UNLOCK(satc);
   1954         return (rv);
   1955     }
   1956     
   1957 	/* Configure endpoint info to hardware. */
   1958     rv = _bcm_sb2_sat_mep_hw_set(unit, endpoint_info, sglp, dglp);
   1959     if (BCM_FAILURE(rv)) {
   1960         LOG_DEBUG(BSL_LS_BCM_SAT, 
   1961                 (BSL_META_U(unit,
   1962                             "SAT(unit %d) Error: %s hw set failed EP=%d %s.\n"),
   1963                  unit, (up_mep ? "UP-MEP" : "Down-MEP"), endpoint_info->ep_id, bcm_errmsg(rv)));
   1964         _bcm_sb2_sat_endpoint_cleanup(unit, up_mep, hash_key, hash_data);
   1965         _BCM_SAT_UNLOCK(satc);
   1966         return (rv);
   1967     }
   1968 
   1969     _BCM_SAT_UNLOCK(satc);
   1970     return (BCM_E_NONE);
   1971 }
   1972 
   1973 
   1974 /*
   1975  * Function:
   1976  *     bcm_sb2_sat_endpoint_destroy
   1977  * Purpose:
   1978  *     Destroy an SAT endpoint object
   1979  * Parameters:
   1980  *     unit     - (IN) BCM device number
   1981  *     endpoint - (IN) Endpoint ID to destroy.
   1982  *     flags    - (IN) Endpoint flags.
   1983  * result =s:
   1984  *     BCM_E_XXX
   1985  */
   1986 int
   1987 bcm_sb2_sat_endpoint_destroy(int unit, 
   1988                              bcm_sat_endpoint_t endpoint, 
   1989                              uint32 flags)
   1990 {
   1991     _bcm_sat_control_t *satc; /* Pointer to SAT control structure. */
   1992     int rv = BCM_E_NONE;      /* Operation return status.          */
   1993 
   1994     BCM_IF_ERROR_RETURN(_bcm_sb2_sat_control_get(unit, &satc));
   1995 
   1996     _BCM_SAT_LOCK(satc);
   1997 
   1998     rv = _bcm_sb2_sat_endpoint_destroy(unit, endpoint, flags);
   1999     if (BCM_FAILURE(rv)) {
   2000         LOG_ERROR(BSL_LS_BCM_SAT, 
   2001                   (BSL_META_U(unit,
   2002                   "SAT(unit %d) Error: Endpoint destroy EP=%d failed %s.\n"),
   2003                   unit, endpoint, bcm_errmsg(rv)));
   2004     }
   2005 
   2006     _BCM_SAT_UNLOCK(satc);
   2007     return (rv);
   2008 }
   2009 
   2010 
   2011 /*
   2012  * Function:
   2013  *     _bcm_sb2_sat_endpoint_destroy_all
   2014  * Purpose:
   2015  *     Delete all endpoints for given endpoint type and free all
   2016  *     its allocated resources.
   2017  * Parameters:
   2018  *     unit   - (IN) BCM device number
   2019  *     flags  - (IN) Endpoint flags.
   2020  * Retruns:
   2021  *     BCM_E_XXX
   2022  */
   2023 STATIC int
   2024 _bcm_sb2_sat_endpoint_destroy_all(int unit, uint32  flags)
   2025 {
   2026     _bcm_sat_control_t      *satc;      /* Pointer to SAT control structure. */
   2027     bcm_sat_endpoint_t      ep_id;      /* Endpoint ID                       */  
   2028     unsigned int            ep_count;   /* Endpoint count                    */
   2029     int                     rv = BCM_E_NONE;/* Operation return status.      */
   2030 
   2031      /* Get SAT device control structure. */
   2032     BCM_IF_ERROR_RETURN(_bcm_sb2_sat_control_get(unit, &satc));
   2033 
   2034     if (flags & BCM_SAT_ENDPOINT_UPMEP) {
   2035 	    ep_count = satc->upsamp_ep_count;
   2036 	}
   2037 	else if (flags & BCM_SAT_ENDPOINT_DOWNMEP) {
   2038         ep_count = satc->downsamp_ep_count;
   2039 	}
   2040     else {
   2041         rv = BCM_E_PARAM;
   2042         return rv;
   2043     }
   2044 
   2045     for(ep_id = 0; ep_id<ep_count; ep_id++) {
   2046 
   2047         /* Check endpoint destroy status. */
   2048         rv = _bcm_sb2_sat_endpoint_destroy(unit, ep_id, flags);
   2049 
   2050          if ((BCM_FAILURE(rv)) && (rv != BCM_E_NOT_FOUND)) {
   2051             /* Endpoint destroy failed. */
   2052             LOG_ERROR(BSL_LS_BCM_SAT, 
   2053                       (BSL_META_U(unit,
   2054                       "SAT(unit %d) Error: Endpoint EP=%d %s.\n"),
   2055                       unit, ep_id, bcm_errmsg(rv)));
   2056             return (rv);
   2057         }
   2058     }
   2059 
   2060     return (BCM_E_NONE);
   2061 }
   2062 
   2063 /*
   2064  * Function:
   2065  *     bcm_sb2_sat_endpoint_destroy_all
   2066  * Purpose:
   2067  *     Delete all endpoints for given endpoint type and free all
   2068  *     its allocated resources.
   2069  * Parameters:
   2070  *     unit   - (IN) BCM device number
   2071  *     flags  - (IN) Endpoint flags.
   2072  * Retruns:
   2073  *     BCM_E_XXX
   2074  */
   2075 int
   2076 bcm_sb2_sat_endpoint_destroy_all(int unit, uint32  flags)
   2077 {
   2078     _bcm_sat_control_t      *satc;      /* Pointer to SAT control structure. */
   2079     int                     rv = BCM_E_NONE;/* Operation return status.      */
   2080 
   2081      /* Get SAT device control structure. */
   2082     BCM_IF_ERROR_RETURN(_bcm_sb2_sat_control_get(unit, &satc));
   2083 
   2084     _BCM_SAT_LOCK(satc);
   2085 
   2086     /* Check endpoint destroy status. */
   2087     rv = _bcm_sb2_sat_endpoint_destroy_all(unit, flags);
   2088 
   2089      if (BCM_FAILURE(rv)) {
   2090         /* Endpoint destroy failed. */
   2091         LOG_ERROR(BSL_LS_BCM_SAT, 
   2092                   (BSL_META_U(unit,
   2093                   "SAT(unit %d) Error: Endpoint destory all %s.\n"),
   2094                   unit, bcm_errmsg(rv)));
   2095         _BCM_SAT_UNLOCK(satc);
   2096         return (rv);
   2097     }
   2098 
   2099      _BCM_SAT_UNLOCK(satc);
   2100 
   2101     return (BCM_E_NONE);
   2102 }
   2103 
   2104 
   2105 /*
   2106  * Function:
   2107  *     bcm_sb2_sat_endpoint_traverse
   2108  * Purpose:
   2109  *     Traverse the set of SAT endpoints associated with the
   2110  *     specified endpoint type, calling a specified callback for each one
   2111  * Parameters:
   2112  *     unit      - (IN) BCM device number
   2113  *     flags     - (IN) The SAT endpoint type whose endpoints should be traversed
   2114  *     cb        - (IN) A pointer to the callback function to call for each SAT
   2115  *                      endpoint in the specified endpoint type
   2116  *     user_data - (IN) Pointer to user data to supply in the callback
   2117  * Returns:
   2118  *      BCM_E_XXX
   2119  */
   2120 int
   2121 bcm_sb2_sat_endpoint_traverse(int unit, uint32 flags,
   2122                               bcm_sat_endpoint_traverse_cb cb,
   2123                               void *user_data)
   2124 {
   2125     _bcm_sat_control_t      *satc;      /* Pointer to SAT control structure. */
   2126     bcm_sat_endpoint_t      ep_id;      /* Endpoint ID                       */  
   2127     unsigned int            ep_count;   /* Endpoint count                    */
   2128     bcm_sat_endpoint_info_t ep_info;    /* Endpoint information              */ 
   2129     _bcm_sat_hash_data_t    *h_data_p;  /* Endpoint count                    */
   2130     _bcm_sat_hash_data_t    *hash_data; 
   2131     int                     rv = BCM_E_NONE ; /* Operation return status.    */
   2132 
   2133 
   2134 
   2135     /* Validate input parameter. */
   2136     if (NULL == cb) {
   2137         return (BCM_E_PARAM);
   2138     }
   2139 
   2140     /* Get SAT device control structure. */
   2141     BCM_IF_ERROR_RETURN(_bcm_sb2_sat_control_get(unit, &satc));
   2142 
   2143 
   2144     _BCM_SAT_LOCK(satc);
   2145 
   2146     if (flags & BCM_SAT_ENDPOINT_UPMEP) {
   2147 	     ep_count = satc->upsamp_ep_count;
   2148          hash_data = satc->upsamp_hash_data;
   2149 	}
   2150 	else if (flags & BCM_SAT_ENDPOINT_DOWNMEP) {
   2151          ep_count = satc->downsamp_ep_count;
   2152          hash_data = satc->downsamp_hash_data;
   2153 	}
   2154     else {
   2155         _BCM_SAT_UNLOCK(satc);
   2156         return (BCM_E_PARAM);
   2157     }
   2158 
   2159     if (NULL == hash_data) {
   2160         LOG_ERROR(BSL_LS_BCM_SAT, 
   2161                   (BSL_META_U(unit,
   2162                   "SAT(unit %d) Error:  endpoints data access failed %s.\n"),
   2163                   unit, bcm_errmsg(BCM_E_INTERNAL)));
   2164         _BCM_SAT_UNLOCK(satc);
   2165         return (BCM_E_INTERNAL);
   2166     }
   2167 
   2168     for(ep_id = 0; ep_id<ep_count; ep_id++) {
   2169 
   2170         h_data_p = &hash_data[ep_id];
   2171 
   2172         if (h_data_p->in_use != 1) {
   2173             LOG_VERBOSE(BSL_LS_BCM_SAT, 
   2174                         (BSL_META_U(unit,
   2175                         "SAT(unit %d) Info:  endpoint does not exist %s.\n"),
   2176                         unit, bcm_errmsg(BCM_E_INTERNAL)));
   2177             continue;
   2178         }
   2179 
   2180         bcm_sat_endpoint_info_t_init(&ep_info);
   2181 
   2182         /* Release the SAT control mutex Lock since it is acquired
   2183          * in bcm_sb2_sat_endpoint_get
   2184          */
   2185          _BCM_SAT_UNLOCK(satc);
   2186 
   2187         rv = bcm_sb2_sat_endpoint_get(unit, ep_id, flags, &ep_info);
   2188 
   2189         /* Require the SAT control mutex Lock */
   2190         _BCM_SAT_LOCK(satc);
   2191 
   2192         if (BCM_FAILURE(rv)) {
   2193             _BCM_SAT_UNLOCK(satc);
   2194             LOG_ERROR(BSL_LS_BCM_SAT, 
   2195                       (BSL_META_U(unit,
   2196                       "SAT(unit %d) Error: EP=%d info get failed %s.\n"),
   2197                       unit, h_data_p->ep_info.ep_id, bcm_errmsg(rv)));
   2198             return (rv);
   2199         }
   2200 
   2201         rv = cb(unit, &ep_info, user_data);
   2202         if (BCM_FAILURE(rv)) {
   2203             _BCM_SAT_UNLOCK(satc);
   2204             LOG_ERROR(BSL_LS_BCM_SAT, 
   2205                       (BSL_META_U(unit,
   2206                       "SAT(unit %d) Error: EP=%d callback failed - %s.\n"),
   2207                       unit, h_data_p->ep_info.ep_id, bcm_errmsg(rv)));
   2208             return (rv);
   2209         }
   2210     }
   2211 
   2212     _BCM_SAT_UNLOCK(satc);
   2213     return (rv);
   2214 }
   2215  
   2216 
   2217 /*
   2218  * Function:
   2219  *     _bcm_sb2_sat_resolve_dglp
   2220  * Purpose:
   2221  *   Add an dglp profile entry 
   2222  * Parameters:
   2223  *     unit        - (IN) BCM device number
   2224  *     dglp        - (IN) DGLP value
   2225  *     olp_enable  - (OUT) Pointer to field indicating whether olp is enabled on
   2226  *                         the port. 
   2227  * Returns:
   2228  *      BCM_E_XXX
   2229  */
   2230 int
   2231 _bcm_sb2_sat_resolve_dglp(int unit, uint32 dglp, int *olp_enable) 
   2232 { 
   2233     int rv = BCM_E_NONE;
   2234     egr_olp_dgpp_config_entry_t *buf;
   2235     egr_olp_dgpp_config_entry_t *entry;
   2236     int         index_max = 0;
   2237     int         index = 0;
   2238     uint32      configured_dglp = 0;
   2239     int         entry_mem_size = 0;
   2240 
   2241     /* Check whether this DGLP is already configured as  OLP port */ 
   2242     entry_mem_size = sizeof(egr_olp_dgpp_config_entry_t);
   2243 	
   2244     /* Allocate buffer to store the DMAed table entries. */
   2245     index_max = soc_mem_index_max(unit, EGR_OLP_DGPP_CONFIGm);
   2246     buf = soc_cm_salloc(unit, entry_mem_size * (index_max + 1),
   2247                               "OLP dglp config table entry buffer");
   2248     if (NULL == buf) {
   2249         return (BCM_E_MEMORY);
   2250     }
   2251     /* Initialize the entry buffer. */
   2252     sal_memset(buf, 0, sizeof(entry_mem_size) * (index_max + 1));
   2253 
   2254     /* Read the table entries into the buffer. */
   2255     rv = soc_mem_read_range(unit, EGR_OLP_DGPP_CONFIGm, MEM_BLOCK_ALL,
   2256                             0, index_max, buf);
   2257     if (BCM_FAILURE(rv)) {
   2258         if (buf) {
   2259             soc_cm_sfree(unit, buf);
   2260         }
   2261         return rv;
   2262     }
   2263 
   2264     /* Iterate over the table entries. */
   2265     for (index = 0; index <= index_max; index++) {
   2266         entry = soc_mem_table_idx_to_pointer
   2267                     (unit, EGR_OLP_DGPP_CONFIGm, egr_olp_dgpp_config_entry_t *,
   2268                      buf, index);
   2269 
   2270         soc_mem_field_get(unit, EGR_OLP_DGPP_CONFIGm, 
   2271                           (uint32 *)entry, DGLPf, &configured_dglp);
   2272         if (dglp == configured_dglp) {
   2273             *olp_enable = 1;
   2274             break;
   2275         }
   2276     }
   2277 	
   2278     if (buf) {
   2279         soc_cm_sfree(unit, buf);
   2280     }
   2281 
   2282     return (BCM_E_NONE);
   2283 } 
   2284 
   2285 #if defined(BCM_WARM_BOOT_SUPPORT)
   2286 /*
   2287  * Function:
   2288  *      _bcm_sb2_sat_wb_upmep_endpoints_recover 
   2289  * Purpose:
   2290  *     Recover SAT UPMEP endpoint configuration.
   2291  * Parameters:
   2292  *     unit        - (IN) BCM device number
   2293  * Returns:
   2294  *     BCM_E_XXX
   2295  */
   2296 STATIC int
   2297 _bcm_sb2_sat_wb_upmep_endpoints_recover(int unit)
   2298 {
   2299     _bcm_gport_dest_t       gport_dest;   /* Gport specification.             */
   2300     _bcm_sat_control_t      *satc;        /* Pointer to control structure.    */
   2301     uint32                  index;        
   2302     uint16                  sglp;         /* Source generic logical port.     */
   2303     uint16                  dglp;         /* Destination generic logical port.*/
   2304     uint16                  vlan_valid;   /* Vlan valid flag.                 */
   2305     uint16                  vlan_pri;     /* Priority.                        */
   2306     uint16                  vlan_cfi;     /* CFI field.                       */
   2307     uint16                  mask;         /* mask field.                      */
   2308     uint32                  fwd_action;   /* SAT packet forward action.       */
   2309     uint32                  time_stamp;   /* Time stamp field.                */
   2310     uint32                  copy_to_cpu;  /* Copy to CPU field.               */
   2311     bcm_sat_endpoint_info_t hw_ep_info; /* Endpoint information read from HW table. */
   2312 
   2313     egr_sat_samp_tcam_entry_t      entry; /* UP-MEP SAMP TCAM  entry.   */
   2314 	egr_sat_samp_data_entry_t      dentry; /* UP-MEP SAMP Data entry.   */
   2315 	int  rv = BCM_E_NONE; /* Operation return status.     */
   2316 
   2317 
   2318 	LOG_VERBOSE(BSL_LS_BCM_SAT, 
   2319                 (BSL_META_U(unit,
   2320                 "SAT(unit %d) Info: _bcm_sb2_sat_upmep_endpoints_recover.\n"),
   2321                 unit));
   2322 	
   2323     sal_memset(&entry, 0, sizeof(egr_sat_samp_tcam_entry_t));
   2324     sal_memset(&dentry, 0, sizeof(egr_sat_samp_data_entry_t));
   2325 	
   2326     /*
   2327      * Get SAT control structure.
   2328      *     Note: Lock taken by calling routine.
   2329      */
   2330     BCM_IF_ERROR_RETURN(_bcm_sb2_sat_control_get(unit, &satc));
   2331 
   2332     _BCM_SAT_LOCK(satc);
   2333 
   2334     for (index = 0; index < satc->upsamp_ep_count; index++) {
   2335         sal_memset(&hw_ep_info,0,sizeof(bcm_sat_endpoint_info_t));
   2336 
   2337         /* Get the UP MEP TCAM table entry. */
   2338 		rv = READ_EGR_SAT_SAMP_TCAMm(unit, MEM_BLOCK_ANY, index, &entry);
   2339 		if (BCM_FAILURE(rv)) {
   2340             LOG_ERROR(BSL_LS_BCM_SAT, 
   2341                       (BSL_META_U(unit,
   2342                     "SAT(unit %d) Error: UP MEP TCAM table read (index=%d) failed "\
   2343                     "- %s.\n"), unit, index, bcm_errmsg(rv)));
   2344             goto cleanup;
   2345         }
   2346 		
   2347 		/* Get the UP MEP DATA table entry. */
   2348 		rv = READ_EGR_SAT_SAMP_DATAm(unit, MEM_BLOCK_ANY, index, &dentry);
   2349 		if (BCM_FAILURE(rv)) {
   2350             LOG_ERROR(BSL_LS_BCM_SAT, 
   2351                       (BSL_META_U(unit,
   2352                       "SAT(unit %d) Error: UP MEP DATA table read (index=%d) failed "\
   2353                     "- %s.\n"), unit, index, bcm_errmsg(rv)));
   2354             goto cleanup;
   2355         }
   2356         
   2357 
   2358         if (soc_EGR_SAT_SAMP_TCAMm_field32_get(unit, &entry, VALIDf)) {
   2359 
   2360             hw_ep_info.ep_id = index;
   2361 
   2362             hw_ep_info.flags |= BCM_SAT_ENDPOINT_UPMEP;
   2363             hw_ep_info.flags |= BCM_SAT_ENDPOINT_WITH_ID;
   2364 
   2365             /* Get ether type field for the UP-MEP SAMP entry. */
   2366             hw_ep_info.ether_type = soc_EGR_SAT_SAMP_TCAMm_field32_get(unit,
   2367                                                             &entry, 
   2368                                                             ETHERTYPEf);
   2369 
   2370             /* Get source port field for the UP-MEP SAMP entry. */
   2371             sglp = soc_EGR_SAT_SAMP_TCAMm_field32_get(unit, &entry, GLPf);
   2372 
   2373             _bcm_gport_dest_t_init(&gport_dest);
   2374             if(_BCM_SAT_GLP_TRUNK_BIT_GET(unit, sglp)) {
   2375                 gport_dest.tgid = _BCM_SAT_GLP_TRUNK_ID_GET(unit, sglp);
   2376                 gport_dest.gport_type = _SHR_GPORT_TYPE_TRUNK;
   2377             } else {
   2378                 gport_dest.gport_type = _SHR_GPORT_TYPE_MODPORT;
   2379                 gport_dest.modid = _BCM_SAT_GLP_MODULE_ID_GET(unit, sglp);
   2380                 gport_dest.port = _BCM_SAT_GLP_PORT_GET(unit, sglp);
   2381             }
   2382             rv = _bcm_esw_gport_construct(unit, &gport_dest, 
   2383                                           &hw_ep_info.src_gport);
   2384             if (BCM_FAILURE(rv)) {
   2385                 LOG_ERROR(BSL_LS_BCM_SAT, 
   2386                           (BSL_META_U(unit,
   2387                           "SAT(unit %d) Error: Gport construct failed"\
   2388                         " - %s.\n"), unit, bcm_errmsg(rv)));
   2389                 goto cleanup;
   2390             }
   2391 
   2392 
   2393             /* Get source MAC address field for the UP-MEP SAMP entry. */
   2394             soc_mem_mac_addr_get(unit, EGR_SAT_SAMP_TCAMm, &entry, 
   2395                                  MACSAf, hw_ep_info.src_mac_address);
   2396             	
   2397             /* Get destination MAC address field for the UP-MEP SAMP entry. */
   2398             soc_mem_mac_addr_get(unit, EGR_SAT_SAMP_TCAMm, &entry, 
   2399                                  MACDAf, hw_ep_info.dst_mac_address);
   2400 
   2401             /* Get the outer TAG valid field  */
   2402             vlan_valid = soc_ING_SAT_SAMP_TCAMm_field32_get(unit, &entry, 
   2403                                                             OTAG_VALIDf); 
   2404 
   2405             if (vlan_valid) {
   2406                 hw_ep_info.flags |= BCM_SAT_ENDPOINT_MATCH_OUTER_VLAN; 
   2407             }
   2408 
   2409             hw_ep_info.outer_vlan = soc_EGR_SAT_SAMP_TCAMm_field32_get(unit, 
   2410                                                       &entry, OVIDf);
   2411                  
   2412             vlan_pri = soc_EGR_SAT_SAMP_TCAMm_field32_get(unit, &entry, OPRIf);
   2413             mask = (1 << soc_mem_field_length(unit, EGR_SAT_SAMP_TCAMm, 
   2414                                               OPRI_MASKf)) - 1;
   2415             _BCM_SAT_VLAN_PRI_SET(hw_ep_info.outer_vlan,vlan_pri,mask);
   2416 
   2417             vlan_cfi = soc_EGR_SAT_SAMP_TCAMm_field32_get(unit, &entry, OCFIf);
   2418             mask = (1 << soc_mem_field_length(unit, EGR_SAT_SAMP_TCAMm, 
   2419                                               OCFI_MASKf)) - 1;
   2420             _BCM_SAT_VLAN_PRI_SET(hw_ep_info.outer_vlan,vlan_cfi,mask);
   2421 
   2422             /* Get the inner TAG valid field  */
   2423             vlan_valid = soc_ING_SAT_SAMP_TCAMm_field32_get(unit, &entry, 
   2424                                                             ITAG_VALIDf); 
   2425             if (vlan_valid) {
   2426                 hw_ep_info.flags |= BCM_SAT_ENDPOINT_MATCH_INNER_VLAN; 
   2427             }
   2428 
   2429             hw_ep_info.inner_vlan = soc_EGR_SAT_SAMP_TCAMm_field32_get(unit, 
   2430                                                       &entry, IVIDf);
   2431             vlan_pri = soc_EGR_SAT_SAMP_TCAMm_field32_get(unit, &entry, IPRIf);
   2432             mask = (1 << soc_mem_field_length(unit, EGR_SAT_SAMP_TCAMm, 
   2433                                               IPRI_MASKf)) - 1;
   2434             _BCM_SAT_VLAN_PRI_SET(hw_ep_info.inner_vlan,vlan_pri,mask);
   2435 
   2436             vlan_cfi = soc_EGR_SAT_SAMP_TCAMm_field32_get(unit, &entry, ICFIf);
   2437             mask = (1 << soc_mem_field_length(unit, EGR_SAT_SAMP_TCAMm, 
   2438                                               ICFI_MASKf)) - 1;
   2439             _BCM_SAT_VLAN_PRI_SET(hw_ep_info.inner_vlan,vlan_cfi,mask);
   2440 
   2441 
   2442             /* Retrieve SAT TCAM Data fields */
   2443 
   2444             /* Get the Copy-to-CPU field  */
   2445             copy_to_cpu = soc_EGR_SAT_SAMP_DATAm_field32_get(unit, &dentry,
   2446                                                              COPYTO_CPUf);
   2447         	
   2448         	if (copy_to_cpu) {
   2449         	    hw_ep_info.action_flags |= BCM_SAT_ACTION_COPY_TO_CPU;
   2450         	}
   2451         						 
   2452             /* Get destination port */
   2453             dglp = soc_EGR_SAT_SAMP_DATAm_field32_get(unit, &dentry,
   2454                                                       DESTINATIONf);
   2455 
   2456             _bcm_gport_dest_t_init(&gport_dest);
   2457             if(_BCM_SAT_GLP_TRUNK_BIT_GET(unit, dglp)) {
   2458                 gport_dest.tgid = _BCM_SAT_GLP_TRUNK_ID_GET(unit, dglp);
   2459                 gport_dest.gport_type = _SHR_GPORT_TYPE_TRUNK;
   2460             } else {
   2461                 gport_dest.gport_type = _SHR_GPORT_TYPE_MODPORT;
   2462                 gport_dest.modid = _BCM_SAT_GLP_MODULE_ID_GET(unit, dglp);
   2463                 gport_dest.port = _BCM_SAT_GLP_PORT_GET(unit, dglp);
   2464             }
   2465             rv = _bcm_esw_gport_construct(unit, &gport_dest, 
   2466                                           &hw_ep_info.dest_gport);
   2467             if (BCM_FAILURE(rv)) {
   2468                 LOG_ERROR(BSL_LS_BCM_SAT, 
   2469                           (BSL_META_U(unit,
   2470                           "SAT(unit %d) Error: Gport construct failed"\
   2471                         " - %s.\n"), unit, bcm_errmsg(rv)));
   2472                 goto cleanup;
   2473             }
   2474 
   2475         	/* Get forward action field */
   2476             fwd_action = soc_EGR_SAT_SAMP_DATAm_field32_get(unit, &dentry,
   2477                                                             FORWARD_ACTIONf);
   2478         	
   2479         	/* Forward action for the SAT packet is to drop */
   2480             if (fwd_action == 0 ) {
   2481         		  hw_ep_info.action_flags |= BCM_SAT_ACTION_FWD_ACTION_DROP;
   2482             }
   2483             
   2484         	/* Forward action for the SAT packet is redirect to DGLP port */
   2485             else if (fwd_action == 1 ) {
   2486                   hw_ep_info.action_flags |= BCM_SAT_ACTION_FWD_ACTION_REDIRECT;
   2487             }
   2488         	/* Forward action for the SAT packet is perform LLF */
   2489         	else if (fwd_action == 2 ) {
   2490                   hw_ep_info.action_flags |= BCM_SAT_ACTION_FWD_ACTION_LLF;
   2491             }
   2492 
   2493             /* Get Sample time stamp status into OLP header field */
   2494             time_stamp = soc_EGR_SAT_SAMP_DATAm_field32_get(unit, &dentry,
   2495                                                             SAMPLE_TIMESTAMPf); 
   2496         	if (time_stamp) {
   2497                 hw_ep_info.action_flags |= BCM_SAT_ACTION_SAMPLE_TIMESTAMP;
   2498         	}
   2499 
   2500             /* Get INT_PRI */
   2501             hw_ep_info.pkt_pri = soc_EGR_SAT_SAMP_DATAm_field32_get(unit,
   2502                                                                     &dentry, 
   2503                                                                     INT_PRIf);
   2504         	
   2505             /* Get Session ID field  */
   2506             hw_ep_info.session_id = soc_EGR_SAT_SAMP_DATAm_field32_get(unit,
   2507                                             &dentry, SAT_SESSION_IDf);
   2508 
   2509             /* Get Time stamp type field  */
   2510             hw_ep_info.timestamp_format = soc_EGR_SAT_SAMP_DATAm_field32_get(
   2511                                             unit,&dentry, 
   2512                                             TIMESTAMP_TYPEf);
   2513 
   2514             /* Release Lock here as lock is aquired in  bcm_sat_endpoint_create */
   2515             _BCM_SAT_UNLOCK(satc);
   2516 
   2517             rv = bcm_sb2_sat_endpoint_create(unit,&hw_ep_info);
   2518 
   2519             if (BCM_FAILURE(rv)) {
   2520                 LOG_ERROR(BSL_LS_BCM_SAT, 
   2521                           (BSL_META_U(unit,
   2522              "SAT(unit %d) Error: UP MEP Endpoint table insert failed EP=%d %s.\n"),
   2523                           unit, hw_ep_info.ep_id, bcm_errmsg(rv)));
   2524                 goto cleanup;
   2525                 return (rv);
   2526             }else {
   2527                 LOG_VERBOSE(BSL_LS_BCM_SAT, 
   2528                             (BSL_META_U(unit,
   2529                             "SAT(unit %d) Info: UP MEP Hash Tbl (EP=%d)"\
   2530                           " inserted  - %s.\n"), unit, hw_ep_info.ep_id,
   2531                           bcm_errmsg(rv)));
   2532             }
   2533 
   2534             /* Aquire Lock as lock is released in bcm_sat_endpoint_create */
   2535             _BCM_SAT_LOCK(satc);
   2536         }
   2537     }
   2538 
   2539     _BCM_SAT_UNLOCK(satc);
   2540     LOG_VERBOSE(BSL_LS_BCM_SAT, 
   2541                 (BSL_META_U(unit,
   2542                 "SAT(unit %d) Info: _bcm_sb2_sat_wb_upmep_endpoints_recover"
   2543               " - done.\n"), unit));
   2544     return (rv);
   2545 
   2546 cleanup:
   2547 
   2548     _BCM_SAT_UNLOCK(satc);
   2549 
   2550     LOG_VERBOSE(BSL_LS_BCM_SAT, 
   2551                 (BSL_META_U(unit,
   2552                 "SAT(unit %d) Info: _bcm_sb2_sat_wb_upmep_endpoints_recover"\
   2553               " - error_done.\n"), unit));
   2554     return (rv);
   2555 }
   2556 
   2557 /*
   2558  * Function:
   2559  *      _bcm_sb2_sat_wb_downmep_endpoints_recover 
   2560  * Purpose:
   2561  *     Recover SAT DOWNMEP endpoint configuration.
   2562  * Parameters:
   2563  *     unit        - (IN) BCM device number
   2564  * Returns:
   2565  *     BCM_E_XXX
   2566  */
   2567 STATIC int
   2568 _bcm_sb2_sat_wb_downmep_endpoints_recover(int unit)
   2569 {
   2570     _bcm_gport_dest_t       gport_dest;   /* Gport specification.             */
   2571     _bcm_sat_control_t      *satc;        /* Pointer to control structure.    */
   2572     uint32                  index;        
   2573     uint16                  sglp;         /* Source generic logical port.     */
   2574     uint16                  dglp;         /* Destination generic logical port.*/
   2575     uint16                  vlan_valid;   /* Vlan valid flag.                 */
   2576     uint16                  vlan_pri;     /* Priority.                        */
   2577     uint16                  vlan_cfi;     /* CFI field.                       */
   2578     uint16                  mask;         /* mask field.                      */
   2579     uint32                  fwd_action;   /* SAT packet forward action.       */
   2580     uint32                  time_stamp;   /* Time stamp field.                */
   2581     uint32                  copy_to_cpu;  /* Copy to CPU field.               */
   2582     bcm_sat_endpoint_info_t hw_ep_info; /* Endpoint information read from HW table. */
   2583 
   2584     egr_sat_samp_tcam_entry_t      entry; /* DOWN-MEP SAMP TCAM  entry.   */
   2585 	egr_sat_samp_data_entry_t      dentry; /* DOWN-MEP SAMP Data entry.   */
   2586 	int  rv = BCM_E_NONE; /* Operation return status.     */
   2587 
   2588 
   2589 	LOG_VERBOSE(BSL_LS_BCM_SAT, 
   2590                 (BSL_META_U(unit,
   2591                 "SAT(unit %d) Info: _bcm_sb2_sat_downmep_endpoints_recover.\n"),
   2592                 unit));
   2593 	
   2594     sal_memset(&entry, 0, sizeof(egr_sat_samp_tcam_entry_t));
   2595     sal_memset(&dentry, 0, sizeof(egr_sat_samp_data_entry_t));
   2596 	
   2597     /*
   2598      * Get SAT control structure.
   2599      *     Note: Lock taken by calling routine.
   2600      */
   2601     BCM_IF_ERROR_RETURN(_bcm_sb2_sat_control_get(unit, &satc));
   2602 
   2603     _BCM_SAT_LOCK(satc);
   2604 
   2605     for (index = 0; index < satc->downsamp_ep_count; index++) {
   2606         sal_memset(&hw_ep_info,0,sizeof(bcm_sat_endpoint_info_t));
   2607 
   2608         /* Get the DOWN MEP TCAM table entry. */
   2609 		rv = READ_ING_SAT_SAMP_TCAMm(unit, MEM_BLOCK_ANY, index, &entry);
   2610 		if (BCM_FAILURE(rv)) {
   2611             LOG_ERROR(BSL_LS_BCM_SAT, 
   2612                       (BSL_META_U(unit,
   2613                   "SAT(unit %d) Error: DOWN MEP TCAM table read (index=%d) failed "\
   2614                     "- %s.\n"), unit, index, bcm_errmsg(rv)));
   2615             goto cleanup;
   2616         }
   2617 		
   2618 		/* Get the DOWN MEP DATA table entry. */
   2619 		rv = READ_ING_SAT_SAMP_DATAm(unit, MEM_BLOCK_ANY, index, &dentry);
   2620 		if (BCM_FAILURE(rv)) {
   2621             LOG_ERROR(BSL_LS_BCM_SAT, 
   2622                       (BSL_META_U(unit,
   2623                   "SAT(unit %d) Error: DOWN MEP DATA table read (index=%d) failed "\
   2624                     "- %s.\n"), unit, index, bcm_errmsg(rv)));
   2625             goto cleanup;
   2626         }
   2627         
   2628 
   2629         if (soc_ING_SAT_SAMP_TCAMm_field32_get(unit, &entry, VALIDf)) {
   2630 
   2631             hw_ep_info.ep_id = index;
   2632 
   2633             hw_ep_info.flags |= BCM_SAT_ENDPOINT_DOWNMEP;
   2634             hw_ep_info.flags |= BCM_SAT_ENDPOINT_WITH_ID;
   2635             
   2636 
   2637             /* Get ether type field for the DOWN-MEP SAMP entry. */
   2638             hw_ep_info.ether_type = soc_ING_SAT_SAMP_TCAMm_field32_get(unit, 
   2639                                                             &entry, 
   2640                                                             ETHERTYPEf);
   2641 
   2642             /* Get source port field for the DOWN-MEP SAMP entry. */
   2643             sglp = soc_ING_SAT_SAMP_TCAMm_field32_get(unit, &entry, GLPf);
   2644 
   2645             _bcm_gport_dest_t_init(&gport_dest);
   2646             if(_BCM_SAT_GLP_TRUNK_BIT_GET(unit, sglp)) {
   2647                 gport_dest.tgid = _BCM_SAT_GLP_TRUNK_ID_GET(unit, sglp);
   2648                 gport_dest.gport_type = _SHR_GPORT_TYPE_TRUNK;
   2649             } else {
   2650                 gport_dest.gport_type = _SHR_GPORT_TYPE_MODPORT;
   2651                 gport_dest.modid = _BCM_SAT_GLP_MODULE_ID_GET(unit, sglp);
   2652                 gport_dest.port = _BCM_SAT_GLP_PORT_GET(unit, sglp);
   2653             }
   2654             rv = _bcm_esw_gport_construct(unit, &gport_dest, 
   2655                                           &hw_ep_info.src_gport);
   2656             if (BCM_FAILURE(rv)) {
   2657                 LOG_ERROR(BSL_LS_BCM_SAT, 
   2658                           (BSL_META_U(unit,
   2659                           "SAT(unit %d) Error: Gport construct failed"\
   2660                         " - %s.\n"), unit, bcm_errmsg(rv)));
   2661                 goto cleanup;
   2662             }
   2663 
   2664             /* Get source MAC address field for the DOWN-MEP SAMP entry. */
   2665             soc_mem_mac_addr_get(unit, ING_SAT_SAMP_TCAMm, &entry, 
   2666                                  MACSAf, hw_ep_info.src_mac_address);
   2667             	
   2668             /* Get destination MAC address field for the DOWN-MEP SAMP entry. */
   2669             soc_mem_mac_addr_get(unit, ING_SAT_SAMP_TCAMm, &entry, 
   2670                                  MACDAf, hw_ep_info.dst_mac_address);
   2671 
   2672             /* Get the outer TAG valid field  */
   2673             vlan_valid = soc_ING_SAT_SAMP_TCAMm_field32_get(unit, &entry, 
   2674                                                             OTAG_VALIDf); 
   2675 
   2676             if (vlan_valid) {
   2677                 hw_ep_info.flags |= BCM_SAT_ENDPOINT_MATCH_OUTER_VLAN; 
   2678             }
   2679 
   2680             hw_ep_info.outer_vlan = soc_ING_SAT_SAMP_TCAMm_field32_get(unit, 
   2681                                                       &entry, OVIDf);
   2682                  
   2683             vlan_pri = soc_ING_SAT_SAMP_TCAMm_field32_get(unit, &entry, OPRIf);
   2684             mask = (1 << soc_mem_field_length(unit, ING_SAT_SAMP_TCAMm, 
   2685                                               OPRI_MASKf)) - 1;
   2686             _BCM_SAT_VLAN_PRI_SET(hw_ep_info.outer_vlan,vlan_pri,mask);
   2687 
   2688             vlan_cfi = soc_ING_SAT_SAMP_TCAMm_field32_get(unit, &entry, OCFIf);
   2689             mask = (1 << soc_mem_field_length(unit, ING_SAT_SAMP_TCAMm, 
   2690                                               OCFI_MASKf)) - 1;
   2691             _BCM_SAT_VLAN_PRI_SET(hw_ep_info.outer_vlan,vlan_cfi,mask);
   2692 
   2693             /* Get the inner TAG valid field  */
   2694             vlan_valid = soc_ING_SAT_SAMP_TCAMm_field32_get(unit, &entry, 
   2695                                                             ITAG_VALIDf); 
   2696             if (vlan_valid) {
   2697                 hw_ep_info.flags |= BCM_SAT_ENDPOINT_MATCH_INNER_VLAN; 
   2698             }
   2699 
   2700             hw_ep_info.inner_vlan = soc_ING_SAT_SAMP_TCAMm_field32_get(unit, 
   2701                                                       &entry, IVIDf);
   2702             vlan_pri = soc_ING_SAT_SAMP_TCAMm_field32_get(unit, &entry, IPRIf);
   2703             mask = (1 << soc_mem_field_length(unit, ING_SAT_SAMP_TCAMm, 
   2704                                               IPRI_MASKf)) - 1;
   2705             _BCM_SAT_VLAN_PRI_SET(hw_ep_info.inner_vlan,vlan_pri,mask);
   2706 
   2707             vlan_cfi = soc_ING_SAT_SAMP_TCAMm_field32_get(unit, &entry, ICFIf);
   2708             mask = (1 << soc_mem_field_length(unit, ING_SAT_SAMP_TCAMm, 
   2709                                               ICFI_MASKf)) - 1;
   2710             _BCM_SAT_VLAN_PRI_SET(hw_ep_info.inner_vlan,vlan_cfi,mask);
   2711 
   2712 
   2713             /* Retrieve SAT TCAM Data fields */
   2714 
   2715             /* Get the Copy-to-CPU field  */
   2716             copy_to_cpu = soc_ING_SAT_SAMP_DATAm_field32_get(unit, &dentry,
   2717                                                              COPYTO_CPUf);
   2718         	
   2719         	if (copy_to_cpu) {
   2720         	    hw_ep_info.action_flags |= BCM_SAT_ACTION_COPY_TO_CPU;
   2721         	}
   2722         						 
   2723             /* Get destination port */
   2724             dglp = soc_ING_SAT_SAMP_DATAm_field32_get(unit, &dentry,
   2725                                                       DESTINATIONf);
   2726 
   2727             _bcm_gport_dest_t_init(&gport_dest);
   2728             if(_BCM_SAT_GLP_TRUNK_BIT_GET(unit, dglp)) {
   2729                 gport_dest.tgid = _BCM_SAT_GLP_TRUNK_ID_GET(unit, dglp);
   2730                 gport_dest.gport_type = _SHR_GPORT_TYPE_TRUNK;
   2731             } else {
   2732                 gport_dest.gport_type = _SHR_GPORT_TYPE_MODPORT;
   2733                 gport_dest.modid = _BCM_SAT_GLP_MODULE_ID_GET(unit, dglp);
   2734                 gport_dest.port = _BCM_SAT_GLP_PORT_GET(unit, dglp);
   2735             }
   2736             rv = _bcm_esw_gport_construct(unit, &gport_dest, 
   2737                                           &hw_ep_info.dest_gport);
   2738             if (BCM_FAILURE(rv)) {
   2739                 LOG_ERROR(BSL_LS_BCM_SAT, 
   2740                           (BSL_META_U(unit,
   2741                           "SAT(unit %d) Error: Gport construct failed"\
   2742                         " - %s.\n"), unit, bcm_errmsg(rv)));
   2743                 goto cleanup;
   2744             }
   2745 
   2746         	/* Get forward action field */
   2747             fwd_action = soc_ING_SAT_SAMP_DATAm_field32_get(unit, &dentry,
   2748                                                             FORWARD_ACTIONf);
   2749         	
   2750         	/* Forward action for the SAT packet is to drop */
   2751             if (fwd_action == 0 ) {
   2752         		  hw_ep_info.action_flags |= BCM_SAT_ACTION_FWD_ACTION_DROP;
   2753             }
   2754             
   2755         	/* Forward action for the SAT packet is redirect to DGLP port */
   2756             else if (fwd_action == 1 ) {
   2757                   hw_ep_info.action_flags |= BCM_SAT_ACTION_FWD_ACTION_REDIRECT;
   2758             }
   2759         	/* Forward action for the SAT packet is perform LLF */
   2760         	else if (fwd_action == 2 ) {
   2761                   hw_ep_info.action_flags |= BCM_SAT_ACTION_FWD_ACTION_LLF;
   2762             }
   2763 
   2764             /* Get Sample time stamp status into OLP header field */
   2765             time_stamp = soc_ING_SAT_SAMP_DATAm_field32_get(unit, &dentry,
   2766                                                             SAMPLE_TIMESTAMPf); 
   2767         	if (time_stamp) {
   2768                 hw_ep_info.action_flags |= BCM_SAT_ACTION_SAMPLE_TIMESTAMP;
   2769         	}
   2770 
   2771             /* Get INT_PRI */
   2772             hw_ep_info.pkt_pri = soc_ING_SAT_SAMP_DATAm_field32_get(unit,
   2773                                                                     &dentry, 
   2774                                                                     INT_PRIf);
   2775         	
   2776             /* Get Session ID field  */
   2777             hw_ep_info.session_id = soc_ING_SAT_SAMP_DATAm_field32_get(unit,
   2778                                             &dentry, SAT_SESSION_IDf);
   2779 
   2780             /* Get Time stamp type field  */
   2781             hw_ep_info.timestamp_format = soc_ING_SAT_SAMP_DATAm_field32_get(
   2782                                             unit,&dentry, 
   2783                                             TIMESTAMP_TYPEf);
   2784 
   2785             /* Release Lock here as lock is aquired in  bcm_sat_endpoint_create */
   2786             _BCM_SAT_UNLOCK(satc);
   2787 
   2788             rv = bcm_sb2_sat_endpoint_create(unit,&hw_ep_info);
   2789 
   2790             if (BCM_FAILURE(rv)) {
   2791                 LOG_ERROR(BSL_LS_BCM_SAT, 
   2792                           (BSL_META_U(unit,
   2793             "SAT(unit %d) Error: DownMEP Endpoint table insert failed EP=%d %s.\n"),
   2794                           unit, hw_ep_info.ep_id, bcm_errmsg(rv)));
   2795                 goto cleanup;
   2796                 return (rv);
   2797             }else {
   2798                 LOG_VERBOSE(BSL_LS_BCM_SAT, 
   2799                             (BSL_META_U(unit,
   2800                             "SAT(unit %d) Info: DOWN MEP Hash Tbl (EP=%d)"\
   2801                           " inserted  - %s.\n"), unit, hw_ep_info.ep_id,
   2802                           bcm_errmsg(rv)));
   2803             }
   2804 
   2805             /* Aquire Lock as lock is released in bcm_sat_endpoint_create */
   2806             _BCM_SAT_LOCK(satc);
   2807         }
   2808     }
   2809 
   2810     _BCM_SAT_UNLOCK(satc);
   2811 
   2812     LOG_VERBOSE(BSL_LS_BCM_SAT, 
   2813                 (BSL_META_U(unit,
   2814                 "SAT(unit %d) Info: _bcm_sb2_sat_wb_downmep_endpoints_recover"
   2815               " - done.\n"), unit));
   2816     return (rv);
   2817 
   2818 cleanup:
   2819     _BCM_SAT_UNLOCK(satc);
   2820     LOG_VERBOSE(BSL_LS_BCM_SAT, 
   2821                 (BSL_META_U(unit,
   2822                 "SAT(unit %d) Info: _bcm_sb2_sat_wb_downmep_endpoints_recover"\
   2823               " - error_done.\n"), unit));
   2824     return (rv);
   2825 }
   2826 #endif
   2827 
   2828 /*
   2829  * Function:
   2830  *     _bcm_sb2_sat_mep_hw_set
   2831  * Purpose:
   2832  *     Configure hardware tables for an UP-MEP/DOWN-MEP endpoint.
   2833  * Parameters:
   2834  *     unit      - (IN) BCM device number
   2835  *     ep_info_p - (IN) Pointer to UP-MEP/DOWN_MEP endpoint information.
   2836  *     sglp      - (IN) SGLP port for UP-MEP/DOWN_MEP endpoint. 
   2837  *     dglp      - (IN) DGLP port for UP-MEP/DOWN_MEP endpoint. 
   2838  * Retruns:
   2839  *     BCM_E_XXX
   2840  */
   2841 STATIC int
   2842 _bcm_sb2_sat_mep_hw_set(int unit, bcm_sat_endpoint_info_t *ep_info_p,
   2843                         uint16 sglp, uint16 dglp)
   2844 {
   2845     _bcm_sat_hash_data_t *hash_data; /* Pointer to endpoint hash data. */
   2846     ing_sat_samp_tcam_entry_t      ing_entry; /* DOWNMEP SAMP TCAM  entry.   */
   2847 	ing_sat_samp_data_entry_t      ing_dentry; /* DOWNMEP SAMP Data entry.   */
   2848     egr_sat_samp_tcam_entry_t      egr_entry; /* UPMEP SAMP TCAM  entry.   */
   2849     egr_sat_samp_data_entry_t      egr_dentry; /* UPMEP SAMP Data entry.   */
   2850     egr_sat_samp_data_1_entry_t      egr_d_1entry; /* UPMEP SAMP Data_1 entry.   */
   2851     void   *ptr_d_1entry; /* MEP SAMP Data entry.   */
   2852     void   *ptr_entry; /*  MEP SAMP TCAM  entry.   */
   2853     void   *ptr_dentry; /* MEP SAMP Data entry.   */
   2854     _bcm_sat_control_t   *satc;        /* Pointer to control structure.  */
   2855     uint8     fwd_action = 0;
   2856     bcm_mac_t mac_mask;
   2857     uint32    mask_field;	
   2858     int       olp_enable = 0;
   2859     uint8     vlan_pri = 0;
   2860     uint8     vlan_cfi = 0;
   2861 	soc_mem_t tcam_mem;
   2862     soc_mem_t data_mem;
   2863     int       rv = BCM_E_NONE;/* Operation return status.      */
   2864 
   2865 
   2866     if (NULL == ep_info_p) {
   2867         return (BCM_E_INTERNAL);
   2868     }
   2869 
   2870     /* Lock already taken by the calling routine. */
   2871     BCM_IF_ERROR_RETURN(_bcm_sb2_sat_control_get(unit, &satc));
   2872 
   2873     if (ep_info_p->flags & BCM_SAT_ENDPOINT_UPMEP) {
   2874         ptr_entry  = &egr_entry;
   2875         ptr_dentry = &egr_dentry;
   2876         tcam_mem = EGR_SAT_SAMP_TCAMm;
   2877         data_mem = EGR_SAT_SAMP_DATAm;
   2878 
   2879         /* Get the stored endpoint information from hash table. */
   2880         hash_data = &satc->upsamp_hash_data[ep_info_p->ep_id];
   2881         if (0 == hash_data->in_use) {
   2882             return(BCM_E_INTERNAL);
   2883         }
   2884         sal_memset(ptr_entry, 0, sizeof(egr_sat_samp_tcam_entry_t));
   2885         sal_memset(ptr_dentry, 0, sizeof(egr_sat_samp_data_entry_t));
   2886     }
   2887     else if (ep_info_p->flags & BCM_SAT_ENDPOINT_DOWNMEP) {
   2888         ptr_entry  = &ing_entry;
   2889         ptr_dentry = &ing_dentry;
   2890         tcam_mem = ING_SAT_SAMP_TCAMm;
   2891         data_mem = ING_SAT_SAMP_DATAm;
   2892 
   2893         /* Get the stored endpoint information from hash table. */
   2894         hash_data = &satc->downsamp_hash_data[ep_info_p->ep_id];
   2895         if (0 == hash_data->in_use) {
   2896             return(BCM_E_INTERNAL);
   2897         }
   2898         sal_memset(ptr_entry, 0, sizeof(ing_sat_samp_tcam_entry_t));
   2899         sal_memset(ptr_dentry, 0, sizeof(ing_sat_samp_data_entry_t));
   2900     }
   2901     else 
   2902     {
   2903         return(BCM_E_PARAM);
   2904     }
   2905 
   2906     /* Set ether type field for the MEP SAMP entry. */
   2907     soc_mem_field32_set(unit, tcam_mem, ptr_entry, 
   2908                         ETHERTYPEf, ep_info_p->ether_type);
   2909 									   
   2910 	/* Set ether type field mask for the MEP SAMP entry. */
   2911 	mask_field = (1 << soc_mem_field_length(unit, tcam_mem, ETHERTYPE_MASKf)) - 1;
   2912 		
   2913     soc_mem_field32_set(unit, tcam_mem, ptr_entry, ETHERTYPE_MASKf, mask_field);
   2914 
   2915     /* Set source port field for the MEP SAMP entry. */
   2916     soc_mem_field32_set(unit, tcam_mem, ptr_entry, GLPf, sglp);
   2917 	
   2918 	/* Set source port field mask for the MEP SAMP entry. */
   2919     mask_field = (1 << soc_mem_field_length(unit, tcam_mem, GLP_MASKf)) - 1;
   2920 		
   2921     soc_mem_field32_set(unit, tcam_mem, ptr_entry, GLP_MASKf, mask_field);
   2922 
   2923 	
   2924     /* Set source MAC address field for the MEP SAMP entry. */
   2925     soc_mem_mac_addr_set(unit, tcam_mem, ptr_entry, 
   2926                          MACSAf, ep_info_p->src_mac_address);
   2927 	
   2928     /* Set source MAC address field mask for the MEP SAMP entry. */
   2929     sal_memset(&mac_mask, 0xff, sizeof(mac_mask));
   2930     soc_mem_mac_addr_set(unit, tcam_mem, ptr_entry, 
   2931                          MACSA_MASKf, mac_mask);
   2932 
   2933 
   2934     /* Set destination MAC address field for the MEP SAMP entry. */
   2935     soc_mem_mac_addr_set(unit, tcam_mem, ptr_entry, 
   2936                          MACDAf, ep_info_p->dst_mac_address);
   2937 
   2938     /* Set destination MAC address field mask for the MEP SAMP entry. */
   2939     sal_memset(&mac_mask, 0xff, sizeof(mac_mask));
   2940     soc_mem_mac_addr_set(unit, tcam_mem, ptr_entry, 
   2941                          MACDA_MASKf, mac_mask);
   2942 	
   2943 	
   2944     /* Configure ITAG fields to hardware only if user flag to match
   2945      * inner VLAN is configured.
   2946      */
   2947     if (ep_info_p->flags & BCM_SAT_ENDPOINT_MATCH_INNER_VLAN) {
   2948 
   2949         /* Set the inner VLAN field  */
   2950         mask_field = (1 << soc_mem_field_length(unit, tcam_mem, IVIDf)) - 1;
   2951 
   2952         soc_mem_field32_set(unit, tcam_mem, ptr_entry, IVIDf, 
   2953                              (ep_info_p->inner_vlan & mask_field));
   2954 
   2955         /* Set the inner VLAN mask field  */
   2956         soc_mem_field32_set(unit, tcam_mem, ptr_entry, IVID_MASKf, mask_field);
   2957 
   2958         /* Set the inner TAG valid field  */
   2959         soc_mem_field32_set(unit, tcam_mem, ptr_entry, ITAG_VALIDf, 
   2960             ((ep_info_p->flags & BCM_SAT_ENDPOINT_MATCH_INNER_VLAN) ? 1 : 0)); 
   2961 
   2962         /* Set the inner TAG valid mask field  */
   2963         mask_field = (1 << soc_mem_field_length(unit, tcam_mem, 
   2964                                                 ITAG_VALID_MASKf)) - 1;
   2965             
   2966         soc_mem_field32_set(unit, tcam_mem, ptr_entry, 
   2967                             ITAG_VALID_MASKf, mask_field);
   2968 
   2969         /* Set the inner VLAN priority field  */
   2970         mask_field = (1 << soc_mem_field_length(unit, tcam_mem, IPRI_MASKf)) - 1;
   2971 
   2972         vlan_pri = _BCM_SAT_VLAN_PRI_GET(ep_info_p->inner_vlan, mask_field);
   2973 
   2974         if (vlan_pri) {
   2975             soc_mem_field32_set(unit, tcam_mem, ptr_entry, IPRIf, vlan_pri);
   2976 
   2977             /* Set the inner VLAN priority mask field  */
   2978             soc_mem_field32_set(unit, tcam_mem, ptr_entry, 
   2979                                 IPRI_MASKf, mask_field);
   2980         }
   2981 
   2982 
   2983         /* Set the inner VLAN CFI field  */
   2984         mask_field = (1 << soc_mem_field_length(unit, tcam_mem, ICFI_MASKf)) - 1;
   2985 
   2986         vlan_cfi = _BCM_SAT_VLAN_CFI_GET(ep_info_p->inner_vlan, mask_field);
   2987 
   2988         if (vlan_cfi) {
   2989             soc_mem_field32_set(unit, tcam_mem, ptr_entry, ICFIf, vlan_cfi);
   2990 
   2991             /* Set the inner VLAN CFI mask field  */
   2992             soc_mem_field32_set(unit, tcam_mem, ptr_entry, 
   2993                                 ICFI_MASKf, mask_field);
   2994         }
   2995     }
   2996 
   2997     /* Configure OTAG valid and OTAG valid mask fields to hardware only if
   2998      * user flag to match outer VLAN is configured.
   2999      */
   3000     if (ep_info_p->flags & BCM_SAT_ENDPOINT_MATCH_OUTER_VLAN) {
   3001         
   3002         /* Set the outer VLAN valid field  */
   3003         mask_field = (1 << soc_mem_field_length(unit, tcam_mem, OVIDf)) - 1;
   3004         soc_mem_field32_set(unit, tcam_mem, ptr_entry, OVIDf, 
   3005                              (ep_info_p->outer_vlan & mask_field));
   3006 
   3007         /* Set the outer VLAN mask field  */
   3008         soc_mem_field32_set(unit, tcam_mem, ptr_entry,
   3009                             OVID_MASKf, mask_field);
   3010        
   3011         /* Set the outer TAG valid field  */
   3012         soc_mem_field32_set(unit, tcam_mem, ptr_entry, OTAG_VALIDf, 
   3013                 ((ep_info_p->flags & BCM_SAT_ENDPOINT_MATCH_OUTER_VLAN) ? 1 : 0));
   3014 
   3015         /* Set the outer TAG valid mask field  */
   3016         mask_field = (1 << soc_mem_field_length(unit, tcam_mem, 
   3017                                                 OTAG_VALID_MASKf)) - 1;
   3018             
   3019         soc_mem_field32_set(unit, tcam_mem, ptr_entry, 
   3020                             OTAG_VALID_MASKf, mask_field);
   3021 
   3022         /* Set the outer VLAN priority field  */
   3023         mask_field = (1 << soc_mem_field_length(unit, tcam_mem, OPRI_MASKf)) - 1;
   3024 
   3025         vlan_pri = _BCM_SAT_VLAN_PRI_GET(ep_info_p->outer_vlan, mask_field);
   3026 
   3027         if (vlan_pri) {
   3028             soc_mem_field32_set(unit, tcam_mem, ptr_entry, OPRIf, vlan_pri);
   3029 
   3030             /* Set the outer VLAN priority mask field  */
   3031             soc_mem_field32_set(unit, tcam_mem, ptr_entry, 
   3032                                 OPRI_MASKf, mask_field);
   3033         }
   3034 
   3035         /* Set the outer VLAN CFI field  */
   3036         mask_field = (1 << soc_mem_field_length(unit, tcam_mem, OCFI_MASKf)) - 1;
   3037         vlan_cfi = _BCM_SAT_VLAN_CFI_GET(ep_info_p->outer_vlan, mask_field);
   3038 
   3039         if (vlan_cfi) {
   3040             soc_mem_field32_set(unit, tcam_mem, ptr_entry, OCFIf, vlan_cfi);
   3041 
   3042             /* Set the outer VLAN CFI mask field  */
   3043             soc_mem_field32_set(unit, tcam_mem, ptr_entry, 
   3044                                 OCFI_MASKf, mask_field);
   3045         }
   3046     }
   3047 
   3048 
   3049     /* Set the VALID field  */ 
   3050     soc_mem_field32_set(unit, tcam_mem, ptr_entry, VALIDf, 
   3051                         BCM_SAT_TCAM_ENTRY_VALID);
   3052     if (ep_info_p->action_flags & BCM_SAT_ACTION_FWD_ACTION_REDIRECT) {   	
   3053         /* Store Egress SAT SAMP DATA fields */	
   3054         rv = _bcm_sb2_sat_resolve_dglp(unit, dglp, &olp_enable); 
   3055         if (BCM_FAILURE(rv)) {
   3056             /* DGLP resolve failed */;
   3057             LOG_ERROR(BSL_LS_BCM_SAT, 
   3058                     (BSL_META_U(unit,
   3059                                 "SAT(unit %d) Error: DGLP resolve for Endpoint EP=%d %s.\n"),
   3060                      unit, ep_info_p->ep_id, bcm_errmsg(rv)));
   3061         }
   3062     }
   3063     /* Set the OLP header add field  */
   3064     soc_mem_field32_set(unit, data_mem, ptr_dentry, ADD_OLP_HDRf,olp_enable); 
   3065 
   3066 	/* Set the Copy-to-CPU field  */
   3067     soc_mem_field32_set(unit, data_mem, ptr_dentry, COPYTO_CPUf, 
   3068            ((ep_info_p->action_flags & BCM_SAT_ACTION_COPY_TO_CPU ) ? 1 : 0));
   3069 						 
   3070     /* Store destination port */
   3071     soc_mem_field32_set(unit, data_mem, ptr_dentry, DESTINATIONf, dglp);
   3072 	
   3073 	/* Forward action for the SAT packet is to drop */
   3074     if(ep_info_p->action_flags & BCM_SAT_ACTION_FWD_ACTION_DROP ) {
   3075           fwd_action = 0;
   3076     }	
   3077 	/* Forward action for the SAT packet is redirect to DGLP port */
   3078     else if(ep_info_p->action_flags & BCM_SAT_ACTION_FWD_ACTION_REDIRECT ) {
   3079           fwd_action = 1;
   3080     }	
   3081 	/* Forward action for the SAT packet is perform */
   3082 	else if(ep_info_p->action_flags & BCM_SAT_ACTION_FWD_ACTION_LLF ) {
   3083           fwd_action = 2;
   3084     }
   3085 	
   3086 	/* Store forward action field */
   3087     soc_mem_field32_set(unit, data_mem, ptr_dentry, 
   3088                                        FORWARD_ACTIONf,fwd_action);
   3089 
   3090 	/* Store INT_PRI */
   3091     mask_field = (1 << soc_mem_field_length(unit, data_mem, 
   3092                                             INT_PRIf)) - 1;
   3093     soc_mem_field32_set(unit, data_mem, ptr_dentry, INT_PRIf, 
   3094                                        ep_info_p->pkt_pri & mask_field);
   3095 	
   3096     /* Sample time stamp into the OLP header field  */
   3097     soc_mem_field32_set(unit, data_mem, ptr_dentry, SAMPLE_TIMESTAMPf, 
   3098        ((ep_info_p->action_flags & BCM_SAT_ACTION_SAMPLE_TIMESTAMP ) ? 1 : 0));
   3099 			
   3100 
   3101 	/* Set OLP header type compressed field OLP_HDR_TYPE_COMPRESSEDf */ 
   3102     if (ep_info_p->flags & BCM_SAT_ENDPOINT_DOWNMEP) {
   3103         mask_field = (1 << soc_mem_field_length(unit, data_mem, 
   3104                                                 OLP_HDR_TYPE_COMPRESSEDf)) - 1;
   3105         soc_mem_field32_set(unit, data_mem, ptr_dentry, OLP_HDR_TYPE_COMPRESSEDf, 
   3106                             BCM_SAT_DOWNMEP_OLP_HDR_COMPRESSED & mask_field);			
   3107     }
   3108     else if (ep_info_p->flags & BCM_SAT_ENDPOINT_UPMEP) {
   3109         mask_field = (1 << soc_mem_field_length(unit, data_mem, 
   3110                                                 OLP_HDR_TYPE_COMPRESSEDf)) - 1;
   3111         soc_mem_field32_set(unit, data_mem, ptr_dentry, OLP_HDR_TYPE_COMPRESSEDf, 
   3112                             BCM_SAT_UPMEP_OLP_HDR_COMPRESSED & mask_field);			
   3113     }
   3114 
   3115 	
   3116     /* Store Session ID field  */
   3117     soc_mem_field32_set(unit, data_mem, ptr_dentry, 
   3118                                        SAT_SESSION_IDf,ep_info_p->session_id);
   3119 
   3120     /* Set Time stamp type field  */
   3121     soc_mem_field32_set(unit, data_mem, ptr_dentry, TIMESTAMP_TYPEf, 
   3122                                        ep_info_p->timestamp_format);
   3123 	
   3124 
   3125     if (ep_info_p->flags & BCM_SAT_ENDPOINT_UPMEP) {
   3126         /* Write entry to hardware EGR_SAT_SAMP_TCAM table. */
   3127         SOC_IF_ERROR_RETURN
   3128             (WRITE_EGR_SAT_SAMP_TCAMm(unit, MEM_BLOCK_ALL, 
   3129             ep_info_p->ep_id, ptr_entry));
   3130 
   3131         /* Write entry to hardware EGR_SAT_SAMP_TCAM table. */
   3132         SOC_IF_ERROR_RETURN
   3133             (WRITE_EGR_SAT_SAMP_DATAm(unit, MEM_BLOCK_ALL, 
   3134             ep_info_p->ep_id, ptr_dentry));
   3135     }
   3136     else  if (ep_info_p->flags & BCM_SAT_ENDPOINT_DOWNMEP) {
   3137         /* Write entry to hardware ING_SAT_SAMP_TCAM table. */
   3138         SOC_IF_ERROR_RETURN
   3139             (WRITE_ING_SAT_SAMP_TCAMm(unit, MEM_BLOCK_ALL, 
   3140             ep_info_p->ep_id, ptr_entry));
   3141 
   3142         /* Write entry to hardware ING_SAT_SAMP_TCAM table. */
   3143         SOC_IF_ERROR_RETURN
   3144             (WRITE_ING_SAT_SAMP_DATAm(unit, MEM_BLOCK_ALL, 
   3145             ep_info_p->ep_id, ptr_dentry));
   3146     }
   3147     else
   3148     {
   3149         return (BCM_E_PARAM);
   3150     }
   3151     
   3152     /* For SAT-UPSAMP processing EGR_SAT_SAMP_DATA_1 Contains OLP-HDR related items.
   3153      * This is a shadow table of the original EGR_SAT_SAMP_DATA table and
   3154      *  stores only a subset of fields.Looked up only in Pass-B */
   3155     if (ep_info_p->flags & BCM_SAT_ENDPOINT_UPMEP) {
   3156 
   3157         data_mem = EGR_SAT_SAMP_DATA_1m;
   3158         ptr_d_1entry = &egr_d_1entry;
   3159 
   3160         /* Store Session ID field  */
   3161         soc_mem_field32_set(unit, data_mem, ptr_d_1entry, 
   3162                                        SAT_SESSION_IDf,ep_info_p->session_id);
   3163 
   3164         /* Set Time stamp type field  */
   3165         soc_mem_field32_set(unit, data_mem, ptr_d_1entry, TIMESTAMP_TYPEf, 
   3166                                        ep_info_p->timestamp_format);
   3167         /* Sample time stamp into the OLP header field  */
   3168         soc_mem_field32_set(unit, data_mem, ptr_d_1entry, SAMPLE_TIMESTAMPf, 
   3169             ((ep_info_p->action_flags & BCM_SAT_ACTION_SAMPLE_TIMESTAMP ) ? 1 : 0));
   3170 
   3171         /* Set OLP header type compressed field OLP_HDR_TYPE_COMPRESSEDf */ 
   3172         mask_field = (1 << soc_mem_field_length(unit, data_mem, 
   3173                                                 OLP_HDR_TYPE_COMPRESSEDf)) - 1;
   3174         soc_mem_field32_set(unit, data_mem, ptr_d_1entry, OLP_HDR_TYPE_COMPRESSEDf, 
   3175                             BCM_SAT_UPMEP_OLP_HDR_COMPRESSED & mask_field);			
   3176 
   3177         /* Set the OLP header add field  */
   3178         soc_mem_field32_set(unit, data_mem, ptr_d_1entry, ADD_OLP_HDRf,olp_enable); 
   3179 
   3180         /* Write entry to hardware EGR_SAT_SAMP_DATA_1 table. */
   3181         SOC_IF_ERROR_RETURN
   3182             (WRITE_EGR_SAT_SAMP_DATA_1m(unit, MEM_BLOCK_ALL, 
   3183             ep_info_p->ep_id, ptr_d_1entry));
   3184 
   3185    }
   3186     return (BCM_E_NONE);
   3187 }
   3188 
   3189 /*
   3190  * Function:
   3191  *     _bcm_sb2_sat_endpoint_hw_delete
   3192  * Purpose:
   3193  *     Delete a UP-MEP/DOWNMEP endpoint from hardware table.
   3194  * Parameters:
   3195  *     unit      - (IN) BCM device number
   3196  *     h_data_p  - (IN) Pointer to endpoint hash data
   3197  * Retruns:
   3198  *     BCM_E_XXX
   3199  */
   3200 STATIC int
   3201 _bcm_sb2_sat_endpoint_hw_delete(int unit, _bcm_sat_hash_data_t *h_data_p)
   3202 {
   3203 
   3204     ing_sat_samp_tcam_entry_t      ing_entry; /* DOWNMEP SAMP TCAM  entry.   */
   3205     ing_sat_samp_data_entry_t      ing_dentry; /* DOWNMEP SAMP Data entry.   */
   3206 
   3207     egr_sat_samp_tcam_entry_t      egr_entry; /* UPMEP SAMP TCAM  entry.   */
   3208     egr_sat_samp_data_entry_t      egr_dentry; /* UPMEP SAMP Data entry.   */
   3209     egr_sat_samp_data_1_entry_t      egr_d_1entry; /* UPMEP SAMP Data_1 entry.   */
   3210 
   3211 	int  rv = BCM_E_NONE; /* Operation return status.     */
   3212 
   3213 	if (h_data_p->ep_info.flags & BCM_SAT_ENDPOINT_UPMEP) {
   3214 
   3215         /* Clear UP-MEP table entry for this endpoint index. */
   3216         sal_memset(&egr_entry, 0, sizeof(egr_sat_samp_tcam_entry_t));
   3217         
   3218         rv = WRITE_EGR_SAT_SAMP_TCAMm(unit, MEM_BLOCK_ALL, 
   3219                                       h_data_p->ep_info.ep_id, &egr_entry);
   3220         if (BCM_FAILURE(rv)) {
   3221             LOG_ERROR(BSL_LS_BCM_SAT, 
   3222                       (BSL_META_U(unit,
   3223                   "SAT(unit %d) Error: EGR SAT SAMP TCAM write index=%x (EP=%d)"\
   3224                   " - %s.\n"), unit, h_data_p->ep_info.ep_id,
   3225                   h_data_p->ep_info.ep_id, bcm_errmsg(rv)));
   3226             return (rv);
   3227         }
   3228         
   3229         sal_memset(&egr_dentry, 0, sizeof(egr_sat_samp_data_entry_t));
   3230         rv = WRITE_EGR_SAT_SAMP_DATAm(unit, MEM_BLOCK_ALL, 
   3231                                       h_data_p->ep_info.ep_id, &egr_dentry);
   3232         if (BCM_FAILURE(rv)) {
   3233             LOG_ERROR(BSL_LS_BCM_SAT, 
   3234                       (BSL_META_U(unit,
   3235              "SAT(unit %d) Error: EGR SAT SAMP Data table write index=%x (EP=%d)"\
   3236                       " - %s.\n"), unit, h_data_p->ep_info.ep_id,
   3237                       h_data_p->ep_info.ep_id, bcm_errmsg(rv)));
   3238             return (rv);
   3239         }
   3240         /* Need to delete the EGR_SAT_SAMP_DATA_1 also */
   3241         sal_memset(&egr_d_1entry, 0, sizeof(egr_sat_samp_data_1_entry_t));
   3242         rv = WRITE_EGR_SAT_SAMP_DATA_1m(unit, MEM_BLOCK_ALL, 
   3243                                         h_data_p->ep_info.ep_id, &egr_d_1entry);
   3244         if (BCM_FAILURE(rv)) {
   3245             LOG_ERROR(BSL_LS_BCM_SAT, 
   3246                       (BSL_META_U(unit,
   3247              "SAT(unit %d) Error: EGR SAT SAMP Data_1 table write index=%x (EP=%d)"\
   3248                       " - %s.\n"), unit, h_data_p->ep_info.ep_id,
   3249                       h_data_p->ep_info.ep_id, bcm_errmsg(rv)));
   3250             return (rv);
   3251         }
   3252 
   3253     }
   3254     
   3255     else if (h_data_p->ep_info.flags & BCM_SAT_ENDPOINT_DOWNMEP) {
   3256         
   3257         /* Clear DOWN-MEP table entry for this endpoint index. */
   3258         sal_memset(&ing_entry, 0, sizeof(egr_sat_samp_tcam_entry_t));
   3259         
   3260         rv = WRITE_ING_SAT_SAMP_TCAMm(unit, MEM_BLOCK_ALL, 
   3261                                       h_data_p->ep_info.ep_id, &ing_entry);
   3262         if (BCM_FAILURE(rv)) {
   3263             LOG_ERROR(BSL_LS_BCM_SAT, 
   3264                       (BSL_META_U(unit,
   3265                   "SAT(unit %d) Error: ING SAT SAMP TCAM write index=%x (EP=%d)"\
   3266                   " - %s.\n"), unit, h_data_p->ep_info.ep_id,
   3267                   h_data_p->ep_info.ep_id, bcm_errmsg(rv)));
   3268             return (rv);
   3269         }
   3270         
   3271         sal_memset(&ing_dentry, 0, sizeof(egr_sat_samp_data_entry_t));
   3272         rv = WRITE_ING_SAT_SAMP_DATAm(unit, MEM_BLOCK_ALL, 
   3273                                       h_data_p->ep_info.ep_id, &ing_dentry);
   3274         if (BCM_FAILURE(rv)) {
   3275             LOG_ERROR(BSL_LS_BCM_SAT, 
   3276                       (BSL_META_U(unit,
   3277              "SAT(unit %d) Error: ING SAT SAMP Data table write index=%x (EP=%d)"\
   3278                       " - %s.\n"), unit, h_data_p->ep_info.ep_id,
   3279                       h_data_p->ep_info.ep_id, bcm_errmsg(rv)));
   3280             return (rv);
   3281         }
   3282     }
   3283     else
   3284     {
   3285         return (BCM_E_PARAM);
   3286     }
   3287 	
   3288 	return rv;
   3289 }
   3290 
   3291 /*
   3292  * Function:
   3293  *     bcm_sb2_sat_oamp_enable_get
   3294  * Purpose:
   3295  *     Get OAMP enable status
   3296  * Parameters:
   3297  *     unit          - (IN) BCM device number
   3298  *     enable        - (OUT) status.
   3299  * Returns:
   3300  *      BCM_E_XXX
   3301  */
   3302 int
   3303 bcm_sb2_sat_oamp_enable_get(int unit, int *enable)
   3304 {
   3305     int     rv = BCM_E_NONE;
   3306     uint32  rval;
   3307 
   3308     BCM_IF_ERROR_RETURN(READ_OAMP_ENABLEr(unit, &rval));
   3309     *enable = soc_reg_field_get(unit, OAMP_ENABLEr, rval, ENABLEf);
   3310 
   3311     return rv;
   3312 }
   3313 
   3314 /*
   3315  * Function:
   3316  *     bcm_sb2_sat_oamp_enable_set
   3317  * Purpose:
   3318  *     Enable or disable OAMP function
   3319  * Parameters:
   3320  *     unit          - (IN) BCM device number
   3321  *     enable        - (IN) zero - disable; Not zero - enable.
   3322  * Returns:
   3323  *      BCM_E_XXX
   3324  */
   3325 int
   3326 bcm_sb2_sat_oamp_enable_set(int unit, int enable)
   3327 {
   3328     int rv = SOC_E_NONE;
   3329     uint32 reg_val;
   3330     uint32 fld_val;
   3331     uint32 mem_entry[SOC_MAX_MEM_WORDS];
   3332     uint32 fld_val_above_64[SOC_MAX_MEM_WORDS];
   3333     int rd_ptr, wr_ptr;
   3334     soc_timeout_t to;
   3335     int timeout_usec;
   3336 
   3337     if (enable) {
   3338         fld_val = 1;
   3339         rv = READ_OAMP_ENABLEr(unit, &reg_val);
   3340         if (SOC_FAILURE(rv)) {
   3341             LOG_ERROR(BSL_LS_BCM_SAT,
   3342                       (BSL_META_U(unit,
   3343                                   "%s\n"), soc_errmsg(rv)));
   3344             return rv;
   3345         }
   3346 
   3347         soc_reg_field_set(unit, OAMP_ENABLEr, &reg_val, ENABLEf, fld_val);
   3348         rv = WRITE_OAMP_ENABLEr(unit, reg_val);
   3349         if (SOC_FAILURE(rv)) {
   3350             LOG_ERROR(BSL_LS_BCM_SAT,
   3351                       (BSL_META_U(unit,
   3352                                   "%s\n"), soc_errmsg(rv)));
   3353             return rv;
   3354         }
   3355 
   3356         /* 
   3357          * Setting OLP RX header to DUNE RX header mapping
   3358  */
   3359         rv = READ_EGR_OAMP_CONTROLr(unit, &reg_val);
   3360         if (SOC_FAILURE(rv)) {
   3361             LOG_ERROR(BSL_LS_BCM_SAT,
   3362                       (BSL_META_U(unit,
   3363                                   "%s\n"), soc_errmsg(rv)));
   3364             return rv;
   3365         }
   3366         fld_val = 1;
   3367         soc_reg_field_set(unit, EGR_OAMP_CONTROLr, &reg_val, OAMP_ENCAP_ENABLEf, fld_val);
   3368         fld_val = 0;
   3369         soc_reg_field_set(unit, EGR_OAMP_CONTROLr, &reg_val, TOD_SAMPLE_MODEf, fld_val);
   3370         fld_val = _BCM_SB2_SAT_OAMP_PHY_PORT_NUMBER;
   3371         soc_reg_field_set(unit, EGR_OAMP_CONTROLr, &reg_val, OAMP_PHY_PORT_NUMBERf, fld_val);
   3372         fld_val = 0xf;
   3373         soc_reg_field_set(unit, EGR_OAMP_CONTROLr, &reg_val, DOWN_SAT_SUBTYPEf, fld_val);
   3374         fld_val = 0x15;
   3375         soc_reg_field_set(unit, EGR_OAMP_CONTROLr, &reg_val, UP_SAT_SUBTYPEf, fld_val);
   3376         rv = WRITE_EGR_OAMP_CONTROLr(unit, reg_val);
   3377         if (SOC_FAILURE(rv)) {
   3378             LOG_ERROR(BSL_LS_BCM_SAT,
   3379                       (BSL_META_U(unit,
   3380                                   "%s\n"), soc_errmsg(rv)));
   3381             return rv;
   3382         }
   3383 
   3384         /* The register has 1 field, the value should be 0x00000000000f000000000000000000170000000000000000000000000000 when SAT is enabled */
   3385         sal_memset(fld_val_above_64, 0, sizeof(fld_val_above_64));
   3386         fld_val_above_64[0] = 0x0;
   3387         fld_val_above_64[1] = 0x0;
   3388         fld_val_above_64[2] = 0x0;
   3389         fld_val_above_64[3] = 0x170000;
   3390         fld_val_above_64[4] = 0x0;
   3391         fld_val_above_64[5] = 0x0;
   3392         fld_val_above_64[6] = 0xf;
   3393         fld_val_above_64[7] = 0x0;
   3394         soc_mem_field_set(unit, EGR_DNX_HEADERm, mem_entry, HDR_DEFAULT_VALUEf, fld_val_above_64); 
   3395         rv = WRITE_EGR_DNX_HEADERm(unit, MEM_BLOCK_ALL, 0, mem_entry);
   3396         if (SOC_FAILURE(rv)) {
   3397             LOG_ERROR(BSL_LS_BCM_SAT,
   3398                       (BSL_META_U(unit,
   3399                                   "%s\n"), soc_errmsg(rv)));
   3400             return rv;
   3401         }
   3402 
   3403         /* 
   3404          * Setting OAMP programmable editor 
   3405          * Every SAT packet sent by the SAT engine goes through the programmable editor
   3406          */
   3407         rv = READ_OAMP_PE_INSTr(unit, &reg_val);
   3408         if (SOC_FAILURE(rv)) {
   3409             LOG_ERROR(BSL_LS_BCM_SAT,
   3410                       (BSL_META_U(unit,
   3411                                   "%s\n"), soc_errmsg(rv)));
   3412             return rv;
   3413         }
   3414 
   3415         fld_val = 0;
   3416         soc_reg_field_set(unit, OAMP_PE_INSTr, &reg_val, PE_DEFAULT_INSTRUCTIONf, fld_val);
   3417         fld_val = 0x1000;
   3418         soc_reg_field_set(unit, OAMP_PE_INSTr, &reg_val, MAX_INSTR_COUNTf, fld_val);
   3419 
   3420         rv = WRITE_OAMP_PE_INSTr(unit, reg_val);
   3421         if (SOC_FAILURE(rv)) {
   3422             LOG_ERROR(BSL_LS_BCM_SAT,
   3423                       (BSL_META_U(unit,
   3424                                   "%s\n"), soc_errmsg(rv)));
   3425             return rv;
   3426         }
   3427 
   3428         rv = READ_OAMP_PE_0_PROG_TCAMm(unit, MEM_BLOCK_ALL, 0, mem_entry);
   3429         if (SOC_FAILURE(rv)) {
   3430             LOG_ERROR(BSL_LS_BCM_SAT,
   3431                       (BSL_META_U(unit,
   3432                                   "%s\n"), soc_errmsg(rv)));
   3433             return rv;
   3434         }
   3435 
   3436         fld_val = 0x0;
   3437         soc_mem_field32_set(unit, OAMP_PE_0_PROG_TCAMm, mem_entry, DATf, fld_val); 
   3438         soc_mem_field32_set(unit, OAMP_PE_0_PROG_TCAMm, mem_entry, KEYf, fld_val); 
   3439         fld_val = 0x7fffff;
   3440         soc_mem_field32_set(unit, OAMP_PE_0_PROG_TCAMm, mem_entry, MASKf, fld_val); 
   3441         fld_val = 0x1;
   3442         soc_mem_field32_set(unit, OAMP_PE_0_PROG_TCAMm, mem_entry, VALIDf, fld_val); 
   3443 
   3444         rv = WRITE_OAMP_PE_0_PROG_TCAMm(unit, MEM_BLOCK_ALL, 0, mem_entry);
   3445         if (SOC_FAILURE(rv)) {
   3446             LOG_ERROR(BSL_LS_BCM_SAT,
   3447                       (BSL_META_U(unit,
   3448                                   "%s\n"), soc_errmsg(rv)));
   3449             return rv;
   3450         }
   3451 
   3452         rv = READ_OAMP_PE_1_PROG_TCAMm(unit, MEM_BLOCK_ALL, 0, mem_entry);
   3453         if (SOC_FAILURE(rv)) {
   3454             LOG_ERROR(BSL_LS_BCM_SAT,
   3455                       (BSL_META_U(unit,
   3456                                   "%s\n"), soc_errmsg(rv)));
   3457             return rv;
   3458         }
   3459 
   3460         fld_val = 0x0;
   3461         soc_mem_field32_set(unit, OAMP_PE_1_PROG_TCAMm, mem_entry, DATf, fld_val); 
   3462         soc_mem_field32_set(unit, OAMP_PE_1_PROG_TCAMm, mem_entry, KEYf, fld_val); 
   3463         fld_val = 0x7fffff;
   3464         soc_mem_field32_set(unit, OAMP_PE_1_PROG_TCAMm, mem_entry, MASKf, fld_val); 
   3465         fld_val = 0x1;
   3466         soc_mem_field32_set(unit, OAMP_PE_1_PROG_TCAMm, mem_entry, VALIDf, fld_val); 
   3467 
   3468         rv = WRITE_OAMP_PE_1_PROG_TCAMm(unit, MEM_BLOCK_ALL, 0, mem_entry);
   3469         if (SOC_FAILURE(rv)) {
   3470             LOG_ERROR(BSL_LS_BCM_SAT,
   3471                       (BSL_META_U(unit,
   3472                                   "%s\n"), soc_errmsg(rv)));
   3473             return rv;
   3474         }
   3475 
   3476         rv = READ_OAMP_PE_PROGRAMm(unit, MEM_BLOCK_ALL, 0, mem_entry);
   3477         if (SOC_FAILURE(rv)) {
   3478             LOG_ERROR(BSL_LS_BCM_SAT,
   3479                       (BSL_META_U(unit,
   3480                                   "%s\n"), soc_errmsg(rv)));
   3481             return rv;
   3482         }
   3483 
   3484         fld_val_above_64[0] = 0x7e56a377;
   3485         fld_val_above_64[1] = 0x280008ae;
   3486         fld_val_above_64[2] = 0x7;
   3487         soc_mem_field_set(unit, OAMP_PE_PROGRAMm, mem_entry, PROG_DATAf, fld_val_above_64); 
   3488 
   3489         rv = WRITE_OAMP_PE_PROGRAMm(unit, MEM_BLOCK_ALL, 0, mem_entry);
   3490         if (SOC_FAILURE(rv)) {
   3491             LOG_ERROR(BSL_LS_BCM_SAT,
   3492                       (BSL_META_U(unit,
   3493                                   "%s\n"), soc_errmsg(rv)));
   3494             return rv;
   3495         }
   3496     } else {
   3497         /* OAMP disable */
   3498         /* 1. Disable redirection to OAMP and DNX header encap */
   3499         SOC_IF_ERROR_RETURN(READ_EGR_OAMP_CONTROLr(unit, &reg_val));
   3500         soc_reg_field_set(unit, EGR_OAMP_CONTROLr, &reg_val, OAMP_ENCAP_ENABLEf, 0);
   3501         SOC_IF_ERROR_RETURN(WRITE_EGR_OAMP_CONTROLr(unit, reg_val));
   3502 
   3503         /* 2. Wait for SAT TX and RX flush */
   3504         if (SAL_BOOT_SIMULATION) {
   3505             timeout_usec = 10000000; /* Simulation - 10sec */
   3506         } else {
   3507             timeout_usec = 50000;
   3508         }
   3509 
   3510         soc_timeout_init(&to, timeout_usec, 0);
   3511         do {
   3512             SOC_IF_ERROR_RETURN(READ_IARB_CELL_DEBUGr(unit, &reg_val));
   3513             rd_ptr = soc_reg_field_get(unit, IARB_CELL_DEBUGr, reg_val,
   3514                     FIFO_RD_PTRf);
   3515             wr_ptr = soc_reg_field_get(unit, IARB_CELL_DEBUGr, reg_val,
   3516                     FIFO_WR_PTRf);
   3517             if (rd_ptr == wr_ptr) {
   3518                 break;
   3519             }
   3520             if (soc_timeout_check(&to)) {
   3521                 LOG_ERROR(BSL_LS_BCM_SAT,
   3522                         (BSL_META_U(unit,"SAT TX Flush Failed\n")));
   3523                 return SOC_E_TIMEOUT;
   3524             }
   3525         }while (TRUE);
   3526 
   3527         soc_timeout_init(&to, timeout_usec, 0);
   3528         do {
   3529             SOC_IF_ERROR_RETURN(READ_EGR_EDBIL_STATUSr(unit, &reg_val));
   3530             rd_ptr = soc_reg_field_get(unit, EGR_EDBIL_STATUSr, reg_val,
   3531                     READ_PTRf);
   3532             wr_ptr = soc_reg_field_get(unit, EGR_EDBIL_STATUSr, reg_val,
   3533                     WR_PTRf);
   3534 
   3535             /* Check : READ_PTR[4:2] == WR_PTR && READ_PTR[0:1] == 0 */
   3536             if ((((rd_ptr & 0x1C) >> 2) == wr_ptr) && ((rd_ptr & 0x3) == 0)) {
   3537                 break;
   3538             }
   3539             if (soc_timeout_check(&to)) {
   3540                 LOG_ERROR(BSL_LS_BCM_SAT,
   3541                         (BSL_META_U(unit,"SAT RX Flush Failed\n")));
   3542                 return SOC_E_TIMEOUT;
   3543             }
   3544         }while (TRUE);
   3545 
   3546         /* 3. Disable OAMP */
   3547         SOC_IF_ERROR_RETURN(READ_OAMP_ENABLEr(unit, &reg_val));
   3548         soc_reg_field_set(unit, OAMP_ENABLEr, &reg_val, ENABLEf, 0);
   3549         SOC_IF_ERROR_RETURN(WRITE_OAMP_ENABLEr(unit, reg_val));
   3550     }
   3551     /* 
   3552      * Setting OAMP programmable editor 
   3553      * Every SAT packet sent by the SAT engine goes through the programmable editor
   3554      */
   3555 
   3556     return (rv);
   3557 }
   3558 
   3559 /*
   3560  * Function:
   3561  *     bcm_sb2_sat_tod_set
   3562  * Purpose:
   3563  *     Set RX timestamp format
   3564  * Parameters:
   3565  *     unit          - (IN) BCM device number
   3566  *     ts_format     - (IN) NTP - bcmSATTimestampFormatNTP; 1588 - bcmSATTimestampFormatIEEE1588v1.
   3567  * Returns:
   3568  *      BCM_E_XXX
   3569  */
   3570 int
   3571 bcm_sb2_sat_ts_format_set(int unit, int ts_format)
   3572 {
   3573     int rv = SOC_E_NONE;
   3574     uint32 reg_val;
   3575     uint32 fld_val;
   3576 
   3577     /*
   3578      * TOD_SAMPLE_MODE - value "1" (PTP) or "2" (NTP). 
   3579      */
   3580 
   3581     fld_val = (ts_format == bcmSATTimestampFormatNTP ? 2 : 1);
   3582     rv = READ_EGR_OAMP_CONTROLr(unit, &reg_val);
   3583     if (SOC_FAILURE(rv)) {
   3584         LOG_ERROR(BSL_LS_BCM_SAT,
   3585                   (BSL_META_U(unit,
   3586                               "%s\n"), soc_errmsg(rv)));
   3587         return rv;
   3588     }
   3589 
   3590     soc_reg_field_set(unit, EGR_OAMP_CONTROLr, &reg_val, TOD_SAMPLE_MODEf, fld_val);
   3591     rv = WRITE_EGR_OAMP_CONTROLr(unit, reg_val);
   3592     if (SOC_FAILURE(rv)) {
   3593         LOG_ERROR(BSL_LS_BCM_SAT,
   3594                   (BSL_META_U(unit,
   3595                               "%s\n"), soc_errmsg(rv)));
   3596         return rv;
   3597     }
   3598 
   3599     return (rv);
   3600 }
   3601 
   3602 /*
   3603  * Function:
   3604  *     bcm_sb2_sat_ctf_report_process
   3605  * Purpose:
   3606  *     Process CTF report message and call registered function
   3607  * Parameters:
   3608  *     unit   - (IN) BCM device number
   3609  *     cb     - (IN) Registered callback function
   3610  *     cookie - (IN) User data
   3611  * Returns:
   3612  *     BCM_E_XXX
   3613  */
   3614 int
   3615 bcm_sb2_sat_ctf_report_process(int unit, bcm_sat_event_cb cb, void *cookie)
   3616 {
   3617     uint32 msg_start_bit = 0, msg_word = 0;
   3618     uint32 empty_fifo_value = 0xffffffff;
   3619     uint32 field_32;
   3620     soc_reg_above_64_val_t data;
   3621     soc_reg_above_64_val_t msg;
   3622     bcm_sat_report_event_data_t report;
   3623     bcm_sat_event_type_t type = bcmSATEventReport;
   3624 
   3625     /* Process report message */
   3626     BCM_IF_ERROR_RETURN(READ_OAMP_STAT_INTERRUPT_MESSAGEr(unit, data));
   3627     soc_reg_above_64_field_get(unit, OAMP_STAT_INTERRUPT_MESSAGEr, data,
   3628                                STAT_INTERRUPT_MESSAGEf, msg);
   3629     while (msg[msg_word] != empty_fifo_value) {
   3630         msg_start_bit = msg_word * 32;
   3631         field_32 = 0;
   3632         SHR_BITCOPY_RANGE(&field_32, 0, msg, msg_start_bit, 5);
   3633         report.ctf_id = field_32;
   3634         field_32 = 0;
   3635         SHR_BITCOPY_RANGE(&field_32, 0, msg, msg_start_bit+14, 1);
   3636         if (field_32) {
   3637             field_32 = 0;
   3638             SHR_BITCOPY_RANGE(&field_32, 0, msg, msg_start_bit+32, 32);
   3639             report.delay = field_32;
   3640             report.delay_valid = 1;
   3641         } else {
   3642             report.delay_valid = 0;
   3643         }
   3644         field_32 = 0;
   3645         SHR_BITCOPY_RANGE(&field_32, 0, msg, msg_start_bit+15, 1);
   3646         if (field_32) {
   3647             field_32 = 0;
   3648             if (report.delay_valid) {
   3649                 SHR_BITCOPY_RANGE(&field_32, 0, msg, msg_start_bit+64, 32);
   3650             } else {
   3651                 SHR_BITCOPY_RANGE(&field_32, 0, msg, msg_start_bit+32, 32);
   3652             }
   3653             report.sequence_number = field_32;
   3654             report.sequence_number_valid = 1;
   3655         } else {
   3656             report.sequence_number_valid = 0;
   3657         }
   3658         field_32 = 0;
   3659         SHR_BITCOPY_RANGE(&field_32, 0, msg, msg_start_bit+16, 4);
   3660         msg_word += field_32;
   3661 
   3662         if (cb != NULL) {
   3663             (void)cb(unit, type, (void *)&report, cookie);
   3664         }
   3665     }
   3666 
   3667     return BCM_E_NONE;
   3668 }
   3669 
   3670 int bcm_sb2_sat_init_check(int unit)
   3671 {
   3672     /* Check whether the SAT module is initialized */
   3673     _BCM_SAT_IS_INIT(unit);
   3674 
   3675     return SOC_E_NONE;
   3676 
   3677 }
   3678 
   3679 #endif /* BCM_SABER2_SUPPORT */