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

rate.c (12675B)


      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  * Rate CLI commands
      8  *
      9  * Note: the "rate" controls Storm Control, as opposed to packet rate
     10  * control (bcm_port_rate_*).
     11  */
     12 
     13 #include <appl/diag/system.h>
     14 #include <appl/diag/parse.h>
     15 #include <appl/diag/dport.h>
     16 #include <shared/bsl.h>
     17 #include <bcm/init.h>
     18 #include <bcm/error.h>
     19 #include <bcm/rate.h>
     20 #include <bcm/debug.h>
     21 
     22 #include <soc/drv.h>
     23 #define _DFT_MAGIC_NUMBER -123456798
     24 
     25 /*
     26  * Manage packet rate controls
     27  */
     28 cmd_result_t
     29 cmd_esw_rate(int unit, args_t *a)
     30 {
     31     int limit = _DFT_MAGIC_NUMBER; /* magic number */
     32     int	fRateBCast;
     33     int fRateMCast;
     34     int fRateDLF;
     35     int fmask = 0;
     36     int flags = 0;
     37     int r;
     38     parse_table_t pt;
     39     bcm_pbmp_t pbmp;
     40     bcm_port_config_t pcfg;
     41     int limitGet = FALSE;
     42     int bRateSet, mRateSet,dlfRateSet;
     43     int bRateFlGet, mRateFlGet, dlfRateFlGet;
     44     int bRateLmGet, mRateLmGet, dlfRateLmGet;
     45     int displayOnly = 0;
     46     soc_port_t p, dport;
     47 
     48     if (!sh_check_attached(ARG_CMD(a), unit)) {
     49 	return CMD_FAIL;
     50     }
     51 
     52     if (bcm_port_config_get(unit, &pcfg) != BCM_E_NONE) {
     53         cli_out("%s: Error: bcm ports not initialized\n", ARG_CMD(a));
     54         return CMD_FAIL;
     55     }
     56 
     57     pbmp       = pcfg.all;  /* All ports by default */
     58     limit      = _DFT_MAGIC_NUMBER;
     59     fRateBCast = _DFT_MAGIC_NUMBER;
     60     fRateMCast = _DFT_MAGIC_NUMBER;
     61     fRateDLF   = _DFT_MAGIC_NUMBER;
     62 
     63     if (ARG_CNT(a)) {
     64         parse_table_init(unit, &pt);
     65         parse_table_add(&pt, "PortBitMap", PQ_DFL|PQ_PBMP|PQ_BCM,
     66                     (void *)0, &pbmp, 0);
     67         parse_table_add(&pt, "Limit", PQ_DFL|PQ_HEX,
     68                     INT_TO_PTR(limit) , &limit, 0);
     69         parse_table_add(&pt, "Bcast", PQ_DFL|PQ_BOOL,
     70                     (void *)0, &fRateBCast, 0);
     71         parse_table_add(&pt, "Mcast",        PQ_BOOL,
     72                     INT_TO_PTR(fRateMCast), &fRateMCast, 0);
     73         parse_table_add(&pt, "Dlf", PQ_DFL|PQ_BOOL,
     74                     INT_TO_PTR(fRateDLF), &fRateDLF, 0);
     75 
     76         if (parse_arg_eq(a, &pt) < 0) {
     77             cli_out("%s: Error: Unknown option: %s\n", ARG_CMD(a), ARG_CUR(a));
     78             parse_arg_eq_done(&pt);
     79             return(CMD_FAIL);
     80         }
     81         parse_arg_eq_done(&pt);
     82         fmask = flags = 0;   
     83 
     84         /* Verify what is being changed */
     85         if (fRateBCast != _DFT_MAGIC_NUMBER) {
     86             fmask |= BCM_RATE_BCAST;
     87             if (fRateBCast == TRUE) {
     88                 flags |= BCM_RATE_BCAST;
     89             }
     90         }
     91         if (fRateMCast != _DFT_MAGIC_NUMBER) {
     92             fmask |= BCM_RATE_MCAST;
     93             if (fRateMCast == TRUE) {
     94                 flags |= BCM_RATE_MCAST;
     95             }
     96         }
     97         if (fRateDLF != _DFT_MAGIC_NUMBER) {
     98             fmask |= BCM_RATE_DLF;
     99             if (fRateDLF == TRUE) {
    100                 flags |= BCM_RATE_DLF;
    101             }
    102         }
    103         if (limit < 0 && limit != _DFT_MAGIC_NUMBER) {
    104             cli_out("Error: Negative rate limit: %d is not " 
    105                     "allowed\n", (int)limit);
    106         }
    107 
    108         /* Check whether original value shall be read back */ 
    109         if (fmask == 0 && limit == _DFT_MAGIC_NUMBER) {
    110             /* only PBM is specified */
    111             displayOnly = TRUE;
    112         } else if (limit == _DFT_MAGIC_NUMBER) {
    113             limitGet = TRUE;
    114         }
    115 
    116     } else {
    117       displayOnly = TRUE;
    118     }
    119 
    120     if (displayOnly) {
    121         cli_out("Current settings:\n");
    122 
    123         DPORT_BCM_PBMP_ITER(unit, pbmp, dport, p) {
    124             cli_out("%4s:",BCM_PORT_NAME(unit, p));
    125             if ((r = bcm_rate_bcast_get(unit, &limit, &flags, p)) < 0) {
    126                 cli_out(" Bcast = UNKNOWN, %s;", bcm_errmsg(r));
    127             } else if (flags == BCM_RATE_BCAST) {
    128                 cli_out(" Bcast= TRUE,Limit=%d;", limit);
    129             } else {
    130                 cli_out(" Bcast=FALSE ;");
    131             }
    132             if ((r = bcm_rate_mcast_get(unit, &limit, &flags, p)) < 0) {
    133                 cli_out(" Mcast=UNKNOWN, %s;", bcm_errmsg(r));
    134             } else if (flags == BCM_RATE_MCAST) {
    135                 cli_out(" Mcast= TRUE,Limit=%d;", limit);
    136             } else {
    137                 cli_out(" Mcast=FALSE ;");
    138             }
    139             if ((r = bcm_rate_dlfbc_get(unit, &limit, &flags, p)) < 0) {
    140                 cli_out(" Dlf=UNKNOWN, %s;", bcm_errmsg(r));
    141             } else if (flags == BCM_RATE_DLF) {
    142                 cli_out(" Dlfbc= TRUE,Limit=%d;", limit);
    143             } else {
    144                 cli_out(" Dlfbc=FALSE ;");
    145             }
    146              cli_out("\n");
    147         }
    148         return(CMD_OK);
    149     }
    150 
    151     bRateSet   = mRateSet   = dlfRateSet   = FALSE;
    152     bRateFlGet = mRateFlGet = dlfRateFlGet = FALSE;
    153     bRateLmGet = mRateLmGet = dlfRateLmGet = FALSE;
    154     fRateBCast = fRateMCast = fRateDLF     = 0;
    155 
    156     if (!fmask) { 
    157         if (limitGet == FALSE) {
    158             /* only new limit specified */
    159             bRateSet   = mRateSet   = dlfRateSet   = TRUE;
    160             bRateFlGet = mRateFlGet = dlfRateFlGet = TRUE;
    161         }
    162     } else {
    163         if ((fmask & BCM_RATE_BCAST)) {
    164             bRateSet = TRUE;
    165             fRateBCast = flags & BCM_RATE_BCAST;
    166             if (fRateBCast && limitGet) {
    167                 bRateLmGet = TRUE;
    168             }
    169         } 
    170         if ((fmask & BCM_RATE_MCAST)) {
    171             mRateSet = TRUE;
    172             fRateMCast = flags & BCM_RATE_MCAST;
    173             if (fRateMCast && limitGet) {
    174                 mRateLmGet = TRUE;
    175             }
    176         } 
    177         if ((fmask & BCM_RATE_DLF)) {
    178             dlfRateSet = TRUE;
    179             fRateDLF = flags & BCM_RATE_DLF;
    180             if (fRateDLF && limitGet) {
    181                 dlfRateLmGet = TRUE;
    182             }
    183         } 
    184     }
    185 
    186     /* Set new config in ports */
    187     /* coverity[overrun-local] */
    188     DPORT_BCM_PBMP_ITER(unit, pbmp, dport, p) {
    189         /* Brocast meter */
    190         if (bRateSet) {
    191             int limitPro, flagPro;
    192             int oriLimit, oriFlag;
    193             int r = 0;
    194 
    195             if (bRateFlGet || bRateLmGet) {
    196                 if ((r = bcm_rate_bcast_get(unit, &oriLimit, &oriFlag, p)) < 0) {
    197                     cli_out("%4s Error: can not get Brocast limit info: %s\n", 
    198                             BCM_PORT_NAME(unit, p), bcm_errmsg(r));
    199                 }
    200              }
    201 
    202              limitPro = (!r && bRateLmGet)? oriLimit : limit;
    203              flagPro  = (!r && bRateFlGet)? oriFlag  : fRateBCast;
    204 
    205              if (!r && (r = bcm_rate_bcast_set(unit, 
    206                                         limitPro, flagPro, p)) < 0) {
    207                  cli_out("%4s Error: can not set Broadcast rate: %s\n", 
    208                          BCM_PORT_NAME(unit, p), bcm_errmsg(r));
    209              }
    210           }
    211         /* Mcast meter control */
    212         if (mRateSet) {
    213             int limitPro, flagPro;
    214             int oriLimit, oriFlag;
    215             int r = 0;
    216 
    217             if (mRateFlGet || mRateLmGet) {
    218                 if ((r = bcm_rate_mcast_get(unit, &oriLimit, &oriFlag, p)) < 0) {
    219                     cli_out("%4s Error: can not get Mcast limit info: %s\n", 
    220                             BCM_PORT_NAME(unit, p), bcm_errmsg(r));
    221                 }
    222              }
    223 
    224              limitPro = (!r && mRateLmGet)? oriLimit : limit;
    225              flagPro  = (!r && mRateFlGet)? oriFlag  : fRateMCast;
    226 
    227              if (!r && (r = bcm_rate_mcast_set(unit, 
    228                                         limitPro, flagPro, p)) < 0) {
    229                  cli_out("%4s Error: can not set Mcast rate: %s\n", 
    230                          BCM_PORT_NAME(unit, p), bcm_errmsg(r));
    231              }
    232           }
    233         /* Dlf meter */
    234         if (dlfRateSet) {
    235             int limitPro, flagPro;
    236             int oriLimit, oriFlag;
    237             int r = 0;
    238 
    239             if (dlfRateFlGet || dlfRateLmGet) {
    240                 if ((r = bcm_rate_dlfbc_get(unit, &oriLimit, &oriFlag, p)) < 0) {
    241                     cli_out("%4s Error: can not get DLF limit info: %s\n", 
    242                             BCM_PORT_NAME(unit, p), bcm_errmsg(r));
    243                 }
    244              }
    245 
    246              limitPro = (!r && dlfRateLmGet)? oriLimit : limit;
    247              flagPro  = (!r && dlfRateFlGet)? oriFlag  : fRateDLF;
    248 
    249              if (!r && (r = bcm_rate_dlfbc_set(unit, 
    250                                         limitPro, flagPro, p)) < 0) {
    251                  cli_out("%4s Error: can not set DLF rate: %s\n", 
    252                          BCM_PORT_NAME(unit, p), bcm_errmsg(r));
    253              }
    254           }
    255     }
    256     return CMD_OK;
    257 }
    258 
    259 /*
    260  * Function:
    261  *      cmd_bw_rate
    262  * Purpose:
    263  *      Set/display of bandwidth rate mitiring limits.
    264  * Parameters:
    265  *      unit - SOC unit #
    266  *      args - pointer to comand line arguments
    267  * Returns:
    268  *      CMD_OK/CMD_FAIL
    269  */
    270 char cmd_bw_rate_usage[] =
    271     "Set/Display port bandwidth rate limiting.\n"
    272     "Parameters: <pbm> flags rate max_burst\n\t"
    273     "    flag is one of the bcast | mcast | dlf\n\t"
    274     "    rate and max_burst are values in kilobits (1000 bits) per second\n";
    275                             
    276 cmd_result_t
    277 cmd_bw_rate(int unit, args_t *a)
    278 {
    279     bcm_pbmp_t      pbm;
    280     bcm_port_config_t pcfg;
    281     soc_port_t      p, dport;
    282     int             flags = 0;
    283     int             rv;
    284     uint32          rate = 0xFFFFFFFF;
    285     uint32          burst = 0xFFFFFFFF;
    286     char           *c;
    287 
    288 
    289     if (!sh_check_attached(ARG_CMD(a), unit)) {
    290         return CMD_FAIL;
    291     }
    292 
    293     /* Check for metering capabilities */
    294     if (! soc_feature(unit, soc_feature_storm_control)) {
    295         cli_out("%s: Error: bandwidth limit unavailable for this device\n", 
    296                 ARG_CMD(a));
    297         return CMD_OK;
    298     }
    299 
    300     if (bcm_port_config_get(unit, &pcfg) != BCM_E_NONE) {
    301         cli_out("%s: Error: bcm ports not initialized\n", ARG_CMD(a));
    302         return CMD_FAIL;
    303     }
    304 
    305     if ((c = ARG_GET(a)) == NULL) {
    306         cli_out("%s: Error: unspecified port bitmap: %s\n",
    307                 ARG_CMD(a), c);
    308         return CMD_FAIL;
    309     } else if (parse_bcm_pbmp(unit, c, &pbm) < 0) {
    310         cli_out("%s: Error: unrecognized port bitmap: %s\n",
    311                 ARG_CMD(a), c);
    312         return CMD_FAIL;
    313     }
    314 
    315     /* Apply PortRate only to those ports which support it */
    316     BCM_PBMP_AND(pbm, pcfg.e);
    317     if (BCM_PBMP_IS_NULL(pbm)) {
    318         cli_out("No ports specified.\n");
    319         return CMD_OK;
    320     }
    321     
    322     /* retrieving the flags */
    323     if ((c = ARG_GET(a)) != NULL) {
    324         /* Get user provided flag */
    325         if (0 == sal_strncasecmp(c, "bcast", sal_strlen(c))){
    326             flags = BCM_RATE_BCAST;
    327         } else if (0 == sal_strncasecmp(c, "mcast", sal_strlen(c))) {
    328             flags = BCM_RATE_MCAST;
    329         } else if (0 == sal_strncasecmp(c, "dlf", sal_strlen(c))) {
    330             flags = BCM_RATE_DLF;
    331         } else {
    332             cli_out("%s: Error: unrecognized rate type: %s\n",
    333                     ARG_CMD(a), c);
    334             return CMD_FAIL;
    335         }
    336     }
    337     else {
    338         cli_out("%s: Error: missing rate type: %s need bcast or mcast or dlf\n",
    339                 ARG_CMD(a), c);
    340         return CMD_FAIL;
    341     }
    342 
    343     /* Set or get */
    344     if ((c = ARG_GET(a)) == NULL) {     /* Get part */
    345         /* coverity[overrun-local] */
    346         DPORT_BCM_PBMP_ITER(unit, pbm, dport, p) {
    347             rv = bcm_rate_bandwidth_get(unit, p, flags, &rate, &burst);
    348             if (rv < 0 ) {
    349                 cli_out("%s port %s: ERROR: bcm_rate_bandwidth_get: "
    350                         "%s\n",
    351                         ARG_CMD(a), BCM_PORT_NAME(unit, p), bcm_errmsg(rv));
    352                 return CMD_FAIL;
    353             }
    354             if (rate) {
    355                 cli_out("%4s:", BCM_PORT_NAME(unit, p));
    356                 if (rate < 64) { 
    357                     cli_out("\tBandwidth meter: ? kbps ? kbits max burst.\n");
    358                 } else {
    359                     cli_out("\tBandwidth meter: "
    360                             "%8d kbps %8d kbits max burst.\n",
    361                             rate, burst);
    362                 }
    363             }
    364         }
    365     } else {      /* Set Part */
    366         rate = parse_integer(c);
    367         if ((c = ARG_GET(a)) != NULL) {
    368             burst = parse_integer(c);
    369         } else {
    370             cli_out("%s: Error: missing port burst size\n",
    371                     ARG_CMD(a));
    372             return CMD_FAIL;
    373         }
    374         DPORT_BCM_PBMP_ITER(unit, pbm, dport, p) {
    375             rv = bcm_rate_bandwidth_set(unit, p, flags, rate, burst); 
    376             if (rv < 0) {
    377                 cli_out("%s: ERROR: bcm_port_rate_ingress_set: %s\n",
    378                         ARG_CMD(a), bcm_errmsg(rv));
    379                 return CMD_FAIL;
    380             }
    381         }
    382     }
    383 
    384     return CMD_OK;
    385 }
    386