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

pfc.c (11705B)


      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  * PFC implemenation for Tomahawk3
      8  */
      9 #if defined(BCM_TOMAHAWK3_SUPPORT)
     10 #include <bcm_int/esw/pfc.h>
     11 #include <bcm_int/esw/port.h>
     12 #include <soc/pfc.h>
     13 #include <soc/feature.h>
     14 #include <soc/drv.h>
     15 #include <soc/types.h>
     16 #include <soc/scache.h>
     17 #include <soc/profile_mem.h>
     18 #include <soc/debug.h>
     19 #include <soc/tomahawk.h>
     20 #include <soc/dma.h>
     21 #include <soc/mmu_config.h>
     22 #include <soc/init/tomahawk3_idb_init.h>
     23 
     24 #define TH3_PFC_PRIORITY_GROUP_ID_MIN 0
     25 #define TH3_PFC_PRIORITY_GROUP_ID_MAX 7
     26 #define TH3_PORT_PG_ENABLE_MASK 0xff
     27 
     28 
     29 
     30 /*
     31  * Function:
     32  *      bcm_th3_port_priority_group_config_set
     33  * Purpose:
     34  *      Set the port priority group configuration.
     35  * Parameters:
     36  *      unit       - (IN) device id.
     37  *      gport     - (IN) generic port.
     38  *      priority_group - (IN) priority group id.
     39  *      prigrp_config  - (IN) structure describes port PG configuration.
     40  * Returns:
     41  *      BCM_E_XXX
     42  */
     43 int
     44 bcm_th3_port_priority_group_config_set(int unit, bcm_gport_t gport,
     45     int priority_group, bcm_port_priority_group_config_t *prigrp_config)
     46 {
     47     bcm_port_t port;
     48     uint32 rval, pri_bmp;
     49 
     50     if(!soc_feature(unit, soc_feature_priority_flow_control)) {
     51         return BCM_E_UNAVAIL;
     52     }
     53     if ((priority_group < TH3_PFC_PRIORITY_GROUP_ID_MIN) ||
     54         (priority_group > TH3_PFC_PRIORITY_GROUP_ID_MAX)) {
     55         return BCM_E_PARAM;
     56     }
     57     if (prigrp_config == NULL) {
     58         return BCM_E_PARAM;
     59     }
     60     /* The following fields should not used in TH3 */
     61     if (prigrp_config->shared_pool_xoff_enable ||
     62         prigrp_config->shared_pool_discard_enable ||
     63         prigrp_config->priority_enable_vector_mask) {
     64         return BCM_E_UNAVAIL;
     65     }
     66 
     67     BCM_IF_ERROR_RETURN(_bcm_th3_cosq_localport_resolve(unit, gport, &port));
     68     if (!SOC_PORT_VALID(unit, port)) {
     69         return BCM_E_PORT;
     70     }
     71 
     72     SOC_IF_ERROR_RETURN(READ_MMU_THDI_ING_PORT_CONFIGr(unit, port, &rval));
     73     pri_bmp = soc_reg_field_get(unit, MMU_THDI_ING_PORT_CONFIGr, rval,
     74                                 PFC_PG_ENABLEf);
     75 
     76     if (prigrp_config->pfc_transmit_enable) {
     77         pri_bmp |= (1 << priority_group);
     78     } else {
     79         pri_bmp &= ~(1 << priority_group);
     80     }
     81 
     82     soc_reg_field_set(unit, MMU_THDI_ING_PORT_CONFIGr, &rval,
     83                                 PFC_PG_ENABLEf, pri_bmp);
     84     BCM_IF_ERROR_RETURN(WRITE_MMU_THDI_ING_PORT_CONFIGr(unit, port, rval));
     85     return BCM_E_NONE;
     86 }
     87 
     88 /*
     89  * Function:
     90  *      bcm_th3_port_priority_group_config_get
     91  * Purpose:
     92  *      Get the port priority group configuration.
     93  * Parameters:
     94  *      unit       - (IN) device id.
     95  *      gport     - (IN) generic port.
     96  *      priority_group - (IN) priority group id.
     97  *      prigrp_config  - (OUT) structure describes port PG configuration.
     98  * Returns:
     99  *      BCM_E_XXX
    100  */
    101 int
    102 bcm_th3_port_priority_group_config_get(int unit, bcm_gport_t gport,
    103     int priority_group, bcm_port_priority_group_config_t *prigrp_config)
    104 {
    105     bcm_port_t port;
    106     uint32 rval, pri_bmp;
    107 
    108     if (!soc_feature(unit, soc_feature_priority_flow_control)) {
    109         return BCM_E_UNAVAIL;
    110     }
    111     if ((priority_group < TH3_PFC_PRIORITY_GROUP_ID_MIN) ||
    112         (priority_group > TH3_PFC_PRIORITY_GROUP_ID_MAX)) {
    113         return BCM_E_PARAM;
    114     }
    115     if (prigrp_config == NULL) {
    116         return BCM_E_PARAM;
    117     }
    118 
    119     BCM_IF_ERROR_RETURN(_bcm_th3_cosq_localport_resolve(unit, gport, &port));
    120     if (!SOC_PORT_VALID(unit, port)) {
    121         return BCM_E_PORT;
    122     }
    123 
    124     SOC_IF_ERROR_RETURN(READ_MMU_THDI_ING_PORT_CONFIGr(unit, port, &rval));
    125     pri_bmp = soc_reg_field_get(unit, MMU_THDI_ING_PORT_CONFIGr, rval,
    126                                 PFC_PG_ENABLEf);
    127     if (pri_bmp & (1U << priority_group)) {
    128         prigrp_config->pfc_transmit_enable = 1;
    129     } else {
    130         prigrp_config->pfc_transmit_enable = 0;
    131     }
    132 
    133     return BCM_E_NONE;
    134 }
    135 /*
    136  * Function:
    137         bcm_th3_mmu_pfc_tx_config_set
    138 * Purpose:
    139  *      Enable/diable PFC tx.
    140  * Parameters:
    141  *      unit       - (IN) device id.
    142  *      port     - (IN) logical port number.
    143  *      pfc_enable - (IN) PFC enable, 0: disable, 1: enable.
    144  *      pri_bmp  - (OUT) priority Group Bitmap.
    145  * Returns:
    146  *      BCM_E_XXX
    147  */
    148 
    149 int
    150 bcm_th3_mmu_pfc_tx_config_set(int unit, bcm_port_t port, int pfc_enable,
    151                               uint32 pri_bmp)
    152 {
    153     soc_reg_t reg = INVALIDr;
    154     uint32 rval;
    155 
    156     /* only 8 bits are needed, higher-position bits are masked out */
    157     pri_bmp = pri_bmp & TH3_PORT_PG_ENABLE_MASK;
    158     reg = MMU_THDI_ING_PORT_CONFIGr;
    159 
    160     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, port, 0, &rval));
    161 
    162     soc_reg_field_set(unit, reg, &rval, PFC_PG_ENABLEf,
    163             pfc_enable ? pri_bmp : 0);
    164 
    165     soc_reg_field_set(unit, reg, &rval, PAUSE_ENABLEf,
    166             pfc_enable ? 0 : 1);
    167 
    168     SOC_IF_ERROR_RETURN
    169             (soc_reg32_set(unit, reg, port, 0, rval));
    170 
    171     if (IS_CD_PORT(unit, port)) {
    172         soc_info_t *si = &SOC_INFO(unit);
    173         uint64 rval64;
    174         int pipe, pm_num, phy_port, subp;
    175         const soc_reg_t obm_fc_config_regs[_TH3_PIPES_PER_DEV]
    176            [_TH3_PBLKS_PER_PIPE] =
    177            {{IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE0r, IDB_OBM1_FLOW_CONTROL_CONFIG_PIPE0r,
    178              IDB_OBM2_FLOW_CONTROL_CONFIG_PIPE0r, IDB_OBM3_FLOW_CONTROL_CONFIG_PIPE0r},
    179             {IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE1r, IDB_OBM1_FLOW_CONTROL_CONFIG_PIPE1r,
    180              IDB_OBM2_FLOW_CONTROL_CONFIG_PIPE1r, IDB_OBM3_FLOW_CONTROL_CONFIG_PIPE1r},
    181             {IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE2r, IDB_OBM1_FLOW_CONTROL_CONFIG_PIPE2r,
    182              IDB_OBM2_FLOW_CONTROL_CONFIG_PIPE2r, IDB_OBM3_FLOW_CONTROL_CONFIG_PIPE2r},
    183             {IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE3r, IDB_OBM1_FLOW_CONTROL_CONFIG_PIPE3r,
    184              IDB_OBM2_FLOW_CONTROL_CONFIG_PIPE3r, IDB_OBM3_FLOW_CONTROL_CONFIG_PIPE3r},
    185             {IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE4r, IDB_OBM1_FLOW_CONTROL_CONFIG_PIPE4r,
    186              IDB_OBM2_FLOW_CONTROL_CONFIG_PIPE4r, IDB_OBM3_FLOW_CONTROL_CONFIG_PIPE4r},
    187             {IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE5r, IDB_OBM1_FLOW_CONTROL_CONFIG_PIPE5r,
    188              IDB_OBM2_FLOW_CONTROL_CONFIG_PIPE5r, IDB_OBM3_FLOW_CONTROL_CONFIG_PIPE5r},
    189             {IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE6r, IDB_OBM1_FLOW_CONTROL_CONFIG_PIPE6r,
    190              IDB_OBM2_FLOW_CONTROL_CONFIG_PIPE6r, IDB_OBM3_FLOW_CONTROL_CONFIG_PIPE6r},
    191             {IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE7r, IDB_OBM1_FLOW_CONTROL_CONFIG_PIPE7r,
    192              IDB_OBM2_FLOW_CONTROL_CONFIG_PIPE7r, IDB_OBM3_FLOW_CONTROL_CONFIG_PIPE7r},
    193         };
    194 
    195         phy_port = si->port_l2p_mapping[port];
    196         pipe = soc_tomahawk3_get_pipe_from_phy_port(phy_port);
    197         pm_num = soc_tomahawk3_get_pipe_pm_from_phy_port(phy_port);
    198         subp = soc_tomahawk3_get_subp_from_phy_port(phy_port);
    199         reg = obm_fc_config_regs[pipe][pm_num];
    200         COMPILER_64_SET(rval64, 0, 0);
    201         SOC_IF_ERROR_RETURN
    202             (soc_reg_rawport_get(unit, reg, REG_PORT_ANY,
    203                                  subp, &rval64));
    204         soc_reg64_field32_set(unit, reg,
    205                               &rval64, FC_TYPEf, pfc_enable);
    206         SOC_IF_ERROR_RETURN
    207             (soc_reg_rawport_set(unit, reg, REG_PORT_ANY,
    208                                  subp, rval64));
    209      }
    210      return BCM_E_NONE;
    211 }
    212 
    213 /*
    214  * Function:
    215         bcm_th3_mmu_pfc_rx_config_set
    216 * Purpose:
    217  *      Enable/diable PFC rx.
    218  * Parameters:
    219  *      unit       - (IN) device id.
    220  *      port     - (IN) logical port number.
    221  *      pfc_enable - (IN) PFC enable, 0: disable, 1: enable.
    222  * Returns:
    223  *      BCM_E_XXX
    224  */
    225 int
    226 bcm_th3_mmu_pfc_rx_config_set(int unit, bcm_port_t port, int pfc_enable)
    227 {
    228     uint32 rval;
    229     soc_reg_t reg = MMU_INTFI_EGR_PORT_CFGr;
    230 
    231     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, port, 0, &rval));
    232 
    233     soc_reg_field_set(unit, reg, &rval, DISABLE_Q_FCf,
    234             pfc_enable ? 0 : 1);
    235 
    236     SOC_IF_ERROR_RETURN
    237             (soc_reg32_set(unit, reg, port, 0, rval));
    238     return BCM_E_NONE;
    239 }
    240 
    241 /*
    242  * Function:
    243         bcm_tomahawk3_cosq_pfc_class_config_profile_get
    244 * Purpose:
    245  *      Get an entire PFC class (RX) profile, tomahawk3 dispatch function
    246  * Parameters:
    247  *      unit       - (IN) device id.
    248  *      profile_id     - (IN) Profile ID.
    249  *      max_count - (IN) Maximum number of elements in config array
    250  *      config_array - (OUT) PFC class config array
    251  *      count   - (OUT) actual size of array
    252  * Returns:
    253  *      BCM_E_XXX
    254  */
    255 
    256 int
    257 bcm_tomahawk3_cosq_pfc_class_config_profile_get(
    258     int unit,
    259     int profile_id,
    260     int max_count,
    261     bcm_cosq_pfc_class_map_config_t *config_array,
    262     int *count)
    263 {
    264     return (soc_th3_pfc_rx_priority_mapping_profile_get
    265              (unit, profile_id, max_count,
    266                 (soc_cosq_pfc_class_map_config_t *) config_array, count));
    267 }
    268 
    269 /*
    270  * Function:
    271         bcm_tomahawk3_cosq_pfc_class_config_profile_set
    272 * Purpose:
    273  *      Set an entire PFC class (RX) profile, tomahawk3 dispatch function.
    274  * Parameters:
    275  *      unit       - (IN) device id.
    276  *      profile_id     - (IN) Profile ID.
    277  *      count   - (IN) actual size of array
    278  *      config_array - (IN) PFC class config array
    279  * Returns:
    280  *      BCM_E_XXX
    281  */
    282 
    283 int
    284 bcm_tomahawk3_cosq_pfc_class_config_profile_set(
    285     int unit,
    286     int profile_id,
    287     int count,
    288     bcm_cosq_pfc_class_map_config_t *config_array)
    289 {
    290 
    291     return (soc_th3_pfc_rx_priority_mapping_profile_set
    292                 (unit, profile_id,
    293                     (soc_cosq_pfc_class_map_config_t *) config_array, count));
    294 }
    295 
    296 /*
    297  * Function:
    298         bcm_tomahawk3_cosq_priority_group_pfc_priority_mapping_profile_get
    299 * Purpose:
    300  *      Get a PFC-tx priority to PG mapping profile, tomahawk3 dispatch function
    301  * Parameters:
    302  *      unit       - (IN) device id.
    303  *      profile_id     - (IN) Profile ID.
    304  *      array_max - (IN) Maximum number of elements in PG array
    305  *      config_array - (OUT) PG array, indexed by PFC priority
    306  *      array_count   - (OUT) actual size of array
    307  * Returns:
    308  *      BCM_E_XXX
    309  */
    310 int
    311 bcm_tomahawk3_cosq_priority_group_pfc_priority_mapping_profile_get(
    312     int unit,
    313     int profile_id,
    314     int array_max,
    315     int *pg_array,
    316     int *array_count)
    317 {
    318     return (soc_th3_pfc_tx_priority_mapping_profile_op(unit, profile_id,
    319                 array_max, SOC_TH3_PFC_PROFILE_OP_GET, array_count, pg_array));
    320 }
    321 
    322 /*
    323  * Function:
    324         bcm_tomahawk3_cosq_priority_group_pfc_priority_mapping_profile_set
    325 * Purpose:
    326  *      Set a PFC-tx priority to PG mapping profile, tomahawk3 dispatch function
    327  * Parameters:
    328  *      unit       - (IN) device id.
    329  *      profile_id     - (IN) Profile ID.
    330  *      array_count   - (IN) actual size of array
    331  *      config_array - (IN) PG array, indexed by PFC priority
    332 
    333  * Returns:
    334  *      BCM_E_XXX
    335  */
    336 int
    337 bcm_tomahawk3_cosq_priority_group_pfc_priority_mapping_profile_set(
    338     int unit,
    339     int profile_id,
    340     int array_count,
    341     int *pg_array)
    342 {
    343     return (soc_th3_pfc_tx_priority_mapping_profile_op(unit, profile_id,
    344                 0, SOC_TH3_PFC_PROFILE_OP_SET, &array_count, pg_array));
    345 }
    346 
    347 
    348 /*
    349  * Function:
    350         bcm_tomahawk3_cosq_port_optimized_pfc_group_num_get
    351  * Purpose:
    352  *      Get number of optimized PFC groups on a port, tomahawk3 dispatch function
    353  * Parameters:
    354  *      unit    - (IN) device id.
    355  *      port    - (IN) logical port number.
    356  *      count   - (OUT) number of optimized PFC groups supported.
    357  *
    358  * Returns:
    359  *      BCM_E_XXX
    360  */
    361 int
    362 bcm_tomahawk3_cosq_port_optimized_pfc_group_num_get(
    363     int unit,
    364     bcm_port_t port,
    365     int *count)
    366 {
    367     return (soc_th3_pfc_num_optimized_group_get(unit, port, count));
    368 }
    369 #endif