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

cpudb.h (19262B)


      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  * File:        cpudb.h
      8  * Purpose:     
      9  */
     10 
     11 #ifndef   _CPUDB_H_
     12 #define   _CPUDB_H_
     13 
     14 #include <sdk_config.h>
     15 #include <sal/core/libc.h>
     16 #include <sal/core/sync.h>
     17 
     18 #include <bcm/types.h>
     19 #include <bcm/rx.h>
     20 
     21 #include <appl/cpudb/brd_ident.h>
     22 
     23 /*
     24  * CPU Database Array Sizes
     25  *
     26  * The current CPU database array sizes determine the maximum
     27  * number of stacking elements as follows,
     28  *     
     29  *   CPUDB_CPU_MAX        Maximum number of stacking CPU systems
     30  *   CPUDB_UNITS_MAX      Maximum number of stacking units per CPU entry
     31  *   CPUDB_STK_PORTS_MAX  Maximum number of stack ports per CPU entry
     32  */
     33 
     34 #ifndef CPUDB_CPU_MAX
     35 #define CPUDB_CPU_MAX        64                /* Max CPUs */
     36 #endif
     37 #ifndef CPUDB_UNITS_MAX
     38 #define CPUDB_UNITS_MAX      BCM_MAX_NUM_UNITS /* Max units per CPU */
     39 #endif
     40 #ifndef CPUDB_CXN_MAX
     41 #define CPUDB_CXN_MAX        32                /* Max stack ports per CPU */
     42 #endif
     43 #ifndef CPUDB_STK_PORTS_MAX
     44 #define CPUDB_STK_PORTS_MAX  CPUDB_CXN_MAX     /* Max stack ports per CPU (same
     45                                                   as above, name more clear) */
     46 #endif
     47 
     48 /*
     49  * CPUDB Key Definition.
     50  *
     51  * Current implementation is MAC as key to database; If this
     52  * is changed, the following macros need to be updated.
     53  *
     54  *     cpudb_key_t                  The key data type
     55  *     CPUDB_KEY_BYTES              Number of bytes when packed in buffer
     56  *     CPUDB_KEY_PACK(buf, _key)    Pack the key into packet data
     57  *     CPUDB_KEY_UNPACK(buf, _key)  Unpack the key from packet data
     58  *     CPUDB_KEY_COMPARE(k1, k2)    Compare like memcmp
     59  *     CPUDB_KEY_COPY(dst, src)     Copy src key to dst key
     60  *     CPUDB_KEY_HASH(_key)         Returns hash value between 0 and
     61  *                                  CPUDB_HASH_ENTRY_COUNT - 1
     62  *     CPUDB_KEY_SEARCH(db_ref, _key, entry)
     63  *                                  Search for key; if found entry is set;
     64  *                                  Otherwise, entry is set to NULL.
     65  */
     66 
     67 typedef struct cpudb_key_s {
     68     bcm_mac_t key;
     69 } cpudb_key_t;
     70 
     71 #define CPUDB_KEY_BYTES             sizeof(cpudb_key_t)
     72 #define CPUDB_KEY_PACK(buf, _key)   sal_memcpy(buf, &(_key), CPUDB_KEY_BYTES)
     73 #define CPUDB_KEY_UNPACK(buf, _key) sal_memcpy(&(_key), buf, CPUDB_KEY_BYTES)
     74 
     75 /* Compare must have same semantics as memcmp and be 0 when == */
     76 #define CPUDB_KEY_COMPARE(k1, k2) sal_memcmp(&(k1), &(k2), CPUDB_KEY_BYTES)
     77 #define CPUDB_KEY_EQUAL(k1, k2)	  (CPUDB_KEY_COMPARE(k1,k2) == 0)
     78 #define CPUDB_KEY_COPY(dst, src)  (dst) = (src)
     79 
     80 /* Hash function for keys.  Testing indicates reasonable distribution */
     81 #define CPUDB_HASH_ENTRY_COUNT      31  /* prime */
     82 #define CPUDB_KEY_HASH(_key)         \
     83     ((((    ((_key).key[2] << 8) | (_key).key[3])) ^      \
     84       ((    ((_key).key[4] << 8) | (_key).key[5]))) % CPUDB_HASH_ENTRY_COUNT)
     85 
     86 /* max length of string formatted key (see key_format) */
     87 #ifndef CPUDB_KEY_STRING_LEN
     88 #define	CPUDB_KEY_STRING_LEN		18
     89 #endif
     90 
     91 /* These are used in print statements as follows:
     92  *     DEBUGK((DK_VERBOSE, "src key: " CPUDB_KEY_FMT,
     93  *             CPUDB_KEY_DISP(src_key)));
     94  */
     95 
     96 #ifndef CPUDB_KEY_FMT
     97 #define CPUDB_KEY_FMT "%x:%x"
     98 #endif
     99 #ifndef CPUDB_KEY_FMT_EOLN
    100 #define CPUDB_KEY_FMT_EOLN "%x:%x\n"
    101 #endif
    102 #ifndef CPUDB_KEY_DISP
    103 #define CPUDB_KEY_DISP(_key) (_key).key[4], (_key).key[5]
    104 #endif
    105 
    106 /*
    107  * Two keys must be reserved as special values for transports:
    108  *     Broadcast key:  For broadcasting packets.
    109  *     Neighbor key:   For sending pkts to a neighbor before the
    110  *                     key of that neighbor is known.
    111  */
    112 extern cpudb_key_t cpudb_bcast_key;
    113 #ifndef CPUDB_BCAST_KEY_DECLARATION
    114 #define CPUDB_BCAST_KEY_DECLARATION \
    115     cpudb_key_t cpudb_bcast_key = {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}}
    116 #endif
    117 
    118 #define CPUDB_KEY_BCAST_SET(_key)     CPUDB_KEY_COPY(_key, cpudb_bcast_key)
    119 #define CPUDB_KEY_BCAST_COMPARE(_key) CPUDB_KEY_COMPARE(_key, cpudb_bcast_key)
    120 #define CPUDB_KEY_IS_BCAST(_key)      CPUDB_KEY_EQUAL(_key, cpudb_bcast_key)
    121 #define CPUDB_KEY_BCAST_PACK(buf)     CPUDB_KEY_PACK(buf, cpudb_bcast_key)
    122 
    123 extern cpudb_key_t cpudb_neighbor_key;
    124 #ifndef CPUDB_NEIGHBOR_KEY_DECLARATION
    125 #define CPUDB_NEIGHBOR_KEY_DECLARATION \
    126     cpudb_key_t cpudb_neighbor_key = {{0xff, 0xff, 0xff, 0xff, 0xff, 0xfe}}
    127 #endif
    128 
    129 #define CPUDB_KEY_NEIGHBOR_SET(_key)      \
    130     CPUDB_KEY_COPY(_key, cpudb_neighbor_key)
    131 #define CPUDB_KEY_NEIGHBOR_COMPARE(_key)  \
    132     CPUDB_KEY_COMPARE(_key, cpudb_neighbor_key)
    133 #define CPUDB_KEY_NEIGHBOR_PACK(buf)     \
    134     CPUDB_KEY_PACK(buf, cpudb_neighbor_key)
    135 
    136 /*
    137  * The base CPU DB entry provides a free format buffer of
    138  * data for applications to use, especially for discovery and
    139  * master election.  CPUDB_APP_DATA_BYTES determines the size of
    140  * this buffer.
    141  */
    142 #ifndef CPUDB_APP_DATA_BYTES
    143 #define CPUDB_APP_DATA_BYTES 8
    144 #endif
    145 
    146 /* Forward type defs */
    147 typedef struct cpudb_s cpudb_t;
    148 typedef cpudb_t *cpudb_ref_t;
    149 #define CPUDB_REF_NULL NULL
    150 
    151 /*
    152  * Stack port information structure; see discovery.txt
    153  *
    154  *        flags           Prefixed by CPUDB_SPF_
    155  *            NO_LINK              Port should be ignored as it doesn't
    156  *                                 have link.
    157  *            DUPLEX               Is this link (physically) duplex?  This may
    158  *                                 be relayed to next hop for efficiency.
    159  *            TX_RESOLVED          Used in discovery process
    160  *            RX_RESOLVED          Used in discovery process
    161  *            ON_BOARD             Does the port connect to a local device?
    162  *                                 Does not support split on/off board ports.
    163  *            The following flags are used by topology:
    164  *            TX_ENABLED           Port is used for TX; (force enable)
    165  *            RX_ENABLED           Port is used for RX; (force enable)
    166  *            TX_DISABLE_FORCE     Force the TX of the port disabled;
    167  *            RX_DISABLE_FORCE     Force the RX of the port disabled;
    168  *            INACTIVE             Link may be up, but no pkts seen during
    169  *                                 discovery.
    170  *            CUT_PORT             See topology.c for more details.
    171  *                                 A spanning tree is generated and those
    172  *                                 edges not in the tree are marked as cut
    173  *                                 ports.  These are used to block BC/MC.
    174  *            TOPO1                Reserved for topo processing.
    175  *        tx_cpu_idx      What is the index (in this DB) of the CPU
    176  *                            subsystem that will receive packets sent
    177  *                            on this stack link?
    178  *        tx_stk_idx      What is the stack port index (in this DB) for
    179  *                            the destination subsystem.
    180  *        rx_cpu_idx      What is the index (in this DB) of the CPU
    181  *                            subsystem from which packets are received
    182  *                            on this link.  Ignored if the DUPLEX flag
    183  *                            is set.
    184  *        rx_stk_idx      What is the stack port index (in this DB) for
    185  *                            the rx_cpu_idx entry?
    186  */
    187 
    188 typedef struct cpudb_stk_port_s {
    189     uint32 flags;               /* See CPUDB_SPF* below */
    190     cpudb_key_t tx_cpu_key;
    191     int tx_stk_idx;
    192     cpudb_key_t rx_cpu_key;
    193     int rx_stk_idx;
    194 } cpudb_stk_port_t;
    195 
    196 #define CPUDB_SPF_NO_LINK           0x1
    197 #define CPUDB_SPF_DUPLEX            0x2
    198 #define CPUDB_SPF_TX_RESOLVED       0x4
    199 #define CPUDB_SPF_RX_RESOLVED       0x8
    200 #define CPUDB_SPF_ON_BOARD          0x10
    201 #define CPUDB_SPF_TX_ENABLED        0x20
    202 #define CPUDB_SPF_RX_ENABLED        0x40
    203 #define CPUDB_SPF_TX_DISABLE_FORCE  0x80
    204 #define CPUDB_SPF_RX_DISABLE_FORCE  0x100
    205 #define CPUDB_SPF_INACTIVE          0x200
    206 #define CPUDB_SPF_CUT_PORT          0x400
    207 #define CPUDB_SPF_TOPO1             0x800
    208 #define CPUDB_SPF_ETHERNET          0x1000
    209 #define CPUDB_SPF_TX_FORWARDED      0x2000
    210 
    211 /* A stack port is "on board" if the tx cxn CPU is the same as it's own CPU */
    212 #define CPUDB_ONBOARD_CXN(_sp) \
    213     (((_sp)->flags & CPUDB_SPF_ON_BOARD) != 0)
    214 
    215 
    216 /*
    217  * Base information for a CPU DB entry.  This is the information
    218  * that needs to be filled out before discovery can start.
    219  *
    220  * Each stack port has information stored in a cpudb_unit_port_t
    221  * structure including:
    222  *     unit/port         - The local, physical unit and port number
    223  *                         of the stack port.
    224  *     weight            - May be used in topology calculations.  Frequently
    225  *                         this is just the speed.  Use of this is to
    226  *                         be implemented.
    227  *     bflags            - (Base) Flags related to the port state
    228  *        DISABLE_IF_CUT   Cut ports may require different treatment
    229  *                         depending on the system's characteristics.
    230  *                         This flag indicates that if a port is 
    231  *                         marked as a CUT port, then it should not
    232  *                         be allowed to convey anything except
    233  *                         stacking management traffic.
    234  *
    235  * Historical note:  unit_port_t started as a structure containing only the
    236  * unit and port.  It was necessary to add the other members to this structure
    237  * to ensure they are conveyed during discovery.
    238  *
    239  * The other base information is:
    240  *
    241  *     key               - Unique key identifying the entry
    242  *     mac               - MAC address of CPU entry
    243  *     dseq_num;         - Discovery sequence number
    244  *
    245  *     slot_id           - For chassis; can be used for stack order (optional)
    246  *     master_pri        - Master priority 
    247  *     app_data          - A string of application data
    248  *
    249  *     num_units         - Number of physical units (devices) controlled
    250  *     dest_unit         - Reach this CPU addressing this unit.  The actual
    251  *                         mod id to use is the base mod id for this unit.
    252  *     dest_port         - Reach this CPU addressing this physical port.
    253  *                         This is the absolute port reference for the
    254  *                         CPU port on dest_unit.  It may be remapped
    255  *                         in entry->dest_port.
    256  *
    257  *     num_stk_ports     - How many external stack ports in subsystem
    258  *
    259  *              variable length info
    260  *     stk_ports         - Physical unit/ports for stack ports.
    261  *     pref_mod_id       - Per device, what is preferred mod id.
    262  *     mod_ids_req       - Per device, how many mod ids required
    263  *     board_id          - Board identifier
    264  *     flags             - Application flags
    265  */
    266 
    267 typedef struct cpudb_unit_port_s {
    268     int unit;
    269     bcm_port_t port;
    270     uint32 weight;
    271     uint32 bflags;
    272 } cpudb_unit_port_t;
    273 
    274 #define CPUDB_UPF_DISABLE_IF_CUT    0x1
    275 
    276 typedef struct cpudb_base_s cpudb_base_t;
    277 struct cpudb_base_s {
    278     cpudb_key_t key;
    279     bcm_mac_t mac;
    280     volatile int dseq_num;      /* Discovery sequence number */
    281 
    282     int slot_id;          /* For chassis; can be used for stack order */
    283     int master_pri;       /* Master priority */
    284     uint8 app_data[CPUDB_APP_DATA_BYTES];   /* Application discovery data */
    285 
    286     int num_units;        /* Number of physical units controlled */
    287     int dest_unit;
    288     int dest_port;
    289 
    290     /* Stack port info; also part of BASE INIT */
    291     int num_stk_ports;
    292 
    293     /* Keep variable length data at end for convenience */
    294     /* sp_u_p:  Stack-port unit/port; Local only */
    295     cpudb_unit_port_t stk_ports[CPUDB_CXN_MAX];  
    296 
    297     int pref_mod_id[BCM_MAX_NUM_UNITS];
    298     int mod_ids_req[BCM_MAX_NUM_UNITS];
    299     CPUDB_BOARD_ID board_id;
    300     uint32 flags;
    301 };
    302 
    303 #define CPUDB_BASE_F_CHASSIS         0x1    /* Are we in a chassis? */
    304 #define CPUDB_BASE_F_LOAD_BALANCE    0x2    /* Should load bal be done ? */
    305 #define CPUDB_BASE_F_CHASSIS_10SLOT  0x4    /* 10 Slot chassis backplane */
    306 #define CPUDB_BASE_F_CHASSIS_AST     0x8    /* Use asymmetric trunks */
    307 
    308 /*
    309  * A CPU entry
    310  *     base              - Base information above,
    311  *     stk_ports         - Current stack port information
    312  *     sysid             - System layer index (post discovery); may be index
    313  *
    314  *     tx_unit           - Send packets destined for this CPU to the
    315  *     tx_port           -    local SOC port (tx_unit, tx_port).
    316  *
    317  *     flags             - Prefixed by CPUDB_F_
    318  *         LOCAL_COMPLETE      Base info filled in for all entries
    319  *         GLOBAL_COMPLETE     All entries report local complete
    320  *
    321  *         BASE_INIT_DONE      For discovery; 
    322  *         DEST_KNOWN          Are dest_mod/port known?
    323  *         SYSID_KNOWN         Is sysid set?
    324  *         TX_KNOWN            tx_unit/port known?
    325  *         IS_LOCAL            Is this entry the local CPU's entry?
    326  *         IS_MASTER           Is this entry the master CPU's entry?
    327  *
    328  *     mod_ids           - Array indexed by device of base mod ids
    329  *                         Length of array is num_units.
    330  */
    331 
    332 typedef int cpudb_mod_list_t[BCM_MAX_NUM_UNITS];
    333 typedef cpudb_stk_port_t cpudb_sp_list_t[CPUDB_CXN_MAX];
    334 
    335 typedef struct cpudb_entry_s cpudb_entry_t;
    336 struct cpudb_entry_s {
    337     cpudb_base_t base;
    338 
    339     cpudb_sp_list_t sp_info; /* cpudb_stk_port_t[CPUDB_CXN_MAX] */
    340 
    341     /* Applications that modify DB entries should update flags */
    342     volatile uint32 flags; /* See CPUDB_F_* below */
    343 
    344     /* SYSID member */
    345     void *sysid;
    346 
    347     /* TX members */
    348     int tx_unit;           /* Local info */
    349     int tx_port;
    350 
    351     /* Destination module ID/port to use to address this CPU */
    352     int dest_mod;
    353     int dest_port;    /* May be remapped for mod-id remapping */
    354 
    355     /* Other info, post discovery */
    356     cpudb_mod_list_t mod_ids; /* int[BCM_MAX_NUM_UNITS] */
    357 
    358     void *user_cookie;         /* Application cookie */
    359 
    360     /* Administrivia */
    361     cpudb_ref_t db_ref;        /* To which DB do we belong? */
    362     cpudb_entry_t *next;
    363     cpudb_entry_t *prev;       /* For easier removal */
    364     cpudb_entry_t *h_next;     /* Hash chain linkage */
    365     cpudb_entry_t *h_prev;
    366     bcm_trans_ptr_t *trans_ptr;   /* Mainly used by c2c for setup, tx */
    367     int topo_idx;            /* Internal, local index for topo, 0..n-1; */
    368 };
    369 
    370 #define CPUDB_F_LOCAL_COMPLETE    0x1    /* For discovery; stk ports rslvd */
    371 #define CPUDB_F_GLOBAL_COMPLETE   0x2    /* For discovery; all cpus cmplt */
    372 #define CPUDB_F_FORWARD_MASK      0xff   /* Only these flags are forwarded */
    373 
    374     /* The following have local significance */
    375 #define CPUDB_F_BASE_INIT_DONE    0x100  /* For discovery; most basic info */
    376 #define CPUDB_F_DEST_KNOWN        0x200  /* Are dest_mod/port known? */
    377 #define CPUDB_F_SYSID_KNOWN       0x400  /* Is sysid set? */
    378 #define CPUDB_F_TX_KNOWN          0x800  /* tx_unit/port known? */
    379 #define CPUDB_F_IS_LOCAL          0x1000 /* Marks the local entry */
    380 #define CPUDB_F_IS_MASTER         0x2000 /* Marks the master entry */
    381 #define CPUDB_F_INACTIVE_MARKED   0x4000 /* Have inactive ports been marked? */
    382 #define CPUDB_F_CONFIG_IN         0x8000 /* Config pkt in from this CPU? */
    383 #define CPUDB_F_TOPO1             0x10000 /* Reserved for topo processing */
    384 #define CPUDB_F_TOPO2             0x20000 /* Reserved for topo processing */
    385 
    386 /* Use the reserved TOPO2 flags in the CPU DB */
    387 #define CPUDB_TOPO_VISITED(entry) ((entry)->flags & CPUDB_F_TOPO2)
    388 #define CPUDB_TOPO_VISITED_SET(entry) ((entry)->flags |= CPUDB_F_TOPO2)
    389 #define CPUDB_TOPO_NOT_VISITED_SET(entry) ((entry)->flags &= ~CPUDB_F_TOPO2)
    390 
    391 /* Constants for unit modid preferences */
    392 #define CPUDB_TOPO_MODID_ANY -1
    393 #define CPUDB_TOPO_MODID_EVEN -2
    394 
    395 extern cpudb_ref_t cpudb_create(void);
    396 extern cpudb_ref_t cpudb_copy(const cpudb_ref_t src_db);
    397 extern int cpudb_clear(cpudb_ref_t db_ref, int keep_local);
    398 extern int cpudb_destroy(cpudb_ref_t db_ref);
    399 extern int cpudb_valid(cpudb_ref_t db_ref);
    400 
    401 extern int cpudb_entry_copy(cpudb_entry_t *dest, const cpudb_entry_t *src);
    402 
    403 extern cpudb_entry_t *cpudb_entry_create(cpudb_ref_t db_ref,
    404                                          const cpudb_key_t key,
    405                                          int is_local);
    406 extern int cpudb_local_base_info_set(cpudb_ref_t db_ref,
    407                                      cpudb_base_t *local_base);
    408 
    409 extern cpudb_entry_t *cpudb_mac_lookup(cpudb_ref_t db_ref,
    410                                        const bcm_mac_t mac);
    411 extern cpudb_entry_t *cpudb_sysid_lookup(cpudb_ref_t db_ref,
    412                                                void *sysid);
    413 extern int cpudb_sysid_set(cpudb_ref_t db_ref, cpudb_key_t key, void *sysid,
    414                            int overwrite);
    415 
    416 extern int cpudb_master_set(cpudb_ref_t db_ref, const cpudb_key_t key);
    417 extern cpudb_entry_t *cpudb_master_get(cpudb_ref_t db_ref);
    418 extern int cpudb_entry_count_get(cpudb_ref_t db_ref);
    419 
    420 extern int cpudb_entry_remove(cpudb_ref_t db_ref, const cpudb_key_t key);
    421 
    422 extern int cpudb_key_format(cpudb_key_t key, char *buf, int len);
    423 extern int cpudb_key_parse(char *buf, cpudb_key_t *keyp);
    424 
    425 extern int cpudb_board_id_get(const char *idstring, CPUDB_BOARD_ID *board_id);
    426 extern int cpudb_board_idstr_get(CPUDB_BOARD_ID board_id, char **board_idstr);
    427 
    428 extern int cpudb_sp_idx_to_slot(const cpudb_ref_t db_ref,
    429                                 const cpudb_entry_t *entry,
    430                                 int sp_idx, cpudb_entry_t **out_entry);
    431 
    432 extern cpudb_entry_t *cpudb_key_lookup(cpudb_ref_t db_ref,
    433                                        const cpudb_key_t key);
    434 
    435 /* An instance of a database */
    436 struct cpudb_s {
    437     int num_cpus;                  /* How many active */
    438     cpudb_entry_t *entries;
    439     cpudb_entry_t *local_entry;    /* Set prior to discovery */
    440     cpudb_entry_t *master_entry;   /* Set by discovery */
    441 
    442     /* Hash for key lookups */
    443     cpudb_entry_t *key_hash[CPUDB_HASH_ENTRY_COUNT];
    444 
    445     /* Administrivia */
    446     void *topo_cookie;             /* Cookie for topology results */
    447     uint32 magic;                  /* For verifying valid */
    448     cpudb_ref_t old_db;            /* Previous DB in system */
    449 };
    450 
    451 /* Quick "get entry" from sys id; treat as const */
    452 #define CPUDB_ENTRY_COUNT_GET(_db_ref)  (_db_ref->num_cpus)
    453 
    454 #define CPUDB_FOREACH_ENTRY(_db_ref, _entry) \
    455     for (_entry = _db_ref->entries; _entry != NULL; _entry = _entry->next)
    456 
    457 #define CPUDB_KEY_SEARCH(_db_ref, _key, _entry)                            \
    458     do {                                                                   \
    459         int _cnt;                                                          \
    460         for (_entry = _db_ref->key_hash[CPUDB_KEY_HASH(_key)], _cnt = 0;   \
    461 		_entry != NULL && _cnt < CPUDB_CPU_MAX;                    \
    462                 _entry = _entry->h_next, _cnt++) {                         \
    463             if (CPUDB_KEY_EQUAL(_key, _entry->base.key)) {                 \
    464                 break;         /* Found it */                              \
    465             }                                                              \
    466         }                                                                  \
    467         if (_entry != NULL && !CPUDB_KEY_EQUAL(_key, _entry->base.key)) {  \
    468             _entry = NULL;                                                 \
    469         }                                                                  \
    470     } while (0)
    471 
    472 #endif /* _CPUDB_H_ */