1 /* $NetBSD: if_udav.c,v 1.26 2009/09/23 19:07:19 plunky Exp $ */
2 /* $nabe: if_udav.c,v 1.3 2003/08/21 16:57:19 nabe Exp $ */
5 * Shingo WATANABE <nabe@nabechan.org>. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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. Neither the name of the author nor the names of any co-contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * DM9601(DAVICOM USB to Ethernet MAC Controller with Integrated 10/100 PHY)
35 * The spec can be found at the following url.
36 * http://www.davicom.com.tw/big5/download/Data%20Sheet/DM9601-DS-F01-062202s.pdf
41 * Interrupt Endpoint support
43 * powerhook() support?
46 #include <sys/cdefs.h>
47 __KERNEL_RCSID(0, "$NetBSD: if_udav.c,v 1.26 2009/09/23 19:07:19 plunky Exp $");
53 #include <sys/param.h>
54 #include <sys/systm.h>
55 #include <sys/mutex.h>
57 #include <sys/kernel.h>
58 #include <sys/socket.h>
59 #include <sys/device.h>
65 #include <net/if_arp.h>
66 #include <net/if_dl.h>
67 #include <net/if_media.h>
72 #define BPF_MTAP(ifp, m) bpf_mtap((ifp)->if_bpf, (m))
74 #include <net/if_ether.h>
76 #include <netinet/in.h>
77 #include <netinet/if_inarp.h>
80 #include <dev/mii/mii.h>
81 #include <dev/mii/miivar.h>
83 #include <dev/usb/usb.h>
84 #include <dev/usb/usbdi.h>
85 #include <dev/usb/usbdi_util.h>
86 #include <dev/usb/usbdevs.h>
88 #include <dev/usb/if_udavreg.h>
91 /* Function declarations */
92 USB_DECLARE_DRIVER(udav
);
94 Static
int udav_openpipes(struct udav_softc
*);
95 Static
int udav_rx_list_init(struct udav_softc
*);
96 Static
int udav_tx_list_init(struct udav_softc
*);
97 Static
int udav_newbuf(struct udav_softc
*, struct udav_chain
*, struct mbuf
*);
98 Static
void udav_start(struct ifnet
*);
99 Static
int udav_send(struct udav_softc
*, struct mbuf
*, int);
100 Static
void udav_txeof(usbd_xfer_handle
, usbd_private_handle
, usbd_status
);
101 Static
void udav_rxeof(usbd_xfer_handle
, usbd_private_handle
, usbd_status
);
102 Static
void udav_tick(void *);
103 Static
void udav_tick_task(void *);
104 Static
int udav_ioctl(struct ifnet
*, u_long
, void *);
105 Static
void udav_stop_task(struct udav_softc
*);
106 Static
void udav_stop(struct ifnet
*, int);
107 Static
void udav_watchdog(struct ifnet
*);
108 Static
int udav_ifmedia_change(struct ifnet
*);
109 Static
void udav_ifmedia_status(struct ifnet
*, struct ifmediareq
*);
110 Static
void udav_lock_mii(struct udav_softc
*);
111 Static
void udav_unlock_mii(struct udav_softc
*);
112 Static
int udav_miibus_readreg(device_ptr_t
, int, int);
113 Static
void udav_miibus_writereg(device_ptr_t
, int, int, int);
114 Static
void udav_miibus_statchg(device_ptr_t
);
115 Static
int udav_init(struct ifnet
*);
116 Static
void udav_setmulti(struct udav_softc
*);
117 Static
void udav_reset(struct udav_softc
*);
119 Static
int udav_csr_read(struct udav_softc
*, int, void *, int);
120 Static
int udav_csr_write(struct udav_softc
*, int, void *, int);
121 Static
int udav_csr_read1(struct udav_softc
*, int);
122 Static
int udav_csr_write1(struct udav_softc
*, int, unsigned char);
125 Static
int udav_mem_read(struct udav_softc
*, int, void *, int);
126 Static
int udav_mem_write(struct udav_softc
*, int, void *, int);
127 Static
int udav_mem_write1(struct udav_softc
*, int, unsigned char);
132 #define DPRINTF(x) if (udavdebug) logprintf x
133 #define DPRINTFN(n,x) if (udavdebug >= (n)) logprintf x
137 #define DPRINTFN(n,x)
140 #define UDAV_SETBIT(sc, reg, x) \
141 udav_csr_write1(sc, reg, udav_csr_read1(sc, reg) | (x))
143 #define UDAV_CLRBIT(sc, reg, x) \
144 udav_csr_write1(sc, reg, udav_csr_read1(sc, reg) & ~(x))
146 static const struct udav_type
{
147 struct usb_devno udav_dev
;
148 u_int16_t udav_flags
;
149 #define UDAV_EXT_PHY 0x0001
152 {{ USB_VENDOR_COREGA
, USB_PRODUCT_COREGA_FETHER_USB_TXC
}, 0},
153 /* ShanTou ST268 USB NIC */
154 {{ USB_VENDOR_SHANTOU
, USB_PRODUCT_SHANTOU_ST268_USB_NIC
}, 0},
155 /* ShanTou ADM8515 */
156 {{ USB_VENDOR_SHANTOU
, USB_PRODUCT_SHANTOU_ADM8515
}, 0},
158 /* DAVICOM DM9601 Generic? */
159 /* XXX: The following ids was obtained from the data sheet. */
160 {{ 0x0a46, 0x9601 }, 0},
163 #define udav_lookup(v, p) ((const struct udav_type *)usb_lookup(udav_devs, v, p))
169 USB_MATCH_START(udav
, uaa
);
171 return (udav_lookup(uaa
->vendor
, uaa
->product
) != NULL
?
172 UMATCH_VENDOR_PRODUCT
: UMATCH_NONE
);
178 USB_ATTACH_START(udav
, sc
, uaa
);
179 usbd_device_handle dev
= uaa
->device
;
180 usbd_interface_handle iface
;
182 usb_interface_descriptor_t
*id
;
183 usb_endpoint_descriptor_t
*ed
;
186 struct mii_data
*mii
;
187 u_char eaddr
[ETHER_ADDR_LEN
];
195 devinfop
= usbd_devinfo_alloc(dev
, 0);
196 aprint_normal_dev(self
, "%s\n", devinfop
);
197 usbd_devinfo_free(devinfop
);
199 /* Move the device into the configured state. */
200 err
= usbd_set_config_no(dev
, UDAV_CONFIG_NO
, 1); /* idx 0 */
202 aprint_error_dev(self
, "setting config no failed\n");
206 usb_init_task(&sc
->sc_tick_task
, udav_tick_task
, sc
);
207 mutex_init(&sc
->sc_mii_lock
, MUTEX_DEFAULT
, IPL_NONE
);
208 usb_init_task(&sc
->sc_stop_task
, (void (*)(void *)) udav_stop_task
, sc
);
210 /* get control interface */
211 err
= usbd_device2interface_handle(dev
, UDAV_IFACE_INDEX
, &iface
);
213 aprint_error_dev(self
, "failed to get interface, err=%s\n",
219 sc
->sc_ctl_iface
= iface
;
220 sc
->sc_flags
= udav_lookup(uaa
->vendor
, uaa
->product
)->udav_flags
;
222 /* get interface descriptor */
223 id
= usbd_get_interface_descriptor(sc
->sc_ctl_iface
);
226 sc
->sc_bulkin_no
= sc
->sc_bulkout_no
= sc
->sc_intrin_no
= -1;
227 for (i
= 0; i
< id
->bNumEndpoints
; i
++) {
228 ed
= usbd_interface2endpoint_descriptor(sc
->sc_ctl_iface
, i
);
230 aprint_error_dev(self
, "couldn't get endpoint %d\n", i
);
233 if ((ed
->bmAttributes
& UE_XFERTYPE
) == UE_BULK
&&
234 UE_GET_DIR(ed
->bEndpointAddress
) == UE_DIR_IN
)
235 sc
->sc_bulkin_no
= ed
->bEndpointAddress
; /* RX */
236 else if ((ed
->bmAttributes
& UE_XFERTYPE
) == UE_BULK
&&
237 UE_GET_DIR(ed
->bEndpointAddress
) == UE_DIR_OUT
)
238 sc
->sc_bulkout_no
= ed
->bEndpointAddress
; /* TX */
239 else if ((ed
->bmAttributes
& UE_XFERTYPE
) == UE_INTERRUPT
&&
240 UE_GET_DIR(ed
->bEndpointAddress
) == UE_DIR_IN
)
241 sc
->sc_intrin_no
= ed
->bEndpointAddress
; /* Status */
244 if (sc
->sc_bulkin_no
== -1 || sc
->sc_bulkout_no
== -1 ||
245 sc
->sc_intrin_no
== -1) {
246 aprint_error_dev(self
, "missing endpoint\n");
252 /* reset the adapter */
255 /* Get Ethernet Address */
256 err
= udav_csr_read(sc
, UDAV_PAR
, (void *)eaddr
, ETHER_ADDR_LEN
);
258 aprint_error_dev(self
, "read MAC address failed\n");
263 /* Print Ethernet Address */
264 aprint_normal_dev(self
, "Ethernet address %s\n", ether_sprintf(eaddr
));
266 /* initialize interface information */
269 ifp
->if_mtu
= ETHERMTU
;
270 strncpy(ifp
->if_xname
, device_xname(self
), IFNAMSIZ
);
271 ifp
->if_flags
= IFF_BROADCAST
| IFF_SIMPLEX
| IFF_MULTICAST
;
272 ifp
->if_start
= udav_start
;
273 ifp
->if_ioctl
= udav_ioctl
;
274 ifp
->if_watchdog
= udav_watchdog
;
275 ifp
->if_init
= udav_init
;
276 ifp
->if_stop
= udav_stop
;
278 IFQ_SET_READY(&ifp
->if_snd
);
285 mii
->mii_readreg
= udav_miibus_readreg
;
286 mii
->mii_writereg
= udav_miibus_writereg
;
287 mii
->mii_statchg
= udav_miibus_statchg
;
288 mii
->mii_flags
= MIIF_AUTOTSLEEP
;
289 sc
->sc_ec
.ec_mii
= mii
;
290 ifmedia_init(&mii
->mii_media
, 0,
291 udav_ifmedia_change
, udav_ifmedia_status
);
292 mii_attach(self
, mii
, 0xffffffff, MII_PHY_ANY
, MII_OFFSET_ANY
, 0);
293 if (LIST_FIRST(&mii
->mii_phys
) == NULL
) {
294 ifmedia_add(&mii
->mii_media
, IFM_ETHER
| IFM_NONE
, 0, NULL
);
295 ifmedia_set(&mii
->mii_media
, IFM_ETHER
| IFM_NONE
);
297 ifmedia_set(&mii
->mii_media
, IFM_ETHER
| IFM_AUTO
);
299 /* attach the interface */
301 Ether_ifattach(ifp
, eaddr
);
304 rnd_attach_source(&sc
->rnd_source
, device_xname(self
),
308 usb_callout_init(sc
->sc_stat_ch
);
312 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH
, dev
, USBDEV(sc
->sc_dev
));
314 USB_ATTACH_SUCCESS_RETURN
;
318 USB_ATTACH_ERROR_RETURN
;
324 USB_DETACH_START(udav
, sc
);
325 struct ifnet
*ifp
= GET_IFP(sc
);
328 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc
->sc_dev
), __func__
));
330 /* Detached before attached finished */
331 if (!sc
->sc_attached
)
334 usb_uncallout(sc
->sc_stat_ch
, udav_tick
, sc
);
336 /* Remove any pending tasks */
337 usb_rem_task(sc
->sc_udev
, &sc
->sc_tick_task
);
338 usb_rem_task(sc
->sc_udev
, &sc
->sc_stop_task
);
342 if (--sc
->sc_refcnt
>= 0) {
343 /* Wait for processes to go away */
344 usb_detach_wait(USBDEV(sc
->sc_dev
));
346 if (ifp
->if_flags
& IFF_RUNNING
)
347 udav_stop(GET_IFP(sc
), 1);
350 rnd_detach_source(&sc
->rnd_source
);
352 mii_detach(&sc
->sc_mii
, MII_PHY_ANY
, MII_OFFSET_ANY
);
353 ifmedia_delete_instance(&sc
->sc_mii
.mii_media
, IFM_INST_ANY
);
358 if (sc
->sc_pipe_tx
!= NULL
)
359 aprint_debug_dev(self
, "detach has active tx endpoint.\n");
360 if (sc
->sc_pipe_rx
!= NULL
)
361 aprint_debug_dev(self
, "detach has active rx endpoint.\n");
362 if (sc
->sc_pipe_intr
!= NULL
)
363 aprint_debug_dev(self
, "detach has active intr endpoint.\n");
369 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH
, sc
->sc_udev
,
372 mutex_destroy(&sc
->sc_mii_lock
);
380 udav_mem_read(struct udav_softc
*sc
, int offset
, void *buf
, int len
)
382 usb_device_request_t req
;
389 ("%s: %s: enter\n", USBDEVNAME(sc
->sc_dev
), __func__
));
397 req
.bmRequestType
= UT_READ_VENDOR_DEVICE
;
398 req
.bRequest
= UDAV_REQ_MEM_READ
;
399 USETW(req
.wValue
, 0x0000);
400 USETW(req
.wIndex
, offset
);
401 USETW(req
.wLength
, len
);
404 err
= usbd_do_request(sc
->sc_udev
, &req
, buf
);
405 if (--sc
->sc_refcnt
< 0)
406 usb_detach_wakeup(USBDEV(sc
->sc_dev
));
408 DPRINTF(("%s: %s: read failed. off=%04x, err=%d\n",
409 USBDEVNAME(sc
->sc_dev
), __func__
, offset
, err
));
417 udav_mem_write(struct udav_softc
*sc
, int offset
, void *buf
, int len
)
419 usb_device_request_t req
;
426 ("%s: %s: enter\n", USBDEVNAME(sc
->sc_dev
), __func__
));
434 req
.bmRequestType
= UT_WRITE_VENDOR_DEVICE
;
435 req
.bRequest
= UDAV_REQ_MEM_WRITE
;
436 USETW(req
.wValue
, 0x0000);
437 USETW(req
.wIndex
, offset
);
438 USETW(req
.wLength
, len
);
441 err
= usbd_do_request(sc
->sc_udev
, &req
, buf
);
442 if (--sc
->sc_refcnt
< 0)
443 usb_detach_wakeup(USBDEV(sc
->sc_dev
));
445 DPRINTF(("%s: %s: write failed. off=%04x, err=%d\n",
446 USBDEVNAME(sc
->sc_dev
), __func__
, offset
, err
));
454 udav_mem_write1(struct udav_softc
*sc
, int offset
, unsigned char ch
)
456 usb_device_request_t req
;
463 ("%s: %s: enter\n", USBDEVNAME(sc
->sc_dev
), __func__
));
470 req
.bmRequestType
= UT_WRITE_VENDOR_DEVICE
;
471 req
.bRequest
= UDAV_REQ_MEM_WRITE1
;
472 USETW(req
.wValue
, ch
);
473 USETW(req
.wIndex
, offset
);
474 USETW(req
.wLength
, 0x0000);
477 err
= usbd_do_request(sc
->sc_udev
, &req
, NULL
);
478 if (--sc
->sc_refcnt
< 0)
479 usb_detach_wakeup(USBDEV(sc
->sc_dev
));
481 DPRINTF(("%s: %s: write failed. off=%04x, err=%d\n",
482 USBDEVNAME(sc
->sc_dev
), __func__
, offset
, err
));
489 /* read register(s) */
491 udav_csr_read(struct udav_softc
*sc
, int offset
, void *buf
, int len
)
493 usb_device_request_t req
;
500 ("%s: %s: enter\n", USBDEVNAME(sc
->sc_dev
), __func__
));
508 req
.bmRequestType
= UT_READ_VENDOR_DEVICE
;
509 req
.bRequest
= UDAV_REQ_REG_READ
;
510 USETW(req
.wValue
, 0x0000);
511 USETW(req
.wIndex
, offset
);
512 USETW(req
.wLength
, len
);
515 err
= usbd_do_request(sc
->sc_udev
, &req
, buf
);
516 if (--sc
->sc_refcnt
< 0)
517 usb_detach_wakeup(USBDEV(sc
->sc_dev
));
519 DPRINTF(("%s: %s: read failed. off=%04x, err=%d\n",
520 USBDEVNAME(sc
->sc_dev
), __func__
, offset
, err
));
526 /* write register(s) */
528 udav_csr_write(struct udav_softc
*sc
, int offset
, void *buf
, int len
)
530 usb_device_request_t req
;
537 ("%s: %s: enter\n", USBDEVNAME(sc
->sc_dev
), __func__
));
545 req
.bmRequestType
= UT_WRITE_VENDOR_DEVICE
;
546 req
.bRequest
= UDAV_REQ_REG_WRITE
;
547 USETW(req
.wValue
, 0x0000);
548 USETW(req
.wIndex
, offset
);
549 USETW(req
.wLength
, len
);
552 err
= usbd_do_request(sc
->sc_udev
, &req
, buf
);
553 if (--sc
->sc_refcnt
< 0)
554 usb_detach_wakeup(USBDEV(sc
->sc_dev
));
556 DPRINTF(("%s: %s: write failed. off=%04x, err=%d\n",
557 USBDEVNAME(sc
->sc_dev
), __func__
, offset
, err
));
564 udav_csr_read1(struct udav_softc
*sc
, int offset
)
572 ("%s: %s: enter\n", USBDEVNAME(sc
->sc_dev
), __func__
));
577 return (udav_csr_read(sc
, offset
, &val
, 1) ? 0 : val
);
580 /* write a register */
582 udav_csr_write1(struct udav_softc
*sc
, int offset
, unsigned char ch
)
584 usb_device_request_t req
;
591 ("%s: %s: enter\n", USBDEVNAME(sc
->sc_dev
), __func__
));
598 req
.bmRequestType
= UT_WRITE_VENDOR_DEVICE
;
599 req
.bRequest
= UDAV_REQ_REG_WRITE1
;
600 USETW(req
.wValue
, ch
);
601 USETW(req
.wIndex
, offset
);
602 USETW(req
.wLength
, 0x0000);
605 err
= usbd_do_request(sc
->sc_udev
, &req
, NULL
);
606 if (--sc
->sc_refcnt
< 0)
607 usb_detach_wakeup(USBDEV(sc
->sc_dev
));
609 DPRINTF(("%s: %s: write failed. off=%04x, err=%d\n",
610 USBDEVNAME(sc
->sc_dev
), __func__
, offset
, err
));
617 udav_init(struct ifnet
*ifp
)
619 struct udav_softc
*sc
= ifp
->if_softc
;
620 struct mii_data
*mii
= GET_MII(sc
);
621 uint8_t eaddr
[ETHER_ADDR_LEN
];
624 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc
->sc_dev
), __func__
));
631 /* Cancel pending I/O and free all TX/RX buffers */
634 memcpy(eaddr
, CLLADDR(ifp
->if_sadl
), sizeof(eaddr
));
635 udav_csr_write(sc
, UDAV_PAR
, eaddr
, ETHER_ADDR_LEN
);
637 /* Initialize network control register */
638 /* Disable loopback */
639 UDAV_CLRBIT(sc
, UDAV_NCR
, UDAV_NCR_LBK0
| UDAV_NCR_LBK1
);
641 /* Initialize RX control register */
642 UDAV_SETBIT(sc
, UDAV_RCR
, UDAV_RCR_DIS_LONG
| UDAV_RCR_DIS_CRC
);
644 /* If we want promiscuous mode, accept all physical frames. */
645 if (ifp
->if_flags
& IFF_PROMISC
)
646 UDAV_SETBIT(sc
, UDAV_RCR
, UDAV_RCR_ALL
|UDAV_RCR_PRMSC
);
648 UDAV_CLRBIT(sc
, UDAV_RCR
, UDAV_RCR_ALL
|UDAV_RCR_PRMSC
);
650 /* Initialize transmit ring */
651 if (udav_tx_list_init(sc
) == ENOBUFS
) {
652 printf("%s: tx list init failed\n", USBDEVNAME(sc
->sc_dev
));
657 /* Initialize receive ring */
658 if (udav_rx_list_init(sc
) == ENOBUFS
) {
659 printf("%s: rx list init failed\n", USBDEVNAME(sc
->sc_dev
));
664 /* Load the multicast filter */
668 UDAV_SETBIT(sc
, UDAV_RCR
, UDAV_RCR_RXEN
);
670 /* clear POWER_DOWN state of internal PHY */
671 UDAV_SETBIT(sc
, UDAV_GPCR
, UDAV_GPCR_GEP_CNTL0
);
672 UDAV_CLRBIT(sc
, UDAV_GPR
, UDAV_GPR_GEPIO0
);
674 if ((rc
= mii_mediachg(mii
)) == ENXIO
)
679 if (sc
->sc_pipe_tx
== NULL
|| sc
->sc_pipe_rx
== NULL
) {
680 if (udav_openpipes(sc
)) {
686 ifp
->if_flags
|= IFF_RUNNING
;
687 ifp
->if_flags
&= ~IFF_OACTIVE
;
689 usb_callout(sc
->sc_stat_ch
, hz
, udav_tick
, sc
);
697 udav_reset(struct udav_softc
*sc
)
701 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc
->sc_dev
), __func__
));
709 * XXX: force select internal phy.
710 * external phy routines are not tested.
712 UDAV_CLRBIT(sc
, UDAV_NCR
, UDAV_NCR_EXT_PHY
);
714 if (sc
->sc_flags
& UDAV_EXT_PHY
) {
715 UDAV_SETBIT(sc
, UDAV_NCR
, UDAV_NCR_EXT_PHY
);
717 UDAV_CLRBIT(sc
, UDAV_NCR
, UDAV_NCR_EXT_PHY
);
721 UDAV_SETBIT(sc
, UDAV_NCR
, UDAV_NCR_RST
);
723 for (i
= 0; i
< UDAV_TX_TIMEOUT
; i
++) {
724 if (!(udav_csr_read1(sc
, UDAV_NCR
) & UDAV_NCR_RST
))
728 delay(10000); /* XXX */
732 udav_activate(device_ptr_t self
, enum devact act
)
734 struct udav_softc
*sc
= device_private(self
);
736 DPRINTF(("%s: %s: enter, act=%d\n", USBDEVNAME(sc
->sc_dev
),
739 case DVACT_DEACTIVATE
:
740 if_deactivate(&sc
->sc_ec
.ec_if
);
750 #define UDAV_CALCHASH(addr) \
751 (ether_crc32_le((addr), ETHER_ADDR_LEN) & ((1 << UDAV_BITS) - 1))
754 udav_setmulti(struct udav_softc
*sc
)
757 struct ether_multi
*enm
;
758 struct ether_multistep step
;
762 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc
->sc_dev
), __func__
));
769 if (ifp
->if_flags
& IFF_PROMISC
) {
770 UDAV_SETBIT(sc
, UDAV_RCR
, UDAV_RCR_ALL
|UDAV_RCR_PRMSC
);
772 } else if (ifp
->if_flags
& IFF_ALLMULTI
) {
774 ifp
->if_flags
|= IFF_ALLMULTI
;
775 UDAV_SETBIT(sc
, UDAV_RCR
, UDAV_RCR_ALL
);
776 UDAV_CLRBIT(sc
, UDAV_RCR
, UDAV_RCR_PRMSC
);
780 /* first, zot all the existing hash bits */
781 memset(hashes
, 0x00, sizeof(hashes
));
782 hashes
[7] |= 0x80; /* broadcast address */
783 udav_csr_write(sc
, UDAV_MAR
, hashes
, sizeof(hashes
));
785 /* now program new ones */
786 ETHER_FIRST_MULTI(step
, &sc
->sc_ec
, enm
);
787 while (enm
!= NULL
) {
788 if (memcmp(enm
->enm_addrlo
, enm
->enm_addrhi
,
789 ETHER_ADDR_LEN
) != 0)
792 h
= UDAV_CALCHASH(enm
->enm_addrlo
);
793 hashes
[h
>>3] |= 1 << (h
& 0x7);
794 ETHER_NEXT_MULTI(step
, enm
);
797 /* disable all multicast */
798 ifp
->if_flags
&= ~IFF_ALLMULTI
;
799 UDAV_CLRBIT(sc
, UDAV_RCR
, UDAV_RCR_ALL
);
801 /* write hash value to the register */
802 udav_csr_write(sc
, UDAV_MAR
, hashes
, sizeof(hashes
));
806 udav_openpipes(struct udav_softc
*sc
)
808 struct udav_chain
*c
;
819 err
= usbd_open_pipe(sc
->sc_ctl_iface
, sc
->sc_bulkin_no
,
820 USBD_EXCLUSIVE_USE
, &sc
->sc_pipe_rx
);
822 printf("%s: open rx pipe failed: %s\n",
823 USBDEVNAME(sc
->sc_dev
), usbd_errstr(err
));
829 err
= usbd_open_pipe(sc
->sc_ctl_iface
, sc
->sc_bulkout_no
,
830 USBD_EXCLUSIVE_USE
, &sc
->sc_pipe_tx
);
832 printf("%s: open tx pipe failed: %s\n",
833 USBDEVNAME(sc
->sc_dev
), usbd_errstr(err
));
839 /* XXX: interrupt endpoint is not yet supported */
840 /* Open Interrupt pipe */
841 err
= usbd_open_pipe_intr(sc
->sc_ctl_iface
, sc
->sc_intrin_no
,
842 USBD_EXCLUSIVE_USE
, &sc
->sc_pipe_intr
, sc
,
843 &sc
->sc_cdata
.udav_ibuf
, UDAV_INTR_PKGLEN
,
844 udav_intr
, USBD_DEFAULT_INTERVAL
);
846 printf("%s: open intr pipe failed: %s\n",
847 USBDEVNAME(sc
->sc_dev
), usbd_errstr(err
));
854 /* Start up the receive pipe. */
855 for (i
= 0; i
< UDAV_RX_LIST_CNT
; i
++) {
856 c
= &sc
->sc_cdata
.udav_rx_chain
[i
];
857 usbd_setup_xfer(c
->udav_xfer
, sc
->sc_pipe_rx
,
858 c
, c
->udav_buf
, UDAV_BUFSZ
,
859 USBD_SHORT_XFER_OK
| USBD_NO_COPY
,
860 USBD_NO_TIMEOUT
, udav_rxeof
);
861 (void)usbd_transfer(c
->udav_xfer
);
862 DPRINTF(("%s: %s: start read\n", USBDEVNAME(sc
->sc_dev
),
867 if (--sc
->sc_refcnt
< 0)
868 usb_detach_wakeup(USBDEV(sc
->sc_dev
));
874 udav_newbuf(struct udav_softc
*sc
, struct udav_chain
*c
, struct mbuf
*m
)
876 struct mbuf
*m_new
= NULL
;
878 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc
->sc_dev
), __func__
));
881 MGETHDR(m_new
, M_DONTWAIT
, MT_DATA
);
883 printf("%s: no memory for rx list "
884 "-- packet dropped!\n", USBDEVNAME(sc
->sc_dev
));
887 MCLGET(m_new
, M_DONTWAIT
);
888 if (!(m_new
->m_flags
& M_EXT
)) {
889 printf("%s: no memory for rx list "
890 "-- packet dropped!\n", USBDEVNAME(sc
->sc_dev
));
894 m_new
->m_len
= m_new
->m_pkthdr
.len
= MCLBYTES
;
897 m_new
->m_len
= m_new
->m_pkthdr
.len
= MCLBYTES
;
898 m_new
->m_data
= m_new
->m_ext
.ext_buf
;
901 m_adj(m_new
, ETHER_ALIGN
);
902 c
->udav_mbuf
= m_new
;
909 udav_rx_list_init(struct udav_softc
*sc
)
911 struct udav_cdata
*cd
;
912 struct udav_chain
*c
;
915 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc
->sc_dev
), __func__
));
918 for (i
= 0; i
< UDAV_RX_LIST_CNT
; i
++) {
919 c
= &cd
->udav_rx_chain
[i
];
922 if (udav_newbuf(sc
, c
, NULL
) == ENOBUFS
)
924 if (c
->udav_xfer
== NULL
) {
925 c
->udav_xfer
= usbd_alloc_xfer(sc
->sc_udev
);
926 if (c
->udav_xfer
== NULL
)
928 c
->udav_buf
= usbd_alloc_buffer(c
->udav_xfer
, UDAV_BUFSZ
);
929 if (c
->udav_buf
== NULL
) {
930 usbd_free_xfer(c
->udav_xfer
);
940 udav_tx_list_init(struct udav_softc
*sc
)
942 struct udav_cdata
*cd
;
943 struct udav_chain
*c
;
946 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc
->sc_dev
), __func__
));
949 for (i
= 0; i
< UDAV_TX_LIST_CNT
; i
++) {
950 c
= &cd
->udav_tx_chain
[i
];
954 if (c
->udav_xfer
== NULL
) {
955 c
->udav_xfer
= usbd_alloc_xfer(sc
->sc_udev
);
956 if (c
->udav_xfer
== NULL
)
958 c
->udav_buf
= usbd_alloc_buffer(c
->udav_xfer
, UDAV_BUFSZ
);
959 if (c
->udav_buf
== NULL
) {
960 usbd_free_xfer(c
->udav_xfer
);
970 udav_start(struct ifnet
*ifp
)
972 struct udav_softc
*sc
= ifp
->if_softc
;
973 struct mbuf
*m_head
= NULL
;
975 DPRINTF(("%s: %s: enter, link=%d\n", USBDEVNAME(sc
->sc_dev
),
976 __func__
, sc
->sc_link
));
984 if (ifp
->if_flags
& IFF_OACTIVE
)
987 IFQ_POLL(&ifp
->if_snd
, m_head
);
991 if (udav_send(sc
, m_head
, 0)) {
992 ifp
->if_flags
|= IFF_OACTIVE
;
996 IFQ_DEQUEUE(&ifp
->if_snd
, m_head
);
1000 bpf_mtap(ifp
->if_bpf
, m_head
);
1003 ifp
->if_flags
|= IFF_OACTIVE
;
1005 /* Set a timeout in case the chip goes out to lunch. */
1010 udav_send(struct udav_softc
*sc
, struct mbuf
*m
, int idx
)
1013 struct udav_chain
*c
;
1016 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc
->sc_dev
),__func__
));
1018 c
= &sc
->sc_cdata
.udav_tx_chain
[idx
];
1020 /* Copy the mbuf data into a contiguous buffer */
1021 /* first 2 bytes are packet length */
1022 m_copydata(m
, 0, m
->m_pkthdr
.len
, c
->udav_buf
+ 2);
1024 total_len
= m
->m_pkthdr
.len
;
1025 if (total_len
< UDAV_MIN_FRAME_LEN
) {
1026 memset(c
->udav_buf
+ 2 + total_len
, 0,
1027 UDAV_MIN_FRAME_LEN
- total_len
);
1028 total_len
= UDAV_MIN_FRAME_LEN
;
1031 /* Frame length is specified in the first 2bytes of the buffer */
1032 c
->udav_buf
[0] = (u_int8_t
)total_len
;
1033 c
->udav_buf
[1] = (u_int8_t
)(total_len
>> 8);
1036 usbd_setup_xfer(c
->udav_xfer
, sc
->sc_pipe_tx
, c
, c
->udav_buf
, total_len
,
1037 USBD_FORCE_SHORT_XFER
| USBD_NO_COPY
,
1038 UDAV_TX_TIMEOUT
, udav_txeof
);
1042 err
= usbd_transfer(c
->udav_xfer
);
1043 if (--sc
->sc_refcnt
< 0)
1044 usb_detach_wakeup(USBDEV(sc
->sc_dev
));
1045 if (err
!= USBD_IN_PROGRESS
) {
1046 printf("%s: udav_send error=%s\n", USBDEVNAME(sc
->sc_dev
),
1048 /* Stop the interface */
1049 usb_add_task(sc
->sc_udev
, &sc
->sc_stop_task
,
1054 DPRINTF(("%s: %s: send %d bytes\n", USBDEVNAME(sc
->sc_dev
),
1055 __func__
, total_len
));
1057 sc
->sc_cdata
.udav_tx_cnt
++;
1063 udav_txeof(usbd_xfer_handle xfer
, usbd_private_handle priv
,
1066 struct udav_chain
*c
= priv
;
1067 struct udav_softc
*sc
= c
->udav_sc
;
1068 struct ifnet
*ifp
= GET_IFP(sc
);
1076 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc
->sc_dev
), __func__
));
1079 ifp
->if_flags
&= ~IFF_OACTIVE
;
1081 if (status
!= USBD_NORMAL_COMPLETION
) {
1082 if (status
== USBD_NOT_STARTED
|| status
== USBD_CANCELLED
) {
1087 printf("%s: usb error on tx: %s\n", USBDEVNAME(sc
->sc_dev
),
1088 usbd_errstr(status
));
1089 if (status
== USBD_STALLED
) {
1091 usbd_clear_endpoint_stall_async(sc
->sc_pipe_tx
);
1092 if (--sc
->sc_refcnt
< 0)
1093 usb_detach_wakeup(USBDEV(sc
->sc_dev
));
1101 m_freem(c
->udav_mbuf
);
1102 c
->udav_mbuf
= NULL
;
1104 if (IFQ_IS_EMPTY(&ifp
->if_snd
) == 0)
1111 udav_rxeof(usbd_xfer_handle xfer
, usbd_private_handle priv
, usbd_status status
)
1113 struct udav_chain
*c
= priv
;
1114 struct udav_softc
*sc
= c
->udav_sc
;
1115 struct ifnet
*ifp
= GET_IFP(sc
);
1117 u_int32_t total_len
;
1121 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc
->sc_dev
),__func__
));
1126 if (status
!= USBD_NORMAL_COMPLETION
) {
1127 if (status
== USBD_NOT_STARTED
|| status
== USBD_CANCELLED
)
1130 if (usbd_ratecheck(&sc
->sc_rx_notice
)) {
1131 printf("%s: %u usb errors on rx: %s\n",
1132 USBDEVNAME(sc
->sc_dev
), sc
->sc_rx_errs
,
1133 usbd_errstr(status
));
1136 if (status
== USBD_STALLED
) {
1138 usbd_clear_endpoint_stall_async(sc
->sc_pipe_rx
);
1139 if (--sc
->sc_refcnt
< 0)
1140 usb_detach_wakeup(USBDEV(sc
->sc_dev
));
1145 usbd_get_xfer_status(xfer
, NULL
, NULL
, &total_len
, NULL
);
1147 /* copy data to mbuf */
1149 memcpy(mtod(m
, char *), c
->udav_buf
, total_len
);
1151 /* first byte in received data */
1152 pktstat
= mtod(m
, u_int8_t
*);
1153 m_adj(m
, sizeof(u_int8_t
));
1154 DPRINTF(("%s: RX Status: 0x%02x\n", USBDEVNAME(sc
->sc_dev
),
1157 total_len
= UGETW(mtod(m
, u_int8_t
*));
1158 m_adj(m
, sizeof(u_int16_t
));
1160 if (*pktstat
& UDAV_RSR_LCS
) {
1161 ifp
->if_collisions
++;
1165 if (total_len
< sizeof(struct ether_header
) ||
1166 *pktstat
& UDAV_RSR_ERR
) {
1172 total_len
-= ETHER_CRC_LEN
;
1174 m
->m_pkthdr
.len
= m
->m_len
= total_len
;
1175 m
->m_pkthdr
.rcvif
= ifp
;
1179 if (udav_newbuf(sc
, c
, NULL
) == ENOBUFS
) {
1189 DPRINTF(("%s: %s: deliver %d\n", USBDEVNAME(sc
->sc_dev
),
1190 __func__
, m
->m_len
));
1197 /* Setup new transfer */
1198 usbd_setup_xfer(xfer
, sc
->sc_pipe_rx
, c
, c
->udav_buf
, UDAV_BUFSZ
,
1199 USBD_SHORT_XFER_OK
| USBD_NO_COPY
,
1200 USBD_NO_TIMEOUT
, udav_rxeof
);
1202 usbd_transfer(xfer
);
1203 if (--sc
->sc_refcnt
< 0)
1204 usb_detach_wakeup(USBDEV(sc
->sc_dev
));
1206 DPRINTF(("%s: %s: start rx\n", USBDEVNAME(sc
->sc_dev
), __func__
));
1210 Static
void udav_intr(void)
1216 udav_ioctl(struct ifnet
*ifp
, u_long cmd
, void *data
)
1218 struct udav_softc
*sc
= ifp
->if_softc
;
1221 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc
->sc_dev
), __func__
));
1228 error
= ether_ioctl(ifp
, cmd
, data
);
1229 if (error
== ENETRESET
) {
1230 if (ifp
->if_flags
& IFF_RUNNING
)
1241 udav_watchdog(struct ifnet
*ifp
)
1243 struct udav_softc
*sc
= ifp
->if_softc
;
1244 struct udav_chain
*c
;
1248 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc
->sc_dev
), __func__
));
1251 printf("%s: watchdog timeout\n", USBDEVNAME(sc
->sc_dev
));
1254 c
= &sc
->sc_cdata
.udav_tx_chain
[0];
1255 usbd_get_xfer_status(c
->udav_xfer
, NULL
, NULL
, NULL
, &stat
);
1256 udav_txeof(c
->udav_xfer
, c
, stat
);
1258 if (IFQ_IS_EMPTY(&ifp
->if_snd
) == 0)
1264 udav_stop_task(struct udav_softc
*sc
)
1266 udav_stop(GET_IFP(sc
), 1);
1269 /* Stop the adapter and free any mbufs allocated to the RX and TX lists. */
1271 udav_stop(struct ifnet
*ifp
, int disable
)
1273 struct udav_softc
*sc
= ifp
->if_softc
;
1277 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc
->sc_dev
), __func__
));
1283 usb_uncallout(sc
->sc_stat_ch
, udav_tick
, sc
);
1285 /* Stop transfers */
1287 if (sc
->sc_pipe_rx
!= NULL
) {
1288 err
= usbd_abort_pipe(sc
->sc_pipe_rx
);
1290 printf("%s: abort rx pipe failed: %s\n",
1291 USBDEVNAME(sc
->sc_dev
), usbd_errstr(err
));
1292 err
= usbd_close_pipe(sc
->sc_pipe_rx
);
1294 printf("%s: close rx pipe failed: %s\n",
1295 USBDEVNAME(sc
->sc_dev
), usbd_errstr(err
));
1296 sc
->sc_pipe_rx
= NULL
;
1300 if (sc
->sc_pipe_tx
!= NULL
) {
1301 err
= usbd_abort_pipe(sc
->sc_pipe_tx
);
1303 printf("%s: abort tx pipe failed: %s\n",
1304 USBDEVNAME(sc
->sc_dev
), usbd_errstr(err
));
1305 err
= usbd_close_pipe(sc
->sc_pipe_tx
);
1307 printf("%s: close tx pipe failed: %s\n",
1308 USBDEVNAME(sc
->sc_dev
), usbd_errstr(err
));
1309 sc
->sc_pipe_tx
= NULL
;
1313 /* XXX: Interrupt endpoint is not yet supported!! */
1314 /* Interrupt endpoint */
1315 if (sc
->sc_pipe_intr
!= NULL
) {
1316 err
= usbd_abort_pipe(sc
->sc_pipe_intr
);
1318 printf("%s: abort intr pipe failed: %s\n",
1319 USBDEVNAME(sc
->sc_dev
), usbd_errstr(err
));
1320 err
= usbd_close_pipe(sc
->sc_pipe_intr
);
1322 printf("%s: close intr pipe failed: %s\n",
1323 USBDEVNAME(sc
->sc_dev
), usbd_errstr(err
));
1324 sc
->sc_pipe_intr
= NULL
;
1328 /* Free RX resources. */
1329 for (i
= 0; i
< UDAV_RX_LIST_CNT
; i
++) {
1330 if (sc
->sc_cdata
.udav_rx_chain
[i
].udav_mbuf
!= NULL
) {
1331 m_freem(sc
->sc_cdata
.udav_rx_chain
[i
].udav_mbuf
);
1332 sc
->sc_cdata
.udav_rx_chain
[i
].udav_mbuf
= NULL
;
1334 if (sc
->sc_cdata
.udav_rx_chain
[i
].udav_xfer
!= NULL
) {
1335 usbd_free_xfer(sc
->sc_cdata
.udav_rx_chain
[i
].udav_xfer
);
1336 sc
->sc_cdata
.udav_rx_chain
[i
].udav_xfer
= NULL
;
1340 /* Free TX resources. */
1341 for (i
= 0; i
< UDAV_TX_LIST_CNT
; i
++) {
1342 if (sc
->sc_cdata
.udav_tx_chain
[i
].udav_mbuf
!= NULL
) {
1343 m_freem(sc
->sc_cdata
.udav_tx_chain
[i
].udav_mbuf
);
1344 sc
->sc_cdata
.udav_tx_chain
[i
].udav_mbuf
= NULL
;
1346 if (sc
->sc_cdata
.udav_tx_chain
[i
].udav_xfer
!= NULL
) {
1347 usbd_free_xfer(sc
->sc_cdata
.udav_tx_chain
[i
].udav_xfer
);
1348 sc
->sc_cdata
.udav_tx_chain
[i
].udav_xfer
= NULL
;
1353 ifp
->if_flags
&= ~(IFF_RUNNING
| IFF_OACTIVE
);
1356 /* Set media options */
1358 udav_ifmedia_change(struct ifnet
*ifp
)
1360 struct udav_softc
*sc
= ifp
->if_softc
;
1361 struct mii_data
*mii
= GET_MII(sc
);
1364 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc
->sc_dev
), __func__
));
1370 if ((rc
= mii_mediachg(mii
)) == ENXIO
)
1375 /* Report current media status. */
1377 udav_ifmedia_status(struct ifnet
*ifp
, struct ifmediareq
*ifmr
)
1379 struct udav_softc
*sc
= ifp
->if_softc
;
1381 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc
->sc_dev
), __func__
));
1386 ether_mediastatus(ifp
, ifmr
);
1390 udav_tick(void *xsc
)
1392 struct udav_softc
*sc
= xsc
;
1397 DPRINTFN(0xff, ("%s: %s: enter\n", USBDEVNAME(sc
->sc_dev
),
1403 /* Perform periodic stuff in process context */
1404 usb_add_task(sc
->sc_udev
, &sc
->sc_tick_task
,
1409 udav_tick_task(void *xsc
)
1411 struct udav_softc
*sc
= xsc
;
1413 struct mii_data
*mii
;
1419 DPRINTFN(0xff, ("%s: %s: enter\n", USBDEVNAME(sc
->sc_dev
),
1436 if (mii
->mii_media_status
& IFM_ACTIVE
&&
1437 IFM_SUBTYPE(mii
->mii_media_active
) != IFM_NONE
) {
1438 DPRINTF(("%s: %s: got link\n",
1439 USBDEVNAME(sc
->sc_dev
), __func__
));
1441 if (IFQ_IS_EMPTY(&ifp
->if_snd
) == 0)
1446 usb_callout(sc
->sc_stat_ch
, hz
, udav_tick
, sc
);
1451 /* Get exclusive access to the MII registers */
1453 udav_lock_mii(struct udav_softc
*sc
)
1455 DPRINTFN(0xff, ("%s: %s: enter\n", USBDEVNAME(sc
->sc_dev
),
1459 mutex_enter(&sc
->sc_mii_lock
);
1463 udav_unlock_mii(struct udav_softc
*sc
)
1465 DPRINTFN(0xff, ("%s: %s: enter\n", USBDEVNAME(sc
->sc_dev
),
1468 mutex_exit(&sc
->sc_mii_lock
);
1469 if (--sc
->sc_refcnt
< 0)
1470 usb_detach_wakeup(USBDEV(sc
->sc_dev
));
1474 udav_miibus_readreg(device_ptr_t dev
, int phy
, int reg
)
1476 struct udav_softc
*sc
;
1483 sc
= USBGETSOFTC(dev
);
1485 DPRINTFN(0xff, ("%s: %s: enter, phy=%d reg=0x%04x\n",
1486 USBDEVNAME(sc
->sc_dev
), __func__
, phy
, reg
));
1490 printf("%s: %s: dying\n", USBDEVNAME(sc
->sc_dev
),
1496 /* XXX: one PHY only for the internal PHY */
1498 DPRINTFN(0xff, ("%s: %s: phy=%d is not supported\n",
1499 USBDEVNAME(sc
->sc_dev
), __func__
, phy
));
1505 /* select internal PHY and set PHY register address */
1506 udav_csr_write1(sc
, UDAV_EPAR
,
1507 UDAV_EPAR_PHY_ADR0
| (reg
& UDAV_EPAR_EROA_MASK
));
1509 /* select PHY operation and start read command */
1510 udav_csr_write1(sc
, UDAV_EPCR
, UDAV_EPCR_EPOS
| UDAV_EPCR_ERPRR
);
1512 /* XXX: should be wait? */
1514 /* end read command */
1515 UDAV_CLRBIT(sc
, UDAV_EPCR
, UDAV_EPCR_ERPRR
);
1517 /* retrieve the result from data registers */
1518 udav_csr_read(sc
, UDAV_EPDRL
, val
, 2);
1520 udav_unlock_mii(sc
);
1522 data16
= val
[0] | (val
[1] << 8);
1524 DPRINTFN(0xff, ("%s: %s: phy=%d reg=0x%04x => 0x%04x\n",
1525 USBDEVNAME(sc
->sc_dev
), __func__
, phy
, reg
, data16
));
1531 udav_miibus_writereg(device_ptr_t dev
, int phy
, int reg
, int data
)
1533 struct udav_softc
*sc
;
1539 sc
= USBGETSOFTC(dev
);
1541 DPRINTFN(0xff, ("%s: %s: enter, phy=%d reg=0x%04x data=0x%04x\n",
1542 USBDEVNAME(sc
->sc_dev
), __func__
, phy
, reg
, data
));
1546 printf("%s: %s: dying\n", USBDEVNAME(sc
->sc_dev
),
1552 /* XXX: one PHY only for the internal PHY */
1554 DPRINTFN(0xff, ("%s: %s: phy=%d is not supported\n",
1555 USBDEVNAME(sc
->sc_dev
), __func__
, phy
));
1561 /* select internal PHY and set PHY register address */
1562 udav_csr_write1(sc
, UDAV_EPAR
,
1563 UDAV_EPAR_PHY_ADR0
| (reg
& UDAV_EPAR_EROA_MASK
));
1565 /* put the value to the data registers */
1566 val
[0] = data
& 0xff;
1567 val
[1] = (data
>> 8) & 0xff;
1568 udav_csr_write(sc
, UDAV_EPDRL
, val
, 2);
1570 /* select PHY operation and start write command */
1571 udav_csr_write1(sc
, UDAV_EPCR
, UDAV_EPCR_EPOS
| UDAV_EPCR_ERPRW
);
1573 /* XXX: should be wait? */
1575 /* end write command */
1576 UDAV_CLRBIT(sc
, UDAV_EPCR
, UDAV_EPCR_ERPRW
);
1578 udav_unlock_mii(sc
);
1584 udav_miibus_statchg(device_ptr_t dev
)
1587 struct udav_softc
*sc
;
1592 sc
= USBGETSOFTC(dev
);
1593 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc
->sc_dev
), __func__
));