FreeBSD kernel usb device Code
if_udav.c
Go to the documentation of this file.
1/* $NetBSD: if_udav.c,v 1.2 2003/09/04 15:17:38 tsutsui Exp $ */
2/* $nabe: if_udav.c,v 1.3 2003/08/21 16:57:19 nabe Exp $ */
3/* $FreeBSD$ */
4/*-
5 * SPDX-License-Identifier: BSD-3-Clause
6 *
7 * Copyright (c) 2003
8 * Shingo WATANABE <nabe@nabechan.org>. 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
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. 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 THE AUTHOR 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 THE AUTHOR OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 *
34 */
35
36/*
37 * DM9601(DAVICOM USB to Ethernet MAC Controller with Integrated 10/100 PHY)
38 * The spec can be found at the following url.
39 * http://ptm2.cc.utu.fi/ftp/network/cards/DM9601/From_NET/DM9601-DS-P01-930914.pdf
40 */
41
42/*
43 * TODO:
44 * Interrupt Endpoint support
45 * External PHYs
46 */
47
48#include <sys/cdefs.h>
49__FBSDID("$FreeBSD$");
50
51#include <sys/stdint.h>
52#include <sys/stddef.h>
53#include <sys/param.h>
54#include <sys/queue.h>
55#include <sys/types.h>
56#include <sys/systm.h>
57#include <sys/socket.h>
58#include <sys/kernel.h>
59#include <sys/bus.h>
60#include <sys/module.h>
61#include <sys/lock.h>
62#include <sys/mutex.h>
63#include <sys/condvar.h>
64#include <sys/sysctl.h>
65#include <sys/sx.h>
66#include <sys/unistd.h>
67#include <sys/callout.h>
68#include <sys/malloc.h>
69#include <sys/priv.h>
70
71#include <net/if.h>
72#include <net/if_var.h>
73#include <net/if_media.h>
74
75#include <dev/mii/mii.h>
76#include <dev/mii/miivar.h>
77
78#include <dev/usb/usb.h>
79#include <dev/usb/usbdi.h>
80#include <dev/usb/usbdi_util.h>
81#include "usbdevs.h"
82
83#include "miibus_if.h"
84
85#define USB_DEBUG_VAR udav_debug
86#include <dev/usb/usb_debug.h>
87#include <dev/usb/usb_process.h>
88
91
92/* prototypes */
93
94static device_probe_t udav_probe;
95static device_attach_t udav_attach;
96static device_detach_t udav_detach;
97
101
109
110static int udav_csr_read(struct udav_softc *, uint16_t, void *, int);
111static int udav_csr_write(struct udav_softc *, uint16_t, void *, int);
112static uint8_t udav_csr_read1(struct udav_softc *, uint16_t);
113static int udav_csr_write1(struct udav_softc *, uint16_t, uint8_t);
114static void udav_reset(struct udav_softc *);
115static int udav_ifmedia_upd(struct ifnet *);
116static void udav_ifmedia_status(struct ifnet *, struct ifmediareq *);
117
118static miibus_readreg_t udav_miibus_readreg;
119static miibus_writereg_t udav_miibus_writereg;
120static miibus_statchg_t udav_miibus_statchg;
121
122static const struct usb_config udav_config[UDAV_N_TRANSFER] = {
123 [UDAV_BULK_DT_WR] = {
124 .type = UE_BULK,
125 .endpoint = UE_ADDR_ANY,
126 .direction = UE_DIR_OUT,
127 .bufsize = (MCLBYTES + 2),
128 .flags = {.pipe_bof = 1,.force_short_xfer = 1,},
129 .callback = udav_bulk_write_callback,
130 .timeout = 10000, /* 10 seconds */
131 },
132
133 [UDAV_BULK_DT_RD] = {
134 .type = UE_BULK,
135 .endpoint = UE_ADDR_ANY,
136 .direction = UE_DIR_IN,
137 .bufsize = (MCLBYTES + 3),
138 .flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
139 .callback = udav_bulk_read_callback,
140 .timeout = 0, /* no timeout */
141 },
142
143 [UDAV_INTR_DT_RD] = {
144 .type = UE_INTERRUPT,
145 .endpoint = UE_ADDR_ANY,
146 .direction = UE_DIR_IN,
147 .flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
148 .bufsize = 0, /* use wMaxPacketSize */
149 .callback = udav_intr_callback,
150 },
151};
152
153static device_method_t udav_methods[] = {
154 /* Device interface */
155 DEVMETHOD(device_probe, udav_probe),
156 DEVMETHOD(device_attach, udav_attach),
157 DEVMETHOD(device_detach, udav_detach),
158
159 /* MII interface */
160 DEVMETHOD(miibus_readreg, udav_miibus_readreg),
161 DEVMETHOD(miibus_writereg, udav_miibus_writereg),
162 DEVMETHOD(miibus_statchg, udav_miibus_statchg),
163
164 DEVMETHOD_END
165};
166
167static driver_t udav_driver = {
168 .name = "udav",
169 .methods = udav_methods,
170 .size = sizeof(struct udav_softc),
171};
172
173static devclass_t udav_devclass;
174
176 /* ShanTou DM9601 USB NIC */
177 {USB_VPI(USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_DM9601, 0)},
178 /* ShanTou ST268 USB NIC */
179 {USB_VPI(USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_ST268, 0)},
180 /* Corega USB-TXC */
181 {USB_VPI(USB_VENDOR_COREGA, USB_PRODUCT_COREGA_FETHER_USB_TXC, 0)},
182 /* ShanTou AMD8515 USB NIC */
183 {USB_VPI(USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_ADM8515, 0)},
184 /* Kontron AG USB Ethernet */
185 {USB_VPI(USB_VENDOR_KONTRON, USB_PRODUCT_KONTRON_DM9601, 0)},
186 {USB_VPI(USB_VENDOR_KONTRON, USB_PRODUCT_KONTRON_JP1082,
188};
189
191DRIVER_MODULE(miibus, udav, miibus_driver, miibus_devclass, 0, 0);
192MODULE_DEPEND(udav, uether, 1, 1, 1);
193MODULE_DEPEND(udav, usb, 1, 1, 1);
194MODULE_DEPEND(udav, ether, 1, 1, 1);
195MODULE_DEPEND(udav, miibus, 1, 1, 1);
198
199static const struct usb_ether_methods udav_ue_methods = {
201 .ue_start = udav_start,
202 .ue_init = udav_init,
203 .ue_stop = udav_stop,
204 .ue_tick = udav_tick,
205 .ue_setmulti = udav_setmulti,
206 .ue_setpromisc = udav_setpromisc,
207 .ue_mii_upd = udav_ifmedia_upd,
208 .ue_mii_sts = udav_ifmedia_status,
209};
210
213 .ue_start = udav_start,
214 .ue_init = udav_init,
215 .ue_stop = udav_stop,
216 .ue_setmulti = udav_setmulti,
217 .ue_setpromisc = udav_setpromisc,
218};
219
220#ifdef USB_DEBUG
221static int udav_debug = 0;
222
223static SYSCTL_NODE(_hw_usb, OID_AUTO, udav, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
224 "USB udav");
225SYSCTL_INT(_hw_usb_udav, OID_AUTO, debug, CTLFLAG_RWTUN, &udav_debug, 0,
226 "Debug level");
227#endif
228
229#define UDAV_SETBIT(sc, reg, x) \
230 udav_csr_write1(sc, reg, udav_csr_read1(sc, reg) | (x))
231
232#define UDAV_CLRBIT(sc, reg, x) \
233 udav_csr_write1(sc, reg, udav_csr_read1(sc, reg) & ~(x))
234
235static void
237{
238 struct udav_softc *sc = uether_getsc(ue);
239
240 /* reset the adapter */
241 udav_reset(sc);
242
243 /* Get Ethernet Address */
244 udav_csr_read(sc, UDAV_PAR, ue->ue_eaddr, ETHER_ADDR_LEN);
245}
246
247static int
248udav_probe(device_t dev)
249{
250 struct usb_attach_arg *uaa = device_get_ivars(dev);
251
252 if (uaa->usb_mode != USB_MODE_HOST)
253 return (ENXIO);
255 return (ENXIO);
257 return (ENXIO);
258
259 return (usbd_lookup_id_by_uaa(udav_devs, sizeof(udav_devs), uaa));
260}
261
262static int
263udav_attach(device_t dev)
264{
265 struct usb_attach_arg *uaa = device_get_ivars(dev);
266 struct udav_softc *sc = device_get_softc(dev);
267 struct usb_ether *ue = &sc->sc_ue;
268 uint8_t iface_index;
269 int error;
270
271 sc->sc_flags = USB_GET_DRIVER_INFO(uaa);
272
274
275 mtx_init(&sc->sc_mtx, device_get_nameunit(dev), NULL, MTX_DEF);
276
277 iface_index = UDAV_IFACE_INDEX;
278 error = usbd_transfer_setup(uaa->device, &iface_index,
279 sc->sc_xfer, udav_config, UDAV_N_TRANSFER, sc, &sc->sc_mtx);
280 if (error) {
281 device_printf(dev, "allocating USB transfers failed\n");
282 goto detach;
283 }
284
285 /*
286 * The JP1082 has an unusable PHY and provides no link information.
287 */
288 if (sc->sc_flags & UDAV_FLAG_NO_PHY) {
291 } else {
293 }
294
295 ue->ue_sc = sc;
296 ue->ue_dev = dev;
297 ue->ue_udev = uaa->device;
298 ue->ue_mtx = &sc->sc_mtx;
299
301 if (error) {
302 device_printf(dev, "could not attach interface\n");
303 goto detach;
304 }
305
306 return (0); /* success */
307
308detach:
310 return (ENXIO); /* failure */
311}
312
313static int
314udav_detach(device_t dev)
315{
316 struct udav_softc *sc = device_get_softc(dev);
317 struct usb_ether *ue = &sc->sc_ue;
318
320 uether_ifdetach(ue);
321 mtx_destroy(&sc->sc_mtx);
322
323 return (0);
324}
325
326#if 0
327static int
328udav_mem_read(struct udav_softc *sc, uint16_t offset, void *buf,
329 int len)
330{
331 struct usb_device_request req;
332
333 len &= 0xff;
334
335 req.bmRequestType = UT_READ_VENDOR_DEVICE;
336 req.bRequest = UDAV_REQ_MEM_READ;
337 USETW(req.wValue, 0x0000);
338 USETW(req.wIndex, offset);
339 USETW(req.wLength, len);
340
341 return (uether_do_request(&sc->sc_ue, &req, buf, 1000));
342}
343
344static int
345udav_mem_write(struct udav_softc *sc, uint16_t offset, void *buf,
346 int len)
347{
348 struct usb_device_request req;
349
350 len &= 0xff;
351
352 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
353 req.bRequest = UDAV_REQ_MEM_WRITE;
354 USETW(req.wValue, 0x0000);
355 USETW(req.wIndex, offset);
356 USETW(req.wLength, len);
357
358 return (uether_do_request(&sc->sc_ue, &req, buf, 1000));
359}
360
361static int
362udav_mem_write1(struct udav_softc *sc, uint16_t offset,
363 uint8_t ch)
364{
365 struct usb_device_request req;
366
367 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
368 req.bRequest = UDAV_REQ_MEM_WRITE1;
369 USETW(req.wValue, ch);
370 USETW(req.wIndex, offset);
371 USETW(req.wLength, 0x0000);
372
373 return (uether_do_request(&sc->sc_ue, &req, NULL, 1000));
374}
375#endif
376
377static int
378udav_csr_read(struct udav_softc *sc, uint16_t offset, void *buf, int len)
379{
380 struct usb_device_request req;
381
382 len &= 0xff;
383
384 req.bmRequestType = UT_READ_VENDOR_DEVICE;
385 req.bRequest = UDAV_REQ_REG_READ;
386 USETW(req.wValue, 0x0000);
387 USETW(req.wIndex, offset);
388 USETW(req.wLength, len);
389
390 return (uether_do_request(&sc->sc_ue, &req, buf, 1000));
391}
392
393static int
394udav_csr_write(struct udav_softc *sc, uint16_t offset, void *buf, int len)
395{
396 struct usb_device_request req;
397
398 offset &= 0xff;
399 len &= 0xff;
400
401 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
402 req.bRequest = UDAV_REQ_REG_WRITE;
403 USETW(req.wValue, 0x0000);
404 USETW(req.wIndex, offset);
405 USETW(req.wLength, len);
406
407 return (uether_do_request(&sc->sc_ue, &req, buf, 1000));
408}
409
410static uint8_t
411udav_csr_read1(struct udav_softc *sc, uint16_t offset)
412{
413 uint8_t val;
414
415 udav_csr_read(sc, offset, &val, 1);
416 return (val);
417}
418
419static int
420udav_csr_write1(struct udav_softc *sc, uint16_t offset,
421 uint8_t ch)
422{
423 struct usb_device_request req;
424
425 offset &= 0xff;
426
427 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
428 req.bRequest = UDAV_REQ_REG_WRITE1;
429 USETW(req.wValue, ch);
430 USETW(req.wIndex, offset);
431 USETW(req.wLength, 0x0000);
432
433 return (uether_do_request(&sc->sc_ue, &req, NULL, 1000));
434}
435
436static void
438{
439 struct udav_softc *sc = ue->ue_sc;
440 struct ifnet *ifp = uether_getifp(&sc->sc_ue);
441
442 UDAV_LOCK_ASSERT(sc, MA_OWNED);
443
444 /*
445 * Cancel pending I/O
446 */
447 udav_stop(ue);
448
449 /* set MAC address */
450 udav_csr_write(sc, UDAV_PAR, IF_LLADDR(ifp), ETHER_ADDR_LEN);
451
452 /* initialize network control register */
453
454 /* disable loopback */
456
457 /* Initialize RX control register */
459
460 /* load multicast filter and update promiscious mode bit */
461 udav_setpromisc(ue);
462
463 /* enable RX */
465
466 /* clear POWER_DOWN state of internal PHY */
469
471
472 ifp->if_drv_flags |= IFF_DRV_RUNNING;
473 udav_start(ue);
474}
475
476static void
478{
479 int i;
480
481 /* Select PHY */
482#if 1
483 /*
484 * XXX: force select internal phy.
485 * external phy routines are not tested.
486 */
488#else
489 if (sc->sc_flags & UDAV_EXT_PHY)
491 else
493#endif
494
496
497 for (i = 0; i < UDAV_TX_TIMEOUT; i++) {
499 break;
500 if (uether_pause(&sc->sc_ue, hz / 100))
501 break;
502 }
503
504 uether_pause(&sc->sc_ue, hz / 100);
505}
506
507static u_int
508udav_hash_maddr(void *arg, struct sockaddr_dl *sdl, u_int cnt)
509{
510 uint8_t *hashtbl = arg;
511 int h;
512
513 h = ether_crc32_be(LLADDR(sdl), ETHER_ADDR_LEN) >> 26;
514 hashtbl[h / 8] |= 1 << (h % 8);
515
516 return (1);
517}
518
519static void
521{
522 struct udav_softc *sc = ue->ue_sc;
523 struct ifnet *ifp = uether_getifp(&sc->sc_ue);
524 uint8_t hashtbl[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
525
526 UDAV_LOCK_ASSERT(sc, MA_OWNED);
527
528 if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
530 return;
531 }
532
533 /* first, zot all the existing hash bits */
534 memset(hashtbl, 0x00, sizeof(hashtbl));
535 hashtbl[7] |= 0x80; /* broadcast address */
536 udav_csr_write(sc, UDAV_MAR, hashtbl, sizeof(hashtbl));
537
538 /* now program new ones */
539 if_foreach_llmaddr(ifp, udav_hash_maddr, hashtbl);
540
541 /* disable all multicast */
543
544 /* write hash value to the register */
545 udav_csr_write(sc, UDAV_MAR, hashtbl, sizeof(hashtbl));
546}
547
548static void
550{
551 struct udav_softc *sc = ue->ue_sc;
552 struct ifnet *ifp = uether_getifp(&sc->sc_ue);
553 uint8_t rxmode;
554
555 rxmode = udav_csr_read1(sc, UDAV_RCR);
556 rxmode &= ~(UDAV_RCR_ALL | UDAV_RCR_PRMSC);
557
558 if (ifp->if_flags & IFF_PROMISC)
559 rxmode |= UDAV_RCR_ALL | UDAV_RCR_PRMSC;
560 else if (ifp->if_flags & IFF_ALLMULTI)
561 rxmode |= UDAV_RCR_ALL;
562
563 /* write new mode bits */
564 udav_csr_write1(sc, UDAV_RCR, rxmode);
565}
566
567static void
569{
570 struct udav_softc *sc = ue->ue_sc;
571
572 /*
573 * start the USB transfers, if not already started:
574 */
578}
579
580static void
582{
583 struct udav_softc *sc = usbd_xfer_softc(xfer);
584 struct ifnet *ifp = uether_getifp(&sc->sc_ue);
585 struct usb_page_cache *pc;
586 struct mbuf *m;
587 int extra_len;
588 int temp_len;
589 uint8_t buf[2];
590
591 switch (USB_GET_STATE(xfer)) {
593 DPRINTFN(11, "transfer complete\n");
594 if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
595
596 /* FALLTHROUGH */
597 case USB_ST_SETUP:
598tr_setup:
599 if ((sc->sc_flags & UDAV_FLAG_LINK) == 0) {
600 /*
601 * don't send anything if there is no link !
602 */
603 return;
604 }
605 IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
606
607 if (m == NULL)
608 return;
609 if (m->m_pkthdr.len > MCLBYTES)
610 m->m_pkthdr.len = MCLBYTES;
611 if (m->m_pkthdr.len < UDAV_MIN_FRAME_LEN) {
612 extra_len = UDAV_MIN_FRAME_LEN - m->m_pkthdr.len;
613 } else {
614 extra_len = 0;
615 }
616
617 temp_len = (m->m_pkthdr.len + extra_len);
618
619 /*
620 * the frame length is specified in the first 2 bytes of the
621 * buffer
622 */
623 buf[0] = (uint8_t)(temp_len);
624 buf[1] = (uint8_t)(temp_len >> 8);
625
626 temp_len += 2;
627
628 pc = usbd_xfer_get_frame(xfer, 0);
629 usbd_copy_in(pc, 0, buf, 2);
630 usbd_m_copy_in(pc, 2, m, 0, m->m_pkthdr.len);
631
632 if (extra_len)
633 usbd_frame_zero(pc, temp_len - extra_len, extra_len);
634 /*
635 * if there's a BPF listener, bounce a copy
636 * of this frame to him:
637 */
638 BPF_MTAP(ifp, m);
639
640 m_freem(m);
641
642 usbd_xfer_set_frame_len(xfer, 0, temp_len);
644 return;
645
646 default: /* Error */
647 DPRINTFN(11, "transfer error, %s\n",
649
650 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
651
652 if (error != USB_ERR_CANCELLED) {
653 /* try to clear stall first */
655 goto tr_setup;
656 }
657 return;
658 }
659}
660
661static void
663{
664 struct udav_softc *sc = usbd_xfer_softc(xfer);
665 struct usb_ether *ue = &sc->sc_ue;
666 struct ifnet *ifp = uether_getifp(ue);
667 struct usb_page_cache *pc;
668 struct udav_rxpkt stat;
669 int len;
670 int actlen;
671
672 usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
673
674 switch (USB_GET_STATE(xfer)) {
676
677 if (actlen < (int)(sizeof(stat) + ETHER_CRC_LEN)) {
678 if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
679 goto tr_setup;
680 }
681 pc = usbd_xfer_get_frame(xfer, 0);
682 usbd_copy_out(pc, 0, &stat, sizeof(stat));
683 actlen -= sizeof(stat);
684 len = min(actlen, le16toh(stat.pktlen));
685 len -= ETHER_CRC_LEN;
686
687 if (stat.rxstat & UDAV_RSR_LCS) {
688 if_inc_counter(ifp, IFCOUNTER_COLLISIONS, 1);
689 goto tr_setup;
690 }
691 if (stat.rxstat & UDAV_RSR_ERR) {
692 if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
693 goto tr_setup;
694 }
695 uether_rxbuf(ue, pc, sizeof(stat), len);
696 /* FALLTHROUGH */
697 case USB_ST_SETUP:
698tr_setup:
701 uether_rxflush(ue);
702 return;
703
704 default: /* Error */
705 DPRINTF("bulk read error, %s\n",
707
708 if (error != USB_ERR_CANCELLED) {
709 /* try to clear stall first */
711 goto tr_setup;
712 }
713 return;
714 }
715}
716
717static void
719{
720 switch (USB_GET_STATE(xfer)) {
722 case USB_ST_SETUP:
723tr_setup:
726 return;
727
728 default: /* Error */
729 if (error != USB_ERR_CANCELLED) {
730 /* try to clear stall first */
732 goto tr_setup;
733 }
734 return;
735 }
736}
737
738static void
740{
741 struct udav_softc *sc = ue->ue_sc;
742 struct ifnet *ifp = uether_getifp(&sc->sc_ue);
743
744 UDAV_LOCK_ASSERT(sc, MA_OWNED);
745
746 ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
747 if (!(sc->sc_flags & UDAV_FLAG_NO_PHY))
748 sc->sc_flags &= ~UDAV_FLAG_LINK;
749
750 /*
751 * stop all the transfers, if not already stopped:
752 */
756
757 udav_reset(sc);
758}
759
760static int
761udav_ifmedia_upd(struct ifnet *ifp)
762{
763 struct udav_softc *sc = ifp->if_softc;
764 struct mii_data *mii = GET_MII(sc);
765 struct mii_softc *miisc;
766 int error;
767
768 UDAV_LOCK_ASSERT(sc, MA_OWNED);
769
770 sc->sc_flags &= ~UDAV_FLAG_LINK;
771 LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
772 PHY_RESET(miisc);
773 error = mii_mediachg(mii);
774 return (error);
775}
776
777static void
778udav_ifmedia_status(struct ifnet *ifp, struct ifmediareq *ifmr)
779{
780 struct udav_softc *sc = ifp->if_softc;
781 struct mii_data *mii = GET_MII(sc);
782
783 UDAV_LOCK(sc);
784 mii_pollstat(mii);
785 ifmr->ifm_active = mii->mii_media_active;
786 ifmr->ifm_status = mii->mii_media_status;
787 UDAV_UNLOCK(sc);
788}
789
790static void
792{
793 struct udav_softc *sc = ue->ue_sc;
794 struct mii_data *mii = GET_MII(sc);
795
796 UDAV_LOCK_ASSERT(sc, MA_OWNED);
797
798 mii_tick(mii);
799 if ((sc->sc_flags & UDAV_FLAG_LINK) == 0
800 && mii->mii_media_status & IFM_ACTIVE &&
801 IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
803 udav_start(ue);
804 }
805}
806
807static int
808udav_miibus_readreg(device_t dev, int phy, int reg)
809{
810 struct udav_softc *sc = device_get_softc(dev);
811 uint16_t data16;
812 uint8_t val[2];
813 int locked;
814
815 /* XXX: one PHY only for the internal PHY */
816 if (phy != 0)
817 return (0);
818
819 locked = mtx_owned(&sc->sc_mtx);
820 if (!locked)
821 UDAV_LOCK(sc);
822
823 /* select internal PHY and set PHY register address */
826
827 /* select PHY operation and start read command */
829
830 /* XXX: should we wait? */
831
832 /* end read command */
834
835 /* retrieve the result from data registers */
837
838 data16 = (val[0] | (val[1] << 8));
839
840 DPRINTFN(11, "phy=%d reg=0x%04x => 0x%04x\n",
841 phy, reg, data16);
842
843 if (!locked)
844 UDAV_UNLOCK(sc);
845 return (data16);
846}
847
848static int
849udav_miibus_writereg(device_t dev, int phy, int reg, int data)
850{
851 struct udav_softc *sc = device_get_softc(dev);
852 uint8_t val[2];
853 int locked;
854
855 /* XXX: one PHY only for the internal PHY */
856 if (phy != 0)
857 return (0);
858
859 locked = mtx_owned(&sc->sc_mtx);
860 if (!locked)
861 UDAV_LOCK(sc);
862
863 /* select internal PHY and set PHY register address */
866
867 /* put the value to the data registers */
868 val[0] = (data & 0xff);
869 val[1] = (data >> 8) & 0xff;
871
872 /* select PHY operation and start write command */
874
875 /* XXX: should we wait? */
876
877 /* end write command */
879
880 if (!locked)
881 UDAV_UNLOCK(sc);
882 return (0);
883}
884
885static void
887{
888 /* nothing to do */
889}
static int debug
Definition: cfumass.c:73
static SYSCTL_NODE(_hw_usb, OID_AUTO, dwc_otg, CTLFLAG_RW|CTLFLAG_MPSAFE, 0, "USB DWC OTG")
SYSCTL_INT(_hw_usb_dwc_otg, OID_AUTO, phy_type, CTLFLAG_RDTUN, &dwc_otg_phy_type, 0, "DWC OTG PHY TYPE - 0/1/2/3 - ULPI/HSIC/INTERNAL/UTMI+")
uint16_t len
Definition: ehci.h:41
#define GET_MII(sc)
Definition: if_auereg.h:188
uint32_t reg
Definition: if_rum.c:283
uint32_t val
Definition: if_rum.c:284
struct @109 error
static device_detach_t udav_detach
Definition: if_udav.c:96
#define UDAV_CLRBIT(sc, reg, x)
Definition: if_udav.c:232
static device_attach_t udav_attach
Definition: if_udav.c:95
static device_probe_t udav_probe
Definition: if_udav.c:94
static void udav_ifmedia_status(struct ifnet *, struct ifmediareq *)
Definition: if_udav.c:778
static const struct usb_config udav_config[UDAV_N_TRANSFER]
Definition: if_udav.c:122
static uether_fn_t udav_start
Definition: if_udav.c:105
static miibus_statchg_t udav_miibus_statchg
Definition: if_udav.c:120
static uether_fn_t udav_tick
Definition: if_udav.c:106
static uether_fn_t udav_setmulti
Definition: if_udav.c:107
static usb_callback_t udav_bulk_read_callback
Definition: if_udav.c:99
static u_int udav_hash_maddr(void *arg, struct sockaddr_dl *sdl, u_int cnt)
Definition: if_udav.c:508
static void udav_reset(struct udav_softc *)
Definition: if_udav.c:477
static const struct usb_ether_methods udav_ue_methods
Definition: if_udav.c:199
static int udav_csr_read(struct udav_softc *, uint16_t, void *, int)
Definition: if_udav.c:378
static usb_callback_t udav_bulk_write_callback
Definition: if_udav.c:98
static uint8_t udav_csr_read1(struct udav_softc *, uint16_t)
Definition: if_udav.c:411
static const struct usb_ether_methods udav_ue_methods_nophy
Definition: if_udav.c:211
static uether_fn_t udav_stop
Definition: if_udav.c:104
__FBSDID("$FreeBSD$")
static usb_callback_t udav_intr_callback
Definition: if_udav.c:100
MODULE_VERSION(udav, 1)
#define UDAV_SETBIT(sc, reg, x)
Definition: if_udav.c:229
USB_PNP_HOST_INFO(udav_devs)
static uether_fn_t udav_setpromisc
Definition: if_udav.c:108
static miibus_writereg_t udav_miibus_writereg
Definition: if_udav.c:119
MODULE_DEPEND(udav, uether, 1, 1, 1)
DRIVER_MODULE(udav, uhub, udav_driver, udav_devclass, NULL, 0)
static miibus_readreg_t udav_miibus_readreg
Definition: if_udav.c:118
static int udav_csr_write(struct udav_softc *, uint16_t, void *, int)
Definition: if_udav.c:394
static device_method_t udav_methods[]
Definition: if_udav.c:153
static uether_fn_t udav_init
Definition: if_udav.c:103
static devclass_t udav_devclass
Definition: if_udav.c:173
static const STRUCT_USB_HOST_ID udav_devs[]
Definition: if_udav.c:175
static driver_t udav_driver
Definition: if_udav.c:167
static uether_fn_t udav_attach_post
Definition: if_udav.c:102
static int udav_csr_write1(struct udav_softc *, uint16_t, uint8_t)
Definition: if_udav.c:420
static int udav_ifmedia_upd(struct ifnet *)
Definition: if_udav.c:761
#define UDAV_RCR_RXEN
Definition: if_udavreg.h:74
#define UDAV_REQ_REG_READ
Definition: if_udavreg.h:49
#define UDAV_TX_TIMEOUT
Definition: if_udavreg.h:42
#define UDAV_PAR
Definition: if_udavreg.h:112
#define UDAV_EPAR
Definition: if_udavreg.h:97
@ UDAV_BULK_DT_WR
Definition: if_udavreg.h:150
@ UDAV_INTR_DT_RD
Definition: if_udavreg.h:152
@ UDAV_BULK_DT_RD
Definition: if_udavreg.h:151
@ UDAV_N_TRANSFER
Definition: if_udavreg.h:153
#define UDAV_UNLOCK(_sc)
Definition: if_udavreg.h:168
#define UDAV_MIN_FRAME_LEN
Definition: if_udavreg.h:46
#define UDAV_REQ_REG_WRITE
Definition: if_udavreg.h:50
#define UDAV_RCR_ALL
Definition: if_udavreg.h:71
#define UDAV_IFACE_INDEX
Definition: if_udavreg.h:36
#define UDAV_FLAG_NO_PHY
Definition: if_udavreg.h:164
#define UDAV_RSR_LCS
Definition: if_udavreg.h:79
#define UDAV_RSR_ERR
Definition: if_udavreg.h:85
#define UDAV_GPCR_GEP_CNTL0
Definition: if_udavreg.h:131
#define UDAV_GPCR
Definition: if_udavreg.h:124
#define UDAV_NCR_LBK1
Definition: if_udavreg.h:63
#define UDAV_RCR
Definition: if_udavreg.h:67
#define UDAV_NCR
Definition: if_udavreg.h:58
#define UDAV_REQ_REG_WRITE1
Definition: if_udavreg.h:51
#define UDAV_LOCK(_sc)
Definition: if_udavreg.h:167
#define UDAV_REQ_MEM_WRITE
Definition: if_udavreg.h:54
#define UDAV_EPCR_ERPRR
Definition: if_udavreg.h:93
#define UDAV_EPCR_EPOS
Definition: if_udavreg.h:92
#define UDAV_NCR_RST
Definition: if_udavreg.h:65
#define UDAV_RCR_DIS_LONG
Definition: if_udavreg.h:69
#define UDAV_FLAG_LINK
Definition: if_udavreg.h:162
#define UDAV_REQ_MEM_WRITE1
Definition: if_udavreg.h:55
#define UDAV_EPAR_EROA_MASK
Definition: if_udavreg.h:101
#define UDAV_LOCK_ASSERT(_sc, t)
Definition: if_udavreg.h:169
#define UDAV_REQ_MEM_READ
Definition: if_udavreg.h:53
#define UDAV_NCR_LBK0
Definition: if_udavreg.h:64
#define UDAV_EPCR_ERPRW
Definition: if_udavreg.h:94
#define UDAV_EPAR_PHY_ADR0
Definition: if_udavreg.h:99
#define UDAV_NCR_EXT_PHY
Definition: if_udavreg.h:59
#define UDAV_EPDRL
Definition: if_udavreg.h:103
#define UDAV_EPCR
Definition: if_udavreg.h:89
#define UDAV_GPR
Definition: if_udavreg.h:133
#define UDAV_MAR
Definition: if_udavreg.h:122
#define UDAV_RCR_PRMSC
Definition: if_udavreg.h:73
#define UDAV_RCR_DIS_CRC
Definition: if_udavreg.h:70
#define UDAV_CONFIG_INDEX
Definition: if_udavreg.h:37
#define UDAV_GPR_GEPIO0
Definition: if_udavreg.h:140
uint16_t data
device_t dev
uint8_t rxstat
Definition: if_udavreg.h:145
uint16_t pktlen
Definition: if_udavreg.h:146
struct mtx sc_mtx
Definition: if_udavreg.h:158
struct usb_ether sc_ue
Definition: if_udavreg.h:157
int sc_flags
Definition: if_udavreg.h:161
struct usb_xfer * sc_xfer[UDAV_N_TRANSFER]
Definition: if_udavreg.h:159
enum usb_hc_mode usb_mode
Definition: usbdi.h:432
struct usbd_lookup_info info
Definition: usbdi.h:426
struct usb_device * device
Definition: usbdi.h:430
struct usb_xfer_flags flags
Definition: usbdi.h:235
uint8_t type
Definition: usbdi.h:238
uether_fn_t * ue_attach_post
Definition: usb_ethernet.h:58
const struct usb_ether_methods * ue_methods
Definition: usb_ethernet.h:81
struct usb_device * ue_udev
Definition: usb_ethernet.h:84
uint8_t ue_eaddr[ETHER_ADDR_LEN]
Definition: usb_ethernet.h:101
device_t ue_dev
Definition: usb_ethernet.h:85
struct mtx * ue_mtx
Definition: usb_ethernet.h:80
void * ue_sc
Definition: usb_ethernet.h:83
uint8_t pipe_bof
Definition: usbdi.h:200
uint8_t bIfaceIndex
Definition: usbdi.h:417
uint8_t bConfigIndex
Definition: usbdi.h:419
#define DPRINTF(...)
Definition: umass.c:179
#define UE_INTERRUPT
Definition: usb.h:544
#define UE_ADDR_ANY
Definition: usb.h:537
#define UE_BULK
Definition: usb.h:543
#define UT_WRITE_VENDOR_DEVICE
Definition: usb.h:184
#define UT_READ_VENDOR_DEVICE
Definition: usb.h:180
#define UE_DIR_IN
Definition: usb.h:531
#define UE_DIR_OUT
Definition: usb.h:532
@ USB_MODE_HOST
Definition: usb.h:778
void usbd_frame_zero(struct usb_page_cache *cache, usb_frlength_t offset, usb_frlength_t len)
Definition: usb_busdma.c:339
void usbd_copy_in(struct usb_page_cache *cache, usb_frlength_t offset, const void *ptr, usb_frlength_t len)
Definition: usb_busdma.c:166
void usbd_copy_out(struct usb_page_cache *cache, usb_frlength_t offset, void *ptr, usb_frlength_t len)
Definition: usb_busdma.c:283
#define USETW(w, v)
Definition: usb_endian.h:77
const char * usbd_errstr(usb_error_t err)
Definition: usb_error.c:93
void uether_rxflush(struct usb_ether *ue)
Definition: usb_ethernet.c:646
void uether_ifdetach(struct usb_ether *ue)
Definition: usb_ethernet.c:302
void * uether_getsc(struct usb_ether *ue)
Definition: usb_ethernet.c:148
int uether_rxbuf(struct usb_ether *ue, struct usb_page_cache *pc, unsigned int offset, unsigned int len)
Definition: usb_ethernet.c:616
struct ifnet * uether_getifp(struct usb_ether *ue)
Definition: usb_ethernet.c:136
uint8_t uether_pause(struct usb_ether *ue, unsigned int _ticks)
Definition: usb_ethernet.c:94
int uether_ifattach(struct usb_ether *ue)
Definition: usb_ethernet.c:164
#define uether_do_request(ue, req, data, timo)
Definition: usb_ethernet.h:104
void() uether_fn_t(struct usb_ether *)
Definition: usb_ethernet.h:55
uint16_t offset
Definition: usb_if.m:54
const void * req
Definition: usb_if.m:51
INTERFACE usb
Definition: usb_if.m:35
int usbd_lookup_id_by_uaa(const struct usb_device_id *id, usb_size_t sizeof_id, struct usb_attach_arg *uaa)
Definition: usb_lookup.c:143
void usbd_transfer_submit(struct usb_xfer *xfer)
void usbd_transfer_unsetup(struct usb_xfer **pxfer, uint16_t n_setup)
void usbd_xfer_set_frame_len(struct usb_xfer *xfer, usb_frcount_t frindex, usb_frlength_t len)
struct usb_page_cache * usbd_xfer_get_frame(struct usb_xfer *xfer, usb_frcount_t frindex)
usb_error_t usbd_transfer_setup(struct usb_device *udev, const uint8_t *ifaces, struct usb_xfer **ppxfer, const struct usb_config *setup_start, uint16_t n_setup, void *priv_sc, struct mtx *xfer_mtx)
Definition: usb_transfer.c:987
void usbd_transfer_start(struct usb_xfer *xfer)
void * usbd_xfer_softc(struct usb_xfer *xfer)
void usbd_xfer_set_stall(struct usb_xfer *xfer)
void usbd_transfer_stop(struct usb_xfer *xfer)
void usbd_xfer_status(struct usb_xfer *xfer, int *actlen, int *sumlen, int *aframes, int *nframes)
usb_frlength_t usbd_xfer_max_len(struct usb_xfer *xfer)
void device_set_usb_desc(device_t dev)
Definition: usb_util.c:73
#define USB_ST_SETUP
Definition: usbdi.h:502
usb_error_t
Definition: usbdi.h:45
@ USB_ERR_CANCELLED
Definition: usbdi.h:51
#define USB_ST_TRANSFERRED
Definition: usbdi.h:503
void usbd_m_copy_in(struct usb_page_cache *cache, usb_frlength_t dst_offset, struct mbuf *m, usb_size_t src_offset, usb_frlength_t src_len)
void() usb_callback_t(struct usb_xfer *, usb_error_t)
Definition: usbdi.h:94
#define USB_VPI(vend, prod, info)
Definition: usbdi.h:367
#define STRUCT_USB_HOST_ID
Definition: usbdi.h:258
#define USB_GET_DRIVER_INFO(did)
Definition: usbdi.h:400
#define USB_GET_STATE(xfer)
Definition: usbdi.h:515