2 * HND generic pktq operation primitives
4 * Copyright (C) 1999-2019, Broadcom.
6 * Unless you and Broadcom execute a separate written software license
7 * agreement governing use of this software, this software is licensed to you
8 * under the terms of the GNU General Public License version 2 (the "GPL"),
9 * available at http://www.broadcom.com/licenses/GPLv2.php, with the
10 * following added to such license:
12 * As a special exception, the copyright holders of this software give you
13 * permission to link this software with independent modules, and to copy and
14 * distribute the resulting executable under terms of your choice, provided that
15 * you also meet, for each linked independent module, the terms and conditions of
16 * the license of that module. An independent module is a module which is not
17 * derived from this software. The special exception does not apply to any
18 * modifications of the software.
20 * Notwithstanding the above, under no circumstances may you combine this
21 * software in any way with any other Broadcom software provided under a license
22 * other than the GPL, without Broadcom's express prior written consent.
25 * <<Broadcom-WL-IPTag/Open:>>
27 * $Id: hnd_pktq.c 698847 2017-05-11 00:10:48Z $
36 /* mutex macros for thread safe */
37 #ifdef HND_PKTQ_THREAD_SAFE
38 #define HND_PKTQ_MUTEX_CREATE(name, mutex) osl_ext_mutex_create(name, mutex)
39 #define HND_PKTQ_MUTEX_DELETE(mutex) osl_ext_mutex_delete(mutex)
40 #define HND_PKTQ_MUTEX_ACQUIRE(mutex, msec) osl_ext_mutex_acquire(mutex, msec)
41 #define HND_PKTQ_MUTEX_RELEASE(mutex) osl_ext_mutex_release(mutex)
43 #define HND_PKTQ_MUTEX_CREATE(name, mutex) OSL_EXT_SUCCESS
44 #define HND_PKTQ_MUTEX_DELETE(mutex) OSL_EXT_SUCCESS
45 #define HND_PKTQ_MUTEX_ACQUIRE(mutex, msec) OSL_EXT_SUCCESS
46 #define HND_PKTQ_MUTEX_RELEASE(mutex) OSL_EXT_SUCCESS
47 #endif /* HND_PKTQ_THREAD_SAFE */
49 /* status during txfifo sync */
50 #if defined(WLAMPDU_MAC) && defined(PROP_TXSTATUS)
51 #define TXQ_PKT_DEL 0x01
52 #define HEAD_PKT_FLUSHED 0xFF
53 #endif /* defined(WLAMPDU_MAC) && defined(PROP_TXSTATUS) */
55 * osl multiple-precedence packet queue
56 * hi_prec is always >= the number of the highest non-empty precedence
59 pktq_penq(struct pktq
*pq
, int prec
, void *p
)
63 /* protect shared resource */
64 if (HND_PKTQ_MUTEX_ACQUIRE(&pq
->mutex
, OSL_EXT_TIME_FOREVER
) != OSL_EXT_SUCCESS
)
67 ASSERT(prec
>= 0 && prec
< pq
->num_prec
);
68 ASSERT(PKTLINK(p
) == NULL
); /* queueing chains not allowed */
70 ASSERT(!pktq_full(pq
));
71 ASSERT(!pktqprec_full(pq
, prec
));
76 PKTSETLINK(q
->tail
, p
);
85 if (pq
->hi_prec
< prec
)
86 pq
->hi_prec
= (uint8
)prec
;
88 /* protect shared resource */
89 if (HND_PKTQ_MUTEX_RELEASE(&pq
->mutex
) != OSL_EXT_SUCCESS
)
96 * osl simple, non-priority packet queue
99 spktq_enq(struct spktq
*spq
, void *p
)
103 /* protect shared resource */
104 if (HND_PKTQ_MUTEX_ACQUIRE(&spq
->mutex
, OSL_EXT_TIME_FOREVER
) != OSL_EXT_SUCCESS
)
107 ASSERT(!spktq_full(spq
));
114 PKTSETLINK(q
->tail
, p
);
121 /* protect shared resource */
122 if (HND_PKTQ_MUTEX_RELEASE(&spq
->mutex
) != OSL_EXT_SUCCESS
)
129 pktq_penq_head(struct pktq
*pq
, int prec
, void *p
)
133 /* protect shared resource */
134 if (HND_PKTQ_MUTEX_ACQUIRE(&pq
->mutex
, OSL_EXT_TIME_FOREVER
) != OSL_EXT_SUCCESS
)
137 ASSERT(prec
>= 0 && prec
< pq
->num_prec
);
138 ASSERT(PKTLINK(p
) == NULL
); /* queueing chains not allowed */
140 ASSERT(!pktq_full(pq
));
141 ASSERT(!pktqprec_full(pq
, prec
));
148 PKTSETLINK(p
, q
->head
);
154 if (pq
->hi_prec
< prec
)
155 pq
->hi_prec
= (uint8
)prec
;
157 /* protect shared resource */
158 if (HND_PKTQ_MUTEX_RELEASE(&pq
->mutex
) != OSL_EXT_SUCCESS
)
165 spktq_enq_head(struct spktq
*spq
, void *p
)
169 /* protect shared resource */
170 if (HND_PKTQ_MUTEX_ACQUIRE(&spq
->mutex
, OSL_EXT_TIME_FOREVER
) != OSL_EXT_SUCCESS
)
173 ASSERT(!spktq_full(spq
));
182 PKTSETLINK(p
, q
->head
);
186 /* protect shared resource */
187 if (HND_PKTQ_MUTEX_RELEASE(&spq
->mutex
) != OSL_EXT_SUCCESS
)
194 pktq_pdeq(struct pktq
*pq
, int prec
)
199 /* protect shared resource */
200 if (HND_PKTQ_MUTEX_ACQUIRE(&pq
->mutex
, OSL_EXT_TIME_FOREVER
) != OSL_EXT_SUCCESS
)
203 ASSERT(prec
>= 0 && prec
< pq
->num_prec
);
207 if ((p
= q
->head
) == NULL
)
210 if ((q
->head
= PKTLINK(p
)) == NULL
)
224 /* protect shared resource */
225 if (HND_PKTQ_MUTEX_RELEASE(&pq
->mutex
) != OSL_EXT_SUCCESS
)
232 spktq_deq(struct spktq
*spq
)
237 /* protect shared resource */
238 if (HND_PKTQ_MUTEX_ACQUIRE(&spq
->mutex
, OSL_EXT_TIME_FOREVER
) != OSL_EXT_SUCCESS
)
243 if ((p
= q
->head
) == NULL
)
246 if ((q
->head
= PKTLINK(p
)) == NULL
)
258 /* protect shared resource */
259 if (HND_PKTQ_MUTEX_RELEASE(&spq
->mutex
) != OSL_EXT_SUCCESS
)
266 pktq_pdeq_tail(struct pktq
*pq
, int prec
)
271 /* protect shared resource */
272 if (HND_PKTQ_MUTEX_ACQUIRE(&pq
->mutex
, OSL_EXT_TIME_FOREVER
) != OSL_EXT_SUCCESS
)
275 ASSERT(prec
>= 0 && prec
< pq
->num_prec
);
279 if ((p
= q
->head
) == NULL
)
282 for (prev
= NULL
; p
!= q
->tail
; p
= PKTLINK(p
))
286 PKTSETLINK(prev
, NULL
);
299 /* protect shared resource */
300 if (HND_PKTQ_MUTEX_RELEASE(&pq
->mutex
) != OSL_EXT_SUCCESS
)
307 spktq_deq_tail(struct spktq
*spq
)
312 /* protect shared resource */
313 if (HND_PKTQ_MUTEX_ACQUIRE(&spq
->mutex
, OSL_EXT_TIME_FOREVER
) != OSL_EXT_SUCCESS
)
318 if ((p
= q
->head
) == NULL
)
321 for (prev
= NULL
; p
!= q
->tail
; p
= PKTLINK(p
))
325 PKTSETLINK(prev
, NULL
);
336 /* protect shared resource */
337 if (HND_PKTQ_MUTEX_RELEASE(&spq
->mutex
) != OSL_EXT_SUCCESS
)
344 pktq_peek_tail(struct pktq
*pq
, int *prec_out
)
349 /* protect shared resource */
350 if (HND_PKTQ_MUTEX_ACQUIRE(&pq
->mutex
, OSL_EXT_TIME_FOREVER
) != OSL_EXT_SUCCESS
)
353 if (pq
->n_pkts_tot
== 0)
356 for (prec
= 0; prec
< pq
->hi_prec
; prec
++)
357 if (pq
->q
[prec
].head
)
363 p
= pq
->q
[prec
].tail
;
366 /* protect shared resource */
367 if (HND_PKTQ_MUTEX_RELEASE(&pq
->mutex
) != OSL_EXT_SUCCESS
)
374 * Append spktq 'list' to the tail of pktq 'pq'
377 pktq_append(struct pktq
*pq
, int prec
, struct spktq
*list
)
380 struct pktq_prec
*list_q
;
382 /* protect shared resource */
383 if (HND_PKTQ_MUTEX_ACQUIRE(&pq
->mutex
, OSL_EXT_TIME_FOREVER
) != OSL_EXT_SUCCESS
)
388 /* empty list check */
389 if (list_q
->head
== NULL
)
392 ASSERT(prec
>= 0 && prec
< pq
->num_prec
);
393 ASSERT(PKTLINK(list_q
->tail
) == NULL
); /* terminated list */
395 ASSERT(!pktq_full(pq
));
396 ASSERT(!pktqprec_full(pq
, prec
));
401 PKTSETLINK(q
->tail
, list_q
->head
);
403 q
->head
= list_q
->head
;
405 q
->tail
= list_q
->tail
;
406 q
->n_pkts
+= list_q
->n_pkts
;
407 pq
->n_pkts_tot
+= list_q
->n_pkts
;
409 if (pq
->hi_prec
< prec
)
410 pq
->hi_prec
= (uint8
)prec
;
413 list_q
->dequeue_count
+= list_q
->n_pkts
;
421 /* protect shared resource */
422 if (HND_PKTQ_MUTEX_RELEASE(&pq
->mutex
) != OSL_EXT_SUCCESS
)
427 * Append spktq 'list' to the tail of spktq 'spq'
430 spktq_append(struct spktq
*spq
, struct spktq
*list
)
433 struct pktq_prec
*list_q
;
435 /* protect shared resource */
436 if (HND_PKTQ_MUTEX_ACQUIRE(&spq
->mutex
, OSL_EXT_TIME_FOREVER
) != OSL_EXT_SUCCESS
)
441 /* empty list check */
442 if (list_q
->head
== NULL
)
445 ASSERT(PKTLINK(list_q
->tail
) == NULL
); /* terminated list */
447 ASSERT(!spktq_full(spq
));
452 PKTSETLINK(q
->tail
, list_q
->head
);
454 q
->head
= list_q
->head
;
456 q
->tail
= list_q
->tail
;
457 q
->n_pkts
+= list_q
->n_pkts
;
460 list_q
->dequeue_count
+= list_q
->n_pkts
;
468 /* protect shared resource */
469 if (HND_PKTQ_MUTEX_RELEASE(&spq
->mutex
) != OSL_EXT_SUCCESS
)
474 * Prepend spktq 'list' to the head of pktq 'pq'
477 pktq_prepend(struct pktq
*pq
, int prec
, struct spktq
*list
)
480 struct pktq_prec
*list_q
;
482 /* protect shared resource */
483 if (HND_PKTQ_MUTEX_ACQUIRE(&pq
->mutex
, OSL_EXT_TIME_FOREVER
) != OSL_EXT_SUCCESS
)
488 /* empty list check */
489 if (list_q
->head
== NULL
)
492 ASSERT(prec
>= 0 && prec
< pq
->num_prec
);
493 ASSERT(PKTLINK(list_q
->tail
) == NULL
); /* terminated list */
495 ASSERT(!pktq_full(pq
));
496 ASSERT(!pktqprec_full(pq
, prec
));
500 /* set the tail packet of list to point at the former pq head */
501 PKTSETLINK(list_q
->tail
, q
->head
);
502 /* the new q head is the head of list */
503 q
->head
= list_q
->head
;
505 /* If the q tail was non-null, then it stays as is.
506 * If the q tail was null, it is now the tail of list
508 if (q
->tail
== NULL
) {
509 q
->tail
= list_q
->tail
;
512 q
->n_pkts
+= list_q
->n_pkts
;
513 pq
->n_pkts_tot
+= list_q
->n_pkts
;
515 if (pq
->hi_prec
< prec
)
516 pq
->hi_prec
= (uint8
)prec
;
519 list_q
->dequeue_count
+= list_q
->n_pkts
;
527 /* protect shared resource */
528 if (HND_PKTQ_MUTEX_RELEASE(&pq
->mutex
) != OSL_EXT_SUCCESS
)
533 * Prepend spktq 'list' to the head of spktq 'spq'
536 spktq_prepend(struct spktq
*spq
, struct spktq
*list
)
539 struct pktq_prec
*list_q
;
541 /* protect shared resource */
542 if (HND_PKTQ_MUTEX_ACQUIRE(&spq
->mutex
, OSL_EXT_TIME_FOREVER
) != OSL_EXT_SUCCESS
)
547 /* empty list check */
548 if (list_q
->head
== NULL
)
551 ASSERT(PKTLINK(list_q
->tail
) == NULL
); /* terminated list */
553 ASSERT(!spktq_full(spq
));
557 /* set the tail packet of list to point at the former pq head */
558 PKTSETLINK(list_q
->tail
, q
->head
);
559 /* the new q head is the head of list */
560 q
->head
= list_q
->head
;
562 /* If the q tail was non-null, then it stays as is.
563 * If the q tail was null, it is now the tail of list
565 if (q
->tail
== NULL
) {
566 q
->tail
= list_q
->tail
;
569 q
->n_pkts
+= list_q
->n_pkts
;
572 list_q
->dequeue_count
+= list_q
->n_pkts
;
580 /* protect shared resource */
581 if (HND_PKTQ_MUTEX_RELEASE(&spq
->mutex
) != OSL_EXT_SUCCESS
)
586 pktq_pdeq_prev(struct pktq
*pq
, int prec
, void *prev_p
)
591 /* protect shared resource */
592 if (HND_PKTQ_MUTEX_ACQUIRE(&pq
->mutex
, OSL_EXT_TIME_FOREVER
) != OSL_EXT_SUCCESS
)
595 ASSERT(prec
>= 0 && prec
< pq
->num_prec
);
602 if ((p
= PKTLINK(prev_p
)) == NULL
)
612 PKTSETLINK(prev_p
, PKTLINK(p
));
616 /* protect shared resource */
617 if (HND_PKTQ_MUTEX_RELEASE(&pq
->mutex
) != OSL_EXT_SUCCESS
)
624 pktq_pdeq_with_fn(struct pktq
*pq
, int prec
, ifpkt_cb_t fn
, int arg
)
627 void *p
, *prev
= NULL
;
629 /* protect shared resource */
630 if (HND_PKTQ_MUTEX_ACQUIRE(&pq
->mutex
, OSL_EXT_TIME_FOREVER
) != OSL_EXT_SUCCESS
)
633 ASSERT(prec
>= 0 && prec
< pq
->num_prec
);
639 if (fn
== NULL
|| (*fn
)(p
, arg
)) {
650 if ((q
->head
= PKTLINK(p
)) == NULL
) {
654 PKTSETLINK(prev
, PKTLINK(p
));
670 /* protect shared resource */
671 if (HND_PKTQ_MUTEX_RELEASE(&pq
->mutex
) != OSL_EXT_SUCCESS
)
678 pktq_pdel(struct pktq
*pq
, void *pktbuf
, int prec
)
684 /* protect shared resource */
685 if (HND_PKTQ_MUTEX_ACQUIRE(&pq
->mutex
, OSL_EXT_TIME_FOREVER
) != OSL_EXT_SUCCESS
)
688 ASSERT(prec
>= 0 && prec
< pq
->num_prec
);
690 /* Should this just assert pktbuf? */
696 if (q
->head
== pktbuf
) {
697 if ((q
->head
= PKTLINK(pktbuf
)) == NULL
)
700 for (p
= q
->head
; p
&& PKTLINK(p
) != pktbuf
; p
= PKTLINK(p
))
705 PKTSETLINK(p
, PKTLINK(pktbuf
));
706 if (q
->tail
== pktbuf
)
717 PKTSETLINK(pktbuf
, NULL
);
721 /* protect shared resource */
722 if (HND_PKTQ_MUTEX_RELEASE(&pq
->mutex
) != OSL_EXT_SUCCESS
)
729 _pktq_pfilter(struct pktq
*pq
, int prec
, pktq_filter_t fltr
, void* fltr_ctx
,
730 defer_free_pkt_fn_t defer
, void *defer_ctx
)
736 /* protect shared resource */
737 if (HND_PKTQ_MUTEX_ACQUIRE(&pq
->mutex
, OSL_EXT_TIME_FOREVER
) != OSL_EXT_SUCCESS
)
740 /* move the prec queue aside to a work queue */
750 q
->dequeue_count
+= wq
.n_pkts
;
753 pq
->n_pkts_tot
-= wq
.n_pkts
;
755 /* protect shared resource */
756 if (HND_PKTQ_MUTEX_RELEASE(&pq
->mutex
) != OSL_EXT_SUCCESS
)
759 /* start with the head of the work queue */
760 while ((p
= wq
.head
) != NULL
) {
761 /* unlink the current packet from the list */
762 wq
.head
= PKTLINK(p
);
770 /* call the filter function on current packet */
771 ASSERT(fltr
!= NULL
);
772 switch ((*fltr
)(fltr_ctx
, p
)) {
773 case PKT_FILTER_NOACTION
:
774 /* put this packet back */
775 pktq_penq(pq
, prec
, p
);
778 case PKT_FILTER_DELETE
:
779 /* delete this packet */
780 ASSERT(defer
!= NULL
);
781 (*defer
)(defer_ctx
, p
);
784 case PKT_FILTER_REMOVE
:
785 /* pkt already removed from list */
794 ASSERT(wq
.n_pkts
== 0);
798 pktq_pfilter(struct pktq
*pq
, int prec
, pktq_filter_t fltr
, void* fltr_ctx
,
799 defer_free_pkt_fn_t defer
, void *defer_ctx
, flush_free_pkt_fn_t flush
, void *flush_ctx
)
801 _pktq_pfilter(pq
, prec
, fltr
, fltr_ctx
, defer
, defer_ctx
);
803 ASSERT(flush
!= NULL
);
808 pktq_filter(struct pktq
*pq
, pktq_filter_t fltr
, void* fltr_ctx
,
809 defer_free_pkt_fn_t defer
, void *defer_ctx
, flush_free_pkt_fn_t flush
, void *flush_ctx
)
813 /* protect shared resource */
814 if (HND_PKTQ_MUTEX_ACQUIRE(&pq
->mutex
, OSL_EXT_TIME_FOREVER
) != OSL_EXT_SUCCESS
)
817 /* Optimize if pktq n_pkts = 0, just return.
818 * pktq len of 0 means pktq's prec q's are all empty.
820 if (pq
->n_pkts_tot
> 0) {
824 /* protect shared resource */
825 if (HND_PKTQ_MUTEX_RELEASE(&pq
->mutex
) != OSL_EXT_SUCCESS
)
831 PKTQ_PREC_ITER(pq
, prec
) {
832 _pktq_pfilter(pq
, prec
, fltr
, fltr_ctx
, defer
, defer_ctx
);
835 ASSERT(flush
!= NULL
);
841 spktq_filter(struct spktq
*spq
, pktq_filter_t fltr
, void* fltr_ctx
,
842 defer_free_pkt_fn_t defer
, void *defer_ctx
, flush_free_pkt_fn_t flush
, void *flush_ctx
)
848 /* protect shared resource */
849 if (HND_PKTQ_MUTEX_ACQUIRE(&spq
->mutex
, OSL_EXT_TIME_FOREVER
) != OSL_EXT_SUCCESS
)
854 /* Optimize if pktq_prec n_pkts = 0, just return. */
855 if (q
->n_pkts
== 0) {
856 (void)HND_PKTQ_MUTEX_RELEASE(&spq
->mutex
);
867 q
->dequeue_count
+= wq
.n_pkts
;
870 /* protect shared resource */
871 if (HND_PKTQ_MUTEX_RELEASE(&spq
->mutex
) != OSL_EXT_SUCCESS
)
874 /* start with the head of the work queue */
876 while ((p
= wq
.head
) != NULL
) {
877 /* unlink the current packet from the list */
878 wq
.head
= PKTLINK(p
);
886 /* call the filter function on current packet */
887 ASSERT(fltr
!= NULL
);
888 switch ((*fltr
)(fltr_ctx
, p
)) {
889 case PKT_FILTER_NOACTION
:
890 /* put this packet back */
894 case PKT_FILTER_DELETE
:
895 /* delete this packet */
896 ASSERT(defer
!= NULL
);
897 (*defer
)(defer_ctx
, p
);
900 case PKT_FILTER_REMOVE
:
901 /* pkt already removed from list */
910 ASSERT(wq
.n_pkts
== 0);
912 ASSERT(flush
!= NULL
);
917 pktq_init(struct pktq
*pq
, int num_prec
, int max_pkts
)
921 ASSERT(num_prec
> 0 && num_prec
<= PKTQ_MAX_PREC
);
923 /* pq is variable size; only zero out what's requested */
924 bzero(pq
, OFFSETOF(struct pktq
, q
) + (sizeof(struct pktq_prec
) * num_prec
));
926 if (HND_PKTQ_MUTEX_CREATE("pktq", &pq
->mutex
) != OSL_EXT_SUCCESS
)
929 pq
->num_prec
= (uint16
)num_prec
;
931 pq
->max_pkts
= (uint16
)max_pkts
;
933 for (prec
= 0; prec
< num_prec
; prec
++)
934 pq
->q
[prec
].max_pkts
= pq
->max_pkts
;
940 spktq_init(struct spktq
*spq
, int max_pkts
)
942 bzero(spq
, sizeof(struct spktq
));
944 if (HND_PKTQ_MUTEX_CREATE("spktq", &spq
->mutex
) != OSL_EXT_SUCCESS
)
947 spq
->q
.max_pkts
= (uint16
)max_pkts
;
953 pktq_deinit(struct pktq
*pq
)
956 if (HND_PKTQ_MUTEX_DELETE(&pq
->mutex
) != OSL_EXT_SUCCESS
)
963 spktq_deinit(struct spktq
*spq
)
966 if (HND_PKTQ_MUTEX_DELETE(&spq
->mutex
) != OSL_EXT_SUCCESS
)
973 pktq_set_max_plen(struct pktq
*pq
, int prec
, int max_pkts
)
975 ASSERT(prec
>= 0 && prec
< pq
->num_prec
);
977 /* protect shared resource */
978 if (HND_PKTQ_MUTEX_ACQUIRE(&pq
->mutex
, OSL_EXT_TIME_FOREVER
) != OSL_EXT_SUCCESS
)
981 if (prec
< pq
->num_prec
)
982 pq
->q
[prec
].max_pkts
= (uint16
)max_pkts
;
984 /* protect shared resource */
985 if (HND_PKTQ_MUTEX_RELEASE(&pq
->mutex
) != OSL_EXT_SUCCESS
)
990 pktq_deq(struct pktq
*pq
, int *prec_out
)
996 /* protect shared resource */
997 if (HND_PKTQ_MUTEX_ACQUIRE(&pq
->mutex
, OSL_EXT_TIME_FOREVER
) != OSL_EXT_SUCCESS
)
1000 if (pq
->n_pkts_tot
== 0)
1003 while ((prec
= pq
->hi_prec
) > 0 && pq
->q
[prec
].head
== NULL
)
1008 if ((p
= q
->head
) == NULL
)
1011 if ((q
->head
= PKTLINK(p
)) == NULL
)
1025 PKTSETLINK(p
, NULL
);
1028 /* protect shared resource */
1029 if (HND_PKTQ_MUTEX_RELEASE(&pq
->mutex
) != OSL_EXT_SUCCESS
)
1036 pktq_deq_tail(struct pktq
*pq
, int *prec_out
)
1038 struct pktq_prec
*q
;
1039 void *p
= NULL
, *prev
;
1042 /* protect shared resource */
1043 if (HND_PKTQ_MUTEX_ACQUIRE(&pq
->mutex
, OSL_EXT_TIME_FOREVER
) != OSL_EXT_SUCCESS
)
1046 if (pq
->n_pkts_tot
== 0)
1049 for (prec
= 0; prec
< pq
->hi_prec
; prec
++)
1050 if (pq
->q
[prec
].head
)
1055 if ((p
= q
->head
) == NULL
)
1058 for (prev
= NULL
; p
!= q
->tail
; p
= PKTLINK(p
))
1062 PKTSETLINK(prev
, NULL
);
1078 PKTSETLINK(p
, NULL
);
1081 /* protect shared resource */
1082 if (HND_PKTQ_MUTEX_RELEASE(&pq
->mutex
) != OSL_EXT_SUCCESS
)
1089 pktq_peek(struct pktq
*pq
, int *prec_out
)
1094 /* protect shared resource */
1095 if (HND_PKTQ_MUTEX_ACQUIRE(&pq
->mutex
, OSL_EXT_TIME_FOREVER
) != OSL_EXT_SUCCESS
)
1098 if (pq
->n_pkts_tot
== 0)
1101 while ((prec
= pq
->hi_prec
) > 0 && pq
->q
[prec
].head
== NULL
)
1107 p
= pq
->q
[prec
].head
;
1110 /* protect shared resource */
1111 if (HND_PKTQ_MUTEX_RELEASE(&pq
->mutex
) != OSL_EXT_SUCCESS
)
1118 spktq_peek(struct spktq
*spq
)
1122 /* protect shared resource */
1123 if (HND_PKTQ_MUTEX_ACQUIRE(&spq
->mutex
, OSL_EXT_TIME_FOREVER
) != OSL_EXT_SUCCESS
)
1126 if (spq
->q
.n_pkts
== 0)
1132 /* protect shared resource */
1133 if (HND_PKTQ_MUTEX_RELEASE(&spq
->mutex
) != OSL_EXT_SUCCESS
)
1140 pktq_pflush(osl_t
*osh
, struct pktq
*pq
, int prec
, bool dir
)
1144 /* no need for a mutex protection! */
1146 /* start with the head of the list */
1147 while ((p
= pktq_pdeq(pq
, prec
)) != NULL
) {
1149 /* delete this packet */
1150 PKTFREE(osh
, p
, dir
);
1155 spktq_flush(osl_t
*osh
, struct spktq
*spq
, bool dir
)
1159 /* no need for a mutex protection! */
1161 /* start with the head of the list */
1162 while ((p
= spktq_deq(spq
)) != NULL
) {
1164 /* delete this packet */
1165 PKTFREE(osh
, p
, dir
);
1170 pktq_flush(osl_t
*osh
, struct pktq
*pq
, bool dir
)
1174 /* protect shared resource */
1175 if (HND_PKTQ_MUTEX_ACQUIRE(&pq
->mutex
, OSL_EXT_TIME_FOREVER
) != OSL_EXT_SUCCESS
)
1178 /* Optimize flush, if pktq n_pkts_tot = 0, just return.
1179 * pktq len of 0 means pktq's prec q's are all empty.
1181 if (pq
->n_pkts_tot
> 0) {
1185 /* protect shared resource */
1186 if (HND_PKTQ_MUTEX_RELEASE(&pq
->mutex
) != OSL_EXT_SUCCESS
)
1192 PKTQ_PREC_ITER(pq
, prec
) {
1193 pktq_pflush(osh
, pq
, prec
, dir
);
1198 /* Return sum of lengths of a specific set of precedences */
1200 pktq_mlen(struct pktq
*pq
, uint prec_bmp
)
1204 /* protect shared resource */
1205 if (HND_PKTQ_MUTEX_ACQUIRE(&pq
->mutex
, OSL_EXT_TIME_FOREVER
) != OSL_EXT_SUCCESS
)
1210 for (prec
= 0; prec
<= pq
->hi_prec
; prec
++)
1211 if (prec_bmp
& (1 << prec
))
1212 len
+= pq
->q
[prec
].n_pkts
;
1214 /* protect shared resource */
1215 if (HND_PKTQ_MUTEX_RELEASE(&pq
->mutex
) != OSL_EXT_SUCCESS
)
1221 /* Priority peek from a specific set of precedences */
1223 pktq_mpeek(struct pktq
*pq
, uint prec_bmp
, int *prec_out
)
1225 struct pktq_prec
*q
;
1229 /* protect shared resource */
1230 if (HND_PKTQ_MUTEX_ACQUIRE(&pq
->mutex
, OSL_EXT_TIME_FOREVER
) != OSL_EXT_SUCCESS
)
1233 if (pq
->n_pkts_tot
== 0)
1236 while ((prec
= pq
->hi_prec
) > 0 && pq
->q
[prec
].head
== NULL
)
1239 while ((prec_bmp
& (1 << prec
)) == 0 || pq
->q
[prec
].head
== NULL
)
1245 if ((p
= q
->head
) == NULL
)
1252 /* protect shared resource */
1253 if (HND_PKTQ_MUTEX_RELEASE(&pq
->mutex
) != OSL_EXT_SUCCESS
)
1258 /* Priority dequeue from a specific set of precedences */
1260 pktq_mdeq(struct pktq
*pq
, uint prec_bmp
, int *prec_out
)
1262 struct pktq_prec
*q
;
1266 /* protect shared resource */
1267 if (HND_PKTQ_MUTEX_ACQUIRE(&pq
->mutex
, OSL_EXT_TIME_FOREVER
) != OSL_EXT_SUCCESS
)
1270 if (pq
->n_pkts_tot
== 0)
1273 while ((prec
= pq
->hi_prec
) > 0 && pq
->q
[prec
].head
== NULL
)
1276 while ((pq
->q
[prec
].head
== NULL
) || ((prec_bmp
& (1 << prec
)) == 0))
1282 if ((p
= q
->head
) == NULL
)
1285 if ((q
->head
= PKTLINK(p
)) == NULL
)
1290 // terence 20150308: fix for non-null pointer of skb->prev sent from ndo_start_xmit
1291 if (q
->n_pkts
== 0) {
1305 PKTSETLINK(p
, NULL
);
1308 /* protect shared resource */
1309 if (HND_PKTQ_MUTEX_RELEASE(&pq
->mutex
) != OSL_EXT_SUCCESS
)
1315 #ifdef HND_PKTQ_THREAD_SAFE
1317 pktqprec_avail_pkts(struct pktq
*pq
, int prec
)
1321 /* protect shared resource */
1322 if (HND_PKTQ_MUTEX_ACQUIRE(&pq
->mutex
, OSL_EXT_TIME_FOREVER
) != OSL_EXT_SUCCESS
)
1325 ASSERT(prec
>= 0 && prec
< pq
->num_prec
);
1327 ret
= pq
->q
[prec
].max_pkts
- pq
->q
[prec
].n_pkts
;
1329 /* protect shared resource */
1330 if (HND_PKTQ_MUTEX_RELEASE(&pq
->mutex
) != OSL_EXT_SUCCESS
)
1337 pktqprec_full(struct pktq
*pq
, int prec
)
1341 /* protect shared resource */
1342 if (HND_PKTQ_MUTEX_ACQUIRE(&pq
->mutex
, OSL_EXT_TIME_FOREVER
) != OSL_EXT_SUCCESS
)
1345 ASSERT(prec
>= 0 && prec
< pq
->num_prec
);
1347 ret
= pq
->q
[prec
].n_pkts
>= pq
->q
[prec
].max_pkts
;
1349 /* protect shared resource */
1350 if (HND_PKTQ_MUTEX_RELEASE(&pq
->mutex
) != OSL_EXT_SUCCESS
)
1357 pktq_avail(struct pktq
*pq
)
1361 /* protect shared resource */
1362 if (HND_PKTQ_MUTEX_ACQUIRE(&pq
->mutex
, OSL_EXT_TIME_FOREVER
) != OSL_EXT_SUCCESS
)
1365 ret
= pq
->max_pkts
- pq
->n_pkts_tot
;
1367 /* protect shared resource */
1368 if (HND_PKTQ_MUTEX_RELEASE(&pq
->mutex
) != OSL_EXT_SUCCESS
)
1375 spktq_avail(struct spktq
*spq
)
1379 /* protect shared resource */
1380 if (HND_PKTQ_MUTEX_ACQUIRE(&spq
->mutex
, OSL_EXT_TIME_FOREVER
) != OSL_EXT_SUCCESS
)
1383 ret
= spq
->q
.max_pkts
- spq
->q
.n_pkts
;
1385 /* protect shared resource */
1386 if (HND_PKTQ_MUTEX_RELEASE(&spq
->mutex
) != OSL_EXT_SUCCESS
)
1393 pktq_full(struct pktq
*pq
)
1397 /* protect shared resource */
1398 if (HND_PKTQ_MUTEX_ACQUIRE(&pq
->mutex
, OSL_EXT_TIME_FOREVER
) != OSL_EXT_SUCCESS
)
1401 ret
= pq
->n_pkts_tot
>= pq
->max_pkts
;
1403 /* protect shared resource */
1404 if (HND_PKTQ_MUTEX_RELEASE(&pq
->mutex
) != OSL_EXT_SUCCESS
)
1411 spktq_full(struct spktq
*spq
)
1415 /* protect shared resource */
1416 if (HND_PKTQ_MUTEX_ACQUIRE(&spq
->mutex
, OSL_EXT_TIME_FOREVER
) != OSL_EXT_SUCCESS
)
1419 ret
= spq
->q
.n_pkts
>= spq
->q
.max_pkts
;
1421 /* protect shared resource */
1422 if (HND_PKTQ_MUTEX_RELEASE(&spq
->mutex
) != OSL_EXT_SUCCESS
)
1428 #endif /* HND_PKTQ_THREAD_SAFE */