1139823Simp/*-
221259Swollman * Copyright (c) 1982, 1986, 1989, 1993
321259Swollman *	The Regents of the University of California.  All rights reserved.
421259Swollman *
521259Swollman * Redistribution and use in source and binary forms, with or without
621259Swollman * modification, are permitted provided that the following conditions
721259Swollman * are met:
821259Swollman * 1. Redistributions of source code must retain the above copyright
921259Swollman *    notice, this list of conditions and the following disclaimer.
1021259Swollman * 2. Redistributions in binary form must reproduce the above copyright
1121259Swollman *    notice, this list of conditions and the following disclaimer in the
1221259Swollman *    documentation and/or other materials provided with the distribution.
1321259Swollman * 4. Neither the name of the University nor the names of its contributors
1421259Swollman *    may be used to endorse or promote products derived from this software
1521259Swollman *    without specific prior written permission.
1621259Swollman *
1721259Swollman * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
1821259Swollman * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1921259Swollman * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2021259Swollman * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2121259Swollman * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2221259Swollman * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2321259Swollman * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2421259Swollman * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2521259Swollman * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2621259Swollman * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2721259Swollman * SUCH DAMAGE.
2821259Swollman *
2921259Swollman *	From: @(#)if.h	8.1 (Berkeley) 6/10/93
3050477Speter * $FreeBSD$
3121259Swollman */
3221259Swollman
33257351Sandre#ifndef	_NET_IFQ_H_
34257351Sandre#define	_NET_IFQ_H_
3521259Swollman
3669224Sjlemon#ifdef _KERNEL
37257244Sglebius#include <sys/mbuf.h>		/* ifqueue only? */
38186207Skmacy#include <sys/buf_ring.h>
39195699Srwatson#include <net/vnet.h>
4069224Sjlemon#endif /* _KERNEL */
4174914Sjhb#include <sys/lock.h>		/* XXX */
42257244Sglebius#include <sys/mutex.h>		/* struct ifqueue */
4369152Sjlemon
44272244Sglebius/*
45272244Sglebius * Couple of ugly extra definitions that are required since ifq.h
46272244Sglebius * is splitted from if_var.h.
47272244Sglebius */
48121816Sbrooks#define	IF_DUNIT_NONE	-1
49121816Sbrooks
50281613Sglebius#include <net/altq/if_altq.h>
51130416Smlaier
5221259Swollman/*
5321259Swollman * Structure defining a queue for a network interface.
5421259Swollman */
5521259Swollmanstruct	ifqueue {
5621259Swollman	struct	mbuf *ifq_head;
5721259Swollman	struct	mbuf *ifq_tail;
5821259Swollman	int	ifq_len;
5921259Swollman	int	ifq_maxlen;
6069152Sjlemon	struct	mtx ifq_mtx;
6121259Swollman};
6221259Swollman
63257351Sandre#ifdef _KERNEL
6421259Swollman/*
6521259Swollman * Output queues (ifp->if_snd) and slow device input queues (*ifp->if_slowq)
6621259Swollman * are queues of messages stored on ifqueue structures
6721259Swollman * (defined above).  Entries are added to and deleted from these structures
68241686Sandre * by these macros.
6921259Swollman */
7072200Sbmilekic#define IF_LOCK(ifq)		mtx_lock(&(ifq)->ifq_mtx)
7172200Sbmilekic#define IF_UNLOCK(ifq)		mtx_unlock(&(ifq)->ifq_mtx)
72130416Smlaier#define	IF_LOCK_ASSERT(ifq)	mtx_assert(&(ifq)->ifq_mtx, MA_OWNED)
7369152Sjlemon#define	_IF_QFULL(ifq)		((ifq)->ifq_len >= (ifq)->ifq_maxlen)
7469152Sjlemon#define	_IF_QLEN(ifq)		((ifq)->ifq_len)
7521259Swollman
7669152Sjlemon#define	_IF_ENQUEUE(ifq, m) do { 				\
7769152Sjlemon	(m)->m_nextpkt = NULL;					\
7869152Sjlemon	if ((ifq)->ifq_tail == NULL) 				\
7969152Sjlemon		(ifq)->ifq_head = m; 				\
8069152Sjlemon	else 							\
8169152Sjlemon		(ifq)->ifq_tail->m_nextpkt = m; 		\
8269152Sjlemon	(ifq)->ifq_tail = m; 					\
8369152Sjlemon	(ifq)->ifq_len++; 					\
8469152Sjlemon} while (0)
8569152Sjlemon
8669152Sjlemon#define IF_ENQUEUE(ifq, m) do {					\
8769152Sjlemon	IF_LOCK(ifq); 						\
8869152Sjlemon	_IF_ENQUEUE(ifq, m); 					\
8969152Sjlemon	IF_UNLOCK(ifq); 					\
9069152Sjlemon} while (0)
9169152Sjlemon
9269152Sjlemon#define	_IF_PREPEND(ifq, m) do {				\
9369152Sjlemon	(m)->m_nextpkt = (ifq)->ifq_head; 			\
9469152Sjlemon	if ((ifq)->ifq_tail == NULL) 				\
9569152Sjlemon		(ifq)->ifq_tail = (m); 				\
9669152Sjlemon	(ifq)->ifq_head = (m); 					\
9769152Sjlemon	(ifq)->ifq_len++; 					\
9869152Sjlemon} while (0)
9969152Sjlemon
10069152Sjlemon#define IF_PREPEND(ifq, m) do {		 			\
10169152Sjlemon	IF_LOCK(ifq); 						\
10269152Sjlemon	_IF_PREPEND(ifq, m); 					\
10369152Sjlemon	IF_UNLOCK(ifq); 					\
10469152Sjlemon} while (0)
10569152Sjlemon
10669152Sjlemon#define	_IF_DEQUEUE(ifq, m) do { 				\
10769152Sjlemon	(m) = (ifq)->ifq_head; 					\
10869152Sjlemon	if (m) { 						\
109136950Sjmg		if (((ifq)->ifq_head = (m)->m_nextpkt) == NULL)	\
11069152Sjlemon			(ifq)->ifq_tail = NULL; 		\
11169152Sjlemon		(m)->m_nextpkt = NULL; 				\
11269152Sjlemon		(ifq)->ifq_len--; 				\
11369152Sjlemon	} 							\
11469152Sjlemon} while (0)
11569152Sjlemon
11669152Sjlemon#define IF_DEQUEUE(ifq, m) do { 				\
11769152Sjlemon	IF_LOCK(ifq); 						\
11869152Sjlemon	_IF_DEQUEUE(ifq, m); 					\
11969152Sjlemon	IF_UNLOCK(ifq); 					\
12069152Sjlemon} while (0)
12169152Sjlemon
122226830Sglebius#define	_IF_DEQUEUE_ALL(ifq, m) do {				\
123226830Sglebius	(m) = (ifq)->ifq_head;					\
124226830Sglebius	(ifq)->ifq_head = (ifq)->ifq_tail = NULL;		\
125226830Sglebius	(ifq)->ifq_len = 0;					\
126226830Sglebius} while (0)
127226830Sglebius
128226830Sglebius#define	IF_DEQUEUE_ALL(ifq, m) do {				\
129226830Sglebius	IF_LOCK(ifq); 						\
130226830Sglebius	_IF_DEQUEUE_ALL(ifq, m);				\
131226830Sglebius	IF_UNLOCK(ifq); 					\
132226830Sglebius} while (0)
133226830Sglebius
134130416Smlaier#define	_IF_POLL(ifq, m)	((m) = (ifq)->ifq_head)
135130416Smlaier#define	IF_POLL(ifq, m)		_IF_POLL(ifq, m)
136130416Smlaier
137130416Smlaier#define _IF_DRAIN(ifq) do { 					\
13869152Sjlemon	struct mbuf *m; 					\
13969152Sjlemon	for (;;) { 						\
14069152Sjlemon		_IF_DEQUEUE(ifq, m); 				\
14169152Sjlemon		if (m == NULL) 					\
14269152Sjlemon			break; 					\
14369152Sjlemon		m_freem(m); 					\
14469152Sjlemon	} 							\
14569152Sjlemon} while (0)
14669152Sjlemon
147130416Smlaier#define IF_DRAIN(ifq) do {					\
148130416Smlaier	IF_LOCK(ifq);						\
149130416Smlaier	_IF_DRAIN(ifq);						\
150130416Smlaier	IF_UNLOCK(ifq);						\
151130416Smlaier} while(0)
152130416Smlaier
153137065Srwatsonint	if_handoff(struct ifqueue *ifq, struct mbuf *m, struct ifnet *ifp,
154137065Srwatson	    int adjust);
155130416Smlaier#define	IF_HANDOFF(ifq, m, ifp)			\
156130416Smlaier	if_handoff((struct ifqueue *)ifq, m, ifp, 0)
157130416Smlaier#define	IF_HANDOFF_ADJ(ifq, m, ifp, adj)	\
158130416Smlaier	if_handoff((struct ifqueue *)ifq, m, ifp, adj)
15921259Swollman
160132712Srwatsonvoid	if_start(struct ifnet *);
161132712Srwatson
162130416Smlaier#define	IFQ_ENQUEUE(ifq, m, err)					\
163130416Smlaierdo {									\
164130416Smlaier	IF_LOCK(ifq);							\
165130416Smlaier	if (ALTQ_IS_ENABLED(ifq))					\
166130416Smlaier		ALTQ_ENQUEUE(ifq, m, NULL, err);			\
167130416Smlaier	else {								\
168130416Smlaier		if (_IF_QFULL(ifq)) {					\
169130416Smlaier			m_freem(m);					\
170130416Smlaier			(err) = ENOBUFS;				\
171130416Smlaier		} else {						\
172130416Smlaier			_IF_ENQUEUE(ifq, m);				\
173130416Smlaier			(err) = 0;					\
174130416Smlaier		}							\
175130416Smlaier	}								\
176130416Smlaier	IF_UNLOCK(ifq);							\
177130416Smlaier} while (0)
17821259Swollman
179130416Smlaier#define	IFQ_DEQUEUE_NOLOCK(ifq, m)					\
180130416Smlaierdo {									\
181130416Smlaier	if (TBR_IS_ENABLED(ifq))					\
182130508Smlaier		(m) = tbr_dequeue_ptr(ifq, ALTDQ_REMOVE);		\
183130416Smlaier	else if (ALTQ_IS_ENABLED(ifq))					\
184130416Smlaier		ALTQ_DEQUEUE(ifq, m);					\
185130416Smlaier	else								\
186130416Smlaier		_IF_DEQUEUE(ifq, m);					\
187130416Smlaier} while (0)
188130416Smlaier
189130416Smlaier#define	IFQ_DEQUEUE(ifq, m)						\
190130416Smlaierdo {									\
191130416Smlaier	IF_LOCK(ifq);							\
192130416Smlaier	IFQ_DEQUEUE_NOLOCK(ifq, m);					\
193130416Smlaier	IF_UNLOCK(ifq);							\
194130416Smlaier} while (0)
195130416Smlaier
196130416Smlaier#define	IFQ_POLL_NOLOCK(ifq, m)						\
197130416Smlaierdo {									\
198130416Smlaier	if (TBR_IS_ENABLED(ifq))					\
199130508Smlaier		(m) = tbr_dequeue_ptr(ifq, ALTDQ_POLL);			\
200130416Smlaier	else if (ALTQ_IS_ENABLED(ifq))					\
201130416Smlaier		ALTQ_POLL(ifq, m);					\
202130416Smlaier	else								\
203130416Smlaier		_IF_POLL(ifq, m);					\
204130416Smlaier} while (0)
205130416Smlaier
206130416Smlaier#define	IFQ_POLL(ifq, m)						\
207130416Smlaierdo {									\
208130416Smlaier	IF_LOCK(ifq);							\
209130416Smlaier	IFQ_POLL_NOLOCK(ifq, m);					\
210130416Smlaier	IF_UNLOCK(ifq);							\
211130416Smlaier} while (0)
212130416Smlaier
213130416Smlaier#define	IFQ_PURGE_NOLOCK(ifq)						\
214130416Smlaierdo {									\
215130416Smlaier	if (ALTQ_IS_ENABLED(ifq)) {					\
216130416Smlaier		ALTQ_PURGE(ifq);					\
217130416Smlaier	} else								\
218130416Smlaier		_IF_DRAIN(ifq);						\
219130416Smlaier} while (0)
220130416Smlaier
221130416Smlaier#define	IFQ_PURGE(ifq)							\
222130416Smlaierdo {									\
223130416Smlaier	IF_LOCK(ifq);							\
224130416Smlaier	IFQ_PURGE_NOLOCK(ifq);						\
225130416Smlaier	IF_UNLOCK(ifq);							\
226130416Smlaier} while (0)
227130416Smlaier
228130416Smlaier#define	IFQ_SET_READY(ifq)						\
229130416Smlaier	do { ((ifq)->altq_flags |= ALTQF_READY); } while (0)
230130416Smlaier
231130416Smlaier#define	IFQ_LOCK(ifq)			IF_LOCK(ifq)
232130416Smlaier#define	IFQ_UNLOCK(ifq)			IF_UNLOCK(ifq)
233130416Smlaier#define	IFQ_LOCK_ASSERT(ifq)		IF_LOCK_ASSERT(ifq)
234130416Smlaier#define	IFQ_IS_EMPTY(ifq)		((ifq)->ifq_len == 0)
235130416Smlaier#define	IFQ_INC_LEN(ifq)		((ifq)->ifq_len++)
236130416Smlaier#define	IFQ_DEC_LEN(ifq)		(--(ifq)->ifq_len)
237130416Smlaier#define	IFQ_SET_MAXLEN(ifq, len)	((ifq)->ifq_maxlen = (len))
238130416Smlaier
239148886Srwatson/*
240148886Srwatson * The IFF_DRV_OACTIVE test should really occur in the device driver, not in
241148886Srwatson * the handoff logic, as that flag is locked by the device driver.
242148886Srwatson */
243130416Smlaier#define	IFQ_HANDOFF_ADJ(ifp, m, adj, err)				\
244130416Smlaierdo {									\
245130416Smlaier	int len;							\
246130416Smlaier	short mflags;							\
247130416Smlaier									\
248130416Smlaier	len = (m)->m_pkthdr.len;					\
249130416Smlaier	mflags = (m)->m_flags;						\
250130416Smlaier	IFQ_ENQUEUE(&(ifp)->if_snd, m, err);				\
251130416Smlaier	if ((err) == 0) {						\
252272244Sglebius		if_inc_counter((ifp), IFCOUNTER_OBYTES, len + (adj));	\
253130416Smlaier		if (mflags & M_MCAST)					\
254272244Sglebius			if_inc_counter((ifp), IFCOUNTER_OMCASTS, 1);	\
255148886Srwatson		if (((ifp)->if_drv_flags & IFF_DRV_OACTIVE) == 0)	\
256132712Srwatson			if_start(ifp);					\
257271856Sglebius	} else								\
258272244Sglebius		if_inc_counter((ifp), IFCOUNTER_OQDROPS, 1);		\
259130416Smlaier} while (0)
260130416Smlaier
261130416Smlaier#define	IFQ_HANDOFF(ifp, m, err)					\
262130512Smlaier	IFQ_HANDOFF_ADJ(ifp, m, 0, err)
263130416Smlaier
264130416Smlaier#define	IFQ_DRV_DEQUEUE(ifq, m)						\
265130416Smlaierdo {									\
266130416Smlaier	(m) = (ifq)->ifq_drv_head;					\
267130416Smlaier	if (m) {							\
268130416Smlaier		if (((ifq)->ifq_drv_head = (m)->m_nextpkt) == NULL)	\
269130416Smlaier			(ifq)->ifq_drv_tail = NULL;			\
270130416Smlaier		(m)->m_nextpkt = NULL;					\
271130416Smlaier		(ifq)->ifq_drv_len--;					\
272130416Smlaier	} else {							\
273130416Smlaier		IFQ_LOCK(ifq);						\
274130416Smlaier		IFQ_DEQUEUE_NOLOCK(ifq, m);				\
275130416Smlaier		while ((ifq)->ifq_drv_len < (ifq)->ifq_drv_maxlen) {	\
276130416Smlaier			struct mbuf *m0;				\
277130416Smlaier			IFQ_DEQUEUE_NOLOCK(ifq, m0);			\
278130416Smlaier			if (m0 == NULL)					\
279130416Smlaier				break;					\
280130416Smlaier			m0->m_nextpkt = NULL;				\
281130416Smlaier			if ((ifq)->ifq_drv_tail == NULL)		\
282130416Smlaier				(ifq)->ifq_drv_head = m0;		\
283130416Smlaier			else						\
284130416Smlaier				(ifq)->ifq_drv_tail->m_nextpkt = m0;	\
285130416Smlaier			(ifq)->ifq_drv_tail = m0;			\
286130416Smlaier			(ifq)->ifq_drv_len++;				\
287130416Smlaier		}							\
288130416Smlaier		IFQ_UNLOCK(ifq);					\
289130416Smlaier	}								\
290130416Smlaier} while (0)
291130416Smlaier
292130416Smlaier#define	IFQ_DRV_PREPEND(ifq, m)						\
293130416Smlaierdo {									\
294130416Smlaier	(m)->m_nextpkt = (ifq)->ifq_drv_head;				\
295132152Smlaier	if ((ifq)->ifq_drv_tail == NULL)				\
296132152Smlaier		(ifq)->ifq_drv_tail = (m);				\
297130416Smlaier	(ifq)->ifq_drv_head = (m);					\
298130416Smlaier	(ifq)->ifq_drv_len++;						\
299130416Smlaier} while (0)
300130416Smlaier
301130416Smlaier#define	IFQ_DRV_IS_EMPTY(ifq)						\
302130416Smlaier	(((ifq)->ifq_drv_len == 0) && ((ifq)->ifq_len == 0))
303130416Smlaier
304130416Smlaier#define	IFQ_DRV_PURGE(ifq)						\
305130416Smlaierdo {									\
306132152Smlaier	struct mbuf *m, *n = (ifq)->ifq_drv_head;			\
307132152Smlaier	while((m = n) != NULL) {					\
308132152Smlaier		n = m->m_nextpkt;					\
309130416Smlaier		m_freem(m);						\
310130416Smlaier	}								\
311130416Smlaier	(ifq)->ifq_drv_head = (ifq)->ifq_drv_tail = NULL;		\
312130416Smlaier	(ifq)->ifq_drv_len = 0;						\
313130416Smlaier	IFQ_PURGE(ifq);							\
314130416Smlaier} while (0)
315130416Smlaier
316186207Skmacystatic __inline int
317186213Skmacydrbr_enqueue(struct ifnet *ifp, struct buf_ring *br, struct mbuf *m)
318186207Skmacy{
319186207Skmacy	int error = 0;
320186207Skmacy
321191033Skmacy#ifdef ALTQ
322191033Skmacy	if (ALTQ_IS_ENABLED(&ifp->if_snd)) {
323191033Skmacy		IFQ_ENQUEUE(&ifp->if_snd, m, error);
324271856Sglebius		if (error)
325272244Sglebius			if_inc_counter((ifp), IFCOUNTER_OQDROPS, 1);
326191033Skmacy		return (error);
327191033Skmacy	}
328191033Skmacy#endif
329241037Sglebius	error = buf_ring_enqueue(br, m);
330241037Sglebius	if (error)
331186207Skmacy		m_freem(m);
332241037Sglebius
333186207Skmacy	return (error);
334186207Skmacy}
335186207Skmacy
336186207Skmacystatic __inline void
337246482Srrsdrbr_putback(struct ifnet *ifp, struct buf_ring *br, struct mbuf *new)
338246482Srrs{
339246482Srrs	/*
340246482Srrs	 * The top of the list needs to be swapped
341246482Srrs	 * for this one.
342246482Srrs	 */
343246482Srrs#ifdef ALTQ
344246482Srrs	if (ifp != NULL && ALTQ_IS_ENABLED(&ifp->if_snd)) {
345246482Srrs		/*
346246482Srrs		 * Peek in altq case dequeued it
347246482Srrs		 * so put it back.
348246482Srrs		 */
349246482Srrs		IFQ_DRV_PREPEND(&ifp->if_snd, new);
350246482Srrs		return;
351246482Srrs	}
352246482Srrs#endif
353246482Srrs	buf_ring_putback_sc(br, new);
354246482Srrs}
355246482Srrs
356246482Srrsstatic __inline struct mbuf *
357246482Srrsdrbr_peek(struct ifnet *ifp, struct buf_ring *br)
358246482Srrs{
359246482Srrs#ifdef ALTQ
360246482Srrs	struct mbuf *m;
361246482Srrs	if (ifp != NULL && ALTQ_IS_ENABLED(&ifp->if_snd)) {
362246482Srrs		/*
363246482Srrs		 * Pull it off like a dequeue
364246482Srrs		 * since drbr_advance() does nothing
365246482Srrs		 * for altq and drbr_putback() will
366246482Srrs		 * use the old prepend function.
367246482Srrs		 */
368246482Srrs		IFQ_DEQUEUE(&ifp->if_snd, m);
369246482Srrs		return (m);
370246482Srrs	}
371246482Srrs#endif
372296178Ssephe	return(buf_ring_peek_clear_sc(br));
373246482Srrs}
374246482Srrs
375246482Srrsstatic __inline void
376194518Skmacydrbr_flush(struct ifnet *ifp, struct buf_ring *br)
377186207Skmacy{
378186207Skmacy	struct mbuf *m;
379186207Skmacy
380194518Skmacy#ifdef ALTQ
381203834Smlaier	if (ifp != NULL && ALTQ_IS_ENABLED(&ifp->if_snd))
382203834Smlaier		IFQ_PURGE(&ifp->if_snd);
383194518Skmacy#endif
384186207Skmacy	while ((m = buf_ring_dequeue_sc(br)) != NULL)
385186207Skmacy		m_freem(m);
386194518Skmacy}
387186207Skmacy
388194518Skmacystatic __inline void
389194518Skmacydrbr_free(struct buf_ring *br, struct malloc_type *type)
390194518Skmacy{
391194518Skmacy
392194518Skmacy	drbr_flush(NULL, br);
393186207Skmacy	buf_ring_free(br, type);
394186207Skmacy}
395191033Skmacy
396191033Skmacystatic __inline struct mbuf *
397191033Skmacydrbr_dequeue(struct ifnet *ifp, struct buf_ring *br)
398191033Skmacy{
399191033Skmacy#ifdef ALTQ
400191033Skmacy	struct mbuf *m;
401191033Skmacy
402246482Srrs	if (ifp != NULL && ALTQ_IS_ENABLED(&ifp->if_snd)) {
403203834Smlaier		IFQ_DEQUEUE(&ifp->if_snd, m);
404191033Skmacy		return (m);
405191033Skmacy	}
406186207Skmacy#endif
407191033Skmacy	return (buf_ring_dequeue_sc(br));
408191033Skmacy}
409186207Skmacy
410246482Srrsstatic __inline void
411246482Srrsdrbr_advance(struct ifnet *ifp, struct buf_ring *br)
412246482Srrs{
413246482Srrs#ifdef ALTQ
414246482Srrs	/* Nothing to do here since peek dequeues in altq case */
415246482Srrs	if (ifp != NULL && ALTQ_IS_ENABLED(&ifp->if_snd))
416246482Srrs		return;
417246482Srrs#endif
418246482Srrs	return (buf_ring_advance_sc(br));
419246482Srrs}
420246482Srrs
421246482Srrs
422193848Skmacystatic __inline struct mbuf *
423193848Skmacydrbr_dequeue_cond(struct ifnet *ifp, struct buf_ring *br,
424193848Skmacy    int (*func) (struct mbuf *, void *), void *arg)
425193848Skmacy{
426193848Skmacy	struct mbuf *m;
427193848Skmacy#ifdef ALTQ
428203834Smlaier	if (ALTQ_IS_ENABLED(&ifp->if_snd)) {
429203834Smlaier		IFQ_LOCK(&ifp->if_snd);
430203834Smlaier		IFQ_POLL_NOLOCK(&ifp->if_snd, m);
431203834Smlaier		if (m != NULL && func(m, arg) == 0) {
432203834Smlaier			IFQ_UNLOCK(&ifp->if_snd);
433203834Smlaier			return (NULL);
434203834Smlaier		}
435205197Smlaier		IFQ_DEQUEUE_NOLOCK(&ifp->if_snd, m);
436203834Smlaier		IFQ_UNLOCK(&ifp->if_snd);
437193848Skmacy		return (m);
438193848Skmacy	}
439193848Skmacy#endif
440193848Skmacy	m = buf_ring_peek(br);
441193848Skmacy	if (m == NULL || func(m, arg) == 0)
442193848Skmacy		return (NULL);
443193848Skmacy
444193848Skmacy	return (buf_ring_dequeue_sc(br));
445193848Skmacy}
446193848Skmacy
447191033Skmacystatic __inline int
448191033Skmacydrbr_empty(struct ifnet *ifp, struct buf_ring *br)
449191033Skmacy{
450191033Skmacy#ifdef ALTQ
451191033Skmacy	if (ALTQ_IS_ENABLED(&ifp->if_snd))
452203834Smlaier		return (IFQ_IS_EMPTY(&ifp->if_snd));
453191033Skmacy#endif
454191033Skmacy	return (buf_ring_empty(br));
455191033Skmacy}
456193848Skmacy
457193848Skmacystatic __inline int
458203834Smlaierdrbr_needs_enqueue(struct ifnet *ifp, struct buf_ring *br)
459203834Smlaier{
460203834Smlaier#ifdef ALTQ
461203834Smlaier	if (ALTQ_IS_ENABLED(&ifp->if_snd))
462203834Smlaier		return (1);
463203834Smlaier#endif
464203834Smlaier	return (!buf_ring_empty(br));
465203834Smlaier}
466203834Smlaier
467203834Smlaierstatic __inline int
468193848Skmacydrbr_inuse(struct ifnet *ifp, struct buf_ring *br)
469193848Skmacy{
470193848Skmacy#ifdef ALTQ
471193848Skmacy	if (ALTQ_IS_ENABLED(&ifp->if_snd))
472193848Skmacy		return (ifp->if_snd.ifq_len);
473191033Skmacy#endif
474193848Skmacy	return (buf_ring_count(br));
475193848Skmacy}
47649459Sbrian
477186048Sbzextern	int ifqmaxlen;
47821259Swollman
479191161Skmacyvoid	if_qflush(struct ifnet *);
480194259Ssamvoid	ifq_init(struct ifaltq *, struct ifnet *ifp);
481194259Ssamvoid	ifq_delete(struct ifaltq *);
482185162Skmacy
48355205Speter#endif /* _KERNEL */
484257351Sandre#endif /* !_NET_IFQ_H_ */
485