if_cue.c revision 194228
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 194228 2009-06-15 01:02:43Z thompsa $");
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 "usbdevs.h"
55#include <dev/usb/usb.h>
56#include <dev/usb/usb_mfunc.h>
57#include <dev/usb/usb_error.h>
58
59#define	USB_DEBUG_VAR cue_debug
60
61#include <dev/usb/usb_core.h>
62#include <dev/usb/usb_lookup.h>
63#include <dev/usb/usb_process.h>
64#include <dev/usb/usb_debug.h>
65#include <dev/usb/usb_request.h>
66#include <dev/usb/usb_busdma.h>
67#include <dev/usb/usb_util.h>
68
69#include <dev/usb/net/usb_ethernet.h>
70#include <dev/usb/net/if_cuereg.h>
71
72/*
73 * Various supported device vendors/products.
74 */
75
76/* Belkin F5U111 adapter covered by NETMATE entry */
77
78static const struct usb_device_id cue_devs[] = {
79	{USB_VPI(USB_VENDOR_CATC, USB_PRODUCT_CATC_NETMATE, 0)},
80	{USB_VPI(USB_VENDOR_CATC, USB_PRODUCT_CATC_NETMATE2, 0)},
81	{USB_VPI(USB_VENDOR_SMARTBRIDGES, USB_PRODUCT_SMARTBRIDGES_SMARTLINK, 0)},
82};
83
84/* prototypes */
85
86static device_probe_t cue_probe;
87static device_attach_t cue_attach;
88static device_detach_t cue_detach;
89
90static usb_callback_t cue_bulk_read_callback;
91static usb_callback_t cue_bulk_write_callback;
92
93static uether_fn_t cue_attach_post;
94static uether_fn_t cue_init;
95static uether_fn_t cue_stop;
96static uether_fn_t cue_start;
97static uether_fn_t cue_tick;
98static uether_fn_t cue_setmulti;
99static uether_fn_t cue_setpromisc;
100
101static uint8_t	cue_csr_read_1(struct cue_softc *, uint16_t);
102static uint16_t	cue_csr_read_2(struct cue_softc *, uint8_t);
103static int	cue_csr_write_1(struct cue_softc *, uint16_t, uint16_t);
104static int	cue_mem(struct cue_softc *, uint8_t, uint16_t, void *, int);
105static int	cue_getmac(struct cue_softc *, void *);
106static uint32_t	cue_mchash(const uint8_t *);
107static void	cue_reset(struct cue_softc *);
108
109#if USB_DEBUG
110static int cue_debug = 0;
111
112SYSCTL_NODE(_hw_usb, OID_AUTO, cue, CTLFLAG_RW, 0, "USB cue");
113SYSCTL_INT(_hw_usb_cue, OID_AUTO, debug, CTLFLAG_RW, &cue_debug, 0,
114    "Debug level");
115#endif
116
117static const struct usb_config cue_config[CUE_N_TRANSFER] = {
118
119	[CUE_BULK_DT_WR] = {
120		.type = UE_BULK,
121		.endpoint = UE_ADDR_ANY,
122		.direction = UE_DIR_OUT,
123		.bufsize = (MCLBYTES + 2),
124		.flags = {.pipe_bof = 1,},
125		.callback = cue_bulk_write_callback,
126		.timeout = 10000,	/* 10 seconds */
127	},
128
129	[CUE_BULK_DT_RD] = {
130		.type = UE_BULK,
131		.endpoint = UE_ADDR_ANY,
132		.direction = UE_DIR_IN,
133		.bufsize = (MCLBYTES + 2),
134		.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
135		.callback = cue_bulk_read_callback,
136	},
137};
138
139static device_method_t cue_methods[] = {
140	/* Device interface */
141	DEVMETHOD(device_probe, cue_probe),
142	DEVMETHOD(device_attach, cue_attach),
143	DEVMETHOD(device_detach, cue_detach),
144
145	{0, 0}
146};
147
148static driver_t cue_driver = {
149	.name = "cue",
150	.methods = cue_methods,
151	.size = sizeof(struct cue_softc),
152};
153
154static devclass_t cue_devclass;
155
156DRIVER_MODULE(cue, uhub, cue_driver, cue_devclass, NULL, 0);
157MODULE_DEPEND(cue, uether, 1, 1, 1);
158MODULE_DEPEND(cue, usb, 1, 1, 1);
159MODULE_DEPEND(cue, ether, 1, 1, 1);
160
161static const struct usb_ether_methods cue_ue_methods = {
162	.ue_attach_post = cue_attach_post,
163	.ue_start = cue_start,
164	.ue_init = cue_init,
165	.ue_stop = cue_stop,
166	.ue_tick = cue_tick,
167	.ue_setmulti = cue_setmulti,
168	.ue_setpromisc = cue_setpromisc,
169};
170
171#define	CUE_SETBIT(sc, reg, x)				\
172	cue_csr_write_1(sc, reg, cue_csr_read_1(sc, reg) | (x))
173
174#define	CUE_CLRBIT(sc, reg, x)				\
175	cue_csr_write_1(sc, reg, cue_csr_read_1(sc, reg) & ~(x))
176
177static uint8_t
178cue_csr_read_1(struct cue_softc *sc, uint16_t reg)
179{
180	struct usb_device_request req;
181	uint8_t val;
182
183	req.bmRequestType = UT_READ_VENDOR_DEVICE;
184	req.bRequest = CUE_CMD_READREG;
185	USETW(req.wValue, 0);
186	USETW(req.wIndex, reg);
187	USETW(req.wLength, 1);
188
189	if (uether_do_request(&sc->sc_ue, &req, &val, 1000)) {
190		/* ignore any errors */
191	}
192	return (val);
193}
194
195static uint16_t
196cue_csr_read_2(struct cue_softc *sc, uint8_t reg)
197{
198	struct usb_device_request req;
199	uint16_t val;
200
201	req.bmRequestType = UT_READ_VENDOR_DEVICE;
202	req.bRequest = CUE_CMD_READREG;
203	USETW(req.wValue, 0);
204	USETW(req.wIndex, reg);
205	USETW(req.wLength, 2);
206
207	(void)uether_do_request(&sc->sc_ue, &req, &val, 1000);
208	return (le16toh(val));
209}
210
211static int
212cue_csr_write_1(struct cue_softc *sc, uint16_t reg, uint16_t val)
213{
214	struct usb_device_request req;
215
216	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
217	req.bRequest = CUE_CMD_WRITEREG;
218	USETW(req.wValue, val);
219	USETW(req.wIndex, reg);
220	USETW(req.wLength, 0);
221
222	return (uether_do_request(&sc->sc_ue, &req, NULL, 1000));
223}
224
225static int
226cue_mem(struct cue_softc *sc, uint8_t cmd, uint16_t addr, void *buf, int len)
227{
228	struct usb_device_request req;
229
230	if (cmd == CUE_CMD_READSRAM)
231		req.bmRequestType = UT_READ_VENDOR_DEVICE;
232	else
233		req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
234	req.bRequest = cmd;
235	USETW(req.wValue, 0);
236	USETW(req.wIndex, addr);
237	USETW(req.wLength, len);
238
239	return (uether_do_request(&sc->sc_ue, &req, buf, 1000));
240}
241
242static int
243cue_getmac(struct cue_softc *sc, void *buf)
244{
245	struct usb_device_request req;
246
247	req.bmRequestType = UT_READ_VENDOR_DEVICE;
248	req.bRequest = CUE_CMD_GET_MACADDR;
249	USETW(req.wValue, 0);
250	USETW(req.wIndex, 0);
251	USETW(req.wLength, ETHER_ADDR_LEN);
252
253	return (uether_do_request(&sc->sc_ue, &req, buf, 1000));
254}
255
256#define	CUE_BITS 9
257
258static uint32_t
259cue_mchash(const uint8_t *addr)
260{
261	uint32_t crc;
262
263	/* Compute CRC for the address value. */
264	crc = ether_crc32_le(addr, ETHER_ADDR_LEN);
265
266	return (crc & ((1 << CUE_BITS) - 1));
267}
268
269static void
270cue_setpromisc(struct usb_ether *ue)
271{
272	struct cue_softc *sc = uether_getsc(ue);
273	struct ifnet *ifp = uether_getifp(ue);
274
275	CUE_LOCK_ASSERT(sc, MA_OWNED);
276
277	/* if we want promiscuous mode, set the allframes bit */
278	if (ifp->if_flags & IFF_PROMISC)
279		CUE_SETBIT(sc, CUE_ETHCTL, CUE_ETHCTL_PROMISC);
280	else
281		CUE_CLRBIT(sc, CUE_ETHCTL, CUE_ETHCTL_PROMISC);
282
283	/* write multicast hash-bits */
284	cue_setmulti(ue);
285}
286
287static void
288cue_setmulti(struct usb_ether *ue)
289{
290	struct cue_softc *sc = uether_getsc(ue);
291	struct ifnet *ifp = uether_getifp(ue);
292	struct ifmultiaddr *ifma;
293	uint32_t h = 0, i;
294	uint8_t hashtbl[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
295
296	CUE_LOCK_ASSERT(sc, MA_OWNED);
297
298	if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
299		for (i = 0; i < 8; i++)
300			hashtbl[i] = 0xff;
301		cue_mem(sc, CUE_CMD_WRITESRAM, CUE_MCAST_TABLE_ADDR,
302		    &hashtbl, 8);
303		return;
304	}
305
306	/* now program new ones */
307	IF_ADDR_LOCK(ifp);
308	TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link)
309	{
310		if (ifma->ifma_addr->sa_family != AF_LINK)
311			continue;
312		h = cue_mchash(LLADDR((struct sockaddr_dl *)ifma->ifma_addr));
313		hashtbl[h >> 3] |= 1 << (h & 0x7);
314	}
315	IF_ADDR_UNLOCK(ifp);
316
317	/*
318	 * Also include the broadcast address in the filter
319	 * so we can receive broadcast frames.
320 	 */
321	if (ifp->if_flags & IFF_BROADCAST) {
322		h = cue_mchash(ifp->if_broadcastaddr);
323		hashtbl[h >> 3] |= 1 << (h & 0x7);
324	}
325
326	cue_mem(sc, CUE_CMD_WRITESRAM, CUE_MCAST_TABLE_ADDR, &hashtbl, 8);
327}
328
329static void
330cue_reset(struct cue_softc *sc)
331{
332	struct usb_device_request req;
333
334	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
335	req.bRequest = CUE_CMD_RESET;
336	USETW(req.wValue, 0);
337	USETW(req.wIndex, 0);
338	USETW(req.wLength, 0);
339
340	if (uether_do_request(&sc->sc_ue, &req, NULL, 1000)) {
341		/* ignore any errors */
342	}
343
344	/*
345	 * wait a little while for the chip to get its brains in order:
346	 */
347	uether_pause(&sc->sc_ue, hz / 100);
348}
349
350static void
351cue_attach_post(struct usb_ether *ue)
352{
353	struct cue_softc *sc = uether_getsc(ue);
354
355	cue_getmac(sc, ue->ue_eaddr);
356}
357
358static int
359cue_probe(device_t dev)
360{
361	struct usb_attach_arg *uaa = device_get_ivars(dev);
362
363	if (uaa->usb_mode != USB_MODE_HOST)
364		return (ENXIO);
365	if (uaa->info.bConfigIndex != CUE_CONFIG_IDX)
366		return (ENXIO);
367	if (uaa->info.bIfaceIndex != CUE_IFACE_IDX)
368		return (ENXIO);
369
370	return (usbd_lookup_id_by_uaa(cue_devs, sizeof(cue_devs), uaa));
371}
372
373/*
374 * Attach the interface. Allocate softc structures, do ifmedia
375 * setup and ethernet/BPF attach.
376 */
377static int
378cue_attach(device_t dev)
379{
380	struct usb_attach_arg *uaa = device_get_ivars(dev);
381	struct cue_softc *sc = device_get_softc(dev);
382	struct usb_ether *ue = &sc->sc_ue;
383	uint8_t iface_index;
384	int error;
385
386	device_set_usb_desc(dev);
387	mtx_init(&sc->sc_mtx, device_get_nameunit(dev), NULL, MTX_DEF);
388
389	iface_index = CUE_IFACE_IDX;
390	error = usbd_transfer_setup(uaa->device, &iface_index,
391	    sc->sc_xfer, cue_config, CUE_N_TRANSFER, sc, &sc->sc_mtx);
392	if (error) {
393		device_printf(dev, "allocating USB transfers failed!\n");
394		goto detach;
395	}
396
397	ue->ue_sc = sc;
398	ue->ue_dev = dev;
399	ue->ue_udev = uaa->device;
400	ue->ue_mtx = &sc->sc_mtx;
401	ue->ue_methods = &cue_ue_methods;
402
403	error = uether_ifattach(ue);
404	if (error) {
405		device_printf(dev, "could not attach interface\n");
406		goto detach;
407	}
408	return (0);			/* success */
409
410detach:
411	cue_detach(dev);
412	return (ENXIO);			/* failure */
413}
414
415static int
416cue_detach(device_t dev)
417{
418	struct cue_softc *sc = device_get_softc(dev);
419	struct usb_ether *ue = &sc->sc_ue;
420
421	usbd_transfer_unsetup(sc->sc_xfer, CUE_N_TRANSFER);
422	uether_ifdetach(ue);
423	mtx_destroy(&sc->sc_mtx);
424
425	return (0);
426}
427
428static void
429cue_bulk_read_callback(struct usb_xfer *xfer)
430{
431	struct cue_softc *sc = xfer->priv_sc;
432	struct usb_ether *ue = &sc->sc_ue;
433	struct ifnet *ifp = uether_getifp(ue);
434	uint8_t buf[2];
435	int len;
436
437	switch (USB_GET_STATE(xfer)) {
438	case USB_ST_TRANSFERRED:
439
440		if (xfer->actlen <= (2 + sizeof(struct ether_header))) {
441			ifp->if_ierrors++;
442			goto tr_setup;
443		}
444		usbd_copy_out(xfer->frbuffers, 0, buf, 2);
445		xfer->actlen -= 2;
446		len = buf[0] | (buf[1] << 8);
447		len = min(xfer->actlen, len);
448
449		uether_rxbuf(ue, xfer->frbuffers, 2, len);
450		/* FALLTHROUGH */
451	case USB_ST_SETUP:
452tr_setup:
453		xfer->frlengths[0] = xfer->max_data_length;
454		usbd_transfer_submit(xfer);
455		uether_rxflush(ue);
456		return;
457
458	default:			/* Error */
459		DPRINTF("bulk read error, %s\n",
460		    usbd_errstr(xfer->error));
461
462		if (xfer->error != USB_ERR_CANCELLED) {
463			/* try to clear stall first */
464			xfer->flags.stall_pipe = 1;
465			goto tr_setup;
466		}
467		return;
468
469	}
470}
471
472static void
473cue_bulk_write_callback(struct usb_xfer *xfer)
474{
475	struct cue_softc *sc = xfer->priv_sc;
476	struct ifnet *ifp = uether_getifp(&sc->sc_ue);
477	struct mbuf *m;
478	uint8_t buf[2];
479
480	switch (USB_GET_STATE(xfer)) {
481	case USB_ST_TRANSFERRED:
482		DPRINTFN(11, "transfer complete\n");
483		ifp->if_opackets++;
484
485		/* FALLTHROUGH */
486	case USB_ST_SETUP:
487tr_setup:
488		IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
489
490		if (m == NULL)
491			return;
492		if (m->m_pkthdr.len > MCLBYTES)
493			m->m_pkthdr.len = MCLBYTES;
494		xfer->frlengths[0] = (m->m_pkthdr.len + 2);
495
496		/* the first two bytes are the frame length */
497
498		buf[0] = (uint8_t)(m->m_pkthdr.len);
499		buf[1] = (uint8_t)(m->m_pkthdr.len >> 8);
500
501		usbd_copy_in(xfer->frbuffers, 0, buf, 2);
502
503		usbd_m_copy_in(xfer->frbuffers, 2,
504		    m, 0, m->m_pkthdr.len);
505
506		/*
507		 * If there's a BPF listener, bounce a copy of this frame
508		 * to him.
509		 */
510		BPF_MTAP(ifp, m);
511
512		m_freem(m);
513
514		usbd_transfer_submit(xfer);
515
516		return;
517
518	default:			/* Error */
519		DPRINTFN(11, "transfer error, %s\n",
520		    usbd_errstr(xfer->error));
521
522		ifp->if_oerrors++;
523
524		if (xfer->error != USB_ERR_CANCELLED) {
525			/* try to clear stall first */
526			xfer->flags.stall_pipe = 1;
527			goto tr_setup;
528		}
529		return;
530	}
531}
532
533static void
534cue_tick(struct usb_ether *ue)
535{
536	struct cue_softc *sc = uether_getsc(ue);
537	struct ifnet *ifp = uether_getifp(ue);
538
539	CUE_LOCK_ASSERT(sc, MA_OWNED);
540
541	ifp->if_collisions += cue_csr_read_2(sc, CUE_TX_SINGLECOLL);
542	ifp->if_collisions += cue_csr_read_2(sc, CUE_TX_MULTICOLL);
543	ifp->if_collisions += cue_csr_read_2(sc, CUE_TX_EXCESSCOLL);
544
545	if (cue_csr_read_2(sc, CUE_RX_FRAMEERR))
546		ifp->if_ierrors++;
547}
548
549static void
550cue_start(struct usb_ether *ue)
551{
552	struct cue_softc *sc = uether_getsc(ue);
553
554	/*
555	 * start the USB transfers, if not already started:
556	 */
557	usbd_transfer_start(sc->sc_xfer[CUE_BULK_DT_RD]);
558	usbd_transfer_start(sc->sc_xfer[CUE_BULK_DT_WR]);
559}
560
561static void
562cue_init(struct usb_ether *ue)
563{
564	struct cue_softc *sc = uether_getsc(ue);
565	struct ifnet *ifp = uether_getifp(ue);
566	int i;
567
568	CUE_LOCK_ASSERT(sc, MA_OWNED);
569
570	/*
571	 * Cancel pending I/O and free all RX/TX buffers.
572	 */
573	cue_stop(ue);
574#if 0
575	cue_reset(sc);
576#endif
577	/* Set MAC address */
578	for (i = 0; i < ETHER_ADDR_LEN; i++)
579		cue_csr_write_1(sc, CUE_PAR0 - i, IF_LLADDR(ifp)[i]);
580
581	/* Enable RX logic. */
582	cue_csr_write_1(sc, CUE_ETHCTL, CUE_ETHCTL_RX_ON | CUE_ETHCTL_MCAST_ON);
583
584	/* Load the multicast filter */
585	cue_setpromisc(ue);
586
587	/*
588	 * Set the number of RX and TX buffers that we want
589	 * to reserve inside the ASIC.
590	 */
591	cue_csr_write_1(sc, CUE_RX_BUFPKTS, CUE_RX_FRAMES);
592	cue_csr_write_1(sc, CUE_TX_BUFPKTS, CUE_TX_FRAMES);
593
594	/* Set advanced operation modes. */
595	cue_csr_write_1(sc, CUE_ADVANCED_OPMODES,
596	    CUE_AOP_EMBED_RXLEN | 0x01);/* 1 wait state */
597
598	/* Program the LED operation. */
599	cue_csr_write_1(sc, CUE_LEDCTL, CUE_LEDCTL_FOLLOW_LINK);
600
601	usbd_transfer_set_stall(sc->sc_xfer[CUE_BULK_DT_WR]);
602
603	ifp->if_drv_flags |= IFF_DRV_RUNNING;
604	cue_start(ue);
605}
606
607/*
608 * Stop the adapter and free any mbufs allocated to the
609 * RX and TX lists.
610 */
611static void
612cue_stop(struct usb_ether *ue)
613{
614	struct cue_softc *sc = uether_getsc(ue);
615	struct ifnet *ifp = uether_getifp(ue);
616
617	CUE_LOCK_ASSERT(sc, MA_OWNED);
618
619	ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
620
621	/*
622	 * stop all the transfers, if not already stopped:
623	 */
624	usbd_transfer_stop(sc->sc_xfer[CUE_BULK_DT_WR]);
625	usbd_transfer_stop(sc->sc_xfer[CUE_BULK_DT_RD]);
626
627	cue_csr_write_1(sc, CUE_ETHCTL, 0);
628	cue_reset(sc);
629}
630