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

macutil.c (164350B)


      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  * MAC driver support utilities. 
      8  */
      9 
     10 #include <shared/bsl.h>
     11 
     12 #include <sal/core/libc.h>
     13 
     14 #include <soc/drv.h>
     15 #include <soc/ll.h>
     16 #include <soc/error.h>
     17 #include <soc/portmode.h>
     18 #include <soc/macutil.h>
     19 #include <soc/phyctrl.h>
     20 #include <soc/mem.h>
     21 #if defined(BCM_TRIDENT2_SUPPORT)
     22 #include <soc/trident2.h>
     23 #endif
     24 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
     25 #include <soc/td2_td2p.h>
     26 #endif
     27 #if defined(BCM_KATANA_SUPPORT)
     28 #include <soc/katana.h>
     29 #endif
     30 #if defined(BCM_SABER2_SUPPORT)
     31 #include <soc/saber2.h>
     32 #endif
     33 #if defined(BCM_MONTEREY_SUPPORT)
     34 #include <soc/monterey.h>
     35 #endif
     36 
     37 #if defined(BCM_APACHE_SUPPORT)
     38 #include <soc/apache.h>
     39 #endif
     40 
     41 #if defined(BCM_TOMAHAWK_SUPPORT)
     42 #include <soc/tomahawk.h>
     43 #endif /* BCM_TOMAHAWK_SUPPORT */
     44 #if defined(BCM_TOMAHAWK2_SUPPORT)
     45 #include <soc/tomahawk2.h>
     46 #endif /* BCM_TOMAHAWK2_SUPPORT */
     47 #if defined (BCM_TOMAHAWK3_SUPPORT)
     48 #include <soc/tomahawk3.h>
     49 #endif
     50 #if defined(BCM_KATANA2_SUPPORT)
     51 #include <soc/katana2.h>
     52 #include <bcm/types.h>
     53 #include <bcm/cosq.h>
     54 #endif
     55 #if defined(BCM_GREYHOUND_SUPPORT)
     56 #include <soc/greyhound.h>
     57 #endif
     58 #if defined(BCM_TRIDENT3_SUPPORT)
     59 #include <soc/trident3.h>
     60 #endif /* BCM_TRIDENT3_SUPPORT */
     61 #if defined(BCM_HURRICANE3_SUPPORT)
     62 #include <soc/hurricane3.h>
     63 #endif
     64 #if defined(BCM_GREYHOUND2_SUPPORT)
     65 #include <soc/greyhound2.h>
     66 #endif
     67 #include <soc/debug.h>
     68 
     69 #if defined(BCM_TRIUMPH3_SUPPORT)
     70 int ibod_recovery_in_progress[SOC_MAX_NUM_DEVICES];
     71 int egress_drain_timeout_flag[SOC_MAX_NUM_DEVICES];
     72 #endif
     73 
     74 #if defined(BCM_KATANA2_SUPPORT)
     75 #define _SOC_KT2_COSQ_MAX_INDEX_S0   128
     76 #define _SOC_KT2_COSQ_MAX_INDEX_S1   256
     77 #endif
     78 
     79 #if defined (BCM_SABER2_SUPPORT)
     80 #define _SOC_SB2_COSQ_MAX_INDEX_S0   16
     81 #endif
     82 
     83 #if defined(BCM_ESW_SUPPORT)
     84 
     85 /*
     86  * Function:
     87  *      soc_egress_cell_count
     88  * Purpose:
     89  *      Return the approximate number of cells of packets pending
     90  *      in the MMU destined for a specified egress.
     91  */
     92 int
     93 soc_egress_cell_count(int unit, soc_port_t port, uint32 *count)
     94 {
     95     uint32              val;
     96     int                 cos;
     97 #if defined(BCM_TRIDENT_SUPPORT)
     98     int                 i;
     99 #if defined(BCM_TRIDENT2_SUPPORT)
    100     soc_mem_t           mem;
    101     int                 index;
    102     uint32              entry[SOC_MAX_MEM_WORDS];
    103 #if defined(BCM_TOMAHAWK_SUPPORT)
    104     soc_info_t          *si = &SOC_INFO(unit);
    105     soc_mem_t           base_mem;
    106     int                 pipe, xpe, base;
    107 #endif /* BCM_TOMAHAWK_SUPPORT */
    108 #endif /* BCM_TRIDENT2_SUPPORT */
    109 #endif /* BCM_TRIDENT_SUPPORT */
    110 #if defined(BCM_TOMAHAWK3_SUPPORT)
    111     int itm, num_ucq, num_mcq, uc_base, mc_base;
    112 #endif
    113     *count = 0;
    114 
    115     switch (SOC_CHIP_GROUP(unit)) {
    116     case SOC_CHIP_BCM56504:
    117     case SOC_CHIP_BCM56102:
    118     case SOC_CHIP_BCM56304:
    119     case SOC_CHIP_BCM56218:
    120     case SOC_CHIP_BCM56112:
    121     case SOC_CHIP_BCM56314:
    122     case SOC_CHIP_BCM56514:
    123     case SOC_CHIP_BCM56224:
    124     case SOC_CHIP_BCM53314:
    125     case SOC_CHIP_BCM56142:
    126     case SOC_CHIP_BCM56150:
    127     case SOC_CHIP_BCM53400:
    128     case SOC_CHIP_BCM56160:
    129     case SOC_CHIP_BCM53540:
    130         for (cos = 0; cos < NUM_COS(unit); cos++) {
    131             SOC_IF_ERROR_RETURN(soc_reg_egress_cell_count_get(unit, port, cos, &val));
    132             *count += val;
    133         }
    134 #if defined(BCM_HURRICANE1_SUPPORT)
    135        if (SOC_IS_HURRICANE(unit) &&
    136           (IS_XE_PORT(unit, port) || IS_HG_PORT(unit, port))) {
    137            if (SOC_REG_PORT_VALID(unit, XP_XBODE_CELL_CNTr, port)) {
    138                SOC_IF_ERROR_RETURN(
    139                        READ_XP_XBODE_CELL_CNTr(unit, port, &val));
    140                *count += soc_reg_field_get(
    141                        unit, XP_XBODE_CELL_CNTr, val, CELL_CNTf);
    142            }
    143            if (SOC_REG_PORT_VALID(unit, GE_GBODE_CELL_CNTr, port)) {
    144                SOC_IF_ERROR_RETURN(READ_GE_GBODE_CELL_CNTr(unit, port, &val));
    145                *count += soc_reg_field_get(
    146                        unit, GE_GBODE_CELL_CNTr, val, CELL_CNTf);
    147            }
    148        }
    149 #endif
    150         break;
    151 #if defined(BCM_GREYHOUND2_SUPPORT)
    152     case SOC_CHIP_BCM53570:
    153         for (cos = 0; cos < SOC_REG_NUMELS(unit, COSLCCOUNTr); cos++) {
    154             SOC_IF_ERROR_RETURN(READ_COSLCCOUNTr(unit, port, cos, &val));
    155             *count += soc_reg_field_get(unit, COSLCCOUNTr, val,
    156                                     LCCOUNTf);
    157         }
    158         for (cos = 0; cos < SOC_REG_NUMELS(unit, COSLCCOUNT_QGROUPr); cos++) {
    159             SOC_IF_ERROR_RETURN(READ_COSLCCOUNT_QGROUPr(unit, port, cos, &val));
    160             *count += soc_reg_field_get(unit, COSLCCOUNT_QGROUPr, val,
    161                                     LCCOUNTf);
    162         }
    163         break;
    164 #endif /* BCM_GREYHOUND2_SUPPORT */
    165 #if defined(BCM_HERCULES_SUPPORT)
    166     case SOC_CHIP_BCM5675:
    167         
    168         break;
    169 #endif /* BCM_HERCULES_SUPPORT */
    170 #if defined(BCM_BRADLEY_SUPPORT)
    171     case SOC_CHIP_BCM56800:
    172     case SOC_CHIP_BCM56820:
    173     case SOC_CHIP_BCM56725:
    174     case SOC_CHIP_BCM88732:
    175         SOC_IF_ERROR_RETURN(READ_OP_PORT_TOTAL_COUNTr(unit, port, &val));
    176         *count += soc_reg_field_get(unit, OP_PORT_TOTAL_COUNTr, val,
    177                                     OP_PORT_TOTAL_COUNTf);
    178         if (IS_GX_PORT(unit, port) && !SOC_IS_SHADOW(unit)) {
    179             SOC_IF_ERROR_RETURN(READ_XP_XBODE_CELL_CNTr(unit, port, &val));
    180             *count += soc_reg_field_get(unit, XP_XBODE_CELL_CNTr, val,
    181                                         CELL_CNTf);
    182             SOC_IF_ERROR_RETURN(READ_GE_GBODE_CELL_CNTr(unit, port, &val));
    183             *count += soc_reg_field_get(unit, GE_GBODE_CELL_CNTr, val,
    184                                         CELL_CNTf);
    185         }
    186         break;
    187 #endif /* BCM_BRADLEY_SUPPORT */
    188 #if defined(BCM_TRIUMPH_SUPPORT)
    189     case SOC_CHIP_BCM56624:
    190     case SOC_CHIP_BCM56680:
    191     case SOC_CHIP_BCM56634:
    192     case SOC_CHIP_BCM56524:
    193     case SOC_CHIP_BCM56685:
    194     case SOC_CHIP_BCM56334:
    195         SOC_IF_ERROR_RETURN(READ_OP_PORT_TOTAL_COUNT_CELLr(unit, port, &val));
    196         *count += soc_reg_field_get(unit, OP_PORT_TOTAL_COUNT_CELLr, val,
    197                                    OP_PORT_TOTAL_COUNT_CELLf);
    198         break;
    199     case SOC_CHIP_BCM56640:
    200     case SOC_CHIP_BCM56340:
    201         SOC_IF_ERROR_RETURN(READ_OP_PORT_TOTAL_COUNT_CELLr(unit, port, &val));
    202         *count += soc_reg_field_get(unit, OP_PORT_TOTAL_COUNT_CELLr, val,
    203                                    TOTAL_COUNTf);
    204         break;
    205 #endif /* BCM_TRIUMPH_SUPPORT */
    206 #if defined(BCM_TRIDENT_SUPPORT)
    207     case SOC_CHIP_BCM56840:
    208         for (i = 0; i < SOC_INFO(unit).port_num_uc_cosq[port]; i++) {
    209             SOC_IF_ERROR_RETURN
    210                 (READ_OP_UC_QUEUE_TOTAL_COUNT_CELLr(unit, port, i, &val));
    211             *count += soc_reg_field_get(unit, OP_UC_QUEUE_TOTAL_COUNT_CELLr,
    212                                         val, Q_TOTAL_COUNT_CELLf);
    213         }
    214         for (i = 0; i < SOC_INFO(unit).port_num_cosq[port]; i++) {
    215             SOC_IF_ERROR_RETURN
    216                 (READ_OP_QUEUE_TOTAL_COUNT_CELLr(unit, port, i, &val));
    217             *count += soc_reg_field_get(unit, OP_QUEUE_TOTAL_COUNT_CELLr,
    218                                         val, Q_TOTAL_COUNT_CELLf);
    219         }
    220         if (SOC_INFO(unit).port_num_ext_cosq[port] > 0) {
    221             for (i = 0; i < SOC_INFO(unit).port_num_uc_cosq[port] +
    222                      SOC_INFO(unit).port_num_ext_cosq[port]; i++) {
    223                 SOC_IF_ERROR_RETURN
    224                     (READ_OP_EX_QUEUE_TOTAL_COUNT_CELLr(unit, port, i, &val));
    225                 *count += soc_reg_field_get(unit,
    226                                             OP_EX_QUEUE_TOTAL_COUNT_CELLr, val,
    227                                             Q_TOTAL_COUNT_CELLf);
    228             }
    229         }
    230         break;
    231 #endif /* BCM_TRIDENT_SUPPORT */
    232     case SOC_CHIP_BCM56440:
    233     case SOC_CHIP_BCM56450:
    234     case SOC_CHIP_BCM56260:
    235     case SOC_CHIP_BCM56270:
    236         
    237         *count = 0;
    238         break;
    239 #if defined (BCM_TRIDENT2_SUPPORT)
    240     case SOC_CHIP_BCM56850:
    241     case SOC_CHIP_BCM56860:
    242         /* Unicast queues */
    243         index = SOC_INFO(unit).port_uc_cosq_base[port];
    244         if (index < 1480) {
    245             mem = MMU_THDU_XPIPE_COUNTER_QUEUEm;
    246         } else {
    247             index -= 1480;
    248             mem = MMU_THDU_YPIPE_COUNTER_QUEUEm;
    249         }
    250         for (i = 0; i < SOC_INFO(unit).port_num_uc_cosq[port]; i++) {
    251             SOC_IF_ERROR_RETURN
    252                 (soc_mem_read(unit, mem, MEM_BLOCK_ANY, index + i, entry));
    253             *count += soc_mem_field32_get(unit, mem, entry, MIN_COUNTf);
    254             *count += soc_mem_field32_get(unit, mem, entry, SHARED_COUNTf);
    255         }
    256 
    257         /* Multicast queues */
    258         index = SOC_INFO(unit).port_cosq_base[port];
    259         if (index < 568) {
    260             mem = MMU_THDM_DB_QUEUE_COUNT_0m;
    261         } else {
    262             index -= 568;
    263             mem = MMU_THDM_DB_QUEUE_COUNT_1m;
    264         }
    265         for (i = 0; i < SOC_INFO(unit).port_num_cosq[port]; i++) {
    266             SOC_IF_ERROR_RETURN
    267                 (soc_mem_read(unit, mem, MEM_BLOCK_ANY, index + i, entry));
    268             *count += soc_mem_field32_get(unit, mem, entry, MIN_COUNTf);
    269             *count += soc_mem_field32_get(unit, mem, entry, SHARED_COUNTf);
    270         }
    271         break;
    272 #endif /* BCM_TRIDENT2_SUPPORT */
    273 #if defined(BCM_TOMAHAWK_SUPPORT)
    274 #if defined(BCM_TRIDENT3_SUPPORT)
    275 	case SOC_CHIP_BCM56870:
    276     case SOC_CHIP_BCM56770:
    277     case SOC_CHIP_BCM56370:
    278 #endif
    279     case SOC_CHIP_BCM56960:
    280     case SOC_CHIP_BCM56965:
    281     case SOC_CHIP_BCM56970:
    282         pipe = si->port_pipe[port];
    283         base = si->port_uc_cosq_base[port];
    284 
    285         /* Since TH has xpe architecture, go over all XPEs and pick the instance
    286          * which is valid for the given Mem/XPE/Pipe combination.
    287          */
    288         for (xpe = 0; xpe < NUM_XPE(unit); xpe++) {
    289             /* UC queue Count */
    290             base_mem = MMU_THDU_COUNTER_QUEUEm;
    291 
    292             /* Get XPE/PIPE view from base mem */
    293             mem = SOC_MEM_UNIQUE_ACC_XPE_PIPE(unit, base_mem, xpe, pipe);
    294 
    295             if (mem == INVALIDm) {
    296                 /* If given XPE/PIPE combination is not valid, continue */
    297                 continue;
    298             }
    299             for (i = 0; i < SOC_INFO(unit).port_num_uc_cosq[port]; i++) {
    300                 SOC_IF_ERROR_RETURN
    301                     (soc_mem_read(unit, mem, MEM_BLOCK_ALL, base + i, &entry));
    302                 *count += soc_mem_field32_get(unit, mem, entry, MIN_COUNTf);
    303                 *count += soc_mem_field32_get(unit, mem, entry, SHARED_COUNTf);
    304             }
    305         }
    306 
    307         base = si->port_cosq_base[port];
    308         for (xpe = 0; xpe < NUM_XPE(unit); xpe++) {
    309             /* MC queue Count */
    310             base_mem = MMU_THDM_DB_QUEUE_COUNTm;
    311 
    312             /* xpe/pipe/mem check not performed again as it is similar to UC
    313              * queue layout.
    314              */
    315 
    316             /* Get XPE/PIPE view from base mem */
    317             mem = SOC_MEM_UNIQUE_ACC_XPE_PIPE(unit, base_mem, xpe, pipe);
    318 
    319             if (mem == INVALIDm) {
    320                 /* If given XPE/PIPE combination is not valid, continue */
    321                 continue;
    322             }
    323             for (i = 0; i < SOC_INFO(unit).port_num_cosq[port]; i++) {
    324                 SOC_IF_ERROR_RETURN
    325                     (soc_mem_read(unit, mem, MEM_BLOCK_ALL, base + i, &entry));
    326                 *count += soc_mem_field32_get(unit, mem, entry, MIN_COUNTf);
    327                 *count += soc_mem_field32_get(unit, mem, entry, SHARED_COUNTf);
    328             }
    329         }
    330 
    331         break;
    332 #endif /* BCM_TOMAHAWK_SUPPORT */
    333 #if defined (BCM_TOMAHAWK3_SUPPORT)
    334         case SOC_CHIP_BCM56980:
    335             num_ucq = _soc_th3_get_num_ucq(unit);
    336             num_mcq = _soc_th3_get_num_mcq(unit);
    337             SOC_IF_ERROR_RETURN(
    338                 soc_th3_chip_queue_num_get(unit, port, 0, 0, &uc_base));
    339             SOC_IF_ERROR_RETURN(
    340                 soc_th3_chip_queue_num_get(unit, port, 0, 1, &mc_base));
    341             for (itm = 0; itm < NUM_ITM(unit); itm++) {
    342                 if (!soc_tomahawk3_itm_valid(unit, itm)) {
    343                     continue;
    344                 }
    345                 mem = SOC_MEM_UNIQUE_ACC_ITM(unit, MMU_THDO_COUNTER_QUEUEm, itm);
    346                 for (i = 0; i < num_ucq; i++) {
    347                     SOC_IF_ERROR_RETURN(
    348                         soc_mem_read(unit, mem, MEM_BLOCK_ALL, uc_base + i, &entry));
    349                     *count += soc_mem_field32_get(unit, mem, entry, TOTALCOUNTf);
    350                 }
    351                 for (i = 0; i< num_mcq; i++) {
    352                     SOC_IF_ERROR_RETURN(
    353                         soc_mem_read(unit, mem, MEM_BLOCK_ALL, mc_base + i, &entry));
    354                     *count += soc_mem_field32_get(unit, mem, entry, TOTALCOUNTf);
    355                 }
    356             }
    357         break;
    358 #endif
    359 #if defined (BCM_APACHE_SUPPORT)
    360     case SOC_CHIP_BCM56560:
    361     case SOC_CHIP_BCM56670:
    362         /* Unicast queues */
    363         index = SOC_INFO(unit).port_uc_cosq_base[port];
    364         mem = MMU_THDU_XPIPE_COUNTER_QUEUEm;
    365         for (i = 0; i < SOC_INFO(unit).port_num_uc_cosq[port]; i++) {
    366             SOC_IF_ERROR_RETURN
    367                 (soc_mem_read(unit, mem, MEM_BLOCK_ANY, index + i, entry));
    368             *count += soc_mem_field32_get(unit, mem, entry, MIN_COUNTf);
    369             *count += soc_mem_field32_get(unit, mem, entry, SHARED_COUNTf);
    370         }
    371 
    372         /* Multicast queues */
    373         index = SOC_INFO(unit).port_cosq_base[port];
    374         mem = MMU_THDM_DB_QUEUE_COUNT_0m;
    375         for (i = 0; i < SOC_INFO(unit).port_num_cosq[port]; i++) {
    376             SOC_IF_ERROR_RETURN
    377                 (soc_mem_read(unit, mem, MEM_BLOCK_ANY, index + i, entry));
    378             *count += soc_mem_field32_get(unit, mem, entry, MIN_COUNTf);
    379             *count += soc_mem_field32_get(unit, mem, entry, SHARED_COUNTf);
    380         }
    381         break;
    382 #endif /* BCM_APACHE_SUPPORT */
    383 
    384     default:
    385         return SOC_E_UNAVAIL;
    386     }
    387 
    388     return SOC_E_NONE;
    389 }
    390 
    391 #if defined(BCM_TRIDENT2_SUPPORT)
    392 int
    393 _soc_egress_cell_check(int unit, soc_port_t port, int *empty)
    394 {
    395     switch (SOC_CHIP_GROUP(unit)) {
    396     case SOC_CHIP_BCM56850:
    397 #if defined (BCM_TRIDENT2PLUS_SUPPORT)
    398     case SOC_CHIP_BCM56860:
    399 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
    400     {
    401         int                 bit_pos, phy_port, mmu_port;
    402         uint64              rval64;
    403         if (SAL_BOOT_SIMULATION && !SAL_BOOT_QUICKTURN) {
    404             *empty = TRUE;
    405             break;
    406         }
    407         phy_port = SOC_INFO(unit).port_l2p_mapping[port];
    408         mmu_port = SOC_INFO(unit).port_p2m_mapping[phy_port];
    409 
    410         if (mmu_port <= 63) {
    411             SOC_IF_ERROR_RETURN(READ_MMU_ENQ_PORT_EMPTY_BMP0r(unit, &rval64));
    412         } else {
    413             SOC_IF_ERROR_RETURN(READ_MMU_ENQ_PORT_EMPTY_BMP1r(unit, &rval64));
    414             mmu_port = mmu_port - 64;
    415         }
    416         bit_pos = mmu_port & 0x3f;
    417         *empty = COMPILER_64_BITTEST(rval64, bit_pos);
    418         break;
    419     }
    420 #if defined (BCM_APACHE_SUPPORT)
    421     case SOC_CHIP_BCM56560:
    422     case SOC_CHIP_BCM56670:
    423     {
    424         int                 bit_pos, phy_port, mmu_port;
    425         uint64              rval64;
    426         if (SAL_BOOT_SIMULATION && !SAL_BOOT_QUICKTURN) {
    427             *empty = TRUE;
    428             break;
    429         }
    430         phy_port = SOC_INFO(unit).port_l2p_mapping[port];
    431         mmu_port = SOC_INFO(unit).port_p2m_mapping[phy_port];
    432 
    433         if (mmu_port <= 63) {
    434             SOC_IF_ERROR_RETURN(READ_MMU_ENQ_PORT_EMPTY_BMP0r(unit, &rval64));
    435         } else {
    436             SOC_IF_ERROR_RETURN(READ_MMU_ENQ_PORT_EMPTY_BMP1r(unit, &rval64));
    437             mmu_port = mmu_port - 64;
    438         }
    439         bit_pos = mmu_port & 0x3f;
    440         *empty = COMPILER_64_BITTEST(rval64, bit_pos);
    441         break;
    442     }
    443 #endif /* BCM_APACHE_SUPPORT */
    444 
    445     default:
    446         return SOC_E_UNAVAIL;
    447     }
    448 
    449     return SOC_E_NONE;
    450 }
    451 #endif /* BCM_TRIDENT2_SUPPORT */
    452 
    453 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT)
    454 STATIC int
    455 _soc_port_txfifo_cell_count(int unit, soc_port_t port, int *count)
    456 {
    457     uint32 rval;
    458 
    459     switch (SOC_CHIP_GROUP(unit)) {
    460     case SOC_CHIP_BCM56640:
    461     case SOC_CHIP_BCM56340:
    462         SOC_IF_ERROR_RETURN(READ_PORT_TXFIFO_CELL_CNTr(unit, port, &rval));
    463         *count = soc_reg_field_get(unit, PORT_TXFIFO_CELL_CNTr, rval,
    464                                    CELL_CNTf);
    465         break;
    466     case SOC_CHIP_BCM56850:
    467     case SOC_CHIP_BCM56860:
    468         /* Should only be called by CMAC driver */
    469         SOC_IF_ERROR_RETURN(READ_CPORT_TXFIFO_CELL_CNTr(unit, port, &rval));
    470         *count = soc_reg_field_get(unit, CPORT_TXFIFO_CELL_CNTr, rval,
    471                                    CELL_CNTf);
    472         break;
    473     default:
    474         return SOC_E_UNAVAIL;
    475     }
    476 
    477     return SOC_E_NONE;
    478 }
    479 #endif /* BCM_TRIUMPH3_SUPPORT || BCM_TRIDENT2_SUPPORT */
    480 
    481 STATIC int
    482 soc_mmu_backpressure_clear(int unit, soc_port_t port) {
    483     uint64 rv;
    484 
    485     COMPILER_64_SET(rv, 0, 0);
    486 
    487     switch (SOC_CHIP_GROUP(unit)) {
    488     case SOC_CHIP_BCM56840:
    489     case SOC_CHIP_BCM56640:
    490     case SOC_CHIP_BCM56850:
    491     case SOC_CHIP_BCM56860:
    492     case SOC_CHIP_BCM56340:
    493     case SOC_CHIP_BCM56960:
    494     case SOC_CHIP_BCM56870:
    495     case SOC_CHIP_BCM56770:
    496     case SOC_CHIP_BCM56965:
    497     case SOC_CHIP_BCM56970:
    498         SOC_IF_ERROR_RETURN(WRITE_XPORT_TO_MMU_BKPr(unit, port, 0));
    499         break;
    500     case SOC_CHIP_BCM56370:
    501         SOC_IF_ERROR_RETURN(WRITE_XPORT_TO_MMU_BKP_64r(unit, port, rv));
    502         break;
    503 
    504     case SOC_CHIP_BCM56440:
    505         if (IS_HG_PORT(unit, port) || IS_XE_PORT(unit, port)) {
    506             SOC_IF_ERROR_RETURN(WRITE_XPORT_TO_MMU_BKPr(unit, port, 0));
    507         }
    508         break;
    509 #if defined (BCM_APACHE_SUPPORT)
    510     case SOC_CHIP_BCM56560:
    511         {
    512             soc_mem_t mem;
    513             soc_field_t field;
    514             static const soc_mem_t flowcontrol_mems[4] = {
    515                 MMU_INTFI_S1_ST_TBm,
    516                 MMU_INTFI_FC_ST_TBL0m, 
    517                 MMU_INTFI_FC_ST_TBL1m, 
    518                 MMU_INTFI_FC_ST_TBL2m 
    519             };
    520 
    521             static const soc_field_t flowcontrol_fields[4] = {
    522                 COEFCf,
    523                 FC_STf,
    524                 FC_STf,
    525                 FC_STf
    526             };
    527             uint32 *bmap;
    528             uint32 *bmap_list[SOC_APACHE_NODE_LVL_MAX - SOC_APACHE_NODE_LVL_S1];
    529             uint32 fval;
    530             mmu_intfi_s1_st_tb_entry_t rval; /* Can be used with all mems  */
    531             int lvl, index, word, bit, word_count, index_count, cindex;
    532             int bit_val, rv;
    533             bmap_list[0] = SOC_CONTROL(unit)->port_lls_s1_bmap[port];
    534             bmap_list[1] = SOC_CONTROL(unit)->port_lls_l0_bmap[port];
    535             bmap_list[2] = SOC_CONTROL(unit)->port_lls_l1_bmap[port];
    536             bmap_list[3] = SOC_CONTROL(unit)->port_lls_l2_bmap[port];
    537 
    538             for (lvl = 0; 
    539                     lvl < (SOC_APACHE_NODE_LVL_MAX - SOC_APACHE_NODE_LVL_S1);
    540                     lvl++) {
    541                 bmap = bmap_list[lvl];
    542                 mem = flowcontrol_mems[lvl];
    543                 field = flowcontrol_fields[lvl];
    544                 index_count = soc_mem_index_count(unit, mem) * 4;
    545                 word_count = _SHR_BITDCLSIZE(index_count);
    546 
    547                 for (word = 0; word < word_count; word++) {
    548                     if (bmap[word] == 0) {
    549                         continue;
    550                     }
    551                     for (bit = 0; bit < SHR_BITWID; bit++) {
    552                         if (!(bmap[word] & (1 << bit))) {
    553                             continue;
    554                         }
    555                         index = (word * SHR_BITWID + bit) / 4;
    556                         cindex = (word * SHR_BITWID + bit) % 4;
    557                         bit_val = 1 << cindex;
    558                         /* Save the entry */
    559                         rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, index,
    560                                 &rval);
    561                         if (SOC_FAILURE(rv)) {
    562                             break;
    563                         }
    564                         fval = soc_mem_field32_get(unit, mem, &rval, field);
    565                         /* Disable the flowcontrol */
    566                         fval = fval & (~bit_val);
    567 
    568                         soc_mem_field32_set(unit, mem, &rval, field, fval);
    569                         rv = soc_mem_write(unit, mem, MEM_BLOCK_ANY, index,
    570                                 &rval);
    571                         if (SOC_FAILURE(rv)) {
    572                             break;
    573                         }
    574                     }
    575                 }
    576 
    577             }
    578             soc_mem_field32_set(unit, mem, &rval, field, 0);
    579             rv = soc_mem_write(unit, MMU_INTFI_PORT_COEFC_TBm, MEM_BLOCK_ANY, port,
    580                     &rval);
    581             if (SOC_FAILURE(rv)) {
    582                 break;
    583             }
    584 
    585             SOC_IF_ERROR_RETURN(WRITE_XPORT_TO_MMU_BKPr(unit, port, 0));
    586             break;
    587         }
    588 #endif /* BCM_APACHE_SUPPORT */
    589     default:
    590         break;
    591     }
    592 
    593     return SOC_E_NONE;
    594 }
    595 
    596 int
    597 _soc_egress_metering_freeze(int unit, soc_port_t port, void **setting)
    598 {
    599     int      rv;
    600 
    601     rv = SOC_E_NONE;
    602 
    603     SOC_EGRESS_METERING_LOCK(unit);
    604 
    605     switch (SOC_CHIP_GROUP(unit)) {
    606 #if defined(BCM_RAVEN_SUPPORT) || defined(BCM_SCORPION_SUPPORT) || defined(BCM_HURRICANE_SUPPORT)
    607     case SOC_CHIP_BCM56820:
    608     case SOC_CHIP_BCM56725:
    609     case SOC_CHIP_BCM56224:
    610     case SOC_CHIP_BCM53314:
    611     case SOC_CHIP_BCM56142:
    612         {
    613             uint32 *rval32;
    614 
    615             rval32 = sal_alloc(sizeof(uint32), "shaper buffer");
    616             if (rval32 == NULL) {
    617                 rv = SOC_E_MEMORY;
    618                 break;
    619             }
    620 
    621             rv = READ_EGRMETERINGCONFIGr(unit, port, rval32);
    622             if (SOC_SUCCESS(rv)) {
    623                 rv = WRITE_EGRMETERINGCONFIGr(unit, port, 0);
    624             }
    625             if (SOC_FAILURE(rv)) {
    626                 sal_free(rval32);
    627                 break;
    628             }
    629             *setting = rval32;
    630             break;
    631         }
    632 #endif /* BCM_RAVEN_SUPPORT || BCM_SCORPION_SUPPORT || BCM_HURRICANE_SUPPORT */
    633 #if defined (BCM_HURRICANE2_SUPPORT)
    634     case SOC_CHIP_BCM56150:
    635     case SOC_CHIP_BCM53400:
    636     case SOC_CHIP_BCM56160:
    637     case SOC_CHIP_BCM53540:
    638         {
    639             int i;
    640             uint32 regval;
    641             uint32 *buffer;
    642             int count;
    643 
    644             /* buffer required = (X+1), for store original register setting.
    645              * MAXBUCKETCONFIGr : X elements for a port
    646              * EGRMETERINGCONFIG : 1 register value for a port
    647              */
    648             count = SOC_REG_NUMELS(unit, MAXBUCKETCONFIGr) + 1;
    649             buffer = sal_alloc(count * sizeof(uint32), "shaper buffer");
    650             if (buffer == NULL) {
    651                 rv = SOC_E_MEMORY;
    652                 goto _hu_freeze_abort;
    653             }
    654             sal_memset(buffer, 0, count);
    655 
    656             /* save the original configuration : MAXBUCKETCONFIGr */
    657             count = 0;
    658             for (i = 0; i < SOC_REG_NUMELS(unit, MAXBUCKETCONFIGr); i++) {
    659                 rv = READ_MAXBUCKETCONFIGr(unit, port, i, &regval);
    660                 if (SOC_FAILURE(rv)) {
    661                     sal_free(buffer);
    662                     goto _hu_freeze_abort;
    663                 }
    664                 buffer[count] = regval;
    665                 count ++;
    666                 /* Disable egress metering for this port */
    667                 soc_reg_field_set(unit, MAXBUCKETCONFIGr, &regval, MAX_REFRESHf, 0);
    668                 soc_reg_field_set(unit, MAXBUCKETCONFIGr, &regval, MAX_THD_SELf, 0);
    669                 rv = WRITE_MAXBUCKETCONFIGr(unit, port, i, regval);
    670                 if (SOC_FAILURE(rv)) {
    671                     sal_free(buffer);
    672                     goto _hu_freeze_abort;
    673                 }
    674             }
    675 
    676             /* save the original configuration : EGRMETERINGCONFIGr */
    677             rv = READ_EGRMETERINGCONFIGr(unit, port, &regval);
    678             if (SOC_SUCCESS(rv)) {
    679                 buffer[count] = regval;
    680                 count ++;
    681                 rv = WRITE_EGRMETERINGCONFIGr(unit, port, 0);
    682             }
    683             if (SOC_FAILURE(rv)) {
    684                 sal_free(buffer);
    685                 goto _hu_freeze_abort;
    686             }
    687             *setting = buffer;
    688 _hu_freeze_abort:
    689             break;
    690         }
    691 #endif /* BCM_HURRICANE2_SUPPORT */
    692 #if defined(BCM_GREYHOUND2_SUPPORT)
    693     case SOC_CHIP_BCM53570:
    694         {
    695             int i;
    696             uint32 value;
    697             uint32 *buffer;
    698             int count;
    699             int qlayer_entry_count = 0;
    700             int qgroup_entry_count = 0;
    701             soc_mem_t config_mem = INVALIDm;
    702             uint32 entry[SOC_MAX_MEM_WORDS];
    703             int memidx;
    704             int is_64q_port;
    705 
    706             rv = soc_gh2_64q_port_check(unit, port, &is_64q_port);
    707             if (SOC_FAILURE(rv)) {
    708                 break;
    709             }
    710 
    711             if (is_64q_port) {
    712                 qlayer_entry_count = SOC_GH2_QLAYER_COSQ_PER_PORT_NUM;
    713                 qgroup_entry_count = SOC_GH2_QGROUP_PER_PORT_NUM;
    714             } else {
    715                 qlayer_entry_count = SOC_GH2_LEGACY_QUEUE_NUM;
    716                 qgroup_entry_count = 0;
    717             }
    718             
    719             /* buffer required (X*2+Y*2+1) for store original setting.
    720              *   MMU port 0~57: X=8, Y=0
    721              *   MMU port 58-65 : X=64, Y=8
    722              * MMU_MAX_BUCKET_QLAYERm : 
    723              *   X entries for a port, 2 fields (REFRESHf, THD_SELf)stored
    724              * MMU_MAX_BUCKET_QGROUPm : Y entries for a port
    725              *   Y entries for a port, 2 fields (REFRESHf, THD_SELf)stored
    726              * EGRMETERINGCONFIG : 1 register value for a port
    727              */
    728             count = (qlayer_entry_count * 2) +  (qgroup_entry_count * 2) + 1;
    729             buffer = sal_alloc(count * sizeof(uint32), "shaper buffer");
    730             if (buffer == NULL) {
    731                 rv = SOC_E_MEMORY;
    732                 break;
    733             }
    734             sal_memset(buffer, 0, count);
    735 
    736             /* save the original configuration : MMU_MAX_BUCKET_QLAYERm */
    737             count = 0;
    738             config_mem = MMU_MAX_BUCKET_QLAYERm;
    739             rv = soc_gh2_mmu_bucket_qlayer_index(unit, port, 0, &memidx);
    740             if (SOC_FAILURE(rv)) {
    741                 sal_free(buffer);
    742                 break;
    743             }
    744             for (i = memidx; i < qlayer_entry_count; i++) {
    745                 rv = soc_mem_read(unit, config_mem, MEM_BLOCK_ALL, 
    746                                   i, &entry);
    747                 if (SOC_FAILURE(rv)) {
    748                     sal_free(buffer);
    749                     break;
    750                 }
    751                 value = soc_mem_field32_get(unit, config_mem,
    752                                             &entry, REFRESHf);
    753                 buffer[count] = value;
    754                 count ++;
    755                 value = soc_mem_field32_get(unit, config_mem,
    756                                             &entry, THD_SELf);
    757                 buffer[count] = value;
    758                 count ++;
    759 
    760                 /* Disable egress metering for this port */
    761                 soc_mem_field32_set(unit, config_mem, &entry, REFRESHf, 0);
    762                 soc_mem_field32_set(unit, config_mem, &entry, THD_SELf, 0);
    763                 rv = soc_mem_write(unit, config_mem, MEM_BLOCK_ALL, 
    764                                    i, &entry);
    765                 if (SOC_FAILURE(rv)) {
    766                     sal_free(buffer);
    767                     break;
    768                 }
    769             }
    770 
    771             /* save the original configuration : MMU_MAX_BUCKET_QGROUPm */
    772             if (qgroup_entry_count) {
    773                 config_mem = MMU_MAX_BUCKET_QGROUPm;
    774                 rv = soc_gh2_mmu_bucket_qgroup_index(unit, port, 0, &memidx);
    775                 if (SOC_FAILURE(rv)) {
    776                     sal_free(buffer);
    777                     break;
    778                 }
    779                 for (i = memidx; i < qgroup_entry_count; i++) {
    780                     rv = soc_mem_read(unit, config_mem, MEM_BLOCK_ALL, 
    781                                   i, &entry);
    782                     if (SOC_FAILURE(rv)) {
    783                         sal_free(buffer);
    784                         break;
    785                     }
    786                     value = soc_mem_field32_get(unit, config_mem,
    787                                                 &entry, REFRESHf);
    788                     buffer[count] = value;
    789                     count ++;
    790                     value = soc_mem_field32_get(unit, config_mem,
    791                                                 &entry, THD_SELf);
    792                     buffer[count] = value;
    793                     count ++;
    794 
    795                     /* Disable egress metering for this port */
    796                     soc_mem_field32_set(unit, config_mem, &entry, REFRESHf, 0);
    797                     soc_mem_field32_set(unit, config_mem, &entry, THD_SELf, 0);
    798                     rv = soc_mem_write(unit, config_mem, MEM_BLOCK_ALL, 
    799                                        i, &entry);
    800                     if (SOC_FAILURE(rv)) {
    801                         sal_free(buffer);
    802                         break;
    803                     }
    804                 }
    805             }
    806 
    807             /* save the original configuration : EGRMETERINGCONFIGr */
    808             rv = READ_EGRMETERINGCONFIGr(unit, port, &value);
    809             if (SOC_SUCCESS(rv)) {
    810                 buffer[count] = value;
    811                 count ++;
    812                 rv = WRITE_EGRMETERINGCONFIGr(unit, port, 0);
    813             }
    814             if (SOC_FAILURE(rv)) {
    815                 sal_free(buffer);
    816                 break;
    817             }
    818             *setting = buffer;
    819             break;
    820         }
    821 #endif /* BCM_GREYHOUND2_SUPPORT */
    822 #if defined(BCM_TRIUMPH_SUPPORT)
    823     case SOC_CHIP_BCM56624:
    824     case SOC_CHIP_BCM56680:
    825     case SOC_CHIP_BCM56634:
    826     case SOC_CHIP_BCM56524:
    827     case SOC_CHIP_BCM56685:
    828     case SOC_CHIP_BCM56334:
    829         {
    830             uint64 *rval64, temp_rval64;
    831 
    832             rval64 = sal_alloc(sizeof(uint64), "shaper buffer");
    833             if (rval64 == NULL) {
    834                 rv = SOC_E_MEMORY;
    835                 break;
    836             }
    837 
    838             rv = READ_EGRMETERINGCONFIG_64r(unit, port, rval64);
    839             if (SOC_SUCCESS(rv)) {
    840                 COMPILER_64_ZERO(temp_rval64);
    841                 rv = WRITE_EGRMETERINGCONFIG_64r(unit, port, temp_rval64);
    842             }
    843             if (SOC_FAILURE(rv)) {
    844                 sal_free(rval64);
    845                 break;
    846             }
    847             *setting = rval64;
    848             break;
    849         }
    850     case SOC_CHIP_BCM56840:
    851         {
    852             uint64 zero_rval64;
    853             int count, index, queue_cnt;
    854             soc_info_t *si;
    855             uint64 *buffer;
    856 
    857             si = &SOC_INFO(unit);
    858             COMPILER_64_ZERO(zero_rval64);
    859             queue_cnt = si->port_num_uc_cosq[port] + si->port_num_cosq[port] +
    860                         si->port_num_ext_cosq[port];
    861             /* Port level + S2 + S3 + UCQ + MCQ + EXT_UCQ. */
    862             count = 1 + 4 + 4 + queue_cnt;
    863 
    864             buffer = sal_alloc(count * sizeof(mem_entry_t),
    865                                "shaper buffer");
    866             if (buffer == NULL) {
    867                 rv = SOC_E_MEMORY;
    868                 goto _trident_freeze_abort;
    869             }
    870 
    871             count = 0;
    872             /* Port level meter. */
    873             rv = READ_EGRMETERINGCONFIG_64r(unit, port, &buffer[count]);
    874             if (SOC_SUCCESS(rv)) {
    875                 rv = WRITE_EGRMETERINGCONFIG_64r(unit, port, zero_rval64);
    876             }
    877             if (SOC_FAILURE(rv)) {
    878                 sal_free(buffer);
    879                 goto _trident_freeze_abort;
    880             }
    881             count++;
    882 
    883             if (!IS_CPU_PORT(unit, port)) {
    884                 /* S2 meter (including MC group). */
    885                 for (index = 0; index < 4; index++) {
    886                     rv = READ_S2_MAXBUCKETCONFIG_64r(unit, port, index,
    887                                                      &buffer[count]);
    888                     if (SOC_SUCCESS(rv)) {
    889                         rv = WRITE_S2_MAXBUCKETCONFIG_64r(unit, port, index,
    890                                                           zero_rval64);
    891                     }
    892                     if (SOC_FAILURE(rv)) {
    893                         sal_free(buffer);
    894                         goto _trident_freeze_abort;
    895                     }
    896                     count++;
    897                 }
    898                 /* S3 meter. */
    899                 for (index = 0; index < 4; index++) {
    900                     rv = READ_S3_MAXBUCKETCONFIG_64r(unit, port, index,
    901                                                      &buffer[count]);
    902                     if (SOC_SUCCESS(rv)) {
    903                         rv = WRITE_S3_MAXBUCKETCONFIG_64r(unit, port, index,
    904                                                           zero_rval64);
    905                     }
    906                     if (SOC_FAILURE(rv)) {
    907                         sal_free(buffer);
    908                         goto _trident_freeze_abort;
    909                     }
    910                     count++;
    911                 }
    912             }
    913 
    914             /* Queue meter. */
    915             for (index = 0; index < queue_cnt; index++) {
    916                 rv = READ_MAXBUCKETCONFIG_64r(unit, port, index,
    917                                               &buffer[count]);
    918                 if (SOC_SUCCESS(rv)) {
    919                     rv = WRITE_MAXBUCKETCONFIG_64r(unit, port, index,
    920                                                    zero_rval64);
    921                 }
    922                 if (SOC_FAILURE(rv)) {
    923                     sal_free(buffer);
    924                     goto _trident_freeze_abort;
    925                 }
    926                 count++;
    927             }
    928             *setting = buffer;
    929 _trident_freeze_abort:
    930             break;
    931         }
    932 #endif /* BCM_TRIUMPH_SUPPORT */
    933 #ifdef BCM_TRIUMPH3_SUPPORT
    934     case SOC_CHIP_BCM56640:
    935     case SOC_CHIP_BCM56340:
    936         {
    937             uint64 rval64, temp_rval64;
    938             soc_mem_t mem;
    939             uint32 *bmap, *bmap_list[3];
    940             int lvl, index, word, bit, word_count, index_count, count;
    941             mem_entry_t *buffer;
    942             static const soc_mem_t shaper_mems[3] = {
    943                 MMU_MTRO_L0_MEMm, MMU_MTRO_L1_MEMm, MMU_MTRO_L2_MEMm
    944             };
    945 
    946             bmap_list[0] = SOC_CONTROL(unit)->port_lls_l0_bmap[port];
    947             bmap_list[1] = SOC_CONTROL(unit)->port_lls_l1_bmap[port];
    948             bmap_list[2] = SOC_CONTROL(unit)->port_lls_l2_bmap[port];
    949 
    950             SOC_LLS_SCHEDULER_LOCK(unit);
    951             count = 1; /* One entry for port level */
    952             for (lvl = 0; lvl < 3; lvl++) {
    953                 bmap = bmap_list[lvl];
    954                 mem = shaper_mems[lvl];
    955                 index_count = soc_mem_index_count(unit, mem);
    956                 word_count = _SHR_BITDCLSIZE(index_count);
    957                 for (word = 0; word < word_count; word++) {
    958                     if (bmap[word] != 0) {
    959                         count += _shr_popcount(bmap[word]);
    960                     }
    961                 }
    962             }
    963 
    964             buffer = sal_alloc((count + 1) * sizeof(mem_entry_t),
    965                                "shaper buffer");
    966             if (buffer == NULL) {
    967                 rv = SOC_E_MEMORY;
    968                 goto _tr_freeze_abort;
    969             }
    970 
    971             /* Port level meter */
    972             rv = READ_EGRMETERINGCONFIG_64r(unit, port, &rval64);
    973             if (SOC_SUCCESS(rv)) {
    974                 COMPILER_64_ZERO(temp_rval64);
    975                 rv = WRITE_EGRMETERINGCONFIG_64r(unit, port, temp_rval64);
    976             }
    977             if (SOC_FAILURE(rv)) {
    978                 sal_free(buffer);
    979                 goto _tr_freeze_abort;
    980             }
    981             sal_memcpy(&buffer[0].entry[0], &rval64, sizeof(uint64));
    982 
    983             /* L0, L1, L2 meter */
    984             count = 1;
    985             for (lvl = 0; lvl < 3; lvl++) {
    986                 bmap = bmap_list[lvl];
    987                 mem = shaper_mems[lvl];
    988                 index_count = soc_mem_index_count(unit, mem);
    989                 word_count = _SHR_BITDCLSIZE(index_count);
    990 
    991                 for (word = 0; word < word_count; word++) {
    992                     if (bmap[word] == 0) {
    993                         continue;
    994                     }
    995                     for (bit = 0; bit < SHR_BITWID; bit++) {
    996                         if (!(bmap[word] & (1 << bit))) {
    997                             continue;
    998                         }
    999                         index = word * SHR_BITWID + bit;
   1000                         /* Save the entry */
   1001                         rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, index,
   1002                                           &buffer[count].entry);
   1003                         if (SOC_FAILURE(rv)) {
   1004                             sal_free(buffer);
   1005                             goto _tr_freeze_abort;
   1006                         }
   1007                         buffer[count].mem = mem;
   1008                         buffer[count].index = index;
   1009                         count++;
   1010                         /* Disable the entry */
   1011                         rv = soc_mem_write(unit, mem, MEM_BLOCK_ANY, index,
   1012                                            soc_mem_entry_null(unit, mem));
   1013                         if (SOC_FAILURE(rv)) {
   1014                             sal_free(buffer);
   1015                             goto _tr_freeze_abort;
   1016                         }
   1017                     }
   1018                 }
   1019             }
   1020 
   1021             buffer[count].mem = INVALIDm;
   1022             *setting = buffer;
   1023 _tr_freeze_abort:
   1024             SOC_LLS_SCHEDULER_UNLOCK(unit);
   1025             break;
   1026         }
   1027 #endif /* BCM_TRIUMPH3_SUPPORT */
   1028 #ifdef BCM_APACHE_SUPPORT
   1029     case SOC_CHIP_BCM56560:
   1030         {
   1031             soc_mem_t mem;
   1032             uint32 *bmap, 
   1033                    *bmap_list[SOC_APACHE_NODE_LVL_MAX - SOC_APACHE_NODE_LVL_S1];
   1034             int pipe, phy_port, mmu_port;
   1035             int lvl, index, word, bit, word_count, index_count, count;
   1036             mem_entry_t *buffer;
   1037             static const int max_l1_table = 2;
   1038             static const int max_l2_table = 8;
   1039             static const soc_mem_t port_shaper_mems[1] = {
   1040                 MMU_MTRO_EGRMETERINGCONFIG_MEM_0m
   1041             };
   1042             static const soc_mem_t shaper_mems[][1] = {
   1043                 { MMU_MTRO_S1_MEM_0m},
   1044                 { MMU_MTRO_L0_MEM_0m},
   1045                 { MMU_MTRO_L1_MEM_0m},
   1046                 { MMU_MTRO_L2_MEM_0m}
   1047             };
   1048             static const soc_mem_t l1_shaper_mems[] = {
   1049                 MMU_MTRO_L1_MEM_0m,
   1050                 MMU_MTRO_L1_MEM_1m
   1051             };
   1052             static const soc_mem_t l2_shaper_mems[] = {
   1053                 MMU_MTRO_L2_MEM_0m,
   1054                 MMU_MTRO_L2_MEM_1m,
   1055                 MMU_MTRO_L2_MEM_2m,
   1056                 MMU_MTRO_L2_MEM_3m,
   1057                 MMU_MTRO_L2_MEM_4m,
   1058                 MMU_MTRO_L2_MEM_5m,
   1059                 MMU_MTRO_L2_MEM_6m,
   1060                 MMU_MTRO_L2_MEM_7m
   1061             };
   1062 
   1063             pipe = 0;
   1064             bmap_list[0] = SOC_CONTROL(unit)->port_lls_s1_bmap[port];
   1065             bmap_list[1] = SOC_CONTROL(unit)->port_lls_l0_bmap[port];
   1066             bmap_list[2] = SOC_CONTROL(unit)->port_lls_l1_bmap[port];
   1067             bmap_list[3] = SOC_CONTROL(unit)->port_lls_l2_bmap[port];
   1068 
   1069             SOC_LLS_SCHEDULER_LOCK(unit);
   1070             count = 1; /* One entry for port level */
   1071             for (lvl = 0; 
   1072                     lvl < (SOC_APACHE_NODE_LVL_MAX - SOC_APACHE_NODE_LVL_S1);
   1073                     lvl++) {
   1074                 bmap = bmap_list[lvl];
   1075                 mem = shaper_mems[lvl][pipe];
   1076                 index_count = soc_mem_index_count(unit, mem);
   1077                 word_count = _SHR_BITDCLSIZE(index_count);
   1078                 for (word = 0; word < word_count; word++) {
   1079                     if (bmap[word] != 0) {
   1080                         count += _shr_popcount(bmap[word]);
   1081                     }
   1082                 }
   1083             }
   1084 
   1085             buffer = sal_alloc((count + 1) * sizeof(mem_entry_t),
   1086                                "shaper buffer");
   1087             if (buffer == NULL) {
   1088                 rv = SOC_E_MEMORY;
   1089                 goto _ap_freeze_abort;
   1090             }
   1091 
   1092             count = 0;
   1093 
   1094             /* Port level meter */
   1095             mem = port_shaper_mems[pipe];
   1096             phy_port = SOC_INFO(unit).port_l2p_mapping[port];
   1097             mmu_port = SOC_INFO(unit).port_p2m_mapping[phy_port];
   1098             index = mmu_port & 0x7f;
   1099             /* Save the entry */
   1100             rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, index,
   1101                               &buffer[count].entry);
   1102             if (SOC_FAILURE(rv)) {
   1103                 sal_free(buffer);
   1104                 goto _ap_freeze_abort;
   1105             }
   1106             buffer[count].mem = mem;
   1107             buffer[count].index = index;
   1108             count++;
   1109             /* Disable the entry */
   1110             rv = soc_mem_write(unit, mem, MEM_BLOCK_ANY, index,
   1111                                soc_mem_entry_null(unit, mem));
   1112             if (SOC_FAILURE(rv)) {
   1113                 sal_free(buffer);
   1114                 goto _ap_freeze_abort;
   1115             }
   1116 
   1117             /*S1, L0, L1, L2 meter */
   1118             mem = shaper_mems[0][pipe];
   1119             for (lvl = 0; lvl < (SOC_APACHE_NODE_LVL_MAX - SOC_APACHE_NODE_LVL_S1);
   1120                     lvl++) {
   1121                 bmap = bmap_list[lvl];
   1122                 mem = shaper_mems[lvl][pipe];
   1123                 index_count = soc_mem_index_count(unit, mem);
   1124                 word_count = _SHR_BITDCLSIZE(index_count);
   1125 
   1126                 for (word = 0; word < word_count; word++) {
   1127                     if (bmap[word] == 0) {
   1128                         continue;
   1129                     }
   1130                     for (bit = 0; bit < SHR_BITWID; bit++) {
   1131                         if (!(bmap[word] & (1 << bit))) {
   1132                             continue;
   1133                         }
   1134                         index = word * SHR_BITWID + bit;
   1135                         if ((SOC_APACHE_NODE_LVL_L1 - SOC_APACHE_NODE_LVL_S1) == lvl) {
   1136                             mem = l1_shaper_mems[index % max_l1_table];
   1137                             index /= max_l1_table;
   1138                         } else if ((SOC_APACHE_NODE_LVL_L2 - SOC_APACHE_NODE_LVL_S1) == lvl) {
   1139                             mem = l2_shaper_mems[index % max_l2_table];
   1140                             index /= max_l2_table;
   1141                         }
   1142                         /* Save the entry */
   1143                         rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, index,
   1144                                           &buffer[count].entry);
   1145                         if (SOC_FAILURE(rv)) {
   1146                             sal_free(buffer);
   1147                             goto _ap_freeze_abort;
   1148                         }
   1149                         buffer[count].mem = mem;
   1150                         buffer[count].index = index;
   1151                         count++;
   1152                         /* Disable the entry */
   1153                         rv = soc_mem_write(unit, mem, MEM_BLOCK_ANY, index,
   1154                                            soc_mem_entry_null(unit, mem));
   1155                         if (SOC_FAILURE(rv)) {
   1156                             sal_free(buffer);
   1157                             goto _ap_freeze_abort;
   1158                         }
   1159                     }
   1160                 }
   1161             }
   1162             buffer[count].mem = INVALIDm;
   1163             *setting = buffer;
   1164 _ap_freeze_abort:
   1165             SOC_LLS_SCHEDULER_UNLOCK(unit);
   1166             break;
   1167         }
   1168 #endif /* BCM_APACHE_SUPPORT */
   1169 
   1170 #ifdef BCM_TRIDENT2_SUPPORT
   1171     case SOC_CHIP_BCM56850:
   1172     case SOC_CHIP_BCM56860:
   1173         {
   1174             soc_info_t *si;
   1175             soc_mem_t mem;
   1176             uint32 *bmap, *bmap_list[3];
   1177             int pipe, phy_port, mmu_port;
   1178             int lvl, index, word, bit, word_count, index_count, count;
   1179             mem_entry_t *buffer;
   1180             static const soc_mem_t port_shaper_mems[2] = {
   1181                 MMU_MTRO_EGRMETERINGCONFIG_MEM_0m,
   1182                 MMU_MTRO_EGRMETERINGCONFIG_MEM_1m
   1183             };
   1184             static const soc_mem_t shaper_mems[][2] = {
   1185                 { MMU_MTRO_L0_MEM_0m, MMU_MTRO_L0_MEM_1m },
   1186                 { MMU_MTRO_L1_MEM_0m, MMU_MTRO_L1_MEM_1m },
   1187                 { MMU_MTRO_L2_MEM_0m, MMU_MTRO_L2_MEM_1m }
   1188             };
   1189 
   1190             si = &SOC_INFO(unit);
   1191             pipe = SOC_PBMP_MEMBER(si->ypipe_pbm, port) ? 1 : 0;
   1192             bmap_list[0] = SOC_CONTROL(unit)->port_lls_l0_bmap[port];
   1193             bmap_list[1] = SOC_CONTROL(unit)->port_lls_l1_bmap[port];
   1194             bmap_list[2] = SOC_CONTROL(unit)->port_lls_l2_bmap[port];
   1195             if ((bmap_list[0] == NULL) ||
   1196                 (bmap_list[1] == NULL) ||
   1197                 (bmap_list[2] == NULL)) {
   1198                 rv =  SOC_E_RESOURCE;
   1199                 goto _td_freeze_abort;
   1200             }
   1201             SOC_LLS_SCHEDULER_LOCK(unit);
   1202             count = 1; /* One entry for port level */
   1203             for (lvl = 0; lvl < 3; lvl++) {
   1204                 bmap = bmap_list[lvl];
   1205                 mem = shaper_mems[lvl][pipe];
   1206                 index_count = soc_mem_index_count(unit, mem);
   1207                 word_count = _SHR_BITDCLSIZE(index_count);
   1208                 for (word = 0; word < word_count; word++) {
   1209                     if (bmap[word] != 0) {
   1210                         count += _shr_popcount(bmap[word]);
   1211                     }
   1212                 }
   1213             }
   1214 
   1215             buffer = sal_alloc((count + 1) * sizeof(mem_entry_t),
   1216                                "shaper buffer");
   1217             if (buffer == NULL) {
   1218                 rv = SOC_E_MEMORY;
   1219                 goto _td_freeze_abort;
   1220             }
   1221 
   1222             count = 0;
   1223 
   1224             /* Port level meter */
   1225             mem = port_shaper_mems[pipe];
   1226             phy_port = SOC_INFO(unit).port_l2p_mapping[port];
   1227             mmu_port = SOC_INFO(unit).port_p2m_mapping[phy_port];
   1228             index = mmu_port & 0x3f;
   1229             /* Save the entry */
   1230             rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, index,
   1231                               &buffer[count].entry);
   1232             if (SOC_FAILURE(rv)) {
   1233                 sal_free(buffer);
   1234                 goto _td_freeze_abort;
   1235             }
   1236             buffer[count].mem = mem;
   1237             buffer[count].index = index;
   1238             count++;
   1239             /* Disable the entry */
   1240             rv = soc_mem_write(unit, mem, MEM_BLOCK_ANY, index,
   1241                                soc_mem_entry_null(unit, mem));
   1242             if (SOC_FAILURE(rv)) {
   1243                 sal_free(buffer);
   1244                 goto _td_freeze_abort;
   1245             }
   1246 
   1247             /* L0, L1, L2 meter */
   1248             mem = shaper_mems[0][pipe];
   1249             for (lvl = 0; lvl < 3; lvl++) {
   1250                 bmap = bmap_list[lvl];
   1251                 mem = shaper_mems[lvl][pipe];
   1252                 index_count = soc_mem_index_count(unit, mem);
   1253                 word_count = _SHR_BITDCLSIZE(index_count);
   1254 
   1255                 for (word = 0; word < word_count; word++) {
   1256                     if (bmap[word] == 0) {
   1257                         continue;
   1258                     }
   1259                     for (bit = 0; bit < SHR_BITWID; bit++) {
   1260                         if (!(bmap[word] & (1 << bit))) {
   1261                             continue;
   1262                         }
   1263                         index = word * SHR_BITWID + bit;
   1264                         /* Save the entry */
   1265                         rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, index,
   1266                                           &buffer[count].entry);
   1267                         if (SOC_FAILURE(rv)) {
   1268                             sal_free(buffer);
   1269                             goto _td_freeze_abort;
   1270                         }
   1271                         buffer[count].mem = mem;
   1272                         buffer[count].index = index;
   1273                         count++;
   1274                         /* Disable the entry */
   1275                         rv = soc_mem_write(unit, mem, MEM_BLOCK_ANY, index,
   1276                                            soc_mem_entry_null(unit, mem));
   1277                         if (SOC_FAILURE(rv)) {
   1278                             sal_free(buffer);
   1279                             goto _td_freeze_abort;
   1280                         }
   1281                     }
   1282                 }
   1283             }
   1284             buffer[count].mem = INVALIDm;
   1285             *setting = buffer;
   1286 _td_freeze_abort:
   1287             SOC_LLS_SCHEDULER_UNLOCK(unit);
   1288             break;
   1289         }
   1290 #endif /* BCM_TRIDENT2_SUPPORT */
   1291 
   1292 #if defined(BCM_KATANA_SUPPORT)
   1293     case SOC_CHIP_BCM56440:
   1294         {
   1295             soc_mem_t mem;
   1296             uint32 *bmap, *bmap_list[3];
   1297             int word_count, wdc[3], blk_size=0;
   1298             int lvl, j, index, word, bit, index_count, count;
   1299             int idx, upper_flag = 0;
   1300             int prev_idx, prev_upper_flag;
   1301             mem_entry_t *buffer;
   1302             uint32 mant, cycle, f_idx;
   1303             uint32 entry[SOC_MAX_MEM_WORDS];
   1304             uint16 dev_id;
   1305             uint8 rev_id;
   1306 
   1307             static const soc_mem_t cfg_mems[][2] = {
   1308                 { LLS_L0_SHAPER_CONFIG_Cm, LLS_L0_MIN_CONFIG_Cm },
   1309                 { LLS_L1_SHAPER_CONFIG_Cm, LLS_L1_MIN_CONFIG_Cm },
   1310                 { LLS_L2_SHAPER_CONFIG_LOWERm, LLS_L2_MIN_CONFIG_LOWER_Cm },
   1311                 { LLS_L2_SHAPER_CONFIG_UPPERm, LLS_L2_MIN_CONFIG_UPPER_Cm },
   1312             };
   1313 
   1314 
   1315             static const soc_field_t rate_mant_fields[] = {
   1316                C_MAX_REF_RATE_MANT_0f, C_MAX_REF_RATE_MANT_1f,
   1317                C_MAX_REF_RATE_MANT_2f, C_MAX_REF_RATE_MANT_3f,
   1318                C_MIN_REF_RATE_MANT_0f, C_MIN_REF_RATE_MANT_1f,
   1319                C_MIN_REF_RATE_MANT_2f, C_MIN_REF_RATE_MANT_3f
   1320             };
   1321 
   1322             static const soc_field_t rate_exp_fields[] = {
   1323                C_MAX_REF_RATE_EXP_0f, C_MAX_REF_RATE_EXP_1f,
   1324                C_MAX_REF_RATE_EXP_2f, C_MAX_REF_RATE_EXP_3f,
   1325                C_MIN_REF_RATE_EXP_0f, C_MIN_REF_RATE_EXP_1f,
   1326                C_MIN_REF_RATE_EXP_2f, C_MIN_REF_RATE_EXP_3f
   1327             };
   1328             static const soc_field_t burst_exp_fields[] = {
   1329                C_MAX_THLD_EXP_0f, C_MAX_THLD_EXP_1f,
   1330                C_MAX_THLD_EXP_2f, C_MAX_THLD_EXP_3f,
   1331                C_MIN_THLD_EXP_0f, C_MIN_THLD_EXP_1f,
   1332                C_MIN_THLD_EXP_2f, C_MIN_THLD_EXP_3f
   1333             };
   1334             static const soc_field_t burst_mant_fields[] = {
   1335                C_MAX_THLD_MANT_0f, C_MAX_THLD_MANT_1f,
   1336                C_MAX_THLD_MANT_2f, C_MAX_THLD_MANT_3f,
   1337                C_MIN_THLD_MANT_0f, C_MIN_THLD_MANT_1f,
   1338                C_MIN_THLD_MANT_2f, C_MIN_THLD_MANT_3f
   1339             };
   1340 
   1341             static const soc_field_t cycle_sel_fields[] = {
   1342                 C_MAX_CYCLE_SEL_0f, C_MAX_CYCLE_SEL_1f,
   1343                 C_MAX_CYCLE_SEL_2f, C_MAX_CYCLE_SEL_3f,
   1344                 C_MIN_CYCLE_SEL_0f, C_MIN_CYCLE_SEL_1f,
   1345                 C_MIN_CYCLE_SEL_2f, C_MIN_CYCLE_SEL_3f
   1346             };
   1347 
   1348             bmap_list[0] = SOC_CONTROL(unit)->port_lls_l0_bmap[port];
   1349             bmap_list[1] = SOC_CONTROL(unit)->port_lls_l1_bmap[port];
   1350             bmap_list[2] = SOC_CONTROL(unit)->port_lls_l2_bmap[port];
   1351 
   1352             count = 0; /* One entry for port level */
   1353             for (lvl = 0; lvl < 3; lvl++) {
   1354                 bmap = bmap_list[lvl];
   1355                 mem = cfg_mems[lvl][0];
   1356                 index_count = soc_mem_index_count(unit, mem);
   1357 
   1358                 /*
   1359                  * Allocation done using LLS_LX_PARENT
   1360                  * reading also done using same memories
   1361                  */
   1362                 if (lvl == 0) {
   1363                     index_count = soc_mem_index_count(unit, LLS_L0_PARENTm);
   1364                 } else if (lvl == 1) {
   1365                     index_count = soc_mem_index_count(unit, LLS_L1_PARENTm);
   1366                 } else if (lvl == 2) {
   1367                     index_count = soc_mem_index_count(unit, LLS_L2_PARENTm);
   1368                 }
   1369 
   1370                 wdc[lvl] = _SHR_BITDCLSIZE(index_count);
   1371                 word_count = wdc[lvl];
   1372                 for (word = 0; word < word_count; word++) {
   1373                     if (bmap[word] != 0) {
   1374                         count += _shr_popcount(bmap[word]);
   1375                     }
   1376                 }
   1377             }
   1378 
   1379             count = (count * 8) + 1;
   1380 
   1381             buffer = sal_alloc((count + 1) * sizeof(mem_entry_t),
   1382                                "shaper buffer");
   1383 
   1384             if (buffer == NULL) {
   1385                 rv = SOC_E_MEMORY;
   1386                 goto _ka_freeze_abort;
   1387             }
   1388 
   1389             count = 0;
   1390             /* port */
   1391             mem = LLS_PORT_SHAPER_CONFIG_Cm;
   1392             index = port & 0x3f;
   1393 
   1394             /* Save the entry */
   1395             rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, index,
   1396                               &buffer[count].entry);
   1397 
   1398             if (SOC_FAILURE(rv)) {
   1399                 sal_free(buffer);
   1400                 goto _ka_freeze_abort;
   1401             }
   1402             buffer[count].mem = mem;
   1403             buffer[count].index = index;
   1404             count++;
   1405             /* Set the threshold for the port to max shaper rate */
   1406             rv = soc_kt_cosq_max_bucket_set(unit, port, index,
   1407                                             _SOC_KT_COSQ_NODE_LEVEL_ROOT);
   1408             if (SOC_FAILURE(rv)) {
   1409                 sal_free(buffer);
   1410                 goto _ka_freeze_abort;
   1411             }
   1412 
   1413             /* L0, L1, L2 meter */
   1414             for (lvl = 0; lvl < 3; lvl++) {
   1415                 idx = upper_flag = 0;
   1416                 prev_idx = prev_upper_flag = -1;
   1417                 blk_size = (lvl == 2) ? 8: ((lvl ==1)? 4:1);
   1418                 bmap = bmap_list[lvl];
   1419                 word_count = wdc[lvl];
   1420                 for (word = 0; word < word_count; word++) {
   1421                     if (bmap[word] == 0) {
   1422                         continue;
   1423                     }
   1424                     for (bit = 0; bit < SHR_BITWID; bit++) {
   1425                         if (!(bmap[word] & (1 << bit))) {
   1426                             continue;
   1427                         }
   1428                         index = word * SHR_BITWID + bit;
   1429                         idx = index / blk_size;
   1430 
   1431                         for (j = 0; j < 2; j++) {
   1432                             mem = cfg_mems[lvl][j];
   1433                             if (lvl == 2) {
   1434                                 if ((index % 8) >= 4) {
   1435                                   mem = cfg_mems[lvl+1][j];
   1436                                   upper_flag = 1;
   1437                                 } else {
   1438                                   upper_flag = 0;
   1439                                 }
   1440                             }
   1441 
   1442                             /* Store the Threshold MIN/MAX table entries only
   1443                              * once per table index as for the
   1444                              * next consecutive L1/L2 indices falling on
   1445                              * to the same table index need not be stored
   1446                              */
   1447                             if ((prev_idx != idx) ||
   1448                               ((lvl == 2) && (prev_upper_flag != upper_flag))) {
   1449                                 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, idx,
   1450                                                   &buffer[count].entry);
   1451                                 if (SOC_FAILURE(rv)) {
   1452                                     sal_free(buffer);
   1453                                     goto _ka_freeze_abort;
   1454                                 }
   1455                                 buffer[count].mem = mem;
   1456                                 buffer[count].index = idx;
   1457                                 count++;
   1458                             }
   1459 
   1460                             if (lvl == 2){
   1461                                 /* Set the  MIN/MAX thresholds for L2 node
   1462                                  * to 2 Kbps
   1463                                  */
   1464                                 mant=1;
   1465                                 /* For 56440_A0 minimum and maximum shapers
   1466                                  * should be programmed to use a common value
   1467                                  * for C_MIN_CYCLE_SEL and C_MAX_CYCLE_SEL
   1468                                  * fields and the recommended value is 0x0.
   1469                                  */
   1470                                 soc_cm_get_id(unit, &dev_id, &rev_id);
   1471                                 cycle = (rev_id == BCM56440_A0_REV_ID) ? 0 : 4;
   1472                                 f_idx = (j * 4) + (index % 4);
   1473                                 sal_memset(entry, 0, (sizeof(uint32) * SOC_MAX_MEM_WORDS));
   1474                                 rv = soc_mem_read(unit, mem, MEM_BLOCK_ALL,
   1475                                                       idx, &entry);
   1476                                 if (SOC_FAILURE(rv)) {
   1477                                     sal_free(buffer);
   1478                                     goto _ka_freeze_abort;
   1479                                 }
   1480 
   1481                                 soc_mem_field32_set(unit, mem, &entry,
   1482                                      rate_mant_fields[f_idx], mant);
   1483                                 soc_mem_field32_set(unit, mem, &entry,
   1484                                      rate_exp_fields[f_idx], 0);
   1485                                 soc_mem_field32_set(unit, mem, &entry,
   1486                                      burst_exp_fields[f_idx], 0);
   1487                                 soc_mem_field32_set(unit, mem, &entry,
   1488                                      burst_mant_fields[f_idx], 0);
   1489                                 soc_mem_field32_set(unit, mem, &entry,
   1490                                      cycle_sel_fields[f_idx], cycle);
   1491                                 rv = soc_mem_write(unit, mem, MEM_BLOCK_ANY,
   1492                                                    idx, &entry);
   1493                             } else if ((lvl != 2) && (j == 1)) {
   1494                                 /* Set the MIN/MAX thresholds for L0/L1 node
   1495                                  * to max shaper rate
   1496                                  */
   1497                                 rv = soc_kt_cosq_max_bucket_set(unit, port,
   1498                                                                 index, (lvl + 1));
   1499                             }
   1500                             if (SOC_FAILURE(rv)) {
   1501                                 sal_free(buffer);
   1502                                 goto _ka_freeze_abort;
   1503                             }
   1504                         }/*END of for j */
   1505                         prev_idx = idx;
   1506                         prev_upper_flag = upper_flag;
   1507                     } /* END of the valid bit */
   1508                 } /* END of the word */
   1509             } /* END of lvl */
   1510 
   1511             buffer[count].mem = INVALIDm;
   1512             *setting = buffer;
   1513 _ka_freeze_abort:
   1514             break;
   1515         }
   1516 #endif /* BCM_KATANA_SUPPORT */
   1517 #ifdef BCM_KATANA2_SUPPORT
   1518     case SOC_CHIP_BCM56450:
   1519         {
   1520             soc_mem_t mem;
   1521             uint32 *bmap, *bmap_list[6];
   1522             int word_count, wdc[6], blk_size=0;
   1523             int lvl, j, index, word, bit, index_count, count;
   1524             int idx, upper_flag = 0;
   1525             int prev_idx, prev_upper_flag;
   1526             mem_entry_t *buffer;
   1527             uint32 mant = 0, cycle = 0 , f_idx;
   1528             uint32 entry[SOC_MAX_MEM_WORDS];
   1529             uint32 lvl_count = 0;
   1530             uint32 min = 0;  
   1531             uint32 exp = 0 ;
   1532             uint32 sched_mode = 0; 
   1533             int wt = 0 ;
   1534             uint32 burst_mant = 0; 
   1535             uint32 burst_exp = 0; 
   1536             soc_info_t *si;
   1537             static const soc_mem_t parent_mems[] = {
   1538                0,
   1539                LLS_L0_PARENTm,
   1540                LLS_L0_PARENTm,
   1541                LLS_L0_PARENTm,
   1542                LLS_L1_PARENTm,
   1543                LLS_L2_PARENTm
   1544             };
   1545 
   1546             static const soc_mem_t cfg_mems[][2] = {
   1547                 { LLS_PORT_SHAPER_CONFIG_Cm, INVALIDm },
   1548                 { LLS_S0_SHAPER_CONFIG_Cm, INVALIDm },
   1549                 { LLS_S1_SHAPER_CONFIG_Cm, INVALIDm },
   1550                 { LLS_L0_SHAPER_CONFIG_Cm, LLS_L0_MIN_CONFIG_Cm },
   1551                 { LLS_L1_SHAPER_CONFIG_Cm, LLS_L1_MIN_CONFIG_Cm },
   1552                 { LLS_L2_SHAPER_CONFIG_LOWERm, LLS_L2_MIN_CONFIG_LOWER_Cm },
   1553                 { LLS_L2_SHAPER_CONFIG_UPPERm, LLS_L2_MIN_CONFIG_UPPER_Cm },
   1554             };
   1555 
   1556             static const soc_field_t rate_mant_fields[] = {
   1557                C_MAX_REF_RATE_MANT_0f, C_MAX_REF_RATE_MANT_1f,
   1558                C_MAX_REF_RATE_MANT_2f, C_MAX_REF_RATE_MANT_3f,
   1559                C_MIN_REF_RATE_MANT_0f, C_MIN_REF_RATE_MANT_1f,
   1560                C_MIN_REF_RATE_MANT_2f, C_MIN_REF_RATE_MANT_3f
   1561             };
   1562 
   1563             static const soc_field_t rate_exp_fields[] = {
   1564                C_MAX_REF_RATE_EXP_0f, C_MAX_REF_RATE_EXP_1f,
   1565                C_MAX_REF_RATE_EXP_2f, C_MAX_REF_RATE_EXP_3f,
   1566                C_MIN_REF_RATE_EXP_0f, C_MIN_REF_RATE_EXP_1f,
   1567                C_MIN_REF_RATE_EXP_2f, C_MIN_REF_RATE_EXP_3f
   1568             };
   1569             static const soc_field_t burst_exp_fields[] = {
   1570                C_MAX_THLD_EXP_0f, C_MAX_THLD_EXP_1f,
   1571                C_MAX_THLD_EXP_2f, C_MAX_THLD_EXP_3f,
   1572                C_MIN_THLD_EXP_0f, C_MIN_THLD_EXP_1f,
   1573                C_MIN_THLD_EXP_2f, C_MIN_THLD_EXP_3f
   1574             };
   1575             static const soc_field_t burst_mant_fields[] = {
   1576                C_MAX_THLD_MANT_0f, C_MAX_THLD_MANT_1f,
   1577                C_MAX_THLD_MANT_2f, C_MAX_THLD_MANT_3f,
   1578                C_MIN_THLD_MANT_0f, C_MIN_THLD_MANT_1f,
   1579                C_MIN_THLD_MANT_2f, C_MIN_THLD_MANT_3f
   1580             };
   1581 
   1582             static const soc_field_t cycle_sel_fields[] = {
   1583                 C_MAX_CYCLE_SEL_0f, C_MAX_CYCLE_SEL_1f,
   1584                 C_MAX_CYCLE_SEL_2f, C_MAX_CYCLE_SEL_3f,
   1585                 C_MIN_CYCLE_SEL_0f, C_MIN_CYCLE_SEL_1f,
   1586                 C_MIN_CYCLE_SEL_2f, C_MIN_CYCLE_SEL_3f
   1587             };
   1588 
   1589             bmap_list[0] = NULL;
   1590             bmap_list[1] = SOC_CONTROL(unit)->port_lls_s0_bmap[port];
   1591             bmap_list[2] = SOC_CONTROL(unit)->port_lls_s1_bmap[port];
   1592             bmap_list[3] = SOC_CONTROL(unit)->port_lls_l0_bmap[port];
   1593             bmap_list[4] = SOC_CONTROL(unit)->port_lls_l1_bmap[port];
   1594             bmap_list[5] = SOC_CONTROL(unit)->port_lls_l2_bmap[port];
   1595 
   1596             si = &SOC_INFO(unit);
   1597             /*
   1598              * On KTX we can have both s0 and s1 node or only
   1599              * s1 node but can not have only s0 node
   1600              */
   1601             bmap = bmap_list[2];
   1602             index_count = _SOC_KT2_COSQ_MAX_INDEX_S1;
   1603             word_count = _SHR_BITDCLSIZE(index_count);
   1604             for (word = 0; word < word_count; word++) {
   1605                  if (bmap[word] != 0) {
   1606                      break;
   1607                  }
   1608             }
   1609             if (word == word_count) {
   1610                /* s1 list is zero */
   1611                bmap =  bmap_list[1];
   1612                index_count = _SOC_KT2_COSQ_MAX_INDEX_S0;
   1613                word_count = _SHR_BITDCLSIZE(index_count);
   1614                for (word = 0; word < word_count; word++) {
   1615                     if (bmap[word] != 0) {
   1616                         break;
   1617                     }
   1618                }
   1619                if (word < word_count) {
   1620                    /* s0 list is non zero */
   1621                    /* swap  s0 ans s1 list */
   1622                    bmap = bmap_list[2];
   1623                    bmap_list[2] = bmap_list[1];
   1624                    bmap_list[1] = bmap;
   1625                }
   1626             }
   1627             count = 0;
   1628             /* Count the number of the valid Root,S0,S1
   1629              * L0/L1/L2 entries per port.
   1630              * To allocate the buffer to store the Min, Max shaper
   1631              * entries for the valid indices
   1632              */
   1633             for (lvl = 0; lvl < _SOC_KT2_COSQ_NODE_LVL_MAX; lvl++) {
   1634                 lvl_count = 0;
   1635                 if (lvl == _SOC_KT2_COSQ_NODE_LVL_ROOT) {
   1636                     /* Port entry */
   1637                     lvl_count = 1;
   1638                     wdc[lvl] = 0;
   1639                 } else {
   1640                     bmap = bmap_list[lvl];
   1641                     mem = parent_mems[lvl];
   1642                     index_count = soc_mem_index_count(unit, mem);
   1643 
   1644                     if (lvl == _SOC_KT2_COSQ_NODE_LVL_S0) {
   1645                         index_count = _SOC_KT2_COSQ_MAX_INDEX_S0;
   1646                     } else
   1647                     if (lvl == _SOC_KT2_COSQ_NODE_LVL_S1) {
   1648                         index_count =_SOC_KT2_COSQ_MAX_INDEX_S1;
   1649                     }
   1650                     wdc[lvl] = _SHR_BITDCLSIZE(index_count);
   1651                     word_count = wdc[lvl];
   1652 
   1653                     for (word = 0; word < word_count; word++) {
   1654                         if (bmap[word] != 0) {
   1655                             lvl_count += _shr_popcount(bmap[word]);
   1656                         }
   1657                     }
   1658                     if (lvl >= _SOC_KT2_COSQ_NODE_LVL_L0) {
   1659                         /* for MIN/MAX  shaper config */
   1660                         /* count allocation is based on worst case
   1661                          * estimate that entries might fall into different
   1662                          * table entries
   1663                          */
   1664                         lvl_count = (lvl_count * 2);
   1665                     }
   1666                 }
   1667                 count += lvl_count;
   1668             }
   1669             count = count + 1;
   1670 
   1671 
   1672             buffer = sal_alloc((count + 1) * sizeof(mem_entry_t),
   1673                           "shaper buffer");
   1674 
   1675             if (buffer == NULL) {
   1676                 rv = SOC_E_MEMORY;
   1677                 goto _ka2_freeze_abort;
   1678             }
   1679             count = 0;
   1680             /* port */
   1681             mem = LLS_PORT_SHAPER_CONFIG_Cm;
   1682             index = port & 0x3f;
   1683 
   1684             /* Save the entry */
   1685             rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, index,
   1686                               &buffer[count].entry);
   1687             if (SOC_FAILURE(rv)) {
   1688                 sal_free(buffer);
   1689                 goto _ka2_freeze_abort;
   1690             }
   1691             buffer[count].mem = mem;
   1692             buffer[count].index = index;
   1693             count++;
   1694 
   1695             /* Set the threshold for the port to max shaper rate */
   1696             rv = soc_kt2_cosq_max_bucket_set(unit, port, index,
   1697                                             _SOC_KT2_COSQ_NODE_LVL_ROOT);
   1698             if (SOC_FAILURE(rv)) {
   1699                 sal_free(buffer);
   1700                 goto _ka2_freeze_abort;
   1701             }
   1702 
   1703             /* S0, S1, L0, L1, L2 meter */
   1704             for (lvl = _SOC_KT2_COSQ_NODE_LVL_S0;
   1705                  lvl < _SOC_KT2_COSQ_NODE_LVL_MAX; lvl++) {
   1706                 idx = upper_flag = 0;
   1707                 prev_idx = prev_upper_flag = -1;
   1708                 blk_size = ((lvl == _SOC_KT2_COSQ_NODE_LVL_L2) ? 8:
   1709                             ((lvl == _SOC_KT2_COSQ_NODE_LVL_L1)? 4: 1));
   1710                 bmap = bmap_list[lvl];
   1711                 word_count = wdc[lvl];
   1712                 for (word = 0; word < word_count; word++) {
   1713                     if (bmap[word] == 0) {
   1714                         continue;
   1715                     }
   1716                     for (bit = 0; bit < SHR_BITWID; bit++) {
   1717                         if (!(bmap[word] & (1 << bit))) {
   1718                             continue;
   1719                         }
   1720                         index = word * SHR_BITWID + bit;
   1721                         idx = index / blk_size;
   1722 
   1723                         for (j = 0; j < 2; j++) {
   1724                             mem = cfg_mems[lvl][j];
   1725 
   1726                             if (mem == INVALIDm) {
   1727                                 continue;
   1728                             }
   1729 
   1730                             if (lvl == _SOC_KT2_COSQ_NODE_LVL_L2) {
   1731                                 if ((index % 8) >= 4) {
   1732                                   mem = cfg_mems[lvl+1][j];
   1733                                   upper_flag = 1;
   1734                                 } else {
   1735                                   upper_flag = 0;
   1736                                 }
   1737                             }
   1738 
   1739                             /* Store the Threshold MIN/MAX table entries only
   1740                              * once per table index as for the
   1741                              * next consecutive L1/L2 indices falling on
   1742                              * to the same table index need not be stored
   1743                              */
   1744                             if ((prev_idx != idx) ||
   1745                                 ((lvl == _SOC_KT2_COSQ_NODE_LVL_L2) &&
   1746                                 (prev_upper_flag != upper_flag))) {
   1747                                 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, idx,
   1748                                                   &buffer[count].entry);
   1749                                 if (SOC_FAILURE(rv)) {
   1750                                     sal_free(buffer);
   1751                                     goto _ka2_freeze_abort;
   1752                                 }
   1753                                 buffer[count].mem = mem;
   1754                                 buffer[count].index = idx;
   1755                                 count++;
   1756                             }
   1757 
   1758                             if (lvl == _SOC_KT2_COSQ_NODE_LVL_L2){
   1759                                 if (SOC_PBMP_MEMBER(si->linkphy_pbm, port)) {
   1760                                     /* coverity[leaked_storage] */ 
   1761                                     rv = soc_kt2_cosq_get_sched_mode(unit, port, lvl,
   1762                                                     index, &sched_mode, &wt);
   1763                                 } else {
   1764                                     /* coverity[leaked_storage] */ 
   1765                                     /* coverity[resource_leak : FALSE] */
   1766                                     rv = soc_kt2_cosq_get_sched_mode(unit, port, lvl - 2,
   1767                                                     index, &sched_mode, &wt);
   1768                                 }
   1769                                 if (SOC_FAILURE(rv)) {
   1770                                     sal_free(buffer);
   1771                                     goto _ka2_freeze_abort;
   1772                                 }
   1773 
   1774                                 if ( sched_mode == BCM_COSQ_STRICT ) 
   1775                                 {
   1776                                      rv = _soc_kt2_cosq_min_bucket_get(unit, port,
   1777                                                                   index, lvl,
   1778                                                                   &min, &mant,
   1779                                                                   &exp, &cycle);
   1780                                      if (SOC_FAILURE(rv)) {
   1781                                         sal_free(buffer);
   1782                                         goto _ka2_freeze_abort;
   1783                                      }
   1784                                      if (min) { 
   1785                                           if (exp != 0) {
   1786                                               if (exp < 10) {
   1787                                                   burst_exp = 5;
   1788                                                   burst_mant = 0;
   1789                                               } else {
   1790                                                   burst_exp = exp - 4;
   1791                                                   burst_mant = (mant >> 3);
   1792                                               }
   1793                                            }
   1794                                            else { 
   1795                                            burst_mant = 0;
   1796                                            burst_exp = 0;
   1797                                            } 
   1798                                      }
   1799                                 }
   1800                                 if (!min) 
   1801                                 {
   1802                                   /* Set the  MIN/MAX thresholds for L2 node
   1803                                    * to 2 Kbps
   1804                                    */
   1805                                   mant = 1;
   1806                                   cycle = 4;
   1807                                   exp = 0; 
   1808                                 }
   1809                                 f_idx = (j * 4) + (index % 4);
   1810                                 sal_memset(entry, 0, (sizeof(uint32) * SOC_MAX_MEM_WORDS));
   1811                                 rv = soc_mem_read(unit, mem, MEM_BLOCK_ALL,
   1812                                                     idx, &entry);
   1813                                 if (SOC_FAILURE(rv)) {
   1814                                     sal_free(buffer);
   1815                                     goto _ka2_freeze_abort;
   1816                                 }
   1817 
   1818                                 soc_mem_field32_set(unit, mem, &entry,
   1819                                      rate_mant_fields[f_idx], mant);
   1820                                 soc_mem_field32_set(unit, mem, &entry,
   1821                                      rate_exp_fields[f_idx], exp);
   1822                                 soc_mem_field32_set(unit, mem, &entry,
   1823                                      burst_exp_fields[f_idx], burst_exp);
   1824                                 soc_mem_field32_set(unit, mem, &entry,
   1825                                    burst_mant_fields[f_idx], burst_mant);
   1826                                 soc_mem_field32_set(unit, mem, &entry,
   1827                                      cycle_sel_fields[f_idx], cycle);
   1828                                 rv = soc_mem_write(unit, mem, MEM_BLOCK_ANY,
   1829                                                  idx, &entry);
   1830                                  min = 0;
   1831                                  sched_mode = 0; 
   1832                                  cycle = 0;
   1833                                  exp = 0; 
   1834                                  mant = 0;
   1835                                  burst_exp = 0;
   1836                                  burst_mant = 0;
   1837                               } else if (((lvl >= _SOC_KT2_COSQ_NODE_LVL_L0) && (j == 1)) ||
   1838                                        (lvl < _SOC_KT2_COSQ_NODE_LVL_L0)) {
   1839                                 /* Set the MIN/MAX thresholds for L0/L1 node
   1840                                  * to max shaper rate
   1841                                  */
   1842                                 rv = soc_kt2_cosq_max_bucket_set(unit, port,
   1843                                                                 index, lvl);
   1844                             }
   1845                             if (SOC_FAILURE(rv)) {
   1846                                 sal_free(buffer);
   1847                                 goto _ka2_freeze_abort;
   1848                             }
   1849                         }/*END of for j */
   1850                         prev_idx = idx;
   1851                         prev_upper_flag = upper_flag;
   1852                     } /* END of the valid bit */
   1853                 } /* END of the word */
   1854             } /* END of lvl */
   1855 
   1856             buffer[count].mem = INVALIDm;
   1857             *setting = buffer;
   1858 _ka2_freeze_abort:
   1859             break;
   1860         }
   1861 #endif /* BCM_KATANA2_SUPPORT */
   1862 #ifdef BCM_SABER2_SUPPORT
   1863     case SOC_CHIP_BCM56260:
   1864     case SOC_CHIP_BCM56270:
   1865         {
   1866             soc_mem_t mem;
   1867             uint32 *bmap, *bmap_list[6];
   1868             int word_count, wdc[6], blk_size=0;
   1869             int lvl, j, index, word, bit, index_count, count;
   1870             int idx;
   1871             int prev_idx;
   1872             mem_entry_t *buffer;
   1873             uint32 mant=0, cycle=0, f_idx;
   1874             uint32 entry[SOC_MAX_MEM_WORDS];
   1875             uint32 lvl_count = 0;
   1876             uint32 min = 0;
   1877             uint32 exp = 0;
   1878             uint32 sched_mode = 0;
   1879             int wt = 0;
   1880             uint32 burst_mant = 0;
   1881             uint32 burst_exp = 0;
   1882             soc_info_t *si;
   1883 
   1884             static const soc_mem_t parent_mems[] = {
   1885                0,
   1886                LLS_L0_PARENTm,
   1887                LLS_L0_PARENTm,
   1888                LLS_L0_PARENTm,
   1889                LLS_L1_PARENTm,
   1890                LLS_L2_PARENTm
   1891             };
   1892 
   1893             static const soc_mem_t cfg_mems[][2] = {
   1894                 { LLS_PORT_SHAPER_CONFIG_Cm, INVALIDm },
   1895                 { LLS_S0_SHAPER_CONFIG_Cm, INVALIDm },
   1896                 { LLS_S1_SHAPER_CONFIG_Cm, INVALIDm },
   1897                 { LLS_L0_SHAPER_CONFIG_Cm, LLS_L0_MIN_CONFIG_Cm },
   1898                 { LLS_L1_SHAPER_CONFIG_Cm, LLS_L1_MIN_CONFIG_Cm },
   1899                 { LLS_L2_SHAPER_CONFIG_Cm, LLS_L2_MIN_CONFIG_Cm },
   1900             };
   1901             static const soc_field_t rate_mant_fields[] = {
   1902                 C_MAX_REF_RATE_MANT_0f, C_MAX_REF_RATE_MANT_1f,
   1903                 C_MAX_REF_RATE_MANT_2f, C_MAX_REF_RATE_MANT_3f,
   1904                 C_MIN_REF_RATE_MANT_0f, C_MIN_REF_RATE_MANT_1f,
   1905                 C_MIN_REF_RATE_MANT_2f, C_MIN_REF_RATE_MANT_3f
   1906             };
   1907 
   1908             static const soc_field_t rate_exp_fields[] = {
   1909                 C_MAX_REF_RATE_EXP_0f, C_MAX_REF_RATE_EXP_1f,
   1910                 C_MAX_REF_RATE_EXP_2f, C_MAX_REF_RATE_EXP_3f,
   1911                 C_MIN_REF_RATE_EXP_0f, C_MIN_REF_RATE_EXP_1f,
   1912                 C_MIN_REF_RATE_EXP_2f, C_MIN_REF_RATE_EXP_3f
   1913             };
   1914             static const soc_field_t burst_exp_fields[] = {
   1915                 C_MAX_THLD_EXP_0f, C_MAX_THLD_EXP_1f,
   1916                 C_MAX_THLD_EXP_2f, C_MAX_THLD_EXP_3f,
   1917                 C_MIN_THLD_EXP_0f, C_MIN_THLD_EXP_1f,
   1918                 C_MIN_THLD_EXP_2f, C_MIN_THLD_EXP_3f
   1919             };
   1920             static const soc_field_t burst_mant_fields[] = {
   1921                 C_MAX_THLD_MANT_0f, C_MAX_THLD_MANT_1f,
   1922                 C_MAX_THLD_MANT_2f, C_MAX_THLD_MANT_3f,
   1923                 C_MIN_THLD_MANT_0f, C_MIN_THLD_MANT_1f,
   1924                 C_MIN_THLD_MANT_2f, C_MIN_THLD_MANT_3f
   1925             };
   1926 
   1927             static const soc_field_t cycle_sel_fields[] = {
   1928                 C_MAX_CYCLE_SEL_0f, C_MAX_CYCLE_SEL_1f,
   1929                 C_MAX_CYCLE_SEL_2f, C_MAX_CYCLE_SEL_3f,
   1930                 C_MIN_CYCLE_SEL_0f, C_MIN_CYCLE_SEL_1f,
   1931                 C_MIN_CYCLE_SEL_2f, C_MIN_CYCLE_SEL_3f
   1932             };
   1933 
   1934             si = &SOC_INFO(unit);
   1935 
   1936             bmap_list[0] = NULL;
   1937             bmap_list[1] = SOC_CONTROL(unit)->port_lls_s0_bmap[port];
   1938             bmap_list[2] = SOC_CONTROL(unit)->port_lls_s1_bmap[port];
   1939             bmap_list[3] = SOC_CONTROL(unit)->port_lls_l0_bmap[port];
   1940             bmap_list[4] = SOC_CONTROL(unit)->port_lls_l1_bmap[port];
   1941             bmap_list[5] = SOC_CONTROL(unit)->port_lls_l2_bmap[port];
   1942             /* 
   1943              * On KTX we can have both s0 and s1 node or only 
   1944              * s1 node but can not have only s0 node 
   1945              */
   1946             bmap = bmap_list[2];
   1947             index_count = soc_mem_index_count(unit, parent_mems[2]);
   1948             word_count = _SHR_BITDCLSIZE(index_count);
   1949             for (word = 0; word < word_count; word++) {
   1950                  if (bmap[word] != 0) {
   1951                      break;
   1952                  }
   1953             }
   1954             if (word == word_count) {
   1955                /* s1 list is zero */
   1956                bmap =  bmap_list[1];
   1957                for (word = 0; word < word_count; word++) {
   1958                     if (bmap[word] != 0) {
   1959                         break;
   1960                     }
   1961                }
   1962                if (word < word_count) {
   1963                    /* s0 list is non zero */
   1964                    /* swap  s0 ans s1 list */
   1965                    bmap = bmap_list[2];
   1966                    bmap_list[2] = bmap_list[1];
   1967                    bmap_list[1] = bmap;
   1968                }
   1969             } 
   1970             count = 0;
   1971             /* Count the number of the valid Root,S0,S1
   1972              * L0/L1/L2 entries per port.
   1973              * To allocate the buffer to store the Min, Max shaper
   1974              * entries for the valid indices
   1975              */
   1976             for (lvl = 0; lvl < _SOC_KT2_COSQ_NODE_LVL_MAX; lvl++) {
   1977                 lvl_count = 0;
   1978                 if (lvl == _SOC_KT2_COSQ_NODE_LVL_ROOT) {
   1979                     /* Port entry */
   1980                     lvl_count = 1;
   1981                     wdc[lvl] = 0;
   1982                 } else {
   1983                     bmap = bmap_list[lvl];
   1984                     mem = parent_mems[lvl];
   1985                     index_count = soc_mem_index_count(unit, mem);
   1986                     if (lvl == _SOC_KT2_COSQ_NODE_LVL_S0) {
   1987                         index_count = _SOC_SB2_COSQ_MAX_INDEX_S0;
   1988                     }
   1989                     wdc[lvl] = _SHR_BITDCLSIZE(index_count);
   1990                     word_count = wdc[lvl];
   1991 
   1992                     for (word = 0; word < word_count; word++) {
   1993                         if (bmap[word] != 0) {
   1994                             lvl_count += _shr_popcount(bmap[word]);
   1995                         }
   1996                     }
   1997                     if (lvl >= _SOC_KT2_COSQ_NODE_LVL_L0) {
   1998                         /* for MIN/MAX  shaper config */
   1999                         /* count allocation is based on worst case
   2000                          * estimate that entries might fall into different
   2001                          * table entries
   2002                          */
   2003                         lvl_count = (lvl_count * 2);
   2004                     }
   2005                 }
   2006                 count += lvl_count;
   2007             }
   2008             count = count + 1;
   2009 
   2010 
   2011             buffer = sal_alloc((count + 1) * sizeof(mem_entry_t),
   2012                           "shaper buffer");
   2013 
   2014             if (buffer == NULL) {
   2015                 rv = SOC_E_MEMORY;
   2016                 break;
   2017             }
   2018             count = 0;
   2019             /* port */
   2020             mem = LLS_PORT_SHAPER_CONFIG_Cm;
   2021             index = port & 0x1f;
   2022 
   2023             /* Save the entry */
   2024             rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, index,
   2025                               &buffer[count].entry);
   2026             if (SOC_FAILURE(rv)) {
   2027                 sal_free(buffer);
   2028                 break;
   2029             }
   2030             buffer[count].mem = mem;
   2031             buffer[count].index = index;
   2032             count++;
   2033 
   2034             /* Set the threshold for the port to max shaper rate */
   2035             rv = soc_sb2_cosq_max_bucket_set(unit, port, index,
   2036                                             _SOC_KT2_COSQ_NODE_LVL_ROOT);
   2037             if (SOC_FAILURE(rv)) {
   2038                 sal_free(buffer);
   2039                 break;
   2040             }
   2041 
   2042             /* S0, S1, L0, L1, L2 meter */
   2043             for (lvl = _SOC_KT2_COSQ_NODE_LVL_S0;
   2044                  lvl < _SOC_KT2_COSQ_NODE_LVL_MAX; lvl++) {
   2045                 idx = 0;
   2046                 prev_idx = -1;
   2047                 blk_size = ((lvl == _SOC_KT2_COSQ_NODE_LVL_L2) ? 4: 1);
   2048                 bmap = bmap_list[lvl];
   2049                 word_count = wdc[lvl];
   2050                 for (word = 0; word < word_count; word++) {
   2051                     if (bmap[word] == 0) {
   2052                         continue;
   2053                     }
   2054                     for (bit = 0; bit < SHR_BITWID; bit++) {
   2055                         if (!(bmap[word] & (1 << bit))) {
   2056                             continue;
   2057                         }
   2058                         index = word * SHR_BITWID + bit;
   2059                         idx = index / blk_size;
   2060                         if ((lvl == _SOC_KT2_COSQ_NODE_LVL_S0) &&
   2061                             (idx >=  _SOC_SB2_COSQ_MAX_INDEX_S0)) {
   2062                             continue;
   2063                         }
   2064 
   2065                         for (j = 0; j < 2; j++) {
   2066                             mem = cfg_mems[lvl][j];
   2067 
   2068                             if (mem == INVALIDm || (!SOC_MEM_IS_VALID(unit, mem))) {
   2069                                 continue;
   2070                             }
   2071 
   2072                             /* Store the Threshold MIN/MAX table entries only
   2073                              * once per table index as for the
   2074                              * next consecutive L1/L2 indices falling on
   2075                              * to the same table index need not be stored
   2076                              */
   2077                             if (prev_idx != idx) { 
   2078                                 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, idx,
   2079                                                   &buffer[count].entry);
   2080                                 if (SOC_FAILURE(rv)) {
   2081                                     sal_free(buffer);
   2082                                     goto _sb2_freeze_abort;
   2083                                 }
   2084                                 buffer[count].mem = mem;
   2085                                 buffer[count].index = idx;
   2086                                 count++;
   2087                             }
   2088 
   2089                             if (lvl == _SOC_KT2_COSQ_NODE_LVL_L2){
   2090                                 /* Set the  MIN/MAX thresholds for L2 node
   2091                                  * to 2 Kbps
   2092                                  */
   2093                                 if (SOC_PBMP_MEMBER(si->linkphy_pbm, port)) {
   2094                                     rv = soc_kt2_cosq_get_sched_mode(unit, port,
   2095                                                lvl, index, &sched_mode, &wt);
   2096                                 } else {
   2097                                     rv = soc_kt2_cosq_get_sched_mode(unit, port,
   2098                                                lvl - 2, index, &sched_mode, &wt);
   2099                                 }
   2100                                 if (SOC_FAILURE(rv)) {
   2101                                     sal_free(buffer);
   2102                                     return rv;
   2103                                 }
   2104                                 if ( sched_mode == BCM_COSQ_STRICT )
   2105                                 {
   2106                                      rv = soc_sb2_cosq_min_bucket_get(unit, port,
   2107                                                                   index, lvl,
   2108                                                                   &min, &mant,
   2109                                                                   &exp, &cycle);
   2110                                      if (SOC_FAILURE(rv)) {
   2111                                         sal_free(buffer);
   2112                                         goto _sb2_freeze_abort;
   2113                                      }
   2114                                      if (min) {
   2115                                           if (exp != 0) {
   2116                                               if (exp < 10) {
   2117                                                   burst_exp = 5;
   2118                                                   burst_mant = 0;
   2119                                               } else {
   2120                                                   burst_exp = exp - 4;
   2121                                                   burst_mant = (mant >> 3);
   2122                                               }
   2123                                            }
   2124                                            else { 
   2125                                            burst_mant = 0;
   2126                                            burst_exp = 0;
   2127                                            } 
   2128                                      }
   2129                                 }
   2130                                 if (!min)
   2131                                 {
   2132                                   /* Set the  MIN/MAX thresholds for L2 node
   2133                                    * to 2 Kbps
   2134                                    */
   2135                                   mant = 1;
   2136                                   cycle = 4;
   2137                                   exp = 0;
   2138                                 }
   2139                                 f_idx = (j * 4) + index % 4;
   2140                                 sal_memset(entry, 0, (sizeof(uint32) * SOC_MAX_MEM_WORDS));
   2141                                 rv = soc_mem_read(unit, mem, MEM_BLOCK_ALL,
   2142                                                       idx, &entry);
   2143                                 if (SOC_FAILURE(rv)) {
   2144                                     sal_free(buffer);
   2145                                     goto _sb2_freeze_abort;
   2146                                 }
   2147                                 soc_mem_field32_set(unit, mem, &entry,
   2148                                      rate_mant_fields[f_idx], mant);
   2149                                 soc_mem_field32_set(unit, mem, &entry,
   2150                                      rate_exp_fields[f_idx], exp);
   2151                                 soc_mem_field32_set(unit, mem, &entry,
   2152                                      burst_exp_fields[f_idx], burst_exp);
   2153                                 soc_mem_field32_set(unit, mem, &entry,
   2154                                      burst_mant_fields[f_idx], burst_mant);
   2155                                 soc_mem_field32_set(unit, mem, &entry,
   2156                                      cycle_sel_fields[f_idx], cycle);
   2157                                 rv = soc_mem_write(unit, mem, MEM_BLOCK_ANY,
   2158                                                    idx, &entry);
   2159                                  min = 0;
   2160                                  sched_mode = 0;
   2161                                  cycle = 0;
   2162                                  exp = 0;
   2163                                  mant = 0;
   2164                                  burst_exp = 0;
   2165                                  burst_mant = 0;
   2166                             } else if (((lvl >= _SOC_KT2_COSQ_NODE_LVL_L0) && (j == 1)) ||
   2167                                        (lvl < _SOC_KT2_COSQ_NODE_LVL_L0)) {
   2168                                 /* Set the MIN/MAX thresholds for L0/L1 node
   2169                                  * to max shaper rate
   2170                                  */
   2171                                 rv = soc_sb2_cosq_max_bucket_set(unit, port,
   2172                                                                 index, lvl);
   2173                             }
   2174                             if (SOC_FAILURE(rv)) {
   2175                                 sal_free(buffer);
   2176                                 goto _sb2_freeze_abort;
   2177                             }
   2178                         }/*END of for j */
   2179                         prev_idx = idx;
   2180                     } /* END of the valid bit */
   2181                 } /* END of the word */
   2182             } /* END of lvl */
   2183 
   2184             buffer[count].mem = INVALIDm;
   2185             *setting = buffer;
   2186 _sb2_freeze_abort:
   2187             break;
   2188         }
   2189 #endif /* BCM_SABER2_SUPPORT */
   2190 #ifdef BCM_TRIDENT3_SUPPORT
   2191     case SOC_CHIP_BCM56870:
   2192     case SOC_CHIP_BCM56370:
   2193     case SOC_CHIP_BCM56770:
   2194         {
   2195             uint64 rval64;
   2196             uint64 *buffer;
   2197             uint64 pbits64;
   2198             int pipe;
   2199             int split, pos;
   2200             soc_reg_t mtro_reg;
   2201             soc_reg_t reg_mtro[2] = {MTRO_PORT_ENTITY_DISABLE_SPLIT0r,
   2202                                      MTRO_PORT_ENTITY_DISABLE_SPLIT1r};
   2203 
   2204             COMPILER_64_ZERO(rval64);
   2205             COMPILER_64_ZERO(pbits64);
   2206 
   2207             SOC_IF_ERROR_RETURN(
   2208                 soc_td3_mmu_bmp_reg_pos_get(unit, port, &pipe, &split, &pos));
   2209             mtro_reg = reg_mtro[split];
   2210 
   2211             if (pos < 32) {
   2212                 COMPILER_64_SET(pbits64, 0, (1 << pos));
   2213             } else {
   2214                 COMPILER_64_SET(pbits64, (1 << (pos - 32)), 0);
   2215             }
   2216 
   2217             buffer = sal_alloc(sizeof(uint64), "MTRO status buffer");
   2218             if (buffer == NULL) {
   2219                 rv = SOC_E_MEMORY;
   2220                 break;
   2221             }
   2222             /* Disable Shaper Updates */
   2223             rv = soc_reg_get(unit, mtro_reg, pipe, 0, &rval64);
   2224             if (SOC_FAILURE(rv)) {
   2225                 sal_free(buffer);
   2226                 break;
   2227             }
   2228             COMPILER_64_COPY(*buffer, rval64);
   2229             COMPILER_64_AND(*buffer, pbits64);
   2230 
   2231             COMPILER_64_OR(rval64, pbits64);
   2232 
   2233             /* METERING_DISABLEf is the only field in reg. */
   2234             rv = soc_reg_set(unit, mtro_reg, pipe, 0, rval64);
   2235             if (SOC_FAILURE(rv)) {
   2236                 sal_free(buffer);
   2237                 break;
   2238             }
   2239 
   2240             *setting = buffer;
   2241             break;
   2242         }
   2243 #endif /* BCM_TRIDENT3_SUPPORT */
   2244     case SOC_CHIP_BCM56960: /* Use hardware flush */
   2245     case SOC_CHIP_BCM56965:
   2246     default:
   2247         break;
   2248     }
   2249 
   2250     if (SOC_FAILURE(rv)) {
   2251         /* UNLOCK if fail */
   2252         SOC_EGRESS_METERING_UNLOCK(unit);
   2253     }
   2254 
   2255     return rv;
   2256 }
   2257 
   2258 int
   2259 _soc_egress_metering_thaw(int unit, soc_port_t port, void *setting)
   2260 {
   2261     int       rv;
   2262 
   2263     if (setting == NULL) {
   2264         SOC_EGRESS_METERING_UNLOCK(unit);
   2265         return SOC_E_NONE;
   2266     }
   2267 
   2268     rv = SOC_E_NONE;
   2269 
   2270     switch (SOC_CHIP_GROUP(unit)) {
   2271 #if defined(BCM_RAVEN_SUPPORT) || defined(BCM_SCORPION_SUPPORT) || defined(BCM_HURRICANE_SUPPORT)
   2272     case SOC_CHIP_BCM56224:
   2273     case SOC_CHIP_BCM56820:
   2274     case SOC_CHIP_BCM56725:
   2275     case SOC_CHIP_BCM53314:
   2276     case SOC_CHIP_BCM56142:
   2277         {
   2278             uint32 *rval32;
   2279 
   2280             rval32 = setting;
   2281             /* Restore egress metering configuration. */
   2282             rv = WRITE_EGRMETERINGCONFIGr(unit, port, *rval32);
   2283             sal_free(setting);
   2284             break;
   2285         }
   2286 #endif /* BCM_RAVEN_SUPPORT || BCM_SCORPION_SUPPORT || BCM_HURRICANE_SUPPORT */
   2287 #if defined (BCM_HURRICANE2_SUPPORT)
   2288     case SOC_CHIP_BCM56150:
   2289     case SOC_CHIP_BCM53400:
   2290     case SOC_CHIP_BCM56160:
   2291     case SOC_CHIP_BCM53540:
   2292         {
   2293             int i;
   2294             uint32 *buffer = setting;
   2295             int count;
   2296             int err_flag = 0;
   2297  
   2298             /* restore the original configuration : MAXBUCKETCONFIGr */
   2299             count = 0;
   2300             for (i = 0; i < SOC_REG_NUMELS(unit, MAXBUCKETCONFIGr); i++) {
   2301                 rv = WRITE_MAXBUCKETCONFIGr(unit, port, i, buffer[count]);
   2302                 if (SOC_FAILURE(rv)) {
   2303                     err_flag = 1;
   2304                     break;
   2305                 }
   2306                 count ++;
   2307             }
   2308             if (!err_flag) {
   2309                 /* restore the original configuration : EGRMETERINGCONFIGr */
   2310                 rv = WRITE_EGRMETERINGCONFIGr(unit, port, buffer[count]);
   2311             }
   2312 
   2313             sal_free(setting);
   2314             break;
   2315         }
   2316 #endif /* BCM_HURRICANE2_SUPPORT */
   2317 #if defined(BCM_GREYHOUND2_SUPPORT)
   2318     case SOC_CHIP_BCM53570:
   2319         {
   2320             int i;
   2321             uint32 *buffer = setting;
   2322             int err_flag = 0;
   2323             int count;
   2324             int qlayer_entry_count = 0;
   2325             int qgroup_entry_count = 0;
   2326             soc_mem_t config_mem = INVALIDm;
   2327             uint32 entry[SOC_MAX_MEM_WORDS];
   2328             int memidx;
   2329             int is_64q_port;
   2330 
   2331             rv = soc_gh2_64q_port_check(unit, port, &is_64q_port);
   2332             if (SOC_FAILURE(rv)) {
   2333                 sal_free(setting);
   2334                 break;
   2335             }
   2336 
   2337             if (is_64q_port) {
   2338                 qlayer_entry_count = SOC_GH2_QLAYER_COSQ_PER_PORT_NUM;
   2339                 qgroup_entry_count = SOC_GH2_QGROUP_PER_PORT_NUM;
   2340             } else {
   2341                 qlayer_entry_count = SOC_GH2_LEGACY_QUEUE_NUM;
   2342                 qgroup_entry_count = 0;
   2343             }
   2344             
   2345             /* buffer required (X*2+Y*2+1) for store original setting.
   2346              *   MMU port 0~57: X=8, Y=0
   2347              *   MMU port 58-65 : X=64, Y=8
   2348              * MMU_MAX_BUCKET_QLAYERm : 
   2349              *   X entries for a port, two fields (REFRESHf, THD_SELf)stored
   2350              * MMU_MAX_BUCKET_QGROUPm : Y entries for a port
   2351              *   Y entries for a port, two fields (REFRESHf, THD_SELf)stored
   2352              * EGRMETERINGCONFIG : 1 register value for a port
   2353              */
   2354 
   2355             /* restore the original configuration : MMU_MAX_BUCKET_QLAYERm */
   2356             count = 0;
   2357             config_mem = MMU_MAX_BUCKET_QLAYERm;
   2358             rv = soc_gh2_mmu_bucket_qlayer_index(unit, port, 0, &memidx);
   2359             if (SOC_FAILURE(rv)) {
   2360                 err_flag = 1;
   2361             } else {
   2362                 for (i = memidx; i < qlayer_entry_count; i++) {
   2363                     rv = soc_mem_read(unit, config_mem, MEM_BLOCK_ALL, 
   2364                                       i, &entry);
   2365                     if (SOC_FAILURE(rv)) {
   2366                         err_flag = 1;
   2367                         break;
   2368                     }
   2369                     soc_mem_field32_set(unit, config_mem, &entry, REFRESHf, 
   2370                                         buffer[count]);
   2371                     count ++;
   2372                     soc_mem_field32_set(unit, config_mem, &entry, THD_SELf, 
   2373                                         buffer[count]);
   2374                     count ++;
   2375                     rv = soc_mem_write(unit, config_mem, MEM_BLOCK_ALL, 
   2376                                        i, &entry);
   2377                     if (SOC_FAILURE(rv)) {
   2378                         err_flag = 1;
   2379                         break;
   2380                     }
   2381                 }
   2382             }
   2383 
   2384             /* restore the original configuration : MMU_MAX_BUCKET_QGROUPm */
   2385             if (!err_flag) {
   2386                 if (qgroup_entry_count) {
   2387                     config_mem = MMU_MAX_BUCKET_QGROUPm;
   2388                     rv = soc_gh2_mmu_bucket_qgroup_index(unit, port, 0, 
   2389                                                          &memidx);
   2390                     if (SOC_FAILURE(rv)) {
   2391                         err_flag = 1;
   2392                     } else {
   2393                         for (i = memidx; i < qgroup_entry_count; i++) {
   2394                             rv = soc_mem_read(unit, config_mem, MEM_BLOCK_ALL,
   2395                                           i, &entry);
   2396                             if (SOC_FAILURE(rv)) {
   2397                                 err_flag = 1;
   2398                                 break;
   2399                             }
   2400 
   2401                             soc_mem_field32_set(unit, config_mem, &entry, 
   2402                                                 REFRESHf, buffer[count]);
   2403                             count ++;
   2404                             soc_mem_field32_set(unit, config_mem, &entry, 
   2405                                                 THD_SELf, buffer[count]);
   2406                             count ++;
   2407                             rv = soc_mem_write(unit, config_mem, 
   2408                                                MEM_BLOCK_ALL, i, &entry);
   2409                             if (SOC_FAILURE(rv)) {
   2410                                 err_flag = 1;
   2411                                 break;
   2412                             }
   2413                         }
   2414                     }
   2415                 }
   2416             }
   2417 
   2418             if (!err_flag) {
   2419                 /* restore the original configuration : EGRMETERINGCONFIGr */
   2420                 rv = WRITE_EGRMETERINGCONFIGr(unit, port, buffer[count]);
   2421             }
   2422             sal_free(setting);
   2423             break;
   2424         }
   2425 #endif /* BCM_GREYHOUND2_SUPPORT */
   2426 #if defined(BCM_TRIUMPH_SUPPORT)
   2427     case SOC_CHIP_BCM56624:
   2428     case SOC_CHIP_BCM56680:
   2429     case SOC_CHIP_BCM56634:
   2430     case SOC_CHIP_BCM56524:
   2431     case SOC_CHIP_BCM56334:
   2432     case SOC_CHIP_BCM56685:
   2433         {
   2434             uint64 *rval64;
   2435 
   2436             rval64 = setting;
   2437             /* Restore egress metering configuration. */
   2438             rv = WRITE_EGRMETERINGCONFIG_64r(unit, port, *rval64);
   2439             sal_free(setting);
   2440             break;
   2441         }
   2442     case SOC_CHIP_BCM56840:
   2443         {
   2444             int count, index, queue_cnt, err_flag = 0;
   2445             soc_info_t *si;
   2446             uint64 *buffer = setting;
   2447 
   2448             si = &SOC_INFO(unit);
   2449             /* Port level + S2 + S3 + UCQ + MCQ + EXT_UCQ. */
   2450             queue_cnt = si->port_num_uc_cosq[port] + si->port_num_cosq[port] +
   2451                         si->port_num_ext_cosq[port];
   2452 
   2453             count = 0;
   2454             /* Port level meter. */
   2455             rv = WRITE_EGRMETERINGCONFIG_64r(unit, port, buffer[count]);
   2456             if (SOC_FAILURE(rv)) {
   2457                 err_flag = 1;
   2458             }
   2459             count++;
   2460 
   2461             if (!IS_CPU_PORT(unit, port)) {
   2462                 /* S2 meter (including MC group). */
   2463                 for (index = 0; (index < 4) && (err_flag == 0); index++) {
   2464                     rv = WRITE_S2_MAXBUCKETCONFIG_64r(unit, port, index,
   2465                                                       buffer[count]);
   2466                     if (SOC_FAILURE(rv)) {
   2467                         err_flag = 1;
   2468                         break;
   2469                     }
   2470                     count++;
   2471                 }
   2472                 /* S3 meter. */
   2473                 for (index = 0; (index < 4) && (err_flag == 0); index++) {
   2474                     rv = WRITE_S3_MAXBUCKETCONFIG_64r(unit, port, index,
   2475                                                       buffer[count]);
   2476                     if (SOC_FAILURE(rv)) {
   2477                         err_flag = 1;
   2478                         break;
   2479                     }
   2480                     count++;
   2481                 }
   2482             }
   2483 
   2484             /* Queue meter. */
   2485             for (index = 0; (index < queue_cnt) && (err_flag == 0); index++) {
   2486                 rv = WRITE_MAXBUCKETCONFIG_64r(unit, port, index,
   2487                                                buffer[count]);
   2488                 if (SOC_FAILURE(rv)) {
   2489                     break;
   2490                 }
   2491                 count++;
   2492             }
   2493             sal_free(setting);
   2494             break;
   2495         }
   2496     case SOC_CHIP_BCM56640:
   2497     case SOC_CHIP_BCM56340:
   2498         {
   2499             uint64 rval64;
   2500             int index;
   2501             mem_entry_t *buffer = setting;
   2502 
   2503             /* Restore port level metering configuration. */
   2504             sal_memcpy(&rval64, &buffer[0].entry[0], sizeof(uint64));
   2505             rv = WRITE_EGRMETERINGCONFIG_64r(unit, port, rval64);
   2506 
   2507             /* Restore L0,L1,L2 metering configuration. */
   2508             for (index = 1; buffer[index].mem != INVALIDm ;index++) {
   2509                 rv = soc_mem_write(unit, buffer[index].mem, MEM_BLOCK_ANY,
   2510                                    buffer[index].index, &buffer[index].entry);
   2511                 if (SOC_FAILURE(rv)) {
   2512                     break;
   2513                 }
   2514             }
   2515 
   2516             sal_free(setting);
   2517             break;
   2518         }
   2519 #endif /* BCM_TRIUMPH_SUPPORT */
   2520 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_KATANA_SUPPORT)
   2521     case SOC_CHIP_BCM56440:
   2522     case SOC_CHIP_BCM56450:
   2523     case SOC_CHIP_BCM56260:
   2524     case SOC_CHIP_BCM56850:
   2525     case SOC_CHIP_BCM56860:
   2526     case SOC_CHIP_BCM56560:
   2527     case SOC_CHIP_BCM56270:
   2528         {
   2529             int index;
   2530             mem_entry_t *buffer;
   2531 
   2532             buffer = setting;
   2533             for (index = 0; buffer[index].mem != INVALIDm ;index++) {
   2534                 rv = soc_mem_write(unit, buffer[index].mem, MEM_BLOCK_ANY,
   2535                                    buffer[index].index, &buffer[index].entry);
   2536                 if (SOC_FAILURE(rv)) {
   2537                     break;
   2538                 }
   2539             }
   2540             sal_free(setting);
   2541             break;
   2542         }
   2543 #endif /* BCM_TRIDENT2_SUPPORT  || BCM_KATANA_SUPPORT */
   2544 #ifdef BCM_TRIDENT3_SUPPORT
   2545     case SOC_CHIP_BCM56870:
   2546     case SOC_CHIP_BCM56370:
   2547     case SOC_CHIP_BCM56770:
   2548         {
   2549             uint64 rval64;
   2550             uint64 *buffer;
   2551             uint64 pbits64;
   2552             int pipe;
   2553             int split, pos;
   2554             soc_reg_t mtro_reg;
   2555             soc_reg_t reg_mtro[2] = {MTRO_PORT_ENTITY_DISABLE_SPLIT0r,
   2556                                      MTRO_PORT_ENTITY_DISABLE_SPLIT1r};
   2557 
   2558             COMPILER_64_ZERO(rval64);
   2559             COMPILER_64_ZERO(pbits64);
   2560 
   2561             SOC_IF_ERROR_RETURN(
   2562                 soc_td3_mmu_bmp_reg_pos_get(unit, port, &pipe, &split, &pos));
   2563             mtro_reg = reg_mtro[split];
   2564 
   2565             if (pos < 32) {
   2566                 COMPILER_64_SET(pbits64, 0, (1 << pos));
   2567             } else {
   2568                 COMPILER_64_SET(pbits64, (1 << (pos - 32)), 0);
   2569             }
   2570 
   2571             /* Restore Shaper Updates */
   2572             rv = soc_reg_get(unit, mtro_reg, pipe, 0, &rval64);
   2573             if (SOC_FAILURE(rv)) {
   2574                 sal_free(setting);
   2575                 break;
   2576             }
   2577             buffer = setting;
   2578             COMPILER_64_NOT(pbits64);
   2579             COMPILER_64_AND(rval64, pbits64);
   2580             COMPILER_64_OR(rval64, *buffer);
   2581 
   2582             /* METERING_DISABLEf is the only field in reg. */
   2583             rv = soc_reg_set(unit, mtro_reg, pipe, 0, rval64);
   2584             if (SOC_FAILURE(rv)) {
   2585                 sal_free(setting);
   2586                 break;
   2587             }
   2588 
   2589             sal_free(setting);
   2590             break;
   2591         }
   2592 #endif /* BCM_TRIDENT3_SUPPORT */
   2593     case SOC_CHIP_BCM56960: /* Use hardware flush */
   2594     case SOC_CHIP_BCM56965:
   2595     default:
   2596         break;
   2597     }
   2598 
   2599     SOC_EGRESS_METERING_UNLOCK(unit);
   2600 
   2601     return rv;
   2602 }
   2603 
   2604 int
   2605 soc_mmu_flush_enable(int unit, soc_port_t port, int enable)
   2606 {
   2607 #if defined(BCM_RAVEN_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIUMPH_SUPPORT) || defined(BCM_SCORPION_SUPPORT)  
   2608     uint32 flush_ctrl;
   2609 #endif
   2610 
   2611 #if defined(BCM_KATANA_SUPPORT)
   2612     void *setting = NULL;
   2613     int rv = SOC_E_NONE;
   2614     int rv1 = SOC_E_NONE;
   2615 #endif
   2616 
   2617     switch (SOC_CHIP_GROUP(unit)) {
   2618 #if defined(BCM_RAVEN_SUPPORT)
   2619     case SOC_CHIP_BCM56224:
   2620     case SOC_CHIP_BCM53314:
   2621         SOC_IF_ERROR_RETURN
   2622             (READ_MMUFLUSHCONTROLr(unit, &flush_ctrl));
   2623         flush_ctrl &= ~(0x1 << port);
   2624         flush_ctrl |= enable ? (0x1 << port) : 0;
   2625         SOC_IF_ERROR_RETURN
   2626             (WRITE_MMUFLUSHCONTROLr(unit, flush_ctrl));
   2627         break;
   2628 #endif /* BCM_RAVEN_SUPPORT */
   2629 
   2630 #if defined(BCM_HURRICANE2_SUPPORT)
   2631     case SOC_CHIP_BCM56150:
   2632     case SOC_CHIP_BCM53400:
   2633     case SOC_CHIP_BCM56160:
   2634     case SOC_CHIP_BCM53540:
   2635         SOC_IF_ERROR_RETURN
   2636             (READ_MMUFLUSHCONTROLr(unit, &flush_ctrl));
   2637         flush_ctrl &= ~(0x1 << port);
   2638         flush_ctrl |= enable ? (0x1 << port) : 0;
   2639         SOC_IF_ERROR_RETURN
   2640             (WRITE_MMUFLUSHCONTROLr(unit, flush_ctrl));
   2641         LOG_VERBOSE(BSL_LS_SOC_COMMON,
   2642                     (BSL_META_U(unit,
   2643                                 "port %d MMUFLUSHCONTROl.FLUSH=0x%x\n"), port, flush_ctrl));
   2644         break;
   2645     case SOC_CHIP_BCM53570:
   2646         {
   2647             int port_off;
   2648             if (port < 32) {
   2649                 port_off = port;
   2650                 SOC_IF_ERROR_RETURN
   2651                     (READ_MMUFLUSHCONTROL_0r(unit, &flush_ctrl));
   2652                 flush_ctrl &= ~(0x1 << port_off);
   2653                 flush_ctrl |= enable ? (0x1 << port_off) : 0;
   2654                 SOC_IF_ERROR_RETURN
   2655                     (WRITE_MMUFLUSHCONTROL_0r(unit, flush_ctrl));
   2656             } else if ((port >= 32) && (port < 64)) {
   2657                 port_off = port - 32;
   2658                 SOC_IF_ERROR_RETURN
   2659                     (READ_MMUFLUSHCONTROL_1r(unit, &flush_ctrl));
   2660                 flush_ctrl &= ~(0x1 << port_off);
   2661                 flush_ctrl |= enable ? (0x1 << port_off) : 0;
   2662                 SOC_IF_ERROR_RETURN
   2663                     (WRITE_MMUFLUSHCONTROL_1r(unit, flush_ctrl));
   2664             } else {
   2665                 port_off = port - 64;
   2666                 SOC_IF_ERROR_RETURN
   2667                     (READ_MMUFLUSHCONTROL_1r(unit, &flush_ctrl));
   2668                 flush_ctrl &= ~(0x1 << port_off);
   2669                 flush_ctrl |= enable ? (0x1 << port_off) : 0;
   2670                 SOC_IF_ERROR_RETURN
   2671                     (WRITE_MMUFLUSHCONTROL_1r(unit, flush_ctrl));
   2672             }
   2673             LOG_VERBOSE(BSL_LS_SOC_COMMON,
   2674                 (BSL_META_U(unit,
   2675                         "port %d MMUFLUSHCONTROl.FLUSH=0x%x\n"), port, flush_ctrl));
   2676         }
   2677         break;
   2678 #endif /* BCM_HURRICANE2_SUPPORT */
   2679 
   2680 #if defined(BCM_HURRICANE_SUPPORT)
   2681     case SOC_CHIP_BCM56142:
   2682         SOC_IF_ERROR_RETURN
   2683             (READ_MMUFLUSHCONTROLr(unit, &flush_ctrl));
   2684         flush_ctrl &= ~(0x1 << port);
   2685         flush_ctrl |= enable ? (0x1 << port) : 0;
   2686         SOC_IF_ERROR_RETURN
   2687             (WRITE_MMUFLUSHCONTROLr(unit, flush_ctrl));
   2688         LOG_VERBOSE(BSL_LS_SOC_COMMON,
   2689                     (BSL_META_U(unit,
   2690                                 "port %d MMUFLUSHCONTROl.FLUSH=0x%x\n"), port, flush_ctrl));
   2691     /* Fall through */
   2692 #endif /* BCM_HURRICANE_SUPPORT */
   2693 
   2694 #if defined(BCM_TRIUMPH2_SUPPORT)
   2695     case SOC_CHIP_BCM56634:
   2696     case SOC_CHIP_BCM56524:
   2697     case SOC_CHIP_BCM56685:
   2698         SOC_IF_ERROR_RETURN
   2699             (READ_FAST_TX_FLUSHr(unit, port, &flush_ctrl));
   2700         soc_reg_field_set(unit, FAST_TX_FLUSHr, &flush_ctrl, IDf,
   2701                           (enable) ? 1 : 0);
   2702         SOC_IF_ERROR_RETURN
   2703             (WRITE_FAST_TX_FLUSHr(unit, port, flush_ctrl));
   2704         LOG_VERBOSE(BSL_LS_SOC_COMMON,
   2705                     (BSL_META_U(unit,
   2706                                 "port %d FAST_TX_FLUSH.ID=0x%x\n"), port, flush_ctrl));
   2707     /* Fall through */
   2708 #endif
   2709 #if defined(BCM_TRIUMPH_SUPPORT)
   2710     case SOC_CHIP_BCM56624:
   2711     case SOC_CHIP_BCM56680:
   2712     case SOC_CHIP_BCM56334:
   2713     /*case SOC_CHIP_BCM88732:*/
   2714         if (IS_XE_PORT(unit, port) || IS_HG_PORT(unit, port)) {
   2715             SOC_IF_ERROR_RETURN
   2716                 (READ_XP_EGR_PKT_DROP_CTLr(unit, port, &flush_ctrl));
   2717             soc_reg_field_set(unit, XP_EGR_PKT_DROP_CTLr, &flush_ctrl, FLUSHf,
   2718                               (enable) ? 1 : 0);
   2719             SOC_IF_ERROR_RETURN
   2720                 (WRITE_XP_EGR_PKT_DROP_CTLr(unit, port, flush_ctrl));
   2721            LOG_VERBOSE(BSL_LS_SOC_COMMON,
   2722                        (BSL_META_U(unit,
   2723                                    "port %d XP_EGR_PKT_DROP_CTL.FLUSH=0x%x\n"), port, flush_ctrl));
   2724         }
   2725         break;
   2726 #endif /* BCM_TRIUMPH_SUPPORT */
   2727 
   2728 #if defined(BCM_SCORPION_SUPPORT)
   2729     case SOC_CHIP_BCM56820:
   2730     case SOC_CHIP_BCM56725:
   2731         if (IS_GX_PORT(unit, port)) {
   2732             SOC_IF_ERROR_RETURN
   2733                 (READ_XP_EGR_PKT_DROP_CTLr(unit, port, &flush_ctrl));
   2734             soc_reg_field_set(unit, XP_EGR_PKT_DROP_CTLr, &flush_ctrl, FLUSHf,
   2735                               (enable) ? 1 : 0);
   2736             SOC_IF_ERROR_RETURN
   2737                 (WRITE_XP_EGR_PKT_DROP_CTLr(unit, port, flush_ctrl));
   2738         }
   2739         break;
   2740 #endif /* BCM_TRIUMPH_SUPPORT || BCM_SCORPION_SUPPORT */
   2741 
   2742 #if defined(BCM_TRIDENT_SUPPORT)
   2743     case SOC_CHIP_BCM56840:
   2744         SOC_IF_ERROR_RETURN
   2745             (soc_reg_field32_modify(unit, XLP_TXFIFO_PKT_DROP_CTLr, port,
   2746                                     DROP_ENf, enable ? 1 : 0));
   2747         break;
   2748 #endif /* BCM_TRIDENT_SUPPORT */
   2749 
   2750     case SOC_CHIP_BCM56640:
   2751     case SOC_CHIP_BCM56340:
   2752         SOC_IF_ERROR_RETURN
   2753             (soc_reg_field32_modify(unit, PORT_TXFIFO_PKT_DROP_CTLr, port,
   2754                                     DROP_ENf, enable ? 1 : 0));
   2755         break;
   2756 
   2757 #ifdef BCM_KATANA_SUPPORT
   2758     case SOC_CHIP_BCM56440:
   2759     case SOC_CHIP_BCM56450:
   2760     case SOC_CHIP_BCM56260:
   2761     case SOC_CHIP_BCM56270:
   2762         if (!(SAL_BOOT_SIMULATION || SAL_BOOT_BCMSIM
   2763                    || SAL_BOOT_XGSSIM)) {
   2764             soc_kt_port_flush_state_set(unit, port, TRUE); 
   2765             if (enable == 0) {
   2766                 rv = soc_kt_port_flush(unit, port, enable);
   2767             } else {
   2768                 rv = soc_mmu_backpressure_clear(unit, port);
   2769                 if (SOC_FAILURE(rv)) {
   2770                     soc_kt_port_flush_state_set(unit, port, FALSE);
   2771                     return rv;
   2772                 } 
   2773                 /*
   2774                  *****************************************************
   2775                  * NOTE: Must not exit soc_kt_port_flush
   2776                  *       without calling soc_egress_metering_thaw,
   2777                  *       soc_egress_metering_freeze holds the lock.
   2778                  *       soc_egress_metering_freeze releases the lock
   2779                  *       on failure.
   2780  */
   2781                 rv = _soc_egress_metering_freeze(unit,
   2782                                         port, &setting);
   2783                 if (SOC_FAILURE(rv)) {
   2784                     soc_kt_port_flush_state_set(unit, port, FALSE);
   2785                     return rv;
   2786                 }
   2787                 rv = soc_kt_port_flush(unit, port, enable);
   2788                 /* Restore egress metering configuration. */
   2789                 rv1 = _soc_egress_metering_thaw(unit, port, setting);
   2790                 if (SOC_SUCCESS(rv)) {
   2791                     rv = rv1;
   2792                 }
   2793             }
   2794             soc_kt_port_flush_state_set(unit, port, FALSE);
   2795             return rv;
   2796         }
   2797         break;
   2798 #endif /* BCM_KATANA_SUPPORT */
   2799 
   2800     default:
   2801         return SOC_E_NONE;
   2802     }
   2803 
   2804     return SOC_E_NONE;
   2805 }
   2806 
   2807 int
   2808 soc_mmu_port_flush_hw(int unit, soc_port_t port, uint32 drain_timeout)
   2809 {
   2810 #if defined(BCM_TOMAHAWK2_SUPPORT)
   2811     if (SOC_IS_TOMAHAWK2(unit)) {
   2812         return SOC_E_NONE;
   2813     }
   2814 #endif
   2815 #if defined(BCM_TOMAHAWK_SUPPORT)
   2816     if (SOC_IS_TOMAHAWK(unit)) {
   2817         return soc_tomahawk_mmu_port_flush_hw(unit, port, drain_timeout);
   2818     }
   2819 #endif
   2820 #if defined(BCM_TRIDENT3_SUPPORT)
   2821     if (SOC_IS_TRIDENT3X(unit)) {
   2822         return SOC_E_NONE;
   2823     }
   2824 #endif
   2825     return SOC_E_UNAVAIL;
   2826 }
   2827 
   2828 #if defined(BCM_TRIUMPH3_SUPPORT)
   2829 /*#define IBOD_DEBUG*/
   2830 void soc_ibod_recovery_in_progress_set(int unit, int enable)
   2831 {
   2832     ibod_recovery_in_progress[unit] = enable;
   2833 }
   2834 int soc_ibod_recovery_in_progress_get(int unit)
   2835 {
   2836     return ibod_recovery_in_progress[unit];
   2837 }
   2838 void _soc_egress_drain_timeout_flag_set(int unit, int flag)
   2839 {
   2840     egress_drain_timeout_flag[unit] = flag;
   2841 }
   2842 void _soc_egress_drain_timeout_flag_get(int unit, int *flag)
   2843 {
   2844     *flag = egress_drain_timeout_flag[unit];
   2845 }
   2846 
   2847 #if defined(IBOD_DEBUG) || defined(TXERR_DEBUG)
   2848 int  _soc_egress_drain_debug(int unit, soc_port_t port, soc_reg_t reg)
   2849 {
   2850     uint32 credit, mmu_req, ep_level, total_count;
   2851     egr_mmu_requests_entry_t mmu_entry;
   2852     uint32 max_used_entry;
   2853     int rv = SOC_E_NONE;
   2854     uint32 rval;
   2855     soc_info_t *si = &SOC_INFO(unit);
   2856 
   2857     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &credit));
   2858 
   2859     SOC_IF_ERROR_RETURN(soc_mem_read(unit, EGR_MMU_REQUESTSm, MEM_BLOCK_ANY,
   2860                             si->port_l2p_mapping[port], &mmu_entry));
   2861     mmu_req = soc_mem_field32_get(unit, EGR_MMU_REQUESTSm, &mmu_entry, OUTSTANDING_MMU_REQUESTSf);
   2862 
   2863     SOC_IF_ERROR_RETURN(READ_EGR_EDB_MISC_CTRLr(unit, &rval));
   2864     soc_reg_field_set(unit, EGR_EDB_MISC_CTRLr, &rval, SELECT_CURRENT_USED_ENTRIESf, 1);
   2865     SOC_IF_ERROR_RETURN(WRITE_EGR_EDB_MISC_CTRLr(unit, rval));
   2866     SOC_IF_ERROR_RETURN(READ_EGR_MAX_USED_ENTRIESm(unit, MEM_BLOCK_ALL,
   2867                          si->port_l2p_mapping[port], &max_used_entry));
   2868     ep_level = soc_mem_field32_get(unit, EGR_MAX_USED_ENTRIESm, &max_used_entry, LEVELf);
   2869 
   2870     SOC_IF_ERROR_RETURN(READ_OP_PORT_TOTAL_COUNT_CELLr(unit, port, &rval));
   2871     total_count = soc_reg_field_get(unit, OP_PORT_TOTAL_COUNT_CELLr,rval, TOTAL_COUNTf);
   2872 
   2873     cli_out("Recovery: port %d mmu still has credit[total_count %d, level %d, credit %d mmu_req %d] \r\n",
   2874        port, total_count, ep_level, credit, mmu_req);
   2875 
   2876     return rv;
   2877 }
   2878 #endif /* IBOD_DEBUG || TXERR_DEBUG */
   2879 
   2880 int _soc_egress_drain_ep_max_level_get(int unit, soc_port_t port, uint32 *ep_max_level)
   2881 {
   2882     int rv = SOC_E_NONE;
   2883     uint32 rval;
   2884     uint32 max_used_entry;
   2885     soc_info_t *si = &SOC_INFO(unit);
   2886 
   2887     SOC_IF_ERROR_RETURN(READ_EGR_EDB_MISC_CTRLr(unit, &rval));
   2888     soc_reg_field_set(unit, EGR_EDB_MISC_CTRLr, &rval, SELECT_CURRENT_USED_ENTRIESf, 0);
   2889     SOC_IF_ERROR_RETURN(WRITE_EGR_EDB_MISC_CTRLr(unit, rval));
   2890 
   2891     SOC_IF_ERROR_RETURN(READ_EGR_MAX_USED_ENTRIESm(unit, MEM_BLOCK_ALL, si->port_l2p_mapping[port], &max_used_entry));
   2892     *ep_max_level = soc_mem_field32_get(unit, EGR_MAX_USED_ENTRIESm, &max_used_entry, LEVELf);
   2893 
   2894     return rv;
   2895 }
   2896 
   2897 int _soc_egress_drain_credit_calc(uint32 credit_current, uint32 credit_default,
   2898                             uint32 mmu_req, uint32 ep_level, uint32 *credit_set)
   2899 {
   2900     if (mmu_req > credit_default ) {
   2901         if(ep_level < credit_default) {
   2902             *credit_set = credit_default - ep_level;
   2903         }
   2904         else {
   2905             *credit_set = credit_default;
   2906         }
   2907     }
   2908     else if (mmu_req == 0) {
   2909         if(ep_level < credit_default) {
   2910             *credit_set = credit_default - ep_level;
   2911         }
   2912         else {
   2913             *credit_set = credit_default;
   2914         }
   2915     }
   2916     else if (mmu_req != credit_current) {
   2917         *credit_set = mmu_req;
   2918     }
   2919     else {
   2920         return 0;
   2921     }
   2922 
   2923     return 1;
   2924 }
   2925 #endif
   2926 
   2927 int
   2928 soc_egress_drain_cells(int unit, soc_port_t port, uint32 drain_timeout)
   2929 {
   2930     soc_timeout_t to;
   2931     uint32 cur_cells, new_cells;
   2932     int rv, rv1;
   2933     void *setting = NULL;
   2934 #if defined(BCM_TRIUMPH3_SUPPORT)
   2935     uint32 max_used_entry, ep_level,rval, overflow0, overflow1, total_cell;
   2936     uint32 credit, mmu_req, credit_set, mmu_cells;
   2937     soc_info_t *si;
   2938     egr_mmu_requests_entry_t mmu_entry;
   2939     static const soc_reg_t lls_port_credit_reg[] = {
   2940         LLS_PORT_0_CREDITr, LLS_PORT_1_CREDITr, LLS_PORT_2_CREDITr,
   2941         LLS_PORT_3_CREDITr, LLS_PORT_4_CREDITr, LLS_PORT_5_CREDITr,
   2942         LLS_PORT_6_CREDITr, LLS_PORT_7_CREDITr, LLS_PORT_8_CREDITr,
   2943         LLS_PORT_9_CREDITr, LLS_PORT_10_CREDITr, LLS_PORT_11_CREDITr,
   2944         LLS_PORT_12_CREDITr, LLS_PORT_13_CREDITr, LLS_PORT_14_CREDITr,
   2945         LLS_PORT_15_CREDITr, LLS_PORT_16_CREDITr, LLS_PORT_17_CREDITr,
   2946         LLS_PORT_18_CREDITr, LLS_PORT_19_CREDITr, LLS_PORT_20_CREDITr,
   2947         LLS_PORT_21_CREDITr, LLS_PORT_22_CREDITr, LLS_PORT_23_CREDITr,
   2948         LLS_PORT_24_CREDITr, LLS_PORT_25_CREDITr, LLS_PORT_26_CREDITr,
   2949         LLS_PORT_27_CREDITr, LLS_PORT_28_CREDITr, LLS_PORT_29_CREDITr,
   2950         LLS_PORT_30_CREDITr, LLS_PORT_31_CREDITr, LLS_PORT_32_CREDITr,
   2951         LLS_PORT_33_CREDITr, LLS_PORT_34_CREDITr, LLS_PORT_35_CREDITr,
   2952         LLS_PORT_36_CREDITr, LLS_PORT_37_CREDITr, LLS_PORT_38_CREDITr,
   2953         LLS_PORT_39_CREDITr, LLS_PORT_40_CREDITr, LLS_PORT_41_CREDITr,
   2954         LLS_PORT_42_CREDITr, LLS_PORT_43_CREDITr, LLS_PORT_44_CREDITr,
   2955         LLS_PORT_45_CREDITr, LLS_PORT_46_CREDITr, LLS_PORT_47_CREDITr,
   2956         LLS_PORT_48_CREDITr, LLS_PORT_49_CREDITr, LLS_PORT_50_CREDITr,
   2957         LLS_PORT_51_CREDITr, LLS_PORT_52_CREDITr, LLS_PORT_53_CREDITr,
   2958         LLS_PORT_54_CREDITr, LLS_PORT_55_CREDITr, LLS_PORT_56_CREDITr,
   2959         LLS_PORT_57_CREDITr, LLS_PORT_58_CREDITr, LLS_PORT_59_CREDITr,
   2960         LLS_PORT_60_CREDITr, LLS_PORT_61_CREDITr, LLS_PORT_62_CREDITr
   2961     }; 
   2962     si = &SOC_INFO(unit);
   2963 #endif
   2964     if (soc_feature(unit, soc_feature_mmu_hw_flush)) {
   2965         SOC_IF_ERROR_RETURN(soc_mmu_port_flush_hw(unit, port, drain_timeout));
   2966         rv = SOC_E_NONE;
   2967     } else {
   2968         if(!SOC_IS_KATANAX(unit)) {
   2969         SOC_IF_ERROR_RETURN(soc_mmu_backpressure_clear(unit, port));
   2970 
   2971         /*
   2972          **************************************************************
   2973          * NOTE: Must not exit this function without calling
   2974          *       soc_egress_metering_thaw(). soc_egress_metering_freeze
   2975          *       holds a lock.
   2976  */
   2977         SOC_IF_ERROR_RETURN(_soc_egress_metering_freeze(unit, port, &setting));
   2978         }
   2979 
   2980 #if defined (BCM_APACHE_SUPPORT) || defined (BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT)
   2981         if (SOC_IS_APACHE(unit) ||
   2982             SOC_IS_TRIDENT2PLUS(unit) ||
   2983             SOC_IS_TRIDENT2(unit)) {
   2984             int empty = 0;
   2985             if (SOC_IS_TRIDENT2PLUS(unit)) {
   2986                 /* Wait long enough to ensure CT FIFO of flushed ports are empty */
   2987                 sal_usleep(4);
   2988             }
   2989             if (SOC_IS_MONTEREY(unit)) { 
   2990             /*  extra delay added in monterey to drain the transit macsec packets for the port*/  
   2991                 sal_usleep(1000);
   2992             }
   2993  
   2994             soc_timeout_init(&to, drain_timeout, 0);
   2995             for (;;) {
   2996                 rv = _soc_egress_cell_check(unit, port, &empty);
   2997                 if (empty == TRUE) {
   2998                     break;
   2999                 }
   3000                 if (soc_timeout_check(&to)) {
   3001                     rv = _soc_egress_cell_check(unit, port, &empty);
   3002                     if (empty == TRUE) {
   3003                         break;
   3004                     }
   3005                     /* Don't return error so that remaining port sequence is executed
   3006                      * and port is recovered successfully
   3007                      */
   3008                     LOG_WARN(BSL_LS_SOC_COMMON,
   3009                             (BSL_META_U(unit,
   3010                                         "MacDrainTimeOut:port %d,%s, "
   3011                                         "timeout draining packets \n"),
   3012                              unit, SOC_PORT_NAME(unit, port)));
   3013                     break;
   3014                 }
   3015             }
   3016         } else
   3017 #endif /* BCM_APACHE_SUPPORT || BCM_TRIDENT2PLUS_SUPPORT || BCM_TRIDENT2_SUPPORT */
   3018         {
   3019 
   3020 #if defined(BCM_TRIDENT2_SUPPORT)
   3021         
   3022 #endif /* BCM_TRIDENT2_SUPPORT */
   3023 
   3024         cur_cells = 0xffffffff;
   3025 
   3026         /* Probably not required to continuously check COSLCCOUNT if the fast
   3027          * MMU flush feature is available - done just as an insurance */
   3028         rv = SOC_E_NONE;
   3029         for (;;) {
   3030 #if defined(BCM_TRIUMPH3_SUPPORT)
   3031             /* only for TR3 MMU drain cells */
   3032             if(SOC_IS_TRIUMPH3(unit) && !SOC_IS_HELIX4(unit) &&
   3033                IS_CL_PORT(unit, port) && ibod_recovery_in_progress[unit]) {
   3034 #ifdef IBOD_DEBUG
   3035                 uint32 ep_max_level = 0;
   3036                 uint32 mmu_req_1 = 0;
   3037                 /* check epc_link_bmap for debug */
   3038                 pbmp_t  pbm;
   3039                 epc_link_bmap_entry_t entry;
   3040                 READ_EPC_LINK_BMAPm(unit, MEM_BLOCK_ALL, 0,&entry);
   3041                 soc_mem_pbmp_field_get(unit, EPC_LINK_BMAPm, &entry, PORT_BITMAPf, &pbm);
   3042                 if (SOC_PBMP_MEMBER(pbm, port)) {
   3043                     LOG_WARN(BSL_LS_BCM_PORT,
   3044                                  (BSL_META_U(unit,
   3045                                  "soc_egress_drain_cells:unit %d port %d still in epc link bitmap 0x%x\r\n"),
   3046                                  unit, port, pbm.pbits[0]));
   3047                 }
   3048 #endif
   3049                 new_cells=0;
   3050 
   3051                 /* check MMU cell */
   3052                 if ((rv = soc_egress_cell_count(unit, port, &mmu_cells)) < 0) {
   3053                     break;
   3054                 }
   3055                 new_cells += mmu_cells;
   3056 
   3057                 /* read MMU credit */
   3058                 rv = soc_reg32_get(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port]]], REG_PORT_ANY, 0, &credit);
   3059                 SOC_IF_ERROR_RETURN(rv);
   3060 
   3061                 rv = soc_mem_read(unit, EGR_MMU_REQUESTSm, MEM_BLOCK_ANY, si->port_l2p_mapping[port], &mmu_entry);
   3062                 SOC_IF_ERROR_RETURN(rv);
   3063                 mmu_req = soc_mem_field32_get(unit, EGR_MMU_REQUESTSm, &mmu_entry, OUTSTANDING_MMU_REQUESTSf);
   3064 
   3065                 /* read EP level */
   3066                 rv = READ_EGR_EDB_MISC_CTRLr(unit, &rval);
   3067                 SOC_IF_ERROR_RETURN(rv);
   3068                 soc_reg_field_set(unit, EGR_EDB_MISC_CTRLr, &rval, SELECT_CURRENT_USED_ENTRIESf, 1);
   3069                 rv = WRITE_EGR_EDB_MISC_CTRLr(unit, rval);
   3070                 SOC_IF_ERROR_RETURN(rv);
   3071                 rv = READ_EGR_MAX_USED_ENTRIESm(unit, MEM_BLOCK_ALL, si->port_l2p_mapping[port], &max_used_entry);
   3072                 SOC_IF_ERROR_RETURN(rv);
   3073                 ep_level = soc_mem_field32_get(unit, EGR_MAX_USED_ENTRIESm, &max_used_entry, LEVELf);
   3074 
   3075                 /* Update cur_cells and give more time to drain packets.  */
   3076                 if (new_cells < cur_cells) {
   3077                     soc_timeout_init(&to, drain_timeout, 0);
   3078                     cur_cells = new_cells;
   3079                 }
   3080                 else {
   3081                     rv = soc_reg32_set(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port]]], REG_PORT_ANY, 0, si->port_credit[port]);
   3082                     SOC_IF_ERROR_RETURN(rv);
   3083 #ifdef IBOD_DEBUG
   3084                     cli_out("soc_egress_drain_cells: port %d mmu cells not draining: %d cells remain,cur_cells %d, mmu_cells %d, level %d, credit %d mmu_req %d \r\n",
   3085                           port, new_cells, cur_cells, mmu_cells, ep_level, credit, mmu_req);
   3086 #endif
   3087                 }
   3088                 if (soc_timeout_check(&to)) {
   3089                     if (ep_level == 0){
   3090                         _soc_egress_drain_timeout_flag_set(unit, 1);
   3091 #ifdef IBOD_DEBUG
   3092                         cli_out("soc_egress_drain_cells: Timeout Drain packets and ep_level is 0 (port %d, %d cells remain,cur_cells %d, mmu_cells %d, level %d, credit %d mmu_req %d) \r\n",
   3093                             port, new_cells, cur_cells, mmu_cells, ep_level, credit, mmu_req);
   3094 #endif
   3095                         rv = SOC_E_NONE;
   3096                         break;
   3097                     }
   3098                     else {
   3099                         SOC_IF_ERROR_RETURN(READ_PQEFIFOOVERFLOW0r(unit, &overflow0));
   3100                         SOC_IF_ERROR_RETURN(READ_PQEFIFOOVERFLOW1r(unit, &overflow1));
   3101                         SOC_IF_ERROR_RETURN(READ_OP_PORT_TOTAL_COUNT_CELLr(unit, port, &total_cell));
   3102                         LOG_ERROR(BSL_LS_BCM_PORT,
   3103                                  (BSL_META_U(unit,
   3104                                    "\n soc_egress_drain_cells: Timeout Drain packets unit %d PORT: %s"
   3105                                    "(%d cells remain,cur_cells %d, mmu_cells %d, level %d, credit %d "
   3106                                    "mmu_req %d overflow0 %d overflow1 %d total_cell %d) \r\n"),
   3107                                   unit, SOC_PORT_NAME(unit,port),
   3108                                   new_cells,cur_cells, mmu_cells, ep_level, credit,
   3109                                   mmu_req, overflow0, overflow1, total_cell));
   3110                         rv = SOC_E_INTERNAL;
   3111                         break;
   3112                     }
   3113                 }
   3114 
   3115 #ifdef IBOD_DEBUG
   3116                 /* for debug */
   3117                 rv = soc_mem_read(unit, EGR_MMU_REQUESTSm, MEM_BLOCK_ANY, si->port_l2p_mapping[port], &mmu_entry);
   3118                 SOC_IF_ERROR_RETURN(rv);
   3119                 mmu_req_1 = soc_mem_field32_get(unit, EGR_MMU_REQUESTSm, &mmu_entry, OUTSTANDING_MMU_REQUESTSf);
   3120                 if(mmu_req_1 != mmu_req){
   3121                     cli_out("soc_egress_drain_cells: port %d credit %d mmu_req %d is not equal mmu_req_1 %d  !!!!!\r\n",port,credit, mmu_req, mmu_req_1);
   3122                 }
   3123 #endif
   3124                 /* All packets were drained */
   3125                 if (new_cells == 0) {
   3126                     /* default credit is not set */
   3127                     if(si->port_credit[port] == 0) {
   3128                         si->port_credit[port] = mmu_req;
   3129                     }
   3130 
   3131                     if (_soc_egress_drain_credit_calc(credit, si->port_credit[port], mmu_req, ep_level, &credit_set)) {
   3132                         rv = soc_reg32_set(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port]]], REG_PORT_ANY, 0, credit_set);
   3133                         SOC_IF_ERROR_RETURN(rv);
   3134                     }
   3135 #ifdef IBOD_DEBUG
   3136                     rv = _soc_egress_drain_ep_max_level_get(unit, port, &ep_max_level);
   3137                     if(rv == SOC_E_NONE)
   3138                     {
   3139                          cli_out("IBOD recovery: MacDrainOK max_level %d  !!!!!\r\n", ep_max_level);
   3140                     }
   3141 #endif
   3142                     break;
   3143                 }
   3144                 else if (mmu_cells){  /* some packets still stay in MMU */
   3145                     if((credit == 0)) {
   3146                         rv = soc_reg32_get(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port]]], REG_PORT_ANY, 0, &credit);
   3147                         SOC_IF_ERROR_RETURN(rv);
   3148                         if(credit == 0) {
   3149                             rv = soc_mem_read(unit, EGR_MMU_REQUESTSm, MEM_BLOCK_ANY, si->port_l2p_mapping[port], &mmu_entry);
   3150                             SOC_IF_ERROR_RETURN(rv);
   3151                             mmu_req = soc_mem_field32_get(unit, EGR_MMU_REQUESTSm, &mmu_entry, OUTSTANDING_MMU_REQUESTSf);
   3152 
   3153                             /* default credit is not set */
   3154                             if(si->port_credit[port] == 0) {
   3155                                 si->port_credit[port] = mmu_req;
   3156                             }
   3157 
   3158                             if (_soc_egress_drain_credit_calc(credit, si->port_credit[port], mmu_req, ep_level, &credit_set)) {
   3159                                 rv = soc_reg32_set(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port]]], REG_PORT_ANY, 0, credit_set);
   3160                                 SOC_IF_ERROR_RETURN(rv);
   3161                             }
   3162                         }
   3163                         else {
   3164 #ifdef IBOD_DEBUG
   3165                             _soc_egress_drain_debug(unit, port, lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port]]]);
   3166 #endif
   3167                         }
   3168                     }
   3169                     else {
   3170 #ifdef IBOD_DEBUG
   3171                         _soc_egress_drain_debug(unit, port, lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port]]]);
   3172 #endif
   3173                     }
   3174                 }
   3175             }
   3176             else
   3177 #endif
   3178         {
   3179             if ((rv = soc_egress_cell_count(unit, port, &new_cells)) < 0) {
   3180                 break;
   3181             }
   3182 
   3183             if (new_cells == 0) {
   3184                 rv = SOC_E_NONE;
   3185                 break;
   3186             }
   3187 
   3188             if (new_cells < cur_cells) {                    /* Progress made */
   3189                 /* Restart timeout */
   3190                 soc_timeout_init(&to, drain_timeout, 0);
   3191                 cur_cells = new_cells;
   3192             }
   3193 
   3194             if (soc_timeout_check(&to)) {
   3195                 if ((rv = soc_egress_cell_count(unit, port, &new_cells)) < 0) {
   3196                     break;
   3197                 }
   3198 #if defined(BCM_TRIUMPH3_SUPPORT)
   3199                 /*Drain timeout is not a real issue for triumph3 and Helix4, so need not return error code*/
   3200                 if(SOC_IS_HELIX4(unit)){
   3201                     SOC_IF_ERROR_RETURN(READ_EGR_EDB_MISC_CTRLr(unit, &rval));
   3202                     soc_reg_field_set(unit, EGR_EDB_MISC_CTRLr, &rval, SELECT_CURRENT_USED_ENTRIESf, 1);
   3203                     SOC_IF_ERROR_RETURN(WRITE_EGR_EDB_MISC_CTRLr(unit, rval));
   3204                     SOC_IF_ERROR_RETURN(READ_EGR_MAX_USED_ENTRIESm(unit, MEM_BLOCK_ALL,
   3205                         si->port_l2p_mapping[port], &max_used_entry));
   3206                     ep_level = soc_mem_field32_get(unit, EGR_MAX_USED_ENTRIESm, &max_used_entry, LEVELf);
   3207                     SOC_IF_ERROR_RETURN(READ_PQEFIFOOVERFLOW0r(unit, &overflow0));
   3208                     SOC_IF_ERROR_RETURN(READ_PQEFIFOOVERFLOW1r(unit, &overflow1));
   3209                     SOC_IF_ERROR_RETURN(READ_OP_PORT_TOTAL_COUNT_CELLr(unit, port, &total_cell));
   3210                     if(ep_level == 0) {
   3211                         _soc_egress_drain_timeout_flag_set(unit, 1);
   3212                     }
   3213                     else {
   3214                         LOG_ERROR(BSL_LS_SOC_COMMON,
   3215                             (BSL_META_U(unit,
   3216                                       "MacDrainTimeOut:port %d,%s, "
   3217                                       "timeout draining packets (%d cells remain), ep_level:%d, overflow0:%d, overflow1:%d,total_cell:%d\n"),
   3218                            unit, SOC_PORT_NAME(unit, port), new_cells, ep_level, overflow0, overflow1,total_cell));
   3219                     }
   3220                 }
   3221 #else
   3222                 LOG_ERROR(BSL_LS_SOC_COMMON,
   3223                            (BSL_META_U(unit,"MacDrainTimeOut:port %d,%s, "
   3224                                     "timeout draining packets (%d cells remain)\n"),
   3225                             unit, SOC_PORT_NAME(unit, port), new_cells));
   3226                 rv = SOC_E_INTERNAL;
   3227 #endif
   3228                 break;
   3229              }
   3230            }
   3231         }
   3232         }
   3233 
   3234         if (!SOC_IS_KATANAX(unit)) {
   3235         /* Restore egress metering configuration. */
   3236         rv1 = _soc_egress_metering_thaw(unit, port, setting);
   3237         if (SOC_SUCCESS(rv)) {
   3238             rv  = rv1;
   3239         }
   3240         }
   3241     }
   3242 
   3243     return rv;
   3244 }
   3245 
   3246 int
   3247 soc_txfifo_drain_cells(int unit, soc_port_t port, uint32 drain_timeout)
   3248 {
   3249 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT)
   3250     if (SOC_IS_TRIUMPH3(unit) || SOC_IS_TRIDENT2X(unit) || SOC_IS_TITAN2X(unit)) {
   3251         soc_timeout_t to;
   3252         int count = 0;
   3253 
   3254         soc_timeout_init(&to, drain_timeout, 0);
   3255         for (;;) {
   3256             SOC_IF_ERROR_RETURN
   3257                 (_soc_port_txfifo_cell_count(unit, port, &count));
   3258             if (!count) {
   3259                 break;
   3260             }
   3261             if (soc_timeout_check(&to)) {
   3262                 LOG_ERROR(BSL_LS_SOC_COMMON,
   3263                           (BSL_META_U(unit,
   3264                                       "MacDrainTimeOut:port %d,%s, timeout draining TXFIFO "
   3265                                       "(pending: %d)\n"),
   3266                            unit, SOC_PORT_NAME(unit, port), count));
   3267                 return SOC_E_INTERNAL;
   3268             }
   3269         }
   3270     }
   3271 #endif /* BCM_TRIUMPH3_SUPPORT || BCM_TRIDENT2_SUPPORT */
   3272 
   3273     return SOC_E_NONE;
   3274 }
   3275 
   3276 int
   3277 soc_port_credit_reset(int unit, soc_port_t port)
   3278 {
   3279     int phy_port;
   3280     egr_port_credit_reset_entry_t entry;
   3281 
   3282     switch (SOC_CHIP_GROUP(unit)) {
   3283     case SOC_CHIP_BCM56850:
   3284     case SOC_CHIP_BCM56860:
   3285     case SOC_CHIP_BCM56560:
   3286     case SOC_CHIP_BCM56870:
   3287     case SOC_CHIP_BCM56770:
   3288     case SOC_CHIP_BCM56370:
   3289     case SOC_CHIP_BCM56970:
   3290     case SOC_CHIP_BCM56670:
   3291         /* Should be called by CLMAC and XLMAC driver */
   3292         phy_port = SOC_INFO(unit).port_l2p_mapping[port];
   3293         sal_memset(&entry, 0, sizeof(entry));
   3294         soc_mem_field32_set(unit, EGR_PORT_CREDIT_RESETm, &entry, VALUEf, 1);
   3295         SOC_IF_ERROR_RETURN(WRITE_EGR_PORT_CREDIT_RESETm(unit, MEM_BLOCK_ALL,
   3296                                                          phy_port, &entry));
   3297         soc_mem_field32_set(unit, EGR_PORT_CREDIT_RESETm, &entry, VALUEf, 0);
   3298         SOC_IF_ERROR_RETURN(WRITE_EGR_PORT_CREDIT_RESETm(unit, MEM_BLOCK_ALL,
   3299                                                          phy_port, &entry));
   3300         break;
   3301     case SOC_CHIP_BCM56150:
   3302     case SOC_CHIP_BCM53400:
   3303     case SOC_CHIP_BCM56160:
   3304     case SOC_CHIP_BCM53570:
   3305     case SOC_CHIP_BCM53540:
   3306     {
   3307         uint32 rval;
   3308         int bindex;
   3309         static const soc_field_t port_field[] = {
   3310             PORT0f, PORT1f, PORT2f, PORT3f
   3311         };
   3312         soc_reg_t txfifo_reg;
   3313 
   3314         /* Should only be called by XLMAC/CLMAC driver */
   3315         if (!IS_XL_PORT(unit, port) && !IS_CL_PORT(unit, port)) {
   3316             break;
   3317         }
   3318 
   3319         txfifo_reg = XLPORT_TXFIFO_CTRLr;
   3320         
   3321         phy_port = SOC_INFO(unit).port_l2p_mapping[port];
   3322         bindex = SOC_PORT_BINDEX(unit, phy_port);
   3323 
   3324 #ifdef BCM_GREYHOUND_SUPPORT
   3325         if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
   3326             SOC_IS_GREYHOUND2(unit)){
   3327             int blk, blktype;
   3328             blk = SOC_PORT_BLOCK(unit, phy_port);
   3329             blktype = SOC_BLOCK_INFO(unit, blk).type;
   3330             if (blktype == SOC_BLK_GXPORT){
   3331                 txfifo_reg = PGW_GX_TXFIFO_CTRLr;
   3332             } else if (blktype == SOC_BLK_XLPORT) {
   3333                 txfifo_reg = PGW_XL_TXFIFO_CTRLr;
   3334             } else if (blktype == SOC_BLK_CLPORT) {
   3335                 txfifo_reg = PGW_CL_TXFIFO_CTRLr;
   3336             }
   3337         }
   3338 #endif
   3339 
   3340         if (IS_CL_PORT(unit, port)) {
   3341             if (SOC_REG_PORT_VALID(unit, CLPORT_ENABLE_REGr, port)) {
   3342                 SOC_IF_ERROR_RETURN
   3343                     (soc_reg_field32_modify(unit, CLPORT_ENABLE_REGr, port,
   3344                                             port_field[bindex], 0));
   3345             }
   3346         } else {
   3347             if (SOC_REG_PORT_VALID(unit, XLPORT_ENABLE_REGr, port)) {
   3348         SOC_IF_ERROR_RETURN
   3349             (soc_reg_field32_modify(unit, XLPORT_ENABLE_REGr, port,
   3350                                     port_field[bindex], 0));
   3351             }
   3352         }
   3353 
   3354         sal_memset(&entry, 0, sizeof(entry));
   3355         soc_mem_field32_set(unit, EGR_PORT_CREDIT_RESETm, &entry, VALUEf, 1);
   3356         SOC_IF_ERROR_RETURN
   3357             (WRITE_EGR_PORT_CREDIT_RESETm(unit, MEM_BLOCK_ALL, phy_port, &entry));
   3358 
   3359         SOC_IF_ERROR_RETURN
   3360             (soc_reg32_get(unit, txfifo_reg, port, 0, &rval));        
   3361         soc_reg_field_set(unit, txfifo_reg, &rval, MAC_CLR_COUNTf,1);
   3362         soc_reg_field_set(unit, txfifo_reg, &rval, CORE_CLR_COUNTf,1);
   3363         SOC_IF_ERROR_RETURN
   3364             (soc_reg32_set(unit, txfifo_reg, port, 0, rval));
   3365 
   3366         sal_usleep(1000);
   3367 
   3368         soc_mem_field32_set(unit, EGR_PORT_CREDIT_RESETm, &entry, VALUEf, 0);
   3369         SOC_IF_ERROR_RETURN
   3370             (WRITE_EGR_PORT_CREDIT_RESETm(unit, MEM_BLOCK_ALL, phy_port, &entry));
   3371 
   3372         SOC_IF_ERROR_RETURN
   3373             (soc_reg32_get(unit, txfifo_reg, port, 0, &rval));        
   3374         soc_reg_field_set(unit, txfifo_reg, &rval, MAC_CLR_COUNTf, 0);
   3375         soc_reg_field_set(unit, txfifo_reg, &rval, CORE_CLR_COUNTf, 0);
   3376         SOC_IF_ERROR_RETURN
   3377             (soc_reg32_set(unit, txfifo_reg, port, 0, rval));
   3378 
   3379         if (IS_CL_PORT(unit, port)) {
   3380             if (SOC_REG_PORT_VALID(unit, CLPORT_ENABLE_REGr, port)) {
   3381                 SOC_IF_ERROR_RETURN
   3382                     (soc_reg_field32_modify(unit, CLPORT_ENABLE_REGr, port,
   3383                                             port_field[bindex], 1));
   3384             }
   3385         } else {
   3386             if (SOC_REG_PORT_VALID(unit, XLPORT_ENABLE_REGr, port)) {
   3387         SOC_IF_ERROR_RETURN
   3388             (soc_reg_field32_modify(unit, XLPORT_ENABLE_REGr, port,
   3389                                     port_field[bindex], 1));
   3390     }
   3391         }
   3392     }
   3393         break;
   3394 #if defined(BCM_SABER2_SUPPORT) 
   3395     case SOC_CHIP_BCM56260:
   3396     case SOC_CHIP_BCM56270:
   3397         /* Bring the port down and back up to clear credits */
   3398         SOC_IF_ERROR_RETURN(soc_saber2_port_enable_set(unit, port, 0));
   3399         SOC_IF_ERROR_RETURN(soc_saber2_port_enable_set(unit, port, 1));
   3400         break;
   3401 #endif
   3402     default:
   3403         break;
   3404     }
   3405 
   3406     return SOC_E_NONE;
   3407 }
   3408 
   3409 int
   3410 soc_port_ingress_buffer_reset(int unit, soc_port_t port, int reset)
   3411 {
   3412     switch (SOC_CHIP_GROUP(unit)) {
   3413 #if defined (BCM_TRIDENT2PLUS_SUPPORT)
   3414     case SOC_CHIP_BCM56860:
   3415         /* Poll until PGW buffers are empty */
   3416         SOC_IF_ERROR_RETURN(soc_td2p_idb_buf_reset(unit, port, reset));
   3417     break;
   3418 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
   3419 #if defined(BCM_TOMAHAWK_SUPPORT)
   3420     case SOC_CHIP_BCM56960:
   3421     case SOC_CHIP_BCM56965:
   3422         SOC_IF_ERROR_RETURN(soc_tomahawk_idb_buf_reset(unit, port, reset));
   3423         break;
   3424 #endif
   3425 #if defined(BCM_TOMAHAWK2_SUPPORT)
   3426     case SOC_CHIP_BCM56970:
   3427         SOC_IF_ERROR_RETURN(soc_tomahawk2_idb_buf_reset(unit, port, reset));
   3428         break;
   3429 #endif
   3430     case SOC_CHIP_BCM56870:
   3431 #if defined(BCM_TRIDENT3_SUPPORT)
   3432     {
   3433         SOC_IF_ERROR_RETURN(soc_trident3_idb_buf_reset(unit, port, reset));
   3434     }
   3435 #endif
   3436         break;
   3437     case SOC_CHIP_BCM56560:
   3438 #if defined(BCM_APACHE_SUPPORT)
   3439     {
   3440         SOC_IF_ERROR_RETURN(soc_apache_idb_buf_reset(unit, port, reset));
   3441     }
   3442 #endif /*  BCM_APACHE_SUPPORT */
   3443        break; 
   3444     case SOC_CHIP_BCM56670:
   3445 #if defined(BCM_MONTEREY_SUPPORT)
   3446     {
   3447         SOC_IF_ERROR_RETURN(soc_monterey_idb_buf_reset(unit, port, reset));
   3448     }
   3449 #endif /*  BCM_APACHE_SUPPORT */
   3450     default:
   3451         break;
   3452     }
   3453     return SOC_E_NONE;
   3454 }
   3455 
   3456 #if defined (BCM_TRIDENT2_SUPPORT)
   3457 STATIC int
   3458 soc_port_credit_init(int unit, soc_port_t port)
   3459 {
   3460 #ifdef BCM_XLMAC_SUPPORT
   3461     soc_info_t *si = &SOC_INFO(unit);
   3462     soc_reg_t reg;
   3463     uint32 rval;
   3464     int rv = SOC_E_NONE, mac_lb, speed;
   3465     int phy_port, mmu_port, pipe;
   3466     static soc_reg_t mmu_port_credit_regs[] = {
   3467         ES_PIPE0_MMU_PORT_CREDITr, ES_PIPE1_MMU_PORT_CREDITr
   3468     };
   3469 
   3470     rv = soc_mac_xl.md_lb_get(unit, port, &mac_lb);
   3471     if (SOC_SUCCESS(rv) && mac_lb) {
   3472         rv = soc_mac_xl.md_speed_get(unit, port, &speed);
   3473     } else {
   3474         rv = soc_phyctrl_speed_get(unit, port, &speed);
   3475         if (SOC_E_UNAVAIL == rv) {
   3476             /* PHY driver doesn't support speed_get.
   3477              * Get the speed from MAC.
   3478              */
   3479             rv = soc_mac_xl.md_speed_get(unit, port, &speed);
   3480         }
   3481         if ((IS_HG_PORT(unit, port) && speed < 5000) &&
   3482             !(IS_HL_PORT(unit,port))) {
   3483             speed = 0;
   3484         }
   3485     }
   3486     /* Set MMU port credit */
   3487     pipe = SOC_PBMP_MEMBER(si->ypipe_pbm, port) ? 1 : 0;
   3488     reg = mmu_port_credit_regs[pipe];
   3489     phy_port = si->port_l2p_mapping[port];
   3490     mmu_port = si->port_p2m_mapping[phy_port];
   3491 
   3492     if (speed > 21000){
   3493         rval = 48;
   3494     } else if (speed > 11000) {
   3495         rval = 24;
   3496     } else if (speed > 1000) {
   3497         rval = 12;
   3498     } else {
   3499         rval = 3;
   3500     }
   3501     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY,
   3502                                       mmu_port & 0x3f, rval));
   3503 #endif
   3504     return SOC_E_NONE;
   3505 }
   3506 #endif
   3507 
   3508 int
   3509 soc_port_egress_buffer_sft_reset(int unit, soc_port_t port, int reset)
   3510 {
   3511     switch (SOC_CHIP_GROUP(unit)) {
   3512     case SOC_CHIP_BCM56850:
   3513 #if defined (BCM_TRIDENT2_SUPPORT)
   3514     {
   3515         soc_info_t *si = &SOC_INFO(unit);
   3516         soc_reg_t reg;
   3517         soc_field_t fields;
   3518         int phy_port, block, bindex, lanemode, lanenum, i;
   3519         uint32 xmrval, errval, value, entry;
   3520         static soc_reg_t egr_reset_regs[] = {
   3521             EGR_XLPORT_BUFFER_SFT_RESET_0_Xr, EGR_XLPORT_BUFFER_SFT_RESET_1_Xr,
   3522             EGR_XLPORT_BUFFER_SFT_RESET_0_Yr, EGR_XLPORT_BUFFER_SFT_RESET_1_Yr
   3523         };
   3524         static soc_field_t egr_reset_fields[] = {
   3525             XLP0_RESETf, XLP1_RESETf, XLP2_RESETf, XLP3_RESETf,
   3526             XLP4_RESETf, XLP5_RESETf, XLP6_RESETf, XLP7_RESETf,
   3527             XLP8_RESETf, XLP9_RESETf, XLP10_RESETf, XLP11_RESETf,
   3528             XLP12_RESETf, XLP13_RESETf, XLP14_RESETf, XLP15_RESETf
   3529         };
   3530 
   3531         /* Find physical for the specified port */
   3532         phy_port = SOC_INFO(unit).port_l2p_mapping[port];
   3533 
   3534         /* Find lane index for the specified port (base port) */
   3535         for (i = 0; i < SOC_DRIVER(unit)->port_num_blktype; i++) {
   3536             block = SOC_PORT_IDX_BLOCK(unit, phy_port, i);
   3537             if (SOC_BLOCK_INFO(unit, block).type == SOC_BLK_XLPORT) {
   3538                 break;
   3539             }
   3540         }
   3541 
   3542         bindex = SOC_PORT_IDX_BINDEX(unit, phy_port, i);
   3543 
   3544         /* Get the current mode */
   3545         SOC_IF_ERROR_RETURN(READ_XLPORT_MODE_REGr(unit, port, &xmrval));
   3546         lanemode = soc_reg_field_get(unit, XLPORT_MODE_REGr, xmrval,
   3547                                      XPORT0_CORE_PORT_MODEf);
   3548 
   3549         /* Figure out the current number of lanes */
   3550         switch (lanemode) {
   3551         case SOC_TD2_PORT_MODE_QUAD:
   3552             lanenum = 1;
   3553             break;
   3554         case SOC_TD2_PORT_MODE_TRI_012:
   3555             lanenum = bindex == 0 ? 1 : 2;
   3556             break;
   3557         case SOC_TD2_PORT_MODE_TRI_023:
   3558             lanenum = bindex == 0 ? 2 : 1;
   3559             break;
   3560         case SOC_TD2_PORT_MODE_DUAL:
   3561             lanenum = 2;
   3562             break;
   3563         case SOC_TD2_PORT_MODE_SINGLE:
   3564             lanenum = 4;
   3565             break;
   3566         default:
   3567             return SOC_E_FAIL;
   3568         }
   3569 
   3570         if (lanenum == 1) {
   3571             /* Don't reset egress buffer if port only take 1 lane */
   3572             return SOC_E_NONE;
   3573         }
   3574 
   3575         if (lanenum == 4) { /* reset all 4 lanes */
   3576             value = 4;
   3577         } else if (bindex == 0) { /* reset lanes 0 and 1 */
   3578             value = 1;
   3579         } else { /* reset lanes 2 and 3 */
   3580             value = 2;
   3581         }
   3582 
   3583         /* Reset egress hardware resource */
   3584         reg = egr_reset_regs[si->port_serdes[port] / 8];
   3585         fields = egr_reset_fields[si->port_serdes[port] % 16];
   3586 
   3587         SOC_IF_ERROR_RETURN
   3588             (soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &errval));
   3589 
   3590         if (reset) {
   3591             /*
   3592              * Hold EDB port buffer in reset state and disable cell
   3593              * request generation in EP.
   3594              */
   3595             SOC_IF_ERROR_RETURN
   3596                 (READ_EGR_ENABLEm(unit, MEM_BLOCK_ALL, phy_port, &entry));
   3597             soc_mem_field32_set(unit, EGR_ENABLEm, &entry, PRT_ENABLEf, 0);
   3598             SOC_IF_ERROR_RETURN
   3599                 (WRITE_EGR_ENABLEm(unit, MEM_BLOCK_ALL, phy_port, &entry));
   3600 
   3601             soc_reg_field_set(unit, reg, &errval, fields, value);
   3602             SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0,
   3603                                                 errval));
   3604         } else {
   3605             /*
   3606              * Release EDB port buffer reset and enable cell request
   3607              * generation in EP.
   3608              */
   3609             soc_reg_field_set(unit, reg, &errval, fields, 0);
   3610             SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0,
   3611                                                 errval));
   3612 
   3613             SOC_IF_ERROR_RETURN
   3614                 (READ_EGR_ENABLEm(unit, MEM_BLOCK_ALL, phy_port, &entry));
   3615             soc_mem_field32_set(unit, EGR_ENABLEm, &entry, PRT_ENABLEf, 1);
   3616             SOC_IF_ERROR_RETURN
   3617                 (WRITE_EGR_ENABLEm(unit, MEM_BLOCK_ALL, phy_port, &entry));
   3618             /*
   3619              * Config credit after EGR_ENABLE is set.
   3620              */
   3621             SOC_IF_ERROR_RETURN(soc_port_credit_init(unit, port));
   3622         }
   3623     }
   3624 #endif
   3625         break;
   3626 
   3627 #if defined (BCM_TRIDENT2PLUS_SUPPORT)
   3628     case SOC_CHIP_BCM56860:
   3629         SOC_IF_ERROR_RETURN(soc_td2p_edb_buf_reset(unit, port, reset));
   3630     break;
   3631 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
   3632 
   3633     case SOC_CHIP_BCM56870:
   3634     case SOC_CHIP_BCM56770:
   3635     case SOC_CHIP_BCM56370:
   3636 #if defined(BCM_TRIDENT3_SUPPORT)
   3637     {
   3638         SOC_IF_ERROR_RETURN(soc_trident3_edb_buf_reset(unit, port, reset));
   3639     }
   3640 #endif
   3641     break;
   3642 
   3643 #if defined(BCM_TOMAHAWK_SUPPORT)
   3644     case SOC_CHIP_BCM56960:
   3645     case SOC_CHIP_BCM56965:
   3646         SOC_IF_ERROR_RETURN(soc_tomahawk_edb_buf_reset(unit, port, reset));
   3647         break;
   3648 #endif
   3649 #if defined(BCM_TOMAHAWK2_SUPPORT)
   3650     case SOC_CHIP_BCM56970:
   3651         SOC_IF_ERROR_RETURN(soc_tomahawk2_edb_buf_reset(unit, port, reset));
   3652         break;
   3653 #endif
   3654     case SOC_CHIP_BCM56560:
   3655 #if defined(BCM_APACHE_SUPPORT)
   3656     {
   3657         SOC_IF_ERROR_RETURN(soc_apache_edb_buf_reset(unit, port, reset));
   3658     }
   3659 #endif /*  BCM_APACHE_SUPPORT */
   3660         break;
   3661 
   3662     case SOC_CHIP_BCM56670:
   3663 
   3664 #if defined(BCM_MONTEREY_SUPPORT)
   3665 if(SOC_IS_MONTEREY(unit)) 
   3666     {
   3667         SOC_IF_ERROR_RETURN(soc_monterey_edb_buf_reset(unit, port, reset));
   3668     }
   3669 #endif /*  BCM_MONTEREY_SUPPORT */
   3670     default:
   3671         break;
   3672     }
   3673 
   3674     return SOC_E_NONE;
   3675 }
   3676 
   3677 int
   3678 soc_port_fifo_reset(int unit, soc_port_t port)
   3679 {
   3680     int phy_port, block, bindex, i;
   3681     uint32 rval, orig_rval;
   3682     static const soc_field_t fields[] = {
   3683         PORT0f, PORT1f, PORT2f, PORT3f
   3684     };
   3685 
   3686     switch (SOC_CHIP_GROUP(unit)) {
   3687     case SOC_CHIP_BCM56850:
   3688     case SOC_CHIP_BCM56860:
   3689 #if defined(BCM_TRIDENT2_SUPPORT)
   3690         /* OBM counters will be cleared by XLPORT_SOFT_RESET.
   3691          * Clear in counter thread accordingly.
   3692          */
   3693         SOC_IF_ERROR_RETURN(soc_td2_obm_counters_reset(unit, port));
   3694 #endif /* BCM_TRIDENT2_SUPPORT */
   3695         phy_port = SOC_INFO(unit).port_l2p_mapping[port];
   3696         SOC_IF_ERROR_RETURN(READ_XLPORT_SOFT_RESETr(unit, port, &rval));
   3697         orig_rval = rval;
   3698         for (i = 0; i < SOC_DRIVER(unit)->port_num_blktype; i++) {
   3699             block = SOC_PORT_IDX_BLOCK(unit, phy_port, i);
   3700             if (SOC_BLOCK_INFO(unit, block).type == SOC_BLK_XLPORT) {
   3701                 bindex = SOC_PORT_IDX_BINDEX(unit, phy_port, i);
   3702                 soc_reg_field_set(unit, XLPORT_SOFT_RESETr, &rval,
   3703                                   fields[bindex], 1);
   3704                 break;
   3705             }
   3706         }
   3707         SOC_IF_ERROR_RETURN(WRITE_XLPORT_SOFT_RESETr(unit, port, rval));
   3708         SOC_IF_ERROR_RETURN(WRITE_XLPORT_SOFT_RESETr(unit, port, orig_rval));
   3709         break;
   3710     case SOC_CHIP_BCM56560:
   3711     case SOC_CHIP_BCM56670:
   3712         {
   3713             soc_block_t port_blk;
   3714             soc_reg_t port_reset_reg;
   3715 
   3716             if (IS_CXX_PORT(unit, port) &&
   3717                 (SOC_INFO(unit).port_speed_max[port] >= 100000)) {
   3718                 port_blk = SOC_BLK_CLPORT;
   3719                 port_reset_reg = CLPORT_SOFT_RESETr;
   3720             } else if (IS_CL_PORT(unit, port) || IS_CLG2_PORT(unit, port)) {
   3721                 port_blk = SOC_BLK_CLPORT;
   3722                 port_reset_reg = CLPORT_SOFT_RESETr;
   3723             } else if (IS_CLG2_PORT(unit, port)) {
   3724                 port_blk = SOC_BLK_CLG2PORT;
   3725                 port_reset_reg = CLPORT_SOFT_RESETr;
   3726             } else {
   3727                 port_blk = SOC_BLK_XLPORT;
   3728                 port_reset_reg = XLPORT_SOFT_RESETr;
   3729             }
   3730 
   3731             phy_port = SOC_INFO(unit).port_l2p_mapping[port];    
   3732             SOC_IF_ERROR_RETURN(soc_reg32_get(unit, port_reset_reg, port, 0, &rval));
   3733             orig_rval = rval;
   3734             for (i = 0; i < SOC_DRIVER(unit)->port_num_blktype; i++) {
   3735                 block = SOC_PORT_IDX_BLOCK(unit, phy_port, i);
   3736                 if (SOC_BLOCK_INFO(unit, block).type == port_blk) {
   3737                     bindex = SOC_PORT_IDX_BINDEX(unit, phy_port, i);
   3738                     soc_reg_field_set(unit, port_reset_reg, &rval,
   3739                                       fields[bindex], 1);
   3740                     break;
   3741                 }
   3742             }
   3743             SOC_IF_ERROR_RETURN(soc_reg32_set(unit, port_reset_reg, port, 0, rval));
   3744             SOC_IF_ERROR_RETURN(soc_reg32_set(unit, port_reset_reg, port, 0, orig_rval));
   3745         }
   3746         break;
   3747     case SOC_CHIP_BCM56260:
   3748     case SOC_CHIP_BCM56270:
   3749         if (SOC_REG_PORT_VALID(unit, XLPORT_SOFT_RESETr, port)) {
   3750             bindex = ( port - 1 ) % 4;
   3751             SOC_IF_ERROR_RETURN(READ_XLPORT_SOFT_RESETr(unit, port, &rval));
   3752             orig_rval = rval;
   3753             soc_reg_field_set(unit, XLPORT_SOFT_RESETr, &rval,
   3754                     fields[bindex], 1);
   3755             SOC_IF_ERROR_RETURN(WRITE_XLPORT_SOFT_RESETr(unit, port, rval));
   3756             SOC_IF_ERROR_RETURN(WRITE_XLPORT_SOFT_RESETr(unit, port, orig_rval));
   3757         }
   3758         break;
   3759     default:
   3760         break;
   3761     }
   3762 
   3763     return SOC_E_NONE;
   3764 }
   3765 
   3766 int
   3767 soc_port_blk_init(int unit, soc_port_t port)
   3768 {    switch (SOC_CHIP_GROUP(unit)) {
   3769 #if defined(BCM_RAVEN_SUPPORT)
   3770     case SOC_CHIP_BCM56224:
   3771         if (IS_S_PORT(unit, port)) {
   3772             soc_pbmp_t pbmp_s0, pbmp_s1, pbmp_s3, pbmp_s4;
   3773             uint32     val32;
   3774             int        higig_mode;
   3775 
   3776             SOC_IF_ERROR_RETURN(READ_GPORT_CONFIGr(unit, port, &val32));
   3777             soc_reg_field_set(unit, GPORT_CONFIGr, &val32, CLR_CNTf, 1);
   3778             soc_reg_field_set(unit, GPORT_CONFIGr, &val32, GPORT_ENf, 1);
   3779             SOC_PBMP_WORD_SET(pbmp_s0, 0, 0x00000002);
   3780             SOC_PBMP_WORD_SET(pbmp_s1, 0, 0x00000004);
   3781             SOC_PBMP_WORD_SET(pbmp_s3, 0, 0x00000010);
   3782             SOC_PBMP_WORD_SET(pbmp_s4, 0, 0x00000020);
   3783  
   3784             higig_mode = IS_ST_PORT(unit, port) ? 1 : 0;
   3785             if (SOC_PBMP_MEMBER(pbmp_s0, port)) {
   3786                 /* The "SOP check enables" are not gated with "HiGig2 enables"
   3787                  * and "bond_disable_stacking".
   3788                  * Thus software need to enable/disable the SOP drop check
   3789                  * in HiGig2 mode as desired.
   3790                  */
   3791                 soc_reg_field_set(unit, GPORT_CONFIGr, &val32,
   3792                                   DROP_ON_WRONG_SOP_EN_S0f, 0);
   3793                 /* Enable HiGig 2 */
   3794                 /* Assuming that always use stacking port in HiGig mode */
   3795                 /* Actually, stacking port can also be used in ethernet mode */
   3796                 soc_reg_field_set(unit, GPORT_CONFIGr, &val32,
   3797                                   HGIG2_EN_S0f, higig_mode); 
   3798             } else if (SOC_PBMP_MEMBER(pbmp_s1, port)) {
   3799                 soc_reg_field_set(unit, GPORT_CONFIGr, &val32,
   3800                                   DROP_ON_WRONG_SOP_EN_S1f, 0);
   3801                 soc_reg_field_set(unit, GPORT_CONFIGr, &val32,
   3802                                   HGIG2_EN_S1f, higig_mode);
   3803             } else if (SOC_PBMP_MEMBER(pbmp_s3, port)) {
   3804                 soc_reg_field_set(unit, GPORT_CONFIGr, &val32,
   3805                                   DROP_ON_WRONG_SOP_EN_S3f, 0);
   3806                 soc_reg_field_set(unit, GPORT_CONFIGr, &val32,
   3807                                   HGIG2_EN_S3f, higig_mode); 
   3808             } else if (SOC_PBMP_MEMBER(pbmp_s4, port)) {
   3809                 soc_reg_field_set(unit, GPORT_CONFIGr, &val32,
   3810                                   DROP_ON_WRONG_SOP_EN_S4f, 0);
   3811                 soc_reg_field_set(unit, GPORT_CONFIGr, &val32,
   3812                                   HGIG2_EN_S4f, higig_mode); 
   3813             }
   3814 
   3815             SOC_IF_ERROR_RETURN
   3816                 (WRITE_GPORT_CONFIGr(unit, port, val32));
   3817 
   3818             /* Reset the clear-count bit after 64 clocks */
   3819             soc_reg_field_set(unit, GPORT_CONFIGr, &val32, CLR_CNTf, 0);
   3820             SOC_IF_ERROR_RETURN
   3821                 (WRITE_GPORT_CONFIGr(unit, port, val32));
   3822         }
   3823         break;
   3824 #endif /* BCM_RAVEN_SUPPORT */
   3825     default:
   3826         return SOC_E_NONE;
   3827     }
   3828     return SOC_E_NONE;
   3829 }
   3830 
   3831 int
   3832 soc_packet_purge_control_init(int unit, soc_port_t port)
   3833 {
   3834 #if defined(BCM_RAVEN_SUPPORT) || defined(BCM_TRX_SUPPORT)
   3835     uint32 mask;
   3836     mask = soc_property_port_get(unit, port, spn_GPORT_RSV_MASK, 0x070);
   3837 #endif
   3838     switch (SOC_CHIP_GROUP(unit)) {
   3839 #if defined(BCM_RAVEN_SUPPORT)
   3840     case SOC_CHIP_BCM56224:
   3841     case SOC_CHIP_BCM53314:
   3842         /* GPORT_RSV_MASK fields
   3843          * bit
   3844          * 0     frm_align_err_latch
   3845          * 1     rx_frm_stack_vlan_latch
   3846          * 2     rx_carrier_event_latch
   3847          * 3     rx_frm_gmii_err_latch
   3848          * 4     (frm_crc_err_latch | frm_crc_err)
   3849          * 5     frm_length_err_latch & ~frm_truncate_latch
   3850          * 6     frm_truncate_latch
   3851          * 7     ~rx_frm_err_latch & ~frm_truncate_latch
   3852          * 8     rx_frm_mltcast_latch
   3853          * 9     rx_frm_broadcast_latch
   3854          * 10    drbl_nbl_latch
   3855          * 11    cmd_rcv_latch
   3856          * 12    pause_rcv_latch
   3857          * 13    rx_cmd_op_err_latch
   3858          * 14    rx_frm_vlan_latch
   3859          * 15    rx_frm_unicast_latch
   3860          * 16    frm_truncate_latch
   3861          */
   3862         SOC_IF_ERROR_RETURN
   3863             (WRITE_GPORT_RSV_MASKr(unit, port, mask));
   3864         SOC_IF_ERROR_RETURN
   3865             (WRITE_GPORT_STAT_UPDATE_MASKr(unit, port, mask));
   3866         break;
   3867 #endif /* BCM_RAVEN_SUPPORT */
   3868 #ifdef BCM_TRX_SUPPORT
   3869     case SOC_CHIP_BCM56624:
   3870     case SOC_CHIP_BCM56680:
   3871     case SOC_CHIP_BCM56634:
   3872     case SOC_CHIP_BCM56524:
   3873     case SOC_CHIP_BCM56685:
   3874     case SOC_CHIP_BCM56820:
   3875     case SOC_CHIP_BCM56725:
   3876         SOC_IF_ERROR_RETURN
   3877             (WRITE_GPORT_RSV_MASKr(unit, port, mask));
   3878         SOC_IF_ERROR_RETURN
   3879             (WRITE_GPORT_STAT_UPDATE_MASKr(unit, port, mask));
   3880         break;
   3881     case SOC_CHIP_BCM56334:
   3882     case SOC_CHIP_BCM56142:
   3883     case SOC_CHIP_BCM56150:
   3884     case SOC_CHIP_BCM53400:
   3885     case SOC_CHIP_BCM56160:                
   3886     case SOC_CHIP_BCM53570:
   3887     case SOC_CHIP_BCM53540:
   3888         if (IS_XE_PORT(unit, port) || IS_HG_PORT(unit, port) ||
   3889             IS_XQ_PORT(unit, port)) {
   3890             SOC_IF_ERROR_RETURN
   3891                 (WRITE_QPORT_RSV_MASKr(unit, port, mask));
   3892             SOC_IF_ERROR_RETURN
   3893                 (WRITE_QPORT_STAT_UPDATE_MASKr(unit, port, mask)); 
   3894         } else {
   3895             SOC_IF_ERROR_RETURN
   3896                 (WRITE_GPORT_RSV_MASKr(unit, port, mask));
   3897             SOC_IF_ERROR_RETURN
   3898                 (WRITE_GPORT_STAT_UPDATE_MASKr(unit, port, mask));
   3899         }
   3900         break;
   3901 #endif
   3902     default:
   3903         return SOC_E_NONE;
   3904     }
   3905 
   3906     return SOC_E_NONE;
   3907 }
   3908 
   3909 int
   3910 soc_egress_enable(int unit, soc_port_t port, int enable)
   3911 {
   3912 #ifdef BCM_SHADOW_SUPPORT
   3913     soc_info_t          *si;
   3914 #endif
   3915 
   3916 #ifdef BCM_SHADOW_SUPPORT
   3917     si = &SOC_INFO(unit);
   3918 #endif
   3919 
   3920     switch (SOC_CHIP_GROUP(unit)) {
   3921 #if defined(BCM_RAVEN_SUPPORT) || defined(BCM_SCORPION_SUPPORT)
   3922     case SOC_CHIP_BCM56820:
   3923     case SOC_CHIP_BCM56224:
   3924     case SOC_CHIP_BCM53314:
   3925     case SOC_CHIP_BCM88732:
   3926     {
   3927         uint32 val32;
   3928         SOC_IF_ERROR_RETURN(READ_EGR_ENABLEr(unit, port, &val32));
   3929 #ifdef BCM_SHADOW_SUPPORT
   3930         if (!SOC_PBMP_MEMBER(si->port.disabled_bitmap, port)) {
   3931          soc_reg_field_set(unit, EGR_ENABLEr, &val32, PRT_ENABLEf, 1);
   3932         }
   3933 #else
   3934         soc_reg_field_set(unit, EGR_ENABLEr, &val32, PRT_ENABLEf, 1);
   3935 #endif
   3936         SOC_IF_ERROR_RETURN(WRITE_EGR_ENABLEr(unit, port, val32));
   3937         break;
   3938     }
   3939 #endif /* BCM_RAVEN_SUPPORT || BCM_SCORPION_SUPPORT */
   3940 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   3941     case SOC_CHIP_BCM56860:
   3942     {
   3943         int phy_port;
   3944         uint32 entry;
   3945 
   3946         phy_port = SOC_INFO(unit).port_l2p_mapping[port];
   3947         SOC_IF_ERROR_RETURN
   3948             (READ_EGR_ENABLEm(unit, MEM_BLOCK_ALL, phy_port, &entry));
   3949         soc_mem_field32_set(unit, EGR_ENABLEm, &entry, PRT_ENABLEf, enable);
   3950         SOC_IF_ERROR_RETURN
   3951             (WRITE_EGR_ENABLEm(unit, MEM_BLOCK_ALL, phy_port, &entry));
   3952         break;
   3953     }
   3954 #endif
   3955     default:
   3956         return SOC_E_NONE;
   3957     }
   3958     return SOC_E_NONE;
   3959 }
   3960 
   3961 int
   3962 soc_port_speed_update(int unit, soc_port_t port, int speed) 
   3963 {
   3964     switch (SOC_CHIP_GROUP(unit)) {
   3965     case SOC_CHIP_BCM56850:
   3966     case SOC_CHIP_BCM56860:
   3967 #ifdef BCM_TRIDENT2_SUPPORT
   3968         SOC_IF_ERROR_RETURN(soc_trident2_port_speed_update(unit, port, speed));
   3969 #endif /* BCM_TRIDENT2_SUPPORT */
   3970         break;
   3971     case SOC_CHIP_BCM56960:
   3972     case SOC_CHIP_BCM56965:
   3973 #ifdef BCM_TOMAHAWK_SUPPORT
   3974         SOC_IF_ERROR_RETURN(soc_tomahawk_port_speed_update(unit, port, speed));
   3975 #endif /* BCM_TOMAHAWK_SUPPORT */
   3976         break;
   3977     case SOC_CHIP_BCM56560:
   3978 #ifdef BCM_APACHE_SUPPORT
   3979         SOC_IF_ERROR_RETURN(soc_apache_port_speed_update(unit, port, speed));
   3980 #endif /* BCM_APACHE_SUPPORT */
   3981         break;
   3982     case SOC_CHIP_BCM56670:
   3983 #ifdef BCM_MONTEREY_SUPPORT
   3984         SOC_IF_ERROR_RETURN(soc_monterey_port_speed_update(unit, port, speed));
   3985 #endif /* BCM_MONTEREY_SUPPORT */
   3986         break;
   3987     case SOC_CHIP_BCM56870:
   3988 #ifdef BCM_TRIDENT3_SUPPORT
   3989         SOC_IF_ERROR_RETURN(soc_trident3_port_speed_update(unit, port, speed));
   3990 #endif /* BCM_TRIDENT3_SUPPORT */
   3991         break;
   3992     case SOC_CHIP_BCM53570:
   3993 #ifdef BCM_GREYHOUND2_SUPPORT
   3994         SOC_IF_ERROR_RETURN(
   3995                 soc_greyhound2_port_speed_update(unit, port, speed));
   3996 #endif /* BCM_GREYHOUND2_SUPPORT */
   3997         break;
   3998     default:
   3999         break;
   4000     }
   4001 
   4002     return SOC_E_NONE;
   4003 
   4004 }
   4005 
   4006 int
   4007 soc_port_hg_speed_get(int unit, soc_port_t port, int *speed)
   4008 {
   4009     switch (SOC_CHIP_GROUP(unit)) {
   4010     case SOC_CHIP_BCM56960:
   4011     case SOC_CHIP_BCM56965:
   4012 #ifdef BCM_TOMAHAWK_SUPPORT
   4013         SOC_IF_ERROR_RETURN(soc_th_port_hg_speed_get(unit, port, speed));
   4014 #endif /* BCM_TOMAHAWK_SUPPORT */
   4015         break;
   4016 #ifdef BCM_GREYHOUND2_SUPPORT
   4017     case SOC_CHIP_BCM53570:
   4018         SOC_IF_ERROR_RETURN(soc_greyhound2_port_hg_speed_get(unit, port, speed));
   4019         break;
   4020 #endif /* BCM_GREYHOUND2_SUPPORT */
   4021 #ifdef BCM_GREYHOUND_SUPPORT
   4022     case SOC_CHIP_BCM53400:
   4023         SOC_IF_ERROR_RETURN(soc_greyhound_port_hg_speed_get(unit, port, speed));
   4024         break;
   4025 #endif /* BCM_GREYHOUND_SUPPORT */
   4026     default:
   4027         break;
   4028     }
   4029 
   4030     return SOC_E_NONE;
   4031 }
   4032 
   4033 int
   4034 soc_port_thdo_rx_enable_set(int unit, soc_port_t port, int enable) 
   4035 {
   4036     switch (SOC_CHIP_GROUP(unit)) {
   4037     case SOC_CHIP_BCM56850:
   4038     case SOC_CHIP_BCM56860:
   4039 #ifdef BCM_TRIDENT2_SUPPORT
   4040         SOC_IF_ERROR_RETURN
   4041             (soc_trident2_port_thdo_rx_enable_set(unit, port, enable));
   4042 #endif
   4043         break;
   4044     case SOC_CHIP_BCM56560:
   4045 #ifdef BCM_APACHE_SUPPORT
   4046         SOC_IF_ERROR_RETURN(soc_apache_port_thdo_rx_enable_set(unit,
   4047                                                                port, enable));
   4048 #endif
   4049     break;
   4050     case SOC_CHIP_BCM56670:
   4051 #ifdef BCM_MONTEREY_SUPPORT
   4052         SOC_IF_ERROR_RETURN(soc_monterey_port_thdo_rx_enable_set(unit,
   4053                                                                port, enable));
   4054 #endif 
   4055      break; 
   4056     default:
   4057         break;
   4058     }
   4059 
   4060     return SOC_E_NONE;
   4061 
   4062 }
   4063 
   4064 #endif /* defined(BCM_ESW_SUPPORT) */
   4065 
   4066 int
   4067 soc_llfc_xon_set(int unit, soc_port_t port, int enable)
   4068 {
   4069     if (enable) {
   4070         /* no action required */
   4071     } else {
   4072 #if defined(BCM_ESW_SUPPORT)
   4073         if (soc_feature(unit, soc_feature_llfc_force_xon)) {
   4074             SOC_IF_ERROR_RETURN(soc_mmu_backpressure_clear(unit, port));
   4075         }
   4076 #endif /* defined(BCM_ESW_SUPPORT) */
   4077     }
   4078 
   4079     return SOC_E_NONE;
   4080 }
   4081 
   4082 /* function to setup EEE Wake/LPI timers per speed */
   4083 int
   4084 soc_port_eee_timers_setup(int unit, soc_port_t port, int speed)
   4085 {
   4086     switch (SOC_CHIP_GROUP(unit)) {
   4087 #ifdef BCM_GREYHOUND_SUPPORT
   4088     case SOC_CHIP_BCM53400:
   4089         SOC_IF_ERROR_RETURN(soc_gh_port_eee_timers_setup(unit, port, speed));
   4090         break;
   4091 #endif  /* BCM_GREYHOUND_SUPPORT */
   4092     default :
   4093         break;
   4094     }
   4095     return SOC_E_NONE;
   4096 }
   4097  
   4098 /* function to provide the ways to assigning EEE timers during MAC init.
   4099  *
   4100  * Note :
   4101  *  1. MAC has it own EEE timer default value but these setting for some
   4102  *      specific chip might not proper for EEE operation.
   4103  *  2. Once EEE timers at reset value=0 on a MAC, Packet lost will happen.
   4104  */
   4105 int
   4106 soc_port_eee_timers_init(int unit, soc_port_t port, int speed)
   4107 {
   4108     if (!soc_feature(unit, soc_feature_eee)) {
   4109         return SOC_E_NONE;
   4110     }
   4111  
   4112     switch (SOC_CHIP_GROUP(unit)) {
   4113 #ifdef BCM_GREYHOUND_SUPPORT
   4114     case SOC_CHIP_BCM53400:
   4115         SOC_IF_ERROR_RETURN(soc_gh_port_eee_ref_count_init(unit, port));
   4116         SOC_IF_ERROR_RETURN(soc_gh_port_eee_timers_setup(unit, port, speed));
   4117         break;
   4118 #endif  /* BCM_GREYHOUND_SUPPORT */
   4119     default :
   4120         break;
   4121     }
   4122     return SOC_E_NONE;
   4123 }
   4124 
   4125 /*
   4126  * Function:
   4127  *      soc_granular_speed_get
   4128  * Purpose:
   4129  *      Map MMU_CELL_CREDIT to port speed
   4130  * Parameters:
   4131  *      unit   - (IN) unit number
   4132  *      port   - (IN) port number
   4133  *      speed  - (OUT) speed in Mbps
   4134  * Returns:
   4135  *      N/A
   4136  */
   4137 soc_error_t
   4138 soc_granular_speed_get(int unit, soc_port_t port, int *speed)
   4139 {
   4140     soc_error_t rc;
   4141 
   4142     switch (SOC_CHIP_GROUP(unit)) {
   4143 #if defined (BCM_TRIDENT3_SUPPORT)
   4144         case SOC_CHIP_BCM56870:
   4145             rc = soc_td3_granular_speed_get(unit, port, speed);
   4146             break;
   4147 #endif
   4148 #if defined (BCM_TOMAHAWK_SUPPORT)
   4149         case SOC_CHIP_BCM56960:
   4150         case SOC_CHIP_BCM56965:
   4151         case SOC_CHIP_BCM56970:
   4152             rc = soc_th_granular_speed_get(unit, port, speed);
   4153             break;
   4154 #endif
   4155 #if defined (BCM_GREYHOUND2_SUPPORT)
   4156         case SOC_CHIP_BCM53570:
   4157             rc = soc_greyhound2_granular_speed_get(unit, port, speed);
   4158             break;
   4159 #endif  /* BCM_GREYHOUND2_SUPPORT */
   4160         default:
   4161             rc = SOC_E_PARAM;
   4162             break;
   4163     }
   4164     return rc;
   4165 }
   4166 
   4167 /*
   4168  * Function:
   4169  *      soc_mac_x_sync_fifo_reset
   4170  * Purpose:
   4171  *      Reset a XMAC loopback syc fifo
   4172  * Parameters:
   4173  *      unit - XGS unit #.
   4174  *      port - XGS unit # on unit.
   4175  * Returns:
   4176  *      SOC_E_XXX
   4177  */
   4178 int
   4179 soc_mac_x_sync_fifo_reset(int unit, soc_port_t port)
   4180 {
   4181 #if defined(BCM_TRIUMPH3_SUPPORT)
   4182     if (SOC_IS_TRIUMPH3(unit) && SOC_INFO(unit).port_num_lanes[port] == 4) {
   4183         static const soc_field_t line_lb_field[] = {
   4184             XMAC0_LINE_LPBK_RESETf,
   4185             XMAC1_LINE_LPBK_RESETf,
   4186             XMAC2_LINE_LPBK_RESETf
   4187         };
   4188         int phy_port, bindex = -1;
   4189         uint32 rval;
   4190         
   4191         phy_port = SOC_INFO(unit).port_l2p_mapping[port];
   4192         if (phy_port != -1) {
   4193             bindex = SOC_PORT_BINDEX(unit, phy_port) / 4;
   4194             if (bindex != -1) {
   4195                 SOC_IF_ERROR_RETURN(READ_PORT_MAC_CONTROLr(unit, port, &rval));
   4196                 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval, 
   4197                                   line_lb_field[bindex], 1);
   4198                 SOC_IF_ERROR_RETURN(WRITE_PORT_MAC_CONTROLr(unit, port, rval));
   4199                 sal_udelay(10);
   4200                 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval, 
   4201                                   line_lb_field[bindex], 0);    
   4202                 SOC_IF_ERROR_RETURN(WRITE_PORT_MAC_CONTROLr(unit, port, rval)); 
   4203             }
   4204         }
   4205     }
   4206 #endif /* BCM_TRIUMPH3_SUPPORT */
   4207     return SOC_E_NONE;
   4208 }
   4209 
   4210 /*
   4211  * Function:
   4212  *      soc_pgw_ge_rx_fifo_reset
   4213  * Purpose:
   4214  *      Reset PGW Rx FIFO to prevent packets entering switch
   4215  * Parameters:
   4216  *      unit - XGS unit #.
   4217  *      port - XGS unit # on unit.
   4218  *      reset - TRUE/FALSE
   4219  * Returns:
   4220  *      SOC_E_XXX
   4221  */
   4222 int soc_pgw_rx_fifo_reset(int unit, int port, int reset)
   4223 {
   4224     if (!soc_feature(unit, soc_feature_unimac_reset_wo_clock)) {
   4225         return SOC_E_UNAVAIL;
   4226     }
   4227 
   4228     switch (SOC_CHIP_GROUP(unit)) {
   4229 #ifdef BCM_HURRICANE3_SUPPORT
   4230     case SOC_CHIP_BCM56160:
   4231     case SOC_CHIP_BCM53540:
   4232         SOC_IF_ERROR_RETURN
   4233             (soc_hurricane3_pgw_rx_fifo_reset(unit, port, reset));
   4234         break;
   4235 #endif  /* BCM_HURRICANE3_SUPPORT */
   4236     default :
   4237         break;
   4238     }
   4239 
   4240     return SOC_E_NONE;
   4241 }
   4242 
   4243 /*
   4244  * Function:
   4245  *      soc_port_mmu_buffer_enable
   4246  * Purpose:
   4247  *      MMU memory buffer enable configuration to specify which
   4248  *      egress ports are allowed to buffer packets.
   4249  * Parameters:
   4250  *      unit - XGS unit #.
   4251  *      port - XGS unit # on unit.
   4252  *      enable - TRUE/FALSE
   4253  * Returns:
   4254  *      SOC_E_XXX
   4255  */
   4256 int
   4257 soc_port_mmu_buffer_enable(int unit, int port, int enable)
   4258 {
   4259     switch (SOC_CHIP_GROUP(unit)) {
   4260 #if defined (BCM_HURRICANE2_SUPPORT)
   4261         case SOC_CHIP_BCM56150:
   4262         case SOC_CHIP_BCM53400:
   4263         case SOC_CHIP_BCM56160:
   4264         {
   4265             uint32      val, pbmp;
   4266             pbmp_t      mmu_pbmp;
   4267 
   4268             SOC_PBMP_CLEAR(mmu_pbmp);
   4269             SOC_IF_ERROR_RETURN(READ_MMUPORTENABLEr(unit, &val));
   4270             pbmp = soc_reg_field_get(unit, MMUPORTENABLEr, val, MMUPORTENABLEf);
   4271             SOC_PBMP_WORD_SET(mmu_pbmp, 0, pbmp);
   4272             if (enable) {
   4273                 SOC_PBMP_PORT_ADD(mmu_pbmp, port);
   4274             } else {
   4275                 SOC_PBMP_PORT_REMOVE(mmu_pbmp, port);
   4276             }
   4277             soc_reg_field_set(unit, MMUPORTENABLEr, &val, MMUPORTENABLEf,
   4278                               SOC_PBMP_WORD_GET(mmu_pbmp, 0));
   4279             SOC_IF_ERROR_RETURN(WRITE_MMUPORTENABLEr(unit, val));
   4280             break;
   4281         }
   4282 #endif /* BCM_HURRICANE2_SUPPORT */
   4283 #if defined (BCM_GREYHOUND2_SUPPORT)
   4284         case SOC_CHIP_BCM53570:
   4285         {
   4286             soc_info_t  *si = &SOC_INFO(unit);
   4287             pbmp_t      mmu_pbmp;
   4288             uint32      val, pbmp;
   4289             int         phy_port, mmu_port, word;
   4290             static const soc_reg_t mmu_reg[] = {MMUPORTENABLE_0r,
   4291                                                 MMUPORTENABLE_1r,
   4292                                                 MMUPORTENABLE_2r};
   4293 
   4294             SOC_PBMP_CLEAR(mmu_pbmp);
   4295             phy_port = si->port_l2p_mapping[port];
   4296             mmu_port = si->port_p2m_mapping[phy_port];
   4297             word = mmu_port / 32;
   4298             SOC_IF_ERROR_RETURN(
   4299                 soc_reg32_get(unit, mmu_reg[word], REG_PORT_ANY, 0, &val));
   4300             pbmp = soc_reg_field_get(unit, mmu_reg[word], val, MMUPORTENABLEf);
   4301             SOC_PBMP_WORD_SET(mmu_pbmp, word, pbmp);
   4302             if (enable) {
   4303                 SOC_PBMP_PORT_ADD(mmu_pbmp, mmu_port);
   4304             } else {
   4305                 SOC_PBMP_PORT_REMOVE(mmu_pbmp, mmu_port);
   4306             }
   4307             soc_reg_field_set(unit, mmu_reg[word], &val, MMUPORTENABLEf,
   4308                               SOC_PBMP_WORD_GET(mmu_pbmp, word));
   4309             SOC_IF_ERROR_RETURN(
   4310                 soc_reg32_set(unit, mmu_reg[word], REG_PORT_ANY, 0, val));
   4311             break;
   4312         }
   4313 #endif /* BCM_GREYHOUND2_SUPPORT */
   4314         default:
   4315             break;
   4316     }
   4317     return SOC_E_NONE;
   4318 }