xref: /dragonfly/sys/bus/u4b/usb_pf.c (revision ae071d8d)
1 /*-
2  * Copyright (c) 1990, 1991, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * This code is derived from the Stanford/CMU enet packet filter,
6  * (net/enet.c) distributed as part of 4.3BSD, and code contributed
7  * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
8  * Berkeley Laboratory.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. Neither the name of the University nor the names of its contributors
19  *    may be used to endorse or promote products derived from this software
20  *    without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  */
34 
35 #include <sys/param.h>
36 #include <sys/kernel.h>
37 #include <sys/bus.h>
38 #include <sys/fcntl.h>
39 #include <sys/malloc.h>
40 #include <sys/proc.h>
41 #include <sys/socket.h>
42 #include <sys/sockio.h>
43 #include <net/if.h>
44 #include <net/if_types.h>
45 #include <net/bpf.h>
46 #include <sys/sysctl.h>
47 #include <sys/condvar.h>
48 
49 #include <bus/u4b/usb.h>
50 #include <bus/u4b/usbdi.h>
51 #include <bus/u4b/usb_busdma.h>
52 
53 #include <bus/u4b/usb_controller.h>
54 #include <bus/u4b/usb_core.h>
55 #include <bus/u4b/usb_process.h>
56 #include <bus/u4b/usb_device.h>
57 #include <bus/u4b/usb_bus.h>
58 #include <bus/u4b/usb_pf.h>
59 #include <bus/u4b/usb_transfer.h>
60 static void usbpf_init(void *);
61 static void usbpf_uninit(void *);
62 static int usbpf_ioctl(struct ifnet *, u_long, caddr_t);
63 static int usbpf_clone_match(struct if_clone *, const char *);
64 static int usbpf_clone_create(struct if_clone *, char *, size_t, caddr_t);
65 static int usbpf_clone_destroy(struct if_clone *, struct ifnet *);
66 static struct usb_bus *usbpf_ifname2ubus(const char *);
67 static uint32_t usbpf_aggregate_xferflags(struct usb_xfer_flags *);
68 static uint32_t usbpf_aggregate_status(struct usb_xfer_flags_int *);
69 static int usbpf_xfer_frame_is_read(struct usb_xfer *, uint32_t);
70 static uint32_t usbpf_xfer_precompute_size(struct usb_xfer *, int);
71 
72 static struct if_clone *usbpf_cloner;
73 static const char usbusname[] = "usbus";
74 
75 SYSINIT(usbpf_init, SI_SUB_PSEUDO, SI_ORDER_MIDDLE, usbpf_init, NULL);
76 SYSUNINIT(usbpf_uninit, SI_SUB_PSEUDO, SI_ORDER_MIDDLE, usbpf_uninit, NULL);
77 
78 static void
79 usbpf_uninit(void *arg)
80 {
81 	int devlcnt;
82 	device_t *devlp;
83 	devclass_t dc;
84 	struct usb_bus *ubus;
85 	int error;
86 	int i;
87 
88 	if_clone_detach(usbpf_cloner);
89 
90 	dc = devclass_find(usbusname);
91 	if (dc == NULL)
92 		return;
93 	error = devclass_get_devices(dc, &devlp, &devlcnt);
94 	if (error)
95 		return;
96 	for (i = 0; i < devlcnt; i++) {
97 		ubus = device_get_softc(devlp[i]);
98 		if (ubus != NULL && ubus->ifp != NULL)
99 			usbpf_clone_destroy(usbpf_cloner, ubus->ifp);
100 	}
101 	free(devlp, M_TEMP);
102 }
103 
104 static int
105 usbpf_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
106 {
107 
108 	/* No configuration allowed. */
109 	return (EINVAL);
110 }
111 
112 static struct usb_bus *
113 usbpf_ifname2ubus(const char *ifname)
114 {
115 	device_t dev;
116 	devclass_t dc;
117 	int unit;
118 	int error;
119 
120 	if (strncmp(ifname, usbusname, sizeof(usbusname) - 1) != 0)
121 		return (NULL);
122 	error = ifc_name2unit(ifname, &unit);
123 	if (error || unit < 0)
124 		return (NULL);
125 	dc = devclass_find(usbusname);
126 	if (dc == NULL)
127 		return (NULL);
128 	dev = devclass_get_device(dc, unit);
129 	if (dev == NULL)
130 		return (NULL);
131 
132 	return (device_get_softc(dev));
133 }
134 
135 static int
136 usbpf_clone_match(struct if_clone *ifc, const char *name)
137 {
138 	struct usb_bus *ubus;
139 
140 	ubus = usbpf_ifname2ubus(name);
141 	if (ubus == NULL)
142 		return (0);
143 	if (ubus->ifp != NULL)
144 		return (0);
145 
146 	return (1);
147 }
148 
149 static int
150 usbpf_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params)
151 {
152 	int error;
153 	int unit;
154 	struct ifnet *ifp;
155 	struct usb_bus *ubus;
156 
157 	error = ifc_name2unit(name, &unit);
158 	if (error)
159 		return (error);
160  	if (unit < 0)
161 		return (EINVAL);
162 
163 	ubus = usbpf_ifname2ubus(name);
164 	if (ubus == NULL)
165 		return (1);
166 	if (ubus->ifp != NULL)
167 		return (1);
168 
169 	error = ifc_alloc_unit(ifc, &unit);
170 	if (error) {
171 		device_printf(ubus->parent, "usbpf: Could not allocate "
172 		    "instance\n");
173 		return (error);
174 	}
175 	ifp = ubus->ifp = if_alloc(IFT_USB);
176 	if (ifp == NULL) {
177 		ifc_free_unit(ifc, unit);
178 		device_printf(ubus->parent, "usbpf: Could not allocate "
179 		    "instance\n");
180 		return (ENOSPC);
181 	}
182 	strlcpy(ifp->if_xname, name, sizeof(ifp->if_xname));
183 	ifp->if_softc = ubus;
184 	ifp->if_dname = usbusname;
185 	ifp->if_dunit = unit;
186 	ifp->if_ioctl = usbpf_ioctl;
187 	if_attach(ifp);
188 	ifp->if_flags |= IFF_UP;
189 	rt_ifmsg(ifp);
190 	/*
191 	 * XXX According to the specification of DLT_USB, it indicates
192 	 * packets beginning with USB setup header. But not sure all
193 	 * packets would be.
194 	 */
195 	bpfattach(ifp, DLT_USB, USBPF_HDR_LEN);
196 
197 	return (0);
198 }
199 
200 static int
201 usbpf_clone_destroy(struct if_clone *ifc, struct ifnet *ifp)
202 {
203 	struct usb_bus *ubus;
204 	int unit;
205 
206 	ubus = ifp->if_softc;
207 	unit = ifp->if_dunit;
208 
209 	ubus->ifp = NULL;
210 	bpfdetach(ifp);
211 	if_detach(ifp);
212 	if_free(ifp);
213 	ifc_free_unit(ifc, unit);
214 
215 	return (0);
216 }
217 
218 void
219 usbpf_attach(struct usb_bus *ubus)
220 {
221 
222 	if (bootverbose)
223 		device_printf(ubus->parent, "usbpf: Attached\n");
224 }
225 
226 void
227 usbpf_detach(struct usb_bus *ubus)
228 {
229 
230 	if (ubus->ifp != NULL)
231 		usbpf_clone_destroy(usbpf_cloner, ubus->ifp);
232 	if (bootverbose)
233 		device_printf(ubus->parent, "usbpf: Detached\n");
234 }
235 
236 static uint32_t
237 usbpf_aggregate_xferflags(struct usb_xfer_flags *flags)
238 {
239 	uint32_t val = 0;
240 
241 	if (flags->force_short_xfer == 1)
242 		val |= USBPF_FLAG_FORCE_SHORT_XFER;
243 	if (flags->short_xfer_ok == 1)
244 		val |= USBPF_FLAG_SHORT_XFER_OK;
245 	if (flags->short_frames_ok == 1)
246 		val |= USBPF_FLAG_SHORT_FRAMES_OK;
247 	if (flags->pipe_bof == 1)
248 		val |= USBPF_FLAG_PIPE_BOF;
249 	if (flags->proxy_buffer == 1)
250 		val |= USBPF_FLAG_PROXY_BUFFER;
251 	if (flags->ext_buffer == 1)
252 		val |= USBPF_FLAG_EXT_BUFFER;
253 	if (flags->manual_status == 1)
254 		val |= USBPF_FLAG_MANUAL_STATUS;
255 	if (flags->no_pipe_ok == 1)
256 		val |= USBPF_FLAG_NO_PIPE_OK;
257 	if (flags->stall_pipe == 1)
258 		val |= USBPF_FLAG_STALL_PIPE;
259 	return (val);
260 }
261 
262 static uint32_t
263 usbpf_aggregate_status(struct usb_xfer_flags_int *flags)
264 {
265 	uint32_t val = 0;
266 
267 	if (flags->open == 1)
268 		val |= USBPF_STATUS_OPEN;
269 	if (flags->transferring == 1)
270 		val |= USBPF_STATUS_TRANSFERRING;
271 	if (flags->did_dma_delay == 1)
272 		val |= USBPF_STATUS_DID_DMA_DELAY;
273 	if (flags->did_close == 1)
274 		val |= USBPF_STATUS_DID_CLOSE;
275 	if (flags->draining == 1)
276 		val |= USBPF_STATUS_DRAINING;
277 	if (flags->started == 1)
278 		val |= USBPF_STATUS_STARTED;
279 	if (flags->bandwidth_reclaimed == 1)
280 		val |= USBPF_STATUS_BW_RECLAIMED;
281 	if (flags->control_xfr == 1)
282 		val |= USBPF_STATUS_CONTROL_XFR;
283 	if (flags->control_hdr == 1)
284 		val |= USBPF_STATUS_CONTROL_HDR;
285 	if (flags->control_act == 1)
286 		val |= USBPF_STATUS_CONTROL_ACT;
287 	if (flags->control_stall == 1)
288 		val |= USBPF_STATUS_CONTROL_STALL;
289 	if (flags->short_frames_ok == 1)
290 		val |= USBPF_STATUS_SHORT_FRAMES_OK;
291 	if (flags->short_xfer_ok == 1)
292 		val |= USBPF_STATUS_SHORT_XFER_OK;
293 #if USB_HAVE_BUSDMA
294 	if (flags->bdma_enable == 1)
295 		val |= USBPF_STATUS_BDMA_ENABLE;
296 	if (flags->bdma_no_post_sync == 1)
297 		val |= USBPF_STATUS_BDMA_NO_POST_SYNC;
298 	if (flags->bdma_setup == 1)
299 		val |= USBPF_STATUS_BDMA_SETUP;
300 #endif
301 	if (flags->isochronous_xfr == 1)
302 		val |= USBPF_STATUS_ISOCHRONOUS_XFR;
303 	if (flags->curr_dma_set == 1)
304 		val |= USBPF_STATUS_CURR_DMA_SET;
305 	if (flags->can_cancel_immed == 1)
306 		val |= USBPF_STATUS_CAN_CANCEL_IMMED;
307 	if (flags->doing_callback == 1)
308 		val |= USBPF_STATUS_DOING_CALLBACK;
309 
310 	return (val);
311 }
312 
313 static int
314 usbpf_xfer_frame_is_read(struct usb_xfer *xfer, uint32_t frame)
315 {
316 	int isread;
317 
318 	if ((frame == 0) && (xfer->flags_int.control_xfr != 0) &&
319 	    (xfer->flags_int.control_hdr != 0)) {
320 		/* special case */
321 		if (xfer->flags_int.usb_mode == USB_MODE_DEVICE) {
322 			/* The device controller writes to memory */
323 			isread = 1;
324 		} else {
325 			/* The host controller reads from memory */
326 			isread = 0;
327 		}
328 	} else {
329 		isread = USB_GET_DATA_ISREAD(xfer);
330 	}
331 	return (isread);
332 }
333 
334 static uint32_t
335 usbpf_xfer_precompute_size(struct usb_xfer *xfer, int type)
336 {
337 	uint32_t totlen;
338 	uint32_t x;
339 	uint32_t nframes;
340 
341 	if (type == USBPF_XFERTAP_SUBMIT)
342 		nframes = xfer->nframes;
343 	else
344 		nframes = xfer->aframes;
345 
346 	totlen = USBPF_HDR_LEN + (USBPF_FRAME_HDR_LEN * nframes);
347 
348 	/* precompute all trace lengths */
349 	for (x = 0; x != nframes; x++) {
350 		if (usbpf_xfer_frame_is_read(xfer, x)) {
351 			if (type != USBPF_XFERTAP_SUBMIT) {
352 				totlen += USBPF_FRAME_ALIGN(
353 				    xfer->frlengths[x]);
354 			}
355 		} else {
356 			if (type == USBPF_XFERTAP_SUBMIT) {
357 				totlen += USBPF_FRAME_ALIGN(
358 				    xfer->frlengths[x]);
359 			}
360 		}
361 	}
362 	return (totlen);
363 }
364 
365 void
366 usbpf_xfertap(struct usb_xfer *xfer, int type)
367 {
368 	struct usb_bus *bus;
369 	struct usbpf_pkthdr *up;
370 	struct usbpf_framehdr *uf;
371 	usb_frlength_t offset;
372 	uint32_t totlen;
373 	uint32_t frame;
374 	uint32_t temp;
375 	uint32_t nframes;
376 	uint32_t x;
377 	uint8_t *buf;
378 	uint8_t *ptr;
379 
380 	bus = xfer->xroot->bus;
381 
382 	/* sanity checks */
383 	if (bus->ifp == NULL)
384 		return;
385 	if (!bpf_peers_present(bus->ifp->if_bpf))
386 		return;
387 
388 	totlen = usbpf_xfer_precompute_size(xfer, type);
389 
390 	if (type == USBPF_XFERTAP_SUBMIT)
391 		nframes = xfer->nframes;
392 	else
393 		nframes = xfer->aframes;
394 
395 	/*
396 	 * XXX TODO XXX
397 	 *
398 	 * When BPF supports it we could pass a fragmented array of
399 	 * buffers avoiding the data copy operation here.
400 	 */
401 	buf = ptr = malloc(totlen, M_TEMP, M_NOWAIT);
402 	if (buf == NULL) {
403 		device_printf(bus->parent, "usbpf: Out of memory\n");
404 		return;
405 	}
406 
407 	up = (struct usbpf_pkthdr *)ptr;
408 	ptr += USBPF_HDR_LEN;
409 
410 	/* fill out header */
411 	temp = device_get_unit(bus->bdev);
412 	up->up_totlen = htole32(totlen);
413 	up->up_busunit = htole32(temp);
414 	up->up_address = xfer->xroot->udev->device_index;
415 	if (xfer->flags_int.usb_mode == USB_MODE_DEVICE)
416 		up->up_mode = USBPF_MODE_DEVICE;
417 	else
418 		up->up_mode = USBPF_MODE_HOST;
419 	up->up_type = type;
420 	up->up_xfertype = xfer->endpoint->edesc->bmAttributes & UE_XFERTYPE;
421 	temp = usbpf_aggregate_xferflags(&xfer->flags);
422 	up->up_flags = htole32(temp);
423 	temp = usbpf_aggregate_status(&xfer->flags_int);
424 	up->up_status = htole32(temp);
425 	temp = xfer->error;
426 	up->up_error = htole32(temp);
427 	temp = xfer->interval;
428 	up->up_interval = htole32(temp);
429 	up->up_frames = htole32(nframes);
430 	temp = xfer->max_packet_size;
431 	up->up_packet_size = htole32(temp);
432 	temp = xfer->max_packet_count;
433 	up->up_packet_count = htole32(temp);
434 	temp = xfer->endpointno;
435 	up->up_endpoint = htole32(temp);
436 	up->up_speed = xfer->xroot->udev->speed;
437 
438 	/* clear reserved area */
439 	memset(up->up_reserved, 0, sizeof(up->up_reserved));
440 
441 	/* init offset and frame */
442 	offset = 0;
443 	frame = 0;
444 
445 	/* iterate all the USB frames and copy data, if any */
446 	for (x = 0; x != nframes; x++) {
447 		uint32_t length;
448 		int isread;
449 
450 		/* get length */
451 		length = xfer->frlengths[x];
452 
453 		/* get frame header pointer */
454 		uf = (struct usbpf_framehdr *)ptr;
455 		ptr += USBPF_FRAME_HDR_LEN;
456 
457 		/* fill out packet header */
458 		uf->length = htole32(length);
459 		uf->flags = 0;
460 
461 		/* get information about data read/write */
462 		isread = usbpf_xfer_frame_is_read(xfer, x);
463 
464 		/* check if we need to copy any data */
465 		if (isread) {
466 			if (type == USBPF_XFERTAP_SUBMIT)
467 				length = 0;
468 			else {
469 				uf->flags |= htole32(
470 				    USBPF_FRAMEFLAG_DATA_FOLLOWS);
471 			}
472 		} else {
473 			if (type != USBPF_XFERTAP_SUBMIT)
474 				length = 0;
475 			else {
476 				uf->flags |= htole32(
477 				    USBPF_FRAMEFLAG_DATA_FOLLOWS);
478 			}
479 		}
480 
481 		/* check if data is read direction */
482 		if (isread)
483 			uf->flags |= htole32(USBPF_FRAMEFLAG_READ);
484 
485 		/* copy USB data, if any */
486 		if (length != 0) {
487 			/* copy data */
488 			usbd_copy_out(&xfer->frbuffers[frame],
489 			    offset, ptr, length);
490 
491 			/* align length */
492 			temp = USBPF_FRAME_ALIGN(length);
493 
494 			/* zero pad */
495 			if (temp != length)
496 				memset(ptr + length, 0, temp - length);
497 
498 			ptr += temp;
499 		}
500 
501 		if (xfer->flags_int.isochronous_xfr) {
502 			offset += usbd_xfer_old_frame_length(xfer, x);
503 		} else {
504 			frame ++;
505 		}
506 	}
507 
508 	bpf_tap(bus->ifp->if_bpf, buf, totlen);
509 
510 	free(buf, M_TEMP);
511 }
512