if_cue.c revision 195049
1/*-
2 * Copyright (c) 1997, 1998, 1999, 2000
3 *	Bill Paul <wpaul@ee.columbia.edu>.  All rights reserved.
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 * 3. All advertising materials mentioning features or use of this software
14 *    must display the following acknowledgement:
15 *	This product includes software developed by Bill Paul.
16 * 4. Neither the name of the author nor the names of any co-contributors
17 *    may be used to endorse or promote products derived from this software
18 *    without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
30 * THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#include <sys/cdefs.h>
34__FBSDID("$FreeBSD: head/sys/dev/usb/net/if_cue.c 195049 2009-06-26 11:45:06Z rwatson $");
35
36/*
37 * CATC USB-EL1210A USB to ethernet driver. Used in the CATC Netmate
38 * adapters and others.
39 *
40 * Written by Bill Paul <wpaul@ee.columbia.edu>
41 * Electrical Engineering Department
42 * Columbia University, New York City
43 */
44
45/*
46 * The CATC USB-EL1210A provides USB ethernet support at 10Mbps. The
47 * RX filter uses a 512-bit multicast hash table, single perfect entry
48 * for the station address, and promiscuous mode. Unlike the ADMtek
49 * and KLSI chips, the CATC ASIC supports read and write combining
50 * mode where multiple packets can be transfered using a single bulk
51 * transaction, which helps performance a great deal.
52 */
53
54#include <sys/stdint.h>
55#include <sys/stddef.h>
56#include <sys/param.h>
57#include <sys/queue.h>
58#include <sys/types.h>
59#include <sys/systm.h>
60#include <sys/kernel.h>
61#include <sys/bus.h>
62#include <sys/linker_set.h>
63#include <sys/module.h>
64#include <sys/lock.h>
65#include <sys/mutex.h>
66#include <sys/condvar.h>
67#include <sys/sysctl.h>
68#include <sys/sx.h>
69#include <sys/unistd.h>
70#include <sys/callout.h>
71#include <sys/malloc.h>
72#include <sys/priv.h>
73
74#include <dev/usb/usb.h>
75#include <dev/usb/usbdi.h>
76#include <dev/usb/usbdi_util.h>
77#include "usbdevs.h"
78
79#define	USB_DEBUG_VAR cue_debug
80#include <dev/usb/usb_debug.h>
81#include <dev/usb/usb_process.h>
82
83#include <dev/usb/net/usb_ethernet.h>
84#include <dev/usb/net/if_cuereg.h>
85
86/*
87 * Various supported device vendors/products.
88 */
89
90/* Belkin F5U111 adapter covered by NETMATE entry */
91
92static const struct usb_device_id cue_devs[] = {
93	{USB_VPI(USB_VENDOR_CATC, USB_PRODUCT_CATC_NETMATE, 0)},
94	{USB_VPI(USB_VENDOR_CATC, USB_PRODUCT_CATC_NETMATE2, 0)},
95	{USB_VPI(USB_VENDOR_SMARTBRIDGES, USB_PRODUCT_SMARTBRIDGES_SMARTLINK, 0)},
96};
97
98/* prototypes */
99
100static device_probe_t cue_probe;
101static device_attach_t cue_attach;
102static device_detach_t cue_detach;
103
104static usb_callback_t cue_bulk_read_callback;
105static usb_callback_t cue_bulk_write_callback;
106
107static uether_fn_t cue_attach_post;
108static uether_fn_t cue_init;
109static uether_fn_t cue_stop;
110static uether_fn_t cue_start;
111static uether_fn_t cue_tick;
112static uether_fn_t cue_setmulti;
113static uether_fn_t cue_setpromisc;
114
115static uint8_t	cue_csr_read_1(struct cue_softc *, uint16_t);
116static uint16_t	cue_csr_read_2(struct cue_softc *, uint8_t);
117static int	cue_csr_write_1(struct cue_softc *, uint16_t, uint16_t);
118static int	cue_mem(struct cue_softc *, uint8_t, uint16_t, void *, int);
119static int	cue_getmac(struct cue_softc *, void *);
120static uint32_t	cue_mchash(const uint8_t *);
121static void	cue_reset(struct cue_softc *);
122
123#if USB_DEBUG
124static int cue_debug = 0;
125
126SYSCTL_NODE(_hw_usb, OID_AUTO, cue, CTLFLAG_RW, 0, "USB cue");
127SYSCTL_INT(_hw_usb_cue, OID_AUTO, debug, CTLFLAG_RW, &cue_debug, 0,
128    "Debug level");
129#endif
130
131static const struct usb_config cue_config[CUE_N_TRANSFER] = {
132
133	[CUE_BULK_DT_WR] = {
134		.type = UE_BULK,
135		.endpoint = UE_ADDR_ANY,
136		.direction = UE_DIR_OUT,
137		.bufsize = (MCLBYTES + 2),
138		.flags = {.pipe_bof = 1,},
139		.callback = cue_bulk_write_callback,
140		.timeout = 10000,	/* 10 seconds */
141	},
142
143	[CUE_BULK_DT_RD] = {
144		.type = UE_BULK,
145		.endpoint = UE_ADDR_ANY,
146		.direction = UE_DIR_IN,
147		.bufsize = (MCLBYTES + 2),
148		.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
149		.callback = cue_bulk_read_callback,
150	},
151};
152
153static device_method_t cue_methods[] = {
154	/* Device interface */
155	DEVMETHOD(device_probe, cue_probe),
156	DEVMETHOD(device_attach, cue_attach),
157	DEVMETHOD(device_detach, cue_detach),
158
159	{0, 0}
160};
161
162static driver_t cue_driver = {
163	.name = "cue",
164	.methods = cue_methods,
165	.size = sizeof(struct cue_softc),
166};
167
168static devclass_t cue_devclass;
169
170DRIVER_MODULE(cue, uhub, cue_driver, cue_devclass, NULL, 0);
171MODULE_DEPEND(cue, uether, 1, 1, 1);
172MODULE_DEPEND(cue, usb, 1, 1, 1);
173MODULE_DEPEND(cue, ether, 1, 1, 1);
174
175static const struct usb_ether_methods cue_ue_methods = {
176	.ue_attach_post = cue_attach_post,
177	.ue_start = cue_start,
178	.ue_init = cue_init,
179	.ue_stop = cue_stop,
180	.ue_tick = cue_tick,
181	.ue_setmulti = cue_setmulti,
182	.ue_setpromisc = cue_setpromisc,
183};
184
185#define	CUE_SETBIT(sc, reg, x)				\
186	cue_csr_write_1(sc, reg, cue_csr_read_1(sc, reg) | (x))
187
188#define	CUE_CLRBIT(sc, reg, x)				\
189	cue_csr_write_1(sc, reg, cue_csr_read_1(sc, reg) & ~(x))
190
191static uint8_t
192cue_csr_read_1(struct cue_softc *sc, uint16_t reg)
193{
194	struct usb_device_request req;
195	uint8_t val;
196
197	req.bmRequestType = UT_READ_VENDOR_DEVICE;
198	req.bRequest = CUE_CMD_READREG;
199	USETW(req.wValue, 0);
200	USETW(req.wIndex, reg);
201	USETW(req.wLength, 1);
202
203	if (uether_do_request(&sc->sc_ue, &req, &val, 1000)) {
204		/* ignore any errors */
205	}
206	return (val);
207}
208
209static uint16_t
210cue_csr_read_2(struct cue_softc *sc, uint8_t reg)
211{
212	struct usb_device_request req;
213	uint16_t val;
214
215	req.bmRequestType = UT_READ_VENDOR_DEVICE;
216	req.bRequest = CUE_CMD_READREG;
217	USETW(req.wValue, 0);
218	USETW(req.wIndex, reg);
219	USETW(req.wLength, 2);
220
221	(void)uether_do_request(&sc->sc_ue, &req, &val, 1000);
222	return (le16toh(val));
223}
224
225static int
226cue_csr_write_1(struct cue_softc *sc, uint16_t reg, uint16_t val)
227{
228	struct usb_device_request req;
229
230	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
231	req.bRequest = CUE_CMD_WRITEREG;
232	USETW(req.wValue, val);
233	USETW(req.wIndex, reg);
234	USETW(req.wLength, 0);
235
236	return (uether_do_request(&sc->sc_ue, &req, NULL, 1000));
237}
238
239static int
240cue_mem(struct cue_softc *sc, uint8_t cmd, uint16_t addr, void *buf, int len)
241{
242	struct usb_device_request req;
243
244	if (cmd == CUE_CMD_READSRAM)
245		req.bmRequestType = UT_READ_VENDOR_DEVICE;
246	else
247		req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
248	req.bRequest = cmd;
249	USETW(req.wValue, 0);
250	USETW(req.wIndex, addr);
251	USETW(req.wLength, len);
252
253	return (uether_do_request(&sc->sc_ue, &req, buf, 1000));
254}
255
256static int
257cue_getmac(struct cue_softc *sc, void *buf)
258{
259	struct usb_device_request req;
260
261	req.bmRequestType = UT_READ_VENDOR_DEVICE;
262	req.bRequest = CUE_CMD_GET_MACADDR;
263	USETW(req.wValue, 0);
264	USETW(req.wIndex, 0);
265	USETW(req.wLength, ETHER_ADDR_LEN);
266
267	return (uether_do_request(&sc->sc_ue, &req, buf, 1000));
268}
269
270#define	CUE_BITS 9
271
272static uint32_t
273cue_mchash(const uint8_t *addr)
274{
275	uint32_t crc;
276
277	/* Compute CRC for the address value. */
278	crc = ether_crc32_le(addr, ETHER_ADDR_LEN);
279
280	return (crc & ((1 << CUE_BITS) - 1));
281}
282
283static void
284cue_setpromisc(struct usb_ether *ue)
285{
286	struct cue_softc *sc = uether_getsc(ue);
287	struct ifnet *ifp = uether_getifp(ue);
288
289	CUE_LOCK_ASSERT(sc, MA_OWNED);
290
291	/* if we want promiscuous mode, set the allframes bit */
292	if (ifp->if_flags & IFF_PROMISC)
293		CUE_SETBIT(sc, CUE_ETHCTL, CUE_ETHCTL_PROMISC);
294	else
295		CUE_CLRBIT(sc, CUE_ETHCTL, CUE_ETHCTL_PROMISC);
296
297	/* write multicast hash-bits */
298	cue_setmulti(ue);
299}
300
301static void
302cue_setmulti(struct usb_ether *ue)
303{
304	struct cue_softc *sc = uether_getsc(ue);
305	struct ifnet *ifp = uether_getifp(ue);
306	struct ifmultiaddr *ifma;
307	uint32_t h = 0, i;
308	uint8_t hashtbl[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
309
310	CUE_LOCK_ASSERT(sc, MA_OWNED);
311
312	if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
313		for (i = 0; i < 8; i++)
314			hashtbl[i] = 0xff;
315		cue_mem(sc, CUE_CMD_WRITESRAM, CUE_MCAST_TABLE_ADDR,
316		    &hashtbl, 8);
317		return;
318	}
319
320	/* now program new ones */
321	if_maddr_rlock(ifp);
322	TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link)
323	{
324		if (ifma->ifma_addr->sa_family != AF_LINK)
325			continue;
326		h = cue_mchash(LLADDR((struct sockaddr_dl *)ifma->ifma_addr));
327		hashtbl[h >> 3] |= 1 << (h & 0x7);
328	}
329	if_maddr_runlock(ifp);
330
331	/*
332	 * Also include the broadcast address in the filter
333	 * so we can receive broadcast frames.
334 	 */
335	if (ifp->if_flags & IFF_BROADCAST) {
336		h = cue_mchash(ifp->if_broadcastaddr);
337		hashtbl[h >> 3] |= 1 << (h & 0x7);
338	}
339
340	cue_mem(sc, CUE_CMD_WRITESRAM, CUE_MCAST_TABLE_ADDR, &hashtbl, 8);
341}
342
343static void
344cue_reset(struct cue_softc *sc)
345{
346	struct usb_device_request req;
347
348	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
349	req.bRequest = CUE_CMD_RESET;
350	USETW(req.wValue, 0);
351	USETW(req.wIndex, 0);
352	USETW(req.wLength, 0);
353
354	if (uether_do_request(&sc->sc_ue, &req, NULL, 1000)) {
355		/* ignore any errors */
356	}
357
358	/*
359	 * wait a little while for the chip to get its brains in order:
360	 */
361	uether_pause(&sc->sc_ue, hz / 100);
362}
363
364static void
365cue_attach_post(struct usb_ether *ue)
366{
367	struct cue_softc *sc = uether_getsc(ue);
368
369	cue_getmac(sc, ue->ue_eaddr);
370}
371
372static int
373cue_probe(device_t dev)
374{
375	struct usb_attach_arg *uaa = device_get_ivars(dev);
376
377	if (uaa->usb_mode != USB_MODE_HOST)
378		return (ENXIO);
379	if (uaa->info.bConfigIndex != CUE_CONFIG_IDX)
380		return (ENXIO);
381	if (uaa->info.bIfaceIndex != CUE_IFACE_IDX)
382		return (ENXIO);
383
384	return (usbd_lookup_id_by_uaa(cue_devs, sizeof(cue_devs), uaa));
385}
386
387/*
388 * Attach the interface. Allocate softc structures, do ifmedia
389 * setup and ethernet/BPF attach.
390 */
391static int
392cue_attach(device_t dev)
393{
394	struct usb_attach_arg *uaa = device_get_ivars(dev);
395	struct cue_softc *sc = device_get_softc(dev);
396	struct usb_ether *ue = &sc->sc_ue;
397	uint8_t iface_index;
398	int error;
399
400	device_set_usb_desc(dev);
401	mtx_init(&sc->sc_mtx, device_get_nameunit(dev), NULL, MTX_DEF);
402
403	iface_index = CUE_IFACE_IDX;
404	error = usbd_transfer_setup(uaa->device, &iface_index,
405	    sc->sc_xfer, cue_config, CUE_N_TRANSFER, sc, &sc->sc_mtx);
406	if (error) {
407		device_printf(dev, "allocating USB transfers failed!\n");
408		goto detach;
409	}
410
411	ue->ue_sc = sc;
412	ue->ue_dev = dev;
413	ue->ue_udev = uaa->device;
414	ue->ue_mtx = &sc->sc_mtx;
415	ue->ue_methods = &cue_ue_methods;
416
417	error = uether_ifattach(ue);
418	if (error) {
419		device_printf(dev, "could not attach interface\n");
420		goto detach;
421	}
422	return (0);			/* success */
423
424detach:
425	cue_detach(dev);
426	return (ENXIO);			/* failure */
427}
428
429static int
430cue_detach(device_t dev)
431{
432	struct cue_softc *sc = device_get_softc(dev);
433	struct usb_ether *ue = &sc->sc_ue;
434
435	usbd_transfer_unsetup(sc->sc_xfer, CUE_N_TRANSFER);
436	uether_ifdetach(ue);
437	mtx_destroy(&sc->sc_mtx);
438
439	return (0);
440}
441
442static void
443cue_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error)
444{
445	struct cue_softc *sc = usbd_xfer_softc(xfer);
446	struct usb_ether *ue = &sc->sc_ue;
447	struct ifnet *ifp = uether_getifp(ue);
448	struct usb_page_cache *pc;
449	uint8_t buf[2];
450	int len;
451	int actlen;
452
453	usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
454
455	switch (USB_GET_STATE(xfer)) {
456	case USB_ST_TRANSFERRED:
457
458		if (actlen <= (2 + sizeof(struct ether_header))) {
459			ifp->if_ierrors++;
460			goto tr_setup;
461		}
462		pc = usbd_xfer_get_frame(xfer, 0);
463		usbd_copy_out(pc, 0, buf, 2);
464		actlen -= 2;
465		len = buf[0] | (buf[1] << 8);
466		len = min(actlen, len);
467
468		uether_rxbuf(ue, pc, 2, len);
469		/* FALLTHROUGH */
470	case USB_ST_SETUP:
471tr_setup:
472		usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer));
473		usbd_transfer_submit(xfer);
474		uether_rxflush(ue);
475		return;
476
477	default:			/* Error */
478		DPRINTF("bulk read error, %s\n",
479		    usbd_errstr(error));
480
481		if (error != USB_ERR_CANCELLED) {
482			/* try to clear stall first */
483			usbd_xfer_set_stall(xfer);
484			goto tr_setup;
485		}
486		return;
487
488	}
489}
490
491static void
492cue_bulk_write_callback(struct usb_xfer *xfer, usb_error_t error)
493{
494	struct cue_softc *sc = usbd_xfer_softc(xfer);
495	struct ifnet *ifp = uether_getifp(&sc->sc_ue);
496	struct usb_page_cache *pc;
497	struct mbuf *m;
498	uint8_t buf[2];
499
500	switch (USB_GET_STATE(xfer)) {
501	case USB_ST_TRANSFERRED:
502		DPRINTFN(11, "transfer complete\n");
503		ifp->if_opackets++;
504
505		/* FALLTHROUGH */
506	case USB_ST_SETUP:
507tr_setup:
508		IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
509
510		if (m == NULL)
511			return;
512		if (m->m_pkthdr.len > MCLBYTES)
513			m->m_pkthdr.len = MCLBYTES;
514		usbd_xfer_set_frame_len(xfer, 0, (m->m_pkthdr.len + 2));
515
516		/* the first two bytes are the frame length */
517
518		buf[0] = (uint8_t)(m->m_pkthdr.len);
519		buf[1] = (uint8_t)(m->m_pkthdr.len >> 8);
520
521		pc = usbd_xfer_get_frame(xfer, 0);
522		usbd_copy_in(pc, 0, buf, 2);
523		usbd_m_copy_in(pc, 2, m, 0, m->m_pkthdr.len);
524
525		/*
526		 * If there's a BPF listener, bounce a copy of this frame
527		 * to him.
528		 */
529		BPF_MTAP(ifp, m);
530
531		m_freem(m);
532
533		usbd_transfer_submit(xfer);
534
535		return;
536
537	default:			/* Error */
538		DPRINTFN(11, "transfer error, %s\n",
539		    usbd_errstr(error));
540
541		ifp->if_oerrors++;
542
543		if (error != USB_ERR_CANCELLED) {
544			/* try to clear stall first */
545			usbd_xfer_set_stall(xfer);
546			goto tr_setup;
547		}
548		return;
549	}
550}
551
552static void
553cue_tick(struct usb_ether *ue)
554{
555	struct cue_softc *sc = uether_getsc(ue);
556	struct ifnet *ifp = uether_getifp(ue);
557
558	CUE_LOCK_ASSERT(sc, MA_OWNED);
559
560	ifp->if_collisions += cue_csr_read_2(sc, CUE_TX_SINGLECOLL);
561	ifp->if_collisions += cue_csr_read_2(sc, CUE_TX_MULTICOLL);
562	ifp->if_collisions += cue_csr_read_2(sc, CUE_TX_EXCESSCOLL);
563
564	if (cue_csr_read_2(sc, CUE_RX_FRAMEERR))
565		ifp->if_ierrors++;
566}
567
568static void
569cue_start(struct usb_ether *ue)
570{
571	struct cue_softc *sc = uether_getsc(ue);
572
573	/*
574	 * start the USB transfers, if not already started:
575	 */
576	usbd_transfer_start(sc->sc_xfer[CUE_BULK_DT_RD]);
577	usbd_transfer_start(sc->sc_xfer[CUE_BULK_DT_WR]);
578}
579
580static void
581cue_init(struct usb_ether *ue)
582{
583	struct cue_softc *sc = uether_getsc(ue);
584	struct ifnet *ifp = uether_getifp(ue);
585	int i;
586
587	CUE_LOCK_ASSERT(sc, MA_OWNED);
588
589	/*
590	 * Cancel pending I/O and free all RX/TX buffers.
591	 */
592	cue_stop(ue);
593#if 0
594	cue_reset(sc);
595#endif
596	/* Set MAC address */
597	for (i = 0; i < ETHER_ADDR_LEN; i++)
598		cue_csr_write_1(sc, CUE_PAR0 - i, IF_LLADDR(ifp)[i]);
599
600	/* Enable RX logic. */
601	cue_csr_write_1(sc, CUE_ETHCTL, CUE_ETHCTL_RX_ON | CUE_ETHCTL_MCAST_ON);
602
603	/* Load the multicast filter */
604	cue_setpromisc(ue);
605
606	/*
607	 * Set the number of RX and TX buffers that we want
608	 * to reserve inside the ASIC.
609	 */
610	cue_csr_write_1(sc, CUE_RX_BUFPKTS, CUE_RX_FRAMES);
611	cue_csr_write_1(sc, CUE_TX_BUFPKTS, CUE_TX_FRAMES);
612
613	/* Set advanced operation modes. */
614	cue_csr_write_1(sc, CUE_ADVANCED_OPMODES,
615	    CUE_AOP_EMBED_RXLEN | 0x01);/* 1 wait state */
616
617	/* Program the LED operation. */
618	cue_csr_write_1(sc, CUE_LEDCTL, CUE_LEDCTL_FOLLOW_LINK);
619
620	usbd_xfer_set_stall(sc->sc_xfer[CUE_BULK_DT_WR]);
621
622	ifp->if_drv_flags |= IFF_DRV_RUNNING;
623	cue_start(ue);
624}
625
626/*
627 * Stop the adapter and free any mbufs allocated to the
628 * RX and TX lists.
629 */
630static void
631cue_stop(struct usb_ether *ue)
632{
633	struct cue_softc *sc = uether_getsc(ue);
634	struct ifnet *ifp = uether_getifp(ue);
635
636	CUE_LOCK_ASSERT(sc, MA_OWNED);
637
638	ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
639
640	/*
641	 * stop all the transfers, if not already stopped:
642	 */
643	usbd_transfer_stop(sc->sc_xfer[CUE_BULK_DT_WR]);
644	usbd_transfer_stop(sc->sc_xfer[CUE_BULK_DT_RD]);
645
646	cue_csr_write_1(sc, CUE_ETHCTL, 0);
647	cue_reset(sc);
648}
649