forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/net/wireless/rockchip_wlan/cywdhd/bcmdhd/include/hnd_pktq.h
....@@ -1,15 +1,16 @@
1
-/* SPDX-License-Identifier: GPL-2.0 */
21 /*
32 * HND generic pktq operation primitives
43 *
5
- * Copyright (C) 1999-2019, Broadcom Corporation
6
- *
4
+ * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
5
+ *
6
+ * Copyright (C) 1999-2017, Broadcom Corporation
7
+ *
78 * Unless you and Broadcom execute a separate written software license
89 * agreement governing use of this software, this software is licensed to you
910 * under the terms of the GNU General Public License version 2 (the "GPL"),
1011 * available at http://www.broadcom.com/licenses/GPLv2.php, with the
1112 * following added to such license:
12
- *
13
+ *
1314 * As a special exception, the copyright holders of this software give you
1415 * permission to link this software with independent modules, and to copy and
1516 * distribute the resulting executable under terms of your choice, provided that
....@@ -17,7 +18,7 @@
1718 * the license of that module. An independent module is a module which is not
1819 * derived from this software. The special exception does not apply to any
1920 * modifications of the software.
20
- *
21
+ *
2122 * Notwithstanding the above, under no circumstances may you combine this
2223 * software in any way with any other Broadcom software provided under a license
2324 * other than the GPL, without Broadcom's express prior written consent.
....@@ -25,7 +26,7 @@
2526 *
2627 * <<Broadcom-WL-IPTag/Open:>>
2728 *
28
- * $Id$
29
+ * $Id: hnd_pktq.h 698847 2017-05-11 00:10:48Z $
2930 */
3031
3132 #ifndef _hnd_pktq_h_
....@@ -35,29 +36,32 @@
3536
3637 #ifdef __cplusplus
3738 extern "C" {
38
-#endif
39
+#endif // endif
3940
4041 /* mutex macros for thread safe */
4142 #ifdef HND_PKTQ_THREAD_SAFE
4243 #define HND_PKTQ_MUTEX_DECL(mutex) OSL_EXT_MUTEX_DECL(mutex)
4344 #else
4445 #define HND_PKTQ_MUTEX_DECL(mutex)
45
-#endif
46
+#endif // endif
4647
4748 /* osl multi-precedence packet queue */
4849 #define PKTQ_LEN_MAX 0xFFFF /* Max uint16 65535 packets */
4950 #ifndef PKTQ_LEN_DEFAULT
5051 #define PKTQ_LEN_DEFAULT 128 /* Max 128 packets */
51
-#endif
52
+#endif // endif
5253 #ifndef PKTQ_MAX_PREC
5354 #define PKTQ_MAX_PREC 16 /* Maximum precedence levels */
54
-#endif
55
+#endif // endif
5556
57
+/** Queue for a single precedence level */
5658 typedef struct pktq_prec {
5759 void *head; /**< first packet to dequeue */
5860 void *tail; /**< last packet to dequeue */
59
- uint16 len; /**< number of queued packets */
60
- uint16 max; /**< maximum number of queued packets */
61
+ uint16 n_pkts; /**< number of queued packets */
62
+ uint16 max_pkts; /**< maximum number of queued packets */
63
+ uint16 stall_count; /**< # seconds since no packets are dequeued */
64
+ uint16 dequeue_count; /**< # of packets dequeued in last 1 second */
6165 } pktq_prec_t;
6266
6367 #ifdef PKTQ_LOG
....@@ -98,73 +102,149 @@
98102 uint32 _logtime; /**< timestamp of last counter clear */
99103 } pktq_counters_t;
100104
101
-typedef struct {
105
+#define PKTQ_LOG_COMMON \
106
+ uint32 pps_time; /**< time spent in ps pretend state */ \
102107 uint32 _prec_log;
108
+
109
+typedef struct {
110
+ PKTQ_LOG_COMMON
103111 pktq_counters_t* _prec_cnt[PKTQ_MAX_PREC]; /**< Counters per queue */
104112 } pktq_log_t;
113
+#else
114
+typedef struct pktq_log pktq_log_t;
105115 #endif /* PKTQ_LOG */
106116
107
-
108117 #define PKTQ_COMMON \
118
+ HND_PKTQ_MUTEX_DECL(mutex) \
119
+ pktq_log_t *pktqlog; \
109120 uint16 num_prec; /**< number of precedences in use */ \
110121 uint16 hi_prec; /**< rapid dequeue hint (>= highest non-empty prec) */ \
111
- uint16 max; /**< total max packets */ \
112
- uint16 len; /**< total number of packets */
122
+ uint16 max_pkts; /**< max packets */ \
123
+ uint16 n_pkts_tot; /**< total (cummulative over all precedences) number of packets */
113124
114
-/* multi-priority pkt queue */
125
+/** multi-priority packet queue */
115126 struct pktq {
116127 PKTQ_COMMON
117128 /* q array must be last since # of elements can be either PKTQ_MAX_PREC or 1 */
118129 struct pktq_prec q[PKTQ_MAX_PREC];
119
- HND_PKTQ_MUTEX_DECL(mutex)
120
-#ifdef PKTQ_LOG
121
- pktq_log_t* pktqlog;
122
-#endif
123130 };
124131
125
-/* simple, non-priority pkt queue */
132
+/** simple, non-priority packet queue */
126133 struct spktq {
127
- PKTQ_COMMON
128
- /* q array must be last since # of elements can be either PKTQ_MAX_PREC or 1 */
129
- struct pktq_prec q[1];
130134 HND_PKTQ_MUTEX_DECL(mutex)
135
+ struct pktq_prec q;
131136 };
132137
133138 #define PKTQ_PREC_ITER(pq, prec) for (prec = (pq)->num_prec - 1; prec >= 0; prec--)
134139
135
-/* fn(pkt, arg). return true if pkt belongs to if */
140
+/* fn(pkt, arg). return true if pkt belongs to bsscfg */
136141 typedef bool (*ifpkt_cb_t)(void*, int);
137142
138
-/* operations on a specific precedence in packet queue */
143
+/*
144
+ * pktq filter support
145
+ */
139146
140
-#define pktq_psetmax(pq, prec, _max) ((pq)->q[prec].max = (_max))
141
-#define pktq_pmax(pq, prec) ((pq)->q[prec].max)
142
-#define pktq_plen(pq, prec) ((pq)->q[prec].len)
143
-#define pktq_pempty(pq, prec) ((pq)->q[prec].len == 0)
144
-#define pktq_ppeek(pq, prec) ((pq)->q[prec].head)
145
-#define pktq_ppeek_tail(pq, prec) ((pq)->q[prec].tail)
147
+/** filter function return values */
148
+typedef enum {
149
+ PKT_FILTER_NOACTION = 0, /**< restore the pkt to its position in the queue */
150
+ PKT_FILTER_DELETE = 1, /**< delete the pkt */
151
+ PKT_FILTER_REMOVE = 2, /**< do not restore the pkt to the queue,
152
+ * filter fn has taken ownership of the pkt
153
+ */
154
+} pktq_filter_result_t;
155
+
156
+/**
157
+ * Caller supplied filter function to pktq_pfilter(), pktq_filter().
158
+ * Function filter(ctx, pkt) is called with its ctx pointer on each pkt in the
159
+ * pktq. When the filter function is called, the supplied pkt will have been
160
+ * unlinked from the pktq. The filter function returns a pktq_filter_result_t
161
+ * result specifying the action pktq_filter()/pktq_pfilter() should take for
162
+ * the pkt.
163
+ * Here are the actions taken by pktq_filter/pfilter() based on the supplied
164
+ * filter function's return value:
165
+ *
166
+ * PKT_FILTER_NOACTION - The filter will re-link the pkt at its
167
+ * previous location.
168
+ *
169
+ * PKT_FILTER_DELETE - The filter will not relink the pkt and will
170
+ * call the user supplied defer_free_pkt fn on the packet.
171
+ *
172
+ * PKT_FILTER_REMOVE - The filter will not relink the pkt. The supplied
173
+ * filter fn took ownership (or deleted) the pkt.
174
+ *
175
+ * WARNING: pkts inserted by the user (in pkt_filter and/or flush callbacks
176
+ * and chains) in the prec queue will not be seen by the filter, and the prec
177
+ * queue will be temporarily be removed from the queue hence there're side
178
+ * effects including pktq_n_pkts_tot() on the queue won't reflect the correct number
179
+ * of packets in the queue.
180
+ */
181
+
182
+typedef pktq_filter_result_t (*pktq_filter_t)(void* ctx, void* pkt);
183
+
184
+/**
185
+ * The defer_free_pkt callback is invoked when the the pktq_filter callback
186
+ * returns PKT_FILTER_DELETE decision, which allows the user to deposite
187
+ * the packet appropriately based on the situation (free the packet or
188
+ * save it in a temporary queue etc.).
189
+ */
190
+typedef void (*defer_free_pkt_fn_t)(void *ctx, void *pkt);
191
+
192
+/**
193
+ * The flush_free_pkt callback is invoked when all packets in the pktq
194
+ * are processed.
195
+ */
196
+typedef void (*flush_free_pkt_fn_t)(void *ctx);
197
+
198
+#if defined(WLAMPDU_MAC) && defined(PROP_TXSTATUS)
199
+/* this callback will be invoked when in low_txq_scb flush()
200
+ * two back-to-back pkts has same epoch value.
201
+ */
202
+typedef void (*flip_epoch_t)(void *ctx, void *pkt, uint8 *flipEpoch, uint8 *lastEpoch);
203
+#endif /* defined(WLAMPDU_MAC) && defined(PROP_TXSTATUS) */
204
+
205
+/** filter a pktq, using the caller supplied filter/deposition/flush functions */
206
+extern void pktq_filter(struct pktq *pq, pktq_filter_t fn, void* arg,
207
+ defer_free_pkt_fn_t defer, void *defer_ctx, flush_free_pkt_fn_t flush, void *flush_ctx);
208
+/** filter a particular precedence in pktq, using the caller supplied filter function */
209
+extern void pktq_pfilter(struct pktq *pq, int prec, pktq_filter_t fn, void* arg,
210
+ defer_free_pkt_fn_t defer, void *defer_ctx, flush_free_pkt_fn_t flush, void *flush_ctx);
211
+/** filter a simple non-precedence in spktq, using the caller supplied filter function */
212
+extern void spktq_filter(struct spktq *spq, pktq_filter_t fltr, void* fltr_ctx,
213
+ defer_free_pkt_fn_t defer, void *defer_ctx, flush_free_pkt_fn_t flush, void *flush_ctx);
214
+
215
+/* operations on a specific precedence in packet queue */
216
+#define pktqprec_max_pkts(pq, prec) ((pq)->q[prec].max_pkts)
217
+#define pktqprec_n_pkts(pq, prec) ((pq)->q[prec].n_pkts)
218
+#define pktqprec_empty(pq, prec) ((pq)->q[prec].n_pkts == 0)
219
+#define pktqprec_peek(pq, prec) ((pq)->q[prec].head)
220
+#define pktqprec_peek_tail(pq, prec) ((pq)->q[prec].tail)
221
+#define spktq_peek_tail(pq) ((pq)->q.tail)
146222 #ifdef HND_PKTQ_THREAD_SAFE
147
-extern int pktq_pavail(struct pktq *pq, int prec);
148
-extern bool pktq_pfull(struct pktq *pq, int prec);
223
+extern int pktqprec_avail_pkts(struct pktq *pq, int prec);
224
+extern bool pktqprec_full(struct pktq *pq, int prec);
149225 #else
150
-#define pktq_pavail(pq, prec) ((pq)->q[prec].max - (pq)->q[prec].len)
151
-#define pktq_pfull(pq, prec) ((pq)->q[prec].len >= (pq)->q[prec].max)
226
+#define pktqprec_avail_pkts(pq, prec) ((pq)->q[prec].max_pkts - (pq)->q[prec].n_pkts)
227
+#define pktqprec_full(pq, prec) ((pq)->q[prec].n_pkts >= (pq)->q[prec].max_pkts)
152228 #endif /* HND_PKTQ_THREAD_SAFE */
153229
154230 extern void pktq_append(struct pktq *pq, int prec, struct spktq *list);
231
+extern void spktq_append(struct spktq *spq, struct spktq *list);
155232 extern void pktq_prepend(struct pktq *pq, int prec, struct spktq *list);
156
-
233
+extern void spktq_prepend(struct spktq *spq, struct spktq *list);
157234 extern void *pktq_penq(struct pktq *pq, int prec, void *p);
158235 extern void *pktq_penq_head(struct pktq *pq, int prec, void *p);
159236 extern void *pktq_pdeq(struct pktq *pq, int prec);
160237 extern void *pktq_pdeq_prev(struct pktq *pq, int prec, void *prev_p);
161238 extern void *pktq_pdeq_with_fn(struct pktq *pq, int prec, ifpkt_cb_t fn, int arg);
162239 extern void *pktq_pdeq_tail(struct pktq *pq, int prec);
163
-/* Empty the queue at particular precedence level */
164
-extern void pktq_pflush(osl_t *osh, struct pktq *pq, int prec, bool dir,
165
- ifpkt_cb_t fn, int arg);
166
-/* Remove a specified packet from its queue */
240
+/** Remove a specified packet from its queue */
167241 extern bool pktq_pdel(struct pktq *pq, void *p, int prec);
242
+
243
+/* For single precedence queues */
244
+extern void *spktq_enq(struct spktq *spq, void *p);
245
+extern void *spktq_enq_head(struct spktq *spq, void *p);
246
+extern void *spktq_deq(struct spktq *spq);
247
+extern void *spktq_deq_tail(struct spktq *spq);
168248
169249 /* operations on a set of precedences in packet queue */
170250
....@@ -174,42 +254,74 @@
174254
175255 /* operations on packet queue as a whole */
176256
177
-#define pktq_len(pq) ((int)(pq)->len)
178
-#define pktq_max(pq) ((int)(pq)->max)
179
-#define pktq_empty(pq) ((pq)->len == 0)
257
+#define pktq_n_pkts_tot(pq) ((int)(pq)->n_pkts_tot)
258
+#define pktq_max(pq) ((int)(pq)->max_pkts)
259
+#define pktq_empty(pq) ((pq)->n_pkts_tot == 0)
260
+#define spktq_n_pkts(spq) ((int)(spq)->q.n_pkts)
261
+#define spktq_empty(spq) ((spq)->q.n_pkts == 0)
262
+
263
+#define spktq_max(spq) ((int)(spq)->q.max_pkts)
264
+#define spktq_empty(spq) ((spq)->q.n_pkts == 0)
180265 #ifdef HND_PKTQ_THREAD_SAFE
181266 extern int pktq_avail(struct pktq *pq);
182267 extern bool pktq_full(struct pktq *pq);
268
+extern int spktq_avail(struct spktq *spq);
269
+extern bool spktq_full(struct spktq *spq);
183270 #else
184
-#define pktq_avail(pq) ((int)((pq)->max - (pq)->len))
185
-#define pktq_full(pq) ((pq)->len >= (pq)->max)
271
+#define pktq_avail(pq) ((int)((pq)->max_pkts - (pq)->n_pkts_tot))
272
+#define pktq_full(pq) ((pq)->n_pkts_tot >= (pq)->max_pkts)
273
+#define spktq_avail(spq) ((int)((spq)->q.max_pkts - (spq)->q.n_pkts))
274
+#define spktq_full(spq) ((spq)->q.n_pkts >= (spq)->q.max_pkts)
186275 #endif /* HND_PKTQ_THREAD_SAFE */
187276
188277 /* operations for single precedence queues */
189
-#define pktenq(pq, p) pktq_penq(((struct pktq *)(void *)pq), 0, (p))
190
-#define pktenq_head(pq, p) pktq_penq_head(((struct pktq *)(void *)pq), 0, (p))
191
-#define pktdeq(pq) pktq_pdeq(((struct pktq *)(void *)pq), 0)
192
-#define pktdeq_tail(pq) pktq_pdeq_tail(((struct pktq *)(void *)pq), 0)
193
-#define pktqflush(osh, pq) pktq_flush(osh, ((struct pktq *)(void *)pq), TRUE, NULL, 0)
194
-#define pktqinit(pq, len) pktq_init(((struct pktq *)(void *)pq), 1, len)
195
-#define pktqdeinit(pq) pktq_deinit((struct pktq *)(void *)pq)
196
-#define pktqavail(pq) pktq_avail((struct pktq *)(void *)pq)
197
-#define pktqfull(pq) pktq_full((struct pktq *)(void *)pq)
278
+#define pktenq(pq, p) pktq_penq((pq), 0, (p))
279
+#define pktenq_head(pq, p) pktq_penq_head((pq), 0, (p))
280
+#define pktdeq(pq) pktq_pdeq((pq), 0)
281
+#define pktdeq_tail(pq) pktq_pdeq_tail((pq), 0)
282
+#define pktqflush(osh, pq, dir) pktq_pflush(osh, (pq), 0, (dir))
283
+#define pktqinit(pq, max_pkts) pktq_init((pq), 1, (max_pkts))
284
+#define pktqdeinit(pq) pktq_deinit((pq))
285
+#define pktqavail(pq) pktq_avail((pq))
286
+#define pktqfull(pq) pktq_full((pq))
287
+#define pktqfilter(pq, fltr, fltr_ctx, defer, defer_ctx, flush, flush_ctx) \
288
+ pktq_pfilter((pq), 0, (fltr), (fltr_ctx), (defer), (defer_ctx), (flush), (flush_ctx))
198289
199
-extern bool pktq_init(struct pktq *pq, int num_prec, int max_len);
290
+/* operations for simple non-precedence queues */
291
+#define spktenq(spq, p) spktq_enq((spq), (p))
292
+#define spktenq_head(spq, p) spktq_enq_head((spq), (p))
293
+#define spktdeq(spq) spktq_deq((spq))
294
+#define spktdeq_tail(spq) spktq_deq_tail((spq))
295
+#define spktqflush(osh, spq, dir) spktq_flush((osh), (spq), (dir))
296
+#define spktqinit(spq, max_pkts) spktq_init((spq), (max_pkts))
297
+#define spktqdeinit(spq) spktq_deinit((spq))
298
+#define spktqavail(spq) spktq_avail((spq))
299
+#define spktqfull(spq) spktq_full((spq))
300
+
301
+#define spktqfilter(spq, fltr, fltr_ctx, defer, defer_ctx, flush, flush_ctx) \
302
+ spktq_filter((spq), (fltr), (fltr_ctx), (defer), (defer_ctx), (flush), (flush_ctx))
303
+extern bool pktq_init(struct pktq *pq, int num_prec, int max_pkts);
200304 extern bool pktq_deinit(struct pktq *pq);
305
+extern bool spktq_init(struct spktq *spq, int max_pkts);
306
+extern bool spktq_deinit(struct spktq *spq);
201307
202
-extern void pktq_set_max_plen(struct pktq *pq, int prec, int max_len);
308
+extern void pktq_set_max_plen(struct pktq *pq, int prec, int max_pkts);
203309
204310 /* prec_out may be NULL if caller is not interested in return value */
205311 extern void *pktq_deq(struct pktq *pq, int *prec_out);
206312 extern void *pktq_deq_tail(struct pktq *pq, int *prec_out);
207313 extern void *pktq_peek(struct pktq *pq, int *prec_out);
314
+extern void *spktq_peek(struct spktq *spq);
208315 extern void *pktq_peek_tail(struct pktq *pq, int *prec_out);
209
-extern void pktq_flush(osl_t *osh, struct pktq *pq, bool dir, ifpkt_cb_t fn, int arg);
316
+
317
+/** flush pktq */
318
+extern void pktq_flush(osl_t *osh, struct pktq *pq, bool dir);
319
+extern void spktq_flush(osl_t *osh, struct spktq *spq, bool dir);
320
+/** Empty the queue at particular precedence level */
321
+extern void pktq_pflush(osl_t *osh, struct pktq *pq, int prec, bool dir);
210322
211323 #ifdef __cplusplus
212
- }
213
-#endif
324
+}
325
+#endif // endif
214326
215327 #endif /* _hnd_pktq_h_ */