openbcm

Git mirror of https://github.com/Broadcom-Network-Switching-Software/OpenBCM
git clone git://git.finwo.net/mirror/broadcom/openbcm
Log | Files | Refs | README

field_class.c (190545B)


      1 /*
      2  * 
      3  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      4  * 
      5  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      6  *
      7  * File:       field_class.c
      8  * Purpose:    BCM56960 Field Processor Group management functions.
      9  */
     10 
     11 #include <soc/defs.h>
     12 #if defined(BCM_TOMAHAWK_SUPPORT) && defined(BCM_FIELD_SUPPORT)
     13 #include <shared/bsl.h>
     14 #include <soc/mem.h>
     15 #include <soc/drv.h>
     16 #include <bcm_int/esw/tomahawk.h>
     17 
     18 #if defined(BCM_TOMAHAWK3_SUPPORT)
     19 #include <bcm_int/esw/tomahawk3.h>
     20 #endif
     21 
     22 #include <bcm/field.h>
     23 #include <bcm_int/esw/field.h>
     24 
     25 /* Local functions prototypes. */
     26 STATIC int
     27 _field_th_class_group_validate(int unit,
     28                                _field_group_t *fg);
     29 STATIC int
     30 _field_th_class_group_sort(int unit,
     31                            _field_group_t *fg,
     32                            _field_class_type_t ctype);
     33 STATIC void
     34 _field_th_class_entry_key_show(int unit,
     35                                    _field_entry_t *class_ent,
     36                                    _field_class_type_t ctype,
     37                                    uint32 *cdata);
     38 STATIC int
     39 _field_th_class_hwindex_get(int unit,
     40                             _field_entry_t *entry,
     41                             _field_class_type_t ctype,
     42                             int *hw_index);
     43 STATIC int
     44 _field_th_class_ethertype_install(int unit,
     45                                   _field_entry_t *entry);
     46 STATIC int
     47 _field_th_class_ethertype_read(int unit,
     48                                _field_entry_t *entry,
     49                                uint32 *databuf);
     50 STATIC int
     51 _field_th_class_l4srcport_install(int unit,
     52                                   _field_entry_t *entry);
     53 STATIC int
     54 _field_th_class_l4srcport_read(int unit,
     55                                _field_entry_t *entry,
     56                                uint32 *databuf);
     57 STATIC int
     58 _field_th_class_l4dstport_install(int unit,
     59                                   _field_entry_t *entry);
     60 STATIC int
     61 _field_th_class_l4dstport_read(int unit,
     62                                _field_entry_t *entry,
     63                                uint32 *databuf);
     64 STATIC int
     65 _field_th_class_srccompression_install(int unit,
     66                                        _field_entry_t *entry);
     67 STATIC int
     68  _field_th_class_srccompression_read(int unit,
     69                                      _field_entry_t *entry,
     70                                      uint32 *databuf);
     71 STATIC int
     72 _field_th_class_dstcompression_install(int unit,
     73                                        _field_entry_t *entry);
     74 STATIC int
     75 _field_th_class_dstcompression_read(int unit,
     76                                     _field_entry_t *entry,
     77                                     uint32 *databuf);
     78 STATIC int
     79 _field_th_class_ttl_install(int unit,
     80                             _field_entry_t *entry);
     81 STATIC int
     82 _field_th_class_ttl_read(int unit,
     83                          _field_entry_t *entry,
     84                          uint32 *databuf);
     85 STATIC int
     86 _field_th_class_tos_install(int unit,
     87                             _field_entry_t *entry);
     88 STATIC int
     89 _field_th_class_tos_read(int unit,
     90                          _field_entry_t *entry,
     91                          uint32 *databuf);
     92 STATIC int
     93 _field_th_class_ipproto_install(int unit,
     94                                 _field_entry_t *entry);
     95 STATIC int
     96 _field_th_class_ipproto_read(int unit,
     97                              _field_entry_t *entry,
     98                              uint32 *databuf);
     99 STATIC int
    100 _field_th_class_tcp_install(int unit,
    101                             _field_entry_t *entry);
    102 STATIC int
    103 _field_th_class_tcp_read(int unit,
    104                          _field_entry_t *entry,
    105                          uint32 *databuf);
    106 
    107 STATIC int
    108 _field_th_class_iptunnelttl_install(int unit,
    109                             _field_entry_t *entry);
    110 STATIC int
    111 _field_th_class_iptunnelttl_read(int unit,
    112                          _field_entry_t *entry,
    113                          uint32 *databuf);
    114 
    115 /*
    116  * Function:
    117  *    _bcm_field_th_class_type_qset_get
    118  * Purpose:
    119  *    Get Field Class Type from qset.
    120  * Parameters:
    121  *     unit     - (IN) BCM device number.
    122  *     qset     - (IN) Field Qualifier Set.
    123  *     ctype    - (OUT) Field Class type.
    124  * Returns:
    125  *     BCM_E_XXX
    126  * Notes:
    127  *     This api assumes that only valid set of qset is passed
    128  *     for class type.
    129  */
    130 int
    131 _bcm_field_th_class_type_qset_get(int unit, bcm_field_qset_t *qset,
    132                                             _field_class_type_t *ctype)
    133 {
    134     int rv = BCM_E_NONE;    /* Operation Return Status */
    135 
    136     /* Input parameters check */
    137     if (qset == NULL || ctype == NULL) {
    138         return (BCM_E_INTERNAL);
    139     }
    140 
    141     /* Retreive class type from provided qset */
    142     if (BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyEtherType)) {
    143         *ctype = _FieldClassEtherType;
    144     } else if (BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyTtl)) {
    145         *ctype = _FieldClassTtl;
    146     } else if (BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyTos)) {
    147         *ctype = _FieldClassToS;
    148     } else if (BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyIpProtocol)) {
    149         *ctype = _FieldClassIpProto;
    150     } else if (BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyL4SrcPort) ||
    151               (BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyFcoeOxID))) {
    152         *ctype = _FieldClassL4SrcPort;
    153     } else if (BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyL4DstPort) ||
    154               (BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyFcoeRxID))) {
    155         *ctype = _FieldClassL4DstPort;
    156     } else if (BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyTcpControl)) {
    157         *ctype = _FieldClassTcp;
    158     } else if (BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifySrcIp) ||
    159                BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifySrcIp6) ||
    160                BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyFibreChanSrcId)) {
    161         *ctype = _FieldClassSrcCompression;
    162     } else if (BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyDstIp) ||
    163                BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyDstIp6) ||
    164                BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyFibreChanDstId)) {
    165         *ctype = _FieldClassDstCompression;
    166     } else if (BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyIpTunnelTtl)) {
    167         *ctype = _FieldClassIpTunnelTtl;
    168     } else {
    169         rv = BCM_E_PARAM;
    170     }
    171 
    172     return (rv);
    173 }
    174 
    175 /*
    176  * Function:
    177  *    _bcm_field_th_class_ctype_supported
    178  * Purpose:
    179  *    Check if the class type is supported for the device.
    180  * Parameters:
    181  *     unit        - (IN) BCM Device number.
    182  *     ctype       - (IN) Field Class Type.
    183  * Returns:
    184  *     BCM_E_XXX
    185  */
    186 int
    187 _bcm_field_th_class_ctype_supported(int unit,
    188                                  _field_class_type_t ctype)
    189 {
    190     int rv = BCM_E_NONE;
    191 
    192 #if defined (BCM_TOMAHAWK3_SUPPORT)
    193     if ((soc_feature(unit, soc_feature_th3_style_fp))) {
    194         return _field_th3_class_ctype_supported (unit, ctype);
    195     }
    196 #endif
    197 
    198     switch(ctype) {
    199         case _FieldClassEtherType:
    200         case _FieldClassTtl:
    201         case _FieldClassToS:
    202         case _FieldClassIpProto:
    203         case _FieldClassL4SrcPort:
    204         case _FieldClassL4DstPort:
    205         case _FieldClassTcp:
    206         case _FieldClassSrcCompression:
    207         case _FieldClassDstCompression:
    208               rv = BCM_E_NONE;
    209               break;
    210         default:
    211               rv = BCM_E_UNAVAIL;
    212               break;
    213     }
    214 
    215     return rv;
    216 }
    217 
    218 /*
    219  * Function:
    220  *    _field_th_class_max_entries
    221  * Purpose:
    222  *    Get Field Class max entries supported for
    223  *    provide class pipe and type.
    224  * Parameters:
    225  *     unit        - (IN) BCM Device number.
    226  *     cpipe       - (IN) Field Class Pipe.
    227  *     ctype       - (IN) Field Class Type.
    228  *     max_entries - (OUT) Max Entries Supported.
    229  * Returns:
    230  *     BCM_E_XXX
    231  */
    232 int
    233 _field_th_class_max_entries(int unit, int cpipe,
    234                                       _field_class_type_t ctype,
    235                                       int *max_entries)
    236 {
    237     int rv = BCM_E_NONE;    /* Operation Return Status */
    238 
    239     /* Validate class pipe */
    240     if (cpipe < 0 || cpipe >= _FP_MAX_NUM_PIPES) {
    241         return (BCM_E_INTERNAL);
    242     }
    243 
    244     /* Validate and fill as per class type */
    245     switch(ctype) {
    246         case _FieldClassEtherType:
    247             *max_entries = _FP_MAX_NUM_CLASS_ETHERTYPE;
    248             break;
    249         case _FieldClassTtl:
    250             *max_entries = _FP_MAX_NUM_CLASS_TTL;
    251             break;
    252         case _FieldClassToS:
    253             *max_entries = _FP_MAX_NUM_CLASS_TOS;
    254             break;
    255         case _FieldClassIpProto:
    256             *max_entries = _FP_MAX_NUM_CLASS_IP_PROTO;
    257             break;
    258         case _FieldClassL4SrcPort:
    259             *max_entries = _FP_MAX_NUM_CLASS_L4_SRC_PORT;
    260             break;
    261         case _FieldClassL4DstPort:
    262             *max_entries = _FP_MAX_NUM_CLASS_L4_DST_PORT;
    263             break;
    264         case _FieldClassTcp:
    265             *max_entries = _FP_MAX_NUM_CLASS_TCP;
    266             break;
    267         case _FieldClassSrcCompression:
    268             *max_entries = _FP_MAX_NUM_CLASS_SRC_COMPRESSION;
    269             break;
    270         case _FieldClassDstCompression:
    271             *max_entries = _FP_MAX_NUM_CLASS_DST_COMPRESSION;
    272             break;
    273         case _FieldClassIpTunnelTtl:
    274             *max_entries = _FP_MAX_NUM_CLASS_IPTUNNELTTL;
    275             break;
    276         default:
    277             rv = BCM_E_PARAM;
    278     }
    279 
    280     return (rv);
    281 }
    282 
    283 /*
    284  * Function:
    285  *    _field_th_class_group_validate
    286  * Purpose:
    287  *    Validate a field processor group for stage class.
    288  * Parameters:
    289  *    unit       - (IN) BCM Device Number.
    290  *    class_fg   - (IN/OUT) Field Class Group.
    291  * Returns:
    292  *    BCM_E_XXX.
    293  * Notes:
    294  *    This function is used to validate
    295  *    qset, aset , pbmp for field class group
    296  *    and update instance information.
    297  */
    298 STATIC int
    299 _field_th_class_group_validate(int unit, _field_group_t *class_fg)
    300 {
    301     int rv = BCM_E_NONE;    /* Operation Return Status */
    302     int stage_cnt = 0, class_cnt = 0;
    303                             /* Stage and Class Count */
    304     _field_stage_t *stage_fc = NULL;
    305                             /* Field Stage Control */
    306     _field_control_t *fc = NULL;
    307                             /* Field Control Structure */
    308     _field_group_t *fg = NULL;
    309                             /* Field Group Control */
    310     int pipe;               /* Device pipe iterator */
    311     bcm_pbmp_t t_pbmp;      /* Pipe Port bitmap */
    312     bcm_field_qset_t *qset = NULL;
    313                             /* Field Qualifier Set */
    314     bcm_field_qset_t qset_supported;
    315                             /* Field Class Qualifier Set */
    316     _bcm_field_aset_t *aset = NULL;
    317                             /* Field Action Set */
    318     bcm_field_qset_t qset_fg;
    319                             /* Field Group Qualifier Set */
    320     bcm_pbmp_t         all_pbmp;   /* Group port bitmap. */
    321 
    322     /* Input parameters check. */
    323     if ((NULL == class_fg) ||
    324         (class_fg->stage_id != _BCM_FIELD_STAGE_CLASS)) {
    325         return (BCM_E_INTERNAL);
    326     }
    327 
    328     /* Get Field Control */
    329     rv = _field_control_get(unit, &fc);
    330     if (BCM_FAILURE(rv)) {
    331         return (rv);
    332     }
    333 
    334     /* Get Field Class Stage Control */
    335     rv = _field_stage_control_get(unit, class_fg->stage_id, &stage_fc);
    336     if (BCM_FAILURE(rv)) {
    337         return (rv);
    338     }
    339 
    340     /* Assign qset and aset */
    341     qset = &class_fg->qset;
    342     aset = &class_fg->aset;
    343 
    344     /* Set Supported QSet for Stage Class */
    345     BCM_FIELD_QSET_INIT(qset_supported);
    346     BCM_FIELD_QSET_ADD(qset_supported, bcmFieldQualifyStageClass);
    347     BCM_FIELD_QSET_ADD(qset_supported, bcmFieldQualifyStageClassExactMatch);
    348     BCM_FIELD_QSET_ADD(qset_supported, bcmFieldQualifyEtherType);
    349     BCM_FIELD_QSET_ADD(qset_supported, bcmFieldQualifyTtl);
    350     BCM_FIELD_QSET_ADD(qset_supported, bcmFieldQualifyTos);
    351     BCM_FIELD_QSET_ADD(qset_supported, bcmFieldQualifyIpProtocol);
    352     BCM_FIELD_QSET_ADD(qset_supported, bcmFieldQualifyTcpControl);
    353 
    354     BCM_FIELD_QSET_ADD(qset_supported, bcmFieldQualifyVrf);
    355 
    356     if (SOC_IS_TOMAHAWK3(unit)) {
    357         BCM_FIELD_QSET_ADD(qset_supported, bcmFieldQualifyIpTunnelTtl);
    358     } else {
    359         BCM_FIELD_QSET_ADD(qset_supported, bcmFieldQualifyL4SrcPort);
    360         BCM_FIELD_QSET_ADD(qset_supported, bcmFieldQualifyL4DstPort);
    361         BCM_FIELD_QSET_ADD(qset_supported, bcmFieldQualifySrcIp);
    362         BCM_FIELD_QSET_ADD(qset_supported, bcmFieldQualifySrcIp6);
    363         BCM_FIELD_QSET_ADD(qset_supported, bcmFieldQualifyDstIp);
    364         BCM_FIELD_QSET_ADD(qset_supported, bcmFieldQualifyDstIp6);
    365         BCM_FIELD_QSET_ADD(qset_supported, bcmFieldQualifyFcoeOxID);
    366         BCM_FIELD_QSET_ADD(qset_supported, bcmFieldQualifyFcoeRxID);
    367         BCM_FIELD_QSET_ADD(qset_supported, bcmFieldQualifyFibreChanSrcId);
    368         BCM_FIELD_QSET_ADD(qset_supported, bcmFieldQualifyFibreChanDstId);
    369     }
    370 
    371     /* Validate Provided qset is supported */
    372     if(!(_field_qset_is_subset(&class_fg->qset, &qset_supported))) {
    373         LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit,
    374                   "FP(unit %d) Error: Un-Supported Qualifier in qset "
    375                   "for stage class.\n"),
    376                   unit));
    377         return (BCM_E_UNAVAIL);
    378     }
    379 
    380     /*
    381      * First Check only one stage is passed either
    382      * it is StageClass or StageClassExactMatch
    383      */
    384     if (BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyStageClass))
    385         stage_cnt++;
    386     if (BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyStageClassExactMatch))
    387         stage_cnt++;
    388 
    389     if (stage_cnt != 1) {
    390         LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit,
    391                   "FP(unit %d) Error: StageClass Parameter not specified "
    392                   "or is not valid.\n"),
    393                   unit));
    394         return (BCM_E_PARAM);
    395     }
    396 
    397     /* Check only one class is specified */
    398     if (BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyEtherType))
    399         class_cnt++;
    400     if (BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyTtl))
    401         class_cnt++;
    402     if (BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyTos))
    403         class_cnt++;
    404     if (BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyIpProtocol))
    405         class_cnt++;
    406     if (BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyL4SrcPort) ||
    407         BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyFcoeOxID))
    408         class_cnt++;
    409     if (BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyL4DstPort) ||
    410         BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyFcoeRxID))
    411         class_cnt++;
    412     if (BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyTcpControl))
    413         class_cnt++;
    414     if (BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifySrcIp) ||
    415         BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifySrcIp6) ||
    416         BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyFibreChanSrcId))
    417         class_cnt++;
    418     if (BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyDstIp) ||
    419         BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyDstIp6) ||
    420         BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyFibreChanDstId))
    421         class_cnt++;
    422     if (BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyIpTunnelTtl))
    423         class_cnt++;
    424 
    425     if (class_cnt != 1) {
    426         LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit,
    427                   "FP(unit %d) Error: Un-Supported combination of class "
    428                   "qualifier.\n"),
    429                   unit));
    430         return (BCM_E_PARAM);
    431     }
    432 
    433     /* Check if Class action provided, if not return error */
    434     if (!(BCM_FIELD_ASET_TEST(*aset, bcmFieldActionClassZero) ||
    435                 BCM_FIELD_ASET_TEST(*aset, bcmFieldActionClassOne))) {
    436         LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit,
    437                      "FP(unit %d) Error: Stage Action Paramter not "
    438                      "specified.\n"),
    439                     unit));
    440         return (BCM_E_PARAM);
    441     }
    442 
    443     /* ClassOne Action Validation */
    444     if (BCM_FIELD_ASET_TEST(*aset, bcmFieldActionClassOne)) {
    445         if (!(BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyTtl) ||
    446               BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyTos) ||
    447               BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyTcpControl) ||
    448               BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyIpTunnelTtl))) {
    449             LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit,
    450                       "FP(unit %d) Error: ClassOne Action unsupported for "
    451                       "provided class qualfier.\n"),
    452                       unit));
    453             return (BCM_E_PARAM);
    454         }
    455     }
    456 
    457     /* Stage Class Validation */
    458     if (BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyStageClass)) {
    459         if (!(BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifySrcIp) ||
    460               BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifySrcIp6) ||
    461               BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyFibreChanSrcId) ||
    462               BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyDstIp) ||
    463               BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyDstIp6) ||
    464               BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyFibreChanDstId))) {
    465             LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit,
    466                       "FP(unit %d) Error: Qualifier unsupported for given "
    467                       "stage class.\n"),
    468                       unit));
    469             return (BCM_E_PARAM);
    470         }
    471     }
    472 
    473     if (BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyStageClassExactMatch)) {
    474         if (!(BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyEtherType) ||
    475               BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyTtl) ||
    476               BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyTos) ||
    477               BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyIpProtocol) ||
    478               BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyL4SrcPort) ||
    479               BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyFcoeOxID) ||
    480               BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyL4DstPort) ||
    481               BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyFcoeRxID) ||
    482               BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyTcpControl) ||
    483               BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyIpTunnelTtl))) {
    484             LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit,
    485                       "FP(unit %d) Error: Qualifier unsupported for given "
    486                       "stage class exact match.\n"),
    487                       unit));
    488             return (BCM_E_PARAM);
    489         }
    490     }
    491 
    492     /* VRF Check */
    493     if (BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyVrf)) {
    494         if (!(BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifySrcIp) ||
    495               BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifySrcIp6) ||
    496               BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyFibreChanSrcId) ||
    497               BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyDstIp) ||
    498               BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyDstIp6) ||
    499               BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyFibreChanDstId))) {
    500             LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit,
    501                       "FP(unit %d) Error: Un-Supported Qualifier set "
    502                       "for VRF.\n"),
    503                       unit));
    504             return (BCM_E_PARAM);
    505         }
    506     }
    507 
    508     /* Read device port configuration. */ 
    509     BCM_PBMP_CLEAR(all_pbmp);
    510     BCM_IF_ERROR_RETURN(_bcm_field_valid_pbmp_get(unit, &all_pbmp));
    511 
    512     /* Verify pbmp based on stage operational mode */
    513     if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) {
    514         /*
    515          * Validate user supplied IPBM value.For global mode,
    516          * all ports must be part of IPBM value, if supplied.
    517          */
    518         if (BCM_PBMP_NEQ(all_pbmp, class_fg->pbmp)) {
    519             /* If port configuration get fails, go to end. */
    520             LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit,
    521                       "FP(unit %d) Error: Global Mode - "
    522                       "Port Bitmap not valid.\n"),
    523                       unit));
    524             return (BCM_E_PARAM);
    525         }
    526 
    527         /* For group global operational mode, use the default instance.  */
    528         class_fg->instance = _FP_DEF_INST;
    529     } else {
    530         /*
    531          * For PipeLocal group oper mode, derive the
    532          * instance information from group's PBM value.
    533          */
    534         for (pipe = 0; pipe < NUM_PIPE(unit); pipe++){
    535             BCM_PBMP_ASSIGN(t_pbmp, PBMP_PIPE(unit,pipe));
    536             BCM_PBMP_REMOVE(t_pbmp, PBMP_LB(unit));
    537             /*
    538              * User must use bcm_port_config_get API to retrieve Pipe PBMP value
    539              * and pass this value in Group's pbmp parameter when creating
    540              * PipeLocal groups.
    541              */
    542             if (BCM_PBMP_EQ(t_pbmp, class_fg->pbmp)) {
    543                 /*
    544                  * Pipe PBM matches user supplied PBM, update field group
    545                  * instance.
    546                  */
    547                 class_fg->instance = pipe;
    548                 break;
    549             }
    550         }
    551 
    552         /*
    553          * Portbit map value supplied by the user not matching any of the pipe's
    554          * port bitmap mask value, hence return input paramter error.
    555          */
    556         if (NUM_PIPE(unit) == pipe) {
    557             LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit,
    558                       "FP(unit %d) Error: Per Pipe Mode - "
    559                       "Port Bitmap not valid.\n"),
    560                       unit));
    561             return (BCM_E_PARAM);
    562         }
    563     }
    564 
    565     /*
    566      * Only one class group is valid per compression
    567      * table. Validate if it exist already in system.
    568      */
    569     fg = fc->groups;
    570     while (fg != NULL) {
    571         /* Skip non class groups */
    572         if (fg->stage_id != _BCM_FIELD_STAGE_CLASS) {
    573             fg = fg->next;
    574             continue;
    575         }
    576         /*
    577          * Check overlapping qualifier additionally.
    578          * SrcIp and DstIp compression groups are superset of
    579          * IPv6 ,V6 and FCoE entries. Hence compare subset
    580          * with superset qset than actual group qset.
    581          */
    582         BCM_FIELD_QSET_INIT(qset_fg);
    583         qset_fg = class_fg->qset;
    584         if (BCM_FIELD_QSET_TEST(qset_fg, bcmFieldQualifyL4SrcPort) ||
    585             BCM_FIELD_QSET_TEST(qset_fg, bcmFieldQualifyFcoeOxID)) {
    586             BCM_FIELD_QSET_ADD(qset_fg, bcmFieldQualifyL4SrcPort);
    587             BCM_FIELD_QSET_ADD(qset_fg, bcmFieldQualifyFcoeOxID);
    588         }
    589         if (BCM_FIELD_QSET_TEST(qset_fg, bcmFieldQualifyL4DstPort) ||
    590             BCM_FIELD_QSET_TEST(qset_fg, bcmFieldQualifyFcoeRxID)) {
    591             BCM_FIELD_QSET_ADD(qset_fg, bcmFieldQualifyL4DstPort);
    592             BCM_FIELD_QSET_ADD(qset_fg, bcmFieldQualifyFcoeRxID);
    593         }
    594         if (BCM_FIELD_QSET_TEST(qset_fg, bcmFieldQualifySrcIp) ||
    595             BCM_FIELD_QSET_TEST(qset_fg, bcmFieldQualifySrcIp6) ||
    596             BCM_FIELD_QSET_TEST(qset_fg, bcmFieldQualifyFibreChanSrcId)) {
    597             BCM_FIELD_QSET_ADD(qset_fg, bcmFieldQualifySrcIp);
    598             BCM_FIELD_QSET_ADD(qset_fg, bcmFieldQualifySrcIp6);
    599             BCM_FIELD_QSET_ADD(qset_fg, bcmFieldQualifyFibreChanSrcId);
    600         }
    601         if (BCM_FIELD_QSET_TEST(qset_fg, bcmFieldQualifyDstIp) ||
    602             BCM_FIELD_QSET_TEST(qset_fg, bcmFieldQualifyDstIp6) ||
    603             BCM_FIELD_QSET_TEST(qset_fg, bcmFieldQualifyFibreChanDstId)) {
    604             BCM_FIELD_QSET_ADD(qset_fg, bcmFieldQualifyDstIp);
    605             BCM_FIELD_QSET_ADD(qset_fg, bcmFieldQualifyDstIp6);
    606             BCM_FIELD_QSET_ADD(qset_fg, bcmFieldQualifyFibreChanDstId);
    607         }
    608 
    609         if (_field_qset_is_subset(&fg->qset, &qset_fg)) {
    610 
    611             if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) {
    612                 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit,
    613                           "FP(unit %d) Error: Global Mode - "
    614                           "Field Group Exist Already.\n"),
    615                           unit));
    616                 return (BCM_E_PARAM);
    617             } else {
    618                 if (BCM_PBMP_EQ(fg->pbmp, class_fg->pbmp)) {
    619                     LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit,
    620                               "FP(unit %d) Error: Per Pipe Mode - "
    621                               "Field Group Exist Already.\n"),
    622                               unit));
    623                     return (BCM_E_PARAM);
    624                 }
    625             }
    626         }
    627         fg = fg->next;
    628     }
    629 
    630     return (rv);
    631 }
    632 
    633 /*
    634  * Function:
    635  *  _bcm_field_th_class_size_get
    636  * Purpose:
    637  *  Get Field Class size supported for
    638  *  provide ctype.
    639  * Parameters:
    640  *  unit        - (IN) BCM Device number.
    641  *  ctype       - (IN) Field Class Type.
    642  *  memsize     - (OUT) Max Class Size.
    643  * Returns:
    644  *  BCM_E_XXX
    645  */
    646 int
    647 _bcm_field_th_class_size_get(int unit, _field_class_type_t ctype,
    648                                                     int *memsize)
    649 {
    650     int rv = BCM_E_NONE; /* Operation Return Status */
    651 
    652     /* Validate and fill as per class type */
    653     switch(ctype) {
    654         case _FieldClassEtherType:
    655             *memsize = _FP_SIZE_CLASS_ETHERTYPE;
    656             break;
    657         case _FieldClassTtl:
    658             *memsize = _FP_SIZE_CLASS_TTL;
    659             break;
    660         case _FieldClassToS:
    661             *memsize = _FP_SIZE_CLASS_TOS;
    662             break;
    663         case _FieldClassIpProto:
    664             *memsize = _FP_SIZE_CLASS_IP_PROTO;
    665             break;
    666         case _FieldClassL4SrcPort:
    667             *memsize = _FP_SIZE_CLASS_L4_SRC_PORT;
    668             break;
    669         case _FieldClassL4DstPort:
    670             *memsize = _FP_SIZE_CLASS_L4_DST_PORT;
    671             break;
    672         case _FieldClassTcp:
    673             *memsize = _FP_SIZE_CLASS_TCP;
    674             break;
    675         case _FieldClassSrcCompression:
    676             *memsize = _FP_SIZE_CLASS_SRC_COMPRESSION;
    677             break;
    678         case _FieldClassDstCompression:
    679             *memsize = _FP_SIZE_CLASS_DST_COMPRESSION;
    680             break;
    681         case _FieldClassIpTunnelTtl:
    682             *memsize = _FP_SIZE_CLASS_IPTUNNELTTL;
    683             break;
    684         default:
    685             rv = BCM_E_PARAM;
    686     }
    687 
    688     return (rv);
    689 }
    690 
    691 /*
    692  * Function:
    693  *  _bcm_field_th_class_stage_add
    694  * Purpose:
    695  *  Add Pseudo Class Stage.
    696  * Parameters:
    697  *  unit     - (IN) BCM device number.
    698  *  fc       - (IN) Field control structure.
    699  *  stage_fc - (IN) Stage field control structure.
    700  * Returns:
    701  *  BCM_E_XXX
    702  */
    703 int
    704 _bcm_field_th_class_stage_add(int unit, _field_control_t *fc,
    705                                      _field_stage_t *stage_fc)
    706 {
    707     int rv = BCM_E_NONE;    /* Operation Return Status */
    708 
    709     /* Input parameters check. */
    710     if ((fc == NULL) ||
    711         (stage_fc == NULL)) {
    712         return (BCM_E_INTERNAL);
    713     }
    714 
    715     /* Add stage to Field Control structure. */
    716     FP_LOCK(unit);
    717 
    718     stage_fc->next = fc->stages;
    719     fc->stages = stage_fc;
    720 
    721     stage_fc->num_pipes = NUM_PIPE(unit);
    722 
    723     if (bcmFieldGroupOperModePipeLocal == stage_fc->oper_mode) {
    724         /*
    725          * Initialize number of FP instances to number of pipes supported in
    726          * hardware.
    727          */
    728         stage_fc->num_instances = stage_fc->num_pipes;
    729     } else {
    730         /* Initialize to legacy TD2 mode - Global mode (single instance). */
    731         stage_fc->num_instances = 1;
    732     }
    733 
    734     /* Initialize Class Stage Tracking Structure. */
    735     rv = _bcm_field_th_class_stage_status_init(unit,stage_fc);
    736 
    737     FP_UNLOCK(unit);
    738 
    739     return (rv);
    740 }
    741 
    742 /*
    743  * Function:
    744  *  _bcm_field_th_class_stage_status_init
    745  * Purpose:
    746  *  Initialize Class Stage Tracking Structure.
    747  * Parameters:
    748  *  unit     - (IN) BCM device number.
    749  *  stage_fc - (IN) Stage field control structure.
    750  * Returns:
    751  *  BCM_E_XXX
    752  */
    753 int
    754 _bcm_field_th_class_stage_status_init(int unit, _field_stage_t *stage_fc)
    755 {
    756     int rv = BCM_E_NONE;    /* Operation Return Status */
    757     _field_class_type_t ctype;
    758                             /* Field Class Type */
    759     _field_class_info_t **class_status_arr;
    760                             /* Field Per Pipe Class Status Array */
    761     _field_class_info_t *class_status_info = NULL;
    762                             /* Field Per Compression table status */
    763     int alloc_sz;           /* Memory allocation size. */
    764     int cpipe = 0, max_entries = 0,size = 0;
    765                             /* Misc Var */
    766 
    767     /* Input parameters check */
    768     if (stage_fc == NULL) {
    769         return (BCM_E_INTERNAL);
    770     }
    771 
    772     /* Skip this routine for non-class stages. */
    773     if (_BCM_FIELD_STAGE_CLASS != stage_fc->stage_id) {
    774         return (BCM_E_NONE);
    775     }
    776 
    777     /* Allocate Per-Pipe Class Stage Pointer Arrays */
    778     for (cpipe = 0; cpipe < _FP_MAX_NUM_PIPES; cpipe++) {
    779         if (stage_fc->class_info_arr[cpipe] == NULL) {
    780             /* Allocate memory for stage class status. */
    781             _FP_XGS3_ALLOC(stage_fc->class_info_arr[cpipe],
    782                   (_FP_MAX_NUM_CLASS_TYPES * sizeof(_field_class_info_t *)),
    783                     "Field Class Status");
    784             if (NULL == stage_fc->class_info_arr[cpipe]) {
    785                 LOG_ERROR(BSL_LS_BCM_FP, (BSL_META_U(unit,
    786                           "FP(unit %d) Error: Allocation failure for field "
    787                           "class status arr info.\n"),
    788                           unit));
    789                 return (BCM_E_MEMORY);
    790             }
    791         } else {
    792             LOG_ERROR(BSL_LS_BCM_FP, (BSL_META_U(unit,
    793                       "FP(unit %d) Error: Allocation already present for "
    794                       "field class status arr info.\n"),
    795                       unit));
    796             return (BCM_E_INTERNAL);
    797         }
    798     }
    799 
    800     /* Allocate Class Stage Tracking Strucutre for all classes per pipe */
    801     for (cpipe = 0; cpipe < _FP_MAX_NUM_PIPES; cpipe++) {
    802         class_status_arr = stage_fc->class_info_arr[cpipe];
    803         for (ctype = 0; ctype < _FP_MAX_NUM_CLASS_TYPES; ctype++) {
    804             /* Check the class types supported */
    805             rv = _bcm_field_th_class_ctype_supported(unit, ctype);
    806             if (BCM_SUCCESS(rv)) {
    807                 class_status_info = class_status_arr[ctype];
    808                 if (class_status_info == NULL) {
    809                     /* Allocate field class status info struct. */
    810                     alloc_sz = sizeof(_field_class_info_t);
    811                     _FP_XGS3_ALLOC(class_status_info, alloc_sz,
    812                                                         "FP Class Status info");
    813                     if (NULL == class_status_info) {
    814                         LOG_ERROR(BSL_LS_BCM_FP, (BSL_META_U(unit,
    815                                   "FP(unit %d) Error: Allocation failure for "
    816                                   "field class status info.\n"),
    817                                   unit));
    818                         return (BCM_E_MEMORY);
    819                     }
    820                     /* Update Class Status Info */
    821                     class_status_info->classtype = ctype;
    822                     class_status_info->total_entries_used = 0;
    823 
    824                     /* Retreive Max Entries for class type */
    825                     rv = _field_th_class_max_entries(unit,cpipe,
    826                                                           ctype,&max_entries);
    827 
    828                     if (BCM_SUCCESS(rv)) {
    829                         class_status_info->total_entries_available = max_entries;
    830                         size = SHR_BITALLOCSIZE(max_entries << 1);
    831                         class_status_info->class_bmp.w =
    832                                                    sal_alloc(size, "class_bmap");
    833                         sal_memset(class_status_info->class_bmp.w, 0, size);
    834                     } else {
    835                         LOG_ERROR(BSL_LS_BCM_FP, (BSL_META_U(unit,
    836                                   "FP(unit %d) Error: Retreiving max entries for "
    837                                   "class type %d.\n"),
    838                                   unit,ctype));
    839                         sal_free(class_status_info);
    840                         return (BCM_E_INTERNAL);
    841                     }
    842                     class_status_arr[ctype] = class_status_info;
    843 
    844                 } else {
    845                         LOG_ERROR(BSL_LS_BCM_FP, (BSL_META_U(unit,
    846                                   "FP(unit %d) Error: Allocation already present "
    847                                   "for field class status info.\n"),
    848                                   unit));
    849                         return (BCM_E_MEMORY);
    850                 }
    851             }
    852         }
    853     }
    854 
    855     return (BCM_E_NONE);
    856 }
    857 
    858 /*
    859  * Function:
    860  *  _bcm_field_th_class_stage_status_deinit
    861  * Purpose:
    862  *  De-Initialize Class Stage Tracking Structure.
    863  * Parameters:
    864  *  unit     - (IN) BCM device number.
    865  *  stage_fc - (IN) Stage field control structure.
    866  * Returns:
    867  *  BCM_E_XXX
    868  */
    869 int
    870 _bcm_field_th_class_stage_status_deinit(int unit, _field_stage_t *stage_fc)
    871 {
    872     int rv = BCM_E_NONE;        /* Operation Return Status */
    873     _field_class_type_t ctype;  /* Field Class Type */
    874     _field_class_info_t **class_status_arr;
    875                                 /* Field Per Pipe Class Status Array */
    876     _field_class_info_t *class_status_info;
    877                                 /* Field Per Compression table status */
    878     int cpipe = 0;              /* Per Pipe Iterator */
    879 
    880     /* Input parameters check. */
    881     if (stage_fc == NULL) {
    882         return (BCM_E_INTERNAL);
    883     }
    884 
    885     /* Skip this routine for non-class stages. */
    886     if (_BCM_FIELD_STAGE_CLASS != stage_fc->stage_id) {
    887         return (BCM_E_NONE);
    888     }
    889 
    890     /* Free Memory Allocated for Class Status Structure */
    891     for (cpipe = 0; cpipe < _FP_MAX_NUM_PIPES; cpipe++) {
    892         class_status_arr = stage_fc->class_info_arr[cpipe];
    893         if (class_status_arr != NULL) {
    894             for (ctype = 0; ctype < _FP_MAX_NUM_CLASS_TYPES; ctype++) {
    895                 /* Check the class types supported */
    896                 rv = _bcm_field_th_class_ctype_supported(unit, ctype);
    897                 if (BCM_SUCCESS(rv)) {
    898                     class_status_info = class_status_arr[ctype];
    899                     if (class_status_info != NULL) {
    900                         if (class_status_info->class_bmp.w != NULL) {
    901                             sal_free(class_status_info->class_bmp.w);
    902                             class_status_info->class_bmp.w = NULL;
    903                         }
    904                         sal_free(class_status_info);
    905                         class_status_info = NULL;
    906                         class_status_arr[ctype] = class_status_info;
    907                     }
    908                 }
    909             }
    910             sal_free(class_status_arr);
    911             class_status_arr = NULL;
    912             stage_fc->class_info_arr[cpipe] = class_status_arr;
    913         }
    914     }
    915 
    916     return (BCM_E_NONE);
    917 }
    918 
    919 /*
    920  * Function:
    921  *  _bcm_field_th_class_group_add
    922  * Purpose:
    923  *  Create a field processor group for stage class.
    924  * Parameters:
    925  *  unit      - (IN) BCM device number.
    926  *  fsm_ptr   - (IN) State machine tracking structure.
    927  * Returns:
    928  *  BCM_E_XXX
    929  */
    930 int
    931 _bcm_field_th_class_group_add(int unit, _field_group_add_fsm_t *fsm_ptr,
    932                                              bcm_field_aset_t aset_class)
    933 {
    934     int rv = BCM_E_NONE;        /* Operation Return Status */
    935     int mem_sz;                 /* Memory size to be allocated */
    936     _field_group_t *fg = NULL;  /* New group information structure */
    937     _field_group_t *fg_temp;    /* Pointer to an existing Field Group */
    938     _field_class_info_t **class_status_arr;
    939                                 /* Field Per Pipe Class Status Array */
    940     _field_class_info_t *class_status_info;
    941                                 /* Field Per Compression table status */
    942     _field_class_type_t ctype;
    943                                 /* Field Class Type */
    944     int idx;
    945 
    946     /* Input parameters check. */
    947     if (NULL == fsm_ptr) {
    948         return (BCM_E_INTERNAL);
    949     }
    950 
    951     /* Validate Group ID Passed */
    952     if (BCM_SUCCESS(_field_group_get(unit, fsm_ptr->group_id, &fg_temp))) {
    953         LOG_ERROR(BSL_LS_BCM_FP,
    954                  (BSL_META_U(unit, "FP(unit %d) Error: group=%d already "
    955                  "exists.\n"),
    956                  unit, fsm_ptr->group_id));
    957         return (BCM_E_EXISTS);
    958     }
    959 
    960     /* Get Field Control */
    961     rv = _field_control_get(unit, &fsm_ptr->fc);
    962     if (BCM_FAILURE(rv)) {
    963         return (rv);
    964     }
    965 
    966     /* Get Field Stage Class Control */
    967     rv = _field_stage_control_get(unit, _BCM_FIELD_STAGE_CLASS,
    968                                              &fsm_ptr->stage_fc);
    969     if (BCM_FAILURE(rv)) {
    970         return (rv);
    971     }
    972 
    973     /* Determine field group structure buffer size. */
    974     mem_sz = sizeof(_field_group_t);
    975 
    976     /* Allocate and initialize memory for Field Group. */
    977     _FP_XGS3_ALLOC(fg, mem_sz, "field group");
    978 
    979     if (NULL == fg) {
    980         LOG_ERROR(BSL_LS_BCM_FP, (BSL_META_U(unit,
    981                   "FP(unit %d) Error:Allocation failure for "
    982                   "_field_group_t\n"), unit));
    983         return (BCM_E_MEMORY);
    984     }
    985 
    986     /* Initialize group structure. */
    987     fg->gid            = fsm_ptr->group_id;
    988     fg->stage_id       = fsm_ptr->stage_fc->stage_id;
    989     fg->qset           = fsm_ptr->qset;
    990     fg->pbmp           = fsm_ptr->pbmp;
    991     fg->priority       = fsm_ptr->priority;
    992     sal_memcpy(&fg->aset, &aset_class, sizeof(bcm_field_aset_t));
    993 
    994     /* Initialize the action profile index's to -1 */
    995     for (idx=0; idx < MAX_ACT_PROF_ENTRIES_PER_GROUP; idx++) {
    996         fg->action_profile_idx[idx] =  -1;
    997     }
    998 
    999     /*
   1000      * Based on the Stage Group Operational mode,
   1001      * set the Field Group's instance information.
   1002      */
   1003     rv = _field_th_class_group_validate(unit, fg);
   1004     if (BCM_FAILURE(rv)) {
   1005         sal_free(fg);
   1006         return rv;
   1007     }
   1008 
   1009     /* Initialize group status. */
   1010     bcm_field_group_status_t_init(&fg->group_status);
   1011 
   1012     /* Retreive Class Type from entry qset */
   1013     rv = _bcm_field_th_class_type_qset_get(unit, &fg->qset, &ctype);
   1014     if (BCM_FAILURE(rv)) {
   1015         sal_free(fg);
   1016         return rv;
   1017     }
   1018 
   1019     /* Update Class Info Status Structure */
   1020     class_status_arr = fsm_ptr->stage_fc->class_info_arr[fg->instance];
   1021     if (class_status_arr == NULL) {
   1022         sal_free(fg);
   1023         return (BCM_E_INTERNAL);
   1024     }
   1025     class_status_info = class_status_arr[ctype];
   1026     if (class_status_info == NULL) {
   1027         sal_free(fg);
   1028         return (BCM_E_INTERNAL);
   1029     }
   1030 
   1031     fg->group_status.entry_count =
   1032                             class_status_info->total_entries_used;
   1033     fg->group_status.entries_total =
   1034                             class_status_info->total_entries_available;
   1035     fg->group_status.entries_free = fg->group_status.entries_total -
   1036                                     fg->group_status.entry_count;
   1037 
   1038     /* By default mark group as active. */
   1039     fg->flags |= _FP_GROUP_LOOKUP_ENABLED;
   1040 
   1041     /* Set allocated pointer to FSM structure. */
   1042     fsm_ptr->fg = fg;
   1043 
   1044     rv = _bcm_field_group_linked_list_insert(unit, fsm_ptr);
   1045     if (BCM_FAILURE(rv)) {
   1046         sal_free(fg);
   1047         return (rv);
   1048     }
   1049 
   1050     return (rv);
   1051 }
   1052 
   1053 /*
   1054  * Function:
   1055  *  _field_classtype_name
   1056  * Purpose:
   1057  *  Translate classtype to a text string.
   1058  * Parameters:
   1059  *  class_type stage field class type.
   1060  * Returns:
   1061  *  Text name of indicated class type enum value.
   1062  */
   1063 STATIC char *
   1064 _field_classtype_name(_field_class_type_t class_type)
   1065 {
   1066     static char *stage_text[] = _BCM_FIELD_CLASS_TYPE_STRINGS;
   1067 
   1068     if (class_type >= _FP_MAX_NUM_CLASS_TYPES) {
   1069         return "??";
   1070     }
   1071     return stage_text[class_type];
   1072 }
   1073 
   1074 /*
   1075  * Function:
   1076  *  _bcm_field_th_class_stage_dump
   1077  * Purpose:
   1078  *  Dump field stage class info entries.
   1079  * Parameters:
   1080  *  unit      - (IN) BCM device number.
   1081  *  stage_fc  - (IN) Field Class Stage Structure.
   1082  * Returns:
   1083  */
   1084 void
   1085 _bcm_field_th_class_stage_dump(int unit, _field_stage_t *stage_fc)
   1086 {
   1087     _field_class_type_t ctype;
   1088                         /* Operation Return Status */
   1089     _field_class_info_t **class_status_arr;
   1090                         /* Field Per Pipe Class Status Array */
   1091     _field_class_info_t *class_status_info;
   1092                         /* Field Per Compression table status */
   1093     int cpipe = 0;      /* Class Pipe Iterator */
   1094     int rv = BCM_E_NONE;/* Return Value */
   1095 
   1096     /* Input parameters check. */
   1097     if ((stage_fc != NULL) &&
   1098         (stage_fc->stage_id == _BCM_FIELD_STAGE_CLASS)) {
   1099 
   1100         LOG_CLI((BSL_META_U(unit,
   1101                         "ClassPipe  ClassType        Flags  "
   1102                         "Entries Used  Entries Available\n")));
   1103         LOG_CLI((BSL_META_U(unit,
   1104                         "---------  ---------------  -----  "
   1105                         "------------  -----------------\n")));
   1106 
   1107         if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) {
   1108             /* Global Mode - Display only default instance */
   1109             class_status_arr = stage_fc->class_info_arr[_FP_DEF_INST];
   1110             if (class_status_arr != NULL) {
   1111                 for (ctype = 0; ctype < _FP_MAX_NUM_CLASS_TYPES; ctype++) {
   1112                     /* Check the class types supported */
   1113                     rv = _bcm_field_th_class_ctype_supported(unit, ctype);
   1114                     if (BCM_SUCCESS(rv)) {
   1115                         class_status_info = class_status_arr[ctype];
   1116                         if (class_status_info != NULL) {
   1117                             LOG_CLI((BSL_META_U(unit,
   1118                                      "%9s  %-14s  %#5x  %12d  %17d\n"),
   1119                                      "Default",_field_classtype_name(ctype),
   1120                                      class_status_info->flags,
   1121                                      class_status_info->total_entries_used,
   1122                                      class_status_info->total_entries_available));
   1123                         }
   1124                     }
   1125                 }
   1126             }
   1127         } else {
   1128             /* Per Pipe Mode - Display all pipe instances */
   1129             for (cpipe = 0; cpipe < _FP_MAX_NUM_PIPES; cpipe++) {
   1130                 class_status_arr = stage_fc->class_info_arr[cpipe];
   1131                 if (class_status_arr != NULL) {
   1132                     for (ctype = 0; ctype < _FP_MAX_NUM_CLASS_TYPES; ctype++) {
   1133                         /* Check the class types supported */
   1134                         rv = _bcm_field_th_class_ctype_supported(unit, ctype);
   1135                         if (BCM_SUCCESS(rv)) {
   1136                             class_status_info = class_status_arr[ctype];
   1137                             if (class_status_info != NULL) {
   1138                                 LOG_CLI((BSL_META_U(unit,
   1139                                        "%9d  %-14s  %#5x  %12d  %17d\n"),
   1140                                        cpipe,_field_classtype_name(ctype),
   1141                                        class_status_info->flags,
   1142                                        class_status_info->total_entries_used,
   1143                                        class_status_info->total_entries_available));
   1144 
   1145                             }
   1146                         }
   1147                     }
   1148                 }
   1149             }
   1150         }
   1151     }
   1152 }
   1153 
   1154 /*
   1155  * Function:
   1156  *  _bcm_field_th_class_group_dump
   1157  * Purpose:
   1158  *  Dump field stage class group.
   1159  * Parameters:
   1160  *  unit      - (IN) BCM device number.
   1161  *  class_fg  - (IN) Field Class Stage Group Structure.
   1162  * Returns:
   1163  *  BCM_E_XXX
   1164  */
   1165 int
   1166 _bcm_field_th_class_group_dump(int unit, _field_group_t *class_fg)
   1167 {
   1168     int rv = BCM_E_NONE;        /* Operation Return Status */
   1169     _field_stage_t *stage_fc = NULL;
   1170                                 /* Field Class Stage info */
   1171     int enable = 0;             /* Group Enable */
   1172     int entry_count = 0;        /* Field Entry Count */
   1173     int entry_index;            /* Field Entry Index */
   1174     bcm_field_entry_t *entry_ids = NULL;
   1175                                 /* Field Entry ID Array */
   1176     char buf[100];              /* Character Buffer */
   1177 
   1178     /* Input parameters check. */
   1179     if (class_fg == NULL) {
   1180         return (BCM_E_INTERNAL);
   1181     }
   1182 
   1183     /* Skip if it is not stage class */
   1184     if (class_fg->stage_id != _BCM_FIELD_STAGE_CLASS) {
   1185         return (BCM_E_NONE);
   1186     }
   1187 
   1188     /* Retreive Field Stage Control */
   1189     rv = _field_stage_control_get(unit, class_fg->stage_id, &stage_fc);
   1190     if (BCM_FAILURE(rv)) {
   1191         return (rv);
   1192     }
   1193 
   1194     /* Dump Field Class Group Information */
   1195     LOG_CLI((BSL_META_U(unit,
   1196              "GID %10d: gid=0x%x, instance=%d, flags %#x, stage=%d "),
   1197              class_fg->gid, class_fg->gid, class_fg->instance, class_fg->flags,
   1198              class_fg->stage_id));
   1199     bcm_esw_field_group_enable_get(unit, class_fg->gid, &enable);
   1200     if (enable) {
   1201         LOG_CLI((BSL_META_U(unit,"lookup=Enabled, ")));
   1202     } else {
   1203         LOG_CLI((BSL_META_U(unit,"lookup=Disabled, ")));
   1204     }
   1205     LOG_CLI((BSL_META_U(unit,
   1206                     "pbmp={%s},\n"), SOC_PBMP_FMT(class_fg->pbmp, buf)));
   1207     _field_qset_dump("         qset=", class_fg->qset, ",\n");
   1208     _field_aset_dump("         aset=", class_fg->aset, ",\n");
   1209     LOG_CLI((BSL_META_U(unit,"         group_status=")));
   1210     LOG_CLI((BSL_META("{entries_total=%d,"),
   1211                       class_fg->group_status.entries_total));
   1212     LOG_CLI((BSL_META(" entries_free=%d,"),
   1213                       class_fg->group_status.entries_free));
   1214     LOG_CLI((BSL_META(" entries_count=%d}"),
   1215                       class_fg->group_status.entry_count));
   1216     LOG_CLI((BSL_META_U(unit,"\n")));
   1217 
   1218     /* Print group's entries */
   1219     rv = bcm_esw_field_entry_multi_get(unit, class_fg->gid, 0,
   1220                                             NULL, &entry_count);
   1221 
   1222     if (BCM_SUCCESS(rv))
   1223     {
   1224         entry_ids = sal_alloc(entry_count * sizeof (bcm_field_entry_t),
   1225                 "Entry ID array");
   1226 
   1227         if (entry_ids == NULL)
   1228         {
   1229             rv = BCM_E_MEMORY;
   1230         }
   1231         else
   1232         {
   1233             rv = bcm_esw_field_entry_multi_get(unit, class_fg->gid,
   1234                                                entry_count,
   1235                                                entry_ids, &entry_count);
   1236 
   1237             if (BCM_SUCCESS(rv))
   1238             {
   1239                 for (entry_index = 0; entry_index < entry_count;
   1240                         ++entry_index)
   1241                 {
   1242                     _bcm_esw_field_entry_dump(unit, entry_ids[entry_index], -1);
   1243                 }
   1244             }
   1245 
   1246             sal_free(entry_ids);
   1247         }
   1248     }
   1249 
   1250     return (BCM_E_NONE);
   1251 }
   1252 
   1253 /*
   1254  * Function:
   1255  *  _bcm_field_th_class_group_brief_dump
   1256  * Purpose:
   1257  *  Dump field stage class group brief.
   1258  * Parameters:
   1259  *  unit      - (IN) BCM device number.
   1260  *  class_fg  - (IN) Field Class Stage Group Structure.
   1261  * Returns:
   1262  *  BCM_E_XXX
   1263  */
   1264 int
   1265 _bcm_field_th_class_group_brief_dump(int unit, _field_group_t *class_fg)
   1266 {
   1267     int rv = BCM_E_NONE;        /* Operation Return Status */
   1268     _field_stage_t *stage_fc = NULL;
   1269                                 /* Field Class Stage info */
   1270     int enable = 0;             /* Group Enable */
   1271     char buf[100];              /* Character Buffer */
   1272 
   1273     /* Input parameters check. */
   1274     if (class_fg == NULL) {
   1275         return (BCM_E_INTERNAL);
   1276     }
   1277 
   1278     /* Skip if it is not stage class */
   1279     if (class_fg->stage_id != _BCM_FIELD_STAGE_CLASS) {
   1280         return (BCM_E_NONE);
   1281     }
   1282 
   1283     /* Retreive Field Stage Control */
   1284     rv = _field_stage_control_get(unit, class_fg->stage_id, &stage_fc);
   1285     if (BCM_FAILURE(rv)) {
   1286         return (rv);
   1287     }
   1288 
   1289     /* Dump Field Class Group Information */
   1290     LOG_CLI((BSL_META_U(unit,
   1291              "GID %10d: gid=0x%x, instance=%d, flags %#x, stage=%d "),
   1292              class_fg->gid,
   1293              class_fg->gid, class_fg->instance, class_fg->flags,
   1294              class_fg->stage_id));
   1295     bcm_esw_field_group_enable_get(unit, class_fg->gid, &enable);
   1296     if (enable) {
   1297         LOG_CLI((BSL_META_U(unit,"lookup=Enabled, ")));
   1298     } else {
   1299         LOG_CLI((BSL_META_U(unit,"lookup=Disabled, ")));
   1300     }
   1301 
   1302     LOG_CLI((BSL_META_U(unit,
   1303                     "pbmp={%s},\n"), SOC_PBMP_FMT(class_fg->pbmp, buf)));
   1304     _field_qset_dump("         qset=", class_fg->qset, ",\n");
   1305     LOG_CLI((BSL_META_U(unit,"         group_status=")));
   1306     LOG_CLI((BSL_META("{entries_total=%d,"),
   1307              class_fg->group_status.entries_total));
   1308     LOG_CLI((BSL_META(" entries_free=%d,"),
   1309              class_fg->group_status.entries_free));
   1310     LOG_CLI((BSL_META(" entries_count=%d}"),
   1311              class_fg->group_status.entry_count));
   1312     LOG_CLI((BSL_META_U(unit,"\n")));
   1313 
   1314     return (BCM_E_NONE);
   1315 }
   1316 
   1317 /*
   1318  * Function:
   1319  *  _bcm_field_th_class_entry_dump
   1320  * Purpose:
   1321  *  Dump field stage class entry.
   1322  * Parameters:
   1323  *  unit       - (IN) BCM device number.
   1324  *  class_ent  - (IN) Field Class Entry Structure.
   1325  * Returns:
   1326  *  BCM_E_XXX
   1327  */
   1328 int
   1329 _bcm_field_th_class_entry_dump(int unit, _field_entry_t *class_ent)
   1330 {
   1331     int rv = BCM_E_NONE;            /* Operation Return Status */
   1332     _field_group_t *fg = NULL;      /* Field group info */
   1333     _field_class_type_t ctype;      /* Field Class Type */
   1334     _field_action_t *fa = NULL;     /* Field action info */
   1335     uint32 *databuf = 0;            /* Data Buffer */
   1336     int tcam_sz = 0;
   1337 
   1338     /* Input parameters check. */
   1339     if (class_ent == NULL ||
   1340         class_ent->group == NULL) {
   1341         return (BCM_E_INTERNAL);
   1342     }
   1343 
   1344     /* Retreive Field Group Info */
   1345     fg = class_ent->group;
   1346 
   1347     /* Skip if stage is not class */
   1348     if (fg->stage_id != _BCM_FIELD_STAGE_CLASS) {
   1349         return (BCM_E_NONE);
   1350     }
   1351 
   1352     /* Dump Field Class Group Info */
   1353     LOG_CLI((BSL_META_U(unit,
   1354              "EID 0x%08x: gid=0x%x,\n"),
   1355              class_ent->eid, fg->gid));
   1356     LOG_CLI((BSL_META_U(unit,
   1357              "         prio=%#x, flags=%#x, "),
   1358              class_ent->prio, class_ent->flags));
   1359     if (class_ent->slice_idx != -1) {
   1360         LOG_CLI((BSL_META_U(unit,
   1361              "hw_index=%#x, "),
   1362              class_ent->slice_idx));
   1363     }
   1364     if (!(class_ent->flags & _FP_ENTRY_INSTALLED)) {
   1365         LOG_CLI((BSL_META_U(unit,
   1366                         "Not installed\n")));
   1367     } else {
   1368         LOG_CLI((BSL_META_U(unit,
   1369                         "Installed")));
   1370         if (class_ent->flags & _FP_ENTRY_DIRTY) {
   1371             LOG_CLI((BSL_META_U(unit,
   1372                             ", Dirty\n")));
   1373         }
   1374         else {
   1375             LOG_CLI((BSL_META_U(unit,
   1376                             "\n")));
   1377         }
   1378     }
   1379 
   1380     /* Retreive Class Type from entry qset */
   1381     rv = _bcm_field_th_class_type_qset_get(unit, &fg->qset, &ctype);
   1382     if (BCM_FAILURE(rv)) {
   1383         return (rv);
   1384     }
   1385 
   1386     /* Get key_size from class type */
   1387     rv = _bcm_field_th_class_size_get(unit, ctype, &tcam_sz);
   1388     if (BCM_FAILURE(rv)) {
   1389         return (rv);
   1390     }
   1391     class_ent->tcam.key_size = tcam_sz;
   1392 
   1393     /* Allocate memory for class data */
   1394     _FP_XGS3_ALLOC(databuf, class_ent->tcam.key_size, "field class data buf");
   1395     if (databuf == NULL) {;
   1396         LOG_ERROR(BSL_LS_BCM_FP,
   1397                  (BSL_META_U(unit,
   1398                  "FP(unit %d) Error: allocation failure for "
   1399                  "field class data buf\n"),
   1400                  unit));
   1401         return (BCM_E_MEMORY);
   1402     }
   1403 
   1404     LOG_CLI((BSL_META_U(unit,
   1405              "         Compression Type: %-14s\n"),
   1406              _field_classtype_name(ctype)));
   1407 
   1408     if (class_ent->tcam.key != NULL) {
   1409         /* Entry is in tcam data buffer , read it from buffer */
   1410         sal_memcpy(databuf, class_ent->tcam.key, class_ent->tcam.key_size);
   1411     } else {
   1412         /* Entry is in hardware , read it from hardware */
   1413         rv = _bcm_field_th_class_entry_hwread(unit, class_ent,
   1414                                                 ctype, databuf);
   1415         if (BCM_FAILURE(rv)) {
   1416             sal_free(databuf);
   1417             return (rv);
   1418         }
   1419     }
   1420 
   1421     /* Dispaly Entry Key */
   1422     _field_th_class_entry_key_show(unit, class_ent, ctype, databuf);
   1423 
   1424     /* Show Actions attached to entry */
   1425     LOG_CLI((BSL_META_U(unit,"         action=")));
   1426 
   1427     fa = class_ent->actions;
   1428     while (fa != NULL) {
   1429         LOG_CLI((BSL_META("{act=%s, class=0x%x%08x}"),
   1430                 _field_action_name(fa->action), fa->param[1], fa->param[0]));
   1431         fa = fa->next;
   1432     }
   1433     LOG_CLI((BSL_META_U(unit,
   1434                         "\n")));
   1435 
   1436     /* Free Entry Buffer */
   1437     sal_free(databuf);
   1438 
   1439     return (BCM_E_NONE);
   1440 }
   1441 
   1442 /*
   1443  * Function:
   1444  *  _field_th_class_entry_key_show.
   1445  * Purpose:
   1446  *  Read Class Entry From Hardware.
   1447  * Parameters:
   1448  *  unit     - (IN) BCM device number.
   1449  *  entry    - (IN) Field Entry Info.
   1450  *  ctype    - (IN) Field Class Type.
   1451  *  cdata    - (IN) Field Class Entry DataBuffer.
   1452  * Returns:
   1453  */
   1454 STATIC void
   1455 _field_th_class_entry_key_show(int unit, _field_entry_t *class_ent,
   1456                                _field_class_type_t ctype,
   1457                                uint32 *cdata)
   1458 {
   1459     soc_reg_t reg;              /* SOC Register */
   1460     soc_mem_t mem;              /* SOC Memory */
   1461     uint32 keytype = 0;         /* Class Entry Type */
   1462     uint32 validbit = 0;        /* Entry Valid Bit  */
   1463     uint32 cval = 0;            /* Class Entry Value */
   1464     uint32 cmask = 0;           /* Class Entry Mask */
   1465     uint32 cip6_field[4];       /* Class IP6 Field */
   1466     uint32 cip6_field_mask[4];  /* Class IP6 Field Mask */
   1467     bcm_ip6_t cip6_addr;        /* Class IP6 Address */
   1468     bcm_ip6_t cip6_addr_mask;   /* Class IP6 Address Mask */
   1469     int i = 0;                  /* Iterator */
   1470 
   1471     LOG_CLI((BSL_META_U(unit,"         {")));
   1472 
   1473     /* Show Key Based on Class Type */
   1474     switch(ctype) {
   1475         case _FieldClassEtherType:
   1476             reg = ETHERTYPE_MAPr;
   1477             cval = soc_reg_field_get(unit, reg, *cdata, ETHERTYPEf);
   1478             LOG_CLI((BSL_META_U(unit,
   1479                      "EtherType=0x%x"),
   1480                      cval));
   1481             break;
   1482         case _FieldClassTtl:
   1483             LOG_CLI((BSL_META_U(unit,
   1484                      "TTL=%d"),
   1485                      class_ent->tcam.ip_type));
   1486             break;
   1487         case _FieldClassToS:
   1488             LOG_CLI((BSL_META_U(unit,
   1489                      "TOS=%d"),
   1490                      class_ent->tcam.ip_type));
   1491             break;
   1492         case _FieldClassIpProto:
   1493             LOG_CLI((BSL_META_U(unit,
   1494                      "IP Protocol=0x%x"),
   1495                      class_ent->tcam.ip_type));
   1496             break;
   1497         case _FieldClassL4SrcPort:
   1498             reg = L4_SRC_PORT_MAPr;
   1499             keytype = soc_reg_field_get(unit, reg, *cdata, MATCH_TYPEf);
   1500             cval = soc_reg_field_get(unit, reg, *cdata, L4_SRC_PORTf);
   1501             if (keytype == _FP_MATCH_L4_PORT_TYPE) {
   1502                 LOG_CLI((BSL_META_U(unit,
   1503                          "L4 SRC Port=%d"),
   1504                          cval));
   1505             } else if (keytype == _FP_MATCH_EXCHANGE_ID_TYPE) {
   1506                 LOG_CLI((BSL_META_U(unit,
   1507                          "FCoE OxID=0x%x"),
   1508                          cval));
   1509             } else {
   1510                 LOG_CLI((BSL_META_U(unit,
   1511                          "Unknown")));
   1512             }
   1513             break;
   1514         case _FieldClassL4DstPort:
   1515             reg = L4_DST_PORT_MAPr;
   1516             keytype = soc_reg_field_get(unit, reg, *cdata, MATCH_TYPEf);
   1517             cval = soc_reg_field_get(unit, reg , *cdata, L4_DST_PORTf);
   1518             if (keytype == _FP_MATCH_L4_PORT_TYPE) {
   1519                 LOG_CLI((BSL_META_U(unit,
   1520                          "L4 Dst Port=%d"),
   1521                          cval));
   1522             } else if (keytype == _FP_MATCH_EXCHANGE_ID_TYPE) {
   1523                 LOG_CLI((BSL_META_U(unit,
   1524                          "FCoE RxID=0x%x"),
   1525                          cval));
   1526             } else {
   1527                 LOG_CLI((BSL_META_U(unit,
   1528                          "Unknown")));
   1529             }
   1530             break;
   1531         case _FieldClassTcp:
   1532             LOG_CLI((BSL_META_U(unit,
   1533                      "TCP=%d"),
   1534                      class_ent->tcam.ip_type));
   1535             break;
   1536         case _FieldClassSrcCompression:
   1537             mem = SRC_COMPRESSIONm;
   1538             soc_mem_field_get(unit, mem, cdata, KEY_TYPEf, &keytype);
   1539             soc_mem_field_get(unit, mem, cdata, VALIDf, &validbit);
   1540             if (keytype == _FP_KEY_IPv4_TYPE) {
   1541                 soc_mem_field_get(unit, mem, cdata,
   1542                                         IPV4__SIP_V4f, &cval);
   1543                 soc_mem_field_get(unit, mem, cdata,
   1544                                         IPV4__SIP_V4_MASKf, &cmask);
   1545                 LOG_CLI((BSL_META_U(unit,"Source IPv4=0x%x, "),cval));
   1546                 LOG_CLI((BSL_META_U(unit,"IPv4 Mask=0x%x, "),cmask));
   1547             } else if (keytype == _FP_KEY_FCoE_TYPE) {
   1548                 soc_mem_field_get(unit, mem, cdata,
   1549                                         FCOE__S_IDf, &cval);
   1550                 soc_mem_field_get(unit, mem, cdata,
   1551                                         FCOE__S_ID_MASKf, &cmask);
   1552                 LOG_CLI((BSL_META_U(unit,"FCoE S_ID=0x%x, "),cval));
   1553                 LOG_CLI((BSL_META_U(unit,"S_ID Mask=0x%x, "),cmask));
   1554             } else if (keytype == _FP_KEY_IPv6_TYPE) {
   1555                 soc_mem_field_get(unit, mem, cdata,
   1556                                         IPV6__SIP_V6f, cip6_field);
   1557                 soc_mem_field_get(unit, mem, cdata,
   1558                                         IPV6__SIP_V6_MASKf, cip6_field_mask);
   1559                 SAL_IP6_ADDR_FROM_UINT32(cip6_addr, cip6_field);
   1560                 SAL_IP6_ADDR_FROM_UINT32(cip6_addr_mask, cip6_field_mask);
   1561                 LOG_CLI((BSL_META_U(unit,"Source Ipv6= ")));
   1562                 LOG_CLI((BSL_META("0x")));
   1563                 for (i = 0; i < sizeof(bcm_ip6_t) - 1; i++) {
   1564                     LOG_CLI((BSL_META("%02x:"), cip6_addr[i]));
   1565                 }
   1566                 LOG_CLI((BSL_META("%02x"), cip6_addr[i]));
   1567                 LOG_CLI((BSL_META(", ")));
   1568                 LOG_CLI((BSL_META_U(unit,"Ipv6 Mask=")));
   1569                 LOG_CLI((BSL_META("0x")));
   1570                 for (i = 0; i < sizeof(bcm_ip6_t); i++) {
   1571                     LOG_CLI((BSL_META("%02x:"), cip6_addr_mask[i]));
   1572                 }
   1573                 LOG_CLI((BSL_META(", ")));
   1574             } else {
   1575                 LOG_CLI((BSL_META_U(unit,"Unknown, ")));
   1576             }
   1577             soc_mem_field_get(unit, mem, cdata, VRFf, &cval);
   1578             soc_mem_field_get(unit, mem, cdata, VRF_MASKf, &cmask);
   1579 
   1580             LOG_CLI((BSL_META_U(unit,"VRF=0x%x, "),cval));
   1581             LOG_CLI((BSL_META_U(unit,"VRF Mask=0x%x, "),cmask));
   1582             LOG_CLI((BSL_META_U(unit,"Valid=%d"),validbit));
   1583             break;
   1584         case _FieldClassDstCompression:
   1585             mem = DST_COMPRESSIONm;
   1586             soc_mem_field_get(unit, mem, cdata, KEY_TYPEf, &keytype);
   1587             soc_mem_field_get(unit, mem, cdata, VALIDf, &validbit);
   1588             if (keytype == _FP_KEY_IPv4_TYPE) {
   1589                 soc_mem_field_get(unit, mem, cdata,
   1590                                         IPV4__DIP_V4f, &cval);
   1591                 soc_mem_field_get(unit, mem, cdata,
   1592                                         IPV4__DIP_V4_MASKf, &cmask);
   1593                 LOG_CLI((BSL_META_U(unit,"Destination IPv4=0x%x, "),cval));
   1594                 LOG_CLI((BSL_META_U(unit,"IPv4 Mask=0x%x, "),cmask));
   1595             } else if (keytype == _FP_KEY_FCoE_TYPE) {
   1596                 soc_mem_field_get(unit, mem, cdata,
   1597                                         FCOE__D_IDf, &cval);
   1598                 soc_mem_field_get(unit, mem, cdata,
   1599                                         FCOE__D_ID_MASKf, &cmask);
   1600                 LOG_CLI((BSL_META_U(unit,"FCoE D_ID=0x%x, "),cval));
   1601                 LOG_CLI((BSL_META_U(unit,"D_ID Mask=0x%x, "),cmask));
   1602             } else if (keytype == _FP_KEY_IPv6_TYPE) {
   1603                 soc_mem_field_get(unit, mem, cdata,
   1604                                         IPV6__DIP_V6f, cip6_field);
   1605                 soc_mem_field_get(unit, mem, cdata,
   1606                                         IPV6__DIP_V6_MASKf, cip6_field_mask);
   1607                 SAL_IP6_ADDR_FROM_UINT32(cip6_addr, cip6_field);
   1608                 SAL_IP6_ADDR_FROM_UINT32(cip6_addr_mask, cip6_field_mask);
   1609                 LOG_CLI((BSL_META_U(unit,"Destination Ipv6= ")));
   1610                 LOG_CLI((BSL_META("0x")));
   1611                 for (i = 0; i < sizeof(bcm_ip6_t) - 1; i++) {
   1612                     LOG_CLI((BSL_META("%02x:"), cip6_addr[i]));
   1613                 }
   1614                 LOG_CLI((BSL_META("%02x"), cip6_addr[i]));
   1615                 LOG_CLI((BSL_META(", ")));
   1616                 LOG_CLI((BSL_META_U(unit,"Ipv6 Mask=")));
   1617                 LOG_CLI((BSL_META("0x")));
   1618                 for (i = 0; i < sizeof(bcm_ip6_t); i++) {
   1619                     LOG_CLI((BSL_META("%02x:"), cip6_addr_mask[i]));
   1620                 }
   1621                 LOG_CLI((BSL_META(", ")));
   1622             } else {
   1623                 LOG_CLI((BSL_META_U(unit,"Unknown, ")));
   1624             }
   1625             soc_mem_field_get(unit, mem, cdata, VRFf, &cval);
   1626             soc_mem_field_get(unit, mem, cdata, VRF_MASKf, &cmask);
   1627 
   1628             LOG_CLI((BSL_META_U(unit,"VRF=0x%x, "),cval));
   1629             LOG_CLI((BSL_META_U(unit,"VRF Mask=0x%x, "),cmask));
   1630             LOG_CLI((BSL_META_U(unit,"Valid=%d"),validbit));
   1631             break;
   1632 #if defined(BCM_TOMAHAWK_SUPPORT)
   1633         case _FieldClassIpTunnelTtl:
   1634             LOG_CLI((BSL_META_U(unit,
   1635                      "TTL=%d"),
   1636                      class_ent->tcam.ip_type));
   1637             break;
   1638 #endif
   1639         default:
   1640             LOG_CLI((BSL_META_U(unit,"Unknown")));
   1641     }
   1642     LOG_CLI((BSL_META_U(unit,"}\n")));
   1643 }
   1644 
   1645 
   1646 /*
   1647  * Function:
   1648  *  _bcm_field_th_class_entry_create
   1649  * Purpose:
   1650  *  Create Field Class Entry.
   1651  * Parameters:
   1652  *  unit      - (IN) BCM device number.
   1653  *  group     - (IN) Field Group Id.
   1654  *  entry     - (IN) Field Entry.
   1655  * Returns:
   1656  *  BCM_E_XXX
   1657  */
   1658 int
   1659 _bcm_field_th_class_entry_create(int unit, bcm_field_group_t group,
   1660                                             bcm_field_entry_t entry)
   1661 {
   1662     int rv = BCM_E_NONE;        /* Operation Return Status */
   1663     _field_stage_t *stage_fc = NULL;
   1664                                 /* Stage field control info */
   1665     _field_group_t *fg = NULL;
   1666                                 /* Field group info */
   1667     _field_entry_t *f_ent = NULL;
   1668                                 /* Field entry info */
   1669     int mem_sz = 0;             /* Memory allocation size */
   1670     _field_class_info_t **class_status_arr;
   1671                                 /* Field Per Pipe Class Status Array */
   1672     _field_class_info_t *class_status_info;
   1673                                 /* Field Per Compression table status */
   1674     _field_class_type_t ctype;
   1675                                 /* Field Class Type */
   1676     int tcam_sz = 0;            /* TCAM data size */
   1677 
   1678     /* Confirm that 'entry' is not already used on unit */
   1679     if (BCM_SUCCESS(_field_entry_get(unit, entry, _FP_ENTRY_PRIMARY, &f_ent))) {
   1680         LOG_ERROR(BSL_LS_BCM_FP,
   1681                  (BSL_META_U(unit,
   1682                  "FP(unit %d) Error: entry=(%d) already exists.\n"),
   1683                  unit, entry));
   1684         return (BCM_E_EXISTS);
   1685     }
   1686 
   1687     /* Get group control structure. */
   1688     rv = _field_group_get(unit, group, &fg);
   1689     if (BCM_FAILURE(rv)) {
   1690         LOG_ERROR(BSL_LS_BCM_FP,
   1691                  (BSL_META_U(unit,
   1692                  "FP(unit %d) Error: group=(%d) group get failure.\n"),
   1693                  unit, group));
   1694         return (rv);
   1695     }
   1696 
   1697     /* Get group stage control structure. */
   1698     rv = _field_stage_control_get(unit, fg->stage_id, &stage_fc);
   1699     if (BCM_FAILURE(rv)) {
   1700         LOG_ERROR(BSL_LS_BCM_FP,
   1701                  (BSL_META_U(unit,
   1702                  "FP(unit %d) Error: Stage (%d) control get failure.\n"),
   1703                  unit, fg->stage_id));
   1704         return (rv);
   1705     }
   1706 
   1707     /* Allocate and zero memory for field entry. */
   1708     mem_sz = sizeof(_field_entry_t);
   1709 
   1710     _FP_XGS3_ALLOC(f_ent, mem_sz, "field entry");
   1711 
   1712     if (f_ent == NULL) {
   1713         LOG_ERROR(BSL_LS_BCM_FP,
   1714                  (BSL_META_U(unit,
   1715                  "FP(unit %d) Error: allocation failure for "
   1716                  "class field_entry.\n"),
   1717                  unit));
   1718         return (BCM_E_MEMORY);
   1719     }
   1720 
   1721     f_ent->eid = entry;
   1722     f_ent->group = fg;
   1723 
   1724     /* Retreive Class Type from entry qset */
   1725     rv = _bcm_field_th_class_type_qset_get(unit, &fg->qset, &ctype);
   1726     if (BCM_FAILURE(rv)) {
   1727         sal_free(f_ent);
   1728         return rv;
   1729     }
   1730 
   1731     /* Update Class Info Status Structure */
   1732     class_status_arr = stage_fc->class_info_arr[fg->instance];
   1733     if (class_status_arr == NULL) {
   1734         sal_free(f_ent);
   1735         return (BCM_E_INTERNAL);
   1736     }
   1737     class_status_info = class_status_arr[ctype];
   1738     if (class_status_info == NULL) {
   1739         sal_free(f_ent);
   1740         return (BCM_E_INTERNAL);
   1741     }
   1742 
   1743     /* Check if resources are present */
   1744     if ((class_status_info->total_entries_used + 1) >
   1745         (class_status_info->total_entries_available)) {
   1746         sal_free(f_ent);
   1747         LOG_DEBUG(BSL_LS_BCM_FP,
   1748                  (BSL_META_U(unit,
   1749                  "FP(unit %d) Error: no resource available in "
   1750                  "hardware.\n"),
   1751                  unit));
   1752         return (BCM_E_RESOURCE);
   1753     }
   1754 
   1755     /* Allocate memory for tcam key and mask */
   1756     rv = _bcm_field_th_class_size_get(unit, ctype, &tcam_sz);
   1757     if (BCM_FAILURE(rv)) {
   1758         sal_free(f_ent);
   1759         return (rv);
   1760     }
   1761 
   1762     /* Check Tcam Key and Size */
   1763     if ((f_ent->tcam.key != NULL) ||
   1764         (tcam_sz == 0)) {
   1765         sal_free(f_ent);
   1766         return (BCM_E_INTERNAL);
   1767     }
   1768 
   1769     /* Allocate memory for field class entry */
   1770     if (tcam_sz != 0) {
   1771         _FP_XGS3_ALLOC(f_ent->tcam.key, tcam_sz, "field class entry key");
   1772         if (f_ent->tcam.key == NULL) {
   1773             LOG_ERROR(BSL_LS_BCM_FP,
   1774                      (BSL_META_U(unit,
   1775                      "FP(unit %d) Error: allocation failure for "
   1776                      "class entry key\n"),
   1777                      unit));
   1778             sal_free(f_ent);
   1779             return (BCM_E_MEMORY);
   1780         }
   1781     }
   1782 
   1783     /* Add field entry in group structure */
   1784     rv = _field_group_entry_add(unit, fg, f_ent);
   1785     if (BCM_FAILURE(rv)) {
   1786         sal_free(f_ent);
   1787         return (rv);
   1788     }
   1789 
   1790     /* Initialize slice idx */
   1791     f_ent->slice_idx = -1;
   1792 
   1793     /* Set TCAM Key Size */
   1794     f_ent->tcam.key_size = tcam_sz;
   1795 
   1796     /* Increment Field Entry Count */
   1797     fg->group_status.entries_free =
   1798                             fg->group_status.entries_total -
   1799                             fg->group_status.entry_count;
   1800     class_status_info->total_entries_used++;
   1801 
   1802     return (rv);
   1803 }
   1804 
   1805 /*
   1806  * Function:
   1807  *  _bcm_field_th_class_entry_destroy
   1808  * Purpose:
   1809  *  Delete Field Class Entry.
   1810  * Parameters:
   1811  *  unit      - (IN) BCM device number.
   1812  *  entryr    - (IN) Field Class Entry.
   1813  * Returns:
   1814  *  BCM_E_XXX
   1815  * Notes:
   1816  *  This api should not delete entry if install flag
   1817  *  is set. This check happens in calling function.
   1818  */
   1819 int
   1820 _bcm_field_th_class_entry_destroy(int unit, _field_entry_t *entry)
   1821 {
   1822     int rv = BCM_E_NONE;    /* Operation Return Status */
   1823     _field_stage_t *stage_fc;
   1824                             /* Stage field control info */
   1825     _field_group_t *fg;
   1826                             /* Field group info */
   1827     _field_entry_t *f_ent;
   1828                             /* Field Entry info */
   1829     _field_class_info_t **class_status_arr;
   1830                             /* Field Per Pipe Class Status Array */
   1831     _field_class_info_t *class_status_info;
   1832                             /* Field Per Compression table status */
   1833     _field_class_type_t ctype;
   1834                             /* Field Class Type */
   1835 
   1836     /* Input paramter check */
   1837     if ((entry == NULL) ||
   1838         (entry->group == NULL)) {
   1839         return (BCM_E_INTERNAL);
   1840     }
   1841 
   1842     /* Assign Entry and Group Info */
   1843     f_ent = entry;
   1844     fg = f_ent->group;
   1845 
   1846     /* Get group stage control structure. */
   1847     rv = _field_stage_control_get(unit, fg->stage_id, &stage_fc);
   1848     if (BCM_FAILURE(rv)) {
   1849         LOG_ERROR(BSL_LS_BCM_FP,
   1850                  (BSL_META_U(unit,
   1851                  "FP(unit %d) Error: Stage (%d) control get failure.\n"),
   1852                  unit, fg->stage_id));
   1853         return (rv);
   1854     }
   1855 
   1856     /* Retreive Class Type from entry qset */
   1857     rv = _bcm_field_th_class_type_qset_get(unit, &fg->qset, &ctype);
   1858     if (BCM_FAILURE(rv)) {
   1859         return rv;
   1860     }
   1861 
   1862     /* Remove entry from hw before destroying sw image. */
   1863     if (f_ent->flags & _FP_ENTRY_INSTALLED) {
   1864         BCM_IF_ERROR_RETURN(
   1865            _bcm_field_th_class_entry_remove(unit, entry->eid));
   1866     }
   1867 
   1868     /* Update Class status info structure */
   1869     class_status_arr = stage_fc->class_info_arr[fg->instance];
   1870     if (class_status_arr == NULL) {
   1871         return (BCM_E_INTERNAL);
   1872     }
   1873     class_status_info = class_status_arr[ctype];
   1874     if (class_status_info == NULL) {
   1875         return (BCM_E_INTERNAL);
   1876     }
   1877 
   1878     /* Free Entry Data */
   1879     if (f_ent->tcam.key != NULL) {
   1880         sal_free(f_ent->tcam.key);
   1881     }
   1882 
   1883     /* Delete Entry From Linked List */
   1884     rv = _field_group_entry_delete(unit, fg, f_ent);
   1885     if (BCM_FAILURE(rv)) {
   1886         sal_free(f_ent);
   1887         return (rv);
   1888     }
   1889 
   1890     /* Free Field Entry Resource */
   1891     sal_free(f_ent);
   1892 
   1893     /* Decrement Field Entry Used Count */
   1894     fg->group_status.entries_free = fg->group_status.entries_total -
   1895                                     fg->group_status.entry_count;
   1896     class_status_info->total_entries_used--;
   1897 
   1898     return (rv);
   1899 }
   1900 
   1901 /*
   1902  * Function:
   1903  *  _bcm_field_th_class_entry_prio_set
   1904  * Purpose:
   1905  *  Set Priority for Field Class Entry.
   1906  * Parameters:
   1907  *  unit      - (IN) BCM device number.
   1908  *  entry     - (IN) Field Entry.
   1909  *  prio      - (IN) New Field Entry Priority.
   1910  * Returns:
   1911  *  BCM_E_XXX
   1912  */
   1913 int
   1914 _bcm_field_th_class_entry_prio_set(int unit, _field_entry_t *entry, int prio)
   1915 {
   1916     int rv = BCM_E_NONE;        /* Operation Return Status */
   1917     _field_group_t *fg;         /* Field Group Info        */
   1918     _field_class_type_t ctype;  /* Field Class Type        */
   1919     int old_prio = 0;           /* Field Entry Priority    */
   1920 
   1921     /* Input paramter check */
   1922     if ((entry == NULL) ||
   1923         (entry->group == NULL)) {
   1924         return (BCM_E_INTERNAL);
   1925     }
   1926 
   1927     /* Assign Group Info */
   1928     fg = entry->group;
   1929 
   1930     /* Retreive Class Type from entry qset */
   1931     rv = _bcm_field_th_class_type_qset_get(unit, &fg->qset, &ctype);
   1932     if (BCM_FAILURE(rv)) {
   1933         return rv;
   1934     }
   1935 
   1936     /* Modify entry priority. */
   1937     old_prio = entry->prio;
   1938     entry->prio = prio;
   1939 
   1940     /* Set and Sort entry priority. */
   1941     switch (ctype) {
   1942         case _FieldClassEtherType:
   1943         case _FieldClassTtl:
   1944         case _FieldClassToS:
   1945         case _FieldClassIpProto:
   1946         case _FieldClassL4SrcPort:
   1947         case _FieldClassL4DstPort:
   1948         case _FieldClassTcp:
   1949              rv = BCM_E_UNAVAIL;
   1950              break;
   1951         case _FieldClassIpTunnelTtl:
   1952              if ((soc_feature(unit, soc_feature_th3_style_fp))) {
   1953                  rv = BCM_E_NONE;
   1954              } else {
   1955                  rv = BCM_E_UNAVAIL;
   1956              }
   1957              break;
   1958         case _FieldClassSrcCompression:
   1959         case _FieldClassDstCompression:
   1960              if (entry->slice_idx != -1) {
   1961                  rv = _field_th_class_group_sort(unit, fg, ctype);
   1962                  if (BCM_SUCCESS(rv)) {
   1963                      /* coverity[end_of_scope] */
   1964                      return (rv);
   1965                  }
   1966              }
   1967              break;
   1968         default:
   1969              rv = BCM_E_PARAM;
   1970     }
   1971 
   1972     /* Restore old value. */
   1973     if (BCM_FAILURE(rv)) {
   1974         entry->prio = old_prio;
   1975     }
   1976 
   1977     return (rv);
   1978 }
   1979 
   1980 /*
   1981  * Function:
   1982  *  _field_th_class_ent_cmp
   1983  * Purpose:
   1984  *  Compare class entries based on priority.
   1985  * Parameters:
   1986  *  b - (IN) first compared field entry.
   1987  *  a - (IN) second compared field entry.
   1988  * Returns:
   1989  *  a<=>b
   1990  */
   1991 static INLINE int
   1992 _field_th_class_ent_cmp(void *a, void *b)
   1993 {
   1994     _field_class_cmp_info_t *first;
   1995                             /* First Class Entry Configuration.   */
   1996     _field_class_cmp_info_t *second;
   1997                             /* Second Class Entry Configuration.  */
   1998 
   1999     first = (_field_class_cmp_info_t *)a;
   2000     second = (_field_class_cmp_info_t *)b;
   2001 
   2002     if (first->entry_prio < second->entry_prio) {
   2003         return (1);
   2004     } else if (first->entry_prio > second->entry_prio) {
   2005         return (-1);
   2006     }
   2007 
   2008     return (0);
   2009 }
   2010 
   2011 /*
   2012  * Function:
   2013  *  _field_th_class_valid_set
   2014  * Purpose:
   2015  *  Set valid bit of given entry.
   2016  * Parameters:
   2017  *  unit           - (IN) Unit Number.
   2018  *  entry          - (IN) Field Entry Info.
   2019  *  ctype          - (IN) Field Class Type.
   2020  *  valid_bit      - (IN) Valid Bit.
   2021  * Returns:
   2022  */
   2023 STATIC int
   2024 _field_th_class_valid_set(int unit,
   2025                           _field_entry_t *entry,
   2026                           _field_class_type_t ctype,
   2027                           uint32 valid_bit)
   2028 {
   2029     int rv = BCM_E_NONE;        /* Operation Return Status.           */
   2030     _field_stage_t *stage_fc = NULL;
   2031                                 /* Stage field control info.          */
   2032     _field_group_t *fg = NULL;  /* Field Group Info.                  */
   2033     soc_mem_t mem;              /* SOC Memory.                        */
   2034     uint32 cdata[SOC_MAX_MEM_FIELD_WORDS] = {0};
   2035                                 /* Entry buffer.                      */
   2036 
   2037     /* Input paramter check */
   2038     if ((entry == NULL) ||
   2039         (entry->group == NULL)) {
   2040         return (BCM_E_INTERNAL);
   2041     }
   2042 
   2043     /* Check Input Valid Bit. */
   2044     if (valid_bit > 1) {
   2045         return (BCM_E_PARAM);
   2046     }
   2047 
   2048 #ifdef BCM_TOMAHAWK_SUPPORT
   2049      /* VALIDf in SRC_COMPRESSIONm and DST_COMPRESSIONm
   2050       * is two bit wide on TH2 and TD3.*/
   2051     if (valid_bit == 1
   2052         && (SOC_IS_TOMAHAWK2(unit)
   2053         || soc_feature(unit, soc_feature_td3_style_fp))) {
   2054         valid_bit = 3;
   2055     }
   2056 #endif /*BCM_TOMAHAWK2_SUPPORT*/
   2057 
   2058     /* Assign Entry and Group Info */
   2059     fg = entry->group;
   2060 
   2061     /* Get group stage control structure. */
   2062     rv = _field_stage_control_get(unit, fg->stage_id, &stage_fc);
   2063     if (BCM_FAILURE(rv)) {
   2064         LOG_ERROR(BSL_LS_BCM_FP,
   2065                  (BSL_META_U(unit,
   2066                  "FP(unit %d) Error: Stage (%d) control get failure.\n"),
   2067                  unit, fg->stage_id));
   2068         return (rv);
   2069     }
   2070 
   2071     /* Get Memory based on compression and stage mode. */
   2072     switch(ctype) {
   2073         case _FieldClassSrcCompression:
   2074             if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) {
   2075                 mem = SRC_COMPRESSIONm;
   2076             } else {
   2077                 BCM_IF_ERROR_RETURN(_bcm_field_mem_instance_get(unit,
   2078                                                        SRC_COMPRESSIONm,
   2079                                                        fg->instance,
   2080                                                        &mem));
   2081             }
   2082             break;
   2083         case _FieldClassDstCompression:
   2084             if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) {
   2085                 mem = DST_COMPRESSIONm;
   2086             } else {
   2087                 BCM_IF_ERROR_RETURN(_bcm_field_mem_instance_get(unit,
   2088                                                        DST_COMPRESSIONm,
   2089                                                        fg->instance,
   2090                                                        &mem));
   2091             }
   2092             break;
   2093         default:
   2094             rv = BCM_E_PARAM;
   2095     }
   2096 
   2097     /* Check Compression Type. */
   2098     if (BCM_FAILURE(rv)) {
   2099         return (rv);
   2100     }
   2101 
   2102     /* Read Memory */
   2103     rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY,
   2104                       entry->slice_idx, cdata);
   2105     if (BCM_FAILURE(rv)) {
   2106         return (rv);
   2107     }
   2108 
   2109     /* Set valid bit. */
   2110     soc_mem_field_set(unit, mem, cdata,
   2111                       VALIDf, &valid_bit);
   2112 
   2113     /* Write Memory. */
   2114     rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL,
   2115                        entry->slice_idx, cdata);
   2116 
   2117     return (rv);
   2118 }
   2119 
   2120 /*
   2121  * Function:
   2122  *  _field_th_class_entry_copy
   2123  * Purpose:
   2124  *  Copy Entry from old index to new index.
   2125  * Parameters:
   2126  *  unit           - (IN) Unit Number.
   2127  *  mem            - (IN) SoC Memory Identifier.
   2128  *  old_entry_idx  - (IN) Old Entry Index.
   2129  *  new_entry_idx  - (IN) New Entry Index.
   2130  * Returns:
   2131  */
   2132 STATIC int
   2133 _field_th_class_entry_copy(int unit,
   2134                            soc_mem_t mem,
   2135                            uint32 old_entry_idx,
   2136                            uint32 new_entry_idx)
   2137 {
   2138     uint32 cdata[SOC_MAX_MEM_FIELD_WORDS] = {0}; /* Entry buffer. */
   2139     int rv = BCM_E_NONE;
   2140 
   2141     /* Read Memory */
   2142     rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY,
   2143                             old_entry_idx, cdata);
   2144     if (BCM_FAILURE(rv)) {
   2145         return (rv);
   2146     }
   2147     /* Write Memory. */
   2148     rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL,
   2149                              new_entry_idx, cdata);
   2150     return (rv);
   2151 }
   2152 
   2153 /*
   2154  * Function:
   2155  *  _field_th_class_entry_del
   2156  * Purpose:
   2157  *  Delete entry from provided index.
   2158  * Parameters:
   2159  *  unit      - (IN) Unit Number.
   2160  *  mem       - (IN) SoC Memory Identifier.
   2161  *  entry_idx - (IN) Entry Index.
   2162  * Returns:
   2163  */
   2164 STATIC int
   2165 _field_th_class_entry_del(int unit,
   2166                           soc_mem_t mem,
   2167                           uint32 entry_idx)
   2168 {
   2169     uint32 cdata[SOC_MAX_MEM_FIELD_WORDS] = {0}; /* Entry buffer. */
   2170     int rv = BCM_E_NONE;
   2171 
   2172     /* Write Memory. */
   2173     rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL,
   2174                              entry_idx, cdata);
   2175     return rv;
   2176 }
   2177 
   2178 /*
   2179  * Function:
   2180  *  _field_th_class_entry_update
   2181  * Purpose:
   2182  *  Update Class entry old entry idx.
   2183  * Parameters:
   2184  *  unit           - (IN) Unit Number.
   2185  *  class_cmp_info - (IN/OUT) - Class Entry Struct.
   2186  *  valid_entries  - (IN) - Valid entries in array.
   2187  *  old_idx        - (IN) - Old Entry Index.
   2188  *  new_idx        - (IN) - New Entry Index.
   2189  * Returns:
   2190  */
   2191 STATIC void
   2192 _field_th_class_entry_update(int unit,
   2193                              _field_class_cmp_info_t *class_cmp_info,
   2194                              int valid_entries,
   2195                              uint32 old_idx, uint32 new_idx)
   2196 {
   2197     int idx = 0;            /* Index Iterator.   */
   2198     _field_class_cmp_info_t *class_cmp_temp = NULL;
   2199                             /* Class Entry temp. */
   2200     int flag = 0;           /* Flag var.         */
   2201 
   2202     /* Find entry in array. */
   2203     for(idx = 0; idx < valid_entries; idx++) {
   2204         class_cmp_temp = class_cmp_info + idx;
   2205         if (class_cmp_temp->cur_entry_idx == old_idx) {
   2206                 flag = 1;
   2207                 break;
   2208         }
   2209     }
   2210 
   2211     /* Update idx if entry is found. */
   2212     if(flag) {
   2213         class_cmp_temp->cur_entry_idx = new_idx;
   2214     }
   2215 }
   2216 
   2217 /*
   2218  * Function:
   2219  *  _field_th_class_entry_shift
   2220  * Purpose:
   2221  *  Shift Class entry old slice idx.
   2222  * Parameters:
   2223  *  unit           - (IN) Unit Number.
   2224  *  mem            - (IN) SoC Memory Identifier.
   2225  *  class_cmp_info - (IN/OUT) - Class Entry Struct.
   2226  *  valid_entries  - (IN) - Valid entries in array.
   2227  *  old_idx        - (IN) - Old Entry Index.
   2228  *  new_idx        - (IN) - New Entry Index.
   2229  *  Returns:
   2230  *  Notes:
   2231  *    This function shifts entry in hardware from new_idx
   2232  *    to free_idx and shift all entries down by 1.
   2233  */
   2234 STATIC int
   2235 _field_th_class_entry_shift(int unit,
   2236                             soc_mem_t mem,
   2237                            _field_class_cmp_info_t *class_cmp_info,
   2238                            _field_class_info_t *class_status_info,
   2239                            int valid_entries,
   2240                            uint32 new_idx, uint32 free_idx)
   2241 {
   2242     uint32 idx = 0;            /* Index Iterator.            */
   2243     uint32 ent_num = 0;        /* No. of entries to shift.   */
   2244     uint32 cur_shift_idx = 0;  /* Current entry Shift Index. */
   2245     uint32 cur_free_idx = 0;   /* Current free Index.        */
   2246     int rv = BCM_E_NONE;       /* Return Status */
   2247 
   2248     /* Initialise Variables. */
   2249     ent_num = free_idx - new_idx;
   2250     cur_free_idx = free_idx;
   2251 
   2252     /* Shift Entries. */
   2253     if ((class_cmp_info != NULL) &&
   2254         (class_status_info != NULL) &&
   2255         (ent_num > 0)) {
   2256 
   2257         for(idx = 0; idx < ent_num; idx++) {
   2258 
   2259             cur_shift_idx = free_idx - idx - 1;
   2260 
   2261             if (_FP_CLASS_TABLE_BMP_TEST(class_status_info->class_bmp,
   2262                                                         cur_shift_idx)) {
   2263 
   2264                 /* Copy entry from new index to free index. */
   2265                 rv = _field_th_class_entry_copy(unit, mem,
   2266                                            cur_shift_idx, cur_free_idx);
   2267                 BCM_IF_ERROR_RETURN(rv);
   2268 
   2269                 _field_th_class_entry_update(unit,
   2270                                              class_cmp_info,
   2271                                              valid_entries,
   2272                                              cur_shift_idx, cur_free_idx);
   2273                 _FP_CLASS_TABLE_BMP_ADD(class_status_info->class_bmp,
   2274                                                             cur_free_idx);
   2275                 _FP_CLASS_TABLE_BMP_REMOVE(class_status_info->class_bmp,
   2276                                                             cur_shift_idx);
   2277             }
   2278             cur_free_idx--;
   2279         }
   2280     }
   2281     return rv;
   2282 }
   2283 
   2284 /*
   2285  * Function:
   2286  *  _field_th_class_group_sort
   2287  * Purpose:
   2288  *  Sort Provided Class Field Group Entries based on priority.
   2289  * Parameters:
   2290  *  unit  - (IN) Unit.
   2291  *  fg    - (IN/OUT) Field Group Structure.
   2292  *  ctype - (IN) Compression Type.
   2293  * Returns:
   2294  *  BCM_E_XXX
   2295  * Notes:
   2296  *  This api will sort Src/Dst Compression entries
   2297  *  based on priority. It can sort entries only
   2298  *  if there is one free index available in hardware
   2299  *  otherwide it will return error. Also it will do hitless
   2300  *  sort which means order of entry prio does not
   2301  *  change during sorting.
   2302  */
   2303 STATIC int
   2304 _field_th_class_group_sort(int unit,
   2305                            _field_group_t *fg,
   2306                            _field_class_type_t ctype)
   2307 {
   2308     int rv = BCM_E_NONE;        /* Operation Return Status.           */
   2309     _field_stage_t *stage_fc = NULL;
   2310                                 /* Stage field control info.          */
   2311     _field_class_info_t **class_status_arr;
   2312                                 /* Field Per Pipe Class Status Array. */
   2313     _field_class_info_t *class_status_info;
   2314                                 /* Field Per Compression table status.*/
   2315     _field_entry_t *f_ent = NULL;
   2316                                 /* Field Entry Structure.             */
   2317     _field_class_cmp_info_t *class_cmp_info = NULL;
   2318                                 /* Class Entry Compare Info Struct.   */
   2319     _field_class_cmp_info_t *class_cmp_temp = NULL;
   2320                                 /* Class Entry Compare Info Temp.     */
   2321     int idx, valid_entries = 0; /* Index and Valid Entries var.       */
   2322     int entry_count = 0;        /* Entry Count in Software.           */
   2323     int e_idx = 0;              /* Entry Iteration Index.             */
   2324     bcm_field_entry_t *entry_ids = NULL;
   2325                                 /* Entry Id. Array.                   */
   2326                                 /* SOC Per Pipe Memory.               */
   2327     soc_mem_t mem;              /* SOC Memory.                        */
   2328     int free_idx = 0;           /* Free Index in Bitmap..             */
   2329 
   2330     /* Input paramter check */
   2331     if (fg == NULL) {
   2332         return (BCM_E_INTERNAL);
   2333     }
   2334 
   2335     /* Get group stage control structure. */
   2336     rv = _field_stage_control_get(unit, fg->stage_id, &stage_fc);
   2337     if (BCM_FAILURE(rv)) {
   2338         LOG_ERROR(BSL_LS_BCM_FP,
   2339                  (BSL_META_U(unit,
   2340                  "FP(unit %d) Error: Stage (%d) control get failure.\n"),
   2341                  unit, fg->stage_id));
   2342         return (rv);
   2343     }
   2344 
   2345     /* Update Class Info Status Structure */
   2346     class_status_arr = stage_fc->class_info_arr[fg->instance];
   2347     if (class_status_arr == NULL) {
   2348         return (BCM_E_INTERNAL);
   2349     }
   2350     class_status_info = class_status_arr[ctype];
   2351     if (class_status_info == NULL) {
   2352         return (BCM_E_INTERNAL);
   2353     }
   2354 
   2355     /* Check if free entry available in hardware. */
   2356     if(class_status_info->total_entries_used ==
   2357        class_status_info->total_entries_available) {
   2358         return (BCM_E_PARAM);
   2359     }
   2360 
   2361     /* Get Memory based on compression and stage mode. */
   2362     switch(ctype) {
   2363         case _FieldClassSrcCompression:
   2364             if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) {
   2365                 mem = SRC_COMPRESSIONm;
   2366             } else {
   2367                 BCM_IF_ERROR_RETURN(_bcm_field_mem_instance_get(unit,
   2368                                                       SRC_COMPRESSIONm,
   2369                                                       fg->instance,
   2370                                                       &mem));
   2371             }
   2372             break;
   2373         case _FieldClassDstCompression:
   2374             if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) {
   2375                 mem = DST_COMPRESSIONm;
   2376             } else {
   2377                 BCM_IF_ERROR_RETURN(_bcm_field_mem_instance_get(unit,
   2378                                                       DST_COMPRESSIONm,
   2379                                                       fg->instance,
   2380                                                       &mem));
   2381             }
   2382             break;
   2383         default:
   2384             rv = BCM_E_PARAM;
   2385     }
   2386 
   2387     /* Check Compression Type. */
   2388     if (BCM_FAILURE(rv)) {
   2389         return (rv);
   2390     }
   2391 
   2392     /* Count number of valid entries present in hardware. */
   2393     for (idx = 0; idx < class_status_info->total_entries_available; idx++) {
   2394         if (_FP_CLASS_TABLE_BMP_TEST(class_status_info->class_bmp, idx)) {
   2395             valid_entries++;
   2396         }
   2397     }
   2398 
   2399     /* No valid entry found in Hardware. */
   2400     if (!valid_entries) {
   2401         return (BCM_E_NONE);
   2402     }
   2403 
   2404     /* Allocate Memory. */
   2405     _FP_XGS3_ALLOC(class_cmp_info,
   2406                   (valid_entries * sizeof(_field_class_cmp_info_t)),
   2407                   "Field Class Status");
   2408     if (class_cmp_info == NULL) {
   2409         return (BCM_E_MEMORY);
   2410     }
   2411 
   2412     /* Get group's entries */
   2413     entry_count = fg->group_status.entry_count;
   2414     _FP_XGS3_ALLOC(entry_ids,
   2415                   (entry_count * sizeof(bcm_field_entry_t)),
   2416                   "Entry ID array");
   2417     if (entry_ids == NULL) {
   2418         sal_free(class_cmp_info);
   2419         return (BCM_E_MEMORY);
   2420     }
   2421 
   2422     rv = bcm_esw_field_entry_multi_get(unit, fg->gid, entry_count,
   2423                                             entry_ids, &entry_count);
   2424 
   2425     if (BCM_FAILURE(rv)) {
   2426         goto cleanup;
   2427     }
   2428 
   2429     /* Copy entry info into class cmp struct. */
   2430     class_cmp_temp = class_cmp_info;
   2431     for (e_idx = 0; e_idx < entry_count; ++e_idx)
   2432     {
   2433         rv = _bcm_field_entry_get_by_id(unit, entry_ids[e_idx], &f_ent);
   2434         if (BCM_FAILURE(rv)) {
   2435             goto cleanup;
   2436         }
   2437         /* Copy only if entry is installed. */
   2438         if (f_ent->slice_idx != -1) {
   2439             class_cmp_temp->f_ent = f_ent;
   2440             class_cmp_temp->cur_entry_idx = f_ent->slice_idx;
   2441             class_cmp_temp->entry_prio  = f_ent->prio;
   2442             class_cmp_temp++;
   2443         }
   2444     }
   2445 
   2446     /* Sort entries based on priority. */
   2447     _shr_sort(class_cmp_info, valid_entries, sizeof(_field_class_cmp_info_t),
   2448                                                      _field_th_class_ent_cmp);
   2449 
   2450     /* Move entries in Hardware. */
   2451     for (e_idx = 0; e_idx< valid_entries; e_idx++) {
   2452 
   2453         /* Update new slice idx. */
   2454         class_cmp_temp = class_cmp_info + e_idx;
   2455         class_cmp_temp->new_entry_idx = e_idx;
   2456         class_cmp_temp->f_ent->slice_idx = class_cmp_temp->new_entry_idx;
   2457 
   2458         /* Check if new index is free. If yes then move entry from
   2459          * old index to new and mark old as free. */
   2460 
   2461         if (!(_FP_CLASS_TABLE_BMP_TEST(class_status_info->class_bmp, e_idx))) {
   2462 
   2463             /* Copy entry from old index to new index. */
   2464             rv = _field_th_class_entry_copy(unit, mem,
   2465                                    class_cmp_temp->cur_entry_idx, e_idx);
   2466             if (BCM_FAILURE(rv)) {
   2467                 goto cleanup;
   2468             }
   2469 
   2470             _FP_CLASS_TABLE_BMP_ADD(class_status_info->class_bmp, e_idx);
   2471 
   2472             /* Delete entry from old index. */
   2473             rv = _field_th_class_entry_del(unit, mem,
   2474                                       class_cmp_temp->cur_entry_idx);
   2475             if (BCM_FAILURE(rv)) {
   2476                 goto cleanup;
   2477             }
   2478 
   2479             _FP_CLASS_TABLE_BMP_REMOVE(class_status_info->class_bmp,
   2480                                        class_cmp_temp->cur_entry_idx);
   2481             class_cmp_temp->cur_entry_idx = e_idx;
   2482         } else {
   2483 
   2484             /* New index is not free, do something only if
   2485              * new index is different from old index. */
   2486             if (class_cmp_temp->cur_entry_idx != e_idx) {
   2487 
   2488                 /* Find free index, it has to be greater than new index. */
   2489                 for (idx = 0; idx < class_status_info->total_entries_available;
   2490                                                                         idx++) {
   2491                     if (0 == _FP_CLASS_TABLE_BMP_TEST(
   2492                                            class_status_info->class_bmp, idx)) {
   2493                         free_idx = idx;
   2494                         break;
   2495                     }
   2496                 }
   2497                 if (free_idx > e_idx) {
   2498 
   2499                     /* Shift entries down starting from e_idx to free_idx and
   2500                      * mark e_idx as free. */
   2501                     rv = _field_th_class_entry_shift(unit, mem,
   2502                                                 class_cmp_info,
   2503                                                 class_status_info,
   2504                                                 valid_entries,
   2505                                                 e_idx, free_idx);
   2506                     if (BCM_FAILURE(rv)) {
   2507                         goto cleanup;
   2508                     }
   2509                     /* Now copy entry to new idx. */
   2510                     rv = _field_th_class_entry_copy(unit, mem,
   2511                                                class_cmp_temp->cur_entry_idx,
   2512                                                e_idx);
   2513                     if (BCM_FAILURE(rv)) {
   2514                         goto cleanup;
   2515                     }
   2516 
   2517                     _FP_CLASS_TABLE_BMP_ADD(class_status_info->class_bmp, e_idx);
   2518 
   2519                     /* Delete entry from old index. */
   2520                     rv = _field_th_class_entry_del(unit, mem,
   2521                                               class_cmp_temp->cur_entry_idx);
   2522                     if (BCM_FAILURE(rv)) {
   2523                         goto cleanup;
   2524                     }
   2525 
   2526                     _FP_CLASS_TABLE_BMP_REMOVE(class_status_info->class_bmp,
   2527                                                class_cmp_temp->cur_entry_idx);
   2528                     class_cmp_temp->cur_entry_idx = e_idx;
   2529                 }
   2530             }
   2531         }
   2532     }
   2533 
   2534 cleanup:
   2535 
   2536     /* Free Resources. */
   2537     sal_free(entry_ids);
   2538     sal_free(class_cmp_info);
   2539 
   2540     return (rv);
   2541 }
   2542 
   2543 /*
   2544  * Function:
   2545  *  _bcm_field_th_class_entry_prio_get
   2546  * Purpose:
   2547  *  Get Priority for Field Class Entry.
   2548  * Parameters:
   2549  *  unit      - (IN) BCM device number.
   2550  *  entry     - (IN) Field Entry.
   2551  * Returns:
   2552  *  BCM_E_XXX
   2553  */
   2554 int
   2555 _bcm_field_th_class_entry_prio_get(int unit, _field_entry_t *entry)
   2556 {
   2557     int rv = BCM_E_NONE;        /* Operation Return Status */
   2558     _field_group_t *fg;         /* Field Group Info        */
   2559     _field_class_type_t ctype;  /* Field Class Type        */
   2560 
   2561     /* Input paramter check */
   2562     if ((entry == NULL) ||
   2563         (entry->group == NULL)) {
   2564         return (BCM_E_INTERNAL);
   2565     }
   2566 
   2567     /* Assign Entry and Group Info */
   2568     fg = entry->group;
   2569 
   2570     /* Retreive Class Type from entry qset */
   2571     rv = _bcm_field_th_class_type_qset_get(unit, &fg->qset, &ctype);
   2572     if (BCM_FAILURE(rv)) {
   2573         return rv;
   2574     }
   2575 
   2576     /* Set and Sort entry priority. */
   2577     switch (ctype) {
   2578         case _FieldClassEtherType:
   2579         case _FieldClassTtl:
   2580         case _FieldClassToS:
   2581         case _FieldClassIpProto:
   2582         case _FieldClassL4SrcPort:
   2583         case _FieldClassL4DstPort:
   2584         case _FieldClassTcp:
   2585              rv = BCM_E_UNAVAIL;
   2586              break;
   2587         case _FieldClassIpTunnelTtl:
   2588              if ((soc_feature(unit, soc_feature_th3_style_fp))) {
   2589                  rv = BCM_E_NONE;
   2590              } else {
   2591                  rv = BCM_E_UNAVAIL;
   2592              }
   2593              break;
   2594         case _FieldClassSrcCompression:
   2595         case _FieldClassDstCompression:
   2596              rv = BCM_E_NONE;
   2597              break;
   2598         default:
   2599              rv = BCM_E_PARAM;
   2600     }
   2601 
   2602     return (rv);
   2603 }
   2604 
   2605 /*
   2606  * Function:
   2607  *  _bcm_field_th_class_qualify_set
   2608  * Purpose:
   2609  *  Qualify Field Class Entry.
   2610  * Parameters:
   2611  *  unit      - (IN) BCM device number.
   2612  *  entry     - (IN) Field Class Entry Id.
   2613  *  qual      - (IN) Field Qualifier.
   2614  *  data      - (IN) Qualify Data Value.
   2615  *  mask      - (IN) Qualify Data Mask.
   2616  * Returns:
   2617  *  BCM_E_XXX
   2618  */
   2619 int
   2620 _bcm_field_th_class_qualify_set(int unit, bcm_field_entry_t entry,
   2621                                     int qual, uint32 *data, uint32 *mask)
   2622 {
   2623     int rv = BCM_E_NONE;        /* Operation Return Status */
   2624     uint32 *cdata = NULL;       /* Field Class Data */
   2625     bcm_field_qset_t cqset;     /* Class Qset */
   2626     _field_class_type_t ctype;  /* Field Class Type */
   2627     soc_reg_t reg;              /* SOC Register */
   2628     soc_mem_t mem;              /* SOC Memory */
   2629     _field_entry_t *class_ent = NULL;
   2630                                 /* Field Class Entry */
   2631     uint32 keytype = 0;         /* Field Class Key Type */
   2632     uint32 keymask = 0;         /* Field Class Key Type Mask */
   2633     uint32 validen = 0;         /* Valid Enable */
   2634 
   2635     /* Retrieve the field entry. */
   2636     rv = _field_entry_get(unit, entry, _FP_ENTRY_PRIMARY, &class_ent);
   2637     BCM_IF_ERROR_RETURN(rv);
   2638 
   2639     /* Initialize Class Qset */
   2640     BCM_FIELD_QSET_INIT(cqset);
   2641 
   2642     /* Input Parameter Check */
   2643     if (class_ent->group == NULL) {
   2644         return (BCM_E_INTERNAL);
   2645     }
   2646 
   2647     /* Input Group Stage Check */
   2648     if (class_ent->group->stage_id !=
   2649                 _BCM_FIELD_STAGE_CLASS) {
   2650         return (BCM_E_INTERNAL);
   2651     }
   2652 
   2653     /* Add qual in class qset */
   2654     BCM_FIELD_QSET_ADD(cqset, qual);
   2655 
   2656     /*
   2657      * Check if qual is present in entry group qset
   2658      */
   2659     if(!(_field_qset_is_subset(&cqset, &class_ent->group->qset))) {
   2660         LOG_DEBUG(BSL_LS_BCM_FP,
   2661                 (BSL_META_U(unit,
   2662                  "FP(unit %d) Error: Qual=%s not in group=%d "
   2663                  "qset.\n"),
   2664                  unit, _field_qual_name(qual),class_ent->group->gid));
   2665         return (BCM_E_PARAM);
   2666     }
   2667 
   2668     /* Retreive Class Type from entry qset */
   2669     rv = _bcm_field_th_class_type_qset_get(unit,
   2670                                            &class_ent->group->qset,
   2671                                            &ctype);
   2672     if (BCM_FAILURE(rv)) {
   2673         return (rv);
   2674     }
   2675 
   2676     /* Assign class data buffer */
   2677     if (class_ent->tcam.key == NULL) {
   2678         if ((class_ent->flags & _FP_ENTRY_INSTALLED) &&
   2679             (class_ent->slice_idx != -1)) {
   2680             /* Allocate memory for class data */
   2681             _FP_XGS3_ALLOC(class_ent->tcam.key,
   2682                            class_ent->tcam.key_size, "field class data buf");
   2683             if (class_ent->tcam.key == NULL) {
   2684                 LOG_ERROR(BSL_LS_BCM_FP,
   2685                         (BSL_META_U(unit,
   2686                          "FP(unit %d) Error: allocation failure for "
   2687                          "field class data buf\n"),
   2688                          unit));
   2689                 return (BCM_E_MEMORY);
   2690             }
   2691             /* Entry is in hardware , read it from hardware */
   2692             rv = _bcm_field_th_class_entry_hwread(unit, class_ent,
   2693                                                   ctype, class_ent->tcam.key);
   2694             if (BCM_FAILURE(rv)) {
   2695                 sal_free(class_ent->tcam.key);
   2696                 return (rv);
   2697             }
   2698         } else {
   2699             return (BCM_E_INTERNAL);
   2700         }
   2701     }
   2702 
   2703     cdata = class_ent->tcam.key;
   2704 
   2705     switch(ctype) {
   2706         case _FieldClassEtherType:
   2707             reg = ETHERTYPE_MAPr;
   2708             soc_reg_field_set(unit, reg, cdata,
   2709                                     ETHERTYPEf, *data);
   2710             break;
   2711         case _FieldClassTtl:
   2712             class_ent->tcam.ip_type = *data;
   2713             break;
   2714         case _FieldClassToS:
   2715             class_ent->tcam.ip_type = *data;
   2716             break;
   2717         case _FieldClassIpProto:
   2718             class_ent->tcam.ip_type = *data;
   2719             break;
   2720         case _FieldClassL4SrcPort:
   2721             /*
   2722              * Validate L4 Src Port,should not be
   2723              * more than 16 bits
   2724              */
   2725             if (*data & ~(0xFFFF)) {
   2726                 return (BCM_E_PARAM);
   2727             }
   2728             reg = L4_SRC_PORT_MAPr;
   2729             if (qual == bcmFieldQualifyL4SrcPort) {
   2730                 keytype = _FP_MATCH_L4_PORT_TYPE;
   2731                 soc_reg_field_set(unit, reg, cdata,
   2732                                         MATCH_TYPEf, keytype);
   2733                 soc_reg_field_set(unit, reg, cdata,
   2734                                         L4_SRC_PORTf, *data);
   2735             } else if (qual == bcmFieldQualifyFcoeOxID) {
   2736                 keytype = _FP_MATCH_EXCHANGE_ID_TYPE;
   2737                 soc_reg_field_set(unit, reg, cdata,
   2738                                         MATCH_TYPEf, keytype);
   2739                 soc_reg_field_set(unit, reg, cdata,
   2740                                         L4_SRC_PORTf, *data);
   2741             } else {
   2742                 rv = BCM_E_PARAM;
   2743             }
   2744             break;
   2745         case _FieldClassL4DstPort:
   2746             /*
   2747              * Validate L4 Dst Port,should not be
   2748              * more than 16 bits
   2749              */
   2750             if (*data & ~(0xFFFF)) {
   2751                 return (BCM_E_PARAM);
   2752             }
   2753             reg = L4_DST_PORT_MAPr;
   2754             if (qual == bcmFieldQualifyL4DstPort) {
   2755                 keytype = _FP_MATCH_L4_PORT_TYPE;
   2756                 soc_reg_field_set(unit, reg, cdata,
   2757                                         MATCH_TYPEf, keytype);
   2758                 soc_reg_field_set(unit, reg, cdata,
   2759                                         L4_DST_PORTf, *data);
   2760             } else if (qual == bcmFieldQualifyFcoeRxID) {
   2761                 keytype = _FP_MATCH_EXCHANGE_ID_TYPE;
   2762                 soc_reg_field_set(unit, reg, cdata,
   2763                                         MATCH_TYPEf, keytype);
   2764                 soc_reg_field_set(unit, reg, cdata,
   2765                                         L4_DST_PORTf, *data);
   2766             } else {
   2767                 rv = BCM_E_PARAM;
   2768             }
   2769             break;
   2770         case _FieldClassTcp:
   2771             class_ent->tcam.ip_type = *data;
   2772             break;
   2773         case _FieldClassSrcCompression:
   2774             mem = SRC_COMPRESSIONm;
   2775             validen = 0;
   2776             if (qual == bcmFieldQualifySrcIp) {
   2777 
   2778                 keytype = _FP_KEY_IPv4_TYPE;
   2779                 keymask = _FP_KEY_TYPE_MASK;
   2780 
   2781                 soc_mem_field_set(unit, mem, cdata,
   2782                                              KEY_TYPEf, &keytype);
   2783                 soc_mem_field_set(unit, mem, cdata,
   2784                                              KEY_TYPE_MASKf, &keymask);
   2785                 soc_mem_field_set(unit, mem, cdata,
   2786                                              VALIDf, &validen);
   2787                 soc_mem_field_set(unit, mem, cdata,
   2788                                              IPV4__SIP_V4f, data);
   2789                 soc_mem_field_set(unit, mem, cdata,
   2790                                              IPV4__SIP_V4_MASKf, mask);
   2791 
   2792             } else if (qual == bcmFieldQualifyFibreChanSrcId) {
   2793                 /*
   2794                  * Validate Fibre Chan Src ID,
   2795                  * should not be more than 24 bits.
   2796                  */
   2797                 if ((*data & ~(0xFFFFFF)) ||
   2798                     (*mask & ~(0xFFFFFF))) {
   2799                     return (BCM_E_PARAM);
   2800                 }
   2801                 keytype = _FP_KEY_FCoE_TYPE;
   2802                 keymask = _FP_KEY_TYPE_MASK;
   2803 
   2804                 soc_mem_field_set(unit, mem, cdata,
   2805                                              KEY_TYPEf, &keytype);
   2806                 soc_mem_field_set(unit, mem, cdata,
   2807                                              KEY_TYPE_MASKf, &keymask);
   2808                 soc_mem_field_set(unit, mem, cdata,
   2809                                              VALIDf, &validen);
   2810                 soc_mem_field_set(unit, mem, cdata,
   2811                                              FCOE__S_IDf, data);
   2812                 soc_mem_field_set(unit, mem, cdata,
   2813                                              FCOE__S_ID_MASKf, mask);
   2814 
   2815             } else if (qual == bcmFieldQualifySrcIp6) {
   2816 
   2817                 keytype = _FP_KEY_IPv6_TYPE;
   2818                 keymask = _FP_KEY_TYPE_MASK;
   2819 
   2820                 soc_mem_field_set(unit, mem, cdata,
   2821                                              KEY_TYPEf, &keytype);
   2822                 soc_mem_field_set(unit, mem, cdata,
   2823                                              KEY_TYPE_MASKf, &keymask);
   2824                 soc_mem_field_set(unit, mem, cdata,
   2825                                              VALIDf, &validen);
   2826                 soc_mem_field_set(unit, mem, cdata,
   2827                                              IPV6__SIP_V6f, data);
   2828                 soc_mem_field_set(unit, mem, cdata,
   2829                                              IPV6__SIP_V6_MASKf, mask);
   2830 
   2831             } else if (qual == bcmFieldQualifyVrf) {
   2832                 /*
   2833                  * Validate VRF Id,
   2834                  * should not be more than 11 bits for TH/TH2.
   2835                  * should not be more than 12 bits for TD3.
   2836                  */
   2837                 if (SOC_IS_TOMAHAWKX(unit)
   2838                     && ((*data & ~(0x7FF)) || (*mask & ~(0x7FF)))) {
   2839                     return (BCM_E_PARAM);
   2840                 }
   2841 #if defined(BCM_TRIDENT3_SUPPORT)
   2842                 else {
   2843                     if (soc_feature(unit, soc_feature_td3_style_fp)
   2844                         && ((*data & ~(0xFFF)) || (*mask & ~(0xFFF)))) {
   2845                         return (BCM_E_PARAM);
   2846                     }
   2847                 }
   2848 #endif
   2849                 soc_mem_field_set(unit, mem, cdata,
   2850                                              VRFf, data);
   2851                 soc_mem_field_set(unit, mem, cdata,
   2852                                              VRF_MASKf, mask);
   2853             } else {
   2854                 rv = BCM_E_PARAM;
   2855             }
   2856             break;
   2857         case _FieldClassDstCompression:
   2858             mem = DST_COMPRESSIONm;
   2859             validen = 0;
   2860 
   2861             if (qual == bcmFieldQualifyDstIp) {
   2862 
   2863                 keytype = _FP_KEY_IPv4_TYPE;
   2864                 keymask = _FP_KEY_TYPE_MASK;
   2865 
   2866                 soc_mem_field_set(unit, mem, cdata,
   2867                                              KEY_TYPEf, &keytype);
   2868                 soc_mem_field_set(unit, mem, cdata,
   2869                                              KEY_TYPE_MASKf, &keymask);
   2870                 soc_mem_field_set(unit, mem, cdata,
   2871                                              VALIDf, &validen);
   2872                 soc_mem_field_set(unit, mem, cdata,
   2873                                              IPV4__DIP_V4f, data);
   2874                 soc_mem_field_set(unit, mem, cdata,
   2875                                              IPV4__DIP_V4_MASKf, mask);
   2876 
   2877             } else if (qual == bcmFieldQualifyFibreChanDstId) {
   2878                 /*
   2879                  * Validate Fibre Chan Dst ID,
   2880                  * should not be more than 24 bits.
   2881                  */
   2882                 if ((*data & ~(0xFFFFFF)) ||
   2883                     (*mask & ~(0xFFFFFF))) {
   2884                     return (BCM_E_PARAM);
   2885                 }
   2886 
   2887                 keytype  = _FP_KEY_FCoE_TYPE;
   2888                 keymask = _FP_KEY_TYPE_MASK;
   2889 
   2890                 soc_mem_field_set(unit, mem, cdata,
   2891                                              KEY_TYPEf, &keytype);
   2892                 soc_mem_field_set(unit, mem, cdata,
   2893                                              KEY_TYPE_MASKf, &keymask);
   2894                 soc_mem_field_set(unit, mem, cdata,
   2895                                              VALIDf, &validen);
   2896                 soc_mem_field_set(unit, mem, cdata,
   2897                                              FCOE__D_IDf, data);
   2898                 soc_mem_field_set(unit, mem, cdata,
   2899                                              FCOE__D_ID_MASKf, mask);
   2900 
   2901             } else if (qual == bcmFieldQualifyDstIp6) {
   2902 
   2903                 keytype = _FP_KEY_IPv6_TYPE;
   2904                 keymask = _FP_KEY_TYPE_MASK;
   2905 
   2906                 soc_mem_field_set(unit, mem, cdata,
   2907                                              KEY_TYPEf, &keytype);
   2908                 soc_mem_field_set(unit, mem, cdata,
   2909                                              KEY_TYPE_MASKf, &keymask);
   2910                 soc_mem_field_set(unit, mem, cdata,
   2911                                              VALIDf, &validen);
   2912                 soc_mem_field_set(unit, mem, cdata,
   2913                                              IPV6__DIP_V6f, data);
   2914                 soc_mem_field_set(unit, mem, cdata,
   2915                                              IPV6__DIP_V6_MASKf, mask);
   2916 
   2917             } else if (qual == bcmFieldQualifyVrf) {
   2918                 /*
   2919                  * Validate VRF Id,
   2920                  * should not be more than 11 bits for TH/TH2.
   2921                  * should not be more than 12 bits for TD3.
   2922                  */
   2923                 if (SOC_IS_TOMAHAWKX(unit)
   2924                     && ((*data & ~(0x7FF)) || (*mask & ~(0x7FF)))) {
   2925                     return (BCM_E_PARAM);
   2926                 }
   2927 #if defined(BCM_TRIDENT3_SUPPORT)
   2928                 else {
   2929                     if (soc_feature(unit, soc_feature_td3_style_fp)
   2930                         && ((*data & ~(0xFFF)) || (*mask & ~(0xFFF)))) {
   2931                         return (BCM_E_PARAM);
   2932                     }
   2933                 }
   2934 #endif
   2935                 soc_mem_field_set(unit, mem, cdata,
   2936                                              VRFf, data);
   2937                 soc_mem_field_set(unit, mem, cdata,
   2938                                              VRF_MASKf, mask);
   2939             } else {
   2940                 rv = BCM_E_PARAM;
   2941             }
   2942             break;
   2943         case _FieldClassIpTunnelTtl:
   2944             class_ent->tcam.ip_type = *data;
   2945             break;
   2946         default:
   2947             rv = BCM_E_PARAM;
   2948     }
   2949 
   2950     /* Mark entry as dirty. */
   2951     class_ent->flags |= _FP_ENTRY_DIRTY;
   2952 
   2953     return (rv);
   2954 }
   2955 
   2956 /*
   2957  * Function:
   2958  *  _bcm_field_th_class_entry_qualifier_key_get
   2959  * Purpose:
   2960  *  Get Qualify Field Class Entry.
   2961  * Parameters:
   2962  *  unit      - (IN) BCM device number.
   2963  *  entry     - (IN) Field Class Entry ID.
   2964  *  qual_id   - (IN) Field Qualifier ID.
   2965  *  q_data    - (OUT) Qualifier Data Array
   2966  *  q_mask    - (OUT) Qualifier Mask Array.
   2967  * Returns:
   2968  *  BCM_E_XXX
   2969  */
   2970 int
   2971 _bcm_field_th_class_entry_qualifier_key_get(int unit,
   2972                                             bcm_field_entry_t entry,
   2973                                             int qual_id,
   2974                                             _bcm_field_qual_data_t q_data,
   2975                                             _bcm_field_qual_data_t q_mask)
   2976 {
   2977     int rv = BCM_E_NONE;                /* Operation Return Status */
   2978     _field_group_t *fg = NULL;          /* Field group info */
   2979     _field_entry_t *class_ent = NULL;   /* Field entry info */
   2980     _field_class_type_t ctype;          /* Field Class Type */
   2981     uint32 *databuf = 0;                /* Data Buffer */
   2982     soc_reg_t reg;                      /* SOC Register */
   2983     soc_mem_t mem;                      /* SOC Memory */
   2984     uint32 keytype = 0;                 /* Class Entry Type */
   2985     bcm_field_qset_t cqset;             /* Class Qset */
   2986 
   2987     /* Confirm that 'entry' is  present on unit */
   2988     if (BCM_FAILURE(_field_entry_get(unit, entry, _FP_ENTRY_PRIMARY,
   2989                                                         &class_ent))) {
   2990         LOG_ERROR(BSL_LS_BCM_FP,
   2991                  (BSL_META_U(unit,
   2992                  "FP(unit %d) Error: entry=(%d) does not exists.\n"),
   2993                  unit, entry));
   2994         return (BCM_E_BADID);
   2995     }
   2996 
   2997     /* Retreive Field Group Info */
   2998     fg = class_ent->group;
   2999 
   3000     /* Skip if stage is not class */
   3001     if (fg->stage_id != _BCM_FIELD_STAGE_CLASS) {
   3002         return (BCM_E_NONE);
   3003     }
   3004 
   3005     /* Initialize Class Qset */
   3006     BCM_FIELD_QSET_INIT(cqset);
   3007 
   3008     /* Add qual in class qset */
   3009     BCM_FIELD_QSET_ADD(cqset, qual_id);
   3010 
   3011     /*
   3012      * Check if qual is present in entry group
   3013      * qset.
   3014      */
   3015     if(!(_field_qset_is_subset(&cqset, &class_ent->group->qset))) {
   3016         LOG_DEBUG(BSL_LS_BCM_FP,
   3017                 (BSL_META_U(unit,
   3018                     "FP(unit %d) Error: Qual=%s not in group=%d "
   3019                     "qset.\n"),
   3020                  unit, _field_qual_name(qual_id),class_ent->group->gid));
   3021         return (BCM_E_NOT_FOUND);
   3022     }
   3023 
   3024     /* Retreive Class Type from entry qset */
   3025     rv = _bcm_field_th_class_type_qset_get(unit, &fg->qset, &ctype);
   3026     if (BCM_FAILURE(rv)) {
   3027         return (rv);
   3028     }
   3029 
   3030     /* Allocate memory for class data */
   3031     _FP_XGS3_ALLOC(databuf, class_ent->tcam.key_size, "field class data buf");
   3032     if (databuf == NULL) {;
   3033         LOG_ERROR(BSL_LS_BCM_FP,
   3034                  (BSL_META_U(unit,
   3035                  "FP(unit %d) Error: allocation failure for "
   3036                  "field class data buf\n"),
   3037                  unit));
   3038         return (BCM_E_MEMORY);
   3039     }
   3040 
   3041     if (class_ent->tcam.key != NULL) {
   3042         /* Entry is in tcam data buffer , read it from buffer */
   3043         sal_memcpy(databuf, class_ent->tcam.key, class_ent->tcam.key_size);
   3044     } else {
   3045         /* Entry is in hardware , read it from hardware */
   3046         rv = _bcm_field_th_class_entry_hwread(unit, class_ent,
   3047                                               ctype, databuf);
   3048         if (BCM_FAILURE(rv)) {
   3049             sal_free(databuf);
   3050             return (rv);
   3051         }
   3052     }
   3053 
   3054     switch(ctype) {
   3055         case _FieldClassEtherType:
   3056             reg = ETHERTYPE_MAPr;
   3057             if (qual_id == bcmFieldQualifyEtherType) {
   3058                 q_data[0] = soc_reg_field_get(unit, reg, *databuf,
   3059                                                     ETHERTYPEf);
   3060             }
   3061             break;
   3062         case _FieldClassTtl:
   3063             if (qual_id == bcmFieldQualifyTtl) {
   3064                 q_data[0] = class_ent->tcam.ip_type;
   3065             }
   3066             break;
   3067         case _FieldClassToS:
   3068             if (qual_id == bcmFieldQualifyTos) {
   3069                 q_data[0] = class_ent->tcam.ip_type;
   3070             }
   3071             break;
   3072         case _FieldClassIpProto:
   3073             if (qual_id == bcmFieldQualifyIpProtocol) {
   3074                 q_data[0] = class_ent->tcam.ip_type;
   3075             }
   3076             break;
   3077         case _FieldClassL4SrcPort:
   3078             reg = L4_SRC_PORT_MAPr;
   3079             keytype = soc_reg_field_get(unit, reg, *databuf,
   3080                                               MATCH_TYPEf);
   3081             if ((keytype == _FP_MATCH_L4_PORT_TYPE) &&
   3082                 (qual_id == bcmFieldQualifyL4SrcPort)) {
   3083                 q_data[0] = soc_reg_field_get(unit, reg, *databuf,
   3084                                                     L4_SRC_PORTf);
   3085             }
   3086             if ((keytype == _FP_MATCH_EXCHANGE_ID_TYPE) &&
   3087                 (qual_id == bcmFieldQualifyFcoeOxID)) {
   3088                 q_data[0] = soc_reg_field_get(unit, reg, *databuf,
   3089                                                     L4_SRC_PORTf);
   3090             }
   3091             break;
   3092         case _FieldClassL4DstPort:
   3093             reg = L4_DST_PORT_MAPr;
   3094             keytype = soc_reg_field_get(unit, reg, *databuf,
   3095                                               MATCH_TYPEf);
   3096             if ((keytype == _FP_MATCH_L4_PORT_TYPE) &&
   3097                 (qual_id == bcmFieldQualifyL4DstPort)) {
   3098                 q_data[0] = soc_reg_field_get(unit, reg, *databuf,
   3099                                                     L4_DST_PORTf);
   3100             }
   3101             if ((keytype == _FP_MATCH_EXCHANGE_ID_TYPE) &&
   3102                 (qual_id == bcmFieldQualifyFcoeRxID)) {
   3103                 q_data[0] = soc_reg_field_get(unit, reg, *databuf,
   3104                                                     L4_DST_PORTf);
   3105             }
   3106             break;
   3107         case _FieldClassTcp:
   3108             if (qual_id == bcmFieldQualifyTcpControl) {
   3109                 q_data[0] = class_ent->tcam.ip_type;
   3110             }
   3111             break;
   3112         case _FieldClassSrcCompression:
   3113             mem = SRC_COMPRESSIONm;
   3114             soc_mem_field_get(unit, mem, databuf,
   3115                                     KEY_TYPEf, &keytype);
   3116             if (keytype == _FP_KEY_IPv4_TYPE &&
   3117                 (qual_id == bcmFieldQualifySrcIp)) {
   3118                 soc_mem_field_get(unit, mem, databuf,
   3119                                         IPV4__SIP_V4f, q_data);
   3120                 soc_mem_field_get(unit, mem, databuf,
   3121                                         IPV4__SIP_V4_MASKf, q_mask);
   3122             } else if (keytype == _FP_KEY_FCoE_TYPE &&
   3123                 (qual_id == bcmFieldQualifyFibreChanSrcId)) {
   3124                 soc_mem_field_get(unit, mem, databuf,
   3125                                         FCOE__S_IDf, q_data);
   3126                 soc_mem_field_get(unit, mem, databuf,
   3127                                         FCOE__S_ID_MASKf, q_mask);
   3128             } else if (keytype == _FP_KEY_IPv6_TYPE &&
   3129                 (qual_id == bcmFieldQualifySrcIp6)) {
   3130                 soc_mem_field_get(unit, mem, databuf,
   3131                                         IPV6__SIP_V6f, q_data);
   3132                 soc_mem_field_get(unit, mem, databuf,
   3133                                         IPV6__SIP_V6_MASKf, q_mask);
   3134             } else {
   3135                 /* Do Nothing */
   3136             }
   3137             if (qual_id == bcmFieldQualifyVrf) {
   3138                 soc_mem_field_get(unit, mem, databuf,
   3139                                         VRFf, q_data);
   3140                 soc_mem_field_get(unit, mem, databuf,
   3141                                         VRF_MASKf, q_mask);
   3142             }
   3143             break;
   3144         case _FieldClassDstCompression:
   3145             mem = DST_COMPRESSIONm;
   3146             soc_mem_field_get(unit, mem, databuf,
   3147                                     KEY_TYPEf, &keytype);
   3148             if ((keytype == _FP_KEY_IPv4_TYPE) &&
   3149                 (qual_id == bcmFieldQualifyDstIp)) {
   3150 
   3151                 soc_mem_field_get(unit, mem, databuf,
   3152                                         IPV4__DIP_V4f, q_data);
   3153                 soc_mem_field_get(unit, mem, databuf,
   3154                                         IPV4__DIP_V4_MASKf, q_mask);
   3155             } else if ((keytype == _FP_KEY_FCoE_TYPE) &&
   3156                        (qual_id == bcmFieldQualifyFibreChanDstId)) {
   3157 
   3158                 soc_mem_field_get(unit, mem, databuf,
   3159                                         FCOE__D_IDf, q_data);
   3160                 soc_mem_field_get(unit, mem, databuf,
   3161                                         FCOE__D_ID_MASKf, q_mask);
   3162             } else if ((keytype == _FP_KEY_IPv6_TYPE) &&
   3163                        (qual_id == bcmFieldQualifyDstIp6)) {
   3164                 soc_mem_field_get(unit, mem, databuf,
   3165                                         IPV6__DIP_V6f, q_data);
   3166                 soc_mem_field_get(unit, mem, databuf,
   3167                                         IPV6__DIP_V6_MASKf, q_mask);
   3168             } else {
   3169                 /* Do Nothing */
   3170             }
   3171             if (qual_id == bcmFieldQualifyVrf) {
   3172                 soc_mem_field_get(unit, mem, databuf,
   3173                                         VRFf, q_data);
   3174                 soc_mem_field_get(unit, mem, databuf,
   3175                                         VRF_MASKf, q_mask);
   3176             }
   3177             break;
   3178         case _FieldClassIpTunnelTtl:
   3179             if (qual_id == bcmFieldQualifyIpTunnelTtl) {
   3180                 q_data[0] = class_ent->tcam.ip_type;
   3181             }
   3182             break;
   3183         default:
   3184             rv = BCM_E_NONE;
   3185     }
   3186 
   3187     /* Free Entry Buffer */
   3188     sal_free(databuf);
   3189 
   3190     return (BCM_E_NONE);
   3191 }
   3192 
   3193 /*
   3194  * Function:
   3195  *  _bcm_field_th_class_qualify_clear
   3196  * Purpose:
   3197  *  Clear Field Class Qualifiers.
   3198  * Parameters:
   3199  *  unit      - (IN) BCM device number.
   3200  *  entry     - (IN) Field Entry Id.
   3201  * Returns:
   3202  *  BCM_E_XXX
   3203  */
   3204 int
   3205 _bcm_field_th_class_qualify_clear(int unit, bcm_field_entry_t entry)
   3206 {
   3207     int rv = BCM_E_NONE;        /* Operation Return Status */
   3208     _field_entry_t *class_ent = NULL;
   3209                                 /* Field Class Entry */
   3210     _field_group_t *fg = NULL;
   3211                                 /* Field group info */
   3212     int q = 0;                  /* Qset iterator */
   3213     _bcm_field_qual_data_t  q_data;
   3214                                 /* Qualifier match data */
   3215     _bcm_field_qual_data_t  q_mask;
   3216                                 /* Qualifier match mask */
   3217 
   3218     /* Retrieve the field entry. */
   3219     rv = _field_entry_get(unit, entry, _FP_ENTRY_PRIMARY, &class_ent);
   3220     BCM_IF_ERROR_RETURN(rv);
   3221 
   3222     /* Parameter Check */
   3223     if (class_ent->group == NULL) {
   3224         return (BCM_E_INTERNAL);
   3225     }
   3226 
   3227     /* Input Group Stage Check */
   3228     if (class_ent->group->stage_id != _BCM_FIELD_STAGE_CLASS) {
   3229         return (BCM_E_INTERNAL);
   3230     }
   3231 
   3232     /* Retreive Field Group from entry */
   3233     fg = class_ent->group;
   3234 
   3235     /* Initialize qdata and qmask */
   3236     sal_memset(q_data, 0, sizeof(_bcm_field_qual_data_t));
   3237     sal_memset(q_mask, 0, sizeof(_bcm_field_qual_data_t));
   3238 
   3239     /* Clear all qualifier in entry group */
   3240     for (q = 0; q < (int)bcmFieldQualifyCount; q++) {
   3241         if (BCM_FIELD_QSET_TEST(fg->qset, q)) {
   3242             if ((q != bcmFieldQualifyStageClass) &&
   3243                 (q != bcmFieldQualifyStageClassExactMatch)) {
   3244                     rv = _bcm_field_th_class_qualify_set(unit, entry,
   3245                                                          q, q_data, q_mask);
   3246                     if (BCM_FAILURE(rv)) {
   3247                         return (rv);
   3248                 }
   3249             }
   3250         }
   3251     }
   3252 
   3253     return (rv);
   3254 }
   3255 
   3256 /*
   3257  * Function:
   3258  *  _bcm_field_th_class_action_set
   3259  * Purpose:
   3260  *  Set Field Class Entry Action.
   3261  * Parameters:
   3262  *  unit        - (IN) BCM device number.
   3263  *  entry       - (IN) Field Entry Id.
   3264  *  class_info  - (IN) Field Class Info Structure.
   3265  * Returns:
   3266  *  BCM_E_XXX
   3267  */
   3268 int
   3269 _bcm_field_th_class_action_set(int unit, bcm_field_entry_t entry,
   3270                                bcm_field_class_info_t *class_info)
   3271 {
   3272     int rv = BCM_E_NONE;        /* Operation Return Status */
   3273     _field_group_t *fg = NULL;
   3274                                 /* Field group info */
   3275     _field_entry_t *f_ent = NULL;
   3276                                 /* Field entry info */
   3277     _field_action_t *fa = NULL;
   3278                                 /* Field action info */
   3279     _field_action_t *faiter = NULL;
   3280                                 /* Field action iterator */
   3281     uint32 *cdata;              /* Class Data */
   3282     _field_class_type_t ctype;  /* Field Class Type */
   3283     soc_reg_t reg;              /* SOC Register */
   3284     soc_mem_t mem;              /* SOC Memory */
   3285 
   3286     /* Confirm that 'entry' is  present on unit */
   3287     if (BCM_FAILURE(_field_entry_get(unit, entry, _FP_ENTRY_PRIMARY, &f_ent))) {
   3288         LOG_ERROR(BSL_LS_BCM_FP,
   3289                  (BSL_META_U(unit,
   3290                  "FP(unit %d) Error: entry=(%d) does not exists.\n"),
   3291                  unit, entry));
   3292         return (BCM_E_NOT_FOUND);
   3293     }
   3294 
   3295     /* Retreive Field Group */
   3296     fg = f_ent->group;
   3297 
   3298     /* Entry Group Check */
   3299     if (fg == NULL) {
   3300         return (BCM_E_INTERNAL);
   3301     }
   3302 
   3303     /* Class Info Check */
   3304     if (class_info == NULL) {
   3305         return (BCM_E_PARAM);
   3306     }
   3307 
   3308     /* Skip if stage is not class */
   3309     if (fg->stage_id != _BCM_FIELD_STAGE_CLASS) {
   3310         return (BCM_E_PARAM);
   3311     }
   3312 
   3313     /* Confirm that action is in aset. */
   3314     if (SHR_BITGET(fg->aset.w, class_info->action) == 0) {
   3315         LOG_DEBUG(BSL_LS_BCM_FP,
   3316                  (BSL_META_U(unit,
   3317                  "FP(unit %d) Error: provided action not present in entry "
   3318                  "group aset.\n"),
   3319                  unit));
   3320         return (BCM_E_PARAM);
   3321     }
   3322 
   3323     /* Check action is not set already in entry */
   3324     faiter = f_ent->actions;
   3325     while (faiter != NULL) {
   3326         if (faiter->action == class_info->action) {
   3327             LOG_DEBUG(BSL_LS_BCM_FP,
   3328                     (BSL_META_U(unit,
   3329                      "FP(unit %d) Error: provided action already present"
   3330                      " in field entry.\n"),
   3331                      unit));
   3332             return (BCM_E_EXISTS);
   3333         }
   3334         faiter = faiter->next;
   3335     }
   3336 
   3337     fa = sal_alloc(sizeof (_field_action_t), "field_action");
   3338     if (fa == NULL) {
   3339         LOG_ERROR(BSL_LS_BCM_FP,
   3340                  (BSL_META_U(unit,
   3341                  "FP(unit %d) Error: allocation failure for field_action\n"),
   3342                  unit));
   3343         return (BCM_E_MEMORY);
   3344     }
   3345 
   3346     sal_memset(fa, 0, sizeof (_field_action_t));
   3347 
   3348     /* Assign and store class action values */
   3349     fa->action = class_info->action;
   3350     COMPILER_64_TO_32_LO(fa->param[0], class_info->class_id);
   3351     COMPILER_64_TO_32_HI(fa->param[1], class_info->class_id);
   3352 
   3353     /* Retreive Class Type from entry qset */
   3354     rv = _bcm_field_th_class_type_qset_get(unit,
   3355                                         &f_ent->group->qset, &ctype);
   3356     if (BCM_FAILURE(rv)) {
   3357         sal_free(fa);
   3358         return (rv);
   3359     }
   3360 
   3361     /* Assign class data buffer */
   3362     if (f_ent->tcam.key == NULL) {
   3363         if ((f_ent->flags & _FP_ENTRY_INSTALLED) &&
   3364                 (f_ent->slice_idx != -1)) {
   3365             /* Allocate memory for class data */
   3366             _FP_XGS3_ALLOC(f_ent->tcam.key,
   3367                            f_ent->tcam.key_size, "field class data buf");
   3368             if (f_ent->tcam.key == NULL) {
   3369                 LOG_ERROR(BSL_LS_BCM_FP,
   3370                          (BSL_META_U(unit,
   3371                          "FP(unit %d) Error: allocation failure for "
   3372                          "field class data buf\n"),
   3373                          unit));
   3374                 sal_free(fa);
   3375                 return (BCM_E_MEMORY);
   3376             }
   3377             /* Entry is in hardware , read it from hardware */
   3378             rv = _bcm_field_th_class_entry_hwread(unit, f_ent,
   3379                                                   ctype, f_ent->tcam.key);
   3380             if (BCM_FAILURE(rv)) {
   3381                 sal_free(f_ent->tcam.key);
   3382                 sal_free(fa);
   3383                 return (rv);
   3384             }
   3385         } else {
   3386             sal_free(fa);
   3387             return (BCM_E_INTERNAL);
   3388         }
   3389     }
   3390 
   3391     /* Assign class data and mask buffer */
   3392     cdata = f_ent->tcam.key;
   3393 
   3394     switch(ctype) {
   3395         case _FieldClassEtherType:
   3396             reg = ETHERTYPE_MAPr;
   3397             if ((fa->param[0] & ~(0xF)) ||
   3398                 (fa->param[1] & ~(0))) {
   3399                 rv = BCM_E_PARAM;
   3400             } else {
   3401                 soc_reg_field_set(unit, reg, cdata,
   3402                                         C_ETHERTYPEf, fa->param[0]);
   3403             }
   3404             break;
   3405         case _FieldClassTtl:
   3406             mem = TTL_FNm;
   3407             if ((fa->param[0] & ~(0xFF)) ||
   3408                 (fa->param[1] & ~(0))) {
   3409                 rv = BCM_E_PARAM;
   3410             } else {
   3411                 if (class_info->action == bcmFieldActionClassZero) {
   3412                     soc_mem_field_set(unit, mem, cdata,
   3413                                             FN0f, &fa->param[0]);
   3414                 } else {
   3415                     soc_mem_field_set(unit, mem, cdata,
   3416                                             FN1f, &fa->param[0]);
   3417                 }
   3418             }
   3419             break;
   3420         case _FieldClassToS:
   3421             mem = TOS_FNm;
   3422             if ((fa->param[0] & ~(0xFF)) ||
   3423                 (fa->param[1] & ~(0))) {
   3424                 rv = BCM_E_PARAM;
   3425             } else {
   3426                 if (class_info->action == bcmFieldActionClassZero) {
   3427                     soc_mem_field_set(unit, mem, cdata,
   3428                                             FN0f, &fa->param[0]);
   3429                 } else {
   3430                     soc_mem_field_set(unit, mem, cdata,
   3431                                             FN1f, &fa->param[0]);
   3432                 }
   3433             }
   3434             break;
   3435         case _FieldClassIpProto:
   3436             mem = IP_PROTO_MAPm;
   3437             if ((fa->param[0] & ~(0xF)) ||
   3438                 (fa->param[1] & ~(0))) {
   3439                 rv = BCM_E_PARAM;
   3440             } else {
   3441                 soc_mem_field_set(unit, mem, cdata,
   3442                                         C_IP_PROTOCOLf, &fa->param[0]);
   3443             }
   3444             break;
   3445         case _FieldClassL4SrcPort:
   3446             reg = L4_SRC_PORT_MAPr;
   3447             if ((fa->param[0] & ~(0xF)) ||
   3448                 (fa->param[1] & ~(0))) {
   3449                 rv = BCM_E_PARAM;
   3450             } else {
   3451                 soc_reg_field_set(unit, reg, cdata,
   3452                                         C_L4_SRC_PORTf, fa->param[0]);
   3453             }
   3454             break;
   3455         case _FieldClassL4DstPort:
   3456             reg = L4_DST_PORT_MAPr;
   3457             if ((fa->param[0] & ~(0xF)) ||
   3458                 (fa->param[1] & ~(0))) {
   3459                 rv = BCM_E_PARAM;
   3460             } else {
   3461                 soc_reg_field_set(unit, reg, cdata,
   3462                                         C_L4_DST_PORTf, fa->param[0]);
   3463             }
   3464             break;
   3465         case _FieldClassTcp:
   3466             mem = TCP_FNm;
   3467             if ((fa->param[0] & ~(0xFF)) ||
   3468                 (fa->param[1] & ~(0))) {
   3469                 rv = BCM_E_PARAM;
   3470             } else {
   3471                 if (class_info->action == bcmFieldActionClassZero) {
   3472                     soc_mem_field_set(unit, mem, cdata,
   3473                                             FN0f, &fa->param[0]);
   3474                 } else {
   3475                     soc_mem_field_set(unit, mem, cdata,
   3476                                             FN1f, &fa->param[0]);
   3477                 }
   3478             }
   3479             break;
   3480         case _FieldClassSrcCompression:
   3481             mem = SRC_COMPRESSIONm;
   3482             if (fa->param[1] & ~(0xF)) {
   3483                 rv = BCM_E_PARAM;
   3484             } else {
   3485                 soc_mem_field_set(unit, mem, cdata,
   3486                                         C_SRCf, &fa->param[0]);
   3487             }
   3488             break;
   3489         case _FieldClassDstCompression:
   3490             mem = DST_COMPRESSIONm;
   3491             if (fa->param[1] & ~(0xF)) {
   3492                 rv = BCM_E_PARAM;
   3493             } else {
   3494                 soc_mem_field_set(unit, mem, cdata,
   3495                                         C_DSTf, &fa->param[0]);
   3496             }
   3497             break;
   3498         case _FieldClassIpTunnelTtl:
   3499             mem = ALT_TTL_FNm;
   3500             if ((fa->param[0] & ~(0xFF)) ||
   3501                 (fa->param[1] & ~(0))) {
   3502                 rv = BCM_E_PARAM;
   3503             } else {
   3504                 if (class_info->action == bcmFieldActionClassZero) {
   3505                     soc_mem_field_set(unit, mem, cdata,
   3506                                             FN0f, &fa->param[0]);
   3507                 } else {
   3508                     rv = BCM_E_PARAM;
   3509                 }
   3510             }
   3511             break;
   3512         default:
   3513             rv = BCM_E_PARAM;
   3514     }
   3515 
   3516     if (BCM_FAILURE(rv)) {
   3517         sal_free(fa);
   3518         return (rv);
   3519     }
   3520 
   3521     /* Add action to front of entry's linked-list. */
   3522     fa->next = f_ent->actions;
   3523     f_ent->actions  = fa;
   3524 
   3525     /* Mark entry as dirty. */
   3526     f_ent->flags |= _FP_ENTRY_DIRTY;
   3527 
   3528     return (rv);
   3529 }
   3530 
   3531 /*
   3532  * Function:
   3533  *  _bcm_field_th_class_action_delete
   3534  * Purpose:
   3535  *  Delete Field Class Entry Action.
   3536  * Parameters:
   3537  *  unit        - (IN) BCM device number.
   3538  *  entry       - (IN) Field Entry Id.
   3539  *  action      - (IN) Field Action info.
   3540  * Returns:
   3541  *  BCM_E_XXX
   3542  */
   3543 int
   3544 _bcm_field_th_class_action_delete(int unit, bcm_field_entry_t entry,
   3545                                            bcm_field_action_t action)
   3546 {
   3547     int rv = BCM_E_NONE;        /* Operation Return Status */
   3548     _field_group_t *fg = NULL;  /* Field group info */
   3549     _field_entry_t *f_ent = NULL;
   3550                                 /* Field entry info */
   3551     _field_action_t *fa = NULL;
   3552                                 /* Field action info */
   3553     _field_action_t *fa_prev = NULL;
   3554                                 /* Field action info previous */
   3555     uint32 *cdata = NULL;       /* Class Data */
   3556     _field_class_type_t ctype;  /* Field Class Type */
   3557     soc_reg_t reg;              /* SOC Register */
   3558     soc_mem_t mem;              /* SOC Memory */
   3559     uint32 valid = 0;           /* Valid */
   3560     uint32 action_clear[2] = {0, 0};
   3561                                 /* Class Src/Dst */
   3562 
   3563     /* Confirm that 'entry' is  present on unit */
   3564     if (BCM_FAILURE(_field_entry_get(unit, entry, _FP_ENTRY_PRIMARY, &f_ent))) {
   3565         LOG_ERROR(BSL_LS_BCM_FP,
   3566                  (BSL_META_U(unit,
   3567                  "FP(unit %d) Error: entry=(%d) does not exists.\n"),
   3568                  unit, entry));
   3569         return (BCM_E_NOT_FOUND);
   3570     }
   3571 
   3572     /* Retreive Field Group */
   3573     fg = f_ent->group;
   3574 
   3575     /* Entry Group Check */
   3576     if (fg == NULL) {
   3577         return (BCM_E_INTERNAL);
   3578     }
   3579 
   3580     /* Find the action in the entry */
   3581     fa = f_ent->actions; /* start at head */
   3582 
   3583     while (fa != NULL) {
   3584         if (fa->action != action) {
   3585             fa_prev = fa;
   3586             fa      = fa->next;
   3587             continue;
   3588         }
   3589         break;
   3590     }
   3591 
   3592     if (NULL == fa) {
   3593         LOG_ERROR(BSL_LS_BCM_FP,
   3594                  (BSL_META_U(unit,
   3595                  "FP(unit %d) Error: action=(%d) is not present in entry.\n"),
   3596                  unit, action));
   3597         return (BCM_E_NOT_FOUND);
   3598     }
   3599 
   3600     /* Retreive Class Type from entry qset */
   3601     rv = _bcm_field_th_class_type_qset_get(unit,
   3602                                        &f_ent->group->qset,
   3603                                        &ctype);
   3604     if (BCM_FAILURE(rv)) {
   3605         return (rv);
   3606     }
   3607 
   3608     /* Assign class data buffer */
   3609     if (f_ent->tcam.key == NULL) {
   3610         if ((f_ent->flags & _FP_ENTRY_INSTALLED) &&
   3611             (f_ent->slice_idx != -1)) {
   3612             /* Allocate memory for class data */
   3613             _FP_XGS3_ALLOC(f_ent->tcam.key,
   3614                     f_ent->tcam.key_size, "field class data buf");
   3615             if (f_ent->tcam.key == NULL) {
   3616                 LOG_ERROR(BSL_LS_BCM_FP,
   3617                          (BSL_META_U(unit,
   3618                          "FP(unit %d) Error: allocation failure for "
   3619                          "field class data buf\n"),
   3620                          unit));
   3621                 return (BCM_E_MEMORY);
   3622             }
   3623             /* Entry is in hardware , read it from hardware */
   3624             rv = _bcm_field_th_class_entry_hwread(unit, f_ent,
   3625                                                   ctype, f_ent->tcam.key);
   3626             if (BCM_FAILURE(rv)) {
   3627                 sal_free(f_ent->tcam.key);
   3628                 return (rv);
   3629             }
   3630         } else {
   3631             return (BCM_E_INTERNAL);
   3632         }
   3633     }
   3634 
   3635     /* Assign class data and mask buffer */
   3636     cdata = f_ent->tcam.key;
   3637 
   3638     switch(ctype) {
   3639         case _FieldClassEtherType:
   3640             reg = ETHERTYPE_MAPr;
   3641             soc_reg_field_set(unit, reg, cdata, C_ETHERTYPEf, valid);
   3642             break;
   3643         case _FieldClassTtl:
   3644             mem = TTL_FNm;
   3645             if (fa->action == bcmFieldActionClassZero) {
   3646                 soc_mem_field_set(unit, mem, cdata, FN0f, &valid);
   3647             } else {
   3648                 soc_mem_field_set(unit, mem, cdata, FN1f, &valid);
   3649             }
   3650             break;
   3651         case _FieldClassToS:
   3652             mem = TOS_FNm;
   3653             if (fa->action == bcmFieldActionClassZero) {
   3654                 soc_mem_field_set(unit, mem, cdata, FN0f, &valid);
   3655             } else {
   3656                 soc_mem_field_set(unit, mem, cdata, FN1f, &valid);
   3657             }
   3658             break;
   3659         case _FieldClassIpProto:
   3660             mem = IP_PROTO_MAPm;
   3661             soc_mem_field_set(unit, mem, cdata, C_IP_PROTOCOLf, &valid);
   3662             break;
   3663         case _FieldClassL4SrcPort:
   3664             reg = L4_SRC_PORT_MAPr;
   3665             soc_reg_field_set(unit, reg , cdata, C_L4_SRC_PORTf, valid);
   3666             break;
   3667         case _FieldClassL4DstPort:
   3668             reg = L4_DST_PORT_MAPr;
   3669             soc_reg_field_set(unit, reg , cdata, C_L4_DST_PORTf, valid);
   3670             break;
   3671         case _FieldClassTcp:
   3672             mem = TCP_FNm;
   3673             if (fa->action == bcmFieldActionClassZero) {
   3674                 soc_mem_field_set(unit, mem, cdata, FN0f, &valid);
   3675             } else {
   3676                 soc_mem_field_set(unit, mem, cdata, FN1f, &valid);
   3677             }
   3678             break;
   3679         case _FieldClassSrcCompression:
   3680             mem = SRC_COMPRESSIONm;
   3681             soc_mem_field_set(unit, mem, cdata, C_SRCf, action_clear);
   3682             break;
   3683         case _FieldClassDstCompression:
   3684             mem = DST_COMPRESSIONm;
   3685             soc_mem_field_set(unit, mem, cdata, C_DSTf, action_clear);
   3686             break;
   3687         case _FieldClassIpTunnelTtl:
   3688             mem = ALT_TTL_FNm;
   3689             if (fa->action == bcmFieldActionClassZero) {
   3690                 soc_mem_field_set(unit, mem, cdata, FN0f, &valid);
   3691             } else {
   3692                 rv = BCM_E_PARAM;
   3693             }
   3694             break;
   3695         default:
   3696             rv = BCM_E_PARAM;
   3697     }
   3698 
   3699     if (fa_prev != NULL) {
   3700         fa_prev->next = fa->next;
   3701     } else { /* matched head of list */
   3702         f_ent->actions = fa->next;
   3703     }
   3704 
   3705     /* okay to free action */
   3706     sal_free(fa);
   3707     fa = NULL;
   3708 
   3709     /* Mark Entry as Dirty */
   3710     f_ent->flags |= _FP_ENTRY_DIRTY;
   3711 
   3712     return rv;
   3713 }
   3714 
   3715 /*
   3716  * Function:
   3717  *  _bcm_field_th_class_action_get
   3718  * Purpose:
   3719  *  Get Field Class Entry Action.
   3720  * Parameters:
   3721  *  unit        - (IN) BCM device number.
   3722  *  entry       - (IN) Field Entry Id.
   3723  *  class_info  - (INOUT) Field Class Info Structure.
   3724  * Returns:
   3725  *  BCM_E_XXX
   3726  */
   3727 int
   3728 _bcm_field_th_class_action_get(int unit, bcm_field_entry_t entry,
   3729                                 bcm_field_class_info_t *class_info)
   3730 {
   3731     int rv = BCM_E_NONE;        /* Operation Return Status */
   3732     _field_group_t *fg = NULL;
   3733                                 /* Field group info */
   3734     _field_entry_t *f_ent = NULL;
   3735                                 /* Field entry info */
   3736     _field_action_t *fa = NULL;
   3737                                 /* Field action info */
   3738 
   3739     /* Confirm that 'entry' is  present on unit */
   3740     if (BCM_FAILURE(_field_entry_get(unit, entry, _FP_ENTRY_PRIMARY, &f_ent))) {
   3741         LOG_ERROR(BSL_LS_BCM_FP,
   3742                  (BSL_META_U(unit,
   3743                  "FP(unit %d) Error: entry=(%d) does not exists.\n"),
   3744                  unit, entry));
   3745         return (BCM_E_BADID);
   3746     }
   3747 
   3748     /* Retreive Field Group */
   3749     fg = f_ent->group;
   3750 
   3751     /* Entry Group Check */
   3752     if (fg == NULL) {
   3753         return (BCM_E_INTERNAL);
   3754     }
   3755 
   3756     /* Class Info Check */
   3757     if (class_info == NULL) {
   3758         return (BCM_E_PARAM);
   3759     }
   3760 
   3761     /* Skip if stage is not class */
   3762     if (fg->stage_id != _BCM_FIELD_STAGE_CLASS) {
   3763         return (BCM_E_PARAM);
   3764     }
   3765 
   3766     /* Check action is not set already in entry */
   3767     fa = f_ent->actions;
   3768     while (fa != NULL) {
   3769         if (fa->action == class_info->action) {
   3770             break;
   3771         }
   3772         fa = fa->next;
   3773     }
   3774 
   3775     if (NULL == fa) {
   3776         LOG_ERROR(BSL_LS_BCM_FP,
   3777                  (BSL_META_U(unit,
   3778                  "FP(unit %d) Error: action=(%d) is not present in entry.\n"),
   3779                  unit, class_info->action));
   3780         return (BCM_E_NOT_FOUND);
   3781     }
   3782 
   3783     COMPILER_64_SET(class_info->class_id, fa->param[1], fa->param[0]);
   3784 
   3785     return (rv);
   3786 }
   3787 
   3788 /*
   3789  * Function:
   3790  *  _bcm_field_th_qual_class_size_get
   3791  * Purpose:
   3792  *  Get Field Qualifier Class Size
   3793  * Parameters:
   3794  *  unit        - (IN) BCM device number.
   3795  *  qual        - (IN) Field Qualifier.
   3796  *  class_size  - (OUT) Field Qualifier Class Size.
   3797  * Returns:
   3798  *  BCM_E_XXX
   3799  * Notes:
   3800  *  This api returns class size for provided qualifier
   3801  *  Size provided is in bits.
   3802  */
   3803 int
   3804 _bcm_field_th_qual_class_size_get(int unit, bcm_field_qualify_t qual,
   3805                                                    uint16 *class_size)
   3806 {
   3807     int rv = BCM_E_NONE;        /* Operation Return Status */
   3808 
   3809 #if defined (BCM_TOMAHAWK3_SUPPORT)
   3810     if (SOC_IS_TOMAHAWK3(unit)) {
   3811         return _bcm_field_th3_qual_class_size_get(unit, qual, class_size);
   3812     }
   3813 #endif
   3814 
   3815     switch (qual) {
   3816         case bcmFieldQualifyEtherType:
   3817             *class_size = _FP_QUAL_CLASS_SIZE_ETHERTYPE;
   3818             break;
   3819         case bcmFieldQualifyTtl:
   3820             *class_size = _FP_QUAL_CLASS_SIZE_TTL;
   3821             break;
   3822         case bcmFieldQualifyTos:
   3823             *class_size = _FP_QUAL_CLASS_SIZE_TOS;
   3824             break;
   3825         case bcmFieldQualifyIpProtocol:
   3826             *class_size = _FP_QUAL_CLASS_SIZE_IP_PROTO;
   3827             break;
   3828         case bcmFieldQualifyL4SrcPort:
   3829             *class_size = _FP_QUAL_CLASS_SIZE_L4_SRC_PORT;
   3830             break;
   3831         case bcmFieldQualifyFcoeOxID:
   3832             *class_size = _FP_QUAL_CLASS_SIZE_L4_SRC_PORT;
   3833             break;
   3834         case bcmFieldQualifyL4DstPort:
   3835             *class_size = _FP_QUAL_CLASS_SIZE_L4_DST_PORT;
   3836             break;
   3837         case bcmFieldQualifyFcoeRxID:
   3838             *class_size = _FP_QUAL_CLASS_SIZE_L4_DST_PORT;
   3839             break;
   3840         case bcmFieldQualifyTcpControl:
   3841             *class_size = _FP_QUAL_CLASS_SIZE_TCP;
   3842             break;
   3843         case bcmFieldQualifySrcIp:
   3844             *class_size = _FP_QUAL_CLASS_SIZE_SRC_COMPRESSION;
   3845             break;
   3846         case bcmFieldQualifySrcIp6:
   3847             *class_size = _FP_QUAL_CLASS_SIZE_SRC_COMPRESSION;
   3848             break;
   3849         case bcmFieldQualifyFibreChanSrcId:
   3850             *class_size = _FP_QUAL_CLASS_SIZE_SRC_COMPRESSION;
   3851             break;
   3852         case bcmFieldQualifyDstIp:
   3853             *class_size = _FP_QUAL_CLASS_SIZE_DST_COMPRESSION;
   3854             break;
   3855         case bcmFieldQualifyDstIp6:
   3856             *class_size = _FP_QUAL_CLASS_SIZE_DST_COMPRESSION;
   3857             break;
   3858         case bcmFieldQualifyFibreChanDstId:
   3859             *class_size = _FP_QUAL_CLASS_SIZE_DST_COMPRESSION;
   3860             break;
   3861         case bcmFieldQualifyVrf:
   3862             *class_size = _FP_QUAL_CLASS_SIZE_SRC_COMPRESSION;
   3863             break;
   3864         default:
   3865             rv = BCM_E_PARAM;
   3866     }
   3867 
   3868     return (rv);
   3869 }
   3870 
   3871 /*
   3872  * Function:
   3873  *  _bcm_field_th_class_entry_install
   3874  * Purpose:
   3875  *  Install Field Class Entry.
   3876  * Parameters:
   3877  *  unit        - (IN) BCM device number.
   3878  *  entry       - (IN) Field Entry Id.
   3879  * Returns:
   3880  *  BCM_E_XXX
   3881  */
   3882 int
   3883 _bcm_field_th_class_entry_install(int unit, bcm_field_entry_t entry)
   3884 {
   3885     int rv = BCM_E_NONE;            /* Operation Return Status */
   3886     _field_group_t *fg = NULL;      /* Field group info */
   3887     _field_entry_t *f_ent = NULL;   /* Field entry info */
   3888     _field_class_type_t ctype;      /* Field Class Type */
   3889     int hw_index = 0;               /* Hardware Index */
   3890     _field_class_info_t **class_status_arr;
   3891                                     /* Field Per Pipe Class Status Array */
   3892     _field_class_info_t *class_status_info;
   3893                                     /* Field Per Compression table status */
   3894     _field_stage_t *stage_fc = NULL;
   3895                                     /* Stage field control info */
   3896 
   3897     /* Confirm that 'entry' is  present on unit */
   3898     if (BCM_FAILURE(_field_entry_get(unit, entry, _FP_ENTRY_PRIMARY, &f_ent))) {
   3899         LOG_ERROR(BSL_LS_BCM_FP,
   3900                  (BSL_META_U(unit,
   3901                  "FP(unit %d) Error: entry=(%d) does not exists.\n"),
   3902                  unit, entry));
   3903         return (BCM_E_BADID);
   3904     }
   3905 
   3906     /* Retreive Field Group */
   3907     fg = f_ent->group;
   3908 
   3909     /* Check if group is associated */
   3910     if (fg == NULL) {
   3911         return (BCM_E_INTERNAL);
   3912     }
   3913 
   3914     /* Get group stage control structure. */
   3915     rv = _field_stage_control_get(unit, fg->stage_id, &stage_fc);
   3916     if (BCM_FAILURE(rv)) {
   3917         LOG_ERROR(BSL_LS_BCM_FP,
   3918                  (BSL_META_U(unit,
   3919                  "FP(unit %d) Error: Stage (%d) control get failure.\n"),
   3920                  unit, fg->stage_id));
   3921         return (rv);
   3922     }
   3923 
   3924     /* Check if entry is installed and not dirty */
   3925     if ((f_ent->flags & _FP_ENTRY_INSTALLED) &&
   3926         (!(f_ent->flags & _FP_ENTRY_DIRTY))) {
   3927         /* Nothing to do - entry is installed and clean */
   3928         return (BCM_E_NONE);
   3929     }
   3930 
   3931     /* Check if data and action exist */
   3932     if ((f_ent->tcam.key == NULL) ||
   3933         (f_ent->actions == NULL)) {
   3934         LOG_DEBUG(BSL_LS_BCM_FP,
   3935                 (BSL_META_U(unit,
   3936                  "FP(unit %d) Error: entry=(%d) data or action is not qualified.\n"),
   3937                  unit, entry));
   3938         return (BCM_E_PARAM);
   3939     }
   3940 
   3941     /* Retreive Class Type from entry qset */
   3942     rv = _bcm_field_th_class_type_qset_get(unit, &fg->qset, &ctype);
   3943     if (BCM_FAILURE(rv)) {
   3944         return (rv);
   3945     }
   3946 
   3947     /* Update Class Status Info Structure */
   3948     class_status_arr = stage_fc->class_info_arr[fg->instance];
   3949     if (class_status_arr == NULL) {
   3950         return (BCM_E_INTERNAL);
   3951     }
   3952     class_status_info = class_status_arr[ctype];
   3953     if (class_status_info == NULL) {
   3954         return (BCM_E_INTERNAL);
   3955     }
   3956 
   3957     /* Allocate HwIndex Only if index is not allocate previously */
   3958     if (f_ent->slice_idx == -1) {
   3959         rv = _field_th_class_hwindex_get(unit, f_ent, ctype, &hw_index);
   3960         if (BCM_FAILURE(rv)) {
   3961             return (BCM_E_RESOURCE);
   3962         }
   3963         f_ent->slice_idx = hw_index;
   3964     }
   3965 
   3966     /* Install Entry in Hardware */
   3967     rv = _bcm_field_th_class_entry_hwinstall(unit, f_ent, ctype);
   3968     if (BCM_FAILURE(rv)) {
   3969         f_ent->slice_idx = -1;
   3970         return (rv);
   3971     }
   3972 
   3973     sal_free(f_ent->tcam.key);
   3974     f_ent->tcam.key = NULL;
   3975     f_ent->flags |= _FP_ENTRY_INSTALLED;
   3976     f_ent->flags &= ~_FP_ENTRY_DIRTY;
   3977     _FP_CLASS_TABLE_BMP_ADD(class_status_info->class_bmp, f_ent->slice_idx);
   3978 
   3979     /* Sorted Insert for Src/Dst Compression. */
   3980     if ((ctype == _FieldClassSrcCompression) ||
   3981         (ctype == _FieldClassDstCompression)) {
   3982         if (class_status_info->total_entries_used !=
   3983             class_status_info->total_entries_available) {
   3984             rv = _bcm_field_th_class_entry_prio_set(unit, f_ent, f_ent->prio);
   3985             if (BCM_FAILURE(rv)) {
   3986                 return (rv);
   3987             }
   3988         }
   3989         rv = _field_th_class_valid_set(unit, f_ent, ctype, 1);
   3990     }
   3991 
   3992     return (rv);
   3993 }
   3994 
   3995 /*
   3996  * Function:
   3997  *  _field_th_class_hwindex_get
   3998  * Purpose:
   3999  *  Get Field Class Entry Hw Index.
   4000  * Parameters:
   4001  *  unit        - (IN) BCM device number.
   4002  *  entry       - (IN) Field Entry Info.
   4003  *  ctype       - (IN) Field Class Type.
   4004  *  hw_index    - (OUT) Field Entry Hardware Index.
   4005  * Returns:
   4006  *  BCM_E_XXX
   4007  */
   4008 STATIC int
   4009 _field_th_class_hwindex_get(int unit, _field_entry_t *entry,
   4010                             _field_class_type_t ctype, int *hw_index)
   4011 {
   4012     int rv = BCM_E_PARAM;           /* Operation Return Status */
   4013     _field_group_t *fg = NULL;      /* Field group info */
   4014     _field_class_info_t **class_status_arr;
   4015                                     /* Field Per Pipe Class Status Array */
   4016     _field_class_info_t *class_status_info;
   4017                                     /* Field Per Compression table status */
   4018     _field_stage_t *stage_fc = NULL;
   4019                                     /* Stage field control info */
   4020     int idx = 0;                    /* Index Iterator */
   4021 
   4022     /* Input Parameters Check */
   4023     if (entry == NULL) {
   4024         return (BCM_E_INTERNAL);
   4025     }
   4026 
   4027     /* Retreive Field Group */
   4028     fg = entry->group;
   4029 
   4030     /* Get group stage control structure. */
   4031     rv = _field_stage_control_get(unit, fg->stage_id, &stage_fc);
   4032     if (BCM_FAILURE(rv)) {
   4033         LOG_ERROR(BSL_LS_BCM_FP,
   4034                  (BSL_META_U(unit,
   4035                  "FP(unit %d) Error: Stage (%d) control get failure.\n"),
   4036                  unit, fg->stage_id));
   4037         return (rv);
   4038     }
   4039 
   4040     /* Update Class Info Status Structure */
   4041     class_status_arr = stage_fc->class_info_arr[fg->instance];
   4042     if (class_status_arr == NULL) {
   4043         return (BCM_E_INTERNAL);
   4044     }
   4045     class_status_info = class_status_arr[ctype];
   4046     if (class_status_info == NULL) {
   4047         return (BCM_E_INTERNAL);
   4048     }
   4049 
   4050     switch (ctype) {
   4051         case _FieldClassEtherType:
   4052         case _FieldClassL4SrcPort:
   4053         case _FieldClassL4DstPort:
   4054         case _FieldClassSrcCompression:
   4055         case _FieldClassDstCompression:
   4056             for (idx = 0; idx < class_status_info->total_entries_available;
   4057                                                                     idx++) {
   4058                 if (0 == _FP_CLASS_TABLE_BMP_TEST(
   4059                                        class_status_info->class_bmp, idx)) {
   4060                     *hw_index = idx;
   4061                     rv = BCM_E_NONE;
   4062                     break;
   4063                 }
   4064             }
   4065             break;
   4066         case _FieldClassTtl:
   4067         case _FieldClassToS:
   4068         case _FieldClassIpProto:
   4069         case _FieldClassTcp:
   4070         case _FieldClassIpTunnelTtl:
   4071             *hw_index = entry->tcam.ip_type;
   4072             rv = BCM_E_NONE;
   4073             break;
   4074         default:
   4075             rv = BCM_E_PARAM;
   4076     }
   4077 
   4078     return rv;
   4079 }
   4080 
   4081 /*
   4082  * Function:
   4083  *  _bcm_field_th_class_entry_hwinstall
   4084  * Purpose:
   4085  *  Install Class Entry In Hardware.
   4086  * Parameters:
   4087  *  unit        - (IN) BCM device number.
   4088  *  entry       - (IN) Field Entry Info.
   4089  *  ctype       - (IN) Field Class Type.
   4090  * Returns:
   4091  *  BCM_E_XXX
   4092  */
   4093 int
   4094 _bcm_field_th_class_entry_hwinstall(int unit, _field_entry_t *entry,
   4095                                            _field_class_type_t ctype)
   4096 {
   4097     int rv = BCM_E_NONE;        /* Operation Return Status */
   4098 
   4099     /* Input Parameter Check */
   4100     if ((entry == NULL) ||
   4101         (entry->group == NULL) ||
   4102         (entry->tcam.key == NULL)) {
   4103         return (BCM_E_INTERNAL);
   4104     }
   4105 
   4106     switch (ctype) {
   4107         case _FieldClassEtherType:
   4108             rv = _field_th_class_ethertype_install(unit,entry);
   4109             break;
   4110         case _FieldClassL4SrcPort:
   4111             rv = _field_th_class_l4srcport_install(unit,entry);
   4112             break;
   4113         case _FieldClassL4DstPort:
   4114             rv = _field_th_class_l4dstport_install(unit,entry);
   4115             break;
   4116         case _FieldClassSrcCompression:
   4117             rv = _field_th_class_srccompression_install(unit,entry);
   4118             break;
   4119         case _FieldClassDstCompression:
   4120             rv = _field_th_class_dstcompression_install(unit,entry);
   4121             break;
   4122         case _FieldClassTtl:
   4123             rv = _field_th_class_ttl_install(unit,entry);
   4124             break;
   4125         case _FieldClassToS:
   4126             rv = _field_th_class_tos_install(unit,entry);
   4127             break;
   4128         case _FieldClassIpProto:
   4129             rv = _field_th_class_ipproto_install(unit,entry);
   4130             break;
   4131         case _FieldClassTcp:
   4132             rv = _field_th_class_tcp_install(unit,entry);
   4133             break;
   4134         case _FieldClassIpTunnelTtl:
   4135             rv = _field_th_class_iptunnelttl_install(unit,entry);
   4136             break;
   4137         default:
   4138             rv = BCM_E_PARAM;
   4139     }
   4140 
   4141     return rv;
   4142 }
   4143 
   4144 /*
   4145  * Function:
   4146  *  _bcm_field_th_class_entry_hwread.
   4147  * Purpose:
   4148  *  Read Class Entry From Hardware.
   4149  * Parameters:
   4150  *  unit        - (IN) BCM device number.
   4151  *  entry       - (IN) Field Entry Info.
   4152  *  ctype       - (IN) Field Class Type.
   4153  *  cdata       - (OUT) Field Class Entry DataBuffer.
   4154  * Returns:
   4155  *  BCM_E_XXX
   4156  */
   4157 int
   4158 _bcm_field_th_class_entry_hwread(int unit, _field_entry_t *entry,
   4159                                        _field_class_type_t ctype,
   4160                                                    uint32 *cdata)
   4161 {
   4162     int rv = BCM_E_NONE;        /* Operation Return Status */
   4163 
   4164     /* Input Parameter Check */
   4165     if ((entry == NULL) ||
   4166         (entry->group == NULL) ||
   4167         (cdata == NULL)) {
   4168         return (BCM_E_INTERNAL);
   4169     }
   4170 
   4171     /* Read based on class type */
   4172     switch (ctype) {
   4173         case _FieldClassEtherType:
   4174             rv = _field_th_class_ethertype_read(unit,entry,cdata);
   4175             break;
   4176         case _FieldClassL4SrcPort:
   4177             rv = _field_th_class_l4srcport_read(unit,entry,cdata);
   4178             break;
   4179         case _FieldClassL4DstPort:
   4180             rv = _field_th_class_l4dstport_read(unit,entry,cdata);
   4181             break;
   4182         case _FieldClassSrcCompression:
   4183             rv = _field_th_class_srccompression_read(unit,entry,cdata);
   4184             break;
   4185         case _FieldClassDstCompression:
   4186             rv = _field_th_class_dstcompression_read(unit,entry,cdata);
   4187             break;
   4188         case _FieldClassTtl:
   4189             rv = _field_th_class_ttl_read(unit,entry,cdata);
   4190             break;
   4191         case _FieldClassToS:
   4192             rv = _field_th_class_tos_read(unit,entry,cdata);
   4193             break;
   4194         case _FieldClassIpProto:
   4195             rv = _field_th_class_ipproto_read(unit,entry,cdata);
   4196             break;
   4197         case _FieldClassTcp:
   4198             rv = _field_th_class_tcp_read(unit,entry,cdata);
   4199             break;
   4200         case _FieldClassIpTunnelTtl:
   4201             rv = _field_th_class_iptunnelttl_read(unit,entry,cdata);
   4202             break;
   4203         default:
   4204             rv = BCM_E_PARAM;
   4205     }
   4206 
   4207     return rv;
   4208 }
   4209 
   4210 /*
   4211  * Function:
   4212  *  _field_th_class_ethertype_install
   4213  * Purpose:
   4214  *  Install EtherType Class Entry In Hardware.
   4215  * Parameters:
   4216  *  unit        - (IN) BCM device number.
   4217  *  entry       - (IN) Field Entry Info.
   4218  * Returns:
   4219  *  BCM_E_XXX:
   4220  * Notes:
   4221  *  No Null Check for entry, group and key.
   4222  *  Done by calling function _bcm_field_th_class_entry_hwinstall
   4223  *  entry->slice_idx contains index to write
   4224  *  entry->tcam.key contains data to write
   4225  */
   4226 STATIC int
   4227 _field_th_class_ethertype_install(int unit, _field_entry_t *entry)
   4228 {
   4229     int rv = BCM_E_NONE;        /* Operation Return Status */
   4230     _field_group_t *fg = NULL;
   4231                                 /* Field group info */
   4232     _field_stage_t *stage_fc = NULL;
   4233                                 /* Stage field control info */
   4234     uint32 rval = 0;            /* Register Value */
   4235     soc_reg_t reg;              /* SOC Register */
   4236     uint32 *cdata = NULL;       /* Class Data */
   4237 
   4238     /* Get class data key and group info */
   4239     cdata = entry->tcam.key;
   4240     fg = entry->group;
   4241 
   4242     /* Get Class Data Value */
   4243     rval = *cdata;
   4244 
   4245     /* Get group stage control structure. */
   4246     rv = _field_stage_control_get(unit, fg->stage_id, &stage_fc);
   4247     if (BCM_FAILURE(rv)) {
   4248         LOG_ERROR(BSL_LS_BCM_FP,
   4249                  (BSL_META_U(unit,
   4250                  "FP(unit %d) Error: Stage (%d) control get failure.\n"),
   4251                  unit, fg->stage_id));
   4252         return (rv);
   4253     }
   4254 
   4255     /* Decide register based on operational mode */
   4256     if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) {
   4257         reg = ETHERTYPE_MAPr;
   4258     } else {
   4259         BCM_IF_ERROR_RETURN(_bcm_field_reg_instance_get(unit,
   4260                                                            ETHERTYPE_MAPr,
   4261                                                            fg->instance,
   4262                                                            &reg));
   4263     }
   4264 
   4265     /* Write Register */
   4266     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg,
   4267                                 REG_PORT_ANY, entry->slice_idx, rval));
   4268 
   4269     return (rv);
   4270 }
   4271 
   4272 /*
   4273  * Function:
   4274  *  _field_th_class_ethertype_read
   4275  * Purpose:
   4276  *  Read EtherType Class Entry From Hardware.
   4277  * Parameters:
   4278  *  unit        - (IN)  BCM device number.
   4279  *  entry       - (IN)  Field Entry Info.
   4280  *  cdata       - (OUT) Field Class Entry DataBuffer.
   4281  * Returns:
   4282  *    BCM_E_XXX
   4283  * Notes:
   4284  *  No Null Check for entry, group and classdata buffer.
   4285  *  Done by calling function _bcm_field_th_class_entry_hwread
   4286  *  entry->slice_idx contains index to read
   4287  *  cdata contains data read from hardware.
   4288  */
   4289 STATIC int
   4290 _field_th_class_ethertype_read(int unit, _field_entry_t *entry,
   4291                                                   uint32 *cdata)
   4292 {
   4293     int rv = BCM_E_NONE;        /* Operation Return Status */
   4294     _field_group_t *fg = NULL;
   4295                                 /* Field group info */
   4296     _field_stage_t *stage_fc = NULL;
   4297                                 /* Stage field control info */
   4298     soc_reg_t reg;              /* SOC Register */
   4299 
   4300     /* Get class group info */
   4301     fg = entry->group;
   4302 
   4303     /* Get group stage control structure. */
   4304     rv = _field_stage_control_get(unit, fg->stage_id, &stage_fc);
   4305     if (BCM_FAILURE(rv)) {
   4306         LOG_ERROR(BSL_LS_BCM_FP,
   4307                  (BSL_META_U(unit,
   4308                  "FP(unit %d) Error: Stage (%d) control get failure.\n"),
   4309                  unit, fg->stage_id));
   4310         return (rv);
   4311     }
   4312 
   4313     /* Decide register based on operational mode */
   4314     if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) {
   4315         reg = ETHERTYPE_MAPr;
   4316     } else {
   4317         BCM_IF_ERROR_RETURN(_bcm_field_reg_instance_get(unit,
   4318                                                            ETHERTYPE_MAPr,
   4319                                                            fg->instance,
   4320                                                            &reg));
   4321     }
   4322 
   4323     /* Read Register */
   4324     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg,
   4325                                 REG_PORT_ANY, entry->slice_idx, cdata));
   4326 
   4327     return (rv);
   4328 }
   4329 
   4330 /*
   4331  * Function:
   4332  *  _field_th_class_l4srcport_install
   4333  * Purpose:
   4334  *  Install L4 Src port Class Entry In Hardware.
   4335  * Parameters:
   4336  *  unit        - (IN) BCM device number.
   4337  *  entry       - (IN) Field Entry Info.
   4338  * Returns:
   4339  *  BCM_E_XXX
   4340  * Notes:
   4341  *  No Null Check for entry, group and key.
   4342  *  Done by calling function _bcm_field_th_class_entry_hwinstall
   4343  *  entry->slice_idx contains index to write
   4344  *  entry->tcam.key contains data to write
   4345  */
   4346 STATIC int
   4347 _field_th_class_l4srcport_install(int unit, _field_entry_t *entry)
   4348 {
   4349     int rv = BCM_E_NONE;        /* Operation Return Status */
   4350     _field_group_t *fg = NULL;
   4351                                 /* Field group info */
   4352     _field_stage_t *stage_fc = NULL;
   4353                                 /* Stage field control info */
   4354     uint32 rval = 0;            /* Register Value */
   4355     soc_reg_t reg;              /* SOC Register */
   4356     uint32 *cdata = NULL;       /* Class Data */
   4357 
   4358     /* Get class data key and group info */
   4359     cdata = entry->tcam.key;
   4360     fg = entry->group;
   4361 
   4362     /* Get Class Data Value */
   4363     rval = *cdata;
   4364 
   4365     /* Get group stage control structure. */
   4366     rv = _field_stage_control_get(unit, fg->stage_id, &stage_fc);
   4367     if (BCM_FAILURE(rv)) {
   4368         LOG_ERROR(BSL_LS_BCM_FP,
   4369                  (BSL_META_U(unit,
   4370                  "FP(unit %d) Error: Stage (%d) control get failure.\n"),
   4371                  unit, fg->stage_id));
   4372         return (rv);
   4373     }
   4374 
   4375     /* Decide register based on operational mode */
   4376     if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) {
   4377         reg = L4_SRC_PORT_MAPr;
   4378     } else {
   4379         BCM_IF_ERROR_RETURN(_bcm_field_reg_instance_get(unit,
   4380                                                            L4_SRC_PORT_MAPr,
   4381                                                            fg->instance,
   4382                                                            &reg));
   4383 
   4384     }
   4385 
   4386     /* Write Register */
   4387     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY,
   4388                                                 entry->slice_idx, rval));
   4389 
   4390     return (rv);
   4391 }
   4392 
   4393 /*
   4394  * Function:
   4395  *  _field_th_class_l4srcport_read
   4396  * Purpose:
   4397  *  Read L4 Src port Class Entry From Hardware.
   4398  * Parameters:
   4399  *  unit        - (IN) BCM device number.
   4400  *  entry       - (IN) Field Entry Info.
   4401  *  cdata       - (OUT) Field Class Entry DataBuffer.
   4402  * Returns:
   4403  *    BCM_E_XXX
   4404  * Notes:
   4405  *  No Null Check for entry, group and classdata buffer.
   4406  *  Done by calling function _bcm_field_th_class_entry_hwread
   4407  *  entry->slice_idx contains index to read
   4408  *  cdata contains data read from hardware.
   4409  */
   4410 STATIC int
   4411 _field_th_class_l4srcport_read(int unit, _field_entry_t *entry,
   4412                                                   uint32 *cdata)
   4413 {
   4414     int rv = BCM_E_NONE;        /* Operation Return Status */
   4415     _field_group_t *fg = NULL;
   4416                                 /* Field group info */
   4417     _field_stage_t *stage_fc = NULL;
   4418                                 /* Stage field control info */
   4419     soc_reg_t reg;              /* SOC Register */
   4420 
   4421 
   4422     /* Get class group info */
   4423     fg = entry->group;
   4424 
   4425     /* Get group stage control structure. */
   4426     rv = _field_stage_control_get(unit, fg->stage_id, &stage_fc);
   4427     if (BCM_FAILURE(rv)) {
   4428         LOG_ERROR(BSL_LS_BCM_FP,
   4429                  (BSL_META_U(unit,
   4430                  "FP(unit %d) Error: Stage (%d) control get failure.\n"),
   4431                  unit, fg->stage_id));
   4432         return (rv);
   4433     }
   4434 
   4435     /* Decide register based on operational mode */
   4436     if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) {
   4437         reg = L4_SRC_PORT_MAPr;
   4438     } else {
   4439         BCM_IF_ERROR_RETURN(_bcm_field_reg_instance_get(unit,
   4440                                                            L4_SRC_PORT_MAPr,
   4441                                                            fg->instance,
   4442                                                            &reg));
   4443 
   4444     }
   4445 
   4446     /* Read Register */
   4447     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY,
   4448                                         entry->slice_idx, cdata));
   4449 
   4450     return (rv);
   4451 }
   4452 
   4453 /*
   4454  * Function:
   4455  *  _field_th_class_l4dstport_install
   4456  * Purpose:
   4457  *  Install L4 Dst Port Class Entry In Hardware.
   4458  * Parameters:
   4459  *  unit        - (IN) BCM device number.
   4460  *  entry       - (IN) Field Entry Info.
   4461  * Returns:
   4462  *  BCM_E_XXX
   4463  * Notes:
   4464  *  No Null Check for entry , group and key.
   4465  *  Done by calling function _bcm_field_th_class_entry_hwinstall
   4466  *  entry->slice_idx contains index to write
   4467  *  entry->tcam.key contains data to write
   4468  */
   4469 STATIC int
   4470 _field_th_class_l4dstport_install(int unit, _field_entry_t *entry)
   4471 {
   4472     int rv = BCM_E_NONE;        /* Operation Return Status */
   4473     _field_group_t *fg = NULL;
   4474                                 /* Field group info */
   4475     _field_stage_t *stage_fc = NULL;
   4476                                 /* Stage field control info */
   4477     uint32 rval = 0;            /* Register Value */
   4478     soc_reg_t reg;              /* SOC Register */
   4479     uint32 *cdata = NULL;       /* Class Data */
   4480 
   4481     /* Get class data key and group info */
   4482     cdata = entry->tcam.key;
   4483     fg = entry->group;
   4484 
   4485     /* Get Class Data Value */
   4486     rval = *cdata;
   4487 
   4488     /* Get group stage control structure. */
   4489     rv = _field_stage_control_get(unit, fg->stage_id, &stage_fc);
   4490     if (BCM_FAILURE(rv)) {
   4491         LOG_ERROR(BSL_LS_BCM_FP,
   4492                  (BSL_META_U(unit,
   4493                  "FP(unit %d) Error: Stage (%d) control get failure.\n"),
   4494                  unit, fg->stage_id));
   4495         return (rv);
   4496     }
   4497 
   4498     /* Decide register based on operational mode */
   4499     if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) {
   4500         reg = L4_DST_PORT_MAPr;
   4501     } else {
   4502         BCM_IF_ERROR_RETURN(_bcm_field_reg_instance_get(unit,
   4503                                                            L4_DST_PORT_MAPr,
   4504                                                            fg->instance,
   4505                                                            &reg));
   4506     }
   4507 
   4508     /* Write Register */
   4509     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY,
   4510                                                   entry->slice_idx, rval));
   4511 
   4512     return (rv);
   4513 }
   4514 
   4515 /*
   4516  * Function:
   4517  *  _field_th_class_l4dstport_read
   4518  * Purpose:
   4519  *  Read L4 Dst Port Class Entry From Hardware.
   4520  * Parameters:
   4521  *  unit        - (IN) BCM device number.
   4522  *  entry       - (IN) Field Entry Info.
   4523  *  cdata       - (OUT) Field Class Entry DataBuffer.
   4524  * Returns:
   4525  *  BCM_E_XXX
   4526  * Notes:
   4527  *  No Null Check for entry, group and classdata buffer.
   4528  *  Done by calling function _bcm_field_th_class_entry_hwread
   4529  *  entry->slice_idx contains index to read
   4530  *  cdata contains data read from hardware.
   4531  */
   4532  STATIC int
   4533 _field_th_class_l4dstport_read(int unit, _field_entry_t *entry,
   4534                                                  uint32 *cdata)
   4535 {
   4536     int rv = BCM_E_NONE;        /* Operation Return Status */
   4537     _field_group_t *fg = NULL;
   4538                                 /* Field group info */
   4539     _field_stage_t *stage_fc = NULL;
   4540                                 /* Stage field control info */
   4541     soc_reg_t reg;              /* SOC Register */
   4542 
   4543     /* Get class group info */
   4544     fg = entry->group;
   4545 
   4546     /* Get group stage control structure. */
   4547     rv = _field_stage_control_get(unit, fg->stage_id, &stage_fc);
   4548     if (BCM_FAILURE(rv)) {
   4549         LOG_ERROR(BSL_LS_BCM_FP,
   4550                  (BSL_META_U(unit,
   4551                  "FP(unit %d) Error: Stage (%d) control get failure.\n"),
   4552                  unit, fg->stage_id));
   4553         return (rv);
   4554     }
   4555 
   4556     /* Decide register based on operational mode */
   4557     if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) {
   4558         reg = L4_DST_PORT_MAPr;
   4559     } else {
   4560         BCM_IF_ERROR_RETURN(_bcm_field_reg_instance_get(unit,
   4561                                                            L4_DST_PORT_MAPr,
   4562                                                            fg->instance,
   4563                                                            &reg));
   4564     }
   4565 
   4566     /* Read Register */
   4567     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY,
   4568                                             entry->slice_idx, cdata));
   4569 
   4570     return (rv);
   4571 }
   4572 
   4573 /*
   4574  * Function:
   4575  *  _field_th_class_srccompression_install
   4576  * Purpose:
   4577  *  Install Src Compression Class Entry In Hardware.
   4578  * Parameters:
   4579  *  unit        - (IN) BCM device number.
   4580  *  entry       - (IN) Field Entry Info.
   4581  * Returns:
   4582  *  BCM_E_XXX
   4583  * Notes:
   4584  *  No Null Check for entry , group and key.
   4585  *  Done by calling function _bcm_field_th_class_entry_hwinstall
   4586  *  entry->slice_idx contains index to write
   4587  *  entry->tcam.key contains data to write
   4588  */
   4589 STATIC int
   4590 _field_th_class_srccompression_install(int unit, _field_entry_t *entry)
   4591 {
   4592     int rv = BCM_E_NONE;        /* Operation Return Status */
   4593     _field_group_t *fg = NULL;
   4594                                 /* Field group info */
   4595     _field_stage_t *stage_fc = NULL;
   4596                                 /* Stage field control info */
   4597     soc_mem_t mem;              /* SOC Memory */
   4598 
   4599     /* Get class group info */
   4600     fg = entry->group;
   4601 
   4602     /* Get group stage control structure. */
   4603     rv = _field_stage_control_get(unit, fg->stage_id, &stage_fc);
   4604     if (BCM_FAILURE(rv)) {
   4605         LOG_ERROR(BSL_LS_BCM_FP,
   4606                  (BSL_META_U(unit,
   4607                  "FP(unit %d) Error: Stage (%d) control get failure.\n"),
   4608                  unit, fg->stage_id));
   4609         return (rv);
   4610     }
   4611 
   4612     /* Decide register based on operational mode */
   4613     if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) {
   4614         mem = SRC_COMPRESSIONm;
   4615     } else {
   4616         BCM_IF_ERROR_RETURN(_bcm_field_mem_instance_get(unit,
   4617                                                SRC_COMPRESSIONm,
   4618                                                fg->instance,
   4619                                                &mem));
   4620     }
   4621 
   4622     /* Write Memory */
   4623     SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL,
   4624                                         entry->slice_idx, entry->tcam.key));
   4625 
   4626     return (rv);
   4627 }
   4628 
   4629 /*
   4630  * Function:
   4631  *  _field_th_class_srccompression_read
   4632  * Purpose:
   4633  *  Read Src Compression Class Entry From Hardware.
   4634  * Parameters:
   4635  *  unit        - (IN) BCM device number.
   4636  *  entry       - (IN) Field Entry Info.
   4637  *  cdata       - (OUT) Field Class Entry DataBuffer.
   4638  * Returns:
   4639  *  BCM_E_XXX
   4640  * Notes:
   4641  *  No Null Check for entry, group and classdata buffer.
   4642  *  Done by calling function _bcm_field_th_class_entry_hwread
   4643  *  entry->slice_idx contains index to read
   4644  *  cdata contains data read from hardware.
   4645  */
   4646 STATIC int
   4647 _field_th_class_srccompression_read(int unit, _field_entry_t *entry,
   4648                                                       uint32 *cdata)
   4649 {
   4650     int rv = BCM_E_NONE;        /* Operation Return Status */
   4651     _field_group_t *fg = NULL;
   4652                                 /* Field group info */
   4653     _field_stage_t *stage_fc = NULL;
   4654                                 /* Stage field control info */
   4655     soc_mem_t mem;              /* SOC Memory */
   4656 
   4657     /* Get class group info */
   4658     fg = entry->group;
   4659 
   4660     /* Get group stage control structure. */
   4661     rv = _field_stage_control_get(unit, fg->stage_id, &stage_fc);
   4662     if (BCM_FAILURE(rv)) {
   4663         LOG_ERROR(BSL_LS_BCM_FP,
   4664                  (BSL_META_U(unit,
   4665                  "FP(unit %d) Error: Stage (%d) control get failure.\n"),
   4666                  unit, fg->stage_id));
   4667         return (rv);
   4668     }
   4669 
   4670     /* Decide register based on operational mode */
   4671     if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) {
   4672         mem = SRC_COMPRESSIONm;
   4673     } else {
   4674         BCM_IF_ERROR_RETURN(_bcm_field_mem_instance_get(unit,
   4675                                                SRC_COMPRESSIONm,
   4676                                                fg->instance,
   4677                                                &mem));
   4678     }
   4679 
   4680     /* Read Memory */
   4681     SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ANY,
   4682                                                 entry->slice_idx, cdata));
   4683 
   4684     return (rv);
   4685 }
   4686 
   4687 /*
   4688  * Function:
   4689  *  _field_th_class_dstcompression_install
   4690  * Purpose:
   4691  *  Install Dst Compression Class Entry In Hardware.
   4692  * Parameters:
   4693  *  unit        - (IN) BCM device number.
   4694  *  entry       - (IN) Field Entry Info.
   4695  * Returns:
   4696  *  BCM_E_XXX
   4697  * Notes:
   4698  *  No Null Check for entry , group and key.
   4699  *  Done by calling function _bcm_field_th_class_entry_hwinstall
   4700  *  entry->slice_idx contains index to write
   4701  *  entry->tcam.key contains data to write
   4702  */
   4703 STATIC int
   4704 _field_th_class_dstcompression_install(int unit, _field_entry_t *entry)
   4705 {
   4706     int rv = BCM_E_NONE;        /* Operation Return Status */
   4707     _field_group_t *fg = NULL;
   4708                                 /* Field group info */
   4709     _field_stage_t *stage_fc = NULL;
   4710                                 /* Stage field control info */
   4711     soc_mem_t mem;              /* SOC Memory */
   4712 
   4713     /* Get class group info */
   4714     fg = entry->group;
   4715 
   4716     /* Get group stage control structure. */
   4717     rv = _field_stage_control_get(unit, fg->stage_id, &stage_fc);
   4718     if (BCM_FAILURE(rv)) {
   4719         LOG_ERROR(BSL_LS_BCM_FP,
   4720                  (BSL_META_U(unit,
   4721                  "FP(unit %d) Error: Stage (%d) control get failure.\n"),
   4722                  unit, fg->stage_id));
   4723         return (rv);
   4724     }
   4725 
   4726     /* Decide register based on operational mode */
   4727     if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) {
   4728         mem = DST_COMPRESSIONm;
   4729     } else {
   4730         BCM_IF_ERROR_RETURN(_bcm_field_mem_instance_get(unit,
   4731                                                DST_COMPRESSIONm,
   4732                                                fg->instance,
   4733                                                &mem));
   4734     }
   4735 
   4736     /* Write Memory */
   4737     SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL,
   4738                                       entry->slice_idx, entry->tcam.key));
   4739 
   4740     return (rv);
   4741 }
   4742 
   4743 /*
   4744  * Function:
   4745  *  _field_th_class_dstcompression_read
   4746  * Purpose:
   4747  *  Read Dst Compression Class Entry From Hardware.
   4748  * Parameters:
   4749  *  unit        - (IN) BCM device number.
   4750  *  entry       - (IN) Field Entry Info.
   4751  *  cdata       - (OUT) Field Class Entry DataBuffer.
   4752  * Returns:
   4753  *  BCM_E_XXX
   4754  * Notes:
   4755  *  No Null Check for entry, group and classdata buffer.
   4756  *  Done by calling function _bcm_field_th_class_entry_hwread
   4757  *  entry->slice_idx contains index to read
   4758  *  cdata contains data read from hardware.
   4759  */
   4760 STATIC int
   4761 _field_th_class_dstcompression_read(int unit, _field_entry_t *entry,
   4762                                                        uint32 *cdata)
   4763 {
   4764     int rv = BCM_E_NONE;        /* Operation Return Status */
   4765     _field_group_t *fg = NULL;
   4766                                 /* Field group info */
   4767     _field_stage_t *stage_fc = NULL;
   4768                                 /* Stage field control info */
   4769     soc_mem_t mem;              /* SOC Memory */
   4770 
   4771     /* Get class group info */
   4772     fg = entry->group;
   4773 
   4774     /* Get group stage control structure. */
   4775     rv = _field_stage_control_get(unit, fg->stage_id, &stage_fc);
   4776     if (BCM_FAILURE(rv)) {
   4777         LOG_ERROR(BSL_LS_BCM_FP,
   4778                  (BSL_META_U(unit,
   4779                  "FP(unit %d) Error: Stage (%d) control get failure.\n"),
   4780                  unit, fg->stage_id));
   4781         return (rv);
   4782     }
   4783 
   4784     /* Decide register based on operational mode */
   4785     if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) {
   4786         mem = DST_COMPRESSIONm;
   4787     } else {
   4788         BCM_IF_ERROR_RETURN(_bcm_field_mem_instance_get(unit,
   4789                                                DST_COMPRESSIONm,
   4790                                                fg->instance,
   4791                                                &mem));
   4792     }
   4793 
   4794     /* Read Memory */
   4795     SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ANY,
   4796                                      entry->slice_idx, cdata));
   4797 
   4798     return (rv);
   4799 }
   4800 
   4801 /*
   4802  * Function:
   4803  *  _field_th_class_ttl_install
   4804  * Purpose:
   4805  *  Install TTL Class Entry In Hardware.
   4806  * Parameters:
   4807  *  unit        - (IN) BCM device number.
   4808  *  entry       - (IN) Field Entry Info.
   4809  * Returns:
   4810  *  BCM_E_XXX
   4811  * Notes:
   4812  *  No Null Check for entry, group and key.
   4813  *  Done by calling function _bcm_field_th_class_entry_hwinstall
   4814  *  entry->slice_idx contains index to write
   4815  *  entry->tcam.key contains data to write
   4816  */
   4817 STATIC int
   4818 _field_th_class_ttl_install(int unit, _field_entry_t *entry)
   4819 {
   4820     int rv = BCM_E_NONE;        /* Operation Return Status */
   4821     _field_group_t *fg = NULL;
   4822                                 /* Field group info */
   4823     _field_stage_t *stage_fc = NULL;
   4824                                 /* Stage field control info */
   4825     soc_mem_t mem;              /* SOC Memory */
   4826 
   4827     /* Get class group info */
   4828     fg = entry->group;
   4829 
   4830     /* Get group stage control structure. */
   4831     rv = _field_stage_control_get(unit, fg->stage_id, &stage_fc);
   4832     if (BCM_FAILURE(rv)) {
   4833         LOG_ERROR(BSL_LS_BCM_FP,
   4834                  (BSL_META_U(unit,
   4835                  "FP(unit %d) Error: Stage (%d) control get failure.\n"),
   4836                  unit, fg->stage_id));
   4837         return (rv);
   4838     }
   4839 
   4840     /* Decide register based on operational mode */
   4841     if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) {
   4842         mem = TTL_FNm;
   4843     } else {
   4844         BCM_IF_ERROR_RETURN(_bcm_field_mem_instance_get(unit,
   4845                                                TTL_FNm,
   4846                                                fg->instance,
   4847                                                &mem));
   4848     }
   4849 
   4850     /* Write Memory */
   4851     SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL,
   4852                                       entry->slice_idx, entry->tcam.key));
   4853 
   4854     return (rv);
   4855 }
   4856 
   4857 /*
   4858  * Function:
   4859  *  _field_th_class_ttl_read
   4860  * Purpose:
   4861  *  Read TTL Class Entry From Hardware.
   4862  * Parameters:
   4863  *  unit        - (IN) BCM device number.
   4864  *  entry       - (IN) Field Entry Info.
   4865  *  cdata       - (OUT) Field Class Entry DataBuffer.
   4866  * Returns:
   4867  *  BCM_E_XXX
   4868  * Notes:
   4869  *  No Null Check for entry, group and classdata buffer.
   4870  *  Done by calling function _bcm_field_th_class_entry_hwread
   4871  *  entry->slice_idx contains index to read
   4872  *  cdata contains data read from hardware.
   4873  */
   4874 STATIC int
   4875 _field_th_class_ttl_read(int unit, _field_entry_t *entry,
   4876                                             uint32 *cdata)
   4877 {
   4878     int rv = BCM_E_NONE;        /* Operation Return Status */
   4879     _field_group_t *fg = NULL;
   4880                                 /* Field group info */
   4881     _field_stage_t *stage_fc = NULL;
   4882                                 /* Stage field control info */
   4883     soc_mem_t mem;              /* SOC Memory */
   4884 
   4885     /* Get class group info */
   4886     fg = entry->group;
   4887 
   4888     /* Get group stage control structure. */
   4889     rv = _field_stage_control_get(unit, fg->stage_id, &stage_fc);
   4890     if (BCM_FAILURE(rv)) {
   4891         LOG_ERROR(BSL_LS_BCM_FP,
   4892                  (BSL_META_U(unit,
   4893                  "FP(unit %d) Error: Stage (%d) control get failure.\n"),
   4894                  unit, fg->stage_id));
   4895         return (rv);
   4896     }
   4897 
   4898     /* Decide register based on operational mode */
   4899     if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) {
   4900         mem = TTL_FNm;
   4901     } else {
   4902         BCM_IF_ERROR_RETURN(_bcm_field_mem_instance_get(unit,
   4903                                                TTL_FNm,
   4904                                                fg->instance,
   4905                                                &mem));
   4906     }
   4907 
   4908     /* Read Memory */
   4909     SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ANY,
   4910                                      entry->slice_idx, cdata));
   4911 
   4912     return (rv);
   4913 }
   4914 
   4915 /*
   4916  * Function:
   4917  *  _field_th_class_tos_install
   4918  * Purpose:
   4919  *  Install TOS Class Entry In Hardware.
   4920  * Parameters:
   4921  *  unit        - (IN) BCM device number.
   4922  *  entry       - (IN) Field Entry Info.
   4923  * Returns:
   4924  *  BCM_E_XXX
   4925  * Notes:
   4926  *  No Null Check for entry, group and key.
   4927  *  Done by calling function _bcm_field_th_class_entry_hwinstall
   4928  *  entry->slice_idx contains index to write
   4929  *  entry->tcam.key contains data to write
   4930  */
   4931 STATIC int
   4932 _field_th_class_tos_install(int unit, _field_entry_t *entry)
   4933 {
   4934     int rv = BCM_E_NONE;        /* Operation Return Status */
   4935     _field_group_t *fg = NULL;
   4936                                 /* Field group info */
   4937     _field_stage_t *stage_fc = NULL;
   4938                                 /* Stage field control info */
   4939     soc_mem_t mem;              /* SOC Memory */
   4940 
   4941     /* Get class group info */
   4942     fg = entry->group;
   4943 
   4944     /* Get group stage control structure. */
   4945     rv = _field_stage_control_get(unit, fg->stage_id, &stage_fc);
   4946     if (BCM_FAILURE(rv)) {
   4947         LOG_ERROR(BSL_LS_BCM_FP,
   4948                  (BSL_META_U(unit,
   4949                  "FP(unit %d) Error: Stage (%d) control get failure.\n"),
   4950                  unit, fg->stage_id));
   4951         return (rv);
   4952     }
   4953 
   4954     /* Decide register based on operational mode */
   4955     if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) {
   4956         mem = TOS_FNm;
   4957     } else {
   4958         BCM_IF_ERROR_RETURN(_bcm_field_mem_instance_get(unit,
   4959                                                TOS_FNm,
   4960                                                fg->instance,
   4961                                                &mem));
   4962     }
   4963 
   4964     /* Write Memory */
   4965     SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL,
   4966                                       entry->slice_idx, entry->tcam.key));
   4967 
   4968     return (rv);
   4969 }
   4970 
   4971 /*
   4972  * Function:
   4973  *  _field_th_class_tos_read
   4974  * Purpose:
   4975  *  Read TOS Class Entry From Hardware.
   4976  * Parameters:
   4977  *  unit        - (IN) BCM device number.
   4978  *  entry       - (IN) Field Entry Info.
   4979  *  cdata       - (OUT) Field Class Entry DataBuffer.
   4980  * Returns:
   4981  *  BCM_E_XXX
   4982  * Notes:
   4983  *  No Null Check for entry, group and classdata buffer.
   4984  *  Done by calling function _bcm_field_th_class_entry_hwread
   4985  *  entry->slice_idx contains index to read
   4986  *  cdata contains data read from hardware.
   4987  */
   4988 STATIC int
   4989 _field_th_class_tos_read(int unit, _field_entry_t *entry,
   4990                                             uint32 *cdata)
   4991 {
   4992     int rv = BCM_E_NONE;        /* Operation Return Status */
   4993     _field_group_t *fg = NULL;
   4994                                 /* Field group info */
   4995     _field_stage_t *stage_fc = NULL;
   4996                                 /* Stage field control info */
   4997     soc_mem_t mem;              /* SOC Memory */
   4998 
   4999     /* Get class group info */
   5000     fg = entry->group;
   5001 
   5002     /* Get group stage control structure. */
   5003     rv = _field_stage_control_get(unit, fg->stage_id, &stage_fc);
   5004     if (BCM_FAILURE(rv)) {
   5005         LOG_ERROR(BSL_LS_BCM_FP,
   5006                  (BSL_META_U(unit,
   5007                  "FP(unit %d) Error: Stage (%d) control get failure.\n"),
   5008                  unit, fg->stage_id));
   5009         return (rv);
   5010     }
   5011 
   5012     /* Decide register based on operational mode */
   5013     if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) {
   5014         mem = TOS_FNm;
   5015     } else {
   5016         BCM_IF_ERROR_RETURN(_bcm_field_mem_instance_get(unit,
   5017                                                TOS_FNm,
   5018                                                fg->instance,
   5019                                                &mem));
   5020 
   5021     }
   5022     /* Read Memory */
   5023     SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ANY,
   5024                                      entry->slice_idx, cdata));
   5025 
   5026     return (rv);
   5027 }
   5028 
   5029 /*
   5030  * Function:
   5031  *  _field_th_class_ipproto_install
   5032  * Purpose:
   5033  *  Install IP Protocol Class Entry In Hardware.
   5034  * Parameters:
   5035  *  unit        - (IN) BCM device number.
   5036  *  entry       - (IN) Field Entry Info.
   5037  * Returns:
   5038  *  BCM_E_XXX
   5039  * Notes:
   5040  *  No Null Check for entry , group and key.
   5041  *  Done by calling function _bcm_field_th_class_entry_hwinstall
   5042  *  entry->slice_idx contains index to write
   5043  *  entry->tcam.key contains data to write
   5044  */
   5045 STATIC int
   5046 _field_th_class_ipproto_install(int unit, _field_entry_t *entry)
   5047 {
   5048     int rv = BCM_E_NONE;        /* Operation Return Status */
   5049     _field_group_t *fg = NULL;
   5050                                 /* Field group info */
   5051     _field_stage_t *stage_fc = NULL;
   5052                                 /* Stage field control info */
   5053     soc_mem_t mem;              /* SOC Memory */
   5054 
   5055     /* Get class group info */
   5056     fg = entry->group;
   5057 
   5058     /* Get group stage control structure. */
   5059     rv = _field_stage_control_get(unit, fg->stage_id, &stage_fc);
   5060     if (BCM_FAILURE(rv)) {
   5061         LOG_ERROR(BSL_LS_BCM_FP,
   5062                  (BSL_META_U(unit,
   5063                  "FP(unit %d) Error: Stage (%d) control get failure.\n"),
   5064                  unit, fg->stage_id));
   5065         return (rv);
   5066     }
   5067 
   5068     /* Decide register based on operational mode */
   5069     if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) {
   5070         mem = IP_PROTO_MAPm;
   5071     } else {
   5072         BCM_IF_ERROR_RETURN(_bcm_field_mem_instance_get(unit,
   5073                                                IP_PROTO_MAPm,
   5074                                                fg->instance,
   5075                                                &mem));
   5076     }
   5077 
   5078     /* Write Memory */
   5079     SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL,
   5080                                       entry->slice_idx, entry->tcam.key));
   5081 
   5082     return (rv);
   5083 }
   5084 
   5085 /*
   5086  * Function:
   5087  *  _field_th_class_ipproto_read
   5088  * Purpose:
   5089  *  Read IP Protocol Class Entry From Hardware.
   5090  * Parameters:
   5091  *  unit        - (IN) BCM device number.
   5092  *  entry       - (IN) Field Entry Info.
   5093  *  cdata       - (OUT) Field Class Entry DataBuffer.
   5094  * Returns:
   5095  *  BCM_E_XXX
   5096  * Notes:
   5097  *  No Null Check for entry, group and classdata buffer.
   5098  *  Done by calling function _bcm_field_th_class_entry_hwread
   5099  *  entry->slice_idx contains index to read
   5100  *  cdata contains data read from hardware.
   5101  */
   5102  STATIC int
   5103 _field_th_class_ipproto_read(int unit, _field_entry_t *entry,
   5104                                                 uint32 *cdata)
   5105 {
   5106     int rv = BCM_E_NONE;        /* Operation Return Status */
   5107     _field_group_t *fg = NULL;
   5108                                 /* Field group info */
   5109     _field_stage_t *stage_fc = NULL;
   5110                                 /* Stage field control info */
   5111     soc_mem_t mem;              /* SOC Memory */
   5112 
   5113     /* Get class group info */
   5114     fg = entry->group;
   5115 
   5116     /* Get group stage control structure. */
   5117     rv = _field_stage_control_get(unit, fg->stage_id, &stage_fc);
   5118     if (BCM_FAILURE(rv)) {
   5119         LOG_ERROR(BSL_LS_BCM_FP,
   5120                  (BSL_META_U(unit,
   5121                  "FP(unit %d) Error: Stage (%d) control get failure.\n"),
   5122                  unit, fg->stage_id));
   5123         return (rv);
   5124     }
   5125 
   5126     /* Decide register based on operational mode */
   5127     if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) {
   5128         mem = IP_PROTO_MAPm;
   5129     } else {
   5130         BCM_IF_ERROR_RETURN(_bcm_field_mem_instance_get(unit,
   5131                                                IP_PROTO_MAPm,
   5132                                                fg->instance,
   5133                                                &mem));
   5134     }
   5135 
   5136     /* Read Memory */
   5137     SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ANY,
   5138                                      entry->slice_idx, cdata));
   5139 
   5140     return (rv);
   5141 }
   5142 
   5143 /*
   5144  * Function:
   5145  *  _field_th_class_tcp_install
   5146  * Purpose:
   5147  *  Install TCP Class Entry In Hardware.
   5148  * Parameters:
   5149  *  unit        - (IN) BCM device number.
   5150  *  entry       - (IN) Field Entry Info.
   5151  * Returns:
   5152  *  BCM_E_XXX
   5153  * Notes:
   5154  *  No Null Check for entry , group and key.
   5155  *  Done by calling function _bcm_field_th_class_entry_hwinstall
   5156  *  entry->slice_idx contains index to write
   5157  *  entry->tcam.key contains data to write
   5158  */
   5159 STATIC int
   5160 _field_th_class_tcp_install(int unit, _field_entry_t *entry)
   5161 {
   5162     int rv = BCM_E_NONE;        /* Operation Return Status */
   5163     _field_group_t *fg = NULL;
   5164                                 /* Field group info */
   5165     _field_stage_t *stage_fc = NULL;
   5166                                 /* Stage field control info */
   5167     soc_mem_t mem;              /* SOC Memory */
   5168 
   5169     /* Get class group info */
   5170     fg = entry->group;
   5171 
   5172     /* Get group stage control structure. */
   5173     rv = _field_stage_control_get(unit, fg->stage_id, &stage_fc);
   5174     if (BCM_FAILURE(rv)) {
   5175         LOG_ERROR(BSL_LS_BCM_FP,
   5176                  (BSL_META_U(unit,
   5177                  "FP(unit %d) Error: Stage (%d) control get failure.\n"),
   5178                  unit, fg->stage_id));
   5179         return (rv);
   5180     }
   5181 
   5182     /* Decide register based on operational mode */
   5183     if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) {
   5184         mem = TCP_FNm;
   5185     } else {
   5186         BCM_IF_ERROR_RETURN(_bcm_field_mem_instance_get(unit,
   5187                                                TCP_FNm,
   5188                                                fg->instance,
   5189                                                &mem));
   5190     }
   5191 
   5192     /* Write Memory */
   5193     SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL,
   5194                                       entry->slice_idx, entry->tcam.key));
   5195 
   5196     return (rv);
   5197 }
   5198 
   5199 /*
   5200  * Function:
   5201  *  _field_th_class_tcp_read
   5202  * Purpose:
   5203  *  Read TCP Class Entry From Hardware.
   5204  * Parameters:
   5205  *  unit        - (IN) BCM device number.
   5206  *  entry       - (IN) Field Entry Info.
   5207  *  cdata       - (OUT) Field Class Entry DataBuffer.
   5208  * Returns:
   5209  *  BCM_E_XXX
   5210  * Notes:
   5211  *  No Null Check for entry, group and classdata buffer.
   5212  *  Done by calling function _bcm_field_th_class_entry_hwread
   5213  *  entry->slice_idx contains index to read
   5214  *  cdata contains data read from hardware.
   5215  */
   5216 STATIC int
   5217 _field_th_class_tcp_read(int unit, _field_entry_t *entry,
   5218                                             uint32 *cdata)
   5219 {
   5220     int rv = BCM_E_NONE;        /* Operation Return Status */
   5221     _field_group_t *fg = NULL;
   5222                                 /* Field group info */
   5223     _field_stage_t *stage_fc = NULL;
   5224                                 /* Stage field control info */
   5225     soc_mem_t mem;              /* SOC Memory */
   5226 
   5227     /* Get class group info */
   5228     fg = entry->group;
   5229 
   5230     /* Get group stage control structure. */
   5231     rv = _field_stage_control_get(unit, fg->stage_id, &stage_fc);
   5232     if (BCM_FAILURE(rv)) {
   5233         LOG_ERROR(BSL_LS_BCM_FP,
   5234                  (BSL_META_U(unit,
   5235                  "FP(unit %d) Error: Stage (%d) control get failure.\n"),
   5236                  unit, fg->stage_id));
   5237         return (rv);
   5238     }
   5239 
   5240     /* Decide register based on operational mode */
   5241     if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) {
   5242         mem = TCP_FNm;
   5243     } else {
   5244         BCM_IF_ERROR_RETURN(_bcm_field_mem_instance_get(unit,
   5245                                                TCP_FNm,
   5246                                                fg->instance,
   5247                                                &mem));
   5248     }
   5249 
   5250     /* Read Memory */
   5251     SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ANY,
   5252                                      entry->slice_idx, cdata));
   5253 
   5254     return (rv);
   5255 }
   5256 /*
   5257  * Function:
   5258  *  _field_th_class_iptunnelttl_install
   5259  * Purpose:
   5260  *  Install IP Tunnel TTL Class Entry In Hardware.
   5261  * Parameters:
   5262  *  unit        - (IN) BCM device number.
   5263  *  entry       - (IN) Field Entry Info.
   5264  * Returns:
   5265  *  BCM_E_XXX
   5266  * Notes:
   5267  *  No Null Check for entry, group and key.
   5268  *  Done by calling function _bcm_field_th_class_entry_hwinstall
   5269  *  entry->slice_idx contains index to write
   5270  *  entry->tcam.key contains data to write
   5271  */
   5272 STATIC int
   5273 _field_th_class_iptunnelttl_install(int unit, _field_entry_t *entry)
   5274 {
   5275     int rv = BCM_E_NONE;        /* Operation Return Status */
   5276     _field_group_t *fg = NULL;
   5277                                 /* Field group info */
   5278     _field_stage_t *stage_fc = NULL;
   5279                                 /* Stage field control info */
   5280     soc_mem_t mem;              /* SOC Memory */
   5281 
   5282     /* Get class group info */
   5283     fg = entry->group;
   5284 
   5285     /* Get group stage control structure. */
   5286     rv = _field_stage_control_get(unit, fg->stage_id, &stage_fc);
   5287     if (BCM_FAILURE(rv)) {
   5288         LOG_ERROR(BSL_LS_BCM_FP,
   5289                  (BSL_META_U(unit,
   5290                  "FP(unit %d) Error: Stage (%d) control get failure.\n"),
   5291                  unit, fg->stage_id));
   5292         return (rv);
   5293     }
   5294 
   5295     /* Decide register based on operational mode */
   5296     if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) {
   5297         mem = ALT_TTL_FNm;
   5298     } else {
   5299         BCM_IF_ERROR_RETURN(_bcm_field_mem_instance_get(unit,
   5300                                                ALT_TTL_FNm,
   5301                                                fg->instance,
   5302                                                &mem));
   5303     }
   5304 
   5305     /* Write Memory */
   5306     SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL,
   5307                                       entry->slice_idx, entry->tcam.key));
   5308 
   5309     return (rv);
   5310 }
   5311 
   5312 /*
   5313  * Function:
   5314  *  _field_th_class_iptunnelttl_read
   5315  * Purpose:
   5316  *  Read Ip Tunnel TTL Class Entry From Hardware.
   5317  * Parameters:
   5318  *  unit        - (IN) BCM device number.
   5319  *  entry       - (IN) Field Entry Info.
   5320  *  cdata       - (OUT) Field Class Entry DataBuffer.
   5321  * Returns:
   5322  *  BCM_E_XXX
   5323  * Notes:
   5324  *  No Null Check for entry, group and classdata buffer.
   5325  *  Done by calling function _bcm_field_th_class_entry_hwread
   5326  *  entry->slice_idx contains index to read
   5327  *  cdata contains data read from hardware.
   5328  */
   5329 STATIC int
   5330 _field_th_class_iptunnelttl_read(int unit, _field_entry_t *entry,
   5331                                             uint32 *cdata)
   5332 {
   5333     int rv = BCM_E_NONE;        /* Operation Return Status */
   5334     _field_group_t *fg = NULL;
   5335                                 /* Field group info */
   5336     _field_stage_t *stage_fc = NULL;
   5337                                 /* Stage field control info */
   5338     soc_mem_t mem;              /* SOC Memory */
   5339 
   5340     /* Get class group info */
   5341     fg = entry->group;
   5342 
   5343     /* Get group stage control structure. */
   5344     rv = _field_stage_control_get(unit, fg->stage_id, &stage_fc);
   5345     if (BCM_FAILURE(rv)) {
   5346         LOG_ERROR(BSL_LS_BCM_FP,
   5347                  (BSL_META_U(unit,
   5348                  "FP(unit %d) Error: Stage (%d) control get failure.\n"),
   5349                  unit, fg->stage_id));
   5350         return (rv);
   5351     }
   5352 
   5353     /* Decide register based on operational mode */
   5354     if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) {
   5355         mem = ALT_TTL_FNm;
   5356     } else {
   5357         BCM_IF_ERROR_RETURN(_bcm_field_mem_instance_get(unit,
   5358                                                ALT_TTL_FNm,
   5359                                                fg->instance,
   5360                                                &mem));
   5361     }
   5362 
   5363     /* Read Memory */
   5364     SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ANY,
   5365                                      entry->slice_idx, cdata));
   5366 
   5367     return (rv);
   5368 }
   5369 
   5370 
   5371 /*
   5372  * Function:
   5373  *  _bcm_field_th_class_entry_remove
   5374  * Purpose:
   5375  *  Remove Field Class Entry In Hardware.
   5376  * Parameters:
   5377  *  unit     - (IN) BCM device number.
   5378  *  entry    - (IN) Field Entry Id.
   5379  * Returns:
   5380  *  BCM_E_XXX
   5381  */
   5382 int
   5383 _bcm_field_th_class_entry_remove(int unit, bcm_field_entry_t entry)
   5384 {
   5385     int rv = BCM_E_NONE;            /* Operation Return Status */
   5386     _field_group_t *fg = NULL;      /* Field group info */
   5387     _field_entry_t *f_ent = NULL;   /* Field entry info */
   5388     _field_class_type_t ctype;      /* Field Class Type */
   5389     _field_class_info_t **class_status_arr;
   5390                                     /* Field Per Pipe Class Status Array */
   5391     _field_class_info_t *class_status_info;
   5392                                     /* Field Per Compression table status */
   5393     _field_stage_t *stage_fc = NULL;
   5394                                     /* Stage field control info */
   5395 
   5396     /* Confirm that 'entry' is  present on unit */
   5397     if (BCM_FAILURE(_field_entry_get(unit, entry, _FP_ENTRY_PRIMARY, &f_ent))) {
   5398         LOG_ERROR(BSL_LS_BCM_FP,
   5399                  (BSL_META_U(unit,
   5400                  "FP(unit %d) Error: entry=(%d) already exists.\n"),
   5401                  unit, entry));
   5402         return (BCM_E_EXISTS);
   5403     }
   5404 
   5405     /* Retreive Field Group and Action */
   5406     fg = f_ent->group;
   5407 
   5408     /* Check if group is associated */
   5409     if (fg == NULL) {
   5410         return (BCM_E_INTERNAL);
   5411     }
   5412 
   5413     /* Get group stage control structure. */
   5414     rv = _field_stage_control_get(unit, fg->stage_id, &stage_fc);
   5415     if (BCM_FAILURE(rv)) {
   5416         LOG_ERROR(BSL_LS_BCM_FP,
   5417                  (BSL_META_U(unit,
   5418                  "FP(unit %d) Error: Stage (%d) control get failure.\n"),
   5419                  unit, fg->stage_id));
   5420         return (rv);
   5421     }
   5422 
   5423     /* Entry not installed in hardware to perform remove operation. */
   5424     if (!(f_ent->flags & _FP_ENTRY_INSTALLED)) {
   5425         return (BCM_E_NONE);
   5426     }
   5427 
   5428     /* Entry hardware index not present */
   5429     if (f_ent->slice_idx == -1) {
   5430         return (BCM_E_INTERNAL);
   5431     }
   5432 
   5433     /* Retreive Class Type from entry qset */
   5434     rv = _bcm_field_th_class_type_qset_get(unit, &fg->qset, &ctype);
   5435     if (BCM_FAILURE(rv)) {
   5436         return (rv);
   5437     }
   5438 
   5439     if (f_ent->tcam.key != NULL) {
   5440         sal_memset(f_ent->tcam.key, 0, f_ent->tcam.key_size);
   5441     } else {
   5442         _FP_XGS3_ALLOC(f_ent->tcam.key,
   5443                        f_ent->tcam.key_size, "field class entry key");
   5444         if (f_ent->tcam.key == NULL) {
   5445             LOG_ERROR(BSL_LS_BCM_FP,
   5446                      (BSL_META_U(unit,
   5447                      "FP(unit %d) Error: allocation failure for "
   5448                      "class entry key.\n"),
   5449                      unit));
   5450             return (BCM_E_MEMORY);
   5451         }
   5452     }
   5453 
   5454     /* Update Class Status Info Structure */
   5455     class_status_arr = stage_fc->class_info_arr[fg->instance];
   5456     if (class_status_arr == NULL) {
   5457         return (BCM_E_INTERNAL);
   5458     }
   5459     class_status_info = class_status_arr[ctype];
   5460     if (class_status_info == NULL) {
   5461         return (BCM_E_INTERNAL);
   5462     }
   5463 
   5464     rv = _bcm_field_th_class_entry_hwinstall(unit, f_ent, ctype);
   5465     if (BCM_FAILURE(rv)) {
   5466         return (rv);
   5467     }
   5468 
   5469     _FP_CLASS_TABLE_BMP_REMOVE(class_status_info->class_bmp, f_ent->slice_idx);
   5470     f_ent->slice_idx = -1;
   5471     f_ent->flags &= ~(_FP_ENTRY_INSTALLED);
   5472 
   5473     return (rv);
   5474 }
   5475 
   5476 /*
   5477  * Function:
   5478  *  _bcm_field_th_class_qual_support_check
   5479  * Purpose:
   5480  *  Check if the qualifier is supported in the stage class
   5481  * Parameters:
   5482  *  unit - (IN) BCM device number.
   5483  *  qual - (IN) Qualifier to check.
   5484  * Returns:
   5485  *  TRUE - Qualifier is supported by the stage
   5486  *  FALSE - Qualifier is NOT supported by the stage
   5487  */
   5488 int
   5489 _bcm_field_th_class_qual_support_check(int unit, int qual)
   5490 {
   5491     switch(qual)
   5492     {
   5493         case bcmFieldQualifyStageClass:
   5494         case bcmFieldQualifyIpProtocolClass:
   5495         case bcmFieldQualifyEtherTypeClass:
   5496         case bcmFieldQualifyL4SrcPortClass:
   5497         case bcmFieldQualifyL4DstPortClass:
   5498         case bcmFieldQualifySrcIpClass:
   5499         case bcmFieldQualifySrcIpClassMsbNibble:
   5500         case bcmFieldQualifySrcIpClassLower:
   5501         case bcmFieldQualifySrcIpClassUpper:
   5502         case bcmFieldQualifySrcIp6Class:
   5503         case bcmFieldQualifySrcIp6ClassMsbNibble:
   5504         case bcmFieldQualifySrcIp6ClassLower:
   5505         case bcmFieldQualifySrcIp6ClassUpper:
   5506         case bcmFieldQualifyFcoeOxIDClass:
   5507         case bcmFieldQualifyDstIpClassMsbNibble:
   5508         case bcmFieldQualifyDstIpClass:
   5509         case bcmFieldQualifyDstIpClassLower:
   5510         case bcmFieldQualifyDstIpClassUpper:
   5511         case bcmFieldQualifyDstIp6Class:
   5512         case bcmFieldQualifyDstIp6ClassMsbNibble:
   5513         case bcmFieldQualifyDstIp6ClassLower:
   5514         case bcmFieldQualifyDstIp6ClassUpper:
   5515         case bcmFieldQualifyFcoeRxIDClass:
   5516         case bcmFieldQualifyFibreChanSrcIdClass:
   5517         case bcmFieldQualifyFibreChanSrcIdClassMsbNibble:
   5518         case bcmFieldQualifyFibreChanSrcIdClassLower:
   5519         case bcmFieldQualifyFibreChanSrcIdClassUpper:
   5520         case bcmFieldQualifyFibreChanDstIdClass:
   5521         case bcmFieldQualifyFibreChanDstIdClassMsbNibble:
   5522         case bcmFieldQualifyFibreChanDstIdClassLower:
   5523         case bcmFieldQualifyFibreChanDstIdClassUpper:
   5524         case bcmFieldQualifyTcpClassZero:
   5525         case bcmFieldQualifyTosClassZero:
   5526         case bcmFieldQualifyTtlClassZero:
   5527         case bcmFieldQualifyIpTunnelTtlClassZero:
   5528         case bcmFieldQualifyTcpClassOne:
   5529         case bcmFieldQualifyTosClassOne:
   5530         case bcmFieldQualifyTtlClassOne:
   5531             return TRUE;
   5532         default:
   5533             ;
   5534     }
   5535     return FALSE;
   5536 }
   5537 
   5538 #else /* BCM_TOMAHAWK_SUPPORT && BCM_FIELD_SUPPORT */
   5539 int _th_field_not_empty;
   5540 #endif /* !BCM_TOMAHAWK_SUPPORT && !BCM_FIELD_SUPPORT */