usb_ethernet.c revision 188942
1/* $FreeBSD: head/sys/dev/usb/net/usb_ethernet.c 188942 2009-02-23 18:31:00Z thompsa $ */
2/*-
3 * Copyright (c) 2009 Andrew Thompson (thompsa@FreeBSD.org)
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include <dev/usb/usb_mfunc.h>
28#include <dev/usb/usb_error.h>
29#include <dev/usb/usb_endian.h>
30#include <dev/usb/usb.h>
31
32#include <dev/usb/usb_core.h>
33#include <dev/usb/usb_process.h>
34#include <dev/usb/usb_busdma.h>
35#include <dev/usb/usb_request.h>
36#include <dev/usb/usb_util.h>
37
38#include <dev/usb/net/usb_ethernet.h>
39
40SYSCTL_NODE(_net, OID_AUTO, ue, CTLFLAG_RD, 0, "USB Ethernet parameters");
41
42#define	UE_LOCK(_ue)		mtx_lock((_ue)->ue_mtx)
43#define	UE_UNLOCK(_ue)		mtx_unlock((_ue)->ue_mtx)
44#define	UE_LOCK_ASSERT(_ue, t)	mtx_assert((_ue)->ue_mtx, t)
45
46MODULE_DEPEND(uether, usb, 1, 1, 1);
47MODULE_DEPEND(uether, miibus, 1, 1, 1);
48
49static struct unrhdr *ueunit;
50
51static usb2_proc_callback_t ue_attach_post_task;
52static usb2_proc_callback_t ue_promisc_task;
53static usb2_proc_callback_t ue_setmulti_task;
54static usb2_proc_callback_t ue_ifmedia_task;
55static usb2_proc_callback_t ue_tick_task;
56static usb2_proc_callback_t ue_start_task;
57static usb2_proc_callback_t ue_stop_task;
58
59static void	ue_init(void *);
60static void	ue_start(struct ifnet *);
61static int	ue_ifmedia_upd(struct ifnet *);
62static void	ue_watchdog(void *);
63
64/*
65 * Return values:
66 *    0: success
67 * Else: device has been detached
68 */
69uint8_t
70usb2_ether_pause(struct usb2_ether *ue, unsigned int _ticks)
71{
72	if (usb2_proc_is_gone(&ue->ue_tq)) {
73		/* nothing to do */
74		return (1);
75	}
76	usb2_pause_mtx(ue->ue_mtx, _ticks);
77	return (0);
78}
79
80static void
81ue_queue_command(struct usb2_ether *ue,
82    usb2_proc_callback_t *fn,
83    struct usb2_proc_msg *t0, struct usb2_proc_msg *t1)
84{
85	struct usb2_ether_cfg_task *task;
86
87	UE_LOCK_ASSERT(ue, MA_OWNED);
88
89	if (usb2_proc_is_gone(&ue->ue_tq)) {
90		return;         /* nothing to do */
91	}
92	/*
93	 * NOTE: The task cannot get executed before we drop the
94	 * "sc_mtx" mutex. It is safe to update fields in the message
95	 * structure after that the message got queued.
96	 */
97	task = (struct usb2_ether_cfg_task *)
98	  usb2_proc_msignal(&ue->ue_tq, t0, t1);
99
100	/* Setup callback and self pointers */
101	task->hdr.pm_callback = fn;
102	task->ue = ue;
103
104	/*
105	 * Start and stop must be synchronous!
106	 */
107	if ((fn == ue_start_task) || (fn == ue_stop_task))
108		usb2_proc_mwait(&ue->ue_tq, t0, t1);
109}
110
111struct ifnet *
112usb2_ether_getifp(struct usb2_ether *ue)
113{
114	return (ue->ue_ifp);
115}
116
117struct mii_data *
118usb2_ether_getmii(struct usb2_ether *ue)
119{
120	return (device_get_softc(ue->ue_miibus));
121}
122
123void *
124usb2_ether_getsc(struct usb2_ether *ue)
125{
126	return (ue->ue_sc);
127}
128
129static int
130ue_sysctl_parent(SYSCTL_HANDLER_ARGS)
131{
132	struct usb2_ether *ue = arg1;
133	const char *name;
134
135	name = device_get_nameunit(ue->ue_dev);
136	return SYSCTL_OUT(req, name, strlen(name));
137}
138
139int
140usb2_ether_ifattach(struct usb2_ether *ue)
141{
142	int error;
143
144	/* check some critical parameters */
145	if ((ue->ue_dev == NULL) ||
146	    (ue->ue_udev == NULL) ||
147	    (ue->ue_mtx == NULL) ||
148	    (ue->ue_methods == NULL))
149		return (EINVAL);
150
151	error = usb2_proc_create(&ue->ue_tq, ue->ue_mtx,
152	    device_get_nameunit(ue->ue_dev), USB_PRI_MED);
153	if (error) {
154		device_printf(ue->ue_dev, "could not setup taskqueue\n");
155		goto error;
156	}
157
158	/* fork rest of the attach code */
159	UE_LOCK(ue);
160	ue_queue_command(ue, ue_attach_post_task,
161	    &ue->ue_sync_task[0].hdr,
162	    &ue->ue_sync_task[1].hdr);
163	UE_UNLOCK(ue);
164
165error:
166	return (error);
167}
168
169static void
170ue_attach_post_task(struct usb2_proc_msg *_task)
171{
172	struct usb2_ether_cfg_task *task =
173	    (struct usb2_ether_cfg_task *)_task;
174	struct usb2_ether *ue = task->ue;
175	struct ifnet *ifp;
176	int error;
177	char num[14];			/* sufficient for 32 bits */
178
179	/* first call driver's post attach routine */
180	ue->ue_methods->ue_attach_post(ue);
181
182	UE_UNLOCK(ue);
183
184	ue->ue_unit = alloc_unr(ueunit);
185	usb2_callout_init_mtx(&ue->ue_watchdog, ue->ue_mtx, 0);
186	sysctl_ctx_init(&ue->ue_sysctl_ctx);
187
188	ifp = if_alloc(IFT_ETHER);
189	if (ifp == NULL) {
190		device_printf(ue->ue_dev, "could not allocate ifnet\n");
191		goto error;
192	}
193
194	ifp->if_softc = ue;
195	if_initname(ifp, "ue", ue->ue_unit);
196	ifp->if_mtu = ETHERMTU;
197	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
198	if (ue->ue_methods->ue_ioctl != NULL)
199		ifp->if_ioctl = ue->ue_methods->ue_ioctl;
200	else
201		ifp->if_ioctl = usb2_ether_ioctl;
202	ifp->if_start = ue_start;
203	ifp->if_init = ue_init;
204	IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
205	ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
206	IFQ_SET_READY(&ifp->if_snd);
207	ue->ue_ifp = ifp;
208
209	if (ue->ue_methods->ue_mii_upd != NULL &&
210	    ue->ue_methods->ue_mii_sts != NULL) {
211		mtx_lock(&Giant);	/* device_xxx() depends on this */
212		error = mii_phy_probe(ue->ue_dev, &ue->ue_miibus,
213		    ue_ifmedia_upd, ue->ue_methods->ue_mii_sts);
214		mtx_unlock(&Giant);
215		if (error) {
216			device_printf(ue->ue_dev, "MII without any PHY\n");
217			goto error;
218		}
219	}
220
221	if_printf(ifp, "<USB Ethernet> on %s\n", device_get_nameunit(ue->ue_dev));
222	ether_ifattach(ifp, ue->ue_eaddr);
223
224	snprintf(num, sizeof(num), "%u", ue->ue_unit);
225	ue->ue_sysctl_oid = SYSCTL_ADD_NODE(&ue->ue_sysctl_ctx,
226	    &SYSCTL_NODE_CHILDREN(_net, ue),
227	    OID_AUTO, num, CTLFLAG_RD, NULL, "");
228	SYSCTL_ADD_PROC(&ue->ue_sysctl_ctx,
229	    SYSCTL_CHILDREN(ue->ue_sysctl_oid), OID_AUTO,
230	    "%parent", CTLFLAG_RD, ue, 0,
231	    ue_sysctl_parent, "A", "parent device");
232
233	UE_LOCK(ue);
234	return;
235
236error:
237	free_unr(ueunit, ue->ue_unit);
238	if (ue->ue_ifp != NULL) {
239		if_free(ue->ue_ifp);
240		ue->ue_ifp = NULL;
241	}
242	UE_LOCK(ue);
243	return;
244}
245
246void
247usb2_ether_ifdetach(struct usb2_ether *ue)
248{
249	struct ifnet *ifp;
250
251	/* wait for any post attach or other command to complete */
252	usb2_proc_drain(&ue->ue_tq);
253
254	/* read "ifnet" pointer after taskqueue drain */
255	ifp = ue->ue_ifp;
256
257	if (ifp != NULL) {
258
259		/* we are not running any more */
260		UE_LOCK(ue);
261		ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
262		UE_UNLOCK(ue);
263
264		/* drain any callouts */
265		usb2_callout_drain(&ue->ue_watchdog);
266
267		/* detach miibus */
268		if (ue->ue_miibus != NULL) {
269			mtx_lock(&Giant);	/* device_xxx() depends on this */
270			device_delete_child(ue->ue_dev, ue->ue_miibus);
271			mtx_unlock(&Giant);
272		}
273
274		/* detach ethernet */
275		ether_ifdetach(ifp);
276
277		/* free interface instance */
278		if_free(ifp);
279
280		/* free sysctl */
281		sysctl_ctx_free(&ue->ue_sysctl_ctx);
282
283		/* free unit */
284		free_unr(ueunit, ue->ue_unit);
285	}
286
287	/* free taskqueue, if any */
288	usb2_proc_free(&ue->ue_tq);
289}
290
291void
292usb2_ether_ifshutdown(struct usb2_ether *ue)
293{
294	struct ifnet *ifp = ue->ue_ifp;
295
296	UE_LOCK(ue);
297	if (ifp->if_drv_flags & IFF_DRV_RUNNING)
298		ue_queue_command(ue, ue_stop_task,
299		    &ue->ue_sync_task[0].hdr,
300		    &ue->ue_sync_task[1].hdr);
301	UE_UNLOCK(ue);
302}
303
304uint8_t
305usb2_ether_is_gone(struct usb2_ether *ue)
306{
307	return (usb2_proc_is_gone(&ue->ue_tq));
308}
309
310static void
311ue_init(void *arg)
312{
313	struct usb2_ether *ue = arg;
314
315	UE_LOCK(ue);
316	ue_queue_command(ue, ue_start_task,
317	    &ue->ue_sync_task[0].hdr,
318	    &ue->ue_sync_task[1].hdr);
319	UE_UNLOCK(ue);
320}
321
322static void
323ue_start_task(struct usb2_proc_msg *_task)
324{
325	struct usb2_ether_cfg_task *task =
326	    (struct usb2_ether_cfg_task *)_task;
327	struct usb2_ether *ue = task->ue;
328	struct ifnet *ifp = ue->ue_ifp;
329
330	UE_LOCK_ASSERT(ue, MA_OWNED);
331
332	ue->ue_methods->ue_init(ue);
333
334	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
335		return;
336
337	if (ue->ue_methods->ue_tick != NULL)
338		usb2_callout_reset(&ue->ue_watchdog, hz, ue_watchdog, ue);
339}
340
341static void
342ue_stop_task(struct usb2_proc_msg *_task)
343{
344	struct usb2_ether_cfg_task *task =
345	    (struct usb2_ether_cfg_task *)_task;
346	struct usb2_ether *ue = task->ue;
347
348	UE_LOCK_ASSERT(ue, MA_OWNED);
349
350	usb2_callout_stop(&ue->ue_watchdog);
351
352	ue->ue_methods->ue_stop(ue);
353}
354
355static void
356ue_start(struct ifnet *ifp)
357{
358	struct usb2_ether *ue = ifp->if_softc;
359
360	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
361		return;
362
363	UE_LOCK(ue);
364	ue->ue_methods->ue_start(ue);
365	UE_UNLOCK(ue);
366}
367
368static void
369ue_promisc_task(struct usb2_proc_msg *_task)
370{
371	struct usb2_ether_cfg_task *task =
372	    (struct usb2_ether_cfg_task *)_task;
373	struct usb2_ether *ue = task->ue;
374
375	ue->ue_methods->ue_setpromisc(ue);
376}
377
378static void
379ue_setmulti_task(struct usb2_proc_msg *_task)
380{
381	struct usb2_ether_cfg_task *task =
382	    (struct usb2_ether_cfg_task *)_task;
383	struct usb2_ether *ue = task->ue;
384
385	ue->ue_methods->ue_setmulti(ue);
386}
387
388static int
389ue_ifmedia_upd(struct ifnet *ifp)
390{
391	struct usb2_ether *ue = ifp->if_softc;
392
393	/* Defer to process context */
394	UE_LOCK(ue);
395	ue_queue_command(ue, ue_ifmedia_task,
396	    &ue->ue_media_task[0].hdr,
397	    &ue->ue_media_task[1].hdr);
398	UE_UNLOCK(ue);
399
400	return (0);
401}
402
403static void
404ue_ifmedia_task(struct usb2_proc_msg *_task)
405{
406	struct usb2_ether_cfg_task *task =
407	    (struct usb2_ether_cfg_task *)_task;
408	struct usb2_ether *ue = task->ue;
409	struct ifnet *ifp = ue->ue_ifp;
410
411	ue->ue_methods->ue_mii_upd(ifp);
412}
413
414static void
415ue_watchdog(void *arg)
416{
417	struct usb2_ether *ue = arg;
418	struct ifnet *ifp = ue->ue_ifp;
419
420	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
421		return;
422
423	ue_queue_command(ue, ue_tick_task,
424	    &ue->ue_tick_task[0].hdr,
425	    &ue->ue_tick_task[1].hdr);
426
427	usb2_callout_reset(&ue->ue_watchdog, hz, ue_watchdog, ue);
428}
429
430static void
431ue_tick_task(struct usb2_proc_msg *_task)
432{
433	struct usb2_ether_cfg_task *task =
434	    (struct usb2_ether_cfg_task *)_task;
435	struct usb2_ether *ue = task->ue;
436	struct ifnet *ifp = ue->ue_ifp;
437
438	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
439		return;
440
441	ue->ue_methods->ue_tick(ue);
442}
443
444int
445usb2_ether_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
446{
447	struct usb2_ether *ue = ifp->if_softc;
448	struct ifreq *ifr = (struct ifreq *)data;
449	struct mii_data *mii;
450	int error = 0;
451
452	switch (command) {
453	case SIOCSIFFLAGS:
454		UE_LOCK(ue);
455		if (ifp->if_flags & IFF_UP) {
456			if (ifp->if_drv_flags & IFF_DRV_RUNNING)
457				ue_queue_command(ue, ue_promisc_task,
458				    &ue->ue_promisc_task[0].hdr,
459				    &ue->ue_promisc_task[1].hdr);
460			else
461				ue_queue_command(ue, ue_start_task,
462				    &ue->ue_sync_task[0].hdr,
463				    &ue->ue_sync_task[1].hdr);
464		} else {
465			ue_queue_command(ue, ue_stop_task,
466			    &ue->ue_sync_task[0].hdr,
467			    &ue->ue_sync_task[1].hdr);
468		}
469		UE_UNLOCK(ue);
470		break;
471	case SIOCADDMULTI:
472	case SIOCDELMULTI:
473		UE_LOCK(ue);
474		ue_queue_command(ue, ue_setmulti_task,
475		    &ue->ue_multi_task[0].hdr,
476		    &ue->ue_multi_task[1].hdr);
477		UE_UNLOCK(ue);
478		break;
479	case SIOCGIFMEDIA:
480	case SIOCSIFMEDIA:
481		if (ue->ue_miibus != NULL) {
482			mii = device_get_softc(ue->ue_miibus);
483			error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command);
484		} else
485			error = ether_ioctl(ifp, command, data);
486		break;
487	default:
488		error = ether_ioctl(ifp, command, data);
489		break;
490	}
491	return (error);
492}
493
494static int
495usb2_ether_modevent(module_t mod, int type, void *data)
496{
497
498	switch (type) {
499	case MOD_LOAD:
500		ueunit = new_unrhdr(0, INT_MAX, NULL);
501		break;
502	case MOD_UNLOAD:
503		break;
504	default:
505		return (EOPNOTSUPP);
506	}
507	return (0);
508}
509static moduledata_t usb2_ether_mod = {
510	"uether",
511	usb2_ether_modevent,
512	0
513};
514
515int
516usb2_ether_rxmbuf(struct usb2_ether *ue, struct mbuf *m,
517    unsigned int len)
518{
519	struct ifnet *ifp = ue->ue_ifp;
520
521	UE_LOCK_ASSERT(ue, MA_OWNED);
522
523	/* finalize mbuf */
524	ifp->if_ipackets++;
525	m->m_pkthdr.rcvif = ifp;
526	m->m_pkthdr.len = m->m_len = len;
527
528	/* enqueue for later when the lock can be released */
529	_IF_ENQUEUE(&ue->ue_rxq, m);
530	return (0);
531}
532
533int
534usb2_ether_rxbuf(struct usb2_ether *ue, struct usb2_page_cache *pc,
535    unsigned int offset, unsigned int len)
536{
537	struct ifnet *ifp = ue->ue_ifp;
538	struct mbuf *m;
539
540	UE_LOCK_ASSERT(ue, MA_OWNED);
541
542	if (len < ETHER_HDR_LEN || len > MCLBYTES)
543		return (1);
544
545	m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
546	if (m == NULL) {
547		ifp->if_ierrors++;
548		return (ENOMEM);
549	}
550
551	m_adj(m, ETHER_ALIGN);
552	usb2_copy_out(pc, offset, mtod(m, uint8_t *), len);
553
554	/* finalize mbuf */
555	ifp->if_ipackets++;
556	m->m_pkthdr.rcvif = ifp;
557	m->m_pkthdr.len = m->m_len = len;
558
559	/* enqueue for later when the lock can be released */
560	_IF_ENQUEUE(&ue->ue_rxq, m);
561	return (0);
562}
563
564void
565usb2_ether_rxflush(struct usb2_ether *ue)
566{
567	struct ifnet *ifp = ue->ue_ifp;
568	struct mbuf *m;
569
570	UE_LOCK_ASSERT(ue, MA_OWNED);
571
572	for (;;) {
573		_IF_DEQUEUE(&ue->ue_rxq, m);
574		if (m == NULL)
575			break;
576
577		/*
578		 * The USB xfer has been resubmitted so its safe to unlock now.
579		 */
580		UE_UNLOCK(ue);
581		ifp->if_input(ifp, m);
582		UE_LOCK(ue);
583	}
584}
585
586DECLARE_MODULE(uether, usb2_ether_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
587MODULE_VERSION(uether, 1);
588