rx.h (28053B)
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: rx.h 8 * Purpose: Internal structures and definitions for RX module 9 */ 10 #ifndef _BCM_COMMON_RX_H_ 11 #define _BCM_COMMON_RX_H_ 12 13 #include <sal/core/libc.h> 14 #include <sal/core/sync.h> 15 #include <sal/core/thread.h> 16 #include <sal/core/time.h> 17 #include <soc/dma.h> 18 #include <bcm/error.h> 19 #include <bcm/rx.h> 20 21 /* 22 * Typedef: 23 * rx_callout_t 24 * Purpose: 25 * Describes a registered callout for RX. 26 * Notes: 27 * For each interface, a list of callouts is maintained in sorted 28 * order from highest priority to lowest. The callouts are called 29 * in order until one returns "bcm_rx_handled" or 30 * "bcm_rx_handled_owned". If all handlers called and none process 31 * the packet, the default "discard" handler is called. 32 */ 33 34 typedef struct rx_callout_s { 35 volatile struct rx_callout_s *rco_next; /* Next in sorted list */ 36 const char *rco_name; /* Name for handler */ 37 void *rco_cookie; /* Cookie for call out */ 38 bcm_rx_cb_f rco_function; /* Callout function */ 39 uint32 rco_flags; /* RCO_F_ flags; see bcm/rx.h */ 40 uint8 rco_priority; /* Callout priority 0 == lowest */ 41 uint32 rco_pkts_handled; /* Counter */ 42 uint32 rco_pkts_owned; /* Counter */ 43 SHR_BITDCL rco_cos[_SHR_BITDCLSIZE(BCM_RX_COS)]; /* cos bitmap */ 44 } rx_callout_t; 45 46 #define SETUP_RCO(rco, name, fun, pri, cookie, next, flags) \ 47 do { \ 48 (rco)->rco_name = (name); \ 49 (rco)->rco_function = (fun); \ 50 (rco)->rco_priority = (pri); \ 51 (rco)->rco_cookie = (cookie); \ 52 (rco)->rco_next = (next); \ 53 (rco)->rco_flags = (flags); \ 54 (rco)->rco_pkts_owned = 0; \ 55 (rco)->rco_pkts_handled = 0; \ 56 sal_memset((void *)((rco)->rco_cos), 0, \ 57 SHR_BITALLOCSIZE(BCM_RX_COS)); \ 58 } while (0) 59 60 #define SETUP_RCO_COS_SET(rco, cos) \ 61 do { \ 62 SHR_BITSET((rco)->rco_cos, (cos)); \ 63 } while (0) 64 65 #define SETUP_RCO_COS_CLR(rco, cos) \ 66 do { \ 67 SHR_BITCLR((rco)->rco_cos, (cos)); \ 68 } while (0) 69 70 /* Some default values */ 71 #define RX_PKT_SIZE_DFLT (16 * 1024) /* 12 K packets, plus spare */ 72 #define RX_PPC_DFLT 8 /* 8 pkts/chain */ 73 #define RX_PPS_DFLT 1000 /* 1000 pkts/sec */ 74 #define RX_CHAINS_DFLT 8 /* 8 chains */ 75 #define RX_THREAD_PRI_DFLT 200 76 77 #define RX_CMICX_PPC_DFLT 8 /* 8 pkts/chain in cmicx devices */ 78 79 /* Could probably be pretty large now */ 80 #define RX_PPC_MAX SOC_DV_PKTS_MAX 81 82 /* Default unit to use for alloc/free */ 83 #define BCM_RX_DFLT_UNIT 0 84 85 86 /* Queue type for packets, one per channel; possibly per COS in the future */ 87 typedef struct rx_queue_s { 88 bcm_pkt_t *head; 89 bcm_pkt_t *tail; 90 int pps; /* Packets/sec for queue; 0 -> disabled */ 91 int burst; /* Burst for queue */ 92 int tokens; /* Token bucket */ 93 sal_usecs_t last_fill; /* Last time bucket updated */ 94 int count; /* Number of pkts in queue */ 95 int max_len; /* Max number of pkts permitted in queue. 96 Disabled if <= 0. NOT RECOMMENDED. */ 97 #define RX_Q_MAX_DFLT 200 98 int tot_pkts; /* Total pkts through the queue (debug) */ 99 int rate_disc; /* Pkts discarded due to rate limiting */ 100 int qlen_disc; /* Pkts discarded due to queue len exceeded */ 101 sal_spinlock_t lock; /* For locking the queue */ 102 } rx_queue_t; 103 104 /* rx_queue_t *q below */ 105 #define _Q_LOCK(q) sal_spinlock_lock((q)->lock) 106 #define _Q_UNLOCK(q) sal_spinlock_unlock((q)->lock) 107 108 /* Steal up to max packets from the queue. Locking. */ 109 #define _Q_STEAL(q, first_pkt, max) \ 110 do { \ 111 int _i = 0; \ 112 bcm_pkt_t *last_pkt; \ 113 bcm_pkt_t *prev_pkt = NULL; \ 114 _Q_LOCK(q); \ 115 last_pkt = (q)->head; \ 116 (first_pkt) = last_pkt; \ 117 while (_i < (max) && last_pkt != NULL) { \ 118 _i++; \ 119 prev_pkt = last_pkt; \ 120 last_pkt = last_pkt->_next; \ 121 } \ 122 if (prev_pkt != NULL) { /* Just to be safe */ \ 123 prev_pkt->_next = NULL; /* Mark list end */\ 124 } \ 125 (q)->head = last_pkt; \ 126 if (last_pkt == NULL) { /* No more pkts in q */ \ 127 (q)->tail = NULL; \ 128 } \ 129 (q)->count -= _i; /* took _i pkts off q */ \ 130 _Q_UNLOCK(q); \ 131 } while (0) 132 133 /* Steal all packets from the queue. Locking. */ 134 #define _Q_STEAL_ALL(q, first_pkt) \ 135 do { \ 136 _Q_LOCK(q); \ 137 (first_pkt) = (q)->head; \ 138 (q)->head = NULL; \ 139 (q)->tail = NULL; \ 140 (q)->count = 0; \ 141 _Q_UNLOCK(q); \ 142 } while (0) 143 144 #define _Q_EMPTY(q) ((q)->tail == NULL) 145 146 #define _Q_ENQUEUE(q, pkt) \ 147 do { \ 148 _Q_LOCK(q); \ 149 (pkt)->_next = NULL; \ 150 if (_Q_EMPTY(q)) (q)->head = (q)->tail = (pkt); \ 151 else { \ 152 (q)->tail->_next = (pkt); \ 153 (q)->tail = (pkt); \ 154 } \ 155 (q)->count++; \ 156 (q)->tot_pkts++; \ 157 _Q_UNLOCK(q); \ 158 } while (0) 159 160 #define RX_CHAINS_MAX 20 161 162 /* 163 * Typedef: 164 * rx_chan_ctl_t 165 * Purpose: 166 * Control structure per channel 167 * Notes: 168 * Tokens must be signed 169 */ 170 171 typedef struct rx_chan_ctl_s { 172 dv_t *dv[RX_CHAINS_MAX]; 173 void *reserved[4]; /* for compability */ 174 int dcb_per_pkt; /* Number DCB/pkt */ 175 176 /* Some stats counters */ 177 int rpkt; /* Received packets */ 178 int rbyte; /* Received bytes */ 179 int dpkt; /* Discard packets */ 180 int dbyte; /* Discard bytes */ 181 int mem_fail; /* How many packet allocation errors */ 182 bcm_pkt_t *all_pkts; 183 } rx_chan_ctl_t; 184 185 typedef void (* bcm_rx_parser_f)(int unit, bcm_pkt_t *pkt); 186 187 /* 188 * Typedef: 189 * rx_ctl_t 190 * Purpose: 191 * Control structure per unit for RX 192 * Notes: 193 * Tokens must be signed 194 */ 195 196 typedef struct rx_ctl_s { 197 int rc_lock; /* For SPL locking */ 198 199 /**************** LOCAL ONLY UNIT CONTROL ****************/ 200 volatile int hndlr_intr_cnt; /* Number of interrupt callouts */ 201 volatile uint32 chan_running; /* Bitmap of channels enabled */ 202 int cur_chan; /* For fairness in refill/start */ 203 rx_chan_ctl_t chan_ctl[BCM_CMICX_RX_CHANNELS]; /* internal chan ctl */ 204 205 206 /**************** LOCAL AND REMOTE UNIT CONTROL ****************/ 207 bcm_rx_cfg_t user_cfg; /* User configuration */ 208 volatile rx_callout_t *rc_callout; /* Callout linked list */ 209 volatile int hndlr_cnt; /* Non-intr callouts, no disc */ 210 rx_queue_t *pkt_queue; /* Packets to process/cos BCM_RX_COS*/ 211 bcm_pkt_t **all_pkts; /* Packet Descriptors avail for Rx */ 212 void **pkt_load; /* Buffers to give back to hw */ 213 int *pkt_load_ids; /* 1:1 buffer to id array */ 214 bcm_rx_parser_f rx_parser; 215 216 /* Thread control */ 217 char rx_tname[16]; /* Thread name */ 218 sal_sem_t pkt_notify; /* Semaphor for pkt thrd */ 219 sal_thread_t rx_tid; /* packet thread id */ 220 int sleep_cur; /* Current sleep time */ 221 int rx_thread_pri; /* thread priority */ 222 volatile int thread_running; /* Input signal to thread */ 223 volatile int thread_exit_complete; /* Output signal from thread */ 224 225 /* For global rate control */ 226 volatile int tokens; /* Rate control tokens. */ 227 sal_usecs_t last_fill; /* Last time bucket updated */ 228 sal_mutex_t rx_mutex; /* Sync for handler list */ 229 230 int flags; 231 int olp_match_rule; /* Olp Match Rule */ 232 #define BCM_RX_F_STARTED 0x1 /* Started? */ 233 #define BCM_RX_REASONS_BFD 0x2 /* BFD reason code configured */ 234 #define BCM_RX_REASONS_MPLS_BFD 0x4 /* MPLS reason code configured using BFD */ 235 uint8 cpu_port_priorities; 236 /**************** Counters ****************/ 237 int restart_errs; 238 int q_depth; 239 int tot_pkts; 240 int dpkt; 241 int dbyte; 242 int rpkt; 243 int rbyte; 244 int pkts_since_start; /* Since last start, how many pkts */ 245 int bad_hndlr_rv; 246 int no_hndlr; 247 int not_running; 248 int thrd_not_running; 249 int dcb_errs; 250 int pkts_owned; 251 int tunnelled; 252 int reasonMapInitialized; 253 int next_unit; /* Next unit with RX started. */ 254 bcm_cos_queue_t queue_max; /* Maximum number of cpu queues. */ 255 volatile void *free_list; /* Deferred free list */ 256 } rx_ctl_t; 257 258 /* DV related defines and DV state transition diagram 259 * 260 * State desriptions: 261 * DV_S_NEEDS_FILL The DV needs to have its packets checked 262 * DV_S_FILLED The DV has packets and is ready to be sent 263 * to the SOC layer. 264 * DV_S_SCHEDULED The DV could not be started due to rate 265 * limiting, so it has been scheduled for a DPC 266 * DV_S_ACTIVE The DV has been handed to the SOC layer and 267 * is receiving packets. 268 * DV_S_CHN_DONE A chain done interrupt has occurred for this 269 * DV. The SOC layer is done with the DV and it 270 * now contains packets to process. 271 * DV_S_RLD_DONE A desc done inter occurred and the reload bit 272 * is set for this DV indicating that the SOC layer 273 * is done with the DV and DMA has followed the 274 * reload address. 275 * DV_S_ERROR An error has occurred. The DV will not be 276 * scheduled until RX is restarted. 277 * 278 * DVs start in the state NEEDS_FILL. 279 * 280 * NEEDS_FILL --> FILLED rx_dv_fill 281 * FILLED --> ACTIVE rx_chain_start 282 * FILLED --> SCHEDULED rx_chain_start_or_schedule 283 * SCHEDULED --> ACTIVE rx_chain_start 284 * ACTIVE --> CHN_DONE rx_done_chain 285 * ACTIVE --> RLD_DONE rx_done_reload 286 * ACTIVE --> NEEDS_FILL all pkts processed, see below 287 * CHN_DONE --> NEEDS_FILL see below 288 * RLD_DONE --> NEEDS_FILL see below 289 * 290 * A DV transitions from RLD_DONE/CHN_DONE or ACTIVE to NEEDS_FILL when all 291 * its packets have been processed. This is detected by the 292 * pkt_done_cnt of DV_INFO reaching the pkts/chain level. Note that 293 * if all pkts are being handled in the interrupt handler, this may 294 * occur before the DV has transitioned to CHN_DONE which occurs in 295 * the chain done interrupt handler. 296 */ 297 298 typedef enum dv_states_e { 299 DV_S_NEEDS_FILL, /* Packets are processed, needs refill */ 300 DV_S_FILLED, /* DV filled, ready to be started */ 301 DV_S_SCHEDULED, /* DV has been scheduled via a DPC */ 302 DV_S_ACTIVE, /* DV has been started (given to soc layer) */ 303 DV_S_CHN_DONE, /* DV is done, needs service (chain done) */ 304 DV_S_RLD_DONE, /* DV is done, but pkts may not be drained */ 305 DV_S_ERROR /* DV has seen error */ 306 } dv_states_t; 307 308 #define DV_STATE_STRINGS { \ 309 "Needs Fill", \ 310 "Filled", \ 311 "Scheduled", \ 312 "Active", \ 313 "Chain Done", \ 314 "Error"} 315 316 /* This is all the extra information associated with a DV for RX */ 317 typedef struct rx_dv_info_s { 318 volatile dv_states_t state; 319 volatile sal_usecs_t sched_time; /* When was DV scheduled */ 320 volatile int time_diff; /* Delta time until started */ 321 volatile int abort_cleanup; /* First packet after Start Channel */ 322 uint8 idx; 323 uint8 chan; 324 volatile uint8 pkt_done_cnt; 325 } rx_dv_info_t; 326 327 /* 328 * DV and DCB related macros 329 */ 330 #define _DV_INFO dv_public1.ptr 331 #define DV_INFO(dv) (((rx_dv_info_t *)(((dv_t *)dv)->_DV_INFO))) 332 333 /* 334 * Record both the time that the DV is scheduled and how many 335 * usecs in the future to schedule. 336 */ 337 #define DV_TIME_DIFF(dv) (DV_INFO(dv)->time_diff) 338 #define DV_SCHED_TIME(dv) (DV_INFO(dv)->sched_time) 339 340 /* 341 * How much futher into the future to schedule. If this is <= 0, 342 * it indicates the DV is ready. 343 */ 344 #define DV_FUTURE_US(dv, cur_us) \ 345 (DV_TIME_DIFF(dv) - (int)((cur_us >= DV_SCHED_TIME(dv)) ? \ 346 (SAL_USECS_SUB(cur_us, DV_SCHED_TIME(dv))) : \ 347 (SAL_USECS_ADD(cur_us, SAL_USECS_SUB(0xffffffff, DV_SCHED_TIME(dv)))))) 348 349 #define DV_INDEX(dv) (DV_INFO(dv)->idx) 350 #define DV_STATE(dv) (DV_INFO(dv)->state) 351 #define DV_CHANNEL(dv) (DV_INFO(dv)->chan) 352 #define DV_ABORT_CLEANUP(dv) (DV_INFO(dv)->abort_cleanup) 353 354 #define DV_PKT(dv, i) \ 355 (RX_PKT(dv->dv_unit, DV_CHANNEL(dv), DV_INFO(dv)->idx, i)) 356 #define DV_PKTS_PROCESSED(dv) (DV_INFO(dv)->pkt_done_cnt) 357 358 #define DV_RX_IDX(dv) ((dv)->dv_public2.u32) 359 #define DV_RX_IDX_SET(dv, val) (dv)->dv_public2.u32 = (val) 360 361 362 /**************************************************************** 363 * 364 * The following defines can only be used in bcm/rx.c as they 365 * refer to the static variable rx_ctl 366 */ 367 extern rx_ctl_t *rx_ctl[]; 368 369 /* 370 * RX_LOCK/UNLOCK should only be used to synchronize with 371 * interrupt handlers. Code protected by these calls should 372 * only involve memory references. 373 */ 374 375 #define RX_LOCK(unit) \ 376 sal_mutex_take(rx_ctl[unit]->rx_mutex, sal_mutex_FOREVER) 377 #define RX_UNLOCK(unit) \ 378 sal_mutex_give(rx_ctl[unit]->rx_mutex) 379 380 /**************************************************************** 381 * Access macros for rx_ctl: 382 * RX_INIT_DONE(unit) Has init been called? 383 * RX_UNIT_CHECK(unit) Legal unit number? 384 * RX_INIT_CHECK(unit) Return error if init not done 385 * RX_CHAN_USED(unit, chan) Has the channel been setup? 386 * RX_CHAN_RUNNING(unit, chan) Is channel currently running (active)? 387 * 388 * RX_PPC(unit) Packets/chain 389 * RX_PPS(unit) Global pkts/second rate limit 390 * RX_BURST(unit) Global burst rate (full bucket setting) 391 * 392 * RX_CHAN_COS(unit, chan) Channel's COS bitmap 393 * RX_CHAN_BURST(unit) Channel's burst rate (full bucket) 394 * 395 * RX_DV(unit, chan, i) Get pointer to i-th dv of channel 396 * RX_DV_PKT(unit, chan, dv_idx, pkt_idx) 397 * Pointer to packet for given dv 398 */ 399 400 /* Access macros for rx_ctl: */ 401 #define RX_INIT_DONE(unit) (rx_ctl[unit] != NULL) 402 #define RX_UNIT_CHECK(unit) \ 403 if (((unit) < 0) || ((unit) >= BCM_CONTROL_MAX)) return BCM_E_UNIT 404 #define RX_INIT_CHECK(unit) \ 405 do { \ 406 RX_UNIT_CHECK(unit); \ 407 if (!RX_INIT_DONE(unit)) \ 408 BCM_IF_ERROR_RETURN(bcm_rx_init(unit)); \ 409 } while (0) 410 #define RX_CHAN_USED(unit, chan) (RX_CHAN_CFG(unit, chan).chains != 0) 411 #define RX_CHAN_RUNNING(unit, chan) (rx_ctl[unit]->chan_running & (1 << chan)) 412 413 /* Global configuration */ 414 #define RX_PPC(unit) (rx_ctl[unit]->user_cfg.pkts_per_chain) 415 #define RX_PPS(unit) (rx_ctl[unit]->user_cfg.global_pps) 416 #define RX_BURST(unit) (rx_ctl[unit]->user_cfg.max_burst) 417 #define RX_THREAD_PRI(unit) (rx_ctl[unit]->user_cfg.thread_pri) 418 #define RX_TOKENS(unit) (rx_ctl[unit]->tokens) 419 #define RX_QUEUE_MAX(unit) (rx_ctl[unit]->queue_max) 420 #define RX_OLP_MATCH_RULE(unit) (rx_ctl[unit]->olp_match_rule) 421 422 /* Channel configuration */ 423 #define RX_CHAN_CFG(unit, chan) (rx_ctl[unit]->user_cfg.chan_cfg[chan]) 424 #define RX_CHAN_FLAGS(unit, chan) (RX_CHAN_CFG(unit, chan).flags) 425 #define RX_CHAINS(unit, chan) (RX_CHAN_CFG(unit, chan).chains) 426 #define RX_CRC_STRIP(unit, chan) \ 427 (RX_CHAN_FLAGS(unit, chan) & BCM_RX_F_CRC_STRIP) 428 #define RX_VTAG_STRIP(unit, chan) \ 429 (RX_CHAN_FLAGS(unit, chan) & BCM_RX_F_VTAG_STRIP) 430 #define RX_PKT_SIZE(unit) (rx_ctl[unit]->user_cfg.pkt_size) 431 #define RX_USER_FLAGS(unit) (rx_ctl[unit]->user_cfg.flags) 432 #define RX_IGNORE_HG(unit) (RX_USER_FLAGS(unit) & BCM_RX_F_IGNORE_HGHDR) 433 #define RX_IGNORE_SL(unit) (RX_USER_FLAGS(unit) & BCM_RX_F_IGNORE_SLTAG) 434 435 /* Per COS rate control */ 436 #define RX_QUEUE(unit, cos) (&(rx_ctl[unit]->pkt_queue[cos])) 437 #define RX_COS_PPS(unit, cos) (RX_QUEUE(unit, cos)->pps) 438 #define RX_COS_BURST(unit, cos) (RX_QUEUE(unit, cos)->burst) 439 #define RX_COS_MAX_LEN(unit, cos) (RX_QUEUE(unit, cos)->max_len) 440 #define RX_COS_TOKENS(unit, cos) (RX_QUEUE(unit, cos)->tokens) 441 442 #define RX_CHAN_COS(unit, chan) (RX_CHAN_CFG(unit, chan).cos_bmp) 443 #define RX_CHAN_BURST(unit, chan) (RX_CHAINS(unit, chan) * RX_PPC(unit)) 444 445 /* Internal configuration/control */ 446 #define RX_CHAN_CTL(unit, chan) (rx_ctl[unit]->chan_ctl[chan]) 447 #define RX_CHAN_PKTS(unit, chan) (rx_ctl[unit]->chan_ctl[chan].all_pkts) 448 449 #define RX_PKT(unit, chan, dv_idx, idx) \ 450 (&(RX_CHAN_CTL(unit, chan).all_pkts[dv_idx * RX_PPC(unit) + idx])) 451 452 /* DV and DCB related macros */ 453 #define RX_DCB_PER_PKT(unit, chan) (RX_CHAN_CTL(unit, chan).dcb_per_pkt) 454 #define RX_DCB_PER_DV(unit, chan) \ 455 (RX_DCB_PER_PKT(unit, chan) * RX_PPC(unit)) 456 457 #define RX_DV(unit, chan, i) (RX_CHAN_CTL(unit, chan).dv[i]) 458 459 /* For each channel that is currently running */ 460 #define FOREACH_RUNNING_CHANNEL(unit, chan) \ 461 for (chan = 0; chan < BCM_CMICX_RX_CHANNELS; chan++) \ 462 if (RX_CHAN_RUNNING(unit, chan)) 463 464 /* For each channel that is setup (could be or is active) */ 465 #define FOREACH_SETUP_CHANNEL(unit, chan) \ 466 for (chan = 0; chan < BCM_CMICX_RX_CHANNELS; chan++) \ 467 if (RX_CHAN_USED(unit, chan)) 468 469 #ifdef BCM_RPC_SUPPORT 470 extern int _bcm_rx_sl_mode_update(int unit); 471 #endif 472 473 extern int rxp_memory_source_heap; 474 /* Default values */ 475 476 #if !defined(BCM_RX_POOL_COUNT_DEFAULT) 477 #define BCM_RX_POOL_COUNT_DEFAULT 256 478 #endif 479 480 #if !defined(BCM_RX_POOL_BYTES_DEFAULT) 481 #define BCM_RX_POOL_BYTES_DEFAULT RX_PKT_SIZE_DFLT 482 #endif 483 484 #define LEGAL_COS(cos) ((cos) >= BCM_RX_COS_ALL && (cos) < BCM_RX_COS) 485 486 extern int rx_spl; 487 #define RX_INTR_LOCK rx_spl = sal_splhi() 488 #define RX_INTR_UNLOCK sal_spl(rx_spl) 489 490 #define BCM_RX_CTRL_ACTIVE_UNITS_UPDATE (1 << 0) 491 492 /* Single RX control structure, common for all units */ 493 typedef struct rx_control_s { 494 /* Thread control */ 495 sal_sem_t pkt_notify; /* Semaphore for pkt thrd */ 496 volatile int pkt_notify_given; /* Semaphore already given */ 497 sal_thread_t rx_tid; /* packet thread id */ 498 sal_thread_t adapter_rx_tid; /* adapter packet thread id */ 499 int sleep_cur; /* Current sleep time */ 500 #define MIN_SLEEP_US 5000 /* Always sleep at least 5 ms */ 501 #define MAX_SLEEP_US 100000 /* For non-rate limiting, .1 sec */ 502 volatile int thread_running; /* Input signal to thread */ 503 volatile int thread_exit_complete; /* Output signal from thread */ 504 505 /* System wide rate limiting */ 506 int system_pps; 507 int system_tokens; 508 sal_usecs_t system_last_fill; 509 510 /* Thread protection mutexes. */ 511 sal_mutex_t system_lock; 512 sal_mutex_t start_lock; 513 514 /* RX started units misc info. */ 515 int rx_unit_first; 516 bcm_cos_queue_t system_cosq_max; 517 518 /* System flags. */ 519 int system_flags; 520 521 /* Scheduler function pointer. */ 522 bcm_rx_sched_cb rx_sched_cb; 523 } rx_control_t; 524 525 extern rx_control_t rx_control; 526 527 528 #ifdef ADAPTER_SERVER_MODE 529 void rx_adapter_process_packet(int unit, bcm_pkt_t *pkt); 530 #endif 531 532 #define _BCM_RX_SYSTEM_LOCK \ 533 sal_mutex_take(rx_control.system_lock, sal_mutex_FOREVER) 534 535 #define _BCM_RX_SYSTEM_UNLOCK sal_mutex_give(rx_control.system_lock) 536 537 #define _BCM_RX_START_LOCK \ 538 sal_mutex_take(rx_control.start_lock, sal_mutex_FOREVER) 539 540 #define _BCM_RX_START_UNLOCK sal_mutex_give(rx_control.start_lock) 541 542 #define _BCM_RX_SCHED_DEFAULT_CB (_bcm_rx_default_scheduler) 543 #define _BCM_RX_CHECK_THREAD_DONE if (!rx_control.thread_running) break 544 545 #define RX_IS_SETUP(unit) ((((unit) >= 0) && \ 546 ((unit) < BCM_CONTROL_MAX)) \ 547 && (rx_ctl[unit] != NULL)) 548 #define RX_UNIT_STARTED(unit) \ 549 (RX_IS_SETUP(unit) && rx_ctl[unit]->flags & BCM_RX_F_STARTED) 550 #define RX_UNIT_REASONS_BFD_SET(unit) \ 551 if(RX_IS_SETUP(unit)) {rx_ctl[unit]->flags |= BCM_RX_REASONS_BFD;} 552 #define RX_UNIT_REASONS_MPLS_BFD_SET(unit) \ 553 if(RX_IS_SETUP(unit)) {rx_ctl[unit]->flags |= BCM_RX_REASONS_MPLS_BFD;} 554 #define RX_UNIT_REASONS_BFD_GET(unit, _x_) \ 555 if(RX_IS_SETUP(unit)) {_x_ = rx_ctl[unit]->flags & BCM_RX_REASONS_BFD;} 556 #define RX_UNIT_REASONS_MPLS_BFD_GET(unit, _x_) \ 557 if(RX_IS_SETUP(unit)) {_x_ = rx_ctl[unit]->flags & BCM_RX_REASONS_MPLS_BFD;} 558 #define RX_UNIT_REASONS_BFD_CLEAR(unit) \ 559 if(RX_IS_SETUP(unit)) {rx_ctl[unit]->flags &= ~BCM_RX_REASONS_BFD;} 560 #define RX_UNIT_REASONS_MPLS_BFD_CLEAR(unit) \ 561 if(RX_IS_SETUP(unit)) {rx_ctl[unit]->flags &= ~BCM_RX_REASONS_MPLS_BFD;} 562 563 /* RCPU units are not local, they are remote */ 564 #define RX_IS_RCPU(unit) (SOC_UNIT_VALID(unit) && SOC_IS_RCPU_UNIT(unit)) 565 566 #if defined(BCM_RPC_SUPPORT) 567 /* Accept that BCM may not be set up; then all units local */ 568 #define RX_IS_LOCAL(unit) \ 569 (RX_IS_SETUP(unit) && (!BCM_UNIT_VALID(unit) || \ 570 (BCM_IS_LOCAL(unit) && !RX_IS_RCPU(unit)))) 571 #define RX_IS_REMOTE(unit) (RX_IS_SETUP(unit) && !RX_IS_LOCAL(unit)) 572 #else 573 #define RX_IS_LOCAL(unit) (RX_IS_SETUP(unit) && !RX_IS_RCPU(unit)) 574 #define RX_IS_REMOTE(unit) FALSE 575 #endif 576 577 /* 578 * give semaphore. Notification is given: 579 * When a packet is marked as processed. 580 * When the thread is stopped 581 * When a channel is enabled 582 * When a packet is queued to be serviced 583 * When a packet is queued to be freed 584 */ 585 #define RX_THREAD_NOTIFY(unit) { \ 586 if (!rx_control.pkt_notify_given) { \ 587 rx_control.pkt_notify_given = TRUE; \ 588 sal_sem_give(rx_control.pkt_notify); \ 589 } \ 590 } 591 592 extern int 593 _bcm_common_rx_sched_register(int unit, bcm_rx_sched_cb sched_cb); 594 595 extern int 596 _bcm_common_rx_sched_unregister(int unit); 597 598 extern int 599 _bcm_common_rx_unit_next_get(int unit, int *unit_next); 600 601 extern int 602 _bcm_common_rx_queue_max_get(int unit, bcm_cos_queue_t *cosq); 603 604 extern int 605 _bcm_common_rx_queue_packet_count_get(int unit, bcm_cos_queue_t cosq, int *packet_count); 606 607 extern int 608 _bcm_common_rx_queue_rate_limit_status_get(int unit, bcm_cos_queue_t cosq, 609 int *packet_tokens); 610 611 extern int 612 _bcm_common_rx_init(int unit); 613 614 extern int 615 _bcm_common_rx_cfg_init(int unit); 616 617 extern int 618 _bcm_common_rx_start(int unit, bcm_rx_cfg_t *cfg); 619 620 extern int 621 _bcm_common_rx_stop(int unit, bcm_rx_cfg_t *cfg); 622 623 extern int 624 _bcm_common_rx_clear(int unit); 625 626 extern int 627 _bcm_common_rx_cfg_get(int unit, bcm_rx_cfg_t *cfg); 628 629 extern int 630 _bcm_common_rx_queue_register(int unit, const char *name, bcm_cos_queue_t cosq, 631 bcm_rx_cb_f callback, uint8 priority, void *cookie, 632 uint32 flags); 633 634 extern int 635 _bcm_common_rx_register(int unit, const char *name, bcm_rx_cb_f callback, 636 uint8 priority, void *cookie, uint32 flags); 637 638 extern int 639 _bcm_common_rx_unregister(int unit, bcm_rx_cb_f callback, uint8 priority); 640 641 extern int 642 _bcm_common_rx_queue_unregister(int unit, bcm_cos_queue_t cosq, 643 bcm_rx_cb_f callback, uint8 priority); 644 645 extern int 646 _bcm_common_rx_reasons_get (int unit, bcm_rx_reasons_t *reasons); 647 648 extern int 649 _bcm_common_rx_queue_channel_set (int unit, bcm_cos_queue_t queue_id, 650 bcm_rx_chan_t chan_id); 651 extern int 652 _bcm_common_rx_queue_channel_set_helper (int unit, bcm_cos_queue_t queue_id, 653 bcm_rx_chan_t chan_id, int cmc); 654 655 extern int 656 _bcm_common_rx_queue_channel_get(int unit, bcm_cos_queue_t queue_id, 657 bcm_rx_chan_t *chan_id); 658 659 extern int 660 _bcm_common_rx_active(int unit); 661 662 extern int 663 _bcm_common_rx_channels_running(int unit, uint32 *channels); 664 665 extern int 666 _bcm_common_rx_alloc(int unit, int pkt_size, uint32 flags, void **buf); 667 668 extern int 669 _bcm_common_rx_free(int unit, void *pkt_data); 670 671 extern int 672 _bcm_common_rx_free_enqueue(int unit, void *pkt_data); 673 674 extern int 675 _bcm_common_rx_olp_match_rule_set (int unit, int olp_match_rule); 676 677 extern int 678 _bcm_common_rx_olp_match_rule_get (int unit, int *olp_match_rule); 679 680 extern int 681 _bcm_common_rx_rate_set(int unit, int pps); 682 683 extern int 684 _bcm_common_rx_rate_get(int unit, int *pps); 685 686 extern int 687 _bcm_common_rx_cpu_rate_set(int unit, int pps); 688 689 extern int 690 _bcm_common_rx_cpu_rate_get(int unit, int *pps); 691 692 extern int 693 _bcm_common_rx_burst_set(int unit, int burst); 694 695 extern int 696 _bcm_common_rx_burst_get(int unit, int *burst); 697 698 extern int 699 _bcm_common_rx_cos_rate_set(int unit, int cos, int pps); 700 701 extern int 702 _bcm_common_rx_cos_rate_get(int unit, int cos, int *pps); 703 704 extern int 705 _bcm_common_rx_cos_burst_set(int unit, int cos, int burst); 706 707 extern int 708 _bcm_common_rx_cos_burst_get(int unit, int cos, int *burst); 709 710 extern int 711 _bcm_common_rx_cos_max_len_set(int unit, int cos, int max_q_len); 712 713 extern int 714 _bcm_common_rx_cos_max_len_get(int unit, int cos, int *max_q_len); 715 716 extern int 717 _bcm_common_rx_remote_pkt_enqueue(int unit, bcm_pkt_t *pkt); 718 719 #if defined(BROADCOM_DEBUG) 720 extern int 721 _bcm_common_rx_show(int unit); 722 #endif /* BROADCOM_DEBUG */ 723 724 #endif