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-2020 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_ */