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 (50638B)


      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 
      8 #include <soc/drv.h>
      9 #include <bcm/port.h>
     10 #include <bcm/error.h>
     11 #include <bcm/types.h>
     12 #include <bcm_int/esw_dispatch.h>
     13 #include <bcm_int/esw/port.h>
     14 #include <bcm_int/esw/preemption.h>
     15 #if defined(BCM_GREYHOUND2_SUPPORT)
     16 #include <bcm_int/esw/greyhound2.h>
     17 #endif
     18 #include <bcm_int/esw/portctrl.h>
     19 #if defined(BCM_MONTEREY_SUPPORT)
     20 #include <bcm_int/esw/monterey.h>
     21 #endif
     22 
     23 
     24 #if defined(BCM_WARM_BOOT_SUPPORT)
     25 #include <bcm/module.h>
     26 #include <bcm_int/esw/switch.h>
     27 #endif /* BCM_WARM_BOOT_SUPPORT */
     28 
     29 #if defined(BCM_PREEMPTION_SUPPORT)
     30 soc_pbmp_t pbmp_verify_enable_cache[SOC_MAX_NUM_DEVICES];
     31 sal_mutex_t verify_enable_cache_mutex[SOC_MAX_NUM_DEVICES];
     32 
     33 #define PREEMPTION_LOCK(_unit_) \
     34         sal_mutex_take(verify_enable_cache_mutex[(_unit_)], sal_mutex_FOREVER);
     35 #define PREEMPTION_UNLOCK(_unit_) \
     36         sal_mutex_give(verify_enable_cache_mutex[(_unit_)]);
     37 
     38 /*
     39  * Function:
     40  *      bcmi_esw_preemption_unimac_enable_tx_set
     41  * Purpose:
     42  *      set preemption tx enable or not on unimac
     43  * Parameters:
     44  *      unit       - (IN) unit number.
     45  *      port       - (IN) port number
     46  *      value      - (IN) value
     47  * Returns:
     48  *      BCM_E_XXX
     49  * Notes:
     50  */
     51 STATIC int
     52 bcmi_esw_preemption_unimac_enable_tx_set(int unit, bcm_port_t port,
     53                                          uint32 value)
     54 {
     55     return soc_reg_field32_modify(unit, MAC_MERGE_CONFIGr,
     56                                   port, PREEMPT_ENABLEf,
     57                                   value ? 1 : 0);
     58 }
     59 
     60 /*
     61  * Function:
     62  *      bcmi_esw_preemption_xlmac_enable_tx_set
     63  * Purpose:
     64  *      set preemption tx enable or not on xlmac
     65  * Parameters:
     66  *      unit       - (IN) unit number.
     67  *      port       - (IN) port number
     68  *      value      - (IN) value
     69  * Returns:
     70  *      BCM_E_XXX
     71  * Notes:
     72  */
     73 STATIC int
     74 bcmi_esw_preemption_xlmac_enable_tx_set(int unit, bcm_port_t port,
     75                                         uint32 value)
     76 {
     77     return soc_reg_field32_modify(unit, XLMAC_MERGE_CONFIGr,
     78                                   port, PREEMPT_ENABLEf,
     79                                   value ? 1 : 0);
     80 }
     81 
     82 /*
     83  * Function:
     84  *      bcmi_esw_preemption_unimac_enable_verify_set
     85  * Purpose:
     86  *      set preemption verify enable or not on unimac
     87  * Parameters:
     88  *      unit       - (IN) unit number.
     89  *      port       - (IN) port number
     90  *      value      - (IN) value
     91  * Returns:
     92  *      BCM_E_XXX
     93  * Notes:
     94  */
     95 STATIC int
     96 bcmi_esw_preemption_unimac_enable_verify_set(int unit, bcm_port_t port,
     97                                          uint32 value)
     98 {
     99     return soc_reg_field32_modify(unit, MAC_MERGE_CONFIGr,
    100                                   port, VERIFY_ENABLEf,
    101                                   value ? 1 : 0);
    102 }
    103 
    104 /*
    105  * Function:
    106  *      bcmi_esw_preemption_xlmac_enable_verify_set
    107  * Purpose:
    108  *      set preemption verify enable or not on xlmac
    109  * Parameters:
    110  *      unit       - (IN) unit number.
    111  *      port       - (IN) port number
    112  *      value      - (IN) value
    113  * Returns:
    114  *      BCM_E_XXX
    115  * Notes:
    116  */
    117 STATIC int
    118 bcmi_esw_preemption_xlmac_enable_verify_set(int unit, bcm_port_t port,
    119                                         uint32 value)
    120 {
    121     return soc_reg_field32_modify(unit, XLMAC_MERGE_CONFIGr,
    122                                   port, VERIFY_ENABLEf,
    123                                   value ? 1 : 0);
    124 }
    125 
    126 /*
    127  * Function:
    128  *      bcmi_esw_preemption_unimac_enable_tx_get
    129  * Purpose:
    130  *      get preemption tx enable or not on unimac
    131  * Parameters:
    132  *      unit       - (IN) unit number.
    133  *      port       - (IN) port number
    134  *      value      - (OUT) value
    135  * Returns:
    136  *      BCM_E_XXX
    137  * Notes:
    138  */
    139 STATIC int
    140 bcmi_esw_preemption_unimac_enable_tx_get(int unit, bcm_port_t port,
    141                                          uint32* value)
    142 {
    143     uint64 regval64;
    144 
    145     if (NULL == value) {
    146         return SOC_E_PARAM;
    147     }
    148     BCM_IF_ERROR_RETURN(soc_reg_get(unit, MAC_MERGE_CONFIGr, port,
    149                                     0, &regval64));
    150     *value = soc_reg64_field32_get(unit, MAC_MERGE_CONFIGr,
    151                                    regval64, PREEMPT_ENABLEf);
    152     return BCM_E_NONE;
    153 }
    154 
    155 /*
    156  * Function:
    157  *      bcmi_esw_preemption_xlmac_enable_tx_get
    158  * Purpose:
    159  *      get preemption tx enable or not on xlmac
    160  * Parameters:
    161  *      unit       - (IN) unit number.
    162  *      port       - (IN) port number
    163  *      value      - (OUT) value
    164  * Returns:
    165  *      BCM_E_XXX
    166  * Notes:
    167  */
    168 STATIC int
    169 bcmi_esw_preemption_xlmac_enable_tx_get(int unit, bcm_port_t port,
    170                                         uint32* value)
    171 {
    172     uint64 regval64;
    173 
    174     if (NULL == value) {
    175         return SOC_E_PARAM;
    176     }
    177     BCM_IF_ERROR_RETURN(soc_reg_get(unit, XLMAC_MERGE_CONFIGr, port,
    178                                     0, &regval64));
    179     *value = soc_reg64_field32_get(unit, XLMAC_MERGE_CONFIGr,
    180                                    regval64, PREEMPT_ENABLEf);
    181     return BCM_E_NONE;
    182 }
    183 
    184 /*
    185  * Function:
    186  *      bcmi_esw_preemption_unimac_mode_set
    187  * Purpose:
    188  *      set preemption mode on unimac
    189  * Parameters:
    190  *      unit       - (IN) unit number.
    191  *      port       - (IN) port number
    192  *      value      - (IN) value
    193  * Returns:
    194  *      BCM_E_XXX
    195  * Notes:
    196  */
    197 STATIC int
    198 bcmi_esw_preemption_unimac_mode_set(int unit, bcm_port_t port,
    199                                     uint32 value)
    200 {
    201     return soc_reg_field32_modify(unit, MAC_MERGE_CONFIGr,
    202                                   port, PREEMPTION_MODEf,
    203                                   value ? 1 : 0);
    204 }
    205 
    206 /*
    207  * Function:
    208  *      bcmi_esw_preemption_xlmac_mode_set
    209  * Purpose:
    210  *      set preemption mode on xlmac
    211  * Parameters:
    212  *      unit       - (IN) unit number.
    213  *      port       - (IN) port number
    214  *      value      - (IN) value
    215  * Returns:
    216  *      BCM_E_XXX
    217  * Notes:
    218  */
    219 STATIC int
    220 bcmi_esw_preemption_xlmac_mode_set(int unit, bcm_port_t port,
    221                                    uint32 value)
    222 {
    223     return soc_reg_field32_modify(unit, XLMAC_MERGE_CONFIGr,
    224                                   port, PREEMPTION_MODEf,
    225                                   value ? 1 : 0);
    226 }
    227 
    228 /*
    229  * Function:
    230  *      bcmi_esw_preemption_unimac_mode_get
    231  * Purpose:
    232  *      get preemption mode on unimac
    233  * Parameters:
    234  *      unit       - (IN) unit number.
    235  *      port       - (IN) port number
    236  *      value      - (OUT) value
    237  * Returns:
    238  *      BCM_E_XXX
    239  * Notes:
    240  */
    241 STATIC int
    242 bcmi_esw_preemption_unimac_mode_get(int unit, bcm_port_t port,
    243                                     uint32* value)
    244 {
    245     uint64 regval64;
    246 
    247     if (NULL == value) {
    248         return SOC_E_PARAM;
    249     }
    250     BCM_IF_ERROR_RETURN(soc_reg_get(unit, MAC_MERGE_CONFIGr, port,
    251                                     0, &regval64));
    252     *value = soc_reg64_field32_get(unit, MAC_MERGE_CONFIGr,
    253                                    regval64, PREEMPTION_MODEf);
    254     return BCM_E_NONE;
    255 }
    256 
    257 /*
    258  * Function:
    259  *      bcmi_esw_preemption_xlmac_mode_get
    260  * Purpose:
    261  *      get preemption mode on xlmac
    262  * Parameters:
    263  *      unit       - (IN) unit number.
    264  *      port       - (IN) port number
    265  *      value      - (OUT) value
    266  * Returns:
    267  *      BCM_E_XXX
    268  * Notes:
    269  */
    270 STATIC int
    271 bcmi_esw_preemption_xlmac_mode_get(int unit, bcm_port_t port,
    272                                    uint32* value)
    273 {
    274     uint64 regval64;
    275 
    276     if (NULL == value) {
    277         return SOC_E_PARAM;
    278     }
    279     BCM_IF_ERROR_RETURN(soc_reg_get(unit, XLMAC_MERGE_CONFIGr, port,
    280                                     0, &regval64));
    281     *value = soc_reg64_field32_get(unit, XLMAC_MERGE_CONFIGr,
    282                                    regval64, PREEMPTION_MODEf);
    283     return BCM_E_NONE;
    284 }
    285 
    286 /*
    287  * Function:
    288  *      bcmi_esw_preemption_unimac_verify_config_set
    289  * Purpose:
    290  *      set preemption verify config on unimac
    291  * Parameters:
    292  *      unit       - (IN) unit number.
    293  *      port       - (IN) port number
    294  *      type       - (IN) bcmPortPreemptControlXXXX
    295  *      value      - (OUT) value
    296  * Returns:
    297  *      BCM_E_XXX
    298  * Notes:
    299  */
    300 STATIC int
    301 bcmi_esw_preemption_unimac_verify_config_set(int unit, bcm_port_t port,
    302                                              bcm_port_preempt_control_t type,
    303                                              uint32 value)
    304 
    305 {
    306     uint32 hw_value;
    307     soc_field_t field;
    308 
    309     switch(type) {
    310         case bcmPortPreemptControlVerifyTime:
    311             field = VERIFY_TIMEf;
    312             break;
    313         case bcmPortPreemptControlVerifyAttempts:
    314             field = VERIFY_ATTEMPT_LIMITf;
    315             break;
    316         default:
    317             return BCM_E_PARAM;
    318     }
    319 
    320     if (value < 1) {
    321         return BCM_E_PARAM;
    322     }
    323     if (value > (1 << soc_reg_field_length(unit, MAC_MERGE_CONFIGr,
    324                                           field))) {
    325         return BCM_E_PARAM;
    326     }
    327     hw_value = value - 1;
    328     return soc_reg_field32_modify(unit, MAC_MERGE_CONFIGr, port,
    329                                   field, hw_value);
    330 }
    331 
    332 /*
    333  * Function:
    334  *      bcmi_esw_preemption_xlmac_verify_config_set
    335  * Purpose:
    336  *      set preemption verify config on xlmac
    337  * Parameters:
    338  *      unit       - (IN) unit number.
    339  *      port       - (IN) port number
    340  *      type       - (IN) bcmPortPreemptControlXXXX
    341  *      value      - (IN) value
    342  * Returns:
    343  *      BCM_E_XXX
    344  * Notes:
    345  */
    346 STATIC int
    347 bcmi_esw_preemption_xlmac_verify_config_set(int unit, bcm_port_t port,
    348                                             bcm_port_preempt_control_t type,
    349                                             uint32 value)
    350 
    351 {
    352     uint32 hw_value;
    353     soc_field_t field;
    354 
    355     switch(type) {
    356         case bcmPortPreemptControlVerifyTime:
    357             field = VERIFY_TIMEf;
    358             break;
    359         case bcmPortPreemptControlVerifyAttempts:
    360             field = VERIFY_ATTEMPT_LIMITf;
    361             break;
    362         default:
    363             return BCM_E_PARAM;
    364     }
    365 
    366     if (value < 1) {
    367         return BCM_E_PARAM;
    368     }
    369     if (value > (1 << soc_reg_field_length(unit, XLMAC_MERGE_CONFIGr,
    370                                           field))) {
    371         return BCM_E_PARAM;
    372     }
    373     hw_value = value - 1;
    374     return soc_reg_field32_modify(unit, XLMAC_MERGE_CONFIGr, port,
    375                                   field, hw_value);
    376 }
    377 
    378 
    379 /*
    380  * Function:
    381  *      bcmi_esw_preemption_unimac_verify_config_get
    382  * Purpose:
    383  *      get preemption verify config on unimac
    384  * Parameters:
    385  *      unit       - (IN) unit number.
    386  *      port       - (IN) port number
    387  *      type       - (IN) bcmPortPreemptControlXXXX
    388  *      value      - (OUT) value
    389  * Returns:
    390  *      BCM_E_XXX
    391  * Notes:
    392  */
    393 STATIC int
    394 bcmi_esw_preemption_unimac_verify_config_get(int unit, bcm_port_t port,
    395                                              bcm_port_preempt_control_t type,
    396                                              uint32* value)
    397 
    398 {
    399     uint64 regval64;
    400     soc_field_t field;
    401 
    402     if (NULL == value) {
    403         return SOC_E_PARAM;
    404     }
    405     switch(type) {
    406         case bcmPortPreemptControlVerifyTime:
    407             field = VERIFY_TIMEf;
    408             break;
    409         case bcmPortPreemptControlVerifyAttempts:
    410             field = VERIFY_ATTEMPT_LIMITf;
    411             break;
    412         default:
    413             return BCM_E_PARAM;
    414     }
    415     BCM_IF_ERROR_RETURN(soc_reg_get(unit, MAC_MERGE_CONFIGr, port,
    416                                     0, &regval64));
    417     *value = soc_reg64_field32_get(unit, MAC_MERGE_CONFIGr,
    418                                    regval64, field) + 1;
    419     return BCM_E_NONE;
    420 }
    421 
    422 /*
    423  * Function:
    424  *      bcmi_esw_preemption_xlmac_verify_config_get
    425  * Purpose:
    426  *      get preemption verify config on xlmac
    427  * Parameters:
    428  *      unit       - (IN) unit number.
    429  *      port       - (IN) port number
    430  *      type       - (IN) bcmPortPreemptControlXXXX
    431  *      value      - (OUT) value
    432  * Returns:
    433  *      BCM_E_XXX
    434  * Notes:
    435  */
    436 STATIC int
    437 bcmi_esw_preemption_xlmac_verify_config_get(int unit, bcm_port_t port,
    438                                             bcm_port_preempt_control_t type,
    439                                             uint32* value)
    440 
    441 {
    442     uint64 regval64;
    443     soc_field_t field;
    444 
    445     if (NULL == value) {
    446         return SOC_E_PARAM;
    447     }
    448     switch(type) {
    449         case bcmPortPreemptControlVerifyTime:
    450             field = VERIFY_TIMEf;
    451             break;
    452         case bcmPortPreemptControlVerifyAttempts:
    453             field = VERIFY_ATTEMPT_LIMITf;
    454             break;
    455         default:
    456             return BCM_E_PARAM;
    457     }
    458     BCM_IF_ERROR_RETURN(soc_reg_get(unit, XLMAC_MERGE_CONFIGr, port,
    459                                     0, &regval64));
    460     *value = soc_reg64_field32_get(unit, XLMAC_MERGE_CONFIGr,
    461                                    regval64, field) + 1;
    462     return BCM_E_NONE;
    463 }
    464 
    465 /*
    466  * Function:
    467  *      bcmi_esw_preemption_unimac_frag_config_rx_set
    468  * Purpose:
    469  *      set preemption fragment config on unimac
    470  * Parameters:
    471  *      unit       - (IN) unit number.
    472  *      port       - (IN) port number
    473  *      type       - (IN) bcmPortPreemptControlXXXX
    474  *      value      - (IN) value
    475  * Returns:
    476  *      BCM_E_XXX
    477  * Notes:
    478  */
    479 STATIC int
    480 bcmi_esw_preemption_unimac_frag_config_rx_set(int unit, bcm_port_t port,
    481                                               bcm_port_preempt_control_t type,
    482                                               uint32 value)
    483 {
    484     uint32 hw_value;
    485     bcm_port_t phy_port = port;
    486     int i,pindex = -1;
    487     int found = 0;
    488     int is_final = 1;
    489     soc_reg_t reg[8]={GE0_MIN_FRAG_SIZEr,
    490                       GE1_MIN_FRAG_SIZEr,
    491                       GE2_MIN_FRAG_SIZEr,
    492                       GE3_MIN_FRAG_SIZEr,
    493                       GE4_MIN_FRAG_SIZEr,
    494                       GE5_MIN_FRAG_SIZEr,
    495                       GE6_MIN_FRAG_SIZEr,
    496                       GE7_MIN_FRAG_SIZEr};
    497 
    498     switch (type) {
    499         case bcmPortPreemptControlNonFinalFragSizeRx:
    500             is_final = 0;
    501             /* coverity[fallthrough:FALSE] */
    502         case bcmPortPreemptControlFinalFragSizeRx:
    503             if (value > 512 || value < 64 || value % 8) {
    504                 return BCM_E_PARAM;
    505             }
    506             hw_value = value / 8;
    507             if (soc_feature(unit, soc_feature_logical_port_num)) {
    508                 phy_port = SOC_INFO(unit).port_l2p_mapping[port];
    509             }
    510             for (i = 0; i < SOC_DRIVER(unit)->port_num_blktype; i++) {
    511                 int block = SOC_PORT_IDX_BLOCK(unit, phy_port, i);
    512                 if (SOC_BLK_GPORT == SOC_BLOCK_TYPE(unit, block)) {
    513                     pindex = SOC_PORT_IDX_BINDEX(unit, phy_port, i);
    514                     found = 1;
    515                     break;
    516                 }
    517             }
    518             if (0 == found || pindex < 0 || pindex > 7) {
    519                 return BCM_E_INTERNAL;
    520             }
    521             return soc_reg_field32_modify(unit, reg[pindex], port,
    522                                           (is_final ? FINAL_FRAGf:
    523                                                       NON_FINAL_FRAGf),
    524                                            hw_value);
    525         default:
    526             return BCM_E_PARAM;
    527     }
    528 }
    529 
    530 /*
    531  * Function:
    532  *      bcmi_esw_preemption_xlmac_frag_config_rx_set
    533  * Purpose:
    534  *      set preemption fragment config on xlmac
    535  * Parameters:
    536  *      unit       - (IN) unit number.
    537  *      port       - (IN) port number
    538  *      type       - (IN) bcmPortPreemptControlXXXX
    539  *      value      - (IN) value
    540  * Returns:
    541  *      BCM_E_XXX
    542  * Notes:
    543  */
    544 STATIC int
    545 bcmi_esw_preemption_xlmac_frag_config_rx_set(int unit, bcm_port_t port,
    546                                              bcm_port_preempt_control_t type,
    547                                              uint32 value)
    548 {
    549     uint32 hw_value;
    550     int is_final = 1;
    551 
    552     switch (type) {
    553         case bcmPortPreemptControlNonFinalFragSizeRx:
    554             is_final = 0;
    555             /* coverity[fallthrough:FALSE] */
    556         case bcmPortPreemptControlFinalFragSizeRx:
    557             if (value > 512 || value < 64 || value % 8) {
    558                 return BCM_E_PARAM;
    559             }
    560             hw_value = value / 8;
    561             return soc_reg_field32_modify(unit, XLPORT_MIB_MIN_FRAG_SIZEr, port,
    562                                           (is_final ? MIN_FINAL_FRAG_SIZEf:
    563                                                       MIN_NON_FINAL_FRAG_SIZEf),
    564                                           hw_value);
    565         default:
    566             return BCM_E_PARAM;
    567     }
    568 }
    569 
    570 /*
    571  * Function:
    572  *      bcmi_esw_preemption_unimac_frag_config_rx_get
    573  * Purpose:
    574  *      get preemption fragment config on unimac
    575  * Parameters:
    576  *      unit       - (IN) unit number.
    577  *      port       - (IN) port number
    578  *      type       - (IN) bcmPortPreemptControlXXXX
    579  *      value      - (OUT) value
    580  * Returns:
    581  *      BCM_E_XXX
    582  * Notes:
    583  */
    584 STATIC int
    585 bcmi_esw_preemption_unimac_frag_config_rx_get(int unit, bcm_port_t port,
    586                                               bcm_port_preempt_control_t type,
    587                                               uint32* value)
    588 {
    589     bcm_port_t phy_port = port;
    590     int i,pindex = -1;
    591     int found = 0;
    592     uint64 regval64;
    593     soc_reg_t reg[8]={GE0_MIN_FRAG_SIZEr,
    594                       GE1_MIN_FRAG_SIZEr,
    595                       GE2_MIN_FRAG_SIZEr,
    596                       GE3_MIN_FRAG_SIZEr,
    597                       GE4_MIN_FRAG_SIZEr,
    598                       GE5_MIN_FRAG_SIZEr,
    599                       GE6_MIN_FRAG_SIZEr,
    600                       GE7_MIN_FRAG_SIZEr};
    601     int is_final = 1;
    602 
    603     if (NULL == value) {
    604         return SOC_E_PARAM;
    605     }
    606     switch (type) {
    607         case bcmPortPreemptControlNonFinalFragSizeRx:
    608             is_final = 0;
    609             /* coverity[fallthrough:FALSE] */
    610         case bcmPortPreemptControlFinalFragSizeRx:
    611             if (soc_feature(unit, soc_feature_logical_port_num)) {
    612                 phy_port = SOC_INFO(unit).port_l2p_mapping[port];
    613             }
    614             for (i = 0; i < SOC_DRIVER(unit)->port_num_blktype; i++) {
    615                 int block = SOC_PORT_IDX_BLOCK(unit, phy_port, i);
    616                 if (SOC_BLK_GPORT == SOC_BLOCK_TYPE(unit, block)) {
    617                     pindex = SOC_PORT_IDX_BINDEX(unit, phy_port, i);
    618                     found = 1;
    619                     break;
    620                 }
    621             }
    622             if (0 == found || pindex < 0 || pindex > 7) {
    623                 return BCM_E_INTERNAL;
    624             }
    625             BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg[pindex],
    626                                             port, 0, &regval64));
    627             *value = soc_reg64_field32_get(unit, reg[pindex], regval64,
    628                                            (is_final ? FINAL_FRAGf:
    629                                                        NON_FINAL_FRAGf)) * 8;
    630             break;
    631         default:
    632             return BCM_E_PARAM;
    633     }
    634     return BCM_E_NONE;
    635 }
    636 
    637 /*
    638  * Function:
    639  *      bcmi_esw_preemption_xlmac_frag_config_rx_get
    640  * Purpose:
    641  *      get preemption fragment config on xlmac
    642  * Parameters:
    643  *      unit       - (IN) unit number.
    644  *      port       - (IN) port number
    645  *      type       - (IN) bcmPortPreemptControlXXXX
    646  *      value      - (OUT) value
    647  * Returns:
    648  *      BCM_E_XXX
    649  * Notes:
    650  */
    651 STATIC int
    652 bcmi_esw_preemption_xlmac_frag_config_rx_get(int unit, bcm_port_t port,
    653                                              bcm_port_preempt_control_t type,
    654                                              uint32* value)
    655 {
    656     int is_final = 1;
    657     uint64 regval64;
    658 
    659     if (NULL == value) {
    660         return SOC_E_PARAM;
    661     }
    662     switch (type) {
    663         case bcmPortPreemptControlNonFinalFragSizeRx:
    664             is_final = 0;
    665             /* coverity[fallthrough:FALSE] */
    666         case bcmPortPreemptControlFinalFragSizeRx:
    667             BCM_IF_ERROR_RETURN(soc_reg_get(unit, XLPORT_MIB_MIN_FRAG_SIZEr,
    668                                             port, 0, &regval64));
    669             *value = soc_reg64_field32_get(unit,
    670                                            XLPORT_MIB_MIN_FRAG_SIZEr,
    671                                            regval64,
    672                                            (is_final ? MIN_FINAL_FRAG_SIZEf:
    673                                                        MIN_NON_FINAL_FRAG_SIZEf)) * 8;
    674              break;
    675         default:
    676             return BCM_E_UNAVAIL;
    677     }
    678     return BCM_E_NONE;
    679 }
    680 
    681 /*
    682  * Function:
    683  *      bcmi_esw_preemption_unimac_status_tx_get
    684  * Purpose:
    685  *      get preemption tx status on unimac
    686  * Parameters:
    687  *      unit       - (IN) unit number.
    688  *      port       - (IN) port number
    689  *      type       - (IN) bcmPortPreemptControlXXXX
    690  *      value      - (OUT) value
    691  * Returns:
    692  *      BCM_E_XXX
    693  * Notes:
    694  */
    695 STATIC int
    696 bcmi_esw_preemption_unimac_status_tx_get(int unit, bcm_port_t port,
    697                                          uint32* value)
    698 {
    699     uint64 regval64;
    700 
    701     if (NULL == value) {
    702         return SOC_E_PARAM;
    703     }
    704     BCM_IF_ERROR_RETURN(soc_reg_get(unit, MAC_MERGE_VERIFY_STATEr, port,
    705                                     0, &regval64));
    706     *value = soc_reg64_field32_get(unit, MAC_MERGE_VERIFY_STATEr,
    707                                    regval64, PREEMPTION_TX_STATUSf);
    708     if (*value > bcmPortPreemptStatusTxActive) {
    709         return BCM_E_INTERNAL;
    710     } else {
    711         return BCM_E_NONE;
    712     }
    713 }
    714 
    715 /*
    716  * Function:
    717  *      bcmi_esw_preemption_xlmac_status_tx_get
    718  * Purpose:
    719  *      get preemption tx status on xlmac
    720  * Parameters:
    721  *      unit       - (IN) unit number.
    722  *      port       - (IN) port number
    723  *      type       - (IN) bcmPortPreemptControlXXXX
    724  *      value      - (OUT) value
    725  * Returns:
    726  *      BCM_E_XXX
    727  * Notes:
    728  */
    729 STATIC int
    730 bcmi_esw_preemption_xlmac_status_tx_get(int unit, bcm_port_t port,
    731                                         uint32* value)
    732 {
    733     uint64 regval64;
    734 
    735     if (NULL == value) {
    736         return SOC_E_PARAM;
    737     }
    738     BCM_IF_ERROR_RETURN(soc_reg_get(unit, XLMAC_MERGE_VERIFY_STATEr, port,
    739                                     0, &regval64));
    740     *value = soc_reg64_field32_get(unit, XLMAC_MERGE_VERIFY_STATEr,
    741                                    regval64, PREEMPTION_TX_STATUSf);
    742     if (*value > bcmPortPreemptStatusTxActive) {
    743         return BCM_E_INTERNAL;
    744     } else {
    745         return BCM_E_NONE;
    746     }
    747 }
    748 
    749 /*
    750  * Function:
    751  *      bcmi_esw_preemption_unimac_status_verify_get
    752  * Purpose:
    753  *      get preemption verify status on unimac
    754  * Parameters:
    755  *      unit       - (IN) unit number.
    756  *      port       - (IN) port number
    757  *      type       - (IN) bcmPortPreemptControlXXXX
    758  *      value      - (OUT) value
    759  * Returns:
    760  *      BCM_E_XXX
    761  * Notes:
    762  */
    763 STATIC int
    764 bcmi_esw_preemption_unimac_status_verify_get(int unit, bcm_port_t port,
    765                                              uint32* value)
    766 {
    767     uint64 regval64;
    768 
    769     if (NULL == value) {
    770         return SOC_E_PARAM;
    771     }
    772     BCM_IF_ERROR_RETURN(soc_reg_get(unit, MAC_MERGE_VERIFY_STATEr, port,
    773                                     0, &regval64));
    774     *value = soc_reg64_field32_get(unit, MAC_MERGE_VERIFY_STATEr,
    775                                    regval64, PREEMPTION_VERIFY_STATUSf);
    776     if (*value > bcmPortPreemptStatusVerifyFailed) {
    777         return BCM_E_INTERNAL;
    778     } else {
    779         return BCM_E_NONE;
    780     }
    781 }
    782 
    783 /*
    784  * Function:
    785  *      bcmi_esw_preemption_xlmac_status_verify_get
    786  * Purpose:
    787  *      get preemption verify status on xlmac
    788  * Parameters:
    789  *      unit       - (IN) unit number.
    790  *      port       - (IN) port number
    791  *      type       - (IN) bcmPortPreemptControlXXXX
    792  *      value      - (OUT) value
    793  * Returns:
    794  *      BCM_E_XXX
    795  * Notes:
    796  */
    797 STATIC int
    798 bcmi_esw_preemption_xlmac_status_verify_get(int unit, bcm_port_t port,
    799                                              uint32* value)
    800 {
    801     uint64 regval64;
    802 
    803     if (NULL == value) {
    804         return SOC_E_PARAM;
    805     }
    806     BCM_IF_ERROR_RETURN(soc_reg_get(unit, XLMAC_MERGE_VERIFY_STATEr, port,
    807                                     0, &regval64));
    808     *value = soc_reg64_field32_get(unit, XLMAC_MERGE_VERIFY_STATEr,
    809                                    regval64, PREEMPTION_VERIFY_STATUSf);
    810     if (*value > bcmPortPreemptStatusVerifyFailed) {
    811         return BCM_E_INTERNAL;
    812     } else {
    813         return BCM_E_NONE;
    814     }
    815 }
    816 
    817 /*
    818  * Function:
    819  *      bcmi_esw_preemption_enable_tx_set
    820  * Purpose:
    821  *      set preemption tx enable or not
    822  * Parameters:
    823  *      unit       - (IN) unit number.
    824  *      port       - (IN) port number
    825  *      value      - (IN) value
    826  * Returns:
    827  *      BCM_E_XXX
    828  * Notes:
    829  */
    830 STATIC int
    831 bcmi_esw_preemption_enable_tx_set(int unit, bcm_port_t port, uint32 value)
    832 {
    833     bcmi_port_mac_type_t mac_type;
    834     
    835     BCM_IF_ERROR_RETURN(bcmi_esw_port_mac_type_get(unit, port,
    836                                                    &mac_type));
    837 
    838     if (bcmiPortMacTypeXLmac == mac_type) {
    839         return bcmi_esw_preemption_xlmac_enable_tx_set(unit, port, value);
    840     } else if (bcmiPortMacTypeUnimac == mac_type) {
    841        return  bcmi_esw_preemption_unimac_enable_tx_set(unit, port, value);
    842     } else {
    843         return BCM_E_UNAVAIL;
    844     }
    845 }
    846 
    847 /*
    848  * Function:
    849  *      _bcmi_esw_preemption_enable_verify_set
    850  * Purpose:
    851  *      helper function to set preemption verify enable or not in hw
    852  * Parameters:
    853  *      unit       - (IN) unit number.
    854  *      port       - (IN) port number
    855  *      value      - (IN) value
    856  * Returns:
    857  *      BCM_E_XXX
    858  * Notes:
    859  */
    860 STATIC int
    861 _bcmi_esw_preemption_enable_verify_set(int unit, bcm_port_t port, uint32 value)
    862 {
    863     bcmi_port_mac_type_t mac_type;
    864 
    865     BCM_IF_ERROR_RETURN(bcmi_esw_port_mac_type_get(unit, port,
    866                                                    &mac_type));
    867     if (bcmiPortMacTypeXLmac == mac_type) {
    868         return bcmi_esw_preemption_xlmac_enable_verify_set(unit, port, value);
    869     } else if (bcmiPortMacTypeUnimac == mac_type) {
    870        return  bcmi_esw_preemption_unimac_enable_verify_set(unit, port, value);
    871     } else {
    872         return BCM_E_UNAVAIL;
    873     }
    874 }
    875 
    876 /*
    877  * Function:
    878  *      bcmi_esw_preemption_enable_verify_set
    879  * Purpose:
    880  *      set preemption verify enable or not
    881  *      write sw cache first, then write hw only when port link up
    882  * Parameters:
    883  *      unit       - (IN) unit number.
    884  *      port       - (IN) port number
    885  *      value      - (IN) value
    886  * Returns:
    887  *      BCM_E_XXX
    888  * Notes:
    889  */
    890 STATIC int
    891 bcmi_esw_preemption_enable_verify_set(int unit, bcm_port_t port, uint32 value)
    892 {
    893     bcmi_port_mac_type_t mac_type;
    894 
    895     BCM_IF_ERROR_RETURN(
    896         bcmi_esw_port_mac_type_get(unit, port, &mac_type));
    897 
    898     if (bcmiPortMacTypeXLmac == mac_type || bcmiPortMacTypeUnimac == mac_type) {
    899         int link_up;
    900 
    901         BCM_IF_ERROR_RETURN(
    902             bcm_esw_port_link_status_get(unit, port, &link_up));
    903 
    904         if (link_up) {
    905             /* write it into hw only when port is link up */
    906             BCM_IF_ERROR_RETURN(
    907                 _bcmi_esw_preemption_enable_verify_set(unit, port, value));
    908         }
    909 
    910         PREEMPTION_LOCK(unit);
    911         if (value) {
    912             SOC_PBMP_PORT_ADD(pbmp_verify_enable_cache[unit], port);
    913         } else {
    914             SOC_PBMP_PORT_REMOVE(pbmp_verify_enable_cache[unit], port);
    915         }
    916         PREEMPTION_UNLOCK(unit);
    917     } else {
    918        return BCM_E_UNAVAIL;
    919     }
    920 
    921     return BCM_E_NONE;
    922 }
    923 
    924 /*
    925  * Function:
    926  *      bcmi_esw_preemption_mode_set
    927  * Purpose:
    928  *      set preemption mode
    929  * Parameters:
    930  *      unit       - (IN) unit number.
    931  *      port       - (IN) port number
    932  *      value      - (IN) value
    933  * Returns:
    934  *      BCM_E_XXX
    935  * Notes:
    936  */
    937 STATIC int
    938 bcmi_esw_preemption_mode_set(int unit, bcm_port_t port, uint32 value)
    939 {
    940     bcmi_port_mac_type_t mac_type;
    941 
    942     BCM_IF_ERROR_RETURN(bcmi_esw_port_mac_type_get(unit, port,
    943                                                    &mac_type));
    944     if (bcmiPortMacTypeXLmac == mac_type) {
    945         return bcmi_esw_preemption_xlmac_mode_set(unit, port, value);
    946     } else if (bcmiPortMacTypeUnimac == mac_type) {
    947         return bcmi_esw_preemption_unimac_mode_set(unit, port, value);
    948     } else {
    949         return BCM_E_UNAVAIL;
    950     }
    951 }
    952 
    953 /*
    954  * Function:
    955  *      bcmi_esw_preemption_verify_config_set
    956  * Purpose:
    957  *      set preemption verify config
    958  * Parameters:
    959  *      unit       - (IN) unit number.
    960  *      port       - (IN) port number
    961  *      value      - (IN) value
    962  * Returns:
    963  *      BCM_E_XXX
    964  * Notes:
    965  */
    966 STATIC int
    967 bcmi_esw_preemption_verify_config_set(int unit, bcm_port_t port,
    968                                       bcm_port_preempt_control_t type,
    969                                       uint32 value)
    970 {
    971     bcmi_port_mac_type_t mac_type;
    972 
    973     BCM_IF_ERROR_RETURN(bcmi_esw_port_mac_type_get(unit, port,
    974                                                    &mac_type));
    975     if (bcmiPortMacTypeXLmac == mac_type) {
    976         return bcmi_esw_preemption_xlmac_verify_config_set(unit, port, type, value);
    977     } else if (bcmiPortMacTypeUnimac == mac_type) {
    978         return bcmi_esw_preemption_unimac_verify_config_set(unit, port, type, value);
    979     } else {
    980         return BCM_E_UNAVAIL;
    981     }
    982 }
    983 
    984 /*
    985  * Function:
    986  *      bcmi_esw_preemption_frag_config_rx_set
    987  * Purpose:
    988  *      set preemption fragment config
    989  * Parameters:
    990  *      unit       - (IN) unit number.
    991  *      port       - (IN) port number
    992  *      value      - (IN) value
    993  * Returns:
    994  *      BCM_E_XXX
    995  * Notes:
    996  */
    997 STATIC int
    998 bcmi_esw_preemption_frag_config_rx_set(int unit, bcm_port_t port,
    999                                        bcm_port_preempt_control_t type,
   1000                                        uint32 value)
   1001 {
   1002     bcmi_port_mac_type_t mac_type;
   1003 
   1004     BCM_IF_ERROR_RETURN(bcmi_esw_port_mac_type_get(unit, port,
   1005                                                    &mac_type));
   1006     if (bcmiPortMacTypeXLmac == mac_type) {
   1007         return bcmi_esw_preemption_xlmac_frag_config_rx_set(unit, port, type, value);
   1008     } else if (bcmiPortMacTypeUnimac == mac_type) {
   1009         return bcmi_esw_preemption_unimac_frag_config_rx_set(unit, port, type, value);
   1010     } else {
   1011         return BCM_E_UNAVAIL;
   1012     }
   1013 }
   1014 
   1015 /*
   1016  * Function:
   1017  *      bcmi_esw_preemption_enable_tx_get
   1018  * Purpose:
   1019  *      get preemption tx enable or not
   1020  * Parameters:
   1021  *      unit       - (IN) unit number.
   1022  *      port       - (IN) port number
   1023  *      value      - (OUT) value
   1024  * Returns:
   1025  *      BCM_E_XXX
   1026  * Notes:
   1027  */
   1028 STATIC int
   1029 bcmi_esw_preemption_enable_tx_get(int unit, bcm_port_t port, uint32* value)
   1030 {
   1031     bcmi_port_mac_type_t mac_type;
   1032 
   1033     BCM_IF_ERROR_RETURN(bcmi_esw_port_mac_type_get(unit, port,
   1034                                                    &mac_type));
   1035     if (bcmiPortMacTypeXLmac == mac_type) {
   1036         return bcmi_esw_preemption_xlmac_enable_tx_get(unit, port, value);
   1037     } else if (bcmiPortMacTypeUnimac == mac_type) {
   1038         return bcmi_esw_preemption_unimac_enable_tx_get(unit, port, value);
   1039     } else {
   1040         return BCM_E_UNAVAIL;
   1041     }
   1042 }
   1043 
   1044 /*
   1045  * Function:
   1046  *      bcmi_esw_preemption_enable_verify_get
   1047  * Purpose:
   1048  *      get preemption verify enable or not
   1049  * Parameters:
   1050  *      unit       - (IN) unit number.
   1051  *      port       - (IN) port number
   1052  *      value      - (OUT) value
   1053  * Returns:
   1054  *      BCM_E_XXX
   1055  * Notes:
   1056  */
   1057 STATIC int
   1058 bcmi_esw_preemption_enable_verify_get(int unit, bcm_port_t port, uint32* value)
   1059 {
   1060     bcmi_port_mac_type_t mac_type;
   1061 
   1062     if (NULL == value) {
   1063         return BCM_E_PARAM;
   1064     }
   1065     BCM_IF_ERROR_RETURN(bcmi_esw_port_mac_type_get(unit, port,
   1066                                                    &mac_type));
   1067 
   1068     if (bcmiPortMacTypeXLmac == mac_type || bcmiPortMacTypeUnimac == mac_type) {
   1069         PREEMPTION_LOCK(unit);
   1070         if (SOC_PBMP_MEMBER(pbmp_verify_enable_cache[unit], port)) {
   1071             *value = 1;
   1072         } else {
   1073             *value = 0;
   1074         }
   1075         PREEMPTION_UNLOCK(unit);
   1076     } else {
   1077         return BCM_E_UNAVAIL;
   1078     }
   1079 
   1080     return BCM_E_NONE;
   1081 }
   1082 
   1083 /*
   1084  * Function:
   1085  *      bcmi_esw_preemption_mode_get
   1086  * Purpose:
   1087  *      get preemption mode
   1088  * Parameters:
   1089  *      unit       - (IN) unit number.
   1090  *      port       - (IN) port number
   1091  *      value      - (OUT) value
   1092  * Returns:
   1093  *      BCM_E_XXX
   1094  * Notes:
   1095  */
   1096 STATIC int
   1097 bcmi_esw_preemption_mode_get(int unit, bcm_port_t port, uint32* value)
   1098 {
   1099     bcmi_port_mac_type_t mac_type;
   1100 
   1101     BCM_IF_ERROR_RETURN(bcmi_esw_port_mac_type_get(unit, port,
   1102                                                    &mac_type));
   1103     if (bcmiPortMacTypeXLmac == mac_type) {
   1104         return bcmi_esw_preemption_xlmac_mode_get(unit, port, value);
   1105     } else if (bcmiPortMacTypeUnimac == mac_type) {
   1106         return bcmi_esw_preemption_unimac_mode_get(unit, port, value);
   1107     } else {
   1108         return BCM_E_UNAVAIL;
   1109     }
   1110 }
   1111 
   1112 /*
   1113  * Function:
   1114  *      bcmi_esw_preemption_verify_config_get
   1115  * Purpose:
   1116  *      get preemption verify config
   1117  * Parameters:
   1118  *      unit       - (IN) unit number.
   1119  *      port       - (IN) port number
   1120  *      type       - (IN) Preemption control type
   1121  *      value      - (OUT) value
   1122  * Returns:
   1123  *      BCM_E_XXX
   1124  * Notes:
   1125  */
   1126 STATIC int
   1127 bcmi_esw_preemption_verify_config_get(int unit, bcm_port_t port,
   1128                                       bcm_port_preempt_control_t type,
   1129                                       uint32* value)
   1130 {
   1131     bcmi_port_mac_type_t mac_type;
   1132 
   1133     BCM_IF_ERROR_RETURN(bcmi_esw_port_mac_type_get(unit, port,
   1134                                                    &mac_type));
   1135     if (bcmiPortMacTypeXLmac == mac_type) {
   1136         return bcmi_esw_preemption_xlmac_verify_config_get(unit, port, type, value);
   1137     } else if (bcmiPortMacTypeUnimac == mac_type) {
   1138         return bcmi_esw_preemption_unimac_verify_config_get(unit, port, type, value);
   1139     } else {
   1140         return BCM_E_UNAVAIL;
   1141     }
   1142 }
   1143 
   1144 /*
   1145  * Function:
   1146  *      bcmi_esw_preemption_frag_config_rx_get
   1147  * Purpose:
   1148  *      get preemption fragment config
   1149  * Parameters:
   1150  *      unit       - (IN) unit number.
   1151  *      port       - (IN) port number
   1152  *      type       - (IN) Preemption control type
   1153  *      value      - (OUT) value
   1154  * Returns:
   1155  *      BCM_E_XXX
   1156  * Notes:
   1157  */
   1158 STATIC int
   1159 bcmi_esw_preemption_frag_config_rx_get(int unit, bcm_port_t port,
   1160                                        bcm_port_preempt_control_t type,
   1161                                        uint32* value)
   1162 {
   1163     bcmi_port_mac_type_t mac_type;
   1164 
   1165     BCM_IF_ERROR_RETURN(bcmi_esw_port_mac_type_get(unit, port,
   1166                                                    &mac_type));
   1167     if (bcmiPortMacTypeXLmac == mac_type) {
   1168         return bcmi_esw_preemption_xlmac_frag_config_rx_get(unit, port, type, value);
   1169     } else if (bcmiPortMacTypeUnimac == mac_type) {
   1170         return bcmi_esw_preemption_unimac_frag_config_rx_get(unit, port, type, value);
   1171     } else {
   1172         return BCM_E_UNAVAIL;
   1173     }
   1174 }
   1175 
   1176 /*
   1177  * Function:
   1178  *      bcmi_esw_preemption_status_tx_get
   1179  * Purpose:
   1180  *      get preemption tx status
   1181  * Parameters:
   1182  *      unit       - (IN) unit number.
   1183  *      port       - (IN) port number
   1184  *      value      - (OUT) value
   1185  * Returns:
   1186  *      BCM_E_XXX
   1187  * Notes:
   1188  */
   1189 int
   1190 bcmi_esw_preemption_status_tx_get(int unit, bcm_port_t port,
   1191                                   uint32* value)
   1192 {
   1193     bcmi_port_mac_type_t mac_type;
   1194 
   1195     if (SOC_USE_PORTCTRL(unit)) {
   1196         BCM_IF_ERROR_RETURN(bcmi_esw_portctrl_preemption_status_tx_get
   1197                             (unit, port, value)); 
   1198         return BCM_E_NONE; 
   1199     }
   1200     BCM_IF_ERROR_RETURN(bcmi_esw_port_mac_type_get(unit, port,
   1201                                                    &mac_type));
   1202     if (bcmiPortMacTypeXLmac == mac_type) {
   1203         return bcmi_esw_preemption_xlmac_status_tx_get(unit, port, value);
   1204     } else if (bcmiPortMacTypeUnimac == mac_type) {
   1205         return bcmi_esw_preemption_unimac_status_tx_get(unit, port, value);
   1206     } else {
   1207         return BCM_E_UNAVAIL;
   1208     }
   1209 }
   1210 
   1211 /*
   1212  * Function:
   1213  *      bcmi_esw_preemption_status_verify_get
   1214  * Purpose:
   1215  *      get preemption verify status
   1216  * Parameters:
   1217  *      unit       - (IN) unit number.
   1218  *      port       - (IN) port number
   1219  *      value      - (OUT) value
   1220  * Returns:
   1221  *      BCM_E_XXX
   1222  * Notes:
   1223  */
   1224 int
   1225 bcmi_esw_preemption_status_verify_get(int unit, bcm_port_t port,
   1226                                       uint32* value)
   1227 {
   1228     bcmi_port_mac_type_t mac_type;
   1229     if (SOC_USE_PORTCTRL(unit)) {
   1230         BCM_IF_ERROR_RETURN(bcmi_esw_portctrl_preemption_status_verify_get
   1231                             (unit, port, value)); 
   1232         return BCM_E_NONE; 
   1233     }
   1234 
   1235     BCM_IF_ERROR_RETURN(bcmi_esw_port_mac_type_get(unit, port,
   1236                                                    &mac_type));
   1237     if (bcmiPortMacTypeXLmac == mac_type) {
   1238         return bcmi_esw_preemption_xlmac_status_verify_get(unit, port, value);
   1239     } else if (bcmiPortMacTypeUnimac == mac_type) {
   1240         return bcmi_esw_preemption_unimac_status_verify_get(unit, port, value);
   1241     } else {
   1242         return BCM_E_UNAVAIL;
   1243     }
   1244 }
   1245 
   1246 /*
   1247  * Function:
   1248  *      bcmi_esw_preemption_mac_config_set
   1249  * Purpose:
   1250  *      set preemption mac config
   1251  * Parameters:
   1252  *      unit       - (IN) unit number.
   1253  *      port       - (IN) port number
   1254  *      type       - (IN) Preemption control type
   1255 *      arg        - (IN) value
   1256  * Returns:
   1257  *      BCM_E_XXX
   1258  * Notes:
   1259  */
   1260 int
   1261 bcmi_esw_preemption_mac_config_set(int unit, bcm_port_t port,
   1262                                    bcm_port_preempt_control_t type,
   1263                                    uint32 arg)
   1264 {
   1265 
   1266     if (SOC_USE_PORTCTRL(unit)) {
   1267 #if defined(BCM_MONTEREY_SUPPORT)
   1268            if (SOC_IS_MONTEREY(unit) &&
   1269            ((type == bcmPortPreemptControlFinalFragSizeRx) ||
   1270            (type == bcmPortPreemptControlNonFinalFragSizeRx))) {
   1271             if ((arg < 64) || (arg > 512)) {
   1272                 return BCM_E_PARAM;
   1273             }
   1274             arg = (arg + 7) / 8;
   1275         }
   1276 #endif
   1277         BCM_IF_ERROR_RETURN(bcmi_esw_portctrl_preemption_mac_config_set
   1278                             (unit, port ,type, arg));
   1279         return BCM_E_NONE;  
   1280     }
   1281     switch (type) {
   1282         case bcmPortPreemptControlPreemptionSupport:
   1283             return bcmi_esw_preemption_mode_set(unit, port, arg);
   1284 
   1285         case bcmPortPreemptControlEnableTx:
   1286             return bcmi_esw_preemption_enable_tx_set(unit, port, arg);
   1287 
   1288         case bcmPortPreemptControlVerifyEnable:
   1289             return bcmi_esw_preemption_enable_verify_set(unit, port, arg);
   1290 
   1291         case bcmPortPreemptControlVerifyTime:
   1292         case bcmPortPreemptControlVerifyAttempts:
   1293             return bcmi_esw_preemption_verify_config_set(unit, port,
   1294                                                          type, arg);
   1295         case bcmPortPreemptControlNonFinalFragSizeRx:
   1296         case bcmPortPreemptControlFinalFragSizeRx:
   1297             return bcmi_esw_preemption_frag_config_rx_set(unit, port,
   1298                                                           type, arg);
   1299         default:
   1300             return BCM_E_UNAVAIL;
   1301     }
   1302 }
   1303 
   1304 /*
   1305  * Function:
   1306  *      bcmi_esw_preemption_mac_config_get
   1307  * Purpose:
   1308  *      get preemption mac config
   1309  * Parameters:
   1310  *      unit       - (IN) unit number.
   1311  *      port       - (IN) port number
   1312  *      type       - (IN) Preemption control type
   1313  *      arg        - (OUT) value
   1314  * Returns:
   1315  *      BCM_E_XXX
   1316  * Notes:
   1317  */
   1318 int
   1319 bcmi_esw_preemption_mac_config_get(int unit, bcm_port_t port,
   1320                                    bcm_port_preempt_control_t type,
   1321                                    uint32* arg)
   1322 {
   1323     if (SOC_USE_PORTCTRL(unit)) {
   1324         BCM_IF_ERROR_RETURN(bcmi_esw_portctrl_preemption_mac_config_get
   1325                             (unit, port ,type, arg));
   1326 #if defined(BCM_MONTEREY_SUPPORT)
   1327         if (SOC_IS_MONTEREY(unit) &&
   1328            ((type == bcmPortPreemptControlFinalFragSizeRx) ||
   1329            (type == bcmPortPreemptControlNonFinalFragSizeRx))) {
   1330             *arg = *arg * 8;
   1331         }
   1332 #endif
   1333         return BCM_E_NONE; 
   1334     }
   1335     switch (type) {
   1336         case bcmPortPreemptControlPreemptionSupport:
   1337             return bcmi_esw_preemption_mode_get(unit, port, arg);
   1338 
   1339         case bcmPortPreemptControlEnableTx:
   1340             return bcmi_esw_preemption_enable_tx_get(unit, port, arg);
   1341 
   1342         case bcmPortPreemptControlVerifyEnable:
   1343             return bcmi_esw_preemption_enable_verify_get(unit, port, arg);
   1344 
   1345         case bcmPortPreemptControlVerifyTime:
   1346         case bcmPortPreemptControlVerifyAttempts:
   1347             return bcmi_esw_preemption_verify_config_get(unit, port,
   1348                                                          type, arg);
   1349         case bcmPortPreemptControlNonFinalFragSizeRx:
   1350         case bcmPortPreemptControlFinalFragSizeRx:
   1351             return bcmi_esw_preemption_frag_config_rx_get(unit, port,
   1352                                                           type, arg);
   1353         default:
   1354             return BCM_E_UNAVAIL;
   1355     }
   1356 }
   1357 
   1358 /*
   1359  * Function:
   1360  *      bcmi_esw_preemption_hold_request_mode_set
   1361  * Purpose:
   1362  *      set preemption hold request mode
   1363  * Parameters:
   1364  *      unit       - (IN) unit number.
   1365  *      port       - (IN) port number
   1366  *      arg        - (IN) value
   1367  * Returns:
   1368  *      BCM_E_XXX
   1369  * Notes:
   1370  */
   1371 int
   1372 bcmi_esw_preemption_hold_request_mode_set(int unit, bcm_port_t port,
   1373                                     uint32 arg)
   1374 {
   1375 #if defined(BCM_GREYHOUND2_SUPPORT)
   1376     if (SOC_IS_GREYHOUND2(unit)) {
   1377         return bcmi_gh2_preemption_hold_request_mode_set(unit, port, arg);
   1378     } else
   1379 #endif /* BCM_GREYHOUND2_SUPPORT */
   1380     {
   1381         return BCM_E_UNAVAIL;
   1382     }
   1383 }
   1384 
   1385 /*
   1386  * Function:
   1387  *      bcmi_esw_preemption_capability_set
   1388  * Purpose:
   1389  *      set preemption capability
   1390  * Parameters:
   1391  *      unit       - (IN) unit number.
   1392  *      port       - (IN) port number
   1393  *      arg        - (IN) value
   1394  * Returns:
   1395  *      BCM_E_XXX
   1396  * Notes:
   1397  */
   1398 int
   1399 bcmi_esw_preemption_capability_set(int unit, bcm_port_t port,
   1400                                    uint32 arg)
   1401 {
   1402     int rv;
   1403 
   1404 #if defined(BCM_GREYHOUND2_SUPPORT)
   1405     if (SOC_IS_GREYHOUND2(unit)) {
   1406         rv = bcmi_gh2_preemption_capability_set(unit, port, arg);
   1407     } else
   1408 #endif /* BCM_GREYHOUND2_SUPPORT */
   1409 #if defined(BCM_MONTEREY_SUPPORT)
   1410     if (SOC_IS_MONTEREY(unit)) {
   1411         rv = bcmi_mn_preemption_capability_set(unit, port, arg);
   1412     } else
   1413 #endif /* BCM_GREYHOUND2_SUPPORT */
   1414     {
   1415         rv = BCM_E_UNAVAIL;
   1416     }
   1417 
   1418     if (BCM_SUCCESS(rv)) {
   1419         rv = bcmi_esw_preemption_mac_config_set(
   1420                  unit, port,
   1421                  bcmPortPreemptControlPreemptionSupport,
   1422                  arg);
   1423     }
   1424 
   1425     return rv;
   1426 }
   1427 
   1428 /*
   1429  * Function:
   1430  *      bcmi_esw_preemption_frag_config_tx_set
   1431  * Purpose:
   1432  *      set preemption fragmentation config
   1433  * Parameters:
   1434  *      unit       - (IN) unit number.
   1435  *      port       - (IN) port number
   1436  *      is_final   - (IN) 1: final 0:non-final
   1437  *      arg        - (IN) value
   1438  * Returns:
   1439  *      BCM_E_XXX
   1440  * Notes:
   1441  */
   1442 int
   1443 bcmi_esw_preemption_frag_config_tx_set(int unit, bcm_port_t port,
   1444                                        int is_final, uint32 arg)
   1445 {
   1446 #if defined(BCM_GREYHOUND2_SUPPORT)
   1447     if (SOC_IS_GREYHOUND2(unit)) {
   1448         return bcmi_gh2_preemption_frag_config_tx_set(unit, port, is_final, arg);
   1449     }
   1450 #endif /* BCM_GREYHOUND2_SUPPORT */
   1451 #if defined(BCM_MONTEREY_SUPPORT)
   1452     if (SOC_IS_MONTEREY(unit)) {
   1453         return bcmi_mn_preemption_frag_config_tx_set(unit, port, is_final, arg);
   1454     }
   1455 #endif /* BCM_MONTEREY_SUPPORT */
   1456     {
   1457         return BCM_E_UNAVAIL;
   1458     }
   1459 }
   1460 
   1461 /*
   1462  * Function:
   1463  *      bcmi_esw_preemption_queue_bitmap_set
   1464  * Purpose:
   1465  *      set preemption queue bitmap
   1466  * Parameters:
   1467  *      unit       - (IN) unit number.
   1468  *      port       - (IN) port number
   1469  *      arg        - (IN) value
   1470  * Returns:
   1471  *      BCM_E_XXX
   1472  * Notes:
   1473  */
   1474 int
   1475 bcmi_esw_preemption_queue_bitmap_set(int unit, bcm_port_t port,
   1476                                      uint32 arg)
   1477 {
   1478 #if defined(BCM_GREYHOUND2_SUPPORT)
   1479     if (SOC_IS_GREYHOUND2(unit)) {
   1480         return bcmi_gh2_preemption_queue_bitmap_set(unit, port, arg);
   1481     } else
   1482 #endif /* BCM_GREYHOUND2_SUPPORT */
   1483 #if defined(BCM_MONTEREY_SUPPORT)
   1484     if (SOC_IS_MONTEREY(unit)) {
   1485         return bcmi_mn_preemption_queue_bitmap_set(unit, port, arg);
   1486     } else
   1487 #endif /* BCM_MONTEREY_SUPPORT */
   1488     {
   1489         return BCM_E_UNAVAIL;
   1490     }
   1491 }
   1492 
   1493 /*
   1494  * Function:
   1495  *      bcmi_esw_preemption_hold_request_mode_get
   1496  * Purpose:
   1497  *      get preemption hold request mode
   1498  * Parameters:
   1499  *      unit       - (IN) unit number.
   1500  *      port       - (IN) port number
   1501  *      arg        - (OUT) value
   1502  * Returns:
   1503  *      BCM_E_XXX
   1504  * Notes:
   1505  */
   1506 int
   1507 bcmi_esw_preemption_hold_request_mode_get(int unit, bcm_port_t port,
   1508                                           uint32* arg)
   1509 {
   1510 #if defined(BCM_GREYHOUND2_SUPPORT)
   1511     if (SOC_IS_GREYHOUND2(unit)) {
   1512         return bcmi_gh2_preemption_hold_request_mode_get(unit, port, arg);
   1513     } else
   1514 #endif /* BCM_GREYHOUND2_SUPPORT */
   1515     {
   1516         return BCM_E_UNAVAIL;
   1517     }
   1518 }
   1519 
   1520 /*
   1521  * Function:
   1522  *      bcmi_esw_preemption_capability_get
   1523  * Purpose:
   1524  *      get preemption capability
   1525  * Parameters:
   1526  *      unit       - (IN) unit number.
   1527  *      port       - (IN) port number
   1528  *      arg        - (OUT) value
   1529  * Returns:
   1530  *      BCM_E_XXX
   1531  * Notes:
   1532  */
   1533 int
   1534 bcmi_esw_preemption_capability_get(int unit, bcm_port_t port,
   1535                                    uint32* arg)
   1536 {
   1537 #if defined(BCM_GREYHOUND2_SUPPORT)
   1538     if (SOC_IS_GREYHOUND2(unit)) {
   1539         return bcmi_gh2_preemption_capability_get(unit, port, arg);
   1540     } else
   1541 #endif /* BCM_GREYHOUND2_SUPPORT */
   1542 #if defined(BCM_MONTEREY_SUPPORT)
   1543     if (SOC_IS_MONTEREY(unit)) {
   1544         return bcmi_mn_preemption_capability_get(unit, port, arg);
   1545     } else
   1546 #endif /* BCM_MONTEREY_SUPPORT */
   1547     {
   1548         return BCM_E_UNAVAIL;
   1549     }
   1550 }
   1551 
   1552 /*
   1553  * Function:
   1554  *      bcmi_esw_preemption_queue_bitmap_get
   1555  * Purpose:
   1556  *      get preemption queue bitmap
   1557  * Parameters:
   1558  *      unit       - (IN) unit number.
   1559  *      port       - (IN) port number
   1560  *      arg        - (OUT) value
   1561  * Returns:
   1562  *      BCM_E_XXX
   1563  * Notes:
   1564  */
   1565 int
   1566 bcmi_esw_preemption_queue_bitmap_get(int unit, bcm_port_t port,
   1567                                      uint32* arg)
   1568 {
   1569 #if defined(BCM_GREYHOUND2_SUPPORT)
   1570     if (SOC_IS_GREYHOUND2(unit)) {
   1571         return bcmi_gh2_preemption_queue_bitmap_get(unit, port, arg);
   1572     } else
   1573 #endif /* BCM_GREYHOUND2_SUPPORT */
   1574 #if defined(BCM_MONTEREY_SUPPORT)
   1575     if (SOC_IS_MONTEREY(unit)) {
   1576         return bcmi_mn_preemption_queue_bitmap_get(unit, port, arg);
   1577     } else
   1578 #endif /* BCM_MONTEREY_SUPPORT */
   1579     {
   1580         return BCM_E_UNAVAIL;
   1581     }
   1582 }
   1583 
   1584 /*
   1585  * Function:
   1586  *      bcmi_esw_preemption_frag_config_tx_get
   1587  * Purpose:
   1588  *      get preemption tx fragmentation config
   1589  * Parameters:
   1590  *      unit       - (IN) unit number.
   1591  *      port       - (IN) port number
   1592  *      is_final   - (IN) 1: final 0:non-final
   1593  *      arg        - (OUT) value
   1594  * Returns:
   1595  *      BCM_E_XXX
   1596  * Notes:
   1597  */
   1598 int
   1599 bcmi_esw_preemption_frag_config_tx_get(int unit, bcm_port_t port,
   1600                                        int is_final, uint32* arg)
   1601 {
   1602 #if defined(BCM_GREYHOUND2_SUPPORT)
   1603     if (SOC_IS_GREYHOUND2(unit)) {
   1604         return bcmi_gh2_preemption_frag_config_tx_get(unit, port, is_final, arg);
   1605     }
   1606 #endif /* BCM_GREYHOUND2_SUPPORT */
   1607 #if defined(BCM_MONTEREY_SUPPORT)
   1608     if (SOC_IS_MONTEREY(unit)) {
   1609         return bcmi_mn_preemption_frag_config_tx_get(unit, port, is_final, arg);
   1610     }
   1611 #endif /* BCM_MONTEREY_SUPPORT */
   1612     {
   1613         return BCM_E_UNAVAIL;
   1614     }
   1615 }
   1616 
   1617 
   1618 void bcmi_esw_preemption_linkscan_update(int unit,
   1619                                          bcm_port_t port,
   1620                                          bcm_port_info_t *portInfo)
   1621 {
   1622     int enable_in_cache;
   1623 
   1624     PREEMPTION_LOCK(unit);
   1625     enable_in_cache = SOC_PBMP_MEMBER(pbmp_verify_enable_cache[unit], port);
   1626     PREEMPTION_UNLOCK(unit);
   1627 
   1628      if (portInfo->linkstatus == BCM_PORT_LINK_STATUS_DOWN) {
   1629         if (enable_in_cache) {
   1630             int rv = _bcmi_esw_preemption_enable_verify_set(unit, port, 0);
   1631             if (BCM_SUCCESS(rv)) {
   1632                 LOG_VERBOSE(
   1633                     BSL_LS_BCM_PORT,
   1634                     (BSL_META("Disable verify on port %d when link down\n"),
   1635                     port));
   1636             }
   1637         }
   1638      } else if (portInfo->linkstatus == BCM_PORT_LINK_STATUS_UP) {
   1639         if (enable_in_cache) {
   1640             int rv = _bcmi_esw_preemption_enable_verify_set(unit, port, 1);
   1641             if (BCM_SUCCESS(rv)) {
   1642                 LOG_VERBOSE(
   1643                     BSL_LS_BCM_PORT,
   1644                     (BSL_META("re-enable verify on port %d when link up\n"),
   1645                     port));
   1646             }
   1647         }
   1648      }
   1649 }
   1650 
   1651 void bcmi_esw_preemption_cleanup(int unit)
   1652 {
   1653     if (NULL != verify_enable_cache_mutex[unit]) {
   1654         sal_mutex_destroy(verify_enable_cache_mutex[unit]);
   1655         verify_enable_cache_mutex[unit] = NULL;
   1656     }
   1657 }
   1658 
   1659 int bcmi_esw_preemption_init(int unit)
   1660 {
   1661 #ifdef BCM_MONTEREY_SUPPORT
   1662     if(SOC_IS_MONTEREY(unit)) {
   1663        BCM_IF_ERROR_RETURN(
   1664        bcmi_mn_preemption_init(unit));
   1665     }
   1666 #endif
   1667 
   1668     SOC_PBMP_CLEAR(pbmp_verify_enable_cache[unit]);
   1669 
   1670     verify_enable_cache_mutex[unit] = sal_mutex_create("preempt_mutex");
   1671     if (NULL == verify_enable_cache_mutex[unit]) {
   1672         bcmi_esw_preemption_cleanup(unit);
   1673         return BCM_E_INTERNAL;
   1674     }
   1675     return BCM_E_NONE;
   1676 }
   1677 
   1678 #ifdef BCM_WARM_BOOT_SUPPORT
   1679 int bcmi_esw_preemption_sync(int unit,
   1680                              soc_scache_handle_t scache_handle)
   1681 {
   1682     uint8 *scache_ptr = NULL;
   1683 
   1684     BCM_IF_ERROR_RETURN(
   1685         _bcm_esw_scache_ptr_get(unit, scache_handle, FALSE, sizeof(soc_pbmp_t),
   1686                                 &scache_ptr,
   1687                                 BCM_PORT_WB_DEFAULT_VERSION, NULL));
   1688 
   1689     if (NULL == scache_ptr) {
   1690         return BCM_E_INTERNAL;
   1691     }
   1692     PREEMPTION_LOCK(unit);
   1693     sal_memcpy(scache_ptr, &pbmp_verify_enable_cache[unit], sizeof(soc_pbmp_t));
   1694     PREEMPTION_UNLOCK(unit);
   1695 
   1696     return BCM_E_NONE;
   1697 }
   1698 
   1699 int bcmi_esw_preemption_wb_alloc(int unit,
   1700                              soc_scache_handle_t scache_handle)
   1701 {
   1702     int rv;
   1703     uint8 *scache_ptr = NULL;
   1704 
   1705     rv = _bcm_esw_scache_ptr_get(
   1706             unit, scache_handle, TRUE, sizeof(soc_pbmp_t),
   1707             &scache_ptr, BCM_PORT_WB_DEFAULT_VERSION, NULL);
   1708 
   1709     if (BCM_E_NOT_FOUND == rv) {
   1710         /* Maybe proceed with Level 1 Warm Boot */
   1711         return BCM_E_NONE;
   1712     } else if (BCM_E_NONE == rv) {
   1713         if (NULL == scache_ptr) {
   1714             return BCM_E_INTERNAL;
   1715         }
   1716     }
   1717     return rv;
   1718 }
   1719 
   1720 int bcmi_esw_preemption_recover(int unit,
   1721                                 soc_scache_handle_t scache_handle)
   1722 {
   1723     int rv;
   1724     uint8 *scache_ptr = NULL;
   1725 
   1726     rv = _bcm_esw_scache_ptr_get(
   1727             unit, scache_handle, FALSE, sizeof(soc_pbmp_t),
   1728             &scache_ptr, BCM_PORT_WB_DEFAULT_VERSION, NULL);
   1729 
   1730     if (BCM_E_NOT_FOUND == rv) {
   1731         /* Maybe proceed with Level 1 Warm Boot */
   1732         return BCM_E_NONE;
   1733     } else if (BCM_E_NONE == rv) {
   1734         if (NULL == scache_ptr) {
   1735             rv = BCM_E_INTERNAL;
   1736         } else {
   1737             PREEMPTION_LOCK(unit);
   1738             sal_memcpy(&pbmp_verify_enable_cache[unit], scache_ptr,
   1739                        sizeof(soc_pbmp_t));
   1740             PREEMPTION_UNLOCK(unit);
   1741         }
   1742     }
   1743 
   1744     return rv;
   1745 }
   1746 #endif /* BCM_WARM_BOOT_SUPPORT */
   1747 
   1748 
   1749 #endif /* BCM_PREEMPTION_SUPPORT */
   1750