1*4882a593Smuzhiyun /* 2*4882a593Smuzhiyun * HND generic pktq operation primitives 3*4882a593Smuzhiyun * 4*4882a593Smuzhiyun * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation 5*4882a593Smuzhiyun * 6*4882a593Smuzhiyun * Copyright (C) 1999-2017, Broadcom Corporation 7*4882a593Smuzhiyun * 8*4882a593Smuzhiyun * Unless you and Broadcom execute a separate written software license 9*4882a593Smuzhiyun * agreement governing use of this software, this software is licensed to you 10*4882a593Smuzhiyun * under the terms of the GNU General Public License version 2 (the "GPL"), 11*4882a593Smuzhiyun * available at http://www.broadcom.com/licenses/GPLv2.php, with the 12*4882a593Smuzhiyun * following added to such license: 13*4882a593Smuzhiyun * 14*4882a593Smuzhiyun * As a special exception, the copyright holders of this software give you 15*4882a593Smuzhiyun * permission to link this software with independent modules, and to copy and 16*4882a593Smuzhiyun * distribute the resulting executable under terms of your choice, provided that 17*4882a593Smuzhiyun * you also meet, for each linked independent module, the terms and conditions of 18*4882a593Smuzhiyun * the license of that module. An independent module is a module which is not 19*4882a593Smuzhiyun * derived from this software. The special exception does not apply to any 20*4882a593Smuzhiyun * modifications of the software. 21*4882a593Smuzhiyun * 22*4882a593Smuzhiyun * Notwithstanding the above, under no circumstances may you combine this 23*4882a593Smuzhiyun * software in any way with any other Broadcom software provided under a license 24*4882a593Smuzhiyun * other than the GPL, without Broadcom's express prior written consent. 25*4882a593Smuzhiyun * 26*4882a593Smuzhiyun * 27*4882a593Smuzhiyun * <<Broadcom-WL-IPTag/Open:>> 28*4882a593Smuzhiyun * 29*4882a593Smuzhiyun * $Id: hnd_pktq.h 698847 2017-05-11 00:10:48Z $ 30*4882a593Smuzhiyun */ 31*4882a593Smuzhiyun 32*4882a593Smuzhiyun #ifndef _hnd_pktq_h_ 33*4882a593Smuzhiyun #define _hnd_pktq_h_ 34*4882a593Smuzhiyun 35*4882a593Smuzhiyun #include <osl_ext.h> 36*4882a593Smuzhiyun 37*4882a593Smuzhiyun #ifdef __cplusplus 38*4882a593Smuzhiyun extern "C" { 39*4882a593Smuzhiyun #endif // endif 40*4882a593Smuzhiyun 41*4882a593Smuzhiyun /* mutex macros for thread safe */ 42*4882a593Smuzhiyun #ifdef HND_PKTQ_THREAD_SAFE 43*4882a593Smuzhiyun #define HND_PKTQ_MUTEX_DECL(mutex) OSL_EXT_MUTEX_DECL(mutex) 44*4882a593Smuzhiyun #else 45*4882a593Smuzhiyun #define HND_PKTQ_MUTEX_DECL(mutex) 46*4882a593Smuzhiyun #endif // endif 47*4882a593Smuzhiyun 48*4882a593Smuzhiyun /* osl multi-precedence packet queue */ 49*4882a593Smuzhiyun #define PKTQ_LEN_MAX 0xFFFF /* Max uint16 65535 packets */ 50*4882a593Smuzhiyun #ifndef PKTQ_LEN_DEFAULT 51*4882a593Smuzhiyun #define PKTQ_LEN_DEFAULT 128 /* Max 128 packets */ 52*4882a593Smuzhiyun #endif // endif 53*4882a593Smuzhiyun #ifndef PKTQ_MAX_PREC 54*4882a593Smuzhiyun #define PKTQ_MAX_PREC 16 /* Maximum precedence levels */ 55*4882a593Smuzhiyun #endif // endif 56*4882a593Smuzhiyun 57*4882a593Smuzhiyun /** Queue for a single precedence level */ 58*4882a593Smuzhiyun typedef struct pktq_prec { 59*4882a593Smuzhiyun void *head; /**< first packet to dequeue */ 60*4882a593Smuzhiyun void *tail; /**< last packet to dequeue */ 61*4882a593Smuzhiyun uint16 n_pkts; /**< number of queued packets */ 62*4882a593Smuzhiyun uint16 max_pkts; /**< maximum number of queued packets */ 63*4882a593Smuzhiyun uint16 stall_count; /**< # seconds since no packets are dequeued */ 64*4882a593Smuzhiyun uint16 dequeue_count; /**< # of packets dequeued in last 1 second */ 65*4882a593Smuzhiyun } pktq_prec_t; 66*4882a593Smuzhiyun 67*4882a593Smuzhiyun #ifdef PKTQ_LOG 68*4882a593Smuzhiyun typedef struct { 69*4882a593Smuzhiyun uint32 requested; /**< packets requested to be stored */ 70*4882a593Smuzhiyun uint32 stored; /**< packets stored */ 71*4882a593Smuzhiyun uint32 saved; /**< packets saved, 72*4882a593Smuzhiyun because a lowest priority queue has given away one packet 73*4882a593Smuzhiyun */ 74*4882a593Smuzhiyun uint32 selfsaved; /**< packets saved, 75*4882a593Smuzhiyun because an older packet from the same queue has been dropped 76*4882a593Smuzhiyun */ 77*4882a593Smuzhiyun uint32 full_dropped; /**< packets dropped, 78*4882a593Smuzhiyun because pktq is full with higher precedence packets 79*4882a593Smuzhiyun */ 80*4882a593Smuzhiyun uint32 dropped; /**< packets dropped because pktq per that precedence is full */ 81*4882a593Smuzhiyun uint32 sacrificed; /**< packets dropped, 82*4882a593Smuzhiyun in order to save one from a queue of a highest priority 83*4882a593Smuzhiyun */ 84*4882a593Smuzhiyun uint32 busy; /**< packets droped because of hardware/transmission error */ 85*4882a593Smuzhiyun uint32 retry; /**< packets re-sent because they were not received */ 86*4882a593Smuzhiyun uint32 ps_retry; /**< packets retried again prior to moving power save mode */ 87*4882a593Smuzhiyun uint32 suppress; /**< packets which were suppressed and not transmitted */ 88*4882a593Smuzhiyun uint32 retry_drop; /**< packets finally dropped after retry limit */ 89*4882a593Smuzhiyun uint32 max_avail; /**< the high-water mark of the queue capacity for packets - 90*4882a593Smuzhiyun goes to zero as queue fills 91*4882a593Smuzhiyun */ 92*4882a593Smuzhiyun uint32 max_used; /**< the high-water mark of the queue utilisation for packets - 93*4882a593Smuzhiyun increases with use ('inverse' of max_avail) 94*4882a593Smuzhiyun */ 95*4882a593Smuzhiyun uint32 queue_capacity; /**< the maximum capacity of the queue */ 96*4882a593Smuzhiyun uint32 rtsfail; /**< count of rts attempts that failed to receive cts */ 97*4882a593Smuzhiyun uint32 acked; /**< count of packets sent (acked) successfully */ 98*4882a593Smuzhiyun uint32 txrate_succ; /**< running total of phy rate of packets sent successfully */ 99*4882a593Smuzhiyun uint32 txrate_main; /**< running totoal of primary phy rate of all packets */ 100*4882a593Smuzhiyun uint32 throughput; /**< actual data transferred successfully */ 101*4882a593Smuzhiyun uint32 airtime; /**< cumulative total medium access delay in useconds */ 102*4882a593Smuzhiyun uint32 _logtime; /**< timestamp of last counter clear */ 103*4882a593Smuzhiyun } pktq_counters_t; 104*4882a593Smuzhiyun 105*4882a593Smuzhiyun #define PKTQ_LOG_COMMON \ 106*4882a593Smuzhiyun uint32 pps_time; /**< time spent in ps pretend state */ \ 107*4882a593Smuzhiyun uint32 _prec_log; 108*4882a593Smuzhiyun 109*4882a593Smuzhiyun typedef struct { 110*4882a593Smuzhiyun PKTQ_LOG_COMMON 111*4882a593Smuzhiyun pktq_counters_t* _prec_cnt[PKTQ_MAX_PREC]; /**< Counters per queue */ 112*4882a593Smuzhiyun } pktq_log_t; 113*4882a593Smuzhiyun #else 114*4882a593Smuzhiyun typedef struct pktq_log pktq_log_t; 115*4882a593Smuzhiyun #endif /* PKTQ_LOG */ 116*4882a593Smuzhiyun 117*4882a593Smuzhiyun #define PKTQ_COMMON \ 118*4882a593Smuzhiyun HND_PKTQ_MUTEX_DECL(mutex) \ 119*4882a593Smuzhiyun pktq_log_t *pktqlog; \ 120*4882a593Smuzhiyun uint16 num_prec; /**< number of precedences in use */ \ 121*4882a593Smuzhiyun uint16 hi_prec; /**< rapid dequeue hint (>= highest non-empty prec) */ \ 122*4882a593Smuzhiyun uint16 max_pkts; /**< max packets */ \ 123*4882a593Smuzhiyun uint16 n_pkts_tot; /**< total (cummulative over all precedences) number of packets */ 124*4882a593Smuzhiyun 125*4882a593Smuzhiyun /** multi-priority packet queue */ 126*4882a593Smuzhiyun struct pktq { 127*4882a593Smuzhiyun PKTQ_COMMON 128*4882a593Smuzhiyun /* q array must be last since # of elements can be either PKTQ_MAX_PREC or 1 */ 129*4882a593Smuzhiyun struct pktq_prec q[PKTQ_MAX_PREC]; 130*4882a593Smuzhiyun }; 131*4882a593Smuzhiyun 132*4882a593Smuzhiyun /** simple, non-priority packet queue */ 133*4882a593Smuzhiyun struct spktq { 134*4882a593Smuzhiyun HND_PKTQ_MUTEX_DECL(mutex) 135*4882a593Smuzhiyun struct pktq_prec q; 136*4882a593Smuzhiyun }; 137*4882a593Smuzhiyun 138*4882a593Smuzhiyun #define PKTQ_PREC_ITER(pq, prec) for (prec = (pq)->num_prec - 1; prec >= 0; prec--) 139*4882a593Smuzhiyun 140*4882a593Smuzhiyun /* fn(pkt, arg). return true if pkt belongs to bsscfg */ 141*4882a593Smuzhiyun typedef bool (*ifpkt_cb_t)(void*, int); 142*4882a593Smuzhiyun 143*4882a593Smuzhiyun /* 144*4882a593Smuzhiyun * pktq filter support 145*4882a593Smuzhiyun */ 146*4882a593Smuzhiyun 147*4882a593Smuzhiyun /** filter function return values */ 148*4882a593Smuzhiyun typedef enum { 149*4882a593Smuzhiyun PKT_FILTER_NOACTION = 0, /**< restore the pkt to its position in the queue */ 150*4882a593Smuzhiyun PKT_FILTER_DELETE = 1, /**< delete the pkt */ 151*4882a593Smuzhiyun PKT_FILTER_REMOVE = 2, /**< do not restore the pkt to the queue, 152*4882a593Smuzhiyun * filter fn has taken ownership of the pkt 153*4882a593Smuzhiyun */ 154*4882a593Smuzhiyun } pktq_filter_result_t; 155*4882a593Smuzhiyun 156*4882a593Smuzhiyun /** 157*4882a593Smuzhiyun * Caller supplied filter function to pktq_pfilter(), pktq_filter(). 158*4882a593Smuzhiyun * Function filter(ctx, pkt) is called with its ctx pointer on each pkt in the 159*4882a593Smuzhiyun * pktq. When the filter function is called, the supplied pkt will have been 160*4882a593Smuzhiyun * unlinked from the pktq. The filter function returns a pktq_filter_result_t 161*4882a593Smuzhiyun * result specifying the action pktq_filter()/pktq_pfilter() should take for 162*4882a593Smuzhiyun * the pkt. 163*4882a593Smuzhiyun * Here are the actions taken by pktq_filter/pfilter() based on the supplied 164*4882a593Smuzhiyun * filter function's return value: 165*4882a593Smuzhiyun * 166*4882a593Smuzhiyun * PKT_FILTER_NOACTION - The filter will re-link the pkt at its 167*4882a593Smuzhiyun * previous location. 168*4882a593Smuzhiyun * 169*4882a593Smuzhiyun * PKT_FILTER_DELETE - The filter will not relink the pkt and will 170*4882a593Smuzhiyun * call the user supplied defer_free_pkt fn on the packet. 171*4882a593Smuzhiyun * 172*4882a593Smuzhiyun * PKT_FILTER_REMOVE - The filter will not relink the pkt. The supplied 173*4882a593Smuzhiyun * filter fn took ownership (or deleted) the pkt. 174*4882a593Smuzhiyun * 175*4882a593Smuzhiyun * WARNING: pkts inserted by the user (in pkt_filter and/or flush callbacks 176*4882a593Smuzhiyun * and chains) in the prec queue will not be seen by the filter, and the prec 177*4882a593Smuzhiyun * queue will be temporarily be removed from the queue hence there're side 178*4882a593Smuzhiyun * effects including pktq_n_pkts_tot() on the queue won't reflect the correct number 179*4882a593Smuzhiyun * of packets in the queue. 180*4882a593Smuzhiyun */ 181*4882a593Smuzhiyun 182*4882a593Smuzhiyun typedef pktq_filter_result_t (*pktq_filter_t)(void* ctx, void* pkt); 183*4882a593Smuzhiyun 184*4882a593Smuzhiyun /** 185*4882a593Smuzhiyun * The defer_free_pkt callback is invoked when the the pktq_filter callback 186*4882a593Smuzhiyun * returns PKT_FILTER_DELETE decision, which allows the user to deposite 187*4882a593Smuzhiyun * the packet appropriately based on the situation (free the packet or 188*4882a593Smuzhiyun * save it in a temporary queue etc.). 189*4882a593Smuzhiyun */ 190*4882a593Smuzhiyun typedef void (*defer_free_pkt_fn_t)(void *ctx, void *pkt); 191*4882a593Smuzhiyun 192*4882a593Smuzhiyun /** 193*4882a593Smuzhiyun * The flush_free_pkt callback is invoked when all packets in the pktq 194*4882a593Smuzhiyun * are processed. 195*4882a593Smuzhiyun */ 196*4882a593Smuzhiyun typedef void (*flush_free_pkt_fn_t)(void *ctx); 197*4882a593Smuzhiyun 198*4882a593Smuzhiyun #if defined(WLAMPDU_MAC) && defined(PROP_TXSTATUS) 199*4882a593Smuzhiyun /* this callback will be invoked when in low_txq_scb flush() 200*4882a593Smuzhiyun * two back-to-back pkts has same epoch value. 201*4882a593Smuzhiyun */ 202*4882a593Smuzhiyun typedef void (*flip_epoch_t)(void *ctx, void *pkt, uint8 *flipEpoch, uint8 *lastEpoch); 203*4882a593Smuzhiyun #endif /* defined(WLAMPDU_MAC) && defined(PROP_TXSTATUS) */ 204*4882a593Smuzhiyun 205*4882a593Smuzhiyun /** filter a pktq, using the caller supplied filter/deposition/flush functions */ 206*4882a593Smuzhiyun extern void pktq_filter(struct pktq *pq, pktq_filter_t fn, void* arg, 207*4882a593Smuzhiyun defer_free_pkt_fn_t defer, void *defer_ctx, flush_free_pkt_fn_t flush, void *flush_ctx); 208*4882a593Smuzhiyun /** filter a particular precedence in pktq, using the caller supplied filter function */ 209*4882a593Smuzhiyun extern void pktq_pfilter(struct pktq *pq, int prec, pktq_filter_t fn, void* arg, 210*4882a593Smuzhiyun defer_free_pkt_fn_t defer, void *defer_ctx, flush_free_pkt_fn_t flush, void *flush_ctx); 211*4882a593Smuzhiyun /** filter a simple non-precedence in spktq, using the caller supplied filter function */ 212*4882a593Smuzhiyun extern void spktq_filter(struct spktq *spq, pktq_filter_t fltr, void* fltr_ctx, 213*4882a593Smuzhiyun defer_free_pkt_fn_t defer, void *defer_ctx, flush_free_pkt_fn_t flush, void *flush_ctx); 214*4882a593Smuzhiyun 215*4882a593Smuzhiyun /* operations on a specific precedence in packet queue */ 216*4882a593Smuzhiyun #define pktqprec_max_pkts(pq, prec) ((pq)->q[prec].max_pkts) 217*4882a593Smuzhiyun #define pktqprec_n_pkts(pq, prec) ((pq)->q[prec].n_pkts) 218*4882a593Smuzhiyun #define pktqprec_empty(pq, prec) ((pq)->q[prec].n_pkts == 0) 219*4882a593Smuzhiyun #define pktqprec_peek(pq, prec) ((pq)->q[prec].head) 220*4882a593Smuzhiyun #define pktqprec_peek_tail(pq, prec) ((pq)->q[prec].tail) 221*4882a593Smuzhiyun #define spktq_peek_tail(pq) ((pq)->q.tail) 222*4882a593Smuzhiyun #ifdef HND_PKTQ_THREAD_SAFE 223*4882a593Smuzhiyun extern int pktqprec_avail_pkts(struct pktq *pq, int prec); 224*4882a593Smuzhiyun extern bool pktqprec_full(struct pktq *pq, int prec); 225*4882a593Smuzhiyun #else 226*4882a593Smuzhiyun #define pktqprec_avail_pkts(pq, prec) ((pq)->q[prec].max_pkts - (pq)->q[prec].n_pkts) 227*4882a593Smuzhiyun #define pktqprec_full(pq, prec) ((pq)->q[prec].n_pkts >= (pq)->q[prec].max_pkts) 228*4882a593Smuzhiyun #endif /* HND_PKTQ_THREAD_SAFE */ 229*4882a593Smuzhiyun 230*4882a593Smuzhiyun extern void pktq_append(struct pktq *pq, int prec, struct spktq *list); 231*4882a593Smuzhiyun extern void spktq_append(struct spktq *spq, struct spktq *list); 232*4882a593Smuzhiyun extern void pktq_prepend(struct pktq *pq, int prec, struct spktq *list); 233*4882a593Smuzhiyun extern void spktq_prepend(struct spktq *spq, struct spktq *list); 234*4882a593Smuzhiyun extern void *pktq_penq(struct pktq *pq, int prec, void *p); 235*4882a593Smuzhiyun extern void *pktq_penq_head(struct pktq *pq, int prec, void *p); 236*4882a593Smuzhiyun extern void *pktq_pdeq(struct pktq *pq, int prec); 237*4882a593Smuzhiyun extern void *pktq_pdeq_prev(struct pktq *pq, int prec, void *prev_p); 238*4882a593Smuzhiyun extern void *pktq_pdeq_with_fn(struct pktq *pq, int prec, ifpkt_cb_t fn, int arg); 239*4882a593Smuzhiyun extern void *pktq_pdeq_tail(struct pktq *pq, int prec); 240*4882a593Smuzhiyun /** Remove a specified packet from its queue */ 241*4882a593Smuzhiyun extern bool pktq_pdel(struct pktq *pq, void *p, int prec); 242*4882a593Smuzhiyun 243*4882a593Smuzhiyun /* For single precedence queues */ 244*4882a593Smuzhiyun extern void *spktq_enq(struct spktq *spq, void *p); 245*4882a593Smuzhiyun extern void *spktq_enq_head(struct spktq *spq, void *p); 246*4882a593Smuzhiyun extern void *spktq_deq(struct spktq *spq); 247*4882a593Smuzhiyun extern void *spktq_deq_tail(struct spktq *spq); 248*4882a593Smuzhiyun 249*4882a593Smuzhiyun /* operations on a set of precedences in packet queue */ 250*4882a593Smuzhiyun 251*4882a593Smuzhiyun extern int pktq_mlen(struct pktq *pq, uint prec_bmp); 252*4882a593Smuzhiyun extern void *pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out); 253*4882a593Smuzhiyun extern void *pktq_mpeek(struct pktq *pq, uint prec_bmp, int *prec_out); 254*4882a593Smuzhiyun 255*4882a593Smuzhiyun /* operations on packet queue as a whole */ 256*4882a593Smuzhiyun 257*4882a593Smuzhiyun #define pktq_n_pkts_tot(pq) ((int)(pq)->n_pkts_tot) 258*4882a593Smuzhiyun #define pktq_max(pq) ((int)(pq)->max_pkts) 259*4882a593Smuzhiyun #define pktq_empty(pq) ((pq)->n_pkts_tot == 0) 260*4882a593Smuzhiyun #define spktq_n_pkts(spq) ((int)(spq)->q.n_pkts) 261*4882a593Smuzhiyun #define spktq_empty(spq) ((spq)->q.n_pkts == 0) 262*4882a593Smuzhiyun 263*4882a593Smuzhiyun #define spktq_max(spq) ((int)(spq)->q.max_pkts) 264*4882a593Smuzhiyun #define spktq_empty(spq) ((spq)->q.n_pkts == 0) 265*4882a593Smuzhiyun #ifdef HND_PKTQ_THREAD_SAFE 266*4882a593Smuzhiyun extern int pktq_avail(struct pktq *pq); 267*4882a593Smuzhiyun extern bool pktq_full(struct pktq *pq); 268*4882a593Smuzhiyun extern int spktq_avail(struct spktq *spq); 269*4882a593Smuzhiyun extern bool spktq_full(struct spktq *spq); 270*4882a593Smuzhiyun #else 271*4882a593Smuzhiyun #define pktq_avail(pq) ((int)((pq)->max_pkts - (pq)->n_pkts_tot)) 272*4882a593Smuzhiyun #define pktq_full(pq) ((pq)->n_pkts_tot >= (pq)->max_pkts) 273*4882a593Smuzhiyun #define spktq_avail(spq) ((int)((spq)->q.max_pkts - (spq)->q.n_pkts)) 274*4882a593Smuzhiyun #define spktq_full(spq) ((spq)->q.n_pkts >= (spq)->q.max_pkts) 275*4882a593Smuzhiyun #endif /* HND_PKTQ_THREAD_SAFE */ 276*4882a593Smuzhiyun 277*4882a593Smuzhiyun /* operations for single precedence queues */ 278*4882a593Smuzhiyun #define pktenq(pq, p) pktq_penq((pq), 0, (p)) 279*4882a593Smuzhiyun #define pktenq_head(pq, p) pktq_penq_head((pq), 0, (p)) 280*4882a593Smuzhiyun #define pktdeq(pq) pktq_pdeq((pq), 0) 281*4882a593Smuzhiyun #define pktdeq_tail(pq) pktq_pdeq_tail((pq), 0) 282*4882a593Smuzhiyun #define pktqflush(osh, pq, dir) pktq_pflush(osh, (pq), 0, (dir)) 283*4882a593Smuzhiyun #define pktqinit(pq, max_pkts) pktq_init((pq), 1, (max_pkts)) 284*4882a593Smuzhiyun #define pktqdeinit(pq) pktq_deinit((pq)) 285*4882a593Smuzhiyun #define pktqavail(pq) pktq_avail((pq)) 286*4882a593Smuzhiyun #define pktqfull(pq) pktq_full((pq)) 287*4882a593Smuzhiyun #define pktqfilter(pq, fltr, fltr_ctx, defer, defer_ctx, flush, flush_ctx) \ 288*4882a593Smuzhiyun pktq_pfilter((pq), 0, (fltr), (fltr_ctx), (defer), (defer_ctx), (flush), (flush_ctx)) 289*4882a593Smuzhiyun 290*4882a593Smuzhiyun /* operations for simple non-precedence queues */ 291*4882a593Smuzhiyun #define spktenq(spq, p) spktq_enq((spq), (p)) 292*4882a593Smuzhiyun #define spktenq_head(spq, p) spktq_enq_head((spq), (p)) 293*4882a593Smuzhiyun #define spktdeq(spq) spktq_deq((spq)) 294*4882a593Smuzhiyun #define spktdeq_tail(spq) spktq_deq_tail((spq)) 295*4882a593Smuzhiyun #define spktqflush(osh, spq, dir) spktq_flush((osh), (spq), (dir)) 296*4882a593Smuzhiyun #define spktqinit(spq, max_pkts) spktq_init((spq), (max_pkts)) 297*4882a593Smuzhiyun #define spktqdeinit(spq) spktq_deinit((spq)) 298*4882a593Smuzhiyun #define spktqavail(spq) spktq_avail((spq)) 299*4882a593Smuzhiyun #define spktqfull(spq) spktq_full((spq)) 300*4882a593Smuzhiyun 301*4882a593Smuzhiyun #define spktqfilter(spq, fltr, fltr_ctx, defer, defer_ctx, flush, flush_ctx) \ 302*4882a593Smuzhiyun spktq_filter((spq), (fltr), (fltr_ctx), (defer), (defer_ctx), (flush), (flush_ctx)) 303*4882a593Smuzhiyun extern bool pktq_init(struct pktq *pq, int num_prec, int max_pkts); 304*4882a593Smuzhiyun extern bool pktq_deinit(struct pktq *pq); 305*4882a593Smuzhiyun extern bool spktq_init(struct spktq *spq, int max_pkts); 306*4882a593Smuzhiyun extern bool spktq_deinit(struct spktq *spq); 307*4882a593Smuzhiyun 308*4882a593Smuzhiyun extern void pktq_set_max_plen(struct pktq *pq, int prec, int max_pkts); 309*4882a593Smuzhiyun 310*4882a593Smuzhiyun /* prec_out may be NULL if caller is not interested in return value */ 311*4882a593Smuzhiyun extern void *pktq_deq(struct pktq *pq, int *prec_out); 312*4882a593Smuzhiyun extern void *pktq_deq_tail(struct pktq *pq, int *prec_out); 313*4882a593Smuzhiyun extern void *pktq_peek(struct pktq *pq, int *prec_out); 314*4882a593Smuzhiyun extern void *spktq_peek(struct spktq *spq); 315*4882a593Smuzhiyun extern void *pktq_peek_tail(struct pktq *pq, int *prec_out); 316*4882a593Smuzhiyun 317*4882a593Smuzhiyun /** flush pktq */ 318*4882a593Smuzhiyun extern void pktq_flush(osl_t *osh, struct pktq *pq, bool dir); 319*4882a593Smuzhiyun extern void spktq_flush(osl_t *osh, struct spktq *spq, bool dir); 320*4882a593Smuzhiyun /** Empty the queue at particular precedence level */ 321*4882a593Smuzhiyun extern void pktq_pflush(osl_t *osh, struct pktq *pq, int prec, bool dir); 322*4882a593Smuzhiyun 323*4882a593Smuzhiyun #ifdef __cplusplus 324*4882a593Smuzhiyun } 325*4882a593Smuzhiyun #endif // endif 326*4882a593Smuzhiyun 327*4882a593Smuzhiyun #endif /* _hnd_pktq_h_ */ 328