if_udav.c revision 1.61 1 /* $NetBSD: if_udav.c,v 1.61 2019/08/07 19:21:48 skrll Exp $ */
2 /* $nabe: if_udav.c,v 1.3 2003/08/21 16:57:19 nabe Exp $ */
3
4 /*
5 * Copyright (c) 2003
6 * Shingo WATANABE <nabe (at) nabechan.org>. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the author nor the names of any co-contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 *
32 */
33
34 /*
35 * DM9601(DAVICOM USB to Ethernet MAC Controller with Integrated 10/100 PHY)
36 * The spec can be found at the following url.
37 * http://www.davicom.com.tw/big5/download/Data%20Sheet/DM9601-DS-F01-062202s.pdf
38 */
39
40 /*
41 * TODO:
42 * Interrupt Endpoint support
43 * External PHYs
44 * powerhook() support?
45 */
46
47 #include <sys/cdefs.h>
48 __KERNEL_RCSID(0, "$NetBSD: if_udav.c,v 1.61 2019/08/07 19:21:48 skrll Exp $");
49
50 #ifdef _KERNEL_OPT
51 #include "opt_usb.h"
52 #endif
53
54 #include <sys/param.h>
55 #include <sys/systm.h>
56 #include <sys/module.h>
57 #include <sys/kernel.h>
58
59 #include <dev/usb/usbnet.h>
60 #include <dev/usb/if_udavreg.h>
61
62 struct udav_softc {
63 struct usbnet sc_un;
64 uint16_t sc_flags;
65 };
66
67 /* Function declarations */
68 int udav_match(device_t, cfdata_t, void *);
69 void udav_attach(device_t, device_t, void *);
70
71 CFATTACH_DECL_NEW(udav, sizeof(struct udav_softc), udav_match, udav_attach,
72 usbnet_detach, usbnet_activate);
73
74 static void udav_chip_init(struct usbnet *);
75
76 static unsigned udav_tx_prepare(struct usbnet *, struct mbuf *,
77 struct usbnet_chain *);
78 static void udav_rxeof_loop(struct usbnet *, struct usbd_xfer *,
79 struct usbnet_chain *, uint32_t);
80 static void udav_stop_cb(struct ifnet *, int);
81 static int udav_ioctl_cb(struct ifnet *, u_long, void *);
82 static usbd_status udav_mii_read_reg(struct usbnet *, int, int, uint16_t *);
83 static usbd_status udav_mii_write_reg(struct usbnet *, int, int, uint16_t);
84 static void udav_mii_statchg(struct ifnet *);
85 static int udav_init(struct ifnet *);
86 static void udav_setiff(struct usbnet *);
87 static void udav_setiff_locked(struct usbnet *);
88 static void udav_reset(struct usbnet *);
89
90 static int udav_csr_read(struct udav_softc *, int, void *, int);
91 static int udav_csr_write(struct udav_softc *, int, void *, int);
92 static int udav_csr_read1(struct udav_softc *, int);
93 static int udav_csr_write1(struct udav_softc *, int, unsigned char);
94
95 #if 0
96 static int udav_mem_read(struct udav_softc *, int, void *, int);
97 static int udav_mem_write(struct udav_softc *, int, void *, int);
98 static int udav_mem_write1(struct udav_softc *, int, unsigned char);
99 #endif
100
101 /* Macros */
102 #ifdef UDAV_DEBUG
103 #define DPRINTF(x) if (udavdebug) printf x
104 #define DPRINTFN(n, x) if (udavdebug >= (n)) printf x
105 int udavdebug = 10;
106 #else
107 #define DPRINTF(x)
108 #define DPRINTFN(n, x)
109 #endif
110
111 #define UDAV_SETBIT(sc, reg, x) \
112 udav_csr_write1(sc, reg, udav_csr_read1(sc, reg) | (x))
113
114 #define UDAV_CLRBIT(sc, reg, x) \
115 udav_csr_write1(sc, reg, udav_csr_read1(sc, reg) & ~(x))
116
117 static const struct udav_type {
118 struct usb_devno udav_dev;
119 uint16_t udav_flags;
120 #define UDAV_EXT_PHY 0x0001
121 #define UDAV_NO_PHY 0x0002
122 } udav_devs [] = {
123 /* Corega USB-TXC */
124 {{ USB_VENDOR_COREGA, USB_PRODUCT_COREGA_FETHER_USB_TXC }, 0},
125 /* ShanTou ST268 USB NIC */
126 {{ USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_ST268_USB_NIC }, 0},
127 /* ShanTou ADM8515 */
128 {{ USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_ADM8515 }, 0},
129 /* SUNRISING SR9600 */
130 {{ USB_VENDOR_SUNRISING, USB_PRODUCT_SUNRISING_SR9600 }, 0 },
131 /* SUNRISING QF9700 */
132 {{ USB_VENDOR_SUNRISING, USB_PRODUCT_SUNRISING_QF9700 }, UDAV_NO_PHY },
133 /* QUAN DM9601 */
134 {{USB_VENDOR_QUAN, USB_PRODUCT_QUAN_DM9601 }, 0},
135 #if 0
136 /* DAVICOM DM9601 Generic? */
137 /* XXX: The following ids was obtained from the data sheet. */
138 {{ 0x0a46, 0x9601 }, 0},
139 #endif
140 };
141 #define udav_lookup(v, p) ((const struct udav_type *)usb_lookup(udav_devs, v, p))
142
143
144 /* Probe */
145 int
146 udav_match(device_t parent, cfdata_t match, void *aux)
147 {
148 struct usb_attach_arg *uaa = aux;
149
150 return udav_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL ?
151 UMATCH_VENDOR_PRODUCT : UMATCH_NONE;
152 }
153
154 /* Attach */
155 void
156 udav_attach(device_t parent, device_t self, void *aux)
157 {
158 struct udav_softc *sc = device_private(self);
159 struct usbnet * const un = &sc->sc_un;
160 struct usb_attach_arg *uaa = aux;
161 struct usbd_device *dev = uaa->uaa_device;
162 struct usbd_interface *iface;
163 usbd_status err;
164 usb_interface_descriptor_t *id;
165 usb_endpoint_descriptor_t *ed;
166 char *devinfop;
167 int i;
168
169 /* Switch to usbnet for device_private() */
170 self->dv_private = un;
171
172 aprint_naive("\n");
173 aprint_normal("\n");
174 devinfop = usbd_devinfo_alloc(dev, 0);
175 aprint_normal_dev(self, "%s\n", devinfop);
176 usbd_devinfo_free(devinfop);
177
178 un->un_dev = self;
179 un->un_udev = dev;
180 un->un_sc = sc;
181 un->un_stop_cb = udav_stop_cb;
182 un->un_ioctl_cb = udav_ioctl_cb;
183 un->un_read_reg_cb = udav_mii_read_reg;
184 un->un_write_reg_cb = udav_mii_write_reg;
185 un->un_statchg_cb = udav_mii_statchg;
186 un->un_tx_prepare_cb = udav_tx_prepare;
187 un->un_rx_loop_cb = udav_rxeof_loop;
188 un->un_init_cb = udav_init;
189 un->un_rx_xfer_flags = USBD_SHORT_XFER_OK;
190 un->un_tx_xfer_flags = USBD_FORCE_SHORT_XFER;
191
192 /* Move the device into the configured state. */
193 err = usbd_set_config_no(dev, UDAV_CONFIG_NO, 1); /* idx 0 */
194 if (err) {
195 aprint_error_dev(self, "failed to set configuration"
196 ", err=%s\n", usbd_errstr(err));
197 return;
198 }
199
200 /* get control interface */
201 err = usbd_device2interface_handle(dev, UDAV_IFACE_INDEX, &iface);
202 if (err) {
203 aprint_error_dev(self, "failed to get interface, err=%s\n",
204 usbd_errstr(err));
205 return;
206 }
207
208 un->un_iface = iface;
209 sc->sc_flags = udav_lookup(uaa->uaa_vendor,
210 uaa->uaa_product)->udav_flags;
211
212 /* get interface descriptor */
213 id = usbd_get_interface_descriptor(un->un_iface);
214
215 /* find endpoints */
216 un->un_ed[USBNET_ENDPT_RX] = un->un_ed[USBNET_ENDPT_TX] =
217 un->un_ed[USBNET_ENDPT_INTR] = -1;
218 for (i = 0; i < id->bNumEndpoints; i++) {
219 ed = usbd_interface2endpoint_descriptor(un->un_iface, i);
220 if (ed == NULL) {
221 aprint_error_dev(self, "couldn't get endpoint %d\n", i);
222 return;
223 }
224 if ((ed->bmAttributes & UE_XFERTYPE) == UE_BULK &&
225 UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN)
226 un->un_ed[USBNET_ENDPT_RX] = ed->bEndpointAddress;
227 else if ((ed->bmAttributes & UE_XFERTYPE) == UE_BULK &&
228 UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT)
229 un->un_ed[USBNET_ENDPT_TX] = ed->bEndpointAddress;
230 else if ((ed->bmAttributes & UE_XFERTYPE) == UE_INTERRUPT &&
231 UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN)
232 un->un_ed[USBNET_ENDPT_INTR] = ed->bEndpointAddress;
233 }
234
235 if (un->un_ed[USBNET_ENDPT_RX] == -1 ||
236 un->un_ed[USBNET_ENDPT_TX] == -1 ||
237 un->un_ed[USBNET_ENDPT_INTR] == -1) {
238 aprint_error_dev(self, "missing endpoint\n");
239 return;
240 }
241
242 /* Not supported yet. */
243 un->un_ed[USBNET_ENDPT_INTR] = 0;
244
245 un->un_cdata.uncd_rx_bufsz = un->un_cdata.uncd_tx_bufsz = UDAV_BUFSZ;
246
247 // /* reset the adapter */
248 // udav_reset(un);
249
250 usbnet_attach(un, "udavdet", UDAV_RX_LIST_CNT, UDAV_TX_LIST_CNT);
251
252 /* Get Ethernet Address */
253 usbnet_lock_mii(un);
254 err = udav_csr_read(sc, UDAV_PAR, un->un_eaddr, ETHER_ADDR_LEN);
255 usbnet_unlock_mii(un);
256 if (err) {
257 aprint_error_dev(self, "read MAC address failed\n");
258 return;
259 }
260
261 bool have_mii = !ISSET(sc->sc_flags, UDAV_NO_PHY);
262 if (!have_mii)
263 un->un_link = 1;
264
265 /* initialize interface information */
266 usbnet_attach_ifp(un, have_mii,
267 IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST, 0, 0);
268
269 return;
270 }
271
272 #if 0
273 /* read memory */
274 static int
275 udav_mem_read(struct udav_softc *sc, int offset, void *buf, int len)
276 {
277 usb_device_request_t req;
278 usbd_status err;
279
280 if (sc == NULL)
281 return 0;
282
283 DPRINTFN(0x200,
284 ("%s: %s: enter\n", device_xname(un->un_dev), __func__));
285
286 if (un->un_dying)
287 return 0;
288
289 offset &= 0xffff;
290 len &= 0xff;
291
292 req.bmRequestType = UT_READ_VENDOR_DEVICE;
293 req.bRequest = UDAV_REQ_MEM_READ;
294 USETW(req.wValue, 0x0000);
295 USETW(req.wIndex, offset);
296 USETW(req.wLength, len);
297
298 err = usbd_do_request(un->un_udev, &req, buf);
299 if (err) {
300 DPRINTF(("%s: %s: read failed. off=%04x, err=%d\n",
301 device_xname(un->un_dev), __func__, offset, err));
302 }
303
304 return err;
305 }
306
307 /* write memory */
308 static int
309 udav_mem_write(struct udav_softc *sc, int offset, void *buf, int len)
310 {
311 usb_device_request_t req;
312 usbd_status err;
313
314 if (sc == NULL)
315 return 0;
316
317 DPRINTFN(0x200,
318 ("%s: %s: enter\n", device_xname(un->un_dev), __func__));
319
320 if (un->un_dying)
321 return 0;
322
323 offset &= 0xffff;
324 len &= 0xff;
325
326 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
327 req.bRequest = UDAV_REQ_MEM_WRITE;
328 USETW(req.wValue, 0x0000);
329 USETW(req.wIndex, offset);
330 USETW(req.wLength, len);
331
332 err = usbd_do_request(un->un_udev, &req, buf);
333 if (err) {
334 DPRINTF(("%s: %s: write failed. off=%04x, err=%d\n",
335 device_xname(un->un_dev), __func__, offset, err));
336 }
337
338 return err;
339 }
340
341 /* write memory */
342 static int
343 udav_mem_write1(struct udav_softc *sc, int offset, unsigned char ch)
344 {
345 usb_device_request_t req;
346 usbd_status err;
347
348 if (sc == NULL)
349 return 0;
350
351 DPRINTFN(0x200,
352 ("%s: %s: enter\n", device_xname(un->un_dev), __func__));
353
354 if (un->un_dying)
355 return 0;
356
357 offset &= 0xffff;
358
359 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
360 req.bRequest = UDAV_REQ_MEM_WRITE1;
361 USETW(req.wValue, ch);
362 USETW(req.wIndex, offset);
363 USETW(req.wLength, 0x0000);
364
365 err = usbd_do_request(un->un_udev, &req, NULL);
366 if (err) {
367 DPRINTF(("%s: %s: write failed. off=%04x, err=%d\n",
368 device_xname(un->un_dev), __func__, offset, err));
369 }
370
371 return err;
372 }
373 #endif
374
375 /* read register(s) */
376 static int
377 udav_csr_read(struct udav_softc *sc, int offset, void *buf, int len)
378 {
379 struct usbnet * const un = &sc->sc_un;
380 usb_device_request_t req;
381 usbd_status err;
382
383 usbnet_isowned_mii(un);
384 KASSERT(!un->un_dying);
385
386 DPRINTFN(0x200,
387 ("%s: %s: enter\n", device_xname(un->un_dev), __func__));
388
389 offset &= 0xff;
390 len &= 0xff;
391
392 req.bmRequestType = UT_READ_VENDOR_DEVICE;
393 req.bRequest = UDAV_REQ_REG_READ;
394 USETW(req.wValue, 0x0000);
395 USETW(req.wIndex, offset);
396 USETW(req.wLength, len);
397
398 err = usbd_do_request(un->un_udev, &req, buf);
399 if (err) {
400 DPRINTF(("%s: %s: read failed. off=%04x, err=%d\n",
401 device_xname(un->un_dev), __func__, offset, err));
402 }
403
404 return err;
405 }
406
407 /* write register(s) */
408 static int
409 udav_csr_write(struct udav_softc *sc, int offset, void *buf, int len)
410 {
411 struct usbnet * const un = &sc->sc_un;
412 usb_device_request_t req;
413 usbd_status err;
414
415 usbnet_isowned_mii(un);
416 KASSERT(!un->un_dying);
417
418 DPRINTFN(0x200,
419 ("%s: %s: enter\n", device_xname(un->un_dev), __func__));
420
421 offset &= 0xff;
422 len &= 0xff;
423
424 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
425 req.bRequest = UDAV_REQ_REG_WRITE;
426 USETW(req.wValue, 0x0000);
427 USETW(req.wIndex, offset);
428 USETW(req.wLength, len);
429
430 err = usbd_do_request(un->un_udev, &req, buf);
431 if (err) {
432 DPRINTF(("%s: %s: write failed. off=%04x, err=%d\n",
433 device_xname(un->un_dev), __func__, offset, err));
434 }
435
436 return err;
437 }
438
439 static int
440 udav_csr_read1(struct udav_softc *sc, int offset)
441 {
442 struct usbnet * const un = &sc->sc_un;
443 uint8_t val = 0;
444
445 usbnet_isowned_mii(un);
446
447 DPRINTFN(0x200,
448 ("%s: %s: enter\n", device_xname(un->un_dev), __func__));
449
450 if (un->un_dying)
451 return 0;
452
453 return udav_csr_read(sc, offset, &val, 1) ? 0 : val;
454 }
455
456 /* write a register */
457 static int
458 udav_csr_write1(struct udav_softc *sc, int offset, unsigned char ch)
459 {
460 struct usbnet * const un = &sc->sc_un;
461 usb_device_request_t req;
462 usbd_status err;
463
464 usbnet_isowned_mii(un);
465 KASSERT(!un->un_dying);
466
467 DPRINTFN(0x200,
468 ("%s: %s: enter\n", device_xname(un->un_dev), __func__));
469
470 offset &= 0xff;
471
472 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
473 req.bRequest = UDAV_REQ_REG_WRITE1;
474 USETW(req.wValue, ch);
475 USETW(req.wIndex, offset);
476 USETW(req.wLength, 0x0000);
477
478 err = usbd_do_request(un->un_udev, &req, NULL);
479 if (err) {
480 DPRINTF(("%s: %s: write failed. off=%04x, err=%d\n",
481 device_xname(un->un_dev), __func__, offset, err));
482 }
483
484 return err;
485 }
486
487 static int
488 udav_init_locked(struct ifnet *ifp)
489 {
490 struct usbnet * const un = ifp->if_softc;
491 struct mii_data * const mii = usbnet_mii(un);
492 struct udav_softc *sc = usbnet_softc(un);
493 uint8_t eaddr[ETHER_ADDR_LEN];
494 int rc;
495
496 DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev), __func__));
497
498 usbnet_isowned(un);
499
500 if (un->un_dying)
501 return EIO;
502
503 /* Cancel pending I/O and free all TX/RX buffers */
504 if (ifp->if_flags & IFF_RUNNING)
505 usbnet_stop(un, ifp, 1);
506
507 usbnet_lock_mii_un_locked(un);
508
509 memcpy(eaddr, CLLADDR(ifp->if_sadl), sizeof(eaddr));
510 udav_csr_write(sc, UDAV_PAR, eaddr, ETHER_ADDR_LEN);
511
512 /* Initialize network control register */
513 /* Disable loopback */
514 UDAV_CLRBIT(sc, UDAV_NCR, UDAV_NCR_LBK0 | UDAV_NCR_LBK1);
515
516 /* Initialize RX control register */
517 UDAV_SETBIT(sc, UDAV_RCR, UDAV_RCR_DIS_LONG | UDAV_RCR_DIS_CRC);
518
519 /* If we want promiscuous mode, accept all physical frames. */
520 if (ifp->if_flags & IFF_PROMISC)
521 UDAV_SETBIT(sc, UDAV_RCR, UDAV_RCR_ALL | UDAV_RCR_PRMSC);
522 else
523 UDAV_CLRBIT(sc, UDAV_RCR, UDAV_RCR_ALL | UDAV_RCR_PRMSC);
524
525 /* Load the multicast filter */
526 udav_setiff_locked(un);
527
528 /* Enable RX */
529 UDAV_SETBIT(sc, UDAV_RCR, UDAV_RCR_RXEN);
530
531 /* clear POWER_DOWN state of internal PHY */
532 UDAV_SETBIT(sc, UDAV_GPCR, UDAV_GPCR_GEP_CNTL0);
533 UDAV_CLRBIT(sc, UDAV_GPR, UDAV_GPR_GEPIO0);
534
535 usbnet_unlock_mii_un_locked(un);
536
537 rc = 0;
538 if (mii) {
539 if ((rc = mii_mediachg(mii)) == ENXIO)
540 rc = 0;
541 }
542
543 if (rc != 0)
544 return rc;
545
546 return usbnet_init_rx_tx(un, 0, USBD_FORCE_SHORT_XFER);
547 }
548
549 static int
550 udav_init(struct ifnet *ifp)
551 {
552 struct usbnet * const un = ifp->if_softc;
553
554 usbnet_lock(un);
555 int ret = udav_init_locked(ifp);
556 usbnet_unlock(un);
557
558 return ret;
559 }
560
561 static void
562 udav_reset(struct usbnet *un)
563 {
564 usbnet_isowned(un);
565
566 if (un->un_dying)
567 return;
568
569 DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev), __func__));
570
571 udav_chip_init(un);
572 }
573
574 static void
575 udav_chip_init(struct usbnet *un)
576 {
577 struct udav_softc * const sc = usbnet_softc(un);
578
579 usbnet_lock_mii_un_locked(un);
580
581 /* Select PHY */
582 #if 1
583 /*
584 * XXX: force select internal phy.
585 * external phy routines are not tested.
586 */
587 UDAV_CLRBIT(sc, UDAV_NCR, UDAV_NCR_EXT_PHY);
588 #else
589 if (sc->sc_flags & UDAV_EXT_PHY) {
590 UDAV_SETBIT(sc, UDAV_NCR, UDAV_NCR_EXT_PHY);
591 } else {
592 UDAV_CLRBIT(sc, UDAV_NCR, UDAV_NCR_EXT_PHY);
593 }
594 #endif
595
596 UDAV_SETBIT(sc, UDAV_NCR, UDAV_NCR_RST);
597
598 for (int i = 0; i < UDAV_TX_TIMEOUT; i++) {
599 if (!(udav_csr_read1(sc, UDAV_NCR) & UDAV_NCR_RST))
600 break;
601 delay(10); /* XXX */
602 }
603 delay(10000); /* XXX */
604
605 usbnet_unlock_mii_un_locked(un);
606 }
607
608 #define UDAV_BITS 6
609
610 #define UDAV_CALCHASH(addr) \
611 (ether_crc32_le((addr), ETHER_ADDR_LEN) & ((1 << UDAV_BITS) - 1))
612
613 static void
614 udav_setiff_locked(struct usbnet *un)
615 {
616 struct udav_softc *sc = usbnet_softc(un);
617 struct ethercom *ec = usbnet_ec(un);
618 struct ifnet * const ifp = usbnet_ifp(un);
619 struct ether_multi *enm;
620 struct ether_multistep step;
621 uint8_t hashes[8];
622 int h = 0;
623
624 DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev), __func__));
625
626 usbnet_isowned_mii(un);
627
628 if (un->un_dying)
629 return;
630
631 if (ISSET(sc->sc_flags, UDAV_NO_PHY)) {
632 UDAV_SETBIT(sc, UDAV_RCR, UDAV_RCR_ALL);
633 UDAV_SETBIT(sc, UDAV_RCR, UDAV_RCR_PRMSC);
634 return;
635 }
636
637 if (ifp->if_flags & IFF_PROMISC) {
638 UDAV_SETBIT(sc, UDAV_RCR, UDAV_RCR_ALL | UDAV_RCR_PRMSC);
639 return;
640 } else if (ifp->if_flags & IFF_ALLMULTI) {
641 allmulti:
642 ifp->if_flags |= IFF_ALLMULTI;
643 UDAV_SETBIT(sc, UDAV_RCR, UDAV_RCR_ALL);
644 UDAV_CLRBIT(sc, UDAV_RCR, UDAV_RCR_PRMSC);
645 return;
646 }
647
648 /* first, zot all the existing hash bits */
649 memset(hashes, 0x00, sizeof(hashes));
650 hashes[7] |= 0x80; /* broadcast address */
651 udav_csr_write(sc, UDAV_MAR, hashes, sizeof(hashes));
652
653 /* now program new ones */
654 ETHER_LOCK(ec);
655 ETHER_FIRST_MULTI(step, ec, enm);
656 while (enm != NULL) {
657 if (memcmp(enm->enm_addrlo, enm->enm_addrhi,
658 ETHER_ADDR_LEN) != 0) {
659 ETHER_UNLOCK(ec);
660 goto allmulti;
661 }
662
663 h = UDAV_CALCHASH(enm->enm_addrlo);
664 hashes[h>>3] |= 1 << (h & 0x7);
665 ETHER_NEXT_MULTI(step, enm);
666 }
667 ETHER_UNLOCK(ec);
668
669 /* disable all multicast */
670 ifp->if_flags &= ~IFF_ALLMULTI;
671 UDAV_CLRBIT(sc, UDAV_RCR, UDAV_RCR_ALL);
672
673 /* write hash value to the register */
674 udav_csr_write(sc, UDAV_MAR, hashes, sizeof(hashes));
675 }
676
677 static void
678 udav_setiff(struct usbnet *un)
679 {
680 usbnet_lock_mii(un);
681 udav_setiff_locked(un);
682 usbnet_unlock_mii(un);
683 }
684
685
686 static unsigned
687 udav_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c)
688 {
689 int total_len;
690 uint8_t *buf = c->unc_buf;
691
692 usbnet_isowned_tx(un);
693
694 DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev), __func__));
695
696 if (m->m_pkthdr.len > UDAV_BUFSZ - 2)
697 return 0;
698
699 /* Copy the mbuf data into a contiguous buffer */
700 m_copydata(m, 0, m->m_pkthdr.len, buf + 2);
701 total_len = m->m_pkthdr.len;
702 if (total_len < UDAV_MIN_FRAME_LEN) {
703 memset(buf + 2 + total_len, 0,
704 UDAV_MIN_FRAME_LEN - total_len);
705 total_len = UDAV_MIN_FRAME_LEN;
706 }
707
708 /* Frame length is specified in the first 2bytes of the buffer */
709 buf[0] = (uint8_t)total_len;
710 buf[1] = (uint8_t)(total_len >> 8);
711 total_len += 2;
712
713 DPRINTF(("%s: %s: send %d bytes\n", device_xname(un->un_dev),
714 __func__, total_len));
715
716 return total_len;
717 }
718
719 static void
720 udav_rxeof_loop(struct usbnet *un, struct usbd_xfer *xfer,
721 struct usbnet_chain *c, uint32_t total_len)
722 {
723 struct ifnet *ifp = usbnet_ifp(un);
724 uint8_t *buf = c->unc_buf;
725 uint16_t pkt_len;
726 uint8_t pktstat;
727
728 DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev), __func__));
729
730 /* first byte in received data */
731 pktstat = *buf;
732 total_len -= sizeof(pktstat);
733 buf += sizeof(pktstat);
734
735 DPRINTF(("%s: RX Status: 0x%02x\n", device_xname(un->un_dev), pktstat));
736
737 pkt_len = UGETW(buf);
738 total_len -= sizeof(pkt_len);
739 buf += sizeof(pkt_len);
740
741 DPRINTF(("%s: RX Length: 0x%02x\n", device_xname(un->un_dev), pkt_len));
742
743 if (pktstat & UDAV_RSR_LCS) {
744 ifp->if_collisions++;
745 return;
746 }
747
748 if (pkt_len < sizeof(struct ether_header) ||
749 pkt_len > total_len ||
750 (pktstat & UDAV_RSR_ERR)) {
751 ifp->if_ierrors++;
752 return;
753 }
754
755 pkt_len -= ETHER_CRC_LEN;
756
757 DPRINTF(("%s: Rx deliver: 0x%02x\n", device_xname(un->un_dev), pkt_len));
758
759 usbnet_enqueue(un, buf, pkt_len, 0, 0, 0);
760 }
761
762 static int
763 udav_ioctl_cb(struct ifnet *ifp, u_long cmd, void *data)
764 {
765 struct usbnet * const un = ifp->if_softc;
766
767 switch (cmd) {
768 case SIOCADDMULTI:
769 case SIOCDELMULTI:
770 udav_setiff(un);
771 break;
772 default:
773 break;
774 }
775
776
777 return 0;
778 }
779
780 /* Stop the adapter and free any mbufs allocated to the RX and TX lists. */
781 static void
782 udav_stop_cb(struct ifnet *ifp, int disable)
783 {
784 struct usbnet * const un = ifp->if_softc;
785
786 DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev), __func__));
787
788 udav_reset(un);
789 }
790
791 static usbd_status
792 udav_mii_read_reg(struct usbnet *un, int phy, int reg, uint16_t *val)
793 {
794 struct udav_softc *sc = usbnet_softc(un);
795 uint8_t data[2];
796
797 usbnet_isowned_mii(un);
798
799 DPRINTFN(0xff, ("%s: %s: enter, phy=%d reg=0x%04x\n",
800 device_xname(un->un_dev), __func__, phy, reg));
801
802 if (un->un_dying) {
803 #ifdef DIAGNOSTIC
804 printf("%s: %s: dying\n", device_xname(un->un_dev),
805 __func__);
806 #endif
807 return USBD_INVAL;
808 }
809
810 /* XXX: one PHY only for the internal PHY */
811 if (phy != 0) {
812 DPRINTFN(0xff, ("%s: %s: phy=%d is not supported\n",
813 device_xname(un->un_dev), __func__, phy));
814 return USBD_INVAL;
815 }
816
817 /* select internal PHY and set PHY register address */
818 udav_csr_write1(sc, UDAV_EPAR,
819 UDAV_EPAR_PHY_ADR0 | (reg & UDAV_EPAR_EROA_MASK));
820
821 /* select PHY operation and start read command */
822 udav_csr_write1(sc, UDAV_EPCR, UDAV_EPCR_EPOS | UDAV_EPCR_ERPRR);
823
824 /* XXX: should be wait? */
825
826 /* end read command */
827 UDAV_CLRBIT(sc, UDAV_EPCR, UDAV_EPCR_ERPRR);
828
829 /* retrieve the result from data registers */
830 udav_csr_read(sc, UDAV_EPDRL, data, 2);
831
832 *val = data[0] | (data[1] << 8);
833
834 DPRINTFN(0xff, ("%s: %s: phy=%d reg=0x%04x => 0x%04hx\n",
835 device_xname(un->un_dev), __func__, phy, reg, *val));
836
837 return USBD_NORMAL_COMPLETION;
838 }
839
840 static usbd_status
841 udav_mii_write_reg(struct usbnet *un, int phy, int reg, uint16_t val)
842 {
843 struct udav_softc *sc = usbnet_softc(un);
844 uint8_t data[2];
845
846 usbnet_isowned_mii(un);
847
848 DPRINTFN(0xff, ("%s: %s: enter, phy=%d reg=0x%04x val=0x%04hx\n",
849 device_xname(un->un_dev), __func__, phy, reg, val));
850
851 if (un->un_dying) {
852 #ifdef DIAGNOSTIC
853 printf("%s: %s: dying\n", device_xname(un->un_dev),
854 __func__);
855 #endif
856 return -1;
857 }
858
859 /* XXX: one PHY only for the internal PHY */
860 if (phy != 0) {
861 DPRINTFN(0xff, ("%s: %s: phy=%d is not supported\n",
862 device_xname(un->un_dev), __func__, phy));
863 return -1;
864 }
865
866 /* select internal PHY and set PHY register address */
867 udav_csr_write1(sc, UDAV_EPAR,
868 UDAV_EPAR_PHY_ADR0 | (reg & UDAV_EPAR_EROA_MASK));
869
870 /* put the value to the data registers */
871 data[0] = val & 0xff;
872 data[1] = (val >> 8) & 0xff;
873 udav_csr_write(sc, UDAV_EPDRL, data, 2);
874
875 /* select PHY operation and start write command */
876 udav_csr_write1(sc, UDAV_EPCR, UDAV_EPCR_EPOS | UDAV_EPCR_ERPRW);
877
878 /* XXX: should be wait? */
879
880 /* end write command */
881 UDAV_CLRBIT(sc, UDAV_EPCR, UDAV_EPCR_ERPRW);
882
883 return USBD_NORMAL_COMPLETION;
884 }
885
886 static void
887 udav_mii_statchg(struct ifnet *ifp)
888 {
889 struct usbnet * const un = ifp->if_softc;
890 struct mii_data * const mii = usbnet_mii(un);
891
892 DPRINTF(("%s: %s: enter\n", ifp->if_xname, __func__));
893
894 if (un->un_dying)
895 return;
896
897 un->un_link = false;
898 if (mii->mii_media_status & IFM_ACTIVE &&
899 IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
900 DPRINTF(("%s: %s: got link\n",
901 device_xname(un->un_dev), __func__));
902 un->un_link = true;
903 }
904 }
905
906 MODULE(MODULE_CLASS_DRIVER, if_udav, "usbnet");
907
908 #ifdef _MODULE
909 #include "ioconf.c"
910 #endif
911
912 static int
913 if_udav_modcmd(modcmd_t cmd, void *aux)
914 {
915 int error = 0;
916
917 switch (cmd) {
918 case MODULE_CMD_INIT:
919 #ifdef _MODULE
920 error = config_init_component(cfdriver_ioconf_udav,
921 cfattach_ioconf_udav, cfdata_ioconf_udav);
922 #endif
923 return error;
924 case MODULE_CMD_FINI:
925 #ifdef _MODULE
926 error = config_fini_component(cfdriver_ioconf_udav,
927 cfattach_ioconf_udav, cfdata_ioconf_udav);
928 #endif
929 return error;
930 default:
931 return ENOTTY;
932 }
933 }
934