xref: /freebsd/sys/dev/firewire/fw_net.h (revision 9919c1a8ebd7da0aa86c6475446a7af255ecb17a)
1*9919c1a8SAbdelkader Boudih /*
2*9919c1a8SAbdelkader Boudih  * Copyright (c) 2026 Abdelkader Boudih <freebsd@seuros.com>
3*9919c1a8SAbdelkader Boudih  *
4*9919c1a8SAbdelkader Boudih  * SPDX-License-Identifier: BSD-2-Clause
5*9919c1a8SAbdelkader Boudih  */
6*9919c1a8SAbdelkader Boudih 
7*9919c1a8SAbdelkader Boudih #ifndef _DEV_FIREWIRE_FW_NET_H_
8*9919c1a8SAbdelkader Boudih #define _DEV_FIREWIRE_FW_NET_H_
9*9919c1a8SAbdelkader Boudih 
10*9919c1a8SAbdelkader Boudih /*
11*9919c1a8SAbdelkader Boudih  * Allocate mbuf clusters for isochronous receive bulk transfers
12*9919c1a8SAbdelkader Boudih  * and insert them into the free queue.
13*9919c1a8SAbdelkader Boudih  */
14*9919c1a8SAbdelkader Boudih static __inline void
fw_net_init_iso_chunks(struct fw_xferq * xferq)15*9919c1a8SAbdelkader Boudih fw_net_init_iso_chunks(struct fw_xferq *xferq)
16*9919c1a8SAbdelkader Boudih {
17*9919c1a8SAbdelkader Boudih 	struct mbuf *m;
18*9919c1a8SAbdelkader Boudih 	int i;
19*9919c1a8SAbdelkader Boudih 
20*9919c1a8SAbdelkader Boudih 	for (i = 0; i < xferq->bnchunk; i++) {
21*9919c1a8SAbdelkader Boudih 		m = m_getcl(M_WAITOK, MT_DATA, M_PKTHDR);
22*9919c1a8SAbdelkader Boudih 		xferq->bulkxfer[i].mbuf = m;
23*9919c1a8SAbdelkader Boudih 		m->m_len = m->m_pkthdr.len = m->m_ext.ext_size;
24*9919c1a8SAbdelkader Boudih 		STAILQ_INSERT_TAIL(&xferq->stfree, &xferq->bulkxfer[i], link);
25*9919c1a8SAbdelkader Boudih 	}
26*9919c1a8SAbdelkader Boudih }
27*9919c1a8SAbdelkader Boudih 
28*9919c1a8SAbdelkader Boudih /*
29*9919c1a8SAbdelkader Boudih  * Allocate a single TX xfer with speed, callback, and softc pre-filled.
30*9919c1a8SAbdelkader Boudih  */
31*9919c1a8SAbdelkader Boudih static __inline struct fw_xfer *
fw_net_alloc_txfer(struct firewire_comm * fc,int speed,void * sc,void (* hand)(struct fw_xfer *),struct malloc_type * mtype)32*9919c1a8SAbdelkader Boudih fw_net_alloc_txfer(struct firewire_comm *fc, int speed,
33*9919c1a8SAbdelkader Boudih     void *sc, void (*hand)(struct fw_xfer *),
34*9919c1a8SAbdelkader Boudih     struct malloc_type *mtype)
35*9919c1a8SAbdelkader Boudih {
36*9919c1a8SAbdelkader Boudih 	struct fw_xfer *xfer;
37*9919c1a8SAbdelkader Boudih 
38*9919c1a8SAbdelkader Boudih 	xfer = fw_xfer_alloc(mtype);
39*9919c1a8SAbdelkader Boudih 	if (xfer == NULL)
40*9919c1a8SAbdelkader Boudih 		return (NULL);
41*9919c1a8SAbdelkader Boudih 	xfer->send.spd = speed;
42*9919c1a8SAbdelkader Boudih 	xfer->fc = fc;
43*9919c1a8SAbdelkader Boudih 	xfer->sc = (caddr_t)sc;
44*9919c1a8SAbdelkader Boudih 	xfer->hand = hand;
45*9919c1a8SAbdelkader Boudih 	return (xfer);
46*9919c1a8SAbdelkader Boudih }
47*9919c1a8SAbdelkader Boudih 
48*9919c1a8SAbdelkader Boudih /*
49*9919c1a8SAbdelkader Boudih  * Free all xfers on a STAILQ list.
50*9919c1a8SAbdelkader Boudih  */
51*9919c1a8SAbdelkader Boudih #define	FW_NET_FREE_XFERLIST(head) do {					\
52*9919c1a8SAbdelkader Boudih 	struct fw_xfer *_xfer, *_next;					\
53*9919c1a8SAbdelkader Boudih 	for (_xfer = STAILQ_FIRST(head); _xfer != NULL;		\
54*9919c1a8SAbdelkader Boudih 	    _xfer = _next) {						\
55*9919c1a8SAbdelkader Boudih 		_next = STAILQ_NEXT(_xfer, link);			\
56*9919c1a8SAbdelkader Boudih 		fw_xfer_free(_xfer);					\
57*9919c1a8SAbdelkader Boudih 	}								\
58*9919c1a8SAbdelkader Boudih } while (0)
59*9919c1a8SAbdelkader Boudih 
60*9919c1a8SAbdelkader Boudih /*
61*9919c1a8SAbdelkader Boudih  * Drain the send queue, counting each dropped packet as an output error.
62*9919c1a8SAbdelkader Boudih  */
63*9919c1a8SAbdelkader Boudih static __inline void
fw_net_drain_sendq(if_t ifp)64*9919c1a8SAbdelkader Boudih fw_net_drain_sendq(if_t ifp)
65*9919c1a8SAbdelkader Boudih {
66*9919c1a8SAbdelkader Boudih 	struct mbuf *m;
67*9919c1a8SAbdelkader Boudih 
68*9919c1a8SAbdelkader Boudih 	do {
69*9919c1a8SAbdelkader Boudih 		m = if_dequeue(ifp);
70*9919c1a8SAbdelkader Boudih 		if (m != NULL)
71*9919c1a8SAbdelkader Boudih 			m_freem(m);
72*9919c1a8SAbdelkader Boudih 		if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
73*9919c1a8SAbdelkader Boudih 	} while (m != NULL);
74*9919c1a8SAbdelkader Boudih }
75*9919c1a8SAbdelkader Boudih 
76*9919c1a8SAbdelkader Boudih /*
77*9919c1a8SAbdelkader Boudih  * Handle SIOCSIFCAP for DEVICE_POLLING.
78*9919c1a8SAbdelkader Boudih  * Returns 0 if handled (caller should return), -1 if not a polling request.
79*9919c1a8SAbdelkader Boudih  */
80*9919c1a8SAbdelkader Boudih #ifdef DEVICE_POLLING
81*9919c1a8SAbdelkader Boudih static __inline int
fw_net_poll_ioctl(if_t ifp,struct ifreq * ifr,struct firewire_comm * fc,poll_handler_t * poll_fn)82*9919c1a8SAbdelkader Boudih fw_net_poll_ioctl(if_t ifp, struct ifreq *ifr,
83*9919c1a8SAbdelkader Boudih     struct firewire_comm *fc, poll_handler_t *poll_fn)
84*9919c1a8SAbdelkader Boudih {
85*9919c1a8SAbdelkader Boudih 	int error;
86*9919c1a8SAbdelkader Boudih 
87*9919c1a8SAbdelkader Boudih 	if (ifr->ifr_reqcap & IFCAP_POLLING &&
88*9919c1a8SAbdelkader Boudih 	    !(if_getcapenable(ifp) & IFCAP_POLLING)) {
89*9919c1a8SAbdelkader Boudih 		error = ether_poll_register(poll_fn, ifp);
90*9919c1a8SAbdelkader Boudih 		if (error)
91*9919c1a8SAbdelkader Boudih 			return (error);
92*9919c1a8SAbdelkader Boudih 		/* Disable interrupts */
93*9919c1a8SAbdelkader Boudih 		fc->set_intr(fc, 0);
94*9919c1a8SAbdelkader Boudih 		if_setcapenablebit(ifp, IFCAP_POLLING, 0);
95*9919c1a8SAbdelkader Boudih 		return (0);
96*9919c1a8SAbdelkader Boudih 	}
97*9919c1a8SAbdelkader Boudih 	if (!(ifr->ifr_reqcap & IFCAP_POLLING) &&
98*9919c1a8SAbdelkader Boudih 	    if_getcapenable(ifp) & IFCAP_POLLING) {
99*9919c1a8SAbdelkader Boudih 		error = ether_poll_deregister(ifp);
100*9919c1a8SAbdelkader Boudih 		/* Enable interrupts. */
101*9919c1a8SAbdelkader Boudih 		fc->set_intr(fc, 1);
102*9919c1a8SAbdelkader Boudih 		if_setcapenablebit(ifp, 0, IFCAP_POLLING);
103*9919c1a8SAbdelkader Boudih 		return (error);
104*9919c1a8SAbdelkader Boudih 	}
105*9919c1a8SAbdelkader Boudih 	return (-1);
106*9919c1a8SAbdelkader Boudih }
107*9919c1a8SAbdelkader Boudih #endif /* DEVICE_POLLING */
108*9919c1a8SAbdelkader Boudih 
109*9919c1a8SAbdelkader Boudih #endif /* !_DEV_FIREWIRE_FW_NET_H_ */
110