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

preemption.c (7378B)


      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 #include <soc/drv.h>
      8 #include <soc/greyhound2.h>
      9 #include <bcm/error.h>
     10 #include <bcm/types.h>
     11 #include <shared/bsl.h>
     12 #include <bcm_int/esw_dispatch.h>
     13 
     14 #if defined(BCM_GREYHOUND2_SUPPORT)
     15 STATIC int
     16 bcmi_gh2_preemption_port_check(int unit, bcm_port_t port)
     17 {
     18     if (!IS_XL_PORT(unit, port) && !IS_GE_PORT(unit, port)) {
     19         return BCM_E_UNAVAIL;
     20     } else {
     21         return BCM_E_NONE;
     22     }
     23 }
     24 
     25 int
     26 bcmi_gh2_preemption_capability_set(int unit, bcm_port_t port,
     27                                    uint32 arg)
     28 {
     29     soc_info_t *si = &SOC_INFO(unit);
     30     int phy_port = si->port_l2p_mapping[port];
     31     int link_up;
     32 
     33     BCM_IF_ERROR_RETURN(
     34         bcm_esw_port_link_status_get(unit, port, &link_up));
     35     if (1 == link_up) {
     36         LOG_ERROR(BSL_LS_BCMAPI_PORT,
     37                   (BSL_META_U(unit,
     38                               "This needs to be setup during link down\n")));
     39         return BCM_E_CONFIG;
     40     }
     41 
     42     BCM_IF_ERROR_RETURN(bcmi_gh2_preemption_port_check(unit, port));
     43     BCM_IF_ERROR_RETURN(
     44         soc_reg_field32_modify(unit,
     45                                MMU_PORT_PREEMPTION_CONFIGr,
     46                                port,
     47                                PREEMPTION_MODEf,
     48                                arg ? 1 : 0));
     49     BCM_IF_ERROR_RETURN(
     50         soc_mem_field32_modify(unit,
     51                                EGR_EDB_XMIT_CTRLm,
     52                                phy_port,
     53                                EP_PORT_PORT_PREEMPT_MODEf,
     54                                arg ? 1 : 0));
     55     return BCM_E_NONE;
     56 }
     57 
     58 int
     59 bcmi_gh2_preemption_queue_bitmap_set(int unit, bcm_port_t port,
     60                                      uint32 arg)
     61 {
     62     BCM_IF_ERROR_RETURN(bcmi_gh2_preemption_port_check(unit, port));
     63     BCM_IF_ERROR_RETURN(
     64         soc_reg_field_validate(unit,
     65                                MMU_PORT_PREEMPTION_CONFIGr,
     66                                PREEMPTION_Q_BITMAPf,
     67                                arg));
     68     BCM_IF_ERROR_RETURN(
     69         soc_reg_field32_modify(unit,
     70                                MMU_PORT_PREEMPTION_CONFIGr,
     71                                port,
     72                                PREEMPTION_Q_BITMAPf,
     73                                arg));
     74     return BCM_E_NONE;
     75 }
     76 
     77 int
     78 bcmi_gh2_preemption_hold_request_mode_set(int unit, bcm_port_t port,
     79                                           uint32 arg)
     80 {
     81     BCM_IF_ERROR_RETURN(bcmi_gh2_preemption_port_check(unit, port));
     82     BCM_IF_ERROR_RETURN(
     83         soc_reg_field32_modify(unit,
     84                                MMU_PORT_PREEMPTION_CONFIGr,
     85                                port,
     86                                HOLD_REQ_CNT_MODEf,
     87                                arg ? 1 : 0));
     88     return BCM_E_NONE;
     89 }
     90 
     91 int
     92 bcmi_gh2_preemption_frag_config_tx_set(int unit, bcm_port_t port,
     93                                        int is_final,
     94                                        uint32 value)
     95 {
     96     uint32 hw_value;
     97     soc_info_t *si = &SOC_INFO(unit);
     98     int phy_port = si->port_l2p_mapping[port];
     99 
    100     BCM_IF_ERROR_RETURN(bcmi_gh2_preemption_port_check(unit, port));
    101 
    102     if(value > 512 || value < 64) {
    103         return BCM_E_PARAM;
    104     }
    105     if (IS_GE_PORT(unit, port)) {
    106         if (value % 16) {
    107            return BCM_E_PARAM;
    108         }
    109     } else if (IS_XL_PORT(unit, port)) {
    110         if (value % 32) {
    111            return BCM_E_PARAM;
    112         }
    113     } else {
    114         return BCM_E_INTERNAL; /* should not happen */
    115     }
    116 
    117     if (512 == value) {
    118         /* The size for is max(32N, hw_value*4)
    119          * because the there is only 7 bits in hw_value
    120          * set hw_value to 127 for the size 512
    121          */
    122         hw_value = 127;
    123     } else {
    124         hw_value = value / 4;
    125     }
    126     return soc_mem_field32_modify(unit, EGR_EDB_XMIT_CTRLm, phy_port,
    127                                   (is_final ? MIN_FINAL_FRAG_SIZEf:
    128                                               MIN_NON_FINAL_FRAG_SIZEf),
    129                                   hw_value);
    130 }
    131 
    132 
    133 int
    134 bcmi_gh2_preemption_capability_get(int unit, bcm_port_t port,
    135                                    uint32* arg)
    136 {
    137     uint32 regval;
    138 
    139     if (NULL == arg) {
    140         return SOC_E_PARAM;
    141     }
    142     BCM_IF_ERROR_RETURN(bcmi_gh2_preemption_port_check(unit, port));
    143     BCM_IF_ERROR_RETURN(
    144         READ_MMU_PORT_PREEMPTION_CONFIGr(unit, port,
    145                                          &regval));
    146     *arg = soc_reg_field_get(unit,
    147                              MMU_PORT_PREEMPTION_CONFIGr,
    148                              regval, PREEMPTION_MODEf);
    149     return BCM_E_NONE;
    150 }
    151 
    152 int
    153 bcmi_gh2_preemption_queue_bitmap_get(int unit, bcm_port_t port,
    154                                      uint32* arg)
    155 {
    156     uint32 regval;
    157 
    158     if (NULL == arg) {
    159         return SOC_E_PARAM;
    160     }
    161     BCM_IF_ERROR_RETURN(bcmi_gh2_preemption_port_check(unit, port));
    162     BCM_IF_ERROR_RETURN(
    163         READ_MMU_PORT_PREEMPTION_CONFIGr(unit, port,
    164                                          &regval));
    165     *arg = soc_reg_field_get(unit,
    166                              MMU_PORT_PREEMPTION_CONFIGr,
    167                              regval, PREEMPTION_Q_BITMAPf);
    168     return BCM_E_NONE;
    169 }
    170 
    171 int
    172 bcmi_gh2_preemption_hold_request_mode_get(int unit, bcm_port_t port,
    173                                           uint32* arg)
    174 {
    175     uint32 regval;
    176 
    177     if (NULL == arg) {
    178         return SOC_E_PARAM;
    179     }
    180     BCM_IF_ERROR_RETURN(bcmi_gh2_preemption_port_check(unit, port));
    181     BCM_IF_ERROR_RETURN(
    182         READ_MMU_PORT_PREEMPTION_CONFIGr(unit, port,
    183                                          &regval));
    184     *arg = soc_reg_field_get(unit,
    185                              MMU_PORT_PREEMPTION_CONFIGr,
    186                              regval, HOLD_REQ_CNT_MODEf);
    187     return BCM_E_NONE;
    188 }
    189 
    190 int
    191 bcmi_gh2_preemption_frag_config_tx_get(int unit, bcm_port_t port,
    192                                        int is_final,
    193                                        uint32* value)
    194 {
    195     egr_edb_xmit_ctrl_entry_t entry;
    196     soc_info_t *si = &SOC_INFO(unit);
    197     int phy_port = si->port_l2p_mapping[port];
    198     uint32 hw_value, remainder, base;
    199 
    200     if (NULL == value) {
    201         return SOC_E_PARAM;
    202     }
    203 
    204     BCM_IF_ERROR_RETURN(bcmi_gh2_preemption_port_check(unit, port));
    205     BCM_IF_ERROR_RETURN(
    206         soc_mem_read(unit, EGR_EDB_XMIT_CTRLm, MEM_BLOCK_ANY,
    207                      phy_port, &entry));
    208     if (IS_GE_PORT(unit, port)) {
    209         base = 16;
    210     } else if (IS_XL_PORT(unit, port)) {
    211         base = 32;
    212     } else {
    213         return BCM_E_INTERNAL; /* should not happen */
    214     }
    215 
    216     /* For GE port :
    217      *    size is the max(16N, hw_value*4),
    218      *    so need to round up as multiple of 16
    219      * For XL port :
    220      *    size is the max(32N, hw_value*4),
    221      *    so need to round up as multiple of 32
    222      */
    223     hw_value = soc_mem_field32_get(unit,
    224                                    EGR_EDB_XMIT_CTRLm,
    225                                    &entry,
    226                                    (is_final ? MIN_FINAL_FRAG_SIZEf:
    227                                                MIN_NON_FINAL_FRAG_SIZEf));
    228 
    229     remainder = (hw_value * 4) % base;
    230     if (remainder == 0) {
    231         *value = hw_value * 4;
    232     } else {
    233         *value = (hw_value * 4) + base - remainder;
    234     }
    235 
    236     return BCM_E_NONE;
    237 }
    238 #endif /* BCM_GREYHOUND2_SUPPORT */