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.c (11714B)


      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  * SOC Routines related to Field module.
      8  */
      9 
     10 #include <soc/debug.h>
     11 #include <soc/tomahawk.h>
     12 #include <bcm_int/esw/tomahawk.h>
     13 #include <bcm_int/esw/xgs4.h>
     14 #if defined(BCM_TOMAHAWK_SUPPORT)
     15 
     16 /*
     17  * Function:
     18  *      soc_th_field_mem_mode_get
     19  * Purpose:
     20  *      Retrieve Field Processor Group operational mode
     21  *      for the given field memory.
     22  * Parameters:
     23  *      unit    - (IN)  BCM Device number.
     24  *      mem     - (IN)  Field TCAM Memory.
     25  *      mode    - (OUT) Reference to SER memory mode.
     26  *
     27  * Returns:
     28  *      SOC_E_NONE   - Operation successful.
     29  *      SOC_E_PARAM  - Invalid parameter.
     30  *      SOC_E_INIT   - BCM unit not initialized.
     31  *
     32  * Notes:
     33  *      Valid "mem" input parameter values supported by
     34  *      this routine:
     35  *          "VFP_TCAMm, EFP_TCAMm, IFP_TCAMm,"
     36  *          "IFP_TCAM_WIDEm, IFP_LOGICAL_TABLE_TCAMm"
     37  *          "EXACT_MATCH_LOGICAL_TABLE_SELECTm."
     38  */
     39 int
     40 soc_th_field_mem_mode_get(int unit, soc_mem_t mem, int *mode)
     41 {
     42    bcm_field_qualify_t          stage;      /* Field Stage Qualifier Id */
     43    bcm_field_group_oper_mode_t  oper_mode;  /* Field Operation Mode */
     44    int                          rv;         /* Return Value */
     45 
     46    /* Validate input parameters */
     47    if (mode == NULL) {
     48       return SOC_E_PARAM;
     49    }
     50 
     51    switch (mem) {
     52      /* Field lookup TCAMs and SRAMs */
     53      case VFP_TCAMm:
     54      case VFP_POLICY_TABLEm:
     55           stage = bcmFieldQualifyStageLookup;
     56           break;
     57 
     58      /* Field Egress TCAMs and SRAMs */
     59      case EFP_TCAMm:
     60      case EFP_POLICY_TABLEm:
     61      case EFP_COUNTER_TABLEm:
     62      case EFP_METER_TABLEm:
     63           stage = bcmFieldQualifyStageEgress;
     64           break;
     65 
     66      /* Field Ingress TCAMs */
     67      case IFP_LOGICAL_TABLE_SELECTm:
     68      case IFP_LOGICAL_TABLE_SELECT_TCAM_ONLYm:
     69      case IFP_TCAMm:
     70      /* Field Ingress SRAMs */
     71      case IFP_LOGICAL_TABLE_SELECT_DATA_ONLYm:
     72      case IFP_LOGICAL_TABLE_ACTION_PRIORITYm:
     73      case IFP_KEY_GEN_PROGRAM_PROFILEm:
     74      case IFP_KEY_GEN_PROGRAM_PROFILE2m:
     75      case IFP_POLICY_TABLEm:
     76      case IFP_METER_TABLEm:
     77           stage = bcmFieldQualifyStageIngress;
     78           break;
     79 
     80      /* Exact Match TCAMs */ 
     81      case EXACT_MATCH_LOGICAL_TABLE_SELECTm:
     82      case EXACT_MATCH_LOGICAL_TABLE_SELECT_TCAM_ONLYm:
     83      /* Exact Match SRAMs */ 
     84      case EXACT_MATCH_LOGICAL_TABLE_SELECT_DATA_ONLYm:
     85      case EXACT_MATCH_KEY_GEN_PROGRAM_PROFILEm:
     86      case EXACT_MATCH_ACTION_PROFILEm:
     87      case EXACT_MATCH_QOS_ACTIONS_PROFILEm:
     88      case EXACT_MATCH_DEFAULT_POLICYm:
     89      case EXACT_MATCH_KEY_GEN_MASKm:
     90      case EXACT_MATCH_2m:
     91      case EXACT_MATCH_4m:
     92      case EXACT_MATCH_2_ENTRY_ONLYm:
     93      case EXACT_MATCH_4_ENTRY_ONLYm:
     94           stage = bcmFieldQualifyStageIngressExactMatch;
     95           break;
     96 
     97      /* Field Ingress Compression TCAMs and SRAMs */
     98      case SRC_COMPRESSIONm:
     99      case SRC_COMPRESSION_TCAM_ONLYm:
    100      case SRC_COMPRESSION_DATA_ONLYm:
    101      case DST_COMPRESSIONm:
    102      case DST_COMPRESSION_TCAM_ONLYm:
    103      case DST_COMPRESSION_DATA_ONLYm:
    104           stage = bcmFieldQualifyStageClass;
    105           break;
    106      case TTL_FNm:
    107      case TOS_FNm:
    108      case TCP_FNm:
    109      case IP_PROTO_MAPm:
    110           stage = bcmFieldQualifyStageClassExactMatch;
    111           break;
    112      case FP_UDF_TCAMm:
    113      case FP_UDF_OFFSETm:
    114           /* 
    115            * When udf support is not available or the memory is not being used
    116            * by either UDF or FIELD module, return BCM_E_UNAVAIL
    117            */
    118           if (soc_feature(unit, soc_feature_udf_support) && UDF_CTRL(unit)) {
    119              if (UDF_CTRL(unit)->udf_used_by_module == UDF_USED_BY_UDF_MODULE) {
    120                   bcm_udf_oper_mode_t udf_oper_mode = 0;
    121                   rv = bcmi_xgs4_udf_oper_mode_get(unit, &udf_oper_mode);
    122                   if (BCM_SUCCESS(rv)) {
    123                      *mode = (udf_oper_mode == bcmUdfOperModeGlobal) ?
    124                       _SOC_SER_MEM_MODE_GLOBAL : _SOC_SER_MEM_MODE_PIPE_UNIQUE;
    125                   }
    126               } else if(UDF_CTRL(unit)->udf_used_by_module ==
    127                                                      UDF_USED_BY_FIELD_MODULE) {
    128                   /*
    129                    *  Currently Field Module is not supporting per-pipe mode
    130                    *  for this memory. Hence, returning it as Global mode.
    131                    */
    132                   *mode = _SOC_SER_MEM_MODE_GLOBAL;
    133                   rv = BCM_E_NONE;
    134               } else {
    135                   /* Not used by any of the module. */
    136                   rv = BCM_E_UNAVAIL;
    137               }
    138           } else {
    139               /* Feature doesn't support */
    140               rv = BCM_E_UNAVAIL;
    141           }
    142 
    143           if (BCM_FAILURE(rv)) {
    144               LOG_ERROR(BSL_LS_BCM_FP, (BSL_META_U(unit,
    145                       "Failed to get Operation Mode[%d] for UDF Memory[%d].\n"),
    146                        rv, mem));
    147           }
    148           return rv; 
    149      case IFP_TCAM_WIDEm:
    150           if (soc_property_get(unit, spn_FIELD_ATOMIC_UPDATE, FALSE) == TRUE) {
    151              stage = bcmFieldQualifyStageIngress;
    152           } else {
    153             /*
    154              *  Inorder to support bcmFieldQualifyInPorts in Global mode,
    155              *  IP_TCAM_WIDE should always be in pipe local mode.
    156              */
    157              *mode = _SOC_SER_MEM_MODE_PIPE_UNIQUE;
    158             return BCM_E_NONE;
    159           }
    160           break;
    161 
    162      default:
    163           return SOC_E_UNAVAIL;
    164           break;
    165    }
    166 
    167    rv = _bcm_field_th_group_oper_mode_get(unit, stage, &oper_mode);
    168    if (SOC_FAILURE(rv)) {
    169        LOG_ERROR(BSL_LS_BCM_FP,
    170                  (BSL_META_U(unit,
    171                              "Failed to get Group Operation Mode[%d] for "
    172                              "Stage Qualifier[%d]/TCAM Memory[%d].\n"),
    173                              rv, stage, mem));
    174        return rv;
    175    }
    176 
    177    *mode = (oper_mode == bcmFieldGroupOperModeGlobal) ?
    178                _SOC_SER_MEM_MODE_GLOBAL:_SOC_SER_MEM_MODE_PIPE_UNIQUE;
    179 
    180    return SOC_E_NONE;
    181 }
    182 
    183 /*
    184  * Function:
    185  *     soc_mem_field_nw_tcam_prio_order_index_get
    186  *
    187  * Purpose:
    188  *     To retrieve the right priority index for the given index for the groups
    189  *     operated in narrow wide (80-bit) TCAMs.
    190  *
    191  * Parameters:
    192  *     unit     - (IN) BCM device number.
    193  *     mem      - (IN) Memory
    194  *     tcam_idx - (IN) Reference to TCAM index.
    195  *
    196  * Returns:
    197  *     SOC_E_NONE      - Success
    198  */
    199 int soc_mem_field_nw_tcam_prio_order_index_get(int unit,
    200                                                soc_mem_t mem,
    201                                                int *tcam_idx)
    202 {
    203    int slice_num;
    204    soc_reg_t reg = INVALIDr;
    205 
    206    if (soc_feature(unit, soc_feature_fp_nw_tcam_prio_order_war) &&
    207        ((mem == IFP_TCAMm) || (mem == IFP_TCAM_PIPE0m) ||
    208         (mem == IFP_TCAM_PIPE1m) || (mem == IFP_TCAM_PIPE2m) ||
    209         (mem == IFP_TCAM_PIPE3m) || (mem == IFP_POLICY_TABLEm) ||
    210         (mem == IFP_POLICY_TABLE_PIPE0m) || (mem == IFP_POLICY_TABLE_PIPE1m) ||
    211         (mem == IFP_POLICY_TABLE_PIPE2m) || (mem == IFP_POLICY_TABLE_PIPE3m))) {
    212    
    213       if (tcam_idx == NULL) {
    214          return SOC_E_PARAM;
    215       }
    216    
    217       /*
    218        * As IFP_POLICY_TABLE is common among multiple IFP_TCAM modes,
    219        * retrieve the field mode in-case of Policy Table.
    220        */              
    221       if (mem == IFP_POLICY_TABLEm) {
    222          reg = IFP_CONFIGr;
    223       } else if (mem == IFP_POLICY_TABLE_PIPE0m) {
    224          reg = IFP_CONFIG_PIPE0r;
    225       } else if (mem == IFP_POLICY_TABLE_PIPE1m) {
    226          reg = IFP_CONFIG_PIPE1r;
    227       } else if (mem == IFP_POLICY_TABLE_PIPE2m) {
    228          reg = IFP_CONFIG_PIPE2r;
    229       } else if (mem == IFP_POLICY_TABLE_PIPE3m) {
    230          reg = IFP_CONFIG_PIPE3r;
    231       }
    232 
    233       /* Calculate slice number of the given tcam_idx. */
    234       slice_num = (*tcam_idx)/512;
    235 
    236       if (reg != INVALIDr) {
    237          uint32 regval = 0;
    238          uint32 mode; 
    239 
    240          SOC_IF_ERROR_RETURN
    241            (soc_reg32_get(unit, reg, REG_PORT_ANY, slice_num, &regval));
    242 
    243          if (soc_feature(unit, soc_feature_ifp_no_narrow_mode_support)) {
    244             mode = 1;
    245          } else {
    246             mode = soc_reg_field_get(unit, reg, regval, IFP_SLICE_MODEf);
    247          }
    248 
    249          /* Return if the TCAM mode is WIDE. */
    250          if (mode == 1) {
    251             return SOC_E_NONE;
    252          }
    253       }
    254 
    255       LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit,
    256                 "Changed TCAM_ID: %d -"), *tcam_idx));
    257 
    258       if (*tcam_idx % 2) {
    259          *tcam_idx = 256 + (slice_num * 256) + ((*tcam_idx)/2);
    260       } else {
    261          *tcam_idx = (slice_num * 256) + ((*tcam_idx)/2);
    262       }
    263 
    264       LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit,
    265                 " %d for slice:%d\n\r"), *tcam_idx, slice_num));
    266    }
    267 
    268    return SOC_E_NONE;
    269 }
    270 
    271 /*
    272  * Function:
    273  *    soc_th_ifp_mem_write
    274  * Purpose:
    275  *    Write a memory internal to the SOC for TH IFP.
    276  * Notes:
    277  *    GBP/CBP memory should only accessed when MMU is in DEBUG mode.
    278  */
    279 int
    280 soc_th_ifp_mem_write(int unit, soc_mem_t mem, int copyno, int index,
    281                      void *entry_data)
    282 {
    283     int rv;
    284 
    285     if (soc_feature(unit, soc_feature_fp_nw_tcam_prio_order_war) &&
    286         ((mem == IFP_TCAMm) || (mem == IFP_TCAM_PIPE0m) ||
    287         (mem == IFP_TCAM_PIPE1m) || (mem == IFP_TCAM_PIPE2m) ||
    288         (mem == IFP_TCAM_PIPE3m) || (mem == IFP_POLICY_TABLEm) ||
    289         (mem == IFP_POLICY_TABLE_PIPE0m) || (mem == IFP_POLICY_TABLE_PIPE1m) ||
    290         (mem == IFP_POLICY_TABLE_PIPE2m) || (mem == IFP_POLICY_TABLE_PIPE3m))) {
    291 
    292          rv = soc_mem_field_nw_tcam_prio_order_index_get(unit, mem, &index);
    293          SOC_IF_ERROR_RETURN(rv);
    294 
    295     }
    296 
    297     return soc_mem_write(unit, mem, copyno, index, entry_data);
    298 }
    299 
    300 /*
    301  * Function:
    302  *    soc_th_ifp_mem_read
    303  * Purpose:
    304  *    Read a memory internal to the SOC for TH IFP.
    305  * Notes:
    306  *    GBP/CBP memory should only accessed when MMU is in DEBUG mode.
    307  */
    308 int
    309 soc_th_ifp_mem_read(int unit, soc_mem_t mem, int copyno, int index,
    310                     void *entry_data)
    311 {
    312     int rv;
    313 
    314     if (soc_feature(unit, soc_feature_fp_nw_tcam_prio_order_war) &&
    315         ((mem == IFP_TCAMm) || (mem == IFP_TCAM_PIPE0m) ||
    316         (mem == IFP_TCAM_PIPE1m) || (mem == IFP_TCAM_PIPE2m) ||
    317         (mem == IFP_TCAM_PIPE3m) || (mem == IFP_POLICY_TABLEm) ||
    318         (mem == IFP_POLICY_TABLE_PIPE0m) || (mem == IFP_POLICY_TABLE_PIPE1m) ||
    319         (mem == IFP_POLICY_TABLE_PIPE2m) || (mem == IFP_POLICY_TABLE_PIPE3m))) {
    320 
    321            rv = soc_mem_field_nw_tcam_prio_order_index_get(unit, mem, &index);
    322            SOC_IF_ERROR_RETURN(rv);
    323 
    324     }
    325 
    326     return soc_mem_read(unit, mem, copyno, index, entry_data);
    327 }
    328 
    329 /*
    330  * Function:
    331  *      soc_th_ifp_slice_mode_get
    332  * Purpose:
    333  *      Retrieve the IFP TCAM slice mode and enable status.
    334  * Parameters:
    335  *      unit       - (IN) BCM Device number.
    336  *      pipe       - (IN) Pipe Instance. (pipe < 0 indicates Global.)
    337  *      slice_num  - (IN) IFP TCAM Slice number.
    338  *      slice_mode - (OUT) IFP TCAM mode.
    339  *      slice_enabled - (OUT) Whether the slice is enabled.
    340  *
    341  * Returns:
    342  *      SOC_E_NONE   - Operation successful.
    343  *      SOC_E_PARAM  - Invalid parameter.
    344  *      SOC_E_INIT   - Field Module is not initialized.
    345  */
    346 int
    347 soc_th_ifp_slice_mode_get(int unit, int pipe, int slice_num, int *slice_mode,
    348                           int *slice_enabled)
    349 {
    350    int    rv;         /* Return Value */
    351 
    352    /* Validate input parameters */
    353    if (slice_mode == NULL || slice_enabled == NULL) {
    354       return SOC_E_PARAM;
    355    }
    356 
    357    rv = _bcm_field_th_ifp_slice_mode_get(unit, pipe, slice_num,
    358                                     slice_mode, slice_enabled);
    359    return rv;
    360 }
    361 
    362 #endif /* BCM_TOMAHAWK_SUPPORT */