1 /* $NetBSD: if_kue.c,v 1.105 2021/06/13 09:26:24 mlelstv Exp $ */ 2 3 /* 4 * Copyright (c) 1997, 1998, 1999, 2000 5 * Bill Paul <wpaul@ee.columbia.edu>. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by Bill Paul. 18 * 4. Neither the name of the author nor the names of any co-contributors 19 * may be used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD 26 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 32 * THE POSSIBILITY OF SUCH DAMAGE. 33 * 34 * $FreeBSD: src/sys/dev/usb/if_kue.c,v 1.14 2000/01/14 01:36:15 wpaul Exp $ 35 */ 36 37 /* 38 * Kawasaki LSI KL5KUSB101B USB to ethernet adapter driver. 39 * 40 * Written by Bill Paul <wpaul@ee.columbia.edu> 41 * Electrical Engineering Department 42 * Columbia University, New York City 43 */ 44 45 /* 46 * The KLSI USB to ethernet adapter chip contains an USB serial interface, 47 * ethernet MAC and embedded microcontroller (called the QT Engine). 48 * The chip must have firmware loaded into it before it will operate. 49 * Packets are passed between the chip and host via bulk transfers. 50 * There is an interrupt endpoint mentioned in the software spec, however 51 * it's currently unused. This device is 10Mbps half-duplex only, hence 52 * there is no media selection logic. The MAC supports a 128 entry 53 * multicast filter, though the exact size of the filter can depend 54 * on the firmware. Curiously, while the software spec describes various 55 * ethernet statistics counters, my sample adapter and firmware combination 56 * claims not to support any statistics counters at all. 57 * 58 * Note that once we load the firmware in the device, we have to be 59 * careful not to load it again: if you restart your computer but 60 * leave the adapter attached to the USB controller, it may remain 61 * powered on and retain its firmware. In this case, we don't need 62 * to load the firmware a second time. 63 * 64 * Special thanks to Rob Furr for providing an ADS Technologies 65 * adapter for development and testing. No monkeys were harmed during 66 * the development of this driver. 67 */ 68 69 /* 70 * Ported to NetBSD and somewhat rewritten by Lennart Augustsson. 71 */ 72 73 #include <sys/cdefs.h> 74 __KERNEL_RCSID(0, "$NetBSD: if_kue.c,v 1.105 2021/06/13 09:26:24 mlelstv Exp $"); 75 76 #ifdef _KERNEL_OPT 77 #include "opt_inet.h" 78 #include "opt_usb.h" 79 #endif 80 81 #include <sys/param.h> 82 #include <sys/kmem.h> 83 84 #include <dev/usb/usbnet.h> 85 86 #ifdef INET 87 #include <netinet/in.h> 88 #include <netinet/if_inarp.h> 89 #endif 90 91 #include <dev/usb/if_kuereg.h> 92 #include <dev/usb/kue_fw.h> 93 94 #ifdef KUE_DEBUG 95 #define DPRINTF(x) if (kuedebug) printf x 96 #define DPRINTFN(n, x) if (kuedebug >= (n)) printf x 97 int kuedebug = 0; 98 #else 99 #define DPRINTF(x) 100 #define DPRINTFN(n, x) 101 #endif 102 103 struct kue_type { 104 uint16_t kue_vid; 105 uint16_t kue_did; 106 }; 107 108 struct kue_softc { 109 struct usbnet kue_un; 110 111 struct kue_ether_desc kue_desc; 112 uint16_t kue_rxfilt; 113 uint8_t *kue_mcfilters; 114 }; 115 116 #define KUE_MCFILT(x, y) \ 117 (uint8_t *)&(sc->kue_mcfilters[y * ETHER_ADDR_LEN]) 118 119 #define KUE_BUFSZ 1536 120 #define KUE_MIN_FRAMELEN 60 121 122 #define KUE_RX_LIST_CNT 1 123 #define KUE_TX_LIST_CNT 1 124 125 /* 126 * Various supported device vendors/products. 127 */ 128 static const struct usb_devno kue_devs[] = { 129 { USB_VENDOR_3COM, USB_PRODUCT_3COM_3C19250 }, 130 { USB_VENDOR_3COM, USB_PRODUCT_3COM_3C460 }, 131 { USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_URE450 }, 132 { USB_VENDOR_ADS, USB_PRODUCT_ADS_UBS10BT }, 133 { USB_VENDOR_ADS, USB_PRODUCT_ADS_UBS10BTX }, 134 { USB_VENDOR_ACTIONTEC, USB_PRODUCT_ACTIONTEC_AR9287 }, 135 { USB_VENDOR_ALLIEDTELESYN, USB_PRODUCT_ALLIEDTELESYN_AT_USB10 }, 136 { USB_VENDOR_AOX, USB_PRODUCT_AOX_USB101 }, 137 { USB_VENDOR_ASANTE, USB_PRODUCT_ASANTE_EA }, 138 { USB_VENDOR_ATEN, USB_PRODUCT_ATEN_UC10T }, 139 { USB_VENDOR_ATEN, USB_PRODUCT_ATEN_DSB650C }, 140 { USB_VENDOR_COREGA, USB_PRODUCT_COREGA_ETHER_USB_T }, 141 { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650C }, 142 { USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_E45 }, 143 { USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_XX1 }, 144 { USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_XX2 }, 145 { USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBETT }, 146 { USB_VENDOR_JATON, USB_PRODUCT_JATON_EDA }, 147 { USB_VENDOR_KINGSTON, USB_PRODUCT_KINGSTON_XX1 }, 148 { USB_VENDOR_KLSI, USB_PRODUCT_KLSI_DUH3E10BT }, 149 { USB_VENDOR_KLSI, USB_PRODUCT_KLSI_DUH3E10BTN }, 150 { USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB10T }, 151 { USB_VENDOR_MOBILITY, USB_PRODUCT_MOBILITY_EA }, 152 { USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_EA101 }, 153 { USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_EA101X }, 154 { USB_VENDOR_PERACOM, USB_PRODUCT_PERACOM_ENET }, 155 { USB_VENDOR_PERACOM, USB_PRODUCT_PERACOM_ENET2 }, 156 { USB_VENDOR_PERACOM, USB_PRODUCT_PERACOM_ENET3 }, 157 { USB_VENDOR_PORTGEAR, USB_PRODUCT_PORTGEAR_EA8 }, 158 { USB_VENDOR_PORTGEAR, USB_PRODUCT_PORTGEAR_EA9 }, 159 { USB_VENDOR_PORTSMITH, USB_PRODUCT_PORTSMITH_EEA }, 160 { USB_VENDOR_SHARK, USB_PRODUCT_SHARK_PA }, 161 { USB_VENDOR_SILICOM, USB_PRODUCT_SILICOM_U2E }, 162 { USB_VENDOR_SILICOM, USB_PRODUCT_SILICOM_GPE }, 163 { USB_VENDOR_SMC, USB_PRODUCT_SMC_2102USB }, 164 }; 165 #define kue_lookup(v, p) (usb_lookup(kue_devs, v, p)) 166 167 static int kue_match(device_t, cfdata_t, void *); 168 static void kue_attach(device_t, device_t, void *); 169 static int kue_detach(device_t, int); 170 171 CFATTACH_DECL_NEW(kue, sizeof(struct kue_softc), kue_match, kue_attach, 172 kue_detach, usbnet_activate); 173 174 static void kue_uno_rx_loop(struct usbnet *, struct usbnet_chain *, uint32_t); 175 static unsigned kue_uno_tx_prepare(struct usbnet *, struct mbuf *, 176 struct usbnet_chain *); 177 static int kue_uno_ioctl(struct ifnet *, u_long, void *); 178 static int kue_uno_init(struct ifnet *); 179 180 static const struct usbnet_ops kue_ops = { 181 .uno_ioctl = kue_uno_ioctl, 182 .uno_tx_prepare = kue_uno_tx_prepare, 183 .uno_rx_loop = kue_uno_rx_loop, 184 .uno_init = kue_uno_init, 185 }; 186 187 static void kue_reset(struct usbnet *); 188 189 static usbd_status kue_ctl(struct usbnet *, int, uint8_t, 190 uint16_t, void *, uint32_t); 191 static int kue_load_fw(struct usbnet *); 192 193 static usbd_status 194 kue_setword(struct usbnet *un, uint8_t breq, uint16_t word) 195 { 196 usb_device_request_t req; 197 198 DPRINTFN(10,("%s: %s: enter\n", device_xname(un->un_dev),__func__)); 199 200 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 201 req.bRequest = breq; 202 USETW(req.wValue, word); 203 USETW(req.wIndex, 0); 204 USETW(req.wLength, 0); 205 206 return usbd_do_request(un->un_udev, &req, NULL); 207 } 208 209 static usbd_status 210 kue_ctl(struct usbnet *un, int rw, uint8_t breq, uint16_t val, 211 void *data, uint32_t len) 212 { 213 usb_device_request_t req; 214 215 DPRINTFN(10,("%s: %s: enter, len=%d\n", device_xname(un->un_dev), 216 __func__, len)); 217 218 if (rw == KUE_CTL_WRITE) 219 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 220 else 221 req.bmRequestType = UT_READ_VENDOR_DEVICE; 222 223 req.bRequest = breq; 224 USETW(req.wValue, val); 225 USETW(req.wIndex, 0); 226 USETW(req.wLength, len); 227 228 return usbd_do_request(un->un_udev, &req, data); 229 } 230 231 static int 232 kue_load_fw(struct usbnet *un) 233 { 234 usb_device_descriptor_t dd; 235 usbd_status err; 236 237 DPRINTFN(1,("%s: %s: enter\n", device_xname(un->un_dev), __func__)); 238 239 /* 240 * First, check if we even need to load the firmware. 241 * If the device was still attached when the system was 242 * rebooted, it may already have firmware loaded in it. 243 * If this is the case, we don't need to do it again. 244 * And in fact, if we try to load it again, we'll hang, 245 * so we have to avoid this condition if we don't want 246 * to look stupid. 247 * 248 * We can test this quickly by checking the bcdRevision 249 * code. The NIC will return a different revision code if 250 * it's probed while the firmware is still loaded and 251 * running. 252 */ 253 if (usbd_get_device_desc(un->un_udev, &dd)) 254 return EIO; 255 if (UGETW(dd.bcdDevice) == KUE_WARM_REV) { 256 printf("%s: warm boot, no firmware download\n", 257 device_xname(un->un_dev)); 258 return 0; 259 } 260 261 printf("%s: cold boot, downloading firmware\n", 262 device_xname(un->un_dev)); 263 264 /* Load code segment */ 265 DPRINTFN(1,("%s: kue_load_fw: download code_seg\n", 266 device_xname(un->un_dev))); 267 /*XXXUNCONST*/ 268 err = kue_ctl(un, KUE_CTL_WRITE, KUE_CMD_SEND_SCAN, 269 0, __UNCONST(kue_code_seg), sizeof(kue_code_seg)); 270 if (err) { 271 printf("%s: failed to load code segment: %s\n", 272 device_xname(un->un_dev), usbd_errstr(err)); 273 return EIO; 274 } 275 276 /* Load fixup segment */ 277 DPRINTFN(1,("%s: kue_load_fw: download fix_seg\n", 278 device_xname(un->un_dev))); 279 /*XXXUNCONST*/ 280 err = kue_ctl(un, KUE_CTL_WRITE, KUE_CMD_SEND_SCAN, 281 0, __UNCONST(kue_fix_seg), sizeof(kue_fix_seg)); 282 if (err) { 283 printf("%s: failed to load fixup segment: %s\n", 284 device_xname(un->un_dev), usbd_errstr(err)); 285 return EIO; 286 } 287 288 /* Send trigger command. */ 289 DPRINTFN(1,("%s: kue_load_fw: download trig_seg\n", 290 device_xname(un->un_dev))); 291 /*XXXUNCONST*/ 292 err = kue_ctl(un, KUE_CTL_WRITE, KUE_CMD_SEND_SCAN, 293 0, __UNCONST(kue_trig_seg), sizeof(kue_trig_seg)); 294 if (err) { 295 printf("%s: failed to load trigger segment: %s\n", 296 device_xname(un->un_dev), usbd_errstr(err)); 297 return EIO; 298 } 299 300 usbd_delay_ms(un->un_udev, 10); 301 302 /* 303 * Reload device descriptor. 304 * Why? The chip without the firmware loaded returns 305 * one revision code. The chip with the firmware 306 * loaded and running returns a *different* revision 307 * code. This confuses the quirk mechanism, which is 308 * dependent on the revision data. 309 */ 310 (void)usbd_reload_device_desc(un->un_udev); 311 312 DPRINTFN(1,("%s: %s: done\n", device_xname(un->un_dev), __func__)); 313 314 /* Reset the adapter. */ 315 kue_reset(un); 316 317 return 0; 318 } 319 320 static void 321 kue_setiff_locked(struct usbnet *un) 322 { 323 struct ethercom * ec = usbnet_ec(un); 324 struct kue_softc * sc = usbnet_softc(un); 325 struct ifnet * const ifp = usbnet_ifp(un); 326 struct ether_multi *enm; 327 struct ether_multistep step; 328 int i; 329 330 DPRINTFN(5,("%s: %s: enter\n", device_xname(un->un_dev), __func__)); 331 332 /* If we want promiscuous mode, set the allframes bit. */ 333 if (ifp->if_flags & IFF_PROMISC) 334 sc->kue_rxfilt |= KUE_RXFILT_PROMISC; 335 else 336 sc->kue_rxfilt &= ~KUE_RXFILT_PROMISC; 337 338 if (ifp->if_flags & IFF_PROMISC) { 339 allmulti: 340 ifp->if_flags |= IFF_ALLMULTI; 341 sc->kue_rxfilt |= KUE_RXFILT_ALLMULTI|KUE_RXFILT_PROMISC; 342 sc->kue_rxfilt &= ~KUE_RXFILT_MULTICAST; 343 kue_setword(un, KUE_CMD_SET_PKT_FILTER, sc->kue_rxfilt); 344 return; 345 } 346 347 sc->kue_rxfilt &= ~(KUE_RXFILT_ALLMULTI|KUE_RXFILT_PROMISC); 348 349 i = 0; 350 ETHER_LOCK(ec); 351 ETHER_FIRST_MULTI(step, ec, enm); 352 while (enm != NULL) { 353 if (i == KUE_MCFILTCNT(sc) || 354 memcmp(enm->enm_addrlo, enm->enm_addrhi, 355 ETHER_ADDR_LEN) != 0) { 356 ETHER_UNLOCK(ec); 357 goto allmulti; 358 } 359 360 memcpy(KUE_MCFILT(sc, i), enm->enm_addrlo, ETHER_ADDR_LEN); 361 ETHER_NEXT_MULTI(step, enm); 362 i++; 363 } 364 ETHER_UNLOCK(ec); 365 366 ifp->if_flags &= ~IFF_ALLMULTI; 367 368 sc->kue_rxfilt |= KUE_RXFILT_MULTICAST; 369 kue_ctl(un, KUE_CTL_WRITE, KUE_CMD_SET_MCAST_FILTERS, 370 i, sc->kue_mcfilters, i * ETHER_ADDR_LEN); 371 372 kue_setword(un, KUE_CMD_SET_PKT_FILTER, sc->kue_rxfilt); 373 } 374 375 /* 376 * Issue a SET_CONFIGURATION command to reset the MAC. This should be 377 * done after the firmware is loaded into the adapter in order to 378 * bring it into proper operation. 379 */ 380 static void 381 kue_reset(struct usbnet *un) 382 { 383 DPRINTFN(5,("%s: %s: enter\n", device_xname(un->un_dev), __func__)); 384 385 if (usbd_set_config_no(un->un_udev, KUE_CONFIG_NO, 1) || 386 usbd_device2interface_handle(un->un_udev, KUE_IFACE_IDX, 387 &un->un_iface)) 388 printf("%s: reset failed\n", device_xname(un->un_dev)); 389 390 /* Wait a little while for the chip to get its brains in order. */ 391 usbd_delay_ms(un->un_udev, 10); 392 } 393 394 /* 395 * Probe for a KLSI chip. 396 */ 397 static int 398 kue_match(device_t parent, cfdata_t match, void *aux) 399 { 400 struct usb_attach_arg *uaa = aux; 401 402 DPRINTFN(25,("kue_match: enter\n")); 403 404 return kue_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL ? 405 UMATCH_VENDOR_PRODUCT : UMATCH_NONE; 406 } 407 408 /* 409 * Attach the interface. Allocate softc structures, do 410 * setup and ethernet/BPF attach. 411 */ 412 static void 413 kue_attach(device_t parent, device_t self, void *aux) 414 { 415 struct kue_softc *sc = device_private(self); 416 struct usbnet * const un = &sc->kue_un; 417 struct usb_attach_arg *uaa = aux; 418 char *devinfop; 419 struct usbd_device * dev = uaa->uaa_device; 420 usbd_status err; 421 usb_interface_descriptor_t *id; 422 usb_endpoint_descriptor_t *ed; 423 int i; 424 425 KASSERT((void *)sc == un); 426 427 DPRINTFN(5,(" : kue_attach: sc=%p, dev=%p", sc, dev)); 428 429 aprint_naive("\n"); 430 aprint_normal("\n"); 431 devinfop = usbd_devinfo_alloc(dev, 0); 432 aprint_normal_dev(self, "%s\n", devinfop); 433 usbd_devinfo_free(devinfop); 434 435 un->un_dev = self; 436 un->un_udev = dev; 437 un->un_sc = sc; 438 un->un_ops = &kue_ops; 439 un->un_rx_xfer_flags = USBD_SHORT_XFER_OK; 440 un->un_tx_xfer_flags = 0; 441 un->un_rx_list_cnt = KUE_RX_LIST_CNT; 442 un->un_tx_list_cnt = KUE_TX_LIST_CNT; 443 un->un_rx_bufsz = KUE_BUFSZ; 444 un->un_tx_bufsz = KUE_BUFSZ; 445 446 err = usbd_set_config_no(dev, KUE_CONFIG_NO, 1); 447 if (err) { 448 aprint_error_dev(self, "failed to set configuration" 449 ", err=%s\n", usbd_errstr(err)); 450 return; 451 } 452 453 /* Load the firmware into the NIC. */ 454 if (kue_load_fw(un)) { 455 aprint_error_dev(self, "loading firmware failed\n"); 456 return; 457 } 458 459 err = usbd_device2interface_handle(dev, KUE_IFACE_IDX, &un->un_iface); 460 if (err) { 461 aprint_error_dev(self, "getting interface handle failed\n"); 462 return; 463 } 464 465 id = usbd_get_interface_descriptor(un->un_iface); 466 467 /* Find endpoints. */ 468 for (i = 0; i < id->bNumEndpoints; i++) { 469 ed = usbd_interface2endpoint_descriptor(un->un_iface, i); 470 if (ed == NULL) { 471 aprint_error_dev(self, "couldn't get ep %d\n", i); 472 return; 473 } 474 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 475 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 476 un->un_ed[USBNET_ENDPT_RX] = ed->bEndpointAddress; 477 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && 478 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 479 un->un_ed[USBNET_ENDPT_TX] = ed->bEndpointAddress; 480 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 481 UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) { 482 /* 483 * The interrupt endpoint is currently unused by the 484 * KLSI part. 485 */ 486 un->un_ed[USBNET_ENDPT_INTR] = ed->bEndpointAddress; 487 } 488 } 489 490 if (un->un_ed[USBNET_ENDPT_RX] == 0 || 491 un->un_ed[USBNET_ENDPT_TX] == 0) { 492 aprint_error_dev(self, "missing endpoint\n"); 493 return; 494 } 495 496 /* First level attach, so kue_ctl() works. */ 497 usbnet_attach(un, "kuedet"); 498 499 /* Read ethernet descriptor */ 500 err = kue_ctl(un, KUE_CTL_READ, KUE_CMD_GET_ETHER_DESCRIPTOR, 501 0, &sc->kue_desc, sizeof(sc->kue_desc)); 502 if (err) { 503 aprint_error_dev(self, "could not read Ethernet descriptor\n"); 504 return; 505 } 506 memcpy(un->un_eaddr, sc->kue_desc.kue_macaddr, sizeof(un->un_eaddr)); 507 508 sc->kue_mcfilters = kmem_alloc(KUE_MCFILTCNT(sc) * ETHER_ADDR_LEN, 509 KM_SLEEP); 510 511 usbnet_attach_ifp(un, IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST, 512 0, NULL); 513 } 514 515 static int 516 kue_detach(device_t self, int flags) 517 { 518 struct kue_softc *sc = device_private(self); 519 520 if (sc->kue_mcfilters != NULL) { 521 kmem_free(sc->kue_mcfilters, 522 KUE_MCFILTCNT(sc) * ETHER_ADDR_LEN); 523 sc->kue_mcfilters = NULL; 524 } 525 526 return usbnet_detach(self, flags); 527 } 528 529 /* 530 * A frame has been uploaded: pass the resulting mbuf chain up to 531 * the higher level protocols. 532 */ 533 static void 534 kue_uno_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len) 535 { 536 struct ifnet *ifp = usbnet_ifp(un); 537 uint8_t *buf = c->unc_buf; 538 unsigned pktlen; 539 540 if (total_len <= 1) 541 return; 542 543 DPRINTFN(10,("%s: %s: total_len=%d len=%d\n", 544 device_xname(un->un_dev), __func__, 545 total_len, le16dec(buf))); 546 547 pktlen = le16dec(buf); 548 if (pktlen > total_len - ETHER_ALIGN) 549 pktlen = total_len - ETHER_ALIGN; 550 551 if (pktlen < ETHER_MIN_LEN - ETHER_CRC_LEN || 552 pktlen > MCLBYTES - ETHER_ALIGN) { 553 if_statinc(ifp, if_ierrors); 554 return; 555 } 556 557 DPRINTFN(10,("%s: %s: deliver %d\n", device_xname(un->un_dev), 558 __func__, pktlen)); 559 usbnet_enqueue(un, buf + 2, pktlen, 0, 0, 0); 560 } 561 562 static unsigned 563 kue_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c) 564 { 565 unsigned total_len, pkt_len; 566 567 pkt_len = m->m_pkthdr.len + 2; 568 total_len = roundup2(pkt_len, 64); 569 570 if ((unsigned)total_len > un->un_tx_bufsz) { 571 DPRINTFN(10,("%s: %s: too big pktlen %u total %u\n", 572 device_xname(un->un_dev), __func__, pkt_len, total_len)); 573 return 0; 574 } 575 576 /* Frame length is specified in the first 2 bytes of the buffer. */ 577 le16enc(c->unc_buf, (uint16_t)m->m_pkthdr.len); 578 579 /* 580 * Copy the mbuf data into a contiguous buffer after the frame length, 581 * possibly zeroing the rest of the buffer. 582 */ 583 m_copydata(m, 0, m->m_pkthdr.len, c->unc_buf + 2); 584 if (total_len - pkt_len > 0) 585 memset(c->unc_buf + pkt_len, 0, total_len - pkt_len); 586 587 DPRINTFN(10,("%s: %s: enter pktlen %u total %u\n", 588 device_xname(un->un_dev), __func__, pkt_len, total_len)); 589 590 return total_len; 591 } 592 593 static int 594 kue_init_locked(struct ifnet *ifp) 595 { 596 struct usbnet * const un = ifp->if_softc; 597 struct kue_softc *sc = usbnet_softc(un); 598 uint8_t eaddr[ETHER_ADDR_LEN]; 599 600 DPRINTFN(5,("%s: %s: enter\n", device_xname(un->un_dev),__func__)); 601 602 if (usbnet_isdying(un)) 603 return EIO; 604 605 /* Cancel pending I/O */ 606 usbnet_stop(un, ifp, 1); 607 608 memcpy(eaddr, CLLADDR(ifp->if_sadl), sizeof(eaddr)); 609 /* Set MAC address */ 610 kue_ctl(un, KUE_CTL_WRITE, KUE_CMD_SET_MAC, 0, eaddr, ETHER_ADDR_LEN); 611 612 sc->kue_rxfilt = KUE_RXFILT_UNICAST | KUE_RXFILT_BROADCAST; 613 614 /* I'm not sure how to tune these. */ 615 #if 0 616 /* 617 * Leave this one alone for now; setting it 618 * wrong causes lockups on some machines/controllers. 619 */ 620 kue_setword(un, KUE_CMD_SET_SOFS, 1); 621 #endif 622 kue_setword(un, KUE_CMD_SET_URB_SIZE, 64); 623 624 /* Load the multicast filter. */ 625 kue_setiff_locked(un); 626 627 return usbnet_init_rx_tx(un); 628 } 629 630 static int 631 kue_uno_init(struct ifnet *ifp) 632 { 633 struct usbnet * const un = ifp->if_softc; 634 int rv; 635 636 usbnet_lock_core(un); 637 usbnet_busy(un); 638 rv = kue_init_locked(ifp); 639 usbnet_unbusy(un); 640 usbnet_unlock_core(un); 641 642 return rv; 643 } 644 645 static int 646 kue_uno_ioctl(struct ifnet *ifp, u_long cmd, void *data) 647 { 648 struct usbnet * const un = ifp->if_softc; 649 650 usbnet_lock_core(un); 651 usbnet_busy(un); 652 653 switch (cmd) { 654 case SIOCADDMULTI: 655 case SIOCDELMULTI: 656 kue_setiff_locked(un); 657 break; 658 default: 659 break; 660 } 661 662 usbnet_unbusy(un); 663 usbnet_unlock_core(un); 664 665 return 0; 666 } 667 668 #ifdef _MODULE 669 #include "ioconf.c" 670 #endif 671 672 USBNET_MODULE(kue) 673