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

rx.h (28171B)


      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:        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 #ifdef BCM_DNX_SUPPORT
    478 #define BCM_RX_POOL_COUNT_DEFAULT      960
    479 #else
    480 #define BCM_RX_POOL_COUNT_DEFAULT      256
    481 #endif
    482 #endif
    483 
    484 #if !defined(BCM_RX_POOL_BYTES_DEFAULT)
    485 #define BCM_RX_POOL_BYTES_DEFAULT      RX_PKT_SIZE_DFLT
    486 #endif
    487 
    488 #define LEGAL_COS(cos) ((cos) >= BCM_RX_COS_ALL && (cos) < BCM_RX_COS)
    489 
    490 extern int                      rx_spl;
    491 #define RX_INTR_LOCK            rx_spl = sal_splhi()
    492 #define RX_INTR_UNLOCK          sal_spl(rx_spl)
    493 
    494 #define BCM_RX_CTRL_ACTIVE_UNITS_UPDATE (1 << 0)
    495 
    496 /* Single RX control structure, common for all units */
    497 typedef struct rx_control_s {
    498     /* Thread control */
    499     sal_sem_t         pkt_notify;       /* Semaphore for pkt thrd */
    500     volatile int      pkt_notify_given; /* Semaphore already given */
    501     sal_thread_t      rx_tid;           /* packet thread id */
    502     sal_thread_t      adapter_rx_tid;    /* adapter packet thread id */
    503     int               sleep_cur;        /* Current sleep time */
    504 #define MIN_SLEEP_US 5000               /* Always sleep at least 5 ms */
    505 #define MAX_SLEEP_US 100000             /* For non-rate limiting, .1 sec */
    506     volatile int      thread_running;   /* Input signal to thread */
    507     volatile int      thread_exit_complete; /* Output signal from thread */
    508 
    509     /* System wide rate limiting */
    510     int               system_pps;
    511     int               system_tokens;
    512     sal_usecs_t       system_last_fill;
    513 
    514     /* Thread protection mutexes. */
    515     sal_mutex_t       system_lock;
    516     sal_mutex_t       start_lock;
    517 
    518     /* RX started units misc info. */
    519     int               rx_unit_first;
    520     bcm_cos_queue_t   system_cosq_max;
    521 
    522     /* System flags. */
    523     int               system_flags;
    524 
    525     /* Scheduler function pointer. */
    526     bcm_rx_sched_cb   rx_sched_cb;
    527 } rx_control_t;
    528 
    529 extern rx_control_t rx_control;
    530 
    531 
    532 #ifdef ADAPTER_SERVER_MODE
    533 void rx_adapter_process_packet(int unit, bcm_pkt_t *pkt);
    534 #endif 
    535 
    536 #define _BCM_RX_SYSTEM_LOCK                                                \
    537           sal_mutex_take(rx_control.system_lock, sal_mutex_FOREVER)
    538 
    539 #define _BCM_RX_SYSTEM_UNLOCK sal_mutex_give(rx_control.system_lock)
    540 
    541 #define _BCM_RX_START_LOCK                                                \
    542           sal_mutex_take(rx_control.start_lock, sal_mutex_FOREVER)
    543 
    544 #define _BCM_RX_START_UNLOCK sal_mutex_give(rx_control.start_lock)
    545 
    546 #define _BCM_RX_SCHED_DEFAULT_CB (_bcm_rx_default_scheduler)
    547 #define _BCM_RX_CHECK_THREAD_DONE  if (!rx_control.thread_running) break
    548 
    549 #define RX_IS_SETUP(unit)     ((((unit) >= 0) && \
    550                                 ((unit) < BCM_CONTROL_MAX)) \
    551                                 && (rx_ctl[unit] != NULL))
    552 #define RX_UNIT_STARTED(unit) \
    553     (RX_IS_SETUP(unit) && rx_ctl[unit]->flags & BCM_RX_F_STARTED)
    554 #define RX_UNIT_REASONS_BFD_SET(unit) \
    555     if(RX_IS_SETUP(unit)) {rx_ctl[unit]->flags |= BCM_RX_REASONS_BFD;}
    556 #define RX_UNIT_REASONS_MPLS_BFD_SET(unit) \
    557     if(RX_IS_SETUP(unit)) {rx_ctl[unit]->flags |= BCM_RX_REASONS_MPLS_BFD;}
    558 #define RX_UNIT_REASONS_BFD_GET(unit, _x_) \
    559     if(RX_IS_SETUP(unit)) {_x_ = rx_ctl[unit]->flags & BCM_RX_REASONS_BFD;}
    560 #define RX_UNIT_REASONS_MPLS_BFD_GET(unit, _x_) \
    561     if(RX_IS_SETUP(unit)) {_x_ = rx_ctl[unit]->flags & BCM_RX_REASONS_MPLS_BFD;}
    562 #define RX_UNIT_REASONS_BFD_CLEAR(unit) \
    563     if(RX_IS_SETUP(unit)) {rx_ctl[unit]->flags &= ~BCM_RX_REASONS_BFD;}
    564 #define RX_UNIT_REASONS_MPLS_BFD_CLEAR(unit) \
    565     if(RX_IS_SETUP(unit)) {rx_ctl[unit]->flags &= ~BCM_RX_REASONS_MPLS_BFD;}
    566 
    567 /* RCPU units are not local, they are remote */
    568 #define RX_IS_RCPU(unit)        (SOC_UNIT_VALID(unit) && SOC_IS_RCPU_UNIT(unit))
    569 
    570 #if defined(BCM_RPC_SUPPORT)
    571 /* Accept that BCM may not be set up; then all units local */
    572 #define RX_IS_LOCAL(unit) \
    573     (RX_IS_SETUP(unit) && (!BCM_UNIT_VALID(unit) || \
    574       (BCM_IS_LOCAL(unit) && !RX_IS_RCPU(unit))))
    575 #define RX_IS_REMOTE(unit)    (RX_IS_SETUP(unit) && !RX_IS_LOCAL(unit))
    576 #else
    577 #define RX_IS_LOCAL(unit)     (RX_IS_SETUP(unit) && !RX_IS_RCPU(unit))
    578 #define RX_IS_REMOTE(unit)    FALSE
    579 #endif
    580 
    581 /*
    582  * give semaphore.  Notification is given:
    583  *      When a packet is marked as processed.
    584  *      When the thread is stopped
    585  *      When a channel is enabled
    586  *      When a packet is queued to be serviced
    587  *      When a packet is queued to be freed
    588  */
    589 #define RX_THREAD_NOTIFY(unit) {                                        \
    590     if (!rx_control.pkt_notify_given) {                                 \
    591         rx_control.pkt_notify_given = TRUE;                             \
    592         sal_sem_give(rx_control.pkt_notify);                            \
    593     }                                                                   \
    594 }
    595 
    596 extern int
    597 _bcm_common_rx_sched_register(int unit, bcm_rx_sched_cb sched_cb);
    598 
    599 extern int
    600 _bcm_common_rx_sched_unregister(int unit);
    601 
    602 extern int
    603 _bcm_common_rx_unit_next_get(int unit, int *unit_next);
    604 
    605 extern int
    606 _bcm_common_rx_queue_max_get(int unit, bcm_cos_queue_t  *cosq);
    607 
    608 extern int
    609 _bcm_common_rx_queue_packet_count_get(int unit, bcm_cos_queue_t cosq, int *packet_count);
    610 
    611 extern int
    612 _bcm_common_rx_queue_rate_limit_status_get(int unit, bcm_cos_queue_t cosq,
    613                                        int *packet_tokens);
    614 
    615 extern int
    616 _bcm_common_rx_init(int unit);
    617 
    618 extern int
    619 _bcm_common_rx_cfg_init(int unit);
    620 
    621 extern int
    622 _bcm_common_rx_start(int unit, bcm_rx_cfg_t *cfg);
    623 
    624 extern int
    625 _bcm_common_rx_stop(int unit, bcm_rx_cfg_t *cfg);
    626 
    627 extern int
    628 _bcm_common_rx_clear(int unit);
    629 
    630 extern int
    631 _bcm_common_rx_cfg_get(int unit, bcm_rx_cfg_t *cfg);
    632 
    633 extern int
    634 _bcm_common_rx_queue_register(int unit, const char *name, bcm_cos_queue_t cosq,
    635                           bcm_rx_cb_f callback, uint8 priority, void *cookie,
    636                           uint32 flags);
    637 
    638 extern int
    639 _bcm_common_rx_register(int unit, const char *name, bcm_rx_cb_f callback,
    640                 uint8 priority, void *cookie, uint32 flags);
    641 
    642 extern int
    643 _bcm_common_rx_unregister(int unit, bcm_rx_cb_f callback, uint8 priority);
    644 
    645 extern int
    646 _bcm_common_rx_queue_unregister(int unit, bcm_cos_queue_t cosq,
    647                             bcm_rx_cb_f callback, uint8 priority);
    648 
    649 extern int
    650 _bcm_common_rx_reasons_get (int unit, bcm_rx_reasons_t *reasons);
    651 
    652 extern int
    653 _bcm_common_rx_queue_channel_set (int unit, bcm_cos_queue_t queue_id,
    654                               bcm_rx_chan_t chan_id);
    655 extern int
    656 _bcm_common_rx_queue_channel_set_helper (int unit, bcm_cos_queue_t queue_id,
    657                               bcm_rx_chan_t chan_id, int cmc);
    658 
    659 extern int
    660 _bcm_common_rx_queue_channel_get(int unit, bcm_cos_queue_t queue_id,
    661                              bcm_rx_chan_t *chan_id);
    662 
    663 extern int
    664 _bcm_common_rx_active(int unit);
    665 
    666 extern int
    667 _bcm_common_rx_channels_running(int unit, uint32 *channels);
    668 
    669 extern int
    670 _bcm_common_rx_alloc(int unit, int pkt_size, uint32 flags, void **buf);
    671 
    672 extern int
    673 _bcm_common_rx_free(int unit, void *pkt_data);
    674 
    675 extern int
    676 _bcm_common_rx_free_enqueue(int unit, void *pkt_data);
    677 
    678 extern int
    679 _bcm_common_rx_olp_match_rule_set (int unit, int olp_match_rule);
    680 
    681 extern int
    682 _bcm_common_rx_olp_match_rule_get (int unit, int *olp_match_rule);
    683 
    684 extern int
    685 _bcm_common_rx_rate_set(int unit, int pps);
    686 
    687 extern int
    688 _bcm_common_rx_rate_get(int unit, int *pps);
    689 
    690 extern int
    691 _bcm_common_rx_cpu_rate_set(int unit, int pps);
    692 
    693 extern int
    694 _bcm_common_rx_cpu_rate_get(int unit, int *pps);
    695 
    696 extern int
    697 _bcm_common_rx_burst_set(int unit, int burst);
    698 
    699 extern int
    700 _bcm_common_rx_burst_get(int unit, int *burst);
    701 
    702 extern int
    703 _bcm_common_rx_cos_rate_set(int unit, int cos, int pps);
    704 
    705 extern int
    706 _bcm_common_rx_cos_rate_get(int unit, int cos, int *pps);
    707 
    708 extern int
    709 _bcm_common_rx_cos_burst_set(int unit, int cos, int burst);
    710 
    711 extern int
    712 _bcm_common_rx_cos_burst_get(int unit, int cos, int *burst);
    713 
    714 extern int
    715 _bcm_common_rx_cos_max_len_set(int unit, int cos, int max_q_len);
    716 
    717 extern int
    718 _bcm_common_rx_cos_max_len_get(int unit, int cos, int *max_q_len);
    719   
    720 extern int
    721 _bcm_common_rx_remote_pkt_enqueue(int unit, bcm_pkt_t *pkt);
    722 
    723 #if defined(BROADCOM_DEBUG)
    724 extern int
    725 _bcm_common_rx_show(int unit);
    726 #endif /* BROADCOM_DEBUG */
    727 
    728 extern int
    729 _bcm_rx_shutdown(int unit);
    730 #endif