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

alpm_tr.c (9928B)


      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  * File:    alpm_tr.c
      7  * Purpose: ALPM trace & log
      8  */
      9 
     10 #include <shared/bsl.h>
     11 
     12 #include <soc/mem.h>
     13 #include <soc/drv.h>
     14 #include <soc/debug.h>
     15 #include <soc/error.h>
     16 #include <soc/format.h>
     17 #include <soc/lpm.h>
     18 #include <soc/trident2.h>
     19 #include <soc/tomahawk.h>
     20 
     21 #include <shared/util.h>
     22 #include <shared/l3.h>
     23 
     24 #if defined(ALPM_ENABLE)
     25 
     26 #include <bcm/l3.h>
     27 #include <bcm_int/esw/l3.h>
     28 #include <bcm_int/esw/firebolt.h>
     29 #include <bcm_int/esw/alpm.h>
     30 #include <bcm_int/esw/alpm_util.h>
     31 
     32 #include <sal/appl/io.h>
     33 
     34 _alpm_trace_t *alpm_trace[SOC_MAX_NUM_DEVICES];
     35 
     36 /* ALPM trace log enable */
     37 int
     38 alpm_trace_set(int u, int val)
     39 {
     40     if (ALPMTR(u) == NULL) {
     41         cli_out("alpm trace not initialized yet\n");
     42         return BCM_E_INIT;
     43     }
     44 
     45     ALPMTR_TRACE_EN(u) = val;
     46     return BCM_E_NONE;
     47 }
     48 
     49 /* ALPM trace wrap enable */
     50 int
     51 alpm_trace_wrap_set(int u, int val)
     52 {
     53     if (ALPMTR(u) == NULL) {
     54         cli_out("alpm trace not initialized yet\n");
     55         return BCM_E_INIT;
     56     }
     57 
     58     ALPMTR_WRAP_EN(u) = val;
     59     return BCM_E_NONE;
     60 }
     61 
     62 /* ALPM trace log clear */
     63 int
     64 alpm_trace_clear(int u)
     65 {
     66     if (ALPMTR(u) == NULL) {
     67         cli_out("alpm trace not initialized yet\n");
     68         return BCM_E_INIT;
     69     }
     70 
     71     if (ALPMTR_INITED(u)) {
     72         ALPMTR_CNT(u) = 0;
     73         ALPMTR_CURR(u) = ALPMTR_START(u) = ALPMTR_BUF(u);
     74         cli_out("alpm trace log deleted\n");
     75     }
     76 
     77     return BCM_E_NONE;
     78 }
     79 
     80 /* ALPM trace periodic sanity check (route add & delete)
     81    enable = -1 for show trace sanity,
     82    enable = 0 means trace sanity check disabled
     83    enable > 0 means sanity check freq
     84 */
     85 int
     86 alpm_trace_sanity(int u, int enable, int start, int end)
     87 {
     88     if (ALPMTR(u) == NULL) {
     89         cli_out("alpm trace not initialized yet\n");
     90         return BCM_E_INIT;
     91     }
     92 
     93     if (enable >= 0) {
     94         ALPMTR_SANITY_EN(u) = enable;
     95         ALPMTR_SANITY_START(u) = start;
     96         ALPMTR_SANITY_END(u) = end;
     97     }
     98 
     99     if (ALPMTR_SANITY_EN(u) == 0) {
    100         cli_out("alpm trace sanity disabled\n");
    101     } else {
    102         cli_out("alpm trace sanity enabled (enable:%d start:%d end:%d)\n",
    103                 ALPMTR_SANITY_EN(u), ALPMTR_SANITY_START(u),
    104                 ALPMTR_SANITY_END(u));
    105     }
    106 
    107     return BCM_E_NONE;
    108 }
    109 
    110 /* ALPM trace log for defip route op (ALPM_TRACE_ADD or ALPM_TRACE_DELETE) */
    111 int
    112 alpm_trace_log(int u, int op, _bcm_defip_cfg_t *cfg, int nh_idx, int rc)
    113 {
    114     int i, alloc_sz;
    115     int rv = BCM_E_NONE;
    116 
    117     if (ALPMTR(u) == NULL) {
    118         return BCM_E_INIT;
    119     }
    120     if (!ALPMTR_TRACE_EN(u)) {
    121         return rv;
    122     }
    123     if ((!ALPMTR_WRAP_EN(u)) && ALPMTR_WRAP(u)) {
    124         return rv; /* if trace wrap is disabled and next log will be wrapped */
    125     }
    126 
    127     if (!ALPMTR_INITED(u)) {
    128         ALPMTR_CNT(u) = 0;
    129         /* Use ALPM_TRACE_SIZE+1 just for reaching buf limit check */
    130         alloc_sz = sizeof(_alpm_log_t) * (ALPM_TRACE_SIZE + 1);
    131         ALPM_ALLOC_EG(ALPMTR_BUF(u), alloc_sz, "alpm trace log");
    132         ALPMTR_CURR(u) = ALPMTR_START(u) = ALPMTR_BUF(u);
    133         ALPMTR_INITED(u) = TRUE;
    134     }
    135 
    136     if (ALPMTR_BUF(u) == NULL) {
    137         return rv;
    138     }
    139 
    140     ALPMTR_CURR(u)->op      = op;
    141     ALPMTR_CURR(u)->rc      = rc;
    142     ALPMTR_CURR(u)->seq     = ALPMTR_CNT(u);
    143     if (cfg) {
    144         ALPMTR_CURR(u)->flags   = cfg->defip_flags;
    145         ALPMTR_CURR(u)->vrf     = cfg->defip_vrf;
    146         ALPMTR_CURR(u)->nh_idx  = nh_idx;
    147         ALPMTR_CURR(u)->sublen  = (uint16)(cfg->defip_sub_len & 0xffff);
    148         if (cfg->defip_flags & BCM_L3_IP6) {
    149             for (i = 0; i < 16; i++) {
    150                 ALPMTR_CURR(u)->u.ip6[i] = cfg->defip_ip6_addr[i];
    151             }
    152         } else {
    153             ALPMTR_CURR(u)->u.ip = cfg->defip_ip_addr;
    154         }
    155     }
    156     /* When current log reaches start log (rollover), except
    157        the initial setting curr=start (without log cnt) */
    158     if ((ALPMTR_CURR(u) == ALPMTR_START(u)) && ALPMTR_CNT(u)) {
    159         ALPMTR_START(u)++; /* advancing start log */
    160         /* when start log reaches buf limit, it goes to buf[0] */
    161         if (ALPMTR_START(u) == &ALPMTR(u)->buf[ALPM_TRACE_SIZE]) {
    162             ALPMTR_START(u) = ALPMTR_BUF(u);
    163         }
    164     }
    165 
    166     ALPMTR_CURR(u)++;
    167     /* when current log reaches buf limit, it goes to buf[0] */
    168     if (ALPMTR_CURR(u) == &ALPMTR(u)->buf[ALPM_TRACE_SIZE]) {
    169         ALPMTR_CURR(u) = ALPMTR_BUF(u);
    170         ALPMTR_WRAP(u) = TRUE; /* next log will be wrapped */
    171     }
    172 
    173     ALPMTR_CNT(u)++;
    174 
    175     /* Periodic sanity check */
    176     if (ALPMTR_SANITY_EN(u) && (ALPMTR_CNT(u) >= ALPMTR_SANITY_START(u)) &&
    177         (((ALPMTR_CNT(u) - ALPMTR_SANITY_START(u))  % ALPMTR_SANITY_EN(u)) == 0) &&
    178         (ALPMTR_SANITY_END(u) <= 0 || ALPMTR_CNT(u) <= ALPMTR_SANITY_END(u))) {
    179         rv = bcm_esw_alpm_sanity_check(u, 0, 0, 1);
    180         if (BCM_FAILURE(rv)) {
    181             ALPM_ERR(("ALPM trace sanity failed!\n"));
    182         }
    183     }
    184 
    185     return rv;
    186 
    187 bad:
    188     if (ALPMTR_BUF(u) != NULL) {
    189         alpm_util_free(ALPMTR_BUF(u));
    190         ALPMTR_BUF(u) = NULL;
    191     }
    192     return rv;
    193 }
    194 
    195 /* ALPM trace log (pointer p) display in (data) string */
    196 void
    197 alpm_trace_print(int u, int showflags, _alpm_log_t *p, char *data)
    198 {
    199     int egress_idx_min;
    200     char flags_st[14] = {0};
    201     char rc_st[40] = {0};
    202     char ip_st[SAL_IPADDR_STR_LEN]; /* only for IPv4 */
    203     char mask_st[SAL_IPADDR_STR_LEN];
    204 
    205     egress_idx_min = (p->flags & BCM_L3_MULTIPATH) ? /* 200000 : 100000 */
    206         BCM_XGS3_MPATH_EGRESS_IDX_MIN(u) : BCM_XGS3_EGRESS_IDX_MIN(u);
    207 
    208     rc_st[0] = 0;
    209     if (BCM_FAILURE(p->rc)) {
    210         sal_sprintf(rc_st, "; #seq=%d return failed (%d)", p->seq, p->rc);
    211     } else {
    212         sal_sprintf(rc_st, "; #seq=%d", p->seq);
    213     }
    214 
    215     flags_st[0] = 0;
    216     if (showflags) {
    217         sal_sprintf(flags_st, " f=0x%08x", p->flags);
    218     }
    219 
    220     if (p->op == ALPM_TRACE_OP_DELETE_ALL) {
    221         sal_sprintf(data, "l3 defip clear %s\n", rc_st);
    222     } else {
    223         if (p->flags & BCM_L3_IP6) { /* IPv6 */
    224             if (p->op == ALPM_TRACE_OP_ADD) { /* l3 ip6route add */
    225                 sal_sprintf(data, "l3 ip6route add vrf=%d ip=%02x%02x:%02x%02x:%02x%02x"
    226                     ":%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x "
    227                     "masklen=%d intf=%d replace=%d ecmp=%d%s%s\n",
    228                     p->vrf,
    229                     p->u.ip6[0],
    230                     p->u.ip6[1],
    231                     p->u.ip6[2],
    232                     p->u.ip6[3],
    233                     p->u.ip6[4],
    234                     p->u.ip6[5],
    235                     p->u.ip6[6],
    236                     p->u.ip6[7],
    237                     p->u.ip6[8],
    238                     p->u.ip6[9],
    239                     p->u.ip6[10],
    240                     p->u.ip6[11],
    241                     p->u.ip6[12],
    242                     p->u.ip6[13],
    243                     p->u.ip6[14],
    244                     p->u.ip6[15],
    245                     p->sublen,
    246                     p->nh_idx + egress_idx_min,
    247                     p->flags & BCM_L3_REPLACE ? 1 : 0,
    248                     p->flags & BCM_L3_MULTIPATH ? 1 : 0,
    249                     flags_st, rc_st);
    250             } else { /* l3 ip6route delete */
    251                 sal_sprintf(data, "l3 ip6route delete vrf=%d ip=%02x%02x:%02x%02x:"
    252                     "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:"
    253                     "%02x%02x masklen=%d%s%s\n",
    254                     p->vrf,
    255                     p->u.ip6[0],
    256                     p->u.ip6[1],
    257                     p->u.ip6[2],
    258                     p->u.ip6[3],
    259                     p->u.ip6[4],
    260                     p->u.ip6[5],
    261                     p->u.ip6[6],
    262                     p->u.ip6[7],
    263                     p->u.ip6[8],
    264                     p->u.ip6[9],
    265                     p->u.ip6[10],
    266                     p->u.ip6[11],
    267                     p->u.ip6[12],
    268                     p->u.ip6[13],
    269                     p->u.ip6[14],
    270                     p->u.ip6[15],
    271                     p->sublen,
    272                     flags_st, rc_st);
    273             }
    274         } else { /* IPv4 */
    275             alpm_util_fmt_ipaddr(ip_st, p->u.ip);
    276             alpm_util_fmt_ipaddr(mask_st, bcm_ip_mask_create(p->sublen));
    277             if (p->op == ALPM_TRACE_OP_ADD) { /* l3 defip add */
    278                 sal_sprintf(data, "l3 defip add vrf=%d ip=%s mask=%s intf=%d replace=%d ecmp=%d%s%s\n",
    279                     p->vrf,
    280                     ip_st,
    281                     mask_st,
    282                     p->nh_idx + egress_idx_min,
    283                     p->flags & BCM_L3_REPLACE ? 1 : 0,
    284                     p->flags & BCM_L3_MULTIPATH ? 1 : 0,
    285                     flags_st, rc_st);
    286             } else { /* l3 defip delete */
    287                 sal_sprintf(data, "l3 defip delete vrf=%d ip=%s mask=%s%s%s\n",
    288                     p->vrf,
    289                     ip_st,
    290                     mask_st,
    291                     flags_st, rc_st);
    292            }
    293         }
    294     }
    295 }
    296 
    297 int
    298 bcm_esw_alpm_trace_init(int u)
    299 {
    300     int rv = BCM_E_NONE;
    301     int alloc_sz;
    302 
    303     alloc_sz = sizeof(_alpm_trace_t);
    304     ALPM_ALLOC_EG(ALPMTR(u), alloc_sz, "ALPMTR");
    305 
    306     /* Init ALPMTR variables */
    307     ALPMTR_TRACE_EN(u) = soc_property_get(u, "alpm_trace_enable", 0);
    308     ALPMTR_SANITY_EN(u) = soc_property_get(u, "alpm_trace_sanity", 0);
    309     ALPMTR_WRAP_EN(u) = soc_property_get(u, "alpm_trace_wrap", 0);
    310 
    311     ALPM_INFO(("bcm_esw_alpm_trace_init: trace %d wrap %d\n",
    312                ALPMTR_TRACE_EN(u), ALPMTR_WRAP_EN(u)));
    313     return rv;
    314 bad:
    315     bcm_esw_alpm_trace_deinit(u);
    316     return rv;
    317 }
    318 
    319 int
    320 bcm_esw_alpm_trace_deinit(int u)
    321 {
    322     int rv = BCM_E_NONE;
    323 
    324     if (ALPMTR(u) != NULL) {
    325 
    326         if (ALPMTR_BUF(u) != NULL) {
    327             alpm_util_free(ALPMTR_BUF(u));
    328             ALPMTR_BUF(u) = NULL;
    329         }
    330 
    331         alpm_util_free(ALPMTR(u));
    332         ALPMTR(u) = NULL;
    333     }
    334 
    335     ALPM_INFO(("bcm_esw_alpm_trace_deinit!\n"));
    336     return rv;
    337 }
    338 
    339 #endif /* ALPM_ENABLE */