Home | History | Annotate | Line # | Download | only in usb
if_cdce.c revision 1.12.10.5
      1  1.12.10.1     itohy /*	$NetBSD: if_cdce.c,v 1.12.10.5 2007/06/13 04:29:22 itohy Exp $ */
      2        1.1  augustss 
      3        1.1  augustss /*
      4        1.1  augustss  * Copyright (c) 1997, 1998, 1999, 2000-2003 Bill Paul <wpaul (at) windriver.com>
      5        1.1  augustss  * Copyright (c) 2003 Craig Boston
      6        1.1  augustss  * Copyright (c) 2004 Daniel Hartmeier
      7        1.1  augustss  * All rights reserved.
      8        1.1  augustss  *
      9        1.1  augustss  * Redistribution and use in source and binary forms, with or without
     10        1.1  augustss  * modification, are permitted provided that the following conditions
     11        1.1  augustss  * are met:
     12        1.1  augustss  * 1. Redistributions of source code must retain the above copyright
     13        1.1  augustss  *    notice, this list of conditions and the following disclaimer.
     14        1.1  augustss  * 2. Redistributions in binary form must reproduce the above copyright
     15        1.1  augustss  *    notice, this list of conditions and the following disclaimer in the
     16        1.1  augustss  *    documentation and/or other materials provided with the distribution.
     17        1.1  augustss  * 3. All advertising materials mentioning features or use of this software
     18        1.1  augustss  *    must display the following acknowledgement:
     19        1.1  augustss  *	This product includes software developed by Bill Paul.
     20        1.1  augustss  * 4. Neither the name of the author nor the names of any co-contributors
     21        1.1  augustss  *    may be used to endorse or promote products derived from this software
     22        1.1  augustss  *    without specific prior written permission.
     23        1.1  augustss  *
     24        1.1  augustss  * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
     25        1.1  augustss  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     26        1.1  augustss  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     27        1.1  augustss  * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul, THE VOICES IN HIS HEAD OR
     28        1.1  augustss  * THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     29        1.1  augustss  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     30        1.1  augustss  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     31        1.1  augustss  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     32        1.1  augustss  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     33        1.1  augustss  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
     34        1.1  augustss  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     35        1.1  augustss  */
     36        1.1  augustss 
     37        1.1  augustss /*
     38        1.1  augustss  * USB Communication Device Class (Ethernet Networking Control Model)
     39        1.1  augustss  * http://www.usb.org/developers/devclass_docs/usbcdc11.pdf
     40        1.1  augustss  *
     41        1.1  augustss  */
     42        1.1  augustss 
     43        1.1  augustss #include <sys/cdefs.h>
     44  1.12.10.1     itohy __KERNEL_RCSID(0, "$NetBSD: if_cdce.c,v 1.12.10.5 2007/06/13 04:29:22 itohy Exp $");
     45        1.1  augustss #include "bpfilter.h"
     46        1.1  augustss 
     47        1.1  augustss #include <sys/param.h>
     48        1.1  augustss #include <sys/systm.h>
     49        1.1  augustss #include <sys/sockio.h>
     50        1.1  augustss #include <sys/mbuf.h>
     51        1.1  augustss #include <sys/malloc.h>
     52        1.1  augustss #include <sys/kernel.h>
     53        1.1  augustss #include <sys/socket.h>
     54        1.1  augustss #include <sys/device.h>
     55        1.1  augustss #if defined(__OpenBSD__)
     56        1.1  augustss #include <sys/proc.h>
     57        1.1  augustss #endif
     58        1.1  augustss 
     59        1.1  augustss #if NRND > 0
     60        1.1  augustss #include <sys/rnd.h>
     61        1.1  augustss #endif
     62        1.1  augustss 
     63        1.1  augustss #include <net/if.h>
     64        1.1  augustss #if defined(__NetBSD__)
     65        1.1  augustss #include <net/if_arp.h>
     66        1.1  augustss #endif
     67        1.1  augustss #include <net/if_dl.h>
     68        1.1  augustss #include <net/if_media.h>
     69        1.1  augustss 
     70        1.1  augustss #define BPF_MTAP(ifp, m) bpf_mtap((ifp)->if_bpf, (m))
     71        1.1  augustss 
     72        1.1  augustss #if NBPFILTER > 0
     73        1.1  augustss #include <net/bpf.h>
     74        1.1  augustss #endif
     75        1.1  augustss 
     76        1.1  augustss #if defined(__NetBSD__)
     77        1.1  augustss #include <net/if_ether.h>
     78        1.1  augustss #ifdef INET
     79        1.1  augustss #include <netinet/in.h>
     80        1.1  augustss #include <netinet/if_inarp.h>
     81        1.1  augustss #endif
     82        1.1  augustss #endif /* defined(__NetBSD__) */
     83        1.1  augustss 
     84        1.1  augustss #if defined(__OpenBSD__)
     85        1.1  augustss #ifdef INET
     86        1.1  augustss #include <netinet/in.h>
     87        1.1  augustss #include <netinet/in_systm.h>
     88        1.1  augustss #include <netinet/in_var.h>
     89        1.1  augustss #include <netinet/ip.h>
     90        1.1  augustss #include <netinet/if_ether.h>
     91        1.1  augustss #endif
     92        1.1  augustss #endif /* defined(__OpenBSD__) */
     93        1.1  augustss 
     94        1.1  augustss 
     95        1.1  augustss #include <dev/usb/usb.h>
     96        1.1  augustss #include <dev/usb/usbdi.h>
     97        1.1  augustss #include <dev/usb/usbdi_util.h>
     98        1.1  augustss #include <dev/usb/usbdevs.h>
     99        1.1  augustss #include <dev/usb/usbcdc.h>
    100  1.12.10.4     itohy #include <dev/usb/usb_ethersubr.h>
    101        1.1  augustss 
    102        1.1  augustss #include <dev/usb/if_cdcereg.h>
    103        1.1  augustss 
    104        1.1  augustss Static int	 cdce_encap(struct cdce_softc *, struct mbuf *, int);
    105        1.1  augustss Static void	 cdce_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
    106        1.1  augustss Static void	 cdce_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
    107        1.1  augustss Static void	 cdce_start(struct ifnet *);
    108        1.1  augustss Static int	 cdce_ioctl(struct ifnet *, u_long, caddr_t);
    109  1.12.10.3     itohy Static int	 cdce_init(struct ifnet *);
    110        1.1  augustss Static void	 cdce_watchdog(struct ifnet *);
    111  1.12.10.3     itohy Static void	 cdce_stop(struct ifnet *, int);
    112  1.12.10.2     itohy Static uint32_t	 cdce_crc32(struct mbuf *);
    113        1.1  augustss 
    114        1.1  augustss Static const struct cdce_type cdce_devs[] = {
    115        1.1  augustss   {{ USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2501 }, CDCE_NO_UNION },
    116        1.1  augustss   {{ USB_VENDOR_SHARP, USB_PRODUCT_SHARP_SL5500 }, CDCE_ZAURUS },
    117        1.1  augustss   {{ USB_VENDOR_SHARP, USB_PRODUCT_SHARP_A300 }, CDCE_ZAURUS | CDCE_NO_UNION },
    118        1.1  augustss   {{ USB_VENDOR_SHARP, USB_PRODUCT_SHARP_SL5600 }, CDCE_ZAURUS | CDCE_NO_UNION },
    119        1.1  augustss   {{ USB_VENDOR_SHARP, USB_PRODUCT_SHARP_C700 }, CDCE_ZAURUS | CDCE_NO_UNION },
    120        1.1  augustss   {{ USB_VENDOR_SHARP, USB_PRODUCT_SHARP_C750 }, CDCE_ZAURUS | CDCE_NO_UNION },
    121        1.1  augustss };
    122        1.1  augustss #define cdce_lookup(v, p) ((const struct cdce_type *)usb_lookup(cdce_devs, v, p))
    123        1.1  augustss 
    124        1.1  augustss USB_DECLARE_DRIVER(cdce);
    125        1.1  augustss 
    126        1.1  augustss USB_MATCH(cdce)
    127        1.1  augustss {
    128        1.1  augustss 	USB_MATCH_START(cdce, uaa);
    129        1.1  augustss 	usb_interface_descriptor_t *id;
    130        1.1  augustss 
    131        1.1  augustss 	if (uaa->iface == NULL)
    132        1.1  augustss 		return (UMATCH_NONE);
    133        1.1  augustss 
    134        1.1  augustss 	id = usbd_get_interface_descriptor(uaa->iface);
    135        1.1  augustss 	if (id == NULL)
    136        1.1  augustss 		return (UMATCH_NONE);
    137        1.1  augustss 
    138        1.1  augustss 	if (cdce_lookup(uaa->vendor, uaa->product) != NULL)
    139        1.1  augustss 		return (UMATCH_VENDOR_PRODUCT);
    140        1.1  augustss 
    141        1.1  augustss 	if (id->bInterfaceClass == UICLASS_CDC && id->bInterfaceSubClass ==
    142        1.1  augustss 	    UISUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL)
    143        1.1  augustss 		return (UMATCH_IFACECLASS_GENERIC);
    144        1.1  augustss 
    145        1.1  augustss 	return (UMATCH_NONE);
    146        1.1  augustss }
    147        1.1  augustss 
    148        1.1  augustss USB_ATTACH(cdce)
    149        1.1  augustss {
    150        1.1  augustss 	USB_ATTACH_START(cdce, sc, uaa);
    151        1.6  augustss 	char				 *devinfop;
    152        1.1  augustss 	int				 s;
    153        1.1  augustss 	struct ifnet			*ifp;
    154        1.1  augustss 	usbd_device_handle		 dev = uaa->device;
    155        1.1  augustss 	const struct cdce_type		*t;
    156        1.1  augustss 	usb_interface_descriptor_t	*id;
    157        1.1  augustss 	usb_endpoint_descriptor_t	*ed;
    158        1.2  augustss 	const usb_cdc_union_descriptor_t *ud;
    159        1.1  augustss 	int				 data_ifcno;
    160        1.1  augustss 	int				 i;
    161        1.1  augustss 	u_char				 eaddr[ETHER_ADDR_LEN];
    162        1.2  augustss 	const usb_cdc_ethernet_descriptor_t *ue;
    163        1.5  augustss 	char				 eaddr_str[USB_MAX_ENCODED_STRING_LEN];
    164        1.1  augustss 
    165        1.6  augustss 	devinfop = usbd_devinfo_alloc(dev, 0);
    166        1.1  augustss 	USB_ATTACH_SETUP;
    167        1.6  augustss 	printf("%s: %s\n", USBDEVNAME(sc->cdce_dev), devinfop);
    168        1.6  augustss 	usbd_devinfo_free(devinfop);
    169        1.1  augustss 
    170        1.1  augustss 	sc->cdce_udev = uaa->device;
    171        1.1  augustss 	sc->cdce_ctl_iface = uaa->iface;
    172        1.1  augustss 
    173        1.1  augustss 	t = cdce_lookup(uaa->vendor, uaa->product);
    174        1.1  augustss 	if (t)
    175        1.1  augustss 		sc->cdce_flags = t->cdce_flags;
    176        1.1  augustss 
    177        1.1  augustss 	if (sc->cdce_flags & CDCE_NO_UNION)
    178        1.1  augustss 		sc->cdce_data_iface = sc->cdce_ctl_iface;
    179        1.1  augustss 	else {
    180        1.7  christos 		ud = (const usb_cdc_union_descriptor_t *)usb_find_desc(sc->cdce_udev,
    181        1.2  augustss 		    UDESC_CS_INTERFACE, UDESCSUB_CDC_UNION);
    182        1.1  augustss 		if (ud == NULL) {
    183        1.1  augustss 			printf("%s: no union descriptor\n",
    184        1.1  augustss 			    USBDEVNAME(sc->cdce_dev));
    185        1.1  augustss 			USB_ATTACH_ERROR_RETURN;
    186        1.1  augustss 		}
    187        1.1  augustss 		data_ifcno = ud->bSlaveInterface[0];
    188        1.1  augustss 
    189        1.1  augustss 		for (i = 0; i < uaa->nifaces; i++) {
    190        1.1  augustss 			if (uaa->ifaces[i] != NULL) {
    191        1.1  augustss 				id = usbd_get_interface_descriptor(
    192        1.1  augustss 				    uaa->ifaces[i]);
    193        1.1  augustss 				if (id != NULL && id->bInterfaceNumber ==
    194        1.1  augustss 				    data_ifcno) {
    195        1.1  augustss 					sc->cdce_data_iface = uaa->ifaces[i];
    196        1.1  augustss 					uaa->ifaces[i] = NULL;
    197        1.1  augustss 				}
    198        1.1  augustss 			}
    199        1.1  augustss 		}
    200        1.1  augustss 	}
    201        1.1  augustss 
    202        1.1  augustss 	if (sc->cdce_data_iface == NULL) {
    203        1.1  augustss 		printf("%s: no data interface\n", USBDEVNAME(sc->cdce_dev));
    204        1.1  augustss 		USB_ATTACH_ERROR_RETURN;
    205        1.1  augustss 	}
    206        1.1  augustss 
    207        1.1  augustss 	/* Find endpoints. */
    208        1.1  augustss 	id = usbd_get_interface_descriptor(sc->cdce_data_iface);
    209        1.1  augustss 	sc->cdce_bulkin_no = sc->cdce_bulkout_no = -1;
    210        1.1  augustss 	for (i = 0; i < id->bNumEndpoints; i++) {
    211        1.1  augustss 		ed = usbd_interface2endpoint_descriptor(sc->cdce_data_iface, i);
    212        1.1  augustss 		if (!ed) {
    213        1.1  augustss 			printf("%s: could not read endpoint descriptor\n",
    214        1.1  augustss 			    USBDEVNAME(sc->cdce_dev));
    215        1.1  augustss 			USB_ATTACH_ERROR_RETURN;
    216        1.1  augustss 		}
    217        1.1  augustss 		if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
    218        1.1  augustss 		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
    219        1.1  augustss 			sc->cdce_bulkin_no = ed->bEndpointAddress;
    220        1.1  augustss 		} else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
    221        1.1  augustss 		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
    222        1.1  augustss 			sc->cdce_bulkout_no = ed->bEndpointAddress;
    223        1.1  augustss 		} else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
    224        1.1  augustss 		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
    225        1.1  augustss 			/* XXX: CDC spec defines an interrupt pipe, but it is not
    226        1.1  augustss 			 * needed for simple host-to-host applications. */
    227        1.1  augustss 		} else {
    228        1.1  augustss 			printf("%s: unexpected endpoint\n",
    229        1.1  augustss 			    USBDEVNAME(sc->cdce_dev));
    230        1.1  augustss 		}
    231        1.1  augustss 	}
    232        1.1  augustss 
    233        1.1  augustss 	if (sc->cdce_bulkin_no == -1) {
    234        1.1  augustss 		printf("%s: could not find data bulk in\n",
    235        1.1  augustss 		    USBDEVNAME(sc->cdce_dev));
    236        1.1  augustss 		USB_ATTACH_ERROR_RETURN;
    237        1.1  augustss 	}
    238        1.1  augustss 	if (sc->cdce_bulkout_no == -1 ) {
    239        1.1  augustss 		printf("%s: could not find data bulk out\n",
    240        1.1  augustss 		    USBDEVNAME(sc->cdce_dev));
    241        1.1  augustss 		USB_ATTACH_ERROR_RETURN;
    242        1.1  augustss 	}
    243        1.1  augustss 
    244        1.7  christos 	ue = (const usb_cdc_ethernet_descriptor_t *)usb_find_desc(dev,
    245        1.2  augustss             UDESC_INTERFACE, UDESCSUB_CDC_ENF);
    246        1.2  augustss 	if (!ue || usbd_get_string(dev, ue->iMacAddress, eaddr_str)) {
    247        1.2  augustss 		printf("%s: faking address\n", USBDEVNAME(sc->cdce_dev));
    248        1.2  augustss 		eaddr[0]= 0x2a;
    249        1.2  augustss 		memcpy(&eaddr[1], &hardclock_ticks, sizeof(u_int32_t));
    250        1.9   thorpej 		eaddr[5] = (u_int8_t)(device_unit(&sc->cdce_dev));
    251        1.2  augustss 	} else {
    252        1.7  christos 		int j;
    253        1.2  augustss 
    254        1.2  augustss 		memset(eaddr, 0, ETHER_ADDR_LEN);
    255        1.7  christos 		for (j = 0; j < ETHER_ADDR_LEN * 2; j++) {
    256        1.7  christos 			int c = eaddr_str[j];
    257        1.2  augustss 
    258        1.2  augustss 			if ('0' <= c && c <= '9')
    259        1.2  augustss 				c -= '0';
    260        1.2  augustss 			else
    261        1.3  augustss 				c -= 'A' - 10;
    262        1.2  augustss 			c &= 0xf;
    263        1.2  augustss 			if (c%2 == 0)
    264        1.2  augustss 				c <<= 4;
    265        1.7  christos 			eaddr[j / 2] |= c;
    266        1.2  augustss 		}
    267        1.2  augustss 	}
    268        1.2  augustss 
    269        1.1  augustss 	s = splnet();
    270        1.1  augustss 
    271        1.1  augustss 	printf("%s: address %s\n", USBDEVNAME(sc->cdce_dev),
    272        1.1  augustss 	    ether_sprintf(eaddr));
    273        1.1  augustss 
    274        1.1  augustss 	ifp = GET_IFP(sc);
    275        1.1  augustss 	ifp->if_softc = sc;
    276        1.1  augustss 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
    277        1.1  augustss 	ifp->if_ioctl = cdce_ioctl;
    278        1.1  augustss 	ifp->if_start = cdce_start;
    279  1.12.10.3     itohy 	ifp->if_init = cdce_init;
    280  1.12.10.3     itohy 	ifp->if_stop = cdce_stop;
    281  1.12.10.4     itohy 	ifp->if_watchdog = cdce_watchdog;
    282        1.1  augustss 	strncpy(ifp->if_xname, USBDEVNAME(sc->cdce_dev), IFNAMSIZ);
    283        1.1  augustss 
    284        1.1  augustss 	IFQ_SET_READY(&ifp->if_snd);
    285        1.1  augustss 
    286        1.1  augustss 	if_attach(ifp);
    287        1.1  augustss 	Ether_ifattach(ifp, eaddr);
    288        1.1  augustss 
    289        1.1  augustss 	sc->cdce_attached = 1;
    290        1.1  augustss 	splx(s);
    291        1.1  augustss 
    292        1.1  augustss 	usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->cdce_udev,
    293        1.1  augustss 	    USBDEV(sc->cdce_dev));
    294        1.1  augustss 
    295        1.1  augustss 	USB_ATTACH_SUCCESS_RETURN;
    296        1.1  augustss }
    297        1.1  augustss 
    298        1.1  augustss USB_DETACH(cdce)
    299        1.1  augustss {
    300        1.1  augustss 	USB_DETACH_START(cdce, sc);
    301        1.1  augustss 	struct ifnet	*ifp = GET_IFP(sc);
    302        1.1  augustss 	int		 s;
    303        1.1  augustss 
    304        1.1  augustss 	s = splusb();
    305        1.1  augustss 
    306        1.1  augustss 	if (!sc->cdce_attached) {
    307        1.1  augustss 		splx(s);
    308        1.1  augustss 		return (0);
    309        1.1  augustss 	}
    310        1.1  augustss 
    311        1.1  augustss 	if (ifp->if_flags & IFF_RUNNING)
    312  1.12.10.3     itohy 		cdce_stop(ifp, 1);
    313        1.1  augustss 
    314        1.1  augustss 	ether_ifdetach(ifp);
    315        1.1  augustss 
    316        1.1  augustss 	if_detach(ifp);
    317        1.1  augustss 
    318        1.1  augustss 	sc->cdce_attached = 0;
    319        1.1  augustss 	splx(s);
    320        1.1  augustss 
    321        1.1  augustss 	return (0);
    322        1.1  augustss }
    323        1.1  augustss 
    324        1.1  augustss Static void
    325        1.1  augustss cdce_start(struct ifnet *ifp)
    326        1.1  augustss {
    327        1.1  augustss 	struct cdce_softc	*sc = ifp->if_softc;
    328        1.1  augustss 	struct mbuf		*m_head = NULL;
    329        1.1  augustss 
    330        1.1  augustss 	if (sc->cdce_dying || (ifp->if_flags & IFF_OACTIVE))
    331        1.1  augustss 		return;
    332        1.1  augustss 
    333        1.1  augustss 	IFQ_POLL(&ifp->if_snd, m_head);
    334        1.1  augustss 	if (m_head == NULL)
    335        1.1  augustss 		return;
    336        1.1  augustss 
    337        1.1  augustss 	IFQ_DEQUEUE(&ifp->if_snd, m_head);
    338        1.1  augustss 
    339        1.1  augustss #if NBPFILTER > 0
    340        1.1  augustss 	if (ifp->if_bpf)
    341        1.1  augustss 		BPF_MTAP(ifp, m_head);
    342        1.1  augustss #endif
    343        1.1  augustss 
    344  1.12.10.4     itohy 	if (cdce_encap(sc, m_head, 0)) {
    345  1.12.10.4     itohy 		ifp->if_flags |= IFF_OACTIVE;
    346  1.12.10.4     itohy 		return;
    347  1.12.10.4     itohy 	}
    348  1.12.10.4     itohy 
    349        1.1  augustss 	ifp->if_flags |= IFF_OACTIVE;
    350        1.1  augustss 
    351        1.1  augustss 	ifp->if_timer = 6;
    352        1.1  augustss }
    353        1.1  augustss 
    354        1.1  augustss Static int
    355        1.1  augustss cdce_encap(struct cdce_softc *sc, struct mbuf *m, int idx)
    356        1.1  augustss {
    357  1.12.10.4     itohy 	struct ue_chain		*c;
    358        1.1  augustss 	usbd_status		 err;
    359  1.12.10.4     itohy 	int			 ret;
    360        1.1  augustss 
    361        1.1  augustss 	c = &sc->cdce_cdata.cdce_tx_chain[idx];
    362        1.1  augustss 
    363        1.1  augustss 	if (sc->cdce_flags & CDCE_ZAURUS) {
    364        1.1  augustss 		/* Zaurus wants a 32-bit CRC appended to every frame */
    365  1.12.10.2     itohy 		u_int32_t crc, crcle;
    366  1.12.10.5     itohy 		int len;
    367        1.1  augustss 
    368  1.12.10.2     itohy 		crc = cdce_crc32(m);
    369  1.12.10.2     itohy 		crcle = htole32(crc);
    370  1.12.10.5     itohy 		len = m->m_pkthdr.len + 4;
    371  1.12.10.2     itohy 		m_copyback(m, m->m_pkthdr.len, 4, &crcle);
    372  1.12.10.5     itohy 		if (m->m_pkthdr.len != len) {
    373  1.12.10.5     itohy 			m_freem(m);
    374  1.12.10.5     itohy 			return (ENOBUFS);
    375  1.12.10.5     itohy 		}
    376        1.1  augustss 	}
    377  1.12.10.2     itohy 
    378  1.12.10.4     itohy 	ret = usb_ether_map_tx_buffer_mbuf(c, m);
    379  1.12.10.4     itohy 	if (ret) {
    380  1.12.10.2     itohy 		m_freem(m);
    381  1.12.10.4     itohy 		return (ret);
    382  1.12.10.2     itohy 	}
    383        1.1  augustss 
    384  1.12.10.4     itohy 	usbd_setup_xfer(c->ue_xfer, sc->cdce_bulkout_pipe, c, NULL /* XXX buf */,
    385  1.12.10.2     itohy 	    m->m_pkthdr.len, USBD_NO_COPY, 10000, cdce_txeof);
    386  1.12.10.4     itohy 	err = usbd_transfer(c->ue_xfer);
    387        1.1  augustss 	if (err != USBD_IN_PROGRESS) {
    388  1.12.10.4     itohy 		c->ue_mbuf = NULL;
    389  1.12.10.4     itohy 		m_freem(m);
    390  1.12.10.3     itohy 		cdce_stop(GET_IFP(sc), 0);
    391        1.1  augustss 		return (EIO);
    392        1.1  augustss 	}
    393        1.1  augustss 
    394        1.1  augustss 	sc->cdce_cdata.cdce_tx_cnt++;
    395        1.1  augustss 
    396        1.1  augustss 	return (0);
    397        1.1  augustss }
    398        1.1  augustss 
    399        1.1  augustss Static void
    400  1.12.10.3     itohy cdce_stop(struct ifnet *ifp, int disable)
    401        1.1  augustss {
    402  1.12.10.3     itohy 	struct cdce_softc	*sc = ifp->if_softc;
    403        1.1  augustss 	usbd_status	 err;
    404        1.1  augustss 
    405        1.1  augustss 	ifp->if_timer = 0;
    406        1.1  augustss 
    407  1.12.10.2     itohy 	/* Stop transfers. */
    408        1.1  augustss 	if (sc->cdce_bulkin_pipe != NULL) {
    409        1.1  augustss 		err = usbd_abort_pipe(sc->cdce_bulkin_pipe);
    410        1.1  augustss 		if (err)
    411        1.1  augustss 			printf("%s: abort rx pipe failed: %s\n",
    412        1.1  augustss 			    USBDEVNAME(sc->cdce_dev), usbd_errstr(err));
    413        1.1  augustss 	}
    414        1.1  augustss 
    415        1.1  augustss 	if (sc->cdce_bulkout_pipe != NULL) {
    416        1.1  augustss 		err = usbd_abort_pipe(sc->cdce_bulkout_pipe);
    417        1.1  augustss 		if (err)
    418        1.1  augustss 			printf("%s: abort tx pipe failed: %s\n",
    419        1.1  augustss 			    USBDEVNAME(sc->cdce_dev), usbd_errstr(err));
    420        1.1  augustss 	}
    421        1.1  augustss 
    422  1.12.10.2     itohy 	/* Free RX/TX list resources. */
    423  1.12.10.4     itohy 	usb_ether_rx_list_free(sc->cdce_cdata.cdce_rx_chain, CDCE_RX_LIST_CNT);
    424  1.12.10.4     itohy 	usb_ether_tx_list_free(sc->cdce_cdata.cdce_tx_chain, CDCE_TX_LIST_CNT);
    425        1.1  augustss 
    426  1.12.10.2     itohy 	/* Close pipes. */
    427  1.12.10.2     itohy 	if (sc->cdce_bulkin_pipe != NULL) {
    428  1.12.10.2     itohy 		err = usbd_close_pipe(sc->cdce_bulkin_pipe);
    429  1.12.10.2     itohy 		if (err)
    430  1.12.10.2     itohy 			printf("%s: close rx pipe failed: %s\n",
    431  1.12.10.2     itohy 			    USBDEVNAME(sc->cdce_dev), usbd_errstr(err));
    432  1.12.10.2     itohy 		sc->cdce_bulkin_pipe = NULL;
    433  1.12.10.2     itohy 	}
    434  1.12.10.2     itohy 
    435  1.12.10.2     itohy 	if (sc->cdce_bulkout_pipe != NULL) {
    436  1.12.10.2     itohy 		err = usbd_close_pipe(sc->cdce_bulkout_pipe);
    437  1.12.10.2     itohy 		if (err)
    438  1.12.10.2     itohy 			printf("%s: close tx pipe failed: %s\n",
    439  1.12.10.2     itohy 			    USBDEVNAME(sc->cdce_dev), usbd_errstr(err));
    440  1.12.10.2     itohy 		sc->cdce_bulkout_pipe = NULL;
    441  1.12.10.2     itohy 	}
    442  1.12.10.2     itohy 
    443        1.1  augustss 	ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
    444        1.1  augustss }
    445        1.1  augustss 
    446        1.1  augustss Static int
    447        1.1  augustss cdce_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
    448        1.1  augustss {
    449        1.1  augustss 	struct cdce_softc	*sc = ifp->if_softc;
    450  1.12.10.3     itohy 	int			 s, error;
    451        1.1  augustss 
    452        1.1  augustss 	if (sc->cdce_dying)
    453        1.1  augustss 		return (EIO);
    454        1.1  augustss 
    455        1.1  augustss 	s = splnet();
    456        1.1  augustss 
    457        1.1  augustss 	switch(command) {
    458  1.12.10.3     itohy #if 0	/* no media support */
    459  1.12.10.3     itohy 	case SIOCGIFMEDIA:
    460  1.12.10.3     itohy 	case SIOCSIFMEDIA:
    461  1.12.10.3     itohy 		error = EINVAL;
    462        1.1  augustss 		break;
    463  1.12.10.3     itohy #endif
    464        1.1  augustss 
    465  1.12.10.3     itohy 	default:
    466  1.12.10.3     itohy 		error = ether_ioctl(ifp, command, data);
    467  1.12.10.3     itohy 		if (error == ENETRESET) {
    468  1.12.10.3     itohy #if 0	/* XXX not yet */
    469        1.1  augustss 			if (ifp->if_flags & IFF_RUNNING)
    470  1.12.10.3     itohy 				cdce_setmulti(sc);
    471  1.12.10.3     itohy #endif
    472  1.12.10.3     itohy 			error = 0;
    473        1.1  augustss 		}
    474        1.1  augustss 		break;
    475        1.1  augustss 	}
    476        1.1  augustss 
    477        1.1  augustss 	splx(s);
    478        1.1  augustss 
    479        1.1  augustss 	return (error);
    480        1.1  augustss }
    481        1.1  augustss 
    482        1.1  augustss Static void
    483        1.1  augustss cdce_watchdog(struct ifnet *ifp)
    484        1.1  augustss {
    485        1.1  augustss 	struct cdce_softc	*sc = ifp->if_softc;
    486        1.1  augustss 
    487        1.1  augustss 	if (sc->cdce_dying)
    488        1.1  augustss 		return;
    489        1.1  augustss 
    490        1.1  augustss 	ifp->if_oerrors++;
    491        1.1  augustss 	printf("%s: watchdog timeout\n", USBDEVNAME(sc->cdce_dev));
    492        1.1  augustss }
    493        1.1  augustss 
    494  1.12.10.3     itohy Static int
    495  1.12.10.3     itohy cdce_init(struct ifnet *ifp)
    496        1.1  augustss {
    497  1.12.10.3     itohy 	struct cdce_softc	*sc = ifp->if_softc;
    498  1.12.10.4     itohy 	struct ue_chain		*c;
    499        1.1  augustss 	usbd_status		 err;
    500        1.1  augustss 	int			 s, i;
    501        1.1  augustss 
    502        1.1  augustss 	if (ifp->if_flags & IFF_RUNNING)
    503  1.12.10.3     itohy 		return (EIO);
    504        1.1  augustss 
    505        1.1  augustss 	s = splnet();
    506        1.1  augustss 
    507        1.1  augustss 	err = usbd_open_pipe(sc->cdce_data_iface, sc->cdce_bulkin_no,
    508        1.1  augustss 	    USBD_EXCLUSIVE_USE, &sc->cdce_bulkin_pipe);
    509        1.1  augustss 	if (err) {
    510        1.1  augustss 		printf("%s: open rx pipe failed: %s\n", USBDEVNAME(sc->cdce_dev),
    511        1.1  augustss 		    usbd_errstr(err));
    512        1.1  augustss 		splx(s);
    513  1.12.10.3     itohy 		return (EIO);
    514        1.1  augustss 	}
    515        1.1  augustss 
    516        1.1  augustss 	err = usbd_open_pipe(sc->cdce_data_iface, sc->cdce_bulkout_no,
    517        1.1  augustss 	    USBD_EXCLUSIVE_USE, &sc->cdce_bulkout_pipe);
    518        1.1  augustss 	if (err) {
    519        1.1  augustss 		printf("%s: open tx pipe failed: %s\n", USBDEVNAME(sc->cdce_dev),
    520        1.1  augustss 		    usbd_errstr(err));
    521        1.1  augustss 		splx(s);
    522  1.12.10.3     itohy 		return (EIO);
    523        1.1  augustss 	}
    524        1.1  augustss 
    525  1.12.10.4     itohy 	if (usb_ether_tx_list_init(USBDEV(sc->cdce_dev),
    526  1.12.10.4     itohy 	    sc->cdce_cdata.cdce_tx_chain, CDCE_TX_LIST_CNT,
    527  1.12.10.4     itohy 	    sc->cdce_udev, sc->cdce_bulkout_pipe, NULL)) {
    528  1.12.10.2     itohy 		printf("%s: tx list init failed\n", USBDEVNAME(sc->cdce_dev));
    529  1.12.10.2     itohy 		splx(s);
    530  1.12.10.3     itohy 		return (EIO);
    531  1.12.10.2     itohy 	}
    532  1.12.10.2     itohy 
    533  1.12.10.4     itohy 	if (usb_ether_rx_list_init(USBDEV(sc->cdce_dev),
    534  1.12.10.4     itohy 	    sc->cdce_cdata.cdce_rx_chain, CDCE_RX_LIST_CNT,
    535  1.12.10.4     itohy 	    sc->cdce_udev, sc->cdce_bulkin_pipe)) {
    536  1.12.10.2     itohy 		printf("%s: rx list init failed\n", USBDEVNAME(sc->cdce_dev));
    537  1.12.10.2     itohy 		splx(s);
    538  1.12.10.3     itohy 		return (ENOMEM);
    539  1.12.10.2     itohy 	}
    540  1.12.10.2     itohy 
    541  1.12.10.2     itohy 	/* Maybe set multicast / broadcast here??? */
    542  1.12.10.2     itohy 
    543        1.1  augustss 	for (i = 0; i < CDCE_RX_LIST_CNT; i++) {
    544        1.1  augustss 		c = &sc->cdce_cdata.cdce_rx_chain[i];
    545  1.12.10.4     itohy 		(void)usbd_map_buffer_mbuf(c->ue_xfer, c->ue_mbuf);
    546  1.12.10.4     itohy 		usbd_setup_xfer(c->ue_xfer, sc->cdce_bulkin_pipe, c,
    547  1.12.10.2     itohy 		    NULL /* XXX buf */, CDCE_BUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY,
    548        1.1  augustss 		    USBD_NO_TIMEOUT, cdce_rxeof);
    549  1.12.10.4     itohy 		usbd_transfer(c->ue_xfer);
    550        1.1  augustss 	}
    551        1.1  augustss 
    552        1.1  augustss 	ifp->if_flags |= IFF_RUNNING;
    553        1.1  augustss 	ifp->if_flags &= ~IFF_OACTIVE;
    554        1.1  augustss 
    555        1.1  augustss 	splx(s);
    556  1.12.10.3     itohy 
    557  1.12.10.3     itohy 	return (0);
    558        1.1  augustss }
    559        1.1  augustss 
    560        1.1  augustss Static void
    561        1.1  augustss cdce_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
    562        1.1  augustss {
    563  1.12.10.4     itohy 	struct ue_chain		*c = priv;
    564  1.12.10.4     itohy 	struct cdce_softc	*sc = (void *)c->ue_dev;
    565        1.1  augustss 	struct ifnet		*ifp = GET_IFP(sc);
    566        1.1  augustss 	struct mbuf		*m;
    567        1.1  augustss 	int			 total_len = 0;
    568        1.1  augustss 	int			 s;
    569        1.1  augustss 
    570        1.1  augustss 	if (sc->cdce_dying || !(ifp->if_flags & IFF_RUNNING))
    571        1.1  augustss 		return;
    572        1.1  augustss 
    573  1.12.10.2     itohy 	usbd_unmap_buffer(xfer);
    574  1.12.10.2     itohy 
    575        1.1  augustss 	if (status != USBD_NORMAL_COMPLETION) {
    576        1.1  augustss 		if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
    577        1.1  augustss 			return;
    578        1.1  augustss 		if (sc->cdce_rxeof_errors == 0)
    579        1.1  augustss 			printf("%s: usb error on rx: %s\n",
    580        1.1  augustss 			    USBDEVNAME(sc->cdce_dev), usbd_errstr(status));
    581        1.1  augustss 		if (status == USBD_STALLED)
    582        1.8  augustss 			usbd_clear_endpoint_stall_async(sc->cdce_bulkin_pipe);
    583        1.1  augustss 		DELAY(sc->cdce_rxeof_errors * 10000);
    584        1.1  augustss 		sc->cdce_rxeof_errors++;
    585        1.1  augustss 		goto done;
    586        1.1  augustss 	}
    587        1.1  augustss 
    588        1.1  augustss 	sc->cdce_rxeof_errors = 0;
    589        1.1  augustss 
    590        1.1  augustss 	usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
    591        1.1  augustss 	if (sc->cdce_flags & CDCE_ZAURUS)
    592        1.1  augustss 		total_len -= 4;	/* Strip off CRC added by Zaurus */
    593  1.12.10.2     itohy 
    594  1.12.10.2     itohy 	if (total_len < sizeof(struct ether_header)) {
    595  1.12.10.2     itohy 		ifp->if_ierrors++;
    596        1.1  augustss 		goto done;
    597  1.12.10.2     itohy 	}
    598        1.1  augustss 
    599  1.12.10.4     itohy 	m = c->ue_mbuf;
    600        1.1  augustss 
    601  1.12.10.2     itohy 	/*
    602  1.12.10.2     itohy 	 * Allocate new mbuf cluster for the next transfer.
    603  1.12.10.2     itohy 	 * If that failed, discard current packet and recycle the mbuf.
    604  1.12.10.2     itohy 	 */
    605  1.12.10.4     itohy 	if ((c->ue_mbuf = usb_ether_newbuf(NULL)) == NULL) {
    606  1.12.10.4     itohy 		printf("%s: no memory for rx list -- packet dropped!\n",
    607  1.12.10.4     itohy 		    USBDEVNAME(sc->cdce_dev));
    608        1.1  augustss 		ifp->if_ierrors++;
    609  1.12.10.4     itohy 		c->ue_mbuf = usb_ether_newbuf(m);
    610        1.1  augustss 		goto done;
    611        1.1  augustss 	}
    612        1.1  augustss 
    613        1.1  augustss 	ifp->if_ipackets++;
    614        1.1  augustss 	m->m_pkthdr.len = m->m_len = total_len;
    615        1.1  augustss 	m->m_pkthdr.rcvif = ifp;
    616        1.1  augustss 
    617        1.1  augustss 	s = splnet();
    618        1.1  augustss 
    619        1.1  augustss #if NBPFILTER > 0
    620        1.1  augustss 	if (ifp->if_bpf)
    621        1.1  augustss 		BPF_MTAP(ifp, m);
    622        1.1  augustss #endif
    623        1.1  augustss 
    624        1.1  augustss 	IF_INPUT(ifp, m);
    625        1.1  augustss 
    626        1.1  augustss 	splx(s);
    627        1.1  augustss 
    628        1.1  augustss done:
    629        1.1  augustss 	/* Setup new transfer. */
    630  1.12.10.4     itohy 	(void)usbd_map_buffer_mbuf(c->ue_xfer, c->ue_mbuf);
    631  1.12.10.4     itohy 	usbd_setup_xfer(c->ue_xfer, sc->cdce_bulkin_pipe, c, NULL /* XXX buf */,
    632        1.1  augustss 	    CDCE_BUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY, USBD_NO_TIMEOUT,
    633        1.1  augustss 	    cdce_rxeof);
    634  1.12.10.4     itohy 	usbd_transfer(c->ue_xfer);
    635        1.1  augustss }
    636        1.1  augustss 
    637        1.1  augustss Static void
    638       1.12  christos cdce_txeof(usbd_xfer_handle xfer, usbd_private_handle priv,
    639       1.11  christos     usbd_status status)
    640        1.1  augustss {
    641  1.12.10.4     itohy 	struct ue_chain		*c = priv;
    642  1.12.10.4     itohy 	struct cdce_softc	*sc = (void *)c->ue_dev;
    643        1.1  augustss 	struct ifnet		*ifp = GET_IFP(sc);
    644        1.1  augustss 	usbd_status		 err;
    645        1.1  augustss 	int			 s;
    646        1.1  augustss 
    647        1.1  augustss 	if (sc->cdce_dying)
    648        1.1  augustss 		return;
    649        1.1  augustss 
    650  1.12.10.2     itohy 	usbd_unmap_buffer(xfer);
    651  1.12.10.2     itohy 
    652        1.1  augustss 	s = splnet();
    653        1.1  augustss 
    654        1.1  augustss 	ifp->if_timer = 0;
    655        1.1  augustss 	ifp->if_flags &= ~IFF_OACTIVE;
    656        1.1  augustss 
    657        1.1  augustss 	if (status != USBD_NORMAL_COMPLETION) {
    658        1.1  augustss 		if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
    659        1.1  augustss 			splx(s);
    660        1.1  augustss 			return;
    661        1.1  augustss 		}
    662        1.1  augustss 		ifp->if_oerrors++;
    663        1.1  augustss 		printf("%s: usb error on tx: %s\n", USBDEVNAME(sc->cdce_dev),
    664        1.1  augustss 		    usbd_errstr(status));
    665        1.1  augustss 		if (status == USBD_STALLED)
    666        1.8  augustss 			usbd_clear_endpoint_stall_async(sc->cdce_bulkout_pipe);
    667        1.1  augustss 		splx(s);
    668        1.1  augustss 		return;
    669        1.1  augustss 	}
    670        1.1  augustss 
    671  1.12.10.4     itohy 	usbd_get_xfer_status(c->ue_xfer, NULL, NULL, NULL, &err);
    672        1.1  augustss 
    673  1.12.10.4     itohy 	if (c->ue_mbuf != NULL) {
    674  1.12.10.4     itohy 		m_freem(c->ue_mbuf);
    675  1.12.10.4     itohy 		c->ue_mbuf = NULL;
    676        1.1  augustss 	}
    677        1.1  augustss 
    678        1.1  augustss 	if (err)
    679        1.1  augustss 		ifp->if_oerrors++;
    680        1.1  augustss 	else
    681        1.1  augustss 		ifp->if_opackets++;
    682        1.1  augustss 
    683        1.1  augustss 	if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
    684        1.1  augustss 		cdce_start(ifp);
    685        1.1  augustss 
    686        1.1  augustss 	splx(s);
    687        1.1  augustss }
    688        1.1  augustss 
    689        1.4  augustss int
    690        1.1  augustss cdce_activate(device_ptr_t self, enum devact act)
    691        1.1  augustss {
    692        1.1  augustss 	struct cdce_softc *sc = (struct cdce_softc *)self;
    693        1.1  augustss 
    694        1.1  augustss 	switch (act) {
    695        1.1  augustss 	case DVACT_ACTIVATE:
    696        1.1  augustss 		return (EOPNOTSUPP);
    697        1.1  augustss 		break;
    698        1.1  augustss 
    699        1.1  augustss 	case DVACT_DEACTIVATE:
    700        1.1  augustss 		if_deactivate(GET_IFP(sc));
    701        1.1  augustss 		sc->cdce_dying = 1;
    702        1.1  augustss 		break;
    703        1.1  augustss 	}
    704        1.1  augustss 	return (0);
    705        1.1  augustss }
    706        1.1  augustss 
    707        1.1  augustss 
    708        1.1  augustss /*  COPYRIGHT (C) 1986 Gary S. Brown.  You may use this program, or
    709        1.1  augustss  *  code or tables extracted from it, as desired without restriction.
    710        1.1  augustss  */
    711        1.1  augustss 
    712  1.12.10.2     itohy static const uint32_t cdce_crc32_tab[] = {
    713        1.1  augustss 	0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
    714        1.1  augustss 	0xe963a535, 0x9e6495a3,	0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
    715        1.1  augustss 	0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
    716        1.1  augustss 	0xf3b97148, 0x84be41de,	0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
    717        1.1  augustss 	0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,	0x14015c4f, 0x63066cd9,
    718        1.1  augustss 	0xfa0f3d63, 0x8d080df5,	0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
    719        1.1  augustss 	0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,	0x35b5a8fa, 0x42b2986c,
    720        1.1  augustss 	0xdbbbc9d6, 0xacbcf940,	0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
    721        1.1  augustss 	0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
    722        1.1  augustss 	0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
    723        1.1  augustss 	0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,	0x76dc4190, 0x01db7106,
    724        1.1  augustss 	0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
    725        1.1  augustss 	0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
    726        1.1  augustss 	0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
    727        1.1  augustss 	0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
    728        1.1  augustss 	0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
    729        1.1  augustss 	0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
    730        1.1  augustss 	0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
    731        1.1  augustss 	0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
    732        1.1  augustss 	0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
    733        1.1  augustss 	0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
    734        1.1  augustss 	0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
    735        1.1  augustss 	0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
    736        1.1  augustss 	0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
    737        1.1  augustss 	0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
    738        1.1  augustss 	0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
    739        1.1  augustss 	0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
    740        1.1  augustss 	0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
    741        1.1  augustss 	0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
    742        1.1  augustss 	0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
    743        1.1  augustss 	0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
    744        1.1  augustss 	0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
    745        1.1  augustss 	0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
    746        1.1  augustss 	0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
    747        1.1  augustss 	0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
    748        1.1  augustss 	0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
    749        1.1  augustss 	0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
    750        1.1  augustss 	0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
    751        1.1  augustss 	0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
    752        1.1  augustss 	0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
    753        1.1  augustss 	0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
    754        1.1  augustss 	0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
    755        1.1  augustss 	0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
    756        1.1  augustss };
    757        1.1  augustss 
    758        1.2  augustss Static uint32_t
    759  1.12.10.2     itohy cdce_crc32(struct mbuf *m)
    760        1.1  augustss {
    761        1.1  augustss 	const uint8_t *p;
    762        1.1  augustss 	uint32_t crc;
    763  1.12.10.2     itohy 	int len;
    764        1.1  augustss 
    765        1.1  augustss 	crc = ~0U;
    766        1.1  augustss 
    767  1.12.10.2     itohy 	for ( ; m; m = m->m_next) {
    768  1.12.10.2     itohy 		for (p = mtod(m, uint8_t *), len = m->m_len; len > 0; len--) {
    769  1.12.10.2     itohy 			crc = cdce_crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8);
    770  1.12.10.2     itohy 		}
    771  1.12.10.2     itohy 	}
    772        1.1  augustss 
    773        1.1  augustss 	return (crc ^ ~0U);
    774        1.1  augustss }
    775