if_cdce.c (187970) | if_cdce.c (188412) |
---|---|
1/* $NetBSD: if_cdce.c,v 1.4 2004/10/24 12:50:54 augustss Exp $ */ 2 3/*- 4 * Copyright (c) 1997, 1998, 1999, 2000-2003 Bill Paul <wpaul@windriver.com> 5 * Copyright (c) 2003-2005 Craig Boston 6 * Copyright (c) 2004 Daniel Hartmeier | 1/* $NetBSD: if_cdce.c,v 1.4 2004/10/24 12:50:54 augustss Exp $ */ 2 3/*- 4 * Copyright (c) 1997, 1998, 1999, 2000-2003 Bill Paul <wpaul@windriver.com> 5 * Copyright (c) 2003-2005 Craig Boston 6 * Copyright (c) 2004 Daniel Hartmeier |
7 * Copyright (c) 2009 Hans Petter Selasky |
|
7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright --- 20 unchanged lines hidden (view full) --- 35 */ 36 37/* 38 * USB Communication Device Class (Ethernet Networking Control Model) 39 * http://www.usb.org/developers/devclass_docs/usbcdc11.pdf 40 */ 41 42#include <sys/cdefs.h> | 8 * All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright --- 20 unchanged lines hidden (view full) --- 36 */ 37 38/* 39 * USB Communication Device Class (Ethernet Networking Control Model) 40 * http://www.usb.org/developers/devclass_docs/usbcdc11.pdf 41 */ 42 43#include <sys/cdefs.h> |
43__FBSDID("$FreeBSD: head/sys/dev/usb2/ethernet/if_cdce2.c 187970 2009-02-01 00:51:25Z thompsa $"); | 44__FBSDID("$FreeBSD: head/sys/dev/usb2/ethernet/if_cdce2.c 188412 2009-02-09 22:02:38Z thompsa $"); |
44 45#include <dev/usb2/include/usb2_devid.h> 46#include <dev/usb2/include/usb2_standard.h> 47#include <dev/usb2/include/usb2_mfunc.h> 48#include <dev/usb2/include/usb2_error.h> 49#include <dev/usb2/include/usb2_cdc.h> 50#include <dev/usb2/include/usb2_defs.h> 51 | 45 46#include <dev/usb2/include/usb2_devid.h> 47#include <dev/usb2/include/usb2_standard.h> 48#include <dev/usb2/include/usb2_mfunc.h> 49#include <dev/usb2/include/usb2_error.h> 50#include <dev/usb2/include/usb2_cdc.h> 51#include <dev/usb2/include/usb2_defs.h> 52 |
52#define usb2_config_td_cc usb2_ether_cc 53#define usb2_config_td_softc cdce_softc 54 | |
55#define USB_DEBUG_VAR cdce_debug 56 57#include <dev/usb2/core/usb2_core.h> 58#include <dev/usb2/core/usb2_lookup.h> 59#include <dev/usb2/core/usb2_process.h> | 53#define USB_DEBUG_VAR cdce_debug 54 55#include <dev/usb2/core/usb2_core.h> 56#include <dev/usb2/core/usb2_lookup.h> 57#include <dev/usb2/core/usb2_process.h> |
60#include <dev/usb2/core/usb2_config_td.h> | |
61#include <dev/usb2/core/usb2_debug.h> 62#include <dev/usb2/core/usb2_request.h> 63#include <dev/usb2/core/usb2_busdma.h> 64#include <dev/usb2/core/usb2_util.h> 65#include <dev/usb2/core/usb2_parse.h> 66#include <dev/usb2/core/usb2_device.h> 67 68#include <dev/usb2/ethernet/usb2_ethernet.h> --- 7 unchanged lines hidden (view full) --- 76static device_resume_t cdce_resume; 77static usb2_handle_request_t cdce_handle_request; 78 79static usb2_callback_t cdce_bulk_write_callback; 80static usb2_callback_t cdce_bulk_read_callback; 81static usb2_callback_t cdce_intr_read_callback; 82static usb2_callback_t cdce_intr_write_callback; 83 | 58#include <dev/usb2/core/usb2_debug.h> 59#include <dev/usb2/core/usb2_request.h> 60#include <dev/usb2/core/usb2_busdma.h> 61#include <dev/usb2/core/usb2_util.h> 62#include <dev/usb2/core/usb2_parse.h> 63#include <dev/usb2/core/usb2_device.h> 64 65#include <dev/usb2/ethernet/usb2_ethernet.h> --- 7 unchanged lines hidden (view full) --- 73static device_resume_t cdce_resume; 74static usb2_handle_request_t cdce_handle_request; 75 76static usb2_callback_t cdce_bulk_write_callback; 77static usb2_callback_t cdce_bulk_read_callback; 78static usb2_callback_t cdce_intr_read_callback; 79static usb2_callback_t cdce_intr_write_callback; 80 |
84static void cdce_start_cb(struct ifnet *); 85static void cdce_start_transfers(struct cdce_softc *); | 81static usb2_ether_fn_t cdce_attach_post; 82static usb2_ether_fn_t cdce_init; 83static usb2_ether_fn_t cdce_stop; 84static usb2_ether_fn_t cdce_start; 85static usb2_ether_fn_t cdce_setmulti; 86static usb2_ether_fn_t cdce_setpromisc; 87 |
86static uint32_t cdce_m_crc32(struct mbuf *, uint32_t, uint32_t); | 88static uint32_t cdce_m_crc32(struct mbuf *, uint32_t, uint32_t); |
87static void cdce_stop(struct cdce_softc *); 88static int cdce_ioctl_cb(struct ifnet *, u_long, caddr_t); 89static void cdce_init_cb(void *); 90static int cdce_ifmedia_upd_cb(struct ifnet *); 91static void cdce_ifmedia_sts_cb(struct ifnet *, struct ifmediareq *); | |
92 93#if USB_DEBUG 94static int cdce_debug = 0; | 89 90#if USB_DEBUG 91static int cdce_debug = 0; |
95static int cdce_force_512x4 = 0; | |
96 | 92 |
97SYSCTL_NODE(_hw_usb2, OID_AUTO, cdce, CTLFLAG_RW, 0, "USB cdce"); | 93SYSCTL_NODE(_hw_usb2, OID_AUTO, cdce, CTLFLAG_RW, 0, "USB CDC-Ethernet"); |
98SYSCTL_INT(_hw_usb2_cdce, OID_AUTO, debug, CTLFLAG_RW, &cdce_debug, 0, | 94SYSCTL_INT(_hw_usb2_cdce, OID_AUTO, debug, CTLFLAG_RW, &cdce_debug, 0, |
99 "cdce debug level"); 100SYSCTL_INT(_hw_usb2_cdce, OID_AUTO, force_512x4, CTLFLAG_RW, 101 &cdce_force_512x4, 0, "cdce force 512x4 protocol"); | 95 "Debug level"); |
102#endif 103 104static const struct usb2_config cdce_config[CDCE_N_TRANSFER] = { 105 106 [CDCE_BULK_A] = { 107 .type = UE_BULK, 108 .endpoint = UE_ADDR_ANY, 109 .direction = UE_DIR_OUT, 110 .if_index = 0, 111 /* Host Mode */ | 96#endif 97 98static const struct usb2_config cdce_config[CDCE_N_TRANSFER] = { 99 100 [CDCE_BULK_A] = { 101 .type = UE_BULK, 102 .endpoint = UE_ADDR_ANY, 103 .direction = UE_DIR_OUT, 104 .if_index = 0, 105 /* Host Mode */ |
112 .mh.frames = CDCE_512X4_FRAGS_MAX + 1, 113 .mh.bufsize = (CDCE_512X4_FRAMES_MAX * MCLBYTES) + sizeof(struct usb2_cdc_mf_eth_512x4_header), | 106 .mh.frames = CDCE_FRAMES_MAX, 107 .mh.bufsize = (CDCE_FRAMES_MAX * MCLBYTES), |
114 .mh.flags = {.pipe_bof = 1,.force_short_xfer = 1,.ext_buffer = 1,}, | 108 .mh.flags = {.pipe_bof = 1,.force_short_xfer = 1,.ext_buffer = 1,}, |
115 .mh.callback = &cdce_bulk_write_callback, | 109 .mh.callback = cdce_bulk_write_callback, |
116 .mh.timeout = 10000, /* 10 seconds */ 117 /* Device Mode */ | 110 .mh.timeout = 10000, /* 10 seconds */ 111 /* Device Mode */ |
118 .md.frames = CDCE_512X4_FRAGS_MAX + 1, 119 .md.bufsize = (CDCE_512X4_FRAMES_MAX * MCLBYTES) + sizeof(struct usb2_cdc_mf_eth_512x4_header), 120 .md.flags = {.pipe_bof = 1,.short_xfer_ok = 1,.ext_buffer = 1,}, 121 .md.callback = &cdce_bulk_read_callback, | 112 .md.frames = CDCE_FRAMES_MAX, 113 .md.bufsize = (CDCE_FRAMES_MAX * MCLBYTES), 114 .md.flags = {.pipe_bof = 1,.short_frames_ok = 1,.short_xfer_ok = 1,.ext_buffer = 1,}, 115 .md.callback = cdce_bulk_read_callback, |
122 .md.timeout = 0, /* no timeout */ 123 }, 124 125 [CDCE_BULK_B] = { 126 .type = UE_BULK, 127 .endpoint = UE_ADDR_ANY, 128 .direction = UE_DIR_IN, 129 .if_index = 0, 130 /* Host Mode */ | 116 .md.timeout = 0, /* no timeout */ 117 }, 118 119 [CDCE_BULK_B] = { 120 .type = UE_BULK, 121 .endpoint = UE_ADDR_ANY, 122 .direction = UE_DIR_IN, 123 .if_index = 0, 124 /* Host Mode */ |
131 .mh.frames = CDCE_512X4_FRAGS_MAX + 1, 132 .mh.bufsize = (CDCE_512X4_FRAMES_MAX * MCLBYTES) + sizeof(struct usb2_cdc_mf_eth_512x4_header), 133 .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,.ext_buffer = 1,}, 134 .mh.callback = &cdce_bulk_read_callback, | 125 .mh.frames = CDCE_FRAMES_MAX, 126 .mh.bufsize = (CDCE_FRAMES_MAX * MCLBYTES), 127 .mh.flags = {.pipe_bof = 1,.short_frames_ok = 1,.short_xfer_ok = 1,.ext_buffer = 1,}, 128 .mh.callback = cdce_bulk_read_callback, |
135 .mh.timeout = 0, /* no timeout */ 136 /* Device Mode */ | 129 .mh.timeout = 0, /* no timeout */ 130 /* Device Mode */ |
137 .md.frames = CDCE_512X4_FRAGS_MAX + 1, 138 .md.bufsize = (CDCE_512X4_FRAMES_MAX * MCLBYTES) + sizeof(struct usb2_cdc_mf_eth_512x4_header), | 131 .md.frames = CDCE_FRAMES_MAX, 132 .md.bufsize = (CDCE_FRAMES_MAX * MCLBYTES), |
139 .md.flags = {.pipe_bof = 1,.force_short_xfer = 1,.ext_buffer = 1,}, | 133 .md.flags = {.pipe_bof = 1,.force_short_xfer = 1,.ext_buffer = 1,}, |
140 .md.callback = &cdce_bulk_write_callback, | 134 .md.callback = cdce_bulk_write_callback, |
141 .md.timeout = 10000, /* 10 seconds */ 142 }, 143 144 [CDCE_INTR] = { 145 .type = UE_INTERRUPT, 146 .endpoint = UE_ADDR_ANY, 147 .direction = UE_DIR_IN, 148 .if_index = 1, 149 /* Host Mode */ 150 .mh.bufsize = CDCE_IND_SIZE_MAX, 151 .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,.no_pipe_ok = 1,}, | 135 .md.timeout = 10000, /* 10 seconds */ 136 }, 137 138 [CDCE_INTR] = { 139 .type = UE_INTERRUPT, 140 .endpoint = UE_ADDR_ANY, 141 .direction = UE_DIR_IN, 142 .if_index = 1, 143 /* Host Mode */ 144 .mh.bufsize = CDCE_IND_SIZE_MAX, 145 .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,.no_pipe_ok = 1,}, |
152 .mh.callback = &cdce_intr_read_callback, | 146 .mh.callback = cdce_intr_read_callback, |
153 .mh.timeout = 0, 154 /* Device Mode */ 155 .md.bufsize = CDCE_IND_SIZE_MAX, 156 .md.flags = {.pipe_bof = 1,.force_short_xfer = 1,.no_pipe_ok = 1,}, | 147 .mh.timeout = 0, 148 /* Device Mode */ 149 .md.bufsize = CDCE_IND_SIZE_MAX, 150 .md.flags = {.pipe_bof = 1,.force_short_xfer = 1,.no_pipe_ok = 1,}, |
157 .md.callback = &cdce_intr_write_callback, | 151 .md.callback = cdce_intr_write_callback, |
158 .md.timeout = 10000, /* 10 seconds */ 159 }, 160}; 161 162static device_method_t cdce_methods[] = { 163 /* USB interface */ 164 DEVMETHOD(usb2_handle_request, cdce_handle_request), 165 --- 17 unchanged lines hidden (view full) --- 183static devclass_t cdce_devclass; 184 185DRIVER_MODULE(cdce, ushub, cdce_driver, cdce_devclass, NULL, 0); 186MODULE_VERSION(cdce, 1); 187MODULE_DEPEND(cdce, usb2_ethernet, 1, 1, 1); 188MODULE_DEPEND(cdce, usb2_core, 1, 1, 1); 189MODULE_DEPEND(cdce, ether, 1, 1, 1); 190 | 152 .md.timeout = 10000, /* 10 seconds */ 153 }, 154}; 155 156static device_method_t cdce_methods[] = { 157 /* USB interface */ 158 DEVMETHOD(usb2_handle_request, cdce_handle_request), 159 --- 17 unchanged lines hidden (view full) --- 177static devclass_t cdce_devclass; 178 179DRIVER_MODULE(cdce, ushub, cdce_driver, cdce_devclass, NULL, 0); 180MODULE_VERSION(cdce, 1); 181MODULE_DEPEND(cdce, usb2_ethernet, 1, 1, 1); 182MODULE_DEPEND(cdce, usb2_core, 1, 1, 1); 183MODULE_DEPEND(cdce, ether, 1, 1, 1); 184 |
185static const struct usb2_ether_methods cdce_ue_methods = { 186 .ue_attach_post = cdce_attach_post, 187 .ue_start = cdce_start, 188 .ue_init = cdce_init, 189 .ue_stop = cdce_stop, 190 .ue_setmulti = cdce_setmulti, 191 .ue_setpromisc = cdce_setpromisc, 192}; 193 |
|
191static const struct usb2_device_id cdce_devs[] = { 192 {USB_IF_CSI(UICLASS_CDC, UISUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL, 0)}, 193 {USB_IF_CSI(UICLASS_CDC, UISUBCLASS_MOBILE_DIRECT_LINE_MODEL, 0)}, 194 195 {USB_VPI(USB_VENDOR_ACERLABS, USB_PRODUCT_ACERLABS_M5632, CDCE_FLAG_NO_UNION)}, 196 {USB_VPI(USB_VENDOR_AMBIT, USB_PRODUCT_AMBIT_NTL_250, CDCE_FLAG_NO_UNION)}, 197 {USB_VPI(USB_VENDOR_COMPAQ, USB_PRODUCT_COMPAQ_IPAQLINUX, CDCE_FLAG_NO_UNION)}, 198 {USB_VPI(USB_VENDOR_GMATE, USB_PRODUCT_GMATE_YP3X00, CDCE_FLAG_NO_UNION)}, --- 11 unchanged lines hidden (view full) --- 210static int 211cdce_probe(device_t dev) 212{ 213 struct usb2_attach_arg *uaa = device_get_ivars(dev); 214 215 return (usb2_lookup_id_by_uaa(cdce_devs, sizeof(cdce_devs), uaa)); 216} 217 | 194static const struct usb2_device_id cdce_devs[] = { 195 {USB_IF_CSI(UICLASS_CDC, UISUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL, 0)}, 196 {USB_IF_CSI(UICLASS_CDC, UISUBCLASS_MOBILE_DIRECT_LINE_MODEL, 0)}, 197 198 {USB_VPI(USB_VENDOR_ACERLABS, USB_PRODUCT_ACERLABS_M5632, CDCE_FLAG_NO_UNION)}, 199 {USB_VPI(USB_VENDOR_AMBIT, USB_PRODUCT_AMBIT_NTL_250, CDCE_FLAG_NO_UNION)}, 200 {USB_VPI(USB_VENDOR_COMPAQ, USB_PRODUCT_COMPAQ_IPAQLINUX, CDCE_FLAG_NO_UNION)}, 201 {USB_VPI(USB_VENDOR_GMATE, USB_PRODUCT_GMATE_YP3X00, CDCE_FLAG_NO_UNION)}, --- 11 unchanged lines hidden (view full) --- 213static int 214cdce_probe(device_t dev) 215{ 216 struct usb2_attach_arg *uaa = device_get_ivars(dev); 217 218 return (usb2_lookup_id_by_uaa(cdce_devs, sizeof(cdce_devs), uaa)); 219} 220 |
221static void 222cdce_attach_post(struct usb2_ether *ue) 223{ 224 /* no-op */ 225 return; 226} 227 |
|
218static int 219cdce_attach(device_t dev) 220{ 221 struct cdce_softc *sc = device_get_softc(dev); | 228static int 229cdce_attach(device_t dev) 230{ 231 struct cdce_softc *sc = device_get_softc(dev); |
232 struct usb2_ether *ue = &sc->sc_ue; |
|
222 struct usb2_attach_arg *uaa = device_get_ivars(dev); 223 struct usb2_interface *iface; 224 const struct usb2_cdc_union_descriptor *ud; | 233 struct usb2_attach_arg *uaa = device_get_ivars(dev); 234 struct usb2_interface *iface; 235 const struct usb2_cdc_union_descriptor *ud; |
225 const struct usb2_cdc_ethernet_descriptor *ue; | |
226 const struct usb2_interface_descriptor *id; | 236 const struct usb2_interface_descriptor *id; |
227 struct ifnet *ifp; | 237 const struct usb2_cdc_ethernet_descriptor *ued; |
228 int error; | 238 int error; |
229 uint8_t alt_index; | |
230 uint8_t i; | 239 uint8_t i; |
231 uint8_t eaddr[ETHER_ADDR_LEN]; | |
232 char eaddr_str[5 * ETHER_ADDR_LEN]; /* approx */ 233 | 240 char eaddr_str[5 * ETHER_ADDR_LEN]; /* approx */ 241 |
234 sc->sc_udev = uaa->device; 235 sc->sc_dev = dev; 236 sc->sc_unit = device_get_unit(dev); | |
237 sc->sc_flags = USB_GET_DRIVER_INFO(uaa); 238 | 242 sc->sc_flags = USB_GET_DRIVER_INFO(uaa); 243 |
239 /* search for alternate settings */ 240 if (uaa->usb2_mode == USB_MODE_HOST) { 241 242 struct usb2_descriptor *desc; 243 struct usb2_config_descriptor *cd; 244 245 cd = usb2_get_config_descriptor(uaa->device); 246 desc = (void *)(uaa->iface->idesc); 247 id = (void *)desc; 248 i = id->bInterfaceNumber; 249 alt_index = 0; 250 while ((desc = usb2_desc_foreach(cd, desc))) { 251 id = (void *)desc; 252 if ((id->bDescriptorType == UDESC_INTERFACE) && 253 (id->bLength >= sizeof(*id))) { 254 if (id->bInterfaceNumber != i) { 255 alt_index = 0; 256 break; 257 } 258 if ((id->bInterfaceClass == UICLASS_CDC) && 259 (id->bInterfaceSubClass == 260 UISUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL) && 261 (id->bInterfaceProtocol == UIPROTO_CDC_ETH_512X4)) { 262 263 alt_index = id->bAlternateSetting; 264 /* 265 * We want this alt setting hence 266 * the protocol supports multi 267 * sub-framing ! 268 */ 269 break; 270 } 271 } 272 } 273 274 if (alt_index > 0) { 275 276 error = usb2_set_alt_interface_index(uaa->device, 277 uaa->info.bIfaceIndex, alt_index); 278 if (error) { 279 device_printf(dev, "Could not set alternate " 280 "setting, error = %s\n", usb2_errstr(error)); 281 return (EINVAL); 282 } 283 } 284 } 285 /* get the interface subclass we are using */ 286 sc->sc_iface_protocol = uaa->iface->idesc->bInterfaceProtocol; 287#if USB_DEBUG 288 if (cdce_force_512x4) { 289 sc->sc_iface_protocol = UIPROTO_CDC_ETH_512X4; 290 } 291#endif | |
292 device_set_usb2_desc(dev); 293 | 244 device_set_usb2_desc(dev); 245 |
294 snprintf(sc->sc_name, sizeof(sc->sc_name), "%s", 295 device_get_nameunit(dev)); | 246 mtx_init(&sc->sc_mtx, device_get_nameunit(dev), NULL, MTX_DEF); |
296 | 247 |
297 mtx_init(&sc->sc_mtx, "cdce lock", NULL, MTX_DEF | MTX_RECURSE); 298 | |
299 if (sc->sc_flags & CDCE_FLAG_NO_UNION) { 300 sc->sc_ifaces_index[0] = uaa->info.bIfaceIndex; 301 sc->sc_ifaces_index[1] = uaa->info.bIfaceIndex; 302 sc->sc_data_iface_no = 0; /* not used */ 303 goto alloc_transfers; 304 } 305 ud = usb2_find_descriptor 306 (uaa->device, NULL, uaa->info.bIfaceIndex, --- 46 unchanged lines hidden (view full) --- 353 * Some devices, most notably cable modems, include interface 354 * settings that have no IN or OUT endpoint, therefore loop 355 * through the list of all available interface settings 356 * looking for one with both IN and OUT endpoints. 357 */ 358 359alloc_transfers: 360 | 248 if (sc->sc_flags & CDCE_FLAG_NO_UNION) { 249 sc->sc_ifaces_index[0] = uaa->info.bIfaceIndex; 250 sc->sc_ifaces_index[1] = uaa->info.bIfaceIndex; 251 sc->sc_data_iface_no = 0; /* not used */ 252 goto alloc_transfers; 253 } 254 ud = usb2_find_descriptor 255 (uaa->device, NULL, uaa->info.bIfaceIndex, --- 46 unchanged lines hidden (view full) --- 302 * Some devices, most notably cable modems, include interface 303 * settings that have no IN or OUT endpoint, therefore loop 304 * through the list of all available interface settings 305 * looking for one with both IN and OUT endpoints. 306 */ 307 308alloc_transfers: 309 |
361 for (i = 0; i < 32; i++) { | 310 for (i = 0; i != 32; i++) { |
362 363 error = usb2_set_alt_interface_index 364 (uaa->device, sc->sc_ifaces_index[0], i); 365 366 if (error) { 367 device_printf(dev, "no valid alternate " 368 "setting found!\n"); 369 goto detach; 370 } 371 error = usb2_transfer_setup 372 (uaa->device, sc->sc_ifaces_index, 373 sc->sc_xfer, cdce_config, CDCE_N_TRANSFER, 374 sc, &sc->sc_mtx); 375 376 if (error == 0) { 377 break; 378 } 379 } 380 | 311 312 error = usb2_set_alt_interface_index 313 (uaa->device, sc->sc_ifaces_index[0], i); 314 315 if (error) { 316 device_printf(dev, "no valid alternate " 317 "setting found!\n"); 318 goto detach; 319 } 320 error = usb2_transfer_setup 321 (uaa->device, sc->sc_ifaces_index, 322 sc->sc_xfer, cdce_config, CDCE_N_TRANSFER, 323 sc, &sc->sc_mtx); 324 325 if (error == 0) { 326 break; 327 } 328 } 329 |
381 ifmedia_init(&sc->sc_ifmedia, 0, 382 &cdce_ifmedia_upd_cb, 383 &cdce_ifmedia_sts_cb); 384 385 ue = usb2_find_descriptor | 330 ued = usb2_find_descriptor |
386 (uaa->device, NULL, uaa->info.bIfaceIndex, 387 UDESC_CS_INTERFACE, 0 - 1, UDESCSUB_CDC_ENF, 0 - 1); 388 | 331 (uaa->device, NULL, uaa->info.bIfaceIndex, 332 UDESC_CS_INTERFACE, 0 - 1, UDESCSUB_CDC_ENF, 0 - 1); 333 |
389 if ((ue == NULL) || (ue->bLength < sizeof(*ue))) { | 334 if ((ued == NULL) || (ued->bLength < sizeof(*ued))) { |
390 error = USB_ERR_INVAL; 391 } else { | 335 error = USB_ERR_INVAL; 336 } else { |
392 error = usb2_req_get_string_any 393 (uaa->device, &Giant, eaddr_str, 394 sizeof(eaddr_str), ue->iMacAddress); | 337 error = usb2_req_get_string_any(uaa->device, NULL, 338 eaddr_str, sizeof(eaddr_str), ued->iMacAddress); |
395 } 396 397 if (error) { 398 399 /* fake MAC address */ 400 401 device_printf(dev, "faking MAC address\n"); | 339 } 340 341 if (error) { 342 343 /* fake MAC address */ 344 345 device_printf(dev, "faking MAC address\n"); |
402 eaddr[0] = 0x2a; 403 memcpy(&eaddr[1], &ticks, sizeof(uint32_t)); 404 eaddr[5] = sc->sc_unit; | 346 sc->sc_ue.ue_eaddr[0] = 0x2a; 347 memcpy(&sc->sc_ue.ue_eaddr[1], &ticks, sizeof(uint32_t)); 348 sc->sc_ue.ue_eaddr[5] = device_get_unit(dev); |
405 406 } else { 407 | 349 350 } else { 351 |
408 bzero(eaddr, sizeof(eaddr)); | 352 bzero(sc->sc_ue.ue_eaddr, sizeof(sc->sc_ue.ue_eaddr)); |
409 | 353 |
410 for (i = 0; i < (ETHER_ADDR_LEN * 2); i++) { | 354 for (i = 0; i != (ETHER_ADDR_LEN * 2); i++) { |
411 412 char c = eaddr_str[i]; 413 | 355 356 char c = eaddr_str[i]; 357 |
414 if ((c >= '0') && (c <= '9')) { | 358 if ('0' <= c && c <= '9') |
415 c -= '0'; | 359 c -= '0'; |
416 } else if (c != 0) { | 360 else if (c != 0) |
417 c -= 'A' - 10; | 361 c -= 'A' - 10; |
418 } else { | 362 else |
419 break; | 363 break; |
420 } | |
421 422 c &= 0xf; 423 | 364 365 c &= 0xf; 366 |
424 if ((i & 1) == 0) { | 367 if ((i & 1) == 0) |
425 c <<= 4; | 368 c <<= 4; |
426 } 427 eaddr[i / 2] |= c; | 369 sc->sc_ue.ue_eaddr[i / 2] |= c; |
428 } 429 430 if (uaa->usb2_mode == USB_MODE_DEVICE) { 431 /* 432 * Do not use the same MAC address like the peer ! 433 */ | 370 } 371 372 if (uaa->usb2_mode == USB_MODE_DEVICE) { 373 /* 374 * Do not use the same MAC address like the peer ! 375 */ |
434 eaddr[5] ^= 0xFF; | 376 sc->sc_ue.ue_eaddr[5] ^= 0xFF; |
435 } 436 } 437 | 377 } 378 } 379 |
438 ifp = if_alloc(IFT_ETHER); | 380 ue->ue_sc = sc; 381 ue->ue_dev = dev; 382 ue->ue_udev = uaa->device; 383 ue->ue_mtx = &sc->sc_mtx; 384 ue->ue_methods = &cdce_ue_methods; |
439 | 385 |
440 if (ifp == NULL) { 441 device_printf(dev, "cannot if_alloc()\n"); | 386 error = usb2_ether_ifattach(ue); 387 if (error) { 388 device_printf(dev, "could not attach interface\n"); |
442 goto detach; 443 } | 389 goto detach; 390 } |
444 445 ifp->if_softc = sc; 446 if_initname(ifp, "cdce", sc->sc_unit); 447 ifp->if_mtu = ETHERMTU; 448 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 449 ifp->if_ioctl = cdce_ioctl_cb; 450 ifp->if_output = ether_output; 451 ifp->if_start = cdce_start_cb; 452 ifp->if_init = cdce_init_cb; 453 ifp->if_baudrate = 11000000; 454 if (sc->sc_iface_protocol == UIPROTO_CDC_ETH_512X4) { 455 IFQ_SET_MAXLEN(&ifp->if_snd, CDCE_512X4_IFQ_MAXLEN); 456 ifp->if_snd.ifq_drv_maxlen = CDCE_512X4_IFQ_MAXLEN; 457 } else { 458 IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); 459 ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN; 460 } 461 IFQ_SET_READY(&ifp->if_snd); 462 463 /* no IFM type for 11Mbps USB, so go with 10baseT */ 464 ifmedia_add(&sc->sc_ifmedia, IFM_ETHER | IFM_10_T, 0, 0); 465 ifmedia_set(&sc->sc_ifmedia, IFM_ETHER | IFM_10_T); 466 467 sc->sc_ifp = ifp; 468 469 ether_ifattach(ifp, eaddr); 470 471 /* start the interrupt transfer, if any */ 472 mtx_lock(&sc->sc_mtx); 473 usb2_transfer_start(sc->sc_xfer[CDCE_INTR]); 474 mtx_unlock(&sc->sc_mtx); 475 | |
476 return (0); /* success */ 477 478detach: 479 cdce_detach(dev); 480 return (ENXIO); /* failure */ 481} 482 483static int 484cdce_detach(device_t dev) 485{ 486 struct cdce_softc *sc = device_get_softc(dev); | 391 return (0); /* success */ 392 393detach: 394 cdce_detach(dev); 395 return (ENXIO); /* failure */ 396} 397 398static int 399cdce_detach(device_t dev) 400{ 401 struct cdce_softc *sc = device_get_softc(dev); |
487 struct ifnet *ifp; | 402 struct usb2_ether *ue = &sc->sc_ue; |
488 | 403 |
489 mtx_lock(&sc->sc_mtx); 490 491 cdce_stop(sc); 492 493 ifp = sc->sc_ifp; 494 495 mtx_unlock(&sc->sc_mtx); 496 | |
497 /* stop all USB transfers first */ 498 usb2_transfer_unsetup(sc->sc_xfer, CDCE_N_TRANSFER); | 404 /* stop all USB transfers first */ 405 usb2_transfer_unsetup(sc->sc_xfer, CDCE_N_TRANSFER); |
499 500 /* get rid of any late children */ 501 bus_generic_detach(dev); 502 503 if (ifp) { 504 ether_ifdetach(ifp); 505 if_free(ifp); 506 ifmedia_removeall(&sc->sc_ifmedia); 507 } | 406 usb2_ether_ifdetach(ue); |
508 mtx_destroy(&sc->sc_mtx); 509 510 return (0); 511} 512 513static void | 407 mtx_destroy(&sc->sc_mtx); 408 409 return (0); 410} 411 412static void |
514cdce_start_cb(struct ifnet *ifp) | 413cdce_start(struct usb2_ether *ue) |
515{ | 414{ |
516 struct cdce_softc *sc = ifp->if_softc; | 415 struct cdce_softc *sc = usb2_ether_getsc(ue); |
517 | 416 |
518 mtx_lock(&sc->sc_mtx); 519 520 cdce_start_transfers(sc); 521 522 mtx_unlock(&sc->sc_mtx); | 417 /* 418 * Start the USB transfers, if not already started: 419 */ 420 usb2_transfer_start(sc->sc_xfer[CDCE_BULK_B]); 421 usb2_transfer_start(sc->sc_xfer[CDCE_BULK_A]); |
523} 524 525static void | 422} 423 424static void |
526cdce_start_transfers(struct cdce_softc *sc) | 425cdce_free_queue(struct mbuf **ppm, uint8_t n) |
527{ | 426{ |
528 if ((sc->sc_flags & CDCE_FLAG_LL_READY) && 529 (sc->sc_flags & CDCE_FLAG_HL_READY)) { 530 531 /* 532 * start the USB transfers, if not already started: 533 */ 534 usb2_transfer_start(sc->sc_xfer[CDCE_BULK_B]); 535 usb2_transfer_start(sc->sc_xfer[CDCE_BULK_A]); 536 } 537} 538 539static uint32_t 540cdce_m_frags(struct mbuf *m) 541{ 542 uint32_t temp = 1; 543 544 while ((m = m->m_next)) { 545 temp++; 546 } 547 return (temp); 548} 549 550static void 551cdce_fwd_mq(struct cdce_softc *sc, struct cdce_mq *mq) 552{ 553 struct mbuf *m; 554 struct ifnet *ifp = sc->sc_ifp; 555 556 if (mq->ifq_head) { 557 558 mtx_unlock(&sc->sc_mtx); 559 560 while (1) { 561 562 _IF_DEQUEUE(mq, m); 563 564 if (m == NULL) 565 break; 566 567 (ifp->if_input) (ifp, m); | 427 uint8_t x; 428 for (x = 0; x != n; x++) { 429 if (ppm[x] != NULL) { 430 m_freem(ppm[x]); 431 ppm[x] = NULL; |
568 } | 432 } |
569 570 mtx_lock(&sc->sc_mtx); | |
571 } 572} 573 574static void | 433 } 434} 435 436static void |
575cdce_free_mq(struct cdce_mq *mq) | 437cdce_bulk_write_callback(struct usb2_xfer *xfer) |
576{ | 438{ |
577 struct mbuf *m; 578 579 if (mq->ifq_head) { 580 581 while (1) { 582 583 _IF_DEQUEUE(mq, m); 584 585 if (m == NULL) 586 break; 587 588 m_freem(m); 589 } 590 } 591} 592 593static void 594cdce_bulk_write_512x4_callback(struct usb2_xfer *xfer) 595{ | |
596 struct cdce_softc *sc = xfer->priv_sc; | 439 struct cdce_softc *sc = xfer->priv_sc; |
597 struct ifnet *ifp = sc->sc_ifp; | 440 struct ifnet *ifp = usb2_ether_getifp(&sc->sc_ue); |
598 struct mbuf *m; 599 struct mbuf *mt; | 441 struct mbuf *m; 442 struct mbuf *mt; |
600 uint16_t x; 601 uint16_t y; 602 uint16_t flen; | 443 uint32_t crc; 444 uint8_t x; |
603 | 445 |
446 DPRINTFN(1, "\n"); 447 |
|
604 switch (USB_GET_STATE(xfer)) { 605 case USB_ST_TRANSFERRED: 606 DPRINTFN(11, "transfer complete: " | 448 switch (USB_GET_STATE(xfer)) { 449 case USB_ST_TRANSFERRED: 450 DPRINTFN(11, "transfer complete: " |
607 "%u bytes in %u fragments and %u frames\n", 608 xfer->actlen, xfer->nframes, sc->sc_tx_mq.ifq_len); | 451 "%u bytes in %u frames\n", xfer->actlen, 452 xfer->aframes); |
609 | 453 |
610 /* update packet counter */ 611 ifp->if_opackets += sc->sc_tx_mq.ifq_len; | 454 ifp->if_opackets++; |
612 | 455 |
613 /* free all previous mbufs */ 614 cdce_free_mq(&sc->sc_tx_mq); | 456 /* free all previous TX buffers */ 457 cdce_free_queue(sc->sc_tx_buf, CDCE_FRAMES_MAX); |
615 | 458 |
459 /* FALLTHROUGH */ |
|
616 case USB_ST_SETUP: 617tr_setup: | 460 case USB_ST_SETUP: 461tr_setup: |
618 x = 0; /* number of frames */ 619 y = 1; /* number of fragments */ | 462 for (x = 0; x != CDCE_FRAMES_MAX; x++) { |
620 | 463 |
621 while (x != CDCE_512X4_FRAMES_MAX) { 622 | |
623 IFQ_DRV_DEQUEUE(&ifp->if_snd, m); 624 | 464 IFQ_DRV_DEQUEUE(&ifp->if_snd, m); 465 |
625 if (m == NULL) { | 466 if (m == NULL) |
626 break; | 467 break; |
468 469 if (sc->sc_flags & CDCE_FLAG_ZAURUS) { 470 /* 471 * Zaurus wants a 32-bit CRC appended 472 * to every frame 473 */ 474 475 crc = cdce_m_crc32(m, 0, m->m_pkthdr.len); 476 crc = htole32(crc); 477 478 if (!m_append(m, 4, (void *)&crc)) { 479 m_freem(m); 480 ifp->if_oerrors++; 481 continue; 482 } |
|
627 } | 483 } |
628 if (m->m_pkthdr.len > MCLBYTES) { 629 m_freem(m); 630 ifp->if_oerrors++; 631 continue; 632 } 633 if (cdce_m_frags(m) > CDCE_512X4_FRAME_FRAG_MAX) { | 484 if (m->m_len != m->m_pkthdr.len) { |
634 mt = m_defrag(m, M_DONTWAIT); 635 if (mt == NULL) { 636 m_freem(m); 637 ifp->if_oerrors++; 638 continue; 639 } 640 m = mt; 641 } | 485 mt = m_defrag(m, M_DONTWAIT); 486 if (mt == NULL) { 487 m_freem(m); 488 ifp->if_oerrors++; 489 continue; 490 } 491 m = mt; 492 } |
642 _IF_ENQUEUE(&sc->sc_tx_mq, m); | 493 if (m->m_pkthdr.len > MCLBYTES) { 494 m->m_pkthdr.len = MCLBYTES; 495 } 496 sc->sc_tx_buf[x] = m; 497 xfer->frlengths[x] = m->m_len; 498 usb2_set_frame_data(xfer, m->m_data, x); |
643 644 /* | 499 500 /* |
645 * if there's a BPF listener, bounce a copy 646 * of this frame to him: | 501 * If there's a BPF listener, bounce a copy of 502 * this frame to him: |
647 */ 648 BPF_MTAP(ifp, m); | 503 */ 504 BPF_MTAP(ifp, m); |
649 650#if (CDCE_512X4_FRAG_LENGTH_MASK < MCLBYTES) 651#error "(CDCE_512X4_FRAG_LENGTH_MASK < MCLBYTES)" 652#endif 653 do { 654 655 flen = m->m_len & CDCE_512X4_FRAG_LENGTH_MASK; 656 xfer->frlengths[y] = m->m_len; 657 usb2_set_frame_data(xfer, m->m_data, y); 658 659 if (m->m_next == NULL) { 660 flen |= CDCE_512X4_FRAG_LAST_MASK; 661 } 662 USETW(sc->sc_tx.hdr.wFragLength[y - 1], flen); 663 664 y++; 665 666 } while ((m = m->m_next)); 667 668 x++; | |
669 } | 505 } |
670 671 if (y == 1) { 672 /* no data to transmit */ 673 break; | 506 if (x != 0) { 507 xfer->nframes = x; 508 usb2_start_hardware(xfer); |
674 } | 509 } |
675 /* fill in Signature */ 676 sc->sc_tx.hdr.bSig[0] = 'F'; 677 sc->sc_tx.hdr.bSig[1] = 'L'; 678 679 /* 680 * We ensure that the header results in a short packet by 681 * making the length odd ! 682 */ 683 USETW(sc->sc_tx.hdr.wFragLength[y - 1], 0); 684 xfer->frlengths[0] = CDCE_512X4_FRAG_LENGTH_OFFSET + ((y - 1) * 2) + 1; 685 usb2_set_frame_data(xfer, &sc->sc_tx.hdr, 0); 686 xfer->nframes = y; 687 usb2_start_hardware(xfer); | |
688 break; 689 690 default: /* Error */ 691 DPRINTFN(11, "transfer error, %s\n", 692 usb2_errstr(xfer->error)); 693 | 510 break; 511 512 default: /* Error */ 513 DPRINTFN(11, "transfer error, %s\n", 514 usb2_errstr(xfer->error)); 515 |
694 /* update error counter */ 695 ifp->if_oerrors += sc->sc_tx_mq.ifq_len; | 516 /* free all previous TX buffers */ 517 cdce_free_queue(sc->sc_tx_buf, CDCE_FRAMES_MAX); |
696 | 518 |
697 /* free all previous mbufs */ 698 cdce_free_mq(&sc->sc_tx_mq); 699 700 if (xfer->error != USB_ERR_CANCELLED) { 701 /* try to clear stall first */ 702 xfer->flags.stall_pipe = 1; 703 goto tr_setup; 704 } 705 break; 706 } 707} 708 709static void 710cdce_bulk_write_std_callback(struct usb2_xfer *xfer) 711{ 712 struct cdce_softc *sc = xfer->priv_sc; 713 struct ifnet *ifp = sc->sc_ifp; 714 struct mbuf *m; 715 struct mbuf *mt; 716 uint32_t crc; 717 718 DPRINTFN(1, "\n"); 719 720 switch (USB_GET_STATE(xfer)) { 721 case USB_ST_TRANSFERRED: 722 DPRINTFN(11, "transfer complete: " 723 "%u bytes in %u frames\n", xfer->actlen, 724 xfer->aframes); 725 726 ifp->if_opackets++; 727 728 /* free all previous mbufs */ 729 cdce_free_mq(&sc->sc_tx_mq); 730 731 case USB_ST_SETUP: 732tr_setup: 733 IFQ_DRV_DEQUEUE(&ifp->if_snd, m); 734 735 if (m == NULL) { 736 break; 737 } 738 if (sc->sc_flags & CDCE_FLAG_ZAURUS) { 739 /* 740 * Zaurus wants a 32-bit CRC appended to 741 * every frame 742 */ 743 744 crc = cdce_m_crc32(m, 0, m->m_pkthdr.len); 745 crc = htole32(crc); 746 747 if (!m_append(m, 4, (void *)&crc)) { 748 m_freem(m); 749 ifp->if_oerrors++; 750 goto tr_setup; 751 } 752 } 753 if (m->m_len != m->m_pkthdr.len) { 754 mt = m_defrag(m, M_DONTWAIT); 755 if (mt == NULL) { 756 m_freem(m); 757 ifp->if_oerrors++; 758 goto tr_setup; 759 } 760 m = mt; 761 } 762 if (m->m_pkthdr.len > MCLBYTES) { 763 m->m_pkthdr.len = MCLBYTES; 764 } 765 _IF_ENQUEUE(&sc->sc_tx_mq, m); 766 767 xfer->frlengths[0] = m->m_len; 768 usb2_set_frame_data(xfer, m->m_data, 0); 769 xfer->nframes = 1; 770 771 /* 772 * if there's a BPF listener, bounce a copy 773 * of this frame to him: 774 */ 775 BPF_MTAP(ifp, m); 776 777 usb2_start_hardware(xfer); 778 break; 779 780 default: /* Error */ 781 DPRINTFN(11, "transfer error, %s\n", 782 usb2_errstr(xfer->error)); 783 784 /* free all previous mbufs */ 785 cdce_free_mq(&sc->sc_tx_mq); | 519 /* count output errors */ |
786 ifp->if_oerrors++; 787 788 if (xfer->error != USB_ERR_CANCELLED) { 789 /* try to clear stall first */ 790 xfer->flags.stall_pipe = 1; 791 goto tr_setup; 792 } 793 break; 794 } 795} 796 | 520 ifp->if_oerrors++; 521 522 if (xfer->error != USB_ERR_CANCELLED) { 523 /* try to clear stall first */ 524 xfer->flags.stall_pipe = 1; 525 goto tr_setup; 526 } 527 break; 528 } 529} 530 |
797static void 798cdce_bulk_write_callback(struct usb2_xfer *xfer) 799{ 800 struct cdce_softc *sc = xfer->priv_sc; 801 802 /* first call - set the correct callback */ 803 if (sc->sc_iface_protocol == UIPROTO_CDC_ETH_512X4) { 804 xfer->flags.force_short_xfer = 0; 805 xfer->callback = &cdce_bulk_write_512x4_callback; 806 } else { 807 xfer->callback = &cdce_bulk_write_std_callback; 808 } 809 (xfer->callback) (xfer); 810} 811 | |
812static int32_t | 531static int32_t |
813#ifdef __FreeBSD__ | |
814cdce_m_crc32_cb(void *arg, void *src, uint32_t count) | 532cdce_m_crc32_cb(void *arg, void *src, uint32_t count) |
815#else 816cdce_m_crc32_cb(void *arg, caddr_t src, uint32_t count) 817#endif | |
818{ | 533{ |
819 register uint32_t *p_crc = arg; | 534 uint32_t *p_crc = arg; |
820 821 *p_crc = crc32_raw(src, count, *p_crc); 822 return (0); 823} 824 825static uint32_t 826cdce_m_crc32(struct mbuf *m, uint32_t src_offset, uint32_t src_len) 827{ | 535 536 *p_crc = crc32_raw(src, count, *p_crc); 537 return (0); 538} 539 540static uint32_t 541cdce_m_crc32(struct mbuf *m, uint32_t src_offset, uint32_t src_len) 542{ |
828 register int error; | |
829 uint32_t crc = 0xFFFFFFFF; | 543 uint32_t crc = 0xFFFFFFFF; |
544 int error; |
|
830 | 545 |
831 error = m_apply(m, src_offset, src_len, &cdce_m_crc32_cb, &crc); | 546 error = m_apply(m, src_offset, src_len, cdce_m_crc32_cb, &crc); |
832 return (crc ^ 0xFFFFFFFF); 833} 834 835static void | 547 return (crc ^ 0xFFFFFFFF); 548} 549 550static void |
836cdce_stop(struct cdce_softc *sc) | 551cdce_init(struct usb2_ether *ue) |
837{ | 552{ |
838 struct ifnet *ifp = sc->sc_ifp; | 553 struct cdce_softc *sc = usb2_ether_getsc(ue); 554 struct ifnet *ifp = usb2_ether_getifp(ue); |
839 | 555 |
840 /* immediate configuration */ | 556 CDCE_LOCK_ASSERT(sc, MA_OWNED); |
841 | 557 |
842 if (ifp) { 843 /* clear flags */ 844 ifp->if_drv_flags &= ~IFF_DRV_RUNNING; 845 } 846 sc->sc_flags &= ~(CDCE_FLAG_HL_READY | 847 CDCE_FLAG_LL_READY); | 558 ifp->if_drv_flags |= IFF_DRV_RUNNING; |
848 | 559 |
560 /* start interrupt transfer */ 561 usb2_transfer_start(sc->sc_xfer[CDCE_INTR]); 562 563 /* stall data write direction, which depends on USB mode */ 564 if (usb2_get_mode(sc->sc_ue.ue_udev) == USB_MODE_HOST) 565 usb2_transfer_set_stall(sc->sc_xfer[CDCE_BULK_A]); 566 else 567 usb2_transfer_set_stall(sc->sc_xfer[CDCE_BULK_B]); 568 569 /* start data transfers */ 570 cdce_start(ue); 571} 572 573static void 574cdce_stop(struct usb2_ether *ue) 575{ 576 struct cdce_softc *sc = usb2_ether_getsc(ue); 577 struct ifnet *ifp = usb2_ether_getifp(ue); 578 579 CDCE_LOCK_ASSERT(sc, MA_OWNED); 580 581 ifp->if_drv_flags &= ~IFF_DRV_RUNNING; 582 |
|
849 /* 850 * stop all the transfers, if not already stopped: 851 */ 852 usb2_transfer_stop(sc->sc_xfer[CDCE_BULK_A]); 853 usb2_transfer_stop(sc->sc_xfer[CDCE_BULK_B]); | 583 /* 584 * stop all the transfers, if not already stopped: 585 */ 586 usb2_transfer_stop(sc->sc_xfer[CDCE_BULK_A]); 587 usb2_transfer_stop(sc->sc_xfer[CDCE_BULK_B]); |
588 usb2_transfer_stop(sc->sc_xfer[CDCE_INTR]); |
|
854} 855 | 589} 590 |
591static void 592cdce_setmulti(struct usb2_ether *ue) 593{ 594 /* no-op */ 595 return; 596} 597 598static void 599cdce_setpromisc(struct usb2_ether *ue) 600{ 601 /* no-op */ 602 return; 603} 604 |
|
856static int 857cdce_shutdown(device_t dev) 858{ 859 struct cdce_softc *sc = device_get_softc(dev); 860 | 605static int 606cdce_shutdown(device_t dev) 607{ 608 struct cdce_softc *sc = device_get_softc(dev); 609 |
861 mtx_lock(&sc->sc_mtx); | 610 usb2_ether_ifshutdown(&sc->sc_ue); |
862 | 611 |
863 cdce_stop(sc); 864 865 mtx_unlock(&sc->sc_mtx); 866 | |
867 return (0); 868} 869 870static int 871cdce_suspend(device_t dev) 872{ 873 device_printf(dev, "Suspending\n"); 874 return (0); 875} 876 877static int 878cdce_resume(device_t dev) 879{ 880 device_printf(dev, "Resuming\n"); 881 return (0); 882} 883 | 612 return (0); 613} 614 615static int 616cdce_suspend(device_t dev) 617{ 618 device_printf(dev, "Suspending\n"); 619 return (0); 620} 621 622static int 623cdce_resume(device_t dev) 624{ 625 device_printf(dev, "Resuming\n"); 626 return (0); 627} 628 |
884static int 885cdce_ioctl_cb(struct ifnet *ifp, u_long command, caddr_t data) 886{ 887 struct cdce_softc *sc = ifp->if_softc; 888 int error = 0; 889 890 switch (command) { 891 case SIOCSIFFLAGS: 892 mtx_lock(&sc->sc_mtx); 893 if (ifp->if_flags & IFF_UP) { 894 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { 895 cdce_init_cb(sc); 896 } 897 } else { 898 if (ifp->if_drv_flags & IFF_DRV_RUNNING) { 899 cdce_stop(sc); 900 } 901 } 902 mtx_unlock(&sc->sc_mtx); 903 break; 904 905 case SIOCSIFMEDIA: 906 case SIOCGIFMEDIA: 907 error = ifmedia_ioctl(ifp, (void *)data, 908 &sc->sc_ifmedia, command); 909 break; 910 911 default: 912 error = ether_ioctl(ifp, command, data); 913 break; 914 } 915 return (error); 916} 917 | |
918static void | 629static void |
919cdce_init_cb(void *arg) | 630cdce_bulk_read_callback(struct usb2_xfer *xfer) |
920{ | 631{ |
921 struct cdce_softc *sc = arg; 922 struct ifnet *ifp; 923 924 mtx_lock(&sc->sc_mtx); 925 926 ifp = sc->sc_ifp; 927 928 /* immediate configuration */ 929 930 cdce_stop(sc); 931 932 ifp->if_drv_flags |= IFF_DRV_RUNNING; 933 934 sc->sc_flags |= ( 935 CDCE_FLAG_LL_READY | 936 CDCE_FLAG_HL_READY); 937 938 usb2_transfer_set_stall(sc->sc_xfer[CDCE_BULK_A]); 939 usb2_transfer_set_stall(sc->sc_xfer[CDCE_BULK_B]); 940 941 cdce_start_transfers(sc); 942 943 mtx_unlock(&sc->sc_mtx); 944} 945 946static void 947cdce_bulk_read_512x4_callback(struct usb2_xfer *xfer) 948{ | |
949 struct cdce_softc *sc = xfer->priv_sc; | 632 struct cdce_softc *sc = xfer->priv_sc; |
950 struct ifnet *ifp = sc->sc_ifp; | |
951 struct mbuf *m; | 633 struct mbuf *m; |
952 void *data_ptr; 953 uint32_t offset; 954 uint16_t x; 955 uint16_t y; 956 uint16_t z; 957 uint16_t rx_frags; 958 uint16_t flen; 959 uint8_t fwd_mq; 960 uint8_t free_mq; | 634 uint8_t x; |
961 | 635 |
962 fwd_mq = 0; 963 free_mq = 0; 964 rx_frags = 0; 965 | |
966 switch (USB_GET_STATE(xfer)) { 967 case USB_ST_TRANSFERRED: 968 969 DPRINTF("received %u bytes in %u frames\n", 970 xfer->actlen, xfer->aframes); 971 | 636 switch (USB_GET_STATE(xfer)) { 637 case USB_ST_TRANSFERRED: 638 639 DPRINTF("received %u bytes in %u frames\n", 640 xfer->actlen, xfer->aframes); 641 |
972 /* check state */ 973 if (!(sc->sc_flags & CDCE_FLAG_RX_DATA)) { | 642 for (x = 0; x != xfer->aframes; x++) { |
974 | 643 |
975 /* verify the header */ 976 if ((xfer->actlen < CDCE_512X4_FRAG_LENGTH_OFFSET) || 977 (sc->sc_rx.hdr.bSig[0] != 'F') || 978 (sc->sc_rx.hdr.bSig[1] != 'L')) { 979 /* try to clear stall first */ 980 xfer->flags.stall_pipe = 1; 981 goto tr_setup; 982 } 983 rx_frags = (xfer->actlen - 984 CDCE_512X4_FRAG_LENGTH_OFFSET) / 2; 985 if (rx_frags != 0) { 986 /* start receiving data */ 987 sc->sc_flags |= CDCE_FLAG_RX_DATA; 988 } 989 DPRINTF("doing %u fragments\n", rx_frags); | 644 m = sc->sc_rx_buf[x]; 645 sc->sc_rx_buf[x] = NULL; |
990 | 646 |
991 } else { 992 /* we are done receiving data */ 993 sc->sc_flags &= ~CDCE_FLAG_RX_DATA; 994 fwd_mq = 1; | 647 /* Strip off CRC added by Zaurus, if any */ 648 if ((sc->sc_flags & CDCE_FLAG_ZAURUS) && 649 (xfer->frlengths[x] >= 14)) 650 xfer->frlengths[x] -= 4; 651 652 if (xfer->frlengths[x] < sizeof(struct ether_header)) { 653 m_freem(m); 654 continue; 655 } 656 /* queue up mbuf */ 657 usb2_ether_rxmbuf(&sc->sc_ue, m, xfer->frlengths[x]); |
995 } 996 | 658 } 659 |
660 /* FALLTHROUGH */ |
|
997 case USB_ST_SETUP: | 661 case USB_ST_SETUP: |
998tr_setup: 999 if (xfer->flags.stall_pipe) { 1000 /* we are done */ 1001 sc->sc_flags &= ~CDCE_FLAG_RX_DATA; 1002 } 1003 /* we expect a Multi Frame Ethernet Header */ 1004 if (!(sc->sc_flags & CDCE_FLAG_RX_DATA)) { 1005 DPRINTF("expecting length header\n"); 1006 usb2_set_frame_data(xfer, &sc->sc_rx.hdr, 0); 1007 xfer->frlengths[0] = sizeof(sc->sc_rx.hdr); 1008 xfer->nframes = 1; 1009 xfer->flags.short_xfer_ok = 1; 1010 usb2_start_hardware(xfer); 1011 free_mq = 1; 1012 break; 1013 } 1014 /* verify number of fragments */ 1015 if (rx_frags > CDCE_512X4_FRAGS_MAX) { 1016 /* try to clear stall first */ 1017 xfer->flags.stall_pipe = 1; 1018 goto tr_setup; 1019 } 1020 /* check if the last fragment does not complete a frame */ 1021 x = rx_frags - 1; 1022 flen = UGETW(sc->sc_rx.hdr.wFragLength[x]); 1023 if (!(flen & CDCE_512X4_FRAG_LAST_MASK)) { 1024 DPRINTF("no last frag mask\n"); 1025 /* try to clear stall first */ 1026 xfer->flags.stall_pipe = 1; 1027 goto tr_setup; 1028 } 1029 /* 1030 * Setup a new USB transfer chain to receive all the 1031 * IP-frame fragments, automagically defragged : | 662 /* 663 * TODO: Implement support for multi frame transfers, 664 * when the USB hardware supports it. |
1032 */ | 665 */ |
1033 x = 0; 1034 y = 0; 1035 while (1) { 1036 1037 z = x; 1038 offset = 0; 1039 1040 /* precompute the frame length */ 1041 while (1) { 1042 flen = UGETW(sc->sc_rx.hdr.wFragLength[z]); 1043 offset += (flen & CDCE_512X4_FRAG_LENGTH_MASK); 1044 if (flen & CDCE_512X4_FRAG_LAST_MASK) { 1045 break; 1046 } 1047 z++; 1048 } 1049 1050 if (offset >= sizeof(struct ether_header)) { 1051 /* 1052 * allocate a suitable memory buffer, if 1053 * possible 1054 */ 1055 if (offset > (MCLBYTES - ETHER_ALIGN)) { 1056 /* try to clear stall first */ 1057 xfer->flags.stall_pipe = 1; 1058 goto tr_setup; 1059 } if (offset > (MHLEN - ETHER_ALIGN)) { 1060 m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); 1061 } else { 1062 m = m_gethdr(M_DONTWAIT, MT_DATA); 1063 } | 666 for (x = 0; x != 1; x++) { 667 if (sc->sc_rx_buf[x] == NULL) { 668 m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); 669 if (m == NULL) 670 goto tr_stall; 671 sc->sc_rx_buf[x] = m; 672 /* adjust for ethernet */ 673 m->m_len = m->m_pkthdr.len = MCLBYTES; 674 m_adj(m, ETHER_ALIGN); |
1064 } else { | 675 } else { |
1065 m = NULL; /* dump it */ | 676 m = sc->sc_rx_buf[x]; |
1066 } 1067 | 677 } 678 |
1068 DPRINTFN(17, "frame %u, length = %u \n", y, offset); 1069 1070 /* check if we have a buffer */ 1071 if (m) { 1072 m->m_data = USB_ADD_BYTES(m->m_data, ETHER_ALIGN); 1073 m->m_pkthdr.rcvif = ifp; 1074 m->m_pkthdr.len = m->m_len = offset; 1075 1076 /* enqueue */ 1077 _IF_ENQUEUE(&sc->sc_rx_mq, m); 1078 1079 data_ptr = m->m_data; 1080 ifp->if_ipackets++; 1081 } else { 1082 data_ptr = sc->sc_rx.data; 1083 ifp->if_ierrors++; 1084 } 1085 1086 /* setup the RX chain */ 1087 offset = 0; 1088 while (1) { 1089 1090 flen = UGETW(sc->sc_rx.hdr.wFragLength[x]); 1091 1092 usb2_set_frame_data(xfer, 1093 USB_ADD_BYTES(data_ptr, offset), x); 1094 1095 xfer->frlengths[x] = 1096 (flen & CDCE_512X4_FRAG_LENGTH_MASK); 1097 1098 DPRINTFN(17, "length[%u] = %u\n", 1099 x, xfer->frlengths[x]); 1100 1101 offset += xfer->frlengths[x]; 1102 1103 x++; 1104 1105 if (flen & CDCE_512X4_FRAG_LAST_MASK) { 1106 break; 1107 } 1108 } 1109 1110 y++; 1111 1112 if (x == rx_frags) { 1113 break; 1114 } 1115 if (y == CDCE_512X4_FRAMES_MAX) { 1116 /* try to clear stall first */ 1117 xfer->flags.stall_pipe = 1; 1118 goto tr_setup; 1119 } | 679 usb2_set_frame_data(xfer, m->m_data, x); 680 xfer->frlengths[x] = m->m_len; |
1120 } | 681 } |
1121 1122 DPRINTF("nframes = %u\n", x); 1123 | 682 /* set number of frames and start hardware */ |
1124 xfer->nframes = x; | 683 xfer->nframes = x; |
1125 xfer->flags.short_xfer_ok = 0; | |
1126 usb2_start_hardware(xfer); | 684 usb2_start_hardware(xfer); |
685 /* flush any received frames */ 686 usb2_ether_rxflush(&sc->sc_ue); |
|
1127 break; 1128 1129 default: /* Error */ 1130 DPRINTF("error = %s\n", 1131 usb2_errstr(xfer->error)); 1132 1133 if (xfer->error != USB_ERR_CANCELLED) { | 687 break; 688 689 default: /* Error */ 690 DPRINTF("error = %s\n", 691 usb2_errstr(xfer->error)); 692 693 if (xfer->error != USB_ERR_CANCELLED) { |
694tr_stall: |
|
1134 /* try to clear stall first */ 1135 xfer->flags.stall_pipe = 1; | 695 /* try to clear stall first */ 696 xfer->flags.stall_pipe = 1; |
1136 goto tr_setup; | 697 xfer->nframes = 0; 698 usb2_start_hardware(xfer); 699 break; |
1137 } | 700 } |
1138 free_mq = 1; 1139 break; 1140 } | |
1141 | 701 |
1142 /* 1143 * At the end of a USB callback it is always safe to unlock 1144 * the private mutex of a device! 1145 * 1146 * 1147 * By safe we mean that if "usb2_transfer_stop()" is called, 1148 * we will get a callback having the error code 1149 * USB_ERR_CANCELLED. 1150 */ 1151 if (fwd_mq) { 1152 cdce_fwd_mq(sc, &sc->sc_rx_mq); 1153 } 1154 if (free_mq) { 1155 cdce_free_mq(&sc->sc_rx_mq); 1156 } 1157} 1158 1159static void 1160cdce_bulk_read_std_callback(struct usb2_xfer *xfer) 1161{ 1162 struct cdce_softc *sc = xfer->priv_sc; 1163 struct ifnet *ifp = sc->sc_ifp; 1164 struct mbuf *m; 1165 struct mbuf *m_rx = NULL; 1166 1167 switch (USB_GET_STATE(xfer)) { 1168 case USB_ST_TRANSFERRED: 1169 1170 DPRINTF("received %u bytes in %u frames\n", 1171 xfer->actlen, xfer->aframes); 1172 1173 if (sc->sc_flags & CDCE_FLAG_ZAURUS) { 1174 1175 /* Strip off CRC added by Zaurus */ 1176 if (xfer->frlengths[0] >= MAX(4, 14)) { 1177 xfer->frlengths[0] -= 4; 1178 } 1179 } 1180 _IF_DEQUEUE(&sc->sc_rx_mq, m); 1181 1182 if (m) { 1183 1184 if (xfer->frlengths[0] < sizeof(struct ether_header)) { 1185 m_freem(m); 1186 goto tr_setup; 1187 } 1188 ifp->if_ipackets++; 1189 m->m_pkthdr.rcvif = ifp; 1190 m->m_pkthdr.len = m->m_len = xfer->frlengths[0]; 1191 m_rx = m; 1192 } 1193 case USB_ST_SETUP: 1194tr_setup: 1195 m = usb2_ether_get_mbuf(); 1196 if (m == NULL) { 1197 1198 /* 1199 * We are out of mbufs and need to dump all the 1200 * received data ! 1201 */ 1202 usb2_set_frame_data(xfer, &sc->sc_rx.data, 0); 1203 xfer->frlengths[0] = sizeof(sc->sc_rx.data); 1204 1205 } else { 1206 usb2_set_frame_data(xfer, m->m_data, 0); 1207 xfer->frlengths[0] = m->m_len; 1208 _IF_ENQUEUE(&sc->sc_rx_mq, m); 1209 } 1210 xfer->nframes = 1; 1211 usb2_start_hardware(xfer); | 702 /* need to free the RX-mbufs when we are cancelled */ 703 cdce_free_queue(sc->sc_rx_buf, CDCE_FRAMES_MAX); |
1212 break; | 704 break; |
1213 1214 default: /* Error */ 1215 DPRINTF("error = %s\n", 1216 usb2_errstr(xfer->error)); 1217 1218 /* free all mbufs */ 1219 cdce_free_mq(&sc->sc_rx_mq); 1220 1221 if (xfer->error != USB_ERR_CANCELLED) { 1222 /* try to clear stall first */ 1223 xfer->flags.stall_pipe = 1; 1224 goto tr_setup; 1225 } 1226 return; | |
1227 } | 705 } |
1228 1229 /* 1230 * At the end of a USB callback it is always safe to unlock 1231 * the private mutex of a device! That is why we do the 1232 * "if_input" here, and not some lines up! 1233 * 1234 * By safe we mean that if "usb2_transfer_stop()" is called, 1235 * we will get a callback having the error code 1236 * USB_ERR_CANCELLED. 1237 */ 1238 if (m_rx) { 1239 mtx_unlock(&sc->sc_mtx); 1240 (ifp->if_input) (ifp, m_rx); 1241 mtx_lock(&sc->sc_mtx); 1242 } | |
1243} 1244 1245static void | 706} 707 708static void |
1246cdce_bulk_read_callback(struct usb2_xfer *xfer) 1247{ 1248 struct cdce_softc *sc = xfer->priv_sc; 1249 1250 /* first call - set the correct callback */ 1251 if (sc->sc_iface_protocol == UIPROTO_CDC_ETH_512X4) { 1252 xfer->callback = &cdce_bulk_read_512x4_callback; 1253 } else { 1254 xfer->callback = &cdce_bulk_read_std_callback; 1255 } 1256 (xfer->callback) (xfer); 1257} 1258 1259static int 1260cdce_ifmedia_upd_cb(struct ifnet *ifp) 1261{ 1262 /* no-op, cdce has only 1 possible media type */ 1263 return (0); 1264} 1265 1266static void 1267cdce_ifmedia_sts_cb(struct ifnet *const ifp, struct ifmediareq *req) 1268{ 1269 1270 req->ifm_status = IFM_AVALID | IFM_ACTIVE; 1271 req->ifm_active = IFM_ETHER | IFM_10_T; 1272} 1273 1274static void | |
1275cdce_intr_read_callback(struct usb2_xfer *xfer) 1276{ 1277 ; /* style fix */ 1278 switch (USB_GET_STATE(xfer)) { 1279 case USB_ST_TRANSFERRED: 1280 1281 DPRINTF("Received %d bytes\n", 1282 xfer->actlen); 1283 1284 /* TODO: decode some indications */ 1285 | 709cdce_intr_read_callback(struct usb2_xfer *xfer) 710{ 711 ; /* style fix */ 712 switch (USB_GET_STATE(xfer)) { 713 case USB_ST_TRANSFERRED: 714 715 DPRINTF("Received %d bytes\n", 716 xfer->actlen); 717 718 /* TODO: decode some indications */ 719 |
720 /* FALLTHROUGH */ |
|
1286 case USB_ST_SETUP: 1287tr_setup: 1288 xfer->frlengths[0] = xfer->max_data_length; 1289 usb2_start_hardware(xfer); 1290 break; 1291 1292 default: /* Error */ 1293 if (xfer->error != USB_ERR_CANCELLED) { --- 9 unchanged lines hidden (view full) --- 1303cdce_intr_write_callback(struct usb2_xfer *xfer) 1304{ 1305 ; /* style fix */ 1306 switch (USB_GET_STATE(xfer)) { 1307 case USB_ST_TRANSFERRED: 1308 1309 DPRINTF("Transferred %d bytes\n", xfer->actlen); 1310 | 721 case USB_ST_SETUP: 722tr_setup: 723 xfer->frlengths[0] = xfer->max_data_length; 724 usb2_start_hardware(xfer); 725 break; 726 727 default: /* Error */ 728 if (xfer->error != USB_ERR_CANCELLED) { --- 9 unchanged lines hidden (view full) --- 738cdce_intr_write_callback(struct usb2_xfer *xfer) 739{ 740 ; /* style fix */ 741 switch (USB_GET_STATE(xfer)) { 742 case USB_ST_TRANSFERRED: 743 744 DPRINTF("Transferred %d bytes\n", xfer->actlen); 745 |
746 /* FALLTHROUGH */ |
|
1311 case USB_ST_SETUP: 1312tr_setup: 1313#if 0 1314 xfer->frlengths[0] = XXX; 1315 usb2_start_hardware(xfer); 1316#endif 1317 break; 1318 --- 17 unchanged lines hidden --- | 747 case USB_ST_SETUP: 748tr_setup: 749#if 0 750 xfer->frlengths[0] = XXX; 751 usb2_start_hardware(xfer); 752#endif 753 break; 754 --- 17 unchanged lines hidden --- |