FreeBSD/Linux Kernel Cross Reference
sys/dev/usb/if_udav.c
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: src/sys/dev/usb/if_udav.c,v 1.8 2004/08/11 03:38:55 rwatson Exp $ */
4 /*
5 * Copyright (c) 2003
6 * Shingo WATANABE <nabe@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 __FBSDID("$FreeBSD: src/sys/dev/usb/if_udav.c,v 1.8 2004/08/11 03:38:55 rwatson Exp $");
49
50 #include "opt_inet.h"
51 #if defined(__NetBSD__)
52 #include "opt_ns.h"
53 #endif
54 #if defined(__NetBSD__)
55 #include "bpfilter.h"
56 #endif
57 #if defined(__FreeBSD__)
58 #define NBPFILTER 1
59 #endif
60 #if defined(__NetBSD__)
61 #include "rnd.h"
62 #endif
63
64 #include <sys/param.h>
65 #include <sys/systm.h>
66 #include <sys/lock.h>
67 #include <sys/mbuf.h>
68 #include <sys/kernel.h>
69 #include <sys/module.h>
70 #include <sys/socket.h>
71 #if defined(__FreeBSD__)
72 #include <sys/types.h>
73 #include <sys/lockmgr.h>
74 #include <sys/sockio.h>
75 #endif
76
77 #if defined(__NetBSD__)
78 #include <sys/device.h>
79 #endif
80
81 #if NRND > 0
82 #include <sys/rnd.h>
83 #endif
84
85 #include <net/if.h>
86 #include <net/if_arp.h>
87 #include <net/if_dl.h>
88 #include <net/if_media.h>
89 #include <net/ethernet.h>
90
91 #if NBPFILTER > 0
92 #include <net/bpf.h>
93 #endif
94 #if defined(__NetBSD__)
95 #ifndef BPF_MTAP
96 #define BPF_MTAP(_ifp, _m) do { \
97 if ((_ifp)->if_bpf)) { \
98 bpf_mtap((_ifp)->if_bpf, (_m)) ; \
99 } \
100 } while (0)
101 #endif
102 #endif
103
104 #if defined(__NetBSD__)
105 #include <net/if_ether.h>
106 #ifdef INET
107 #include <netinet/in.h>
108 #include <netinet/if_inarp.h>
109 #endif /* INET */
110 #elif defined(__FreeBSD__) /* defined(__NetBSD__) */
111 #include <netinet/in.h>
112 #include <netinet/if_ether.h>
113 #endif /* defined(__FreeBSD__) */
114
115 #if defined(__NetBSD__)
116 #ifdef NS
117 #include <netns/ns.h>
118 #include <netns/ns_if.h>
119 #endif
120 #endif /* defined (__NetBSD__) */
121
122 #include <sys/bus.h>
123 #include <machine/bus.h>
124 #if __FreeBSD_version < 500000
125 #include <machine/clock.h>
126 #endif
127
128 #include <dev/mii/mii.h>
129 #include <dev/mii/miivar.h>
130
131 #include <dev/usb/usb.h>
132 #include <dev/usb/usbdi.h>
133 #include <dev/usb/usbdi_util.h>
134 #include "usbdevs.h"
135 #include <dev/usb/usbdivar.h>
136 #include <dev/usb/usb_ethersubr.h>
137
138 #include <dev/usb/if_udavreg.h>
139
140 #if defined(__FreeBSD__)
141 MODULE_DEPEND(udav, usb, 1, 1, 1);
142 MODULE_DEPEND(udav, ether, 1, 1, 1);
143 MODULE_DEPEND(udav, miibus, 1, 1, 1);
144 #endif
145
146 /* "controller miibus0" required. See GENERIC if you get errors here. */
147 #include "miibus_if.h"
148
149 #if !defined(__FreeBSD__)
150 /* Function declarations */
151 USB_DECLARE_DRIVER(udav);
152 #endif
153
154 #if defined(__FreeBSD__)
155 Static int udav_match(device_ptr_t);
156 Static int udav_attach(device_ptr_t);
157 Static int udav_detach(device_ptr_t);
158 Static void udav_shutdown(device_ptr_t);
159 #endif
160
161 Static int udav_openpipes(struct udav_softc *);
162 Static int udav_rx_list_init(struct udav_softc *);
163 Static int udav_tx_list_init(struct udav_softc *);
164 Static int udav_newbuf(struct udav_softc *, struct udav_chain *, struct mbuf *);
165 Static void udav_start(struct ifnet *);
166 Static int udav_send(struct udav_softc *, struct mbuf *, int);
167 Static void udav_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
168 #if defined(__FreeBSD__)
169 Static void udav_rxstart(struct ifnet *ifp);
170 #endif
171 Static void udav_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
172 Static void udav_tick(void *);
173 Static void udav_tick_task(void *);
174 Static int udav_ioctl(struct ifnet *, u_long, caddr_t);
175 Static void udav_stop_task(struct udav_softc *);
176 Static void udav_stop(struct ifnet *, int);
177 Static void udav_watchdog(struct ifnet *);
178 Static int udav_ifmedia_change(struct ifnet *);
179 Static void udav_ifmedia_status(struct ifnet *, struct ifmediareq *);
180 Static void udav_lock_mii(struct udav_softc *);
181 Static void udav_unlock_mii(struct udav_softc *);
182 Static int udav_miibus_readreg(device_ptr_t, int, int);
183 Static void udav_miibus_writereg(device_ptr_t, int, int, int);
184 Static void udav_miibus_statchg(device_ptr_t);
185 #if defined(__NetBSD__)
186 Static int udav_init(struct ifnet *);
187 #elif defined(__FreeBSD__)
188 Static void udav_init(void *);
189 #endif
190 Static void udav_setmulti(struct udav_softc *);
191 Static void udav_reset(struct udav_softc *);
192
193 Static int udav_csr_read(struct udav_softc *, int, void *, int);
194 Static int udav_csr_write(struct udav_softc *, int, void *, int);
195 Static int udav_csr_read1(struct udav_softc *, int);
196 Static int udav_csr_write1(struct udav_softc *, int, unsigned char);
197
198 #if 0
199 Static int udav_mem_read(struct udav_softc *, int, void *, int);
200 Static int udav_mem_write(struct udav_softc *, int, void *, int);
201 Static int udav_mem_write1(struct udav_softc *, int, unsigned char);
202 #endif
203
204 #if defined(__FreeBSD__)
205 Static device_method_t udav_methods[] = {
206 /* Device interface */
207 DEVMETHOD(device_probe, udav_match),
208 DEVMETHOD(device_attach, udav_attach),
209 DEVMETHOD(device_detach, udav_detach),
210 DEVMETHOD(device_shutdown, udav_shutdown),
211
212 /* bus interface */
213 DEVMETHOD(bus_print_child, bus_generic_print_child),
214 DEVMETHOD(bus_driver_added, bus_generic_driver_added),
215
216 /* MII interface */
217 DEVMETHOD(miibus_readreg, udav_miibus_readreg),
218 DEVMETHOD(miibus_writereg, udav_miibus_writereg),
219 DEVMETHOD(miibus_statchg, udav_miibus_statchg),
220
221 { 0, 0 }
222 };
223
224 Static driver_t udav_driver = {
225 "udav",
226 udav_methods,
227 sizeof(struct udav_softc)
228 };
229
230 Static devclass_t udav_devclass;
231
232 DRIVER_MODULE(udav, uhub, udav_driver, udav_devclass, usbd_driver_load, 0);
233 DRIVER_MODULE(miibus, udav, miibus_driver, miibus_devclass, 0, 0);
234
235 #endif /* defined(__FreeBSD__) */
236
237 /* Macros */
238 #ifdef UDAV_DEBUG
239 #define DPRINTF(x) if (udavdebug) logprintf x
240 #define DPRINTFN(n,x) if (udavdebug >= (n)) logprintf x
241 int udavdebug = 0;
242 #else
243 #define DPRINTF(x)
244 #define DPRINTFN(n,x)
245 #endif
246
247 #define delay(d) DELAY(d)
248
249 #define UDAV_SETBIT(sc, reg, x) \
250 udav_csr_write1(sc, reg, udav_csr_read1(sc, reg) | (x))
251
252 #define UDAV_CLRBIT(sc, reg, x) \
253 udav_csr_write1(sc, reg, udav_csr_read1(sc, reg) & ~(x))
254
255 static const struct udav_type {
256 struct usb_devno udav_dev;
257 u_int16_t udav_flags;
258 #define UDAV_EXT_PHY 0x0001
259 } udav_devs [] = {
260 /* Corega USB-TXC */
261 {{ USB_VENDOR_COREGA, USB_PRODUCT_COREGA_FETHER_USB_TXC }, 0},
262 #if 0
263 /* DAVICOM DM9601 Generic? */
264 /* XXX: The following ids was obtained from the data sheet. */
265 {{ 0x0a46, 0x9601 }, 0},
266 #endif
267 };
268 #define udav_lookup(v, p) ((const struct udav_type *)usb_lookup(udav_devs, v, p))
269
270
271 /* Probe */
272 USB_MATCH(udav)
273 {
274 USB_MATCH_START(udav, uaa);
275
276 if (uaa->iface != NULL)
277 return (UMATCH_NONE);
278
279 return (udav_lookup(uaa->vendor, uaa->product) != NULL ?
280 UMATCH_VENDOR_PRODUCT : UMATCH_NONE);
281 }
282
283 /* Attach */
284 USB_ATTACH(udav)
285 {
286 USB_ATTACH_START(udav, sc, uaa);
287 usbd_device_handle dev = uaa->device;
288 usbd_interface_handle iface;
289 usbd_status err;
290 usb_interface_descriptor_t *id;
291 usb_endpoint_descriptor_t *ed;
292 char devinfo[1024];
293 const char *devname ;
294 struct ifnet *ifp;
295 #if defined(__NetBSD__)
296 struct mii_data *mii;
297 #endif
298 u_char eaddr[ETHER_ADDR_LEN];
299 int i;
300 #if defined(__NetBSD__)
301 int s;
302 #endif
303
304 bzero(sc, sizeof(struct udav_softc));
305
306 usbd_devinfo(dev, 0, devinfo);
307 USB_ATTACH_SETUP;
308 devname = USBDEVNAME(sc->sc_dev);
309 printf("%s: %s\n", devname, devinfo);
310
311 /* Move the device into the configured state. */
312 err = usbd_set_config_no(dev, UDAV_CONFIG_NO, 1);
313 if (err) {
314 printf("%s: setting config no failed\n", devname);
315 goto bad;
316 }
317
318 usb_init_task(&sc->sc_tick_task, udav_tick_task, sc);
319 lockinit(&sc->sc_mii_lock, PZERO, "udavmii", 0, 0);
320 usb_init_task(&sc->sc_stop_task, (void (*)(void *)) udav_stop_task, sc);
321
322 /* get control interface */
323 err = usbd_device2interface_handle(dev, UDAV_IFACE_INDEX, &iface);
324 if (err) {
325 printf("%s: failed to get interface, err=%s\n", devname,
326 usbd_errstr(err));
327 goto bad;
328 }
329
330 sc->sc_udev = dev;
331 sc->sc_ctl_iface = iface;
332 sc->sc_flags = udav_lookup(uaa->vendor, uaa->product)->udav_flags;
333
334 /* get interface descriptor */
335 id = usbd_get_interface_descriptor(sc->sc_ctl_iface);
336
337 /* find endpoints */
338 sc->sc_bulkin_no = sc->sc_bulkout_no = sc->sc_intrin_no = -1;
339 for (i = 0; i < id->bNumEndpoints; i++) {
340 ed = usbd_interface2endpoint_descriptor(sc->sc_ctl_iface, i);
341 if (ed == NULL) {
342 printf("%s: couldn't get endpoint %d\n", devname, i);
343 goto bad;
344 }
345 if ((ed->bmAttributes & UE_XFERTYPE) == UE_BULK &&
346 UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN)
347 sc->sc_bulkin_no = ed->bEndpointAddress; /* RX */
348 else if ((ed->bmAttributes & UE_XFERTYPE) == UE_BULK &&
349 UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT)
350 sc->sc_bulkout_no = ed->bEndpointAddress; /* TX */
351 else if ((ed->bmAttributes & UE_XFERTYPE) == UE_INTERRUPT &&
352 UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN)
353 sc->sc_intrin_no = ed->bEndpointAddress; /* Status */
354 }
355
356 if (sc->sc_bulkin_no == -1 || sc->sc_bulkout_no == -1 ||
357 sc->sc_intrin_no == -1) {
358 printf("%s: missing endpoint\n", devname);
359 goto bad;
360 }
361
362 #if defined(__FreeBSD__) && __FreeBSD_version >= 500000
363 mtx_init(&sc->sc_mtx, device_get_nameunit(self), MTX_NETWORK_LOCK,
364 MTX_DEF | MTX_RECURSE);
365 #endif
366 #if defined(__NetBSD__)
367 s = splnet();
368 #elif defined(__FreeBSD__)
369 UDAV_LOCK(sc);
370 #endif
371
372 /* reset the adapter */
373 udav_reset(sc);
374
375 /* Get Ethernet Address */
376 err = udav_csr_read(sc, UDAV_PAR, (void *)eaddr, ETHER_ADDR_LEN);
377 if (err) {
378 printf("%s: read MAC address failed\n", devname);
379 #if defined(__NetBSD__)
380 splx(s);
381 #elif defined(__FreeBSD__)
382 UDAV_UNLOCK(sc);
383 #endif
384 goto bad;
385 }
386
387 /* Print Ethernet Address */
388 printf("%s: Ethernet address %s\n", devname, ether_sprintf(eaddr));
389
390 #if defined(__FreeBSD__)
391 bcopy(eaddr, (char *)&sc->sc_ac.ac_enaddr, ETHER_ADDR_LEN);
392 #endif
393
394 /* initialize interface infomation */
395 ifp = GET_IFP(sc);
396 ifp->if_softc = sc;
397 ifp->if_mtu = ETHERMTU;
398 #if defined(__NetBSD__)
399 strncpy(ifp->if_xname, devname, IFNAMSIZ);
400 #elif defined(__FreeBSD__)
401 if_initname(ifp, "udav", device_get_unit(self));
402 #endif
403 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST |
404 IFF_NEEDSGIANT;
405 ifp->if_start = udav_start;
406 ifp->if_ioctl = udav_ioctl;
407 ifp->if_watchdog = udav_watchdog;
408 ifp->if_init = udav_init;
409 #if defined(__NetBSD__)
410 ifp->if_stop = udav_stop;
411 #endif
412 #if defined(__FreeBSD__)
413 ifp->if_baudrate = 10000000;
414 ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
415 #endif
416 #if defined(__NetBSD__)
417 IFQ_SET_READY(&ifp->if_snd);
418 #endif
419
420
421 #if defined(__NetBSD__)
422 /*
423 * Do ifmedia setup.
424 */
425 mii = &sc->sc_mii;
426 mii->mii_ifp = ifp;
427 mii->mii_readreg = udav_miibus_readreg;
428 mii->mii_writereg = udav_miibus_writereg;
429 mii->mii_statchg = udav_miibus_statchg;
430 mii->mii_flags = MIIF_AUTOTSLEEP;
431 ifmedia_init(&mii->mii_media, 0,
432 udav_ifmedia_change, udav_ifmedia_status);
433 mii_attach(self, mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, 0);
434 if (LIST_FIRST(&mii->mii_phys) == NULL) {
435 ifmedia_add(&mii->mii_media, IFM_ETHER | IFM_NONE, 0, NULL);
436 ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_NONE);
437 } else
438 ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_AUTO);
439
440 /* attach the interface */
441 if_attach(ifp);
442 Ether_ifattach(ifp, eaddr);
443 #elif defined(__FreeBSD__)
444 if (mii_phy_probe(self, &sc->sc_miibus,
445 udav_ifmedia_change, udav_ifmedia_status)) {
446 printf("%s: MII without any PHY!\n", USBDEVNAME(sc->sc_dev));
447 UDAV_UNLOCK(sc);
448 mtx_destroy(&sc->sc_mtx);
449 USB_ATTACH_ERROR_RETURN;
450 }
451
452 sc->sc_qdat.ifp = ifp;
453 sc->sc_qdat.if_rxstart = udav_rxstart;
454
455 /*
456 * Call MI attach routine.
457 */
458
459 ether_ifattach(ifp, eaddr);
460 #endif
461
462 #if NRND > 0
463 rnd_attach_source(&sc->rnd_source, devname, RND_TYPE_NET, 0);
464 #endif
465
466 usb_callout_init(sc->sc_stat_ch);
467 #if defined(__FreeBSD__)
468 usb_register_netisr();
469 #endif
470 sc->sc_attached = 1;
471 #if defined(__NetBSD__)
472 splx(s);
473 #elif defined(__FreeBSD__)
474 UDAV_UNLOCK(sc);
475 #endif
476
477 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, dev, USBDEV(sc->sc_dev));
478
479 USB_ATTACH_SUCCESS_RETURN;
480
481 bad:
482 sc->sc_dying = 1;
483 USB_ATTACH_ERROR_RETURN;
484 }
485
486 /* detach */
487 USB_DETACH(udav)
488 {
489 USB_DETACH_START(udav, sc);
490 struct ifnet *ifp = GET_IFP(sc);
491 #if defined(__NetBSD__)
492 int s;
493 #endif
494
495 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
496
497 /* Detached before attached finished */
498 if (!sc->sc_attached)
499 return (0);
500
501 UDAV_LOCK(sc);
502
503 usb_uncallout(sc->sc_stat_ch, udav_tick, sc);
504
505 /* Remove any pending tasks */
506 usb_rem_task(sc->sc_udev, &sc->sc_tick_task);
507 usb_rem_task(sc->sc_udev, &sc->sc_stop_task);
508
509 #if defined(__NetBSD__)
510 s = splusb();
511 #elif defined(__FreeBSD__)
512 UDAV_LOCK(sc);
513 #endif
514
515 if (--sc->sc_refcnt >= 0) {
516 /* Wait for processes to go away */
517 usb_detach_wait(USBDEV(sc->sc_dev));
518 }
519 if (ifp->if_flags & IFF_RUNNING)
520 udav_stop(GET_IFP(sc), 1);
521
522 #if NRND > 0
523 rnd_detach_source(&sc->rnd_source);
524 #endif
525 #if defined(__NetBSD__)
526 mii_detach(&sc->sc_mii, MII_PHY_ANY, MII_OFFSET_ANY);
527 ifmedia_delete_instance(&sc->sc_mii.mii_media, IFM_INST_ANY);
528 #endif
529 ether_ifdetach(ifp);
530 #if defined(__NetBSD__)
531 if_detach(ifp);
532 #endif
533
534 #ifdef DIAGNOSTIC
535 if (sc->sc_pipe_tx != NULL)
536 printf("%s: detach has active tx endpoint.\n",
537 USBDEVNAME(sc->sc_dev));
538 if (sc->sc_pipe_rx != NULL)
539 printf("%s: detach has active rx endpoint.\n",
540 USBDEVNAME(sc->sc_dev));
541 if (sc->sc_pipe_intr != NULL)
542 printf("%s: detach has active intr endpoint.\n",
543 USBDEVNAME(sc->sc_dev));
544 #endif
545 sc->sc_attached = 0;
546
547 #if defined(__NetBSD__)
548 splx(s);
549 #elif defined(__FreeBSD__)
550 UDAV_UNLOCK(sc);
551 #endif
552
553 #if defined(__FreeBSD__)
554 mtx_destroy(&sc->sc_mtx);
555 #endif
556
557 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
558 USBDEV(sc->sc_dev));
559 return (0);
560 }
561
562 #if 0
563 /* read memory */
564 Static int
565 udav_mem_read(struct udav_softc *sc, int offset, void *buf, int len)
566 {
567 usb_device_request_t req;
568 usbd_status err;
569
570 if (sc == NULL)
571 return (0);
572
573 DPRINTFN(0x200,
574 ("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
575
576 if (sc->sc_dying)
577 return (0);
578
579 offset &= 0xffff;
580 len &= 0xff;
581
582 req.bmRequestType = UT_READ_VENDOR_DEVICE;
583 req.bRequest = UDAV_REQ_MEM_READ;
584 USETW(req.wValue, 0x0000);
585 USETW(req.wIndex, offset);
586 USETW(req.wLength, len);
587
588 sc->sc_refcnt++;
589 err = usbd_do_request(sc->sc_udev, &req, buf);
590 if (--sc->sc_refcnt < 0)
591 usb_detach_wakeup(USBDEV(sc->sc_dev));
592 if (err) {
593 DPRINTF(("%s: %s: read failed. off=%04x, err=%d\n",
594 USBDEVNAME(sc->sc_dev), __func__, offset, err));
595 }
596
597 return (err);
598 }
599
600 /* write memory */
601 Static int
602 udav_mem_write(struct udav_softc *sc, int offset, void *buf, int len)
603 {
604 usb_device_request_t req;
605 usbd_status err;
606
607 if (sc == NULL)
608 return (0);
609
610 DPRINTFN(0x200,
611 ("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
612
613 if (sc->sc_dying)
614 return (0);
615
616 offset &= 0xffff;
617 len &= 0xff;
618
619 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
620 req.bRequest = UDAV_REQ_MEM_WRITE;
621 USETW(req.wValue, 0x0000);
622 USETW(req.wIndex, offset);
623 USETW(req.wLength, len);
624
625 sc->sc_refcnt++;
626 err = usbd_do_request(sc->sc_udev, &req, buf);
627 if (--sc->sc_refcnt < 0)
628 usb_detach_wakeup(USBDEV(sc->sc_dev));
629 if (err) {
630 DPRINTF(("%s: %s: write failed. off=%04x, err=%d\n",
631 USBDEVNAME(sc->sc_dev), __func__, offset, err));
632 }
633
634 return (err);
635 }
636
637 /* write memory */
638 Static int
639 udav_mem_write1(struct udav_softc *sc, int offset, unsigned char ch)
640 {
641 usb_device_request_t req;
642 usbd_status err;
643
644 if (sc == NULL)
645 return (0);
646
647 DPRINTFN(0x200,
648 ("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
649
650 if (sc->sc_dying)
651 return (0);
652
653 offset &= 0xffff;
654
655 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
656 req.bRequest = UDAV_REQ_MEM_WRITE1;
657 USETW(req.wValue, ch);
658 USETW(req.wIndex, offset);
659 USETW(req.wLength, 0x0000);
660
661 sc->sc_refcnt++;
662 err = usbd_do_request(sc->sc_udev, &req, NULL);
663 if (--sc->sc_refcnt < 0)
664 usb_detach_wakeup(USBDEV(sc->sc_dev));
665 if (err) {
666 DPRINTF(("%s: %s: write failed. off=%04x, err=%d\n",
667 USBDEVNAME(sc->sc_dev), __func__, offset, err));
668 }
669
670 return (err);
671 }
672 #endif
673
674 /* read register(s) */
675 Static int
676 udav_csr_read(struct udav_softc *sc, int offset, void *buf, int len)
677 {
678 usb_device_request_t req;
679 usbd_status err;
680
681 if (sc == NULL)
682 return (0);
683
684 DPRINTFN(0x200,
685 ("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
686
687 if (sc->sc_dying)
688 return (0);
689
690 offset &= 0xff;
691 len &= 0xff;
692
693 req.bmRequestType = UT_READ_VENDOR_DEVICE;
694 req.bRequest = UDAV_REQ_REG_READ;
695 USETW(req.wValue, 0x0000);
696 USETW(req.wIndex, offset);
697 USETW(req.wLength, len);
698
699 sc->sc_refcnt++;
700 err = usbd_do_request(sc->sc_udev, &req, buf);
701 if (--sc->sc_refcnt < 0)
702 usb_detach_wakeup(USBDEV(sc->sc_dev));
703 if (err) {
704 DPRINTF(("%s: %s: read failed. off=%04x, err=%d\n",
705 USBDEVNAME(sc->sc_dev), __func__, offset, err));
706 }
707
708 return (err);
709 }
710
711 /* write register(s) */
712 Static int
713 udav_csr_write(struct udav_softc *sc, int offset, void *buf, int len)
714 {
715 usb_device_request_t req;
716 usbd_status err;
717
718 if (sc == NULL)
719 return (0);
720
721 DPRINTFN(0x200,
722 ("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
723
724 if (sc->sc_dying)
725 return (0);
726
727 offset &= 0xff;
728 len &= 0xff;
729
730 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
731 req.bRequest = UDAV_REQ_REG_WRITE;
732 USETW(req.wValue, 0x0000);
733 USETW(req.wIndex, offset);
734 USETW(req.wLength, len);
735
736 sc->sc_refcnt++;
737 err = usbd_do_request(sc->sc_udev, &req, buf);
738 if (--sc->sc_refcnt < 0)
739 usb_detach_wakeup(USBDEV(sc->sc_dev));
740 if (err) {
741 DPRINTF(("%s: %s: write failed. off=%04x, err=%d\n",
742 USBDEVNAME(sc->sc_dev), __func__, offset, err));
743 }
744
745 return (err);
746 }
747
748 Static int
749 udav_csr_read1(struct udav_softc *sc, int offset)
750 {
751 u_int8_t val = 0;
752
753 if (sc == NULL)
754 return (0);
755
756 DPRINTFN(0x200,
757 ("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
758
759 if (sc->sc_dying)
760 return (0);
761
762 return (udav_csr_read(sc, offset, &val, 1) ? 0 : val);
763 }
764
765 /* write a register */
766 Static int
767 udav_csr_write1(struct udav_softc *sc, int offset, unsigned char ch)
768 {
769 usb_device_request_t req;
770 usbd_status err;
771
772 if (sc == NULL)
773 return (0);
774
775 DPRINTFN(0x200,
776 ("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
777
778 if (sc->sc_dying)
779 return (0);
780
781 offset &= 0xff;
782
783 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
784 req.bRequest = UDAV_REQ_REG_WRITE1;
785 USETW(req.wValue, ch);
786 USETW(req.wIndex, offset);
787 USETW(req.wLength, 0x0000);
788
789 sc->sc_refcnt++;
790 err = usbd_do_request(sc->sc_udev, &req, NULL);
791 if (--sc->sc_refcnt < 0)
792 usb_detach_wakeup(USBDEV(sc->sc_dev));
793 if (err) {
794 DPRINTF(("%s: %s: write failed. off=%04x, err=%d\n",
795 USBDEVNAME(sc->sc_dev), __func__, offset, err));
796 }
797
798 return (err);
799 }
800
801 #if defined(__NetBSD__)
802 Static int
803 udav_init(struct ifnet *ifp)
804 #elif defined(__FreeBSD__)
805 Static void
806 udav_init(void *xsc)
807 #endif
808 {
809 #if defined(__NetBSD__)
810 struct udav_softc *sc = ifp->if_softc;
811 #elif defined(__FreeBSD__)
812 struct udav_softc *sc = (struct udav_softc *)xsc;
813 struct ifnet *ifp = GET_IFP(sc);
814 #endif
815 struct mii_data *mii = GET_MII(sc);
816 u_char *eaddr;
817 #if defined(__NetBSD__)
818 int s;
819 #endif
820
821 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
822
823 if (sc->sc_dying)
824 #if defined(__NetBSD__)
825 return (EIO);
826 #elif defined(__FreeBSD__)
827 return ;
828 #endif
829
830 #if defined(__NetBSD__)
831 s = splnet();
832 #elif defined(__FreeBSD__)
833 UDAV_LOCK(sc);
834 #endif
835
836 /* Cancel pending I/O and free all TX/RX buffers */
837 udav_stop(ifp, 1);
838
839 #if defined(__NetBSD__)
840 eaddr = LLADDR(ifp->if_sadl);
841 #elif defined(__FreeBSD__)
842 eaddr = sc->sc_ac.ac_enaddr ;
843 #endif
844 udav_csr_write(sc, UDAV_PAR, eaddr, ETHER_ADDR_LEN);
845
846 /* Initialize network control register */
847 /* Disable loopback */
848 UDAV_CLRBIT(sc, UDAV_NCR, UDAV_NCR_LBK0 | UDAV_NCR_LBK1);
849
850 /* Initialize RX control register */
851 UDAV_SETBIT(sc, UDAV_RCR, UDAV_RCR_DIS_LONG | UDAV_RCR_DIS_CRC);
852
853 /* If we want promiscuous mode, accept all physical frames. */
854 if (ifp->if_flags & IFF_PROMISC)
855 UDAV_SETBIT(sc, UDAV_RCR, UDAV_RCR_ALL|UDAV_RCR_PRMSC);
856 else
857 UDAV_CLRBIT(sc, UDAV_RCR, UDAV_RCR_ALL|UDAV_RCR_PRMSC);
858
859 /* Initialize transmit ring */
860 if (udav_tx_list_init(sc) == ENOBUFS) {
861 printf("%s: tx list init failed\n", USBDEVNAME(sc->sc_dev));
862 #if defined(__NetBSD__)
863 splx(s);
864 return (EIO);
865 #elif defined(__FreeBSD__)
866 UDAV_UNLOCK(sc);
867 return ;
868 #endif
869
870 }
871
872 /* Initialize receive ring */
873 if (udav_rx_list_init(sc) == ENOBUFS) {
874 printf("%s: rx list init failed\n", USBDEVNAME(sc->sc_dev));
875 #if defined(__NetBSD__)
876 splx(s);
877 return (EIO);
878 #elif defined(__FreeBSD__)
879 UDAV_UNLOCK(sc);
880 return ;
881 #endif
882 }
883
884 /* Load the multicast filter */
885 udav_setmulti(sc);
886
887 /* Enable RX */
888 UDAV_SETBIT(sc, UDAV_RCR, UDAV_RCR_RXEN);
889
890 /* clear POWER_DOWN state of internal PHY */
891 UDAV_SETBIT(sc, UDAV_GPCR, UDAV_GPCR_GEP_CNTL0);
892 UDAV_CLRBIT(sc, UDAV_GPR, UDAV_GPR_GEPIO0);
893
894 mii_mediachg(mii);
895
896 if (sc->sc_pipe_tx == NULL || sc->sc_pipe_rx == NULL) {
897 if (udav_openpipes(sc)) {
898 #if defined(__NetBSD__)
899 splx(s);
900 return (EIO);
901 #elif defined(__FreeBSD__)
902 UDAV_UNLOCK(sc);
903 return ;
904 #endif
905 }
906 }
907
908 ifp->if_flags |= IFF_RUNNING;
909 ifp->if_flags &= ~IFF_OACTIVE;
910
911 #if defined(__NetBSD__)
912 splx(s);
913 #elif defined(__FreeBSD__)
914 UDAV_UNLOCK(sc);
915 #endif
916
917 usb_callout(sc->sc_stat_ch, hz, udav_tick, sc);
918
919 #if defined(__NetBSD__)
920 return (0);
921 #elif defined(__FreeBSD__)
922 return ;
923 #endif
924 }
925
926 Static void
927 udav_reset(struct udav_softc *sc)
928 {
929 int i;
930
931 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
932
933 if (sc->sc_dying)
934 return;
935
936 /* Select PHY */
937 #if 1
938 /*
939 * XXX: force select internal phy.
940 * external phy routines are not tested.
941 */
942 UDAV_CLRBIT(sc, UDAV_NCR, UDAV_NCR_EXT_PHY);
943 #else
944 if (sc->sc_flags & UDAV_EXT_PHY) {
945 UDAV_SETBIT(sc, UDAV_NCR, UDAV_NCR_EXT_PHY);
946 } else {
947 UDAV_CLRBIT(sc, UDAV_NCR, UDAV_NCR_EXT_PHY);
948 }
949 #endif
950
951 UDAV_SETBIT(sc, UDAV_NCR, UDAV_NCR_RST);
952
953 for (i = 0; i < UDAV_TX_TIMEOUT; i++) {
954 if (!(udav_csr_read1(sc, UDAV_NCR) & UDAV_NCR_RST))
955 break;
956 delay(10); /* XXX */
957 }
958 delay(10000); /* XXX */
959 }
960
961 #if defined(__NetBSD__) || defined(__OpenBSD__)
962 int
963 udav_activate(device_ptr_t self, enum devact act)
964 {
965 struct udav_softc *sc = (struct udav_softc *)self;
966
967 DPRINTF(("%s: %s: enter, act=%d\n", USBDEVNAME(sc->sc_dev),
968 __func__, act));
969 switch (act) {
970 case DVACT_ACTIVATE:
971 return (EOPNOTSUPP);
972 break;
973
974 case DVACT_DEACTIVATE:
975 if_deactivate(&sc->sc_ec.ec_if);
976 sc->sc_dying = 1;
977 break;
978 }
979 return (0);
980 }
981 #endif
982
983 #define UDAV_BITS 6
984
985 #define UDAV_CALCHASH(addr) \
986 (ether_crc32_le((addr), ETHER_ADDR_LEN) & ((1 << UDAV_BITS) - 1))
987
988 Static void
989 udav_setmulti(struct udav_softc *sc)
990 {
991 struct ifnet *ifp;
992 #if defined(__NetBSD__)
993 struct ether_multi *enm;
994 struct ether_multistep step;
995 #elif defined(__FreeBSD__)
996 struct ifmultiaddr *ifma;
997 #endif
998 u_int8_t hashes[8];
999 int h = 0;
1000
1001 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
1002
1003 if (sc->sc_dying)
1004 return;
1005
1006 ifp = GET_IFP(sc);
1007
1008 if (ifp->if_flags & IFF_PROMISC) {
1009 UDAV_SETBIT(sc, UDAV_RCR, UDAV_RCR_ALL|UDAV_RCR_PRMSC);
1010 return;
1011 } else if (ifp->if_flags & IFF_ALLMULTI) {
1012 #if defined(__NetBSD__)
1013 allmulti:
1014 #endif
1015 ifp->if_flags |= IFF_ALLMULTI;
1016 UDAV_SETBIT(sc, UDAV_RCR, UDAV_RCR_ALL);
1017 UDAV_CLRBIT(sc, UDAV_RCR, UDAV_RCR_PRMSC);
1018 return;
1019 }
1020
1021 /* first, zot all the existing hash bits */
1022 memset(hashes, 0x00, sizeof(hashes));
1023 hashes[7] |= 0x80; /* broadcast address */
1024 udav_csr_write(sc, UDAV_MAR, hashes, sizeof(hashes));
1025
1026 /* now program new ones */
1027 #if defined(__NetBSD__)
1028 ETHER_FIRST_MULTI(step, &sc->sc_ec, enm);
1029 while (enm != NULL) {
1030 if (memcmp(enm->enm_addrlo, enm->enm_addrhi,
1031 ETHER_ADDR_LEN) != 0)
1032 goto allmulti;
1033
1034 h = UDAV_CALCHASH(enm->enm_addrlo);
1035 hashes[h>>3] |= 1 << (h & 0x7);
1036 ETHER_NEXT_MULTI(step, enm);
1037 }
1038 #elif defined(__FreeBSD__)
1039 #if __FreeBSD_version >= 500000
1040 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link)
1041 #else
1042 LIST_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link)
1043 #endif
1044 {
1045 if (ifma->ifma_addr->sa_family != AF_LINK)
1046 continue;
1047 h = UDAV_CALCHASH(LLADDR((struct sockaddr_dl *)
1048 ifma->ifma_addr));
1049 hashes[h>>3] |= 1 << (h & 0x7);
1050 }
1051 #endif
1052
1053 /* disable all multicast */
1054 ifp->if_flags &= ~IFF_ALLMULTI;
1055 UDAV_CLRBIT(sc, UDAV_RCR, UDAV_RCR_ALL);
1056
1057 /* write hash value to the register */
1058 udav_csr_write(sc, UDAV_MAR, hashes, sizeof(hashes));
1059 }
1060
1061 Static int
1062 udav_openpipes(struct udav_softc *sc)
1063 {
1064 struct udav_chain *c;
1065 usbd_status err;
1066 int i;
1067 int error = 0;
1068
1069 if (sc->sc_dying)
1070 return (EIO);
1071
1072 sc->sc_refcnt++;
1073
1074 /* Open RX pipe */
1075 err = usbd_open_pipe(sc->sc_ctl_iface, sc->sc_bulkin_no,
1076 USBD_EXCLUSIVE_USE, &sc->sc_pipe_rx);
1077 if (err) {
1078 printf("%s: open rx pipe failed: %s\n",
1079 USBDEVNAME(sc->sc_dev), usbd_errstr(err));
1080 error = EIO;
1081 goto done;
1082 }
1083
1084 /* Open TX pipe */
1085 err = usbd_open_pipe(sc->sc_ctl_iface, sc->sc_bulkout_no,
1086 USBD_EXCLUSIVE_USE, &sc->sc_pipe_tx);
1087 if (err) {
1088 printf("%s: open tx pipe failed: %s\n",
1089 USBDEVNAME(sc->sc_dev), usbd_errstr(err));
1090 error = EIO;
1091 goto done;
1092 }
1093
1094 #if 0
1095 /* XXX: interrupt endpoint is not yet supported */
1096 /* Open Interrupt pipe */
1097 err = usbd_open_pipe_intr(sc->sc_ctl_iface, sc->sc_intrin_no,
1098 USBD_EXCLUSIVE_USE, &sc->sc_pipe_intr, sc,
1099 &sc->sc_cdata.udav_ibuf, UDAV_INTR_PKGLEN,
1100 udav_intr, UDAV_INTR_INTERVAL);
1101 if (err) {
1102 printf("%s: open intr pipe failed: %s\n",
1103 USBDEVNAME(sc->sc_dev), usbd_errstr(err));
1104 error = EIO;
1105 goto done;
1106 }
1107 #endif
1108
1109
1110 /* Start up the receive pipe. */
1111 for (i = 0; i < UDAV_RX_LIST_CNT; i++) {
1112 c = &sc->sc_cdata.udav_rx_chain[i];
1113 usbd_setup_xfer(c->udav_xfer, sc->sc_pipe_rx,
1114 c, c->udav_buf, UDAV_BUFSZ,
1115 USBD_SHORT_XFER_OK | USBD_NO_COPY,
1116 USBD_NO_TIMEOUT, udav_rxeof);
1117 (void)usbd_transfer(c->udav_xfer);
1118 DPRINTF(("%s: %s: start read\n", USBDEVNAME(sc->sc_dev),
1119 __func__));
1120 }
1121
1122 done:
1123 if (--sc->sc_refcnt < 0)
1124 usb_detach_wakeup(USBDEV(sc->sc_dev));
1125
1126 return (error);
1127 }
1128
1129 Static int
1130 udav_newbuf(struct udav_softc *sc, struct udav_chain *c, struct mbuf *m)
1131 {
1132 struct mbuf *m_new = NULL;
1133
1134 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
1135
1136 if (m == NULL) {
1137 MGETHDR(m_new, M_DONTWAIT, MT_DATA);
1138 if (m_new == NULL) {
1139 printf("%s: no memory for rx list "
1140 "-- packet dropped!\n", USBDEVNAME(sc->sc_dev));
1141 return (ENOBUFS);
1142 }
1143 MCLGET(m_new, M_DONTWAIT);
1144 if (!(m_new->m_flags & M_EXT)) {
1145 printf("%s: no memory for rx list "
1146 "-- packet dropped!\n", USBDEVNAME(sc->sc_dev));
1147 m_freem(m_new);
1148 return (ENOBUFS);
1149 }
1150 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
1151 } else {
1152 m_new = m;
1153 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
1154 m_new->m_data = m_new->m_ext.ext_buf;
1155 }
1156
1157 m_adj(m_new, ETHER_ALIGN);
1158 c->udav_mbuf = m_new;
1159
1160 return (0);
1161 }
1162
1163
1164 Static int
1165 udav_rx_list_init(struct udav_softc *sc)
1166 {
1167 struct udav_cdata *cd;
1168 struct udav_chain *c;
1169 int i;
1170
1171 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
1172
1173 cd = &sc->sc_cdata;
1174 for (i = 0; i < UDAV_RX_LIST_CNT; i++) {
1175 c = &cd->udav_rx_chain[i];
1176 c->udav_sc = sc;
1177 c->udav_idx = i;
1178 if (udav_newbuf(sc, c, NULL) == ENOBUFS)
1179 return (ENOBUFS);
1180 if (c->udav_xfer == NULL) {
1181 c->udav_xfer = usbd_alloc_xfer(sc->sc_udev);
1182 if (c->udav_xfer == NULL)
1183 return (ENOBUFS);
1184 c->udav_buf = usbd_alloc_buffer(c->udav_xfer, UDAV_BUFSZ);
1185 if (c->udav_buf == NULL) {
1186 usbd_free_xfer(c->udav_xfer);
1187 return (ENOBUFS);
1188 }
1189 }
1190 }
1191
1192 return (0);
1193 }
1194
1195 Static int
1196 udav_tx_list_init(struct udav_softc *sc)
1197 {
1198 struct udav_cdata *cd;
1199 struct udav_chain *c;
1200 int i;
1201
1202 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
1203
1204 cd = &sc->sc_cdata;
1205 for (i = 0; i < UDAV_TX_LIST_CNT; i++) {
1206 c = &cd->udav_tx_chain[i];
1207 c->udav_sc = sc;
1208 c->udav_idx = i;
1209 c->udav_mbuf = NULL;
1210 if (c->udav_xfer == NULL) {
1211 c->udav_xfer = usbd_alloc_xfer(sc->sc_udev);
1212 if (c->udav_xfer == NULL)
1213 return (ENOBUFS);
1214 c->udav_buf = usbd_alloc_buffer(c->udav_xfer, UDAV_BUFSZ);
1215 if (c->udav_buf == NULL) {
1216 usbd_free_xfer(c->udav_xfer);
1217 return (ENOBUFS);
1218 }
1219 }
1220 }
1221
1222 return (0);
1223 }
1224
1225 Static void
1226 udav_start(struct ifnet *ifp)
1227 {
1228 struct udav_softc *sc = ifp->if_softc;
1229 struct mbuf *m_head = NULL;
1230
1231 DPRINTF(("%s: %s: enter, link=%d\n", USBDEVNAME(sc->sc_dev),
1232 __func__, sc->sc_link));
1233
1234 if (sc->sc_dying)
1235 return;
1236
1237 if (!sc->sc_link)
1238 return;
1239
1240 if (ifp->if_flags & IFF_OACTIVE)
1241 return;
1242 #if defined(__NetBSD__)
1243 IFQ_POLL(&ifp->if_snd, m_head);
1244 #elif defined(__FreeBSD__)
1245 IF_DEQUEUE(&ifp->if_snd, m_head);
1246 #endif
1247 if (m_head == NULL)
1248 return;
1249
1250 if (udav_send(sc, m_head, 0)) {
1251 #if defined(__FreeBSD__)
1252 IF_PREPEND(&ifp->if_snd, m_head);
1253 #endif
1254 ifp->if_flags |= IFF_OACTIVE;
1255 return;
1256 }
1257
1258 #if defined(__NetBSD__)
1259 IFQ_DEQUEUE(&ifp->if_snd, m_head);
1260 #endif
1261
1262 #if NBPFILTER > 0
1263 BPF_MTAP(ifp, m_head);
1264 #endif
1265
1266 ifp->if_flags |= IFF_OACTIVE;
1267
1268 /* Set a timeout in case the chip goes out to lunch. */
1269 ifp->if_timer = 5;
1270 }
1271
1272 Static int
1273 udav_send(struct udav_softc *sc, struct mbuf *m, int idx)
1274 {
1275 int total_len;
1276 struct udav_chain *c;
1277 usbd_status err;
1278
1279 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev),__func__));
1280
1281 c = &sc->sc_cdata.udav_tx_chain[idx];
1282
1283 /* Copy the mbuf data into a contiguous buffer */
1284 /* first 2 bytes are packet length */
1285 m_copydata(m, 0, m->m_pkthdr.len, c->udav_buf + 2);
1286 c->udav_mbuf = m;
1287 total_len = m->m_pkthdr.len;
1288 if (total_len < UDAV_MIN_FRAME_LEN) {
1289 memset(c->udav_buf + 2 + total_len, 0,
1290 UDAV_MIN_FRAME_LEN - total_len);
1291 total_len = UDAV_MIN_FRAME_LEN;
1292 }
1293
1294 /* Frame length is specified in the first 2bytes of the buffer */
1295 c->udav_buf[0] = (u_int8_t)total_len;
1296 c->udav_buf[1] = (u_int8_t)(total_len >> 8);
1297 total_len += 2;
1298
1299 usbd_setup_xfer(c->udav_xfer, sc->sc_pipe_tx, c, c->udav_buf, total_len,
1300 USBD_FORCE_SHORT_XFER | USBD_NO_COPY,
1301 UDAV_TX_TIMEOUT, udav_txeof);
1302
1303 /* Transmit */
1304 sc->sc_refcnt++;
1305 err = usbd_transfer(c->udav_xfer);
1306 if (--sc->sc_refcnt < 0)
1307 usb_detach_wakeup(USBDEV(sc->sc_dev));
1308 if (err != USBD_IN_PROGRESS) {
1309 printf("%s: udav_send error=%s\n", USBDEVNAME(sc->sc_dev),
1310 usbd_errstr(err));
1311 /* Stop the interface */
1312 usb_add_task(sc->sc_udev, &sc->sc_stop_task);
1313 return (EIO);
1314 }
1315
1316 DPRINTF(("%s: %s: send %d bytes\n", USBDEVNAME(sc->sc_dev),
1317 __func__, total_len));
1318
1319 sc->sc_cdata.udav_tx_cnt++;
1320
1321 return (0);
1322 }
1323
1324 Static void
1325 udav_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
1326 {
1327 struct udav_chain *c = priv;
1328 struct udav_softc *sc = c->udav_sc;
1329 struct ifnet *ifp = GET_IFP(sc);
1330 #if defined(__NetBSD__)
1331 int s;
1332 #endif
1333
1334 if (sc->sc_dying)
1335 return;
1336
1337 #if defined(__NetBSD__)
1338 s = splnet();
1339 #elif defined(__FreeBSD__)
1340 UDAV_LOCK(sc);
1341 #endif
1342
1343 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
1344
1345 ifp->if_timer = 0;
1346 ifp->if_flags &= ~IFF_OACTIVE;
1347
1348 if (status != USBD_NORMAL_COMPLETION) {
1349 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
1350 #if defined(__NetBSD__)
1351 splx(s);
1352 #elif defined(__FreeBSD__)
1353 UDAV_UNLOCK(sc);
1354 #endif
1355 return;
1356 }
1357 ifp->if_oerrors++;
1358 printf("%s: usb error on tx: %s\n", USBDEVNAME(sc->sc_dev),
1359 usbd_errstr(status));
1360 if (status == USBD_STALLED) {
1361 sc->sc_refcnt++;
1362 usbd_clear_endpoint_stall(sc->sc_pipe_tx);
1363 if (--sc->sc_refcnt < 0)
1364 usb_detach_wakeup(USBDEV(sc->sc_dev));
1365 }
1366 #if defined(__NetBSD__)
1367 splx(s);
1368 #elif defined(__FreeBSD__)
1369 UDAV_UNLOCK(sc);
1370 #endif
1371 return;
1372 }
1373
1374 ifp->if_opackets++;
1375
1376 m_freem(c->udav_mbuf);
1377 c->udav_mbuf = NULL;
1378
1379 #if defined(__NetBSD__)
1380 if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
1381 #elif defined(__FreeBSD__)
1382 if ( ifp->if_snd.ifq_head != NULL )
1383 #endif
1384 udav_start(ifp);
1385
1386 #if defined(__NetBSD__)
1387 splx(s);
1388 #elif defined(__FreeBSD__)
1389 UDAV_UNLOCK(sc);
1390 #endif
1391 }
1392
1393 Static void
1394 udav_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
1395 {
1396 struct udav_chain *c = priv;
1397 struct udav_softc *sc = c->udav_sc;
1398 struct ifnet *ifp = GET_IFP(sc);
1399 struct mbuf *m;
1400 u_int32_t total_len;
1401 u_int8_t *pktstat;
1402 #if defined(__NetBSD__)
1403 int s;
1404 #endif
1405
1406 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev),__func__));
1407
1408 if (sc->sc_dying)
1409 return;
1410
1411 if (status != USBD_NORMAL_COMPLETION) {
1412 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
1413 return;
1414 sc->sc_rx_errs++;
1415 if (usbd_ratecheck(&sc->sc_rx_notice)) {
1416 printf("%s: %u usb errors on rx: %s\n",
1417 USBDEVNAME(sc->sc_dev), sc->sc_rx_errs,
1418 usbd_errstr(status));
1419 sc->sc_rx_errs = 0;
1420 }
1421 if (status == USBD_STALLED) {
1422 sc->sc_refcnt++;
1423 usbd_clear_endpoint_stall(sc->sc_pipe_rx);
1424 if (--sc->sc_refcnt < 0)
1425 usb_detach_wakeup(USBDEV(sc->sc_dev));
1426 }
1427 goto done;
1428 }
1429
1430 usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
1431
1432 /* copy data to mbuf */
1433 m = c->udav_mbuf;
1434 memcpy(mtod(m, char *), c->udav_buf, total_len);
1435
1436 /* first byte in received data */
1437 pktstat = mtod(m, u_int8_t *);
1438 m_adj(m, sizeof(u_int8_t));
1439 DPRINTF(("%s: RX Status: 0x%02x\n", USBDEVNAME(sc->sc_dev), *pktstat));
1440
1441 total_len = UGETW(mtod(m, u_int8_t *));
1442 m_adj(m, sizeof(u_int16_t));
1443
1444 if (*pktstat & UDAV_RSR_LCS) {
1445 ifp->if_collisions++;
1446 goto done;
1447 }
1448
1449 if (total_len < sizeof(struct ether_header) ||
1450 *pktstat & UDAV_RSR_ERR) {
1451 ifp->if_ierrors++;
1452 goto done;
1453 }
1454
1455 ifp->if_ipackets++;
1456 total_len -= ETHER_CRC_LEN;
1457
1458 m->m_pkthdr.len = m->m_len = total_len;
1459 #if defined(__NetBSD__)
1460 m->m_pkthdr.rcvif = ifp;
1461 #elif defined(__FreeBSD__)
1462 m->m_pkthdr.rcvif = (struct ifnet *)&sc->sc_qdat;
1463 #endif
1464
1465 #if defined(__NetBSD__)
1466 s = splnet();
1467 #elif defined(__FreeBSD__)
1468 UDAV_LOCK(sc);
1469 #endif
1470
1471 #if defined(__NetBSD__)
1472 if (udav_newbuf(sc, c, NULL) == ENOBUFS) {
1473 ifp->if_ierrors++;
1474 goto done1;
1475 }
1476 #endif
1477
1478 #if NBPFILTER > 0
1479 BPF_MTAP(ifp, m);
1480 #endif
1481
1482 DPRINTF(("%s: %s: deliver %d\n", USBDEVNAME(sc->sc_dev),
1483 __func__, m->m_len));
1484 #if defined(__NetBSD__)
1485 IF_INPUT(ifp, m);
1486 #endif
1487 #if defined(__FreeBSD__)
1488 usb_ether_input(m);
1489 UDAV_UNLOCK(sc);
1490 return ;
1491 #endif
1492
1493 #if defined(__NetBSD__)
1494 done1:
1495 splx(s);
1496 #elif defined(__FreeBSD__)
1497 UDAV_UNLOCK(sc);
1498 #endif
1499 done:
1500 /* Setup new transfer */
1501 usbd_setup_xfer(xfer, sc->sc_pipe_rx, c, c->udav_buf, UDAV_BUFSZ,
1502 USBD_SHORT_XFER_OK | USBD_NO_COPY,
1503 USBD_NO_TIMEOUT, udav_rxeof);
1504 sc->sc_refcnt++;
1505 usbd_transfer(xfer);
1506 if (--sc->sc_refcnt < 0)
1507 usb_detach_wakeup(USBDEV(sc->sc_dev));
1508
1509 DPRINTF(("%s: %s: start rx\n", USBDEVNAME(sc->sc_dev), __func__));
1510 }
1511
1512 #if 0
1513 Static void udav_intr()
1514 {
1515 }
1516 #endif
1517
1518 Static int
1519 udav_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
1520 {
1521 struct udav_softc *sc = ifp->if_softc;
1522 struct ifreq *ifr = (struct ifreq *)data;
1523 struct mii_data *mii;
1524 #if defined(__NetBSD__)
1525 int s;
1526 #endif
1527 int error = 0;
1528
1529 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
1530
1531 if (sc->sc_dying)
1532 return (EIO);
1533
1534 #if defined(__NetBSD__)
1535 s = splnet();
1536 #elif defined(__FreeBSD__)
1537 UDAV_LOCK(sc);
1538 #endif
1539
1540 switch (cmd) {
1541 #if defined(__FreeBSD__)
1542 case SIOCSIFFLAGS:
1543 if (ifp->if_flags & IFF_UP) {
1544 if (ifp->if_flags & IFF_RUNNING &&
1545 ifp->if_flags & IFF_PROMISC) {
1546 UDAV_SETBIT(sc, UDAV_RCR,
1547 UDAV_RCR_ALL|UDAV_RCR_PRMSC);
1548 } else if (ifp->if_flags & IFF_RUNNING &&
1549 !(ifp->if_flags & IFF_PROMISC)) {
1550 if (ifp->if_flags & IFF_ALLMULTI)
1551 UDAV_CLRBIT(sc, UDAV_RCR,
1552 UDAV_RCR_PRMSC);
1553 else
1554 UDAV_CLRBIT(sc, UDAV_RCR,
1555 UDAV_RCR_ALL|UDAV_RCR_PRMSC);
1556 } else if (!(ifp->if_flags & IFF_RUNNING))
1557 udav_init(sc);
1558 } else {
1559 if (ifp->if_flags & IFF_RUNNING)
1560 udav_stop(ifp, 1);
1561 }
1562 error = 0;
1563 break;
1564 case SIOCADDMULTI:
1565 case SIOCDELMULTI:
1566 udav_setmulti(sc);
1567 error = 0;
1568 break;
1569 #endif
1570 case SIOCGIFMEDIA:
1571 case SIOCSIFMEDIA:
1572 mii = GET_MII(sc);
1573 error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, cmd);
1574 break;
1575
1576 default:
1577 error = ether_ioctl(ifp, cmd, data);
1578 #if defined(__NetBSD__)
1579 if (error == ENETRESET) {
1580 udav_setmulti(sc);
1581 error = 0;
1582 }
1583 #endif
1584 break;
1585 }
1586
1587 #if defined(__NetBSD__)
1588 splx(s);
1589 #elif defined(__FreeBSD__)
1590 UDAV_UNLOCK(sc);
1591 #endif
1592
1593 return (error);
1594 }
1595
1596 Static void
1597 udav_watchdog(struct ifnet *ifp)
1598 {
1599 struct udav_softc *sc = ifp->if_softc;
1600 struct udav_chain *c;
1601 usbd_status stat;
1602 #if defined(__NetBSD__)
1603 int s;
1604 #endif
1605
1606 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
1607
1608 ifp->if_oerrors++;
1609 printf("%s: watchdog timeout\n", USBDEVNAME(sc->sc_dev));
1610
1611 #if defined(__NetBSD__)
1612 s = splusb();
1613 #elif defined(__FreeBSD__)
1614 UDAV_LOCK(sc)
1615 #endif
1616 c = &sc->sc_cdata.udav_tx_chain[0];
1617 usbd_get_xfer_status(c->udav_xfer, NULL, NULL, NULL, &stat);
1618 udav_txeof(c->udav_xfer, c, stat);
1619
1620 #if defined(__NetBSD__)
1621 if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
1622 #elif defined(__FreeBSD__)
1623 if ( ifp->if_snd.ifq_head != NULL )
1624 #endif
1625 udav_start(ifp);
1626 #if defined(__NetBSD__)
1627 splx(s);
1628 #elif defined(__FreeBSD__)
1629 UDAV_UNLOCK(sc);
1630 #endif
1631 }
1632
1633 Static void
1634 udav_stop_task(struct udav_softc *sc)
1635 {
1636 udav_stop(GET_IFP(sc), 1);
1637 }
1638
1639 /* Stop the adapter and free any mbufs allocated to the RX and TX lists. */
1640 Static void
1641 udav_stop(struct ifnet *ifp, int disable)
1642 {
1643 struct udav_softc *sc = ifp->if_softc;
1644 usbd_status err;
1645 int i;
1646
1647 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
1648
1649 ifp->if_timer = 0;
1650
1651 udav_reset(sc);
1652
1653 usb_uncallout(sc->sc_stat_ch, udav_tick, sc);
1654
1655 /* Stop transfers */
1656 /* RX endpoint */
1657 if (sc->sc_pipe_rx != NULL) {
1658 err = usbd_abort_pipe(sc->sc_pipe_rx);
1659 if (err)
1660 printf("%s: abort rx pipe failed: %s\n",
1661 USBDEVNAME(sc->sc_dev), usbd_errstr(err));
1662 err = usbd_close_pipe(sc->sc_pipe_rx);
1663 if (err)
1664 printf("%s: close rx pipe failed: %s\n",
1665 USBDEVNAME(sc->sc_dev), usbd_errstr(err));
1666 sc->sc_pipe_rx = NULL;
1667 }
1668
1669 /* TX endpoint */
1670 if (sc->sc_pipe_tx != NULL) {
1671 err = usbd_abort_pipe(sc->sc_pipe_tx);
1672 if (err)
1673 printf("%s: abort tx pipe failed: %s\n",
1674 USBDEVNAME(sc->sc_dev), usbd_errstr(err));
1675 err = usbd_close_pipe(sc->sc_pipe_tx);
1676 if (err)
1677 printf("%s: close tx pipe failed: %s\n",
1678 USBDEVNAME(sc->sc_dev), usbd_errstr(err));
1679 sc->sc_pipe_tx = NULL;
1680 }
1681
1682 #if 0
1683 /* XXX: Interrupt endpoint is not yet supported!! */
1684 /* Interrupt endpoint */
1685 if (sc->sc_pipe_intr != NULL) {
1686 err = usbd_abort_pipe(sc->sc_pipe_intr);
1687 if (err)
1688 printf("%s: abort intr pipe failed: %s\n",
1689 USBDEVNAME(sc->sc_dev), usbd_errstr(err));
1690 err = usbd_close_pipe(sc->sc_pipe_intr);
1691 if (err)
1692 printf("%s: close intr pipe failed: %s\n",
1693 USBDEVNAME(sc->sc_dev), usbd_errstr(err));
1694 sc->sc_pipe_intr = NULL;
1695 }
1696 #endif
1697
1698 /* Free RX resources. */
1699 for (i = 0; i < UDAV_RX_LIST_CNT; i++) {
1700 if (sc->sc_cdata.udav_rx_chain[i].udav_mbuf != NULL) {
1701 m_freem(sc->sc_cdata.udav_rx_chain[i].udav_mbuf);
1702 sc->sc_cdata.udav_rx_chain[i].udav_mbuf = NULL;
1703 }
1704 if (sc->sc_cdata.udav_rx_chain[i].udav_xfer != NULL) {
1705 usbd_free_xfer(sc->sc_cdata.udav_rx_chain[i].udav_xfer);
1706 sc->sc_cdata.udav_rx_chain[i].udav_xfer = NULL;
1707 }
1708 }
1709
1710 /* Free TX resources. */
1711 for (i = 0; i < UDAV_TX_LIST_CNT; i++) {
1712 if (sc->sc_cdata.udav_tx_chain[i].udav_mbuf != NULL) {
1713 m_freem(sc->sc_cdata.udav_tx_chain[i].udav_mbuf);
1714 sc->sc_cdata.udav_tx_chain[i].udav_mbuf = NULL;
1715 }
1716 if (sc->sc_cdata.udav_tx_chain[i].udav_xfer != NULL) {
1717 usbd_free_xfer(sc->sc_cdata.udav_tx_chain[i].udav_xfer);
1718 sc->sc_cdata.udav_tx_chain[i].udav_xfer = NULL;
1719 }
1720 }
1721
1722 sc->sc_link = 0;
1723 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
1724 }
1725
1726 /* Set media options */
1727 Static int
1728 udav_ifmedia_change(struct ifnet *ifp)
1729 {
1730 struct udav_softc *sc = ifp->if_softc;
1731 struct mii_data *mii = GET_MII(sc);
1732
1733 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
1734
1735 if (sc->sc_dying)
1736 return (0);
1737
1738 sc->sc_link = 0;
1739 if (mii->mii_instance) {
1740 struct mii_softc *miisc;
1741 for (miisc = LIST_FIRST(&mii->mii_phys); miisc != NULL;
1742 miisc = LIST_NEXT(miisc, mii_list))
1743 mii_phy_reset(miisc);
1744 }
1745
1746 return (mii_mediachg(mii));
1747 }
1748
1749 /* Report current media status. */
1750 Static void
1751 udav_ifmedia_status(struct ifnet *ifp, struct ifmediareq *ifmr)
1752 {
1753 struct udav_softc *sc = ifp->if_softc;
1754 struct mii_data *mii = GET_MII(sc);
1755
1756 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
1757
1758 if (sc->sc_dying)
1759 return;
1760
1761 if ((ifp->if_flags & IFF_RUNNING) == 0) {
1762 ifmr->ifm_active = IFM_ETHER | IFM_NONE;
1763 ifmr->ifm_status = 0;
1764 return;
1765 }
1766
1767 mii_pollstat(mii);
1768 ifmr->ifm_active = mii->mii_media_active;
1769 ifmr->ifm_status = mii->mii_media_status;
1770 }
1771
1772 Static void
1773 udav_tick(void *xsc)
1774 {
1775 struct udav_softc *sc = xsc;
1776
1777 if (sc == NULL)
1778 return;
1779
1780 DPRINTFN(0xff, ("%s: %s: enter\n", USBDEVNAME(sc->sc_dev),
1781 __func__));
1782
1783 if (sc->sc_dying)
1784 return;
1785
1786 /* Perform periodic stuff in process context */
1787 usb_add_task(sc->sc_udev, &sc->sc_tick_task);
1788 }
1789
1790 Static void
1791 udav_tick_task(void *xsc)
1792 {
1793 struct udav_softc *sc = xsc;
1794 struct ifnet *ifp;
1795 struct mii_data *mii;
1796 #if defined(__NetBSD__)
1797 int s;
1798 #endif
1799
1800 if (sc == NULL)
1801 return;
1802
1803 DPRINTFN(0xff, ("%s: %s: enter\n", USBDEVNAME(sc->sc_dev),
1804 __func__));
1805
1806 if (sc->sc_dying)
1807 return;
1808
1809 ifp = GET_IFP(sc);
1810 mii = GET_MII(sc);
1811
1812 if (mii == NULL)
1813 return;
1814
1815 #if defined(__NetBSD__)
1816 s = splnet();
1817 #elif defined(__FreeBSD__)
1818 UDAV_LOCK(sc);
1819 #endif
1820
1821 mii_tick(mii);
1822 if (!sc->sc_link) {
1823 mii_pollstat(mii);
1824 if (mii->mii_media_status & IFM_ACTIVE &&
1825 IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
1826 DPRINTF(("%s: %s: got link\n",
1827 USBDEVNAME(sc->sc_dev), __func__));
1828 sc->sc_link++;
1829 #if defined(__NetBSD__)
1830 if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
1831 #elif defined(__FreeBSD__)
1832 if ( ifp->if_snd.ifq_head != NULL )
1833 #endif
1834 udav_start(ifp);
1835 }
1836 }
1837
1838 usb_callout(sc->sc_stat_ch, hz, udav_tick, sc);
1839
1840 #if defined(__NetBSD__)
1841 splx(s);
1842 #elif defined(__FreeBSD__)
1843 UDAV_UNLOCK(sc);
1844 #endif
1845 }
1846
1847 /* Get exclusive access to the MII registers */
1848 Static void
1849 udav_lock_mii(struct udav_softc *sc)
1850 {
1851 DPRINTFN(0xff, ("%s: %s: enter\n", USBDEVNAME(sc->sc_dev),
1852 __func__));
1853
1854 sc->sc_refcnt++;
1855 #if defined(__NetBSD__)
1856 lockmgr(&sc->sc_mii_lock, LK_EXCLUSIVE, NULL);
1857 #elif defined(__FreeBSD__)
1858 lockmgr(&sc->sc_mii_lock, LK_EXCLUSIVE, NULL, NULL);
1859 #endif
1860 }
1861
1862 Static void
1863 udav_unlock_mii(struct udav_softc *sc)
1864 {
1865 DPRINTFN(0xff, ("%s: %s: enter\n", USBDEVNAME(sc->sc_dev),
1866 __func__));
1867
1868 #if defined(__NetBSD__)
1869 lockmgr(&sc->sc_mii_lock, LK_RELEASE, NULL);
1870 #elif defined(__FreeBSD__)
1871 lockmgr(&sc->sc_mii_lock, LK_RELEASE, NULL, NULL);
1872 #endif
1873 if (--sc->sc_refcnt < 0)
1874 usb_detach_wakeup(USBDEV(sc->sc_dev));
1875 }
1876
1877 Static int
1878 udav_miibus_readreg(device_ptr_t dev, int phy, int reg)
1879 {
1880 struct udav_softc *sc;
1881 u_int8_t val[2];
1882 u_int16_t data16;
1883
1884 if (dev == NULL)
1885 return (0);
1886
1887 sc = USBGETSOFTC(dev);
1888
1889 DPRINTFN(0xff, ("%s: %s: enter, phy=%d reg=0x%04x\n",
1890 USBDEVNAME(sc->sc_dev), __func__, phy, reg));
1891
1892 if (sc->sc_dying) {
1893 #ifdef DIAGNOSTIC
1894 printf("%s: %s: dying\n", USBDEVNAME(sc->sc_dev),
1895 __func__);
1896 #endif
1897 return (0);
1898 }
1899
1900 /* XXX: one PHY only for the internal PHY */
1901 if (phy != 0) {
1902 DPRINTFN(0xff, ("%s: %s: phy=%d is not supported\n",
1903 USBDEVNAME(sc->sc_dev), __func__, phy));
1904 return (0);
1905 }
1906
1907 udav_lock_mii(sc);
1908
1909 /* select internal PHY and set PHY register address */
1910 udav_csr_write1(sc, UDAV_EPAR,
1911 UDAV_EPAR_PHY_ADR0 | (reg & UDAV_EPAR_EROA_MASK));
1912
1913 /* select PHY operation and start read command */
1914 udav_csr_write1(sc, UDAV_EPCR, UDAV_EPCR_EPOS | UDAV_EPCR_ERPRR);
1915
1916 /* XXX: should be wait? */
1917
1918 /* end read command */
1919 UDAV_CLRBIT(sc, UDAV_EPCR, UDAV_EPCR_ERPRR);
1920
1921 /* retrieve the result from data registers */
1922 udav_csr_read(sc, UDAV_EPDRL, val, 2);
1923
1924 udav_unlock_mii(sc);
1925
1926 data16 = val[0] | (val[1] << 8);
1927
1928 DPRINTFN(0xff, ("%s: %s: phy=%d reg=0x%04x => 0x%04x\n",
1929 USBDEVNAME(sc->sc_dev), __func__, phy, reg, data16));
1930
1931 return (data16);
1932 }
1933
1934 Static void
1935 udav_miibus_writereg(device_ptr_t dev, int phy, int reg, int data)
1936 {
1937 struct udav_softc *sc;
1938 u_int8_t val[2];
1939
1940 if (dev == NULL)
1941 return;
1942
1943 sc = USBGETSOFTC(dev);
1944
1945 DPRINTFN(0xff, ("%s: %s: enter, phy=%d reg=0x%04x data=0x%04x\n",
1946 USBDEVNAME(sc->sc_dev), __func__, phy, reg, data));
1947
1948 if (sc->sc_dying) {
1949 #ifdef DIAGNOSTIC
1950 printf("%s: %s: dying\n", USBDEVNAME(sc->sc_dev),
1951 __func__);
1952 #endif
1953 return;
1954 }
1955
1956 /* XXX: one PHY only for the internal PHY */
1957 if (phy != 0) {
1958 DPRINTFN(0xff, ("%s: %s: phy=%d is not supported\n",
1959 USBDEVNAME(sc->sc_dev), __func__, phy));
1960 return;
1961 }
1962
1963 udav_lock_mii(sc);
1964
1965 /* select internal PHY and set PHY register address */
1966 udav_csr_write1(sc, UDAV_EPAR,
1967 UDAV_EPAR_PHY_ADR0 | (reg & UDAV_EPAR_EROA_MASK));
1968
1969 /* put the value to the data registers */
1970 val[0] = data & 0xff;
1971 val[1] = (data >> 8) & 0xff;
1972 udav_csr_write(sc, UDAV_EPDRL, val, 2);
1973
1974 /* select PHY operation and start write command */
1975 udav_csr_write1(sc, UDAV_EPCR, UDAV_EPCR_EPOS | UDAV_EPCR_ERPRW);
1976
1977 /* XXX: should be wait? */
1978
1979 /* end write command */
1980 UDAV_CLRBIT(sc, UDAV_EPCR, UDAV_EPCR_ERPRW);
1981
1982 udav_unlock_mii(sc);
1983
1984 return;
1985 }
1986
1987 Static void
1988 udav_miibus_statchg(device_ptr_t dev)
1989 {
1990 #ifdef UDAV_DEBUG
1991 struct udav_softc *sc;
1992
1993 if (dev == NULL)
1994 return;
1995
1996 sc = USBGETSOFTC(dev);
1997 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
1998 #endif
1999 /* Nothing to do */
2000 }
2001
2002 #if defined(__FreeBSD__)
2003 /*
2004 * Stop all chip I/O so that the kernel's probe routines don't
2005 * get confused by errant DMAs when rebooting.
2006 */
2007 Static void
2008 udav_shutdown(device_ptr_t dev)
2009 {
2010 struct udav_softc *sc;
2011
2012 sc = device_get_softc(dev);
2013
2014 udav_stop_task(sc);
2015
2016 return;
2017 }
2018
2019 Static void
2020 udav_rxstart(struct ifnet *ifp)
2021 {
2022 struct udav_softc *sc;
2023 struct udav_chain *c;
2024
2025 sc = ifp->if_softc;
2026 UDAV_LOCK(sc);
2027 c = &sc->sc_cdata.udav_rx_chain[sc->sc_cdata.udav_rx_prod];
2028
2029 if (udav_newbuf(sc, c, NULL) == ENOBUFS) {
2030 ifp->if_ierrors++;
2031 UDAV_UNLOCK(sc);
2032 return;
2033 }
2034
2035 /* Setup new transfer. */
2036 usbd_setup_xfer(c->udav_xfer, sc->sc_pipe_rx,
2037 c, c->udav_buf, UDAV_BUFSZ,
2038 USBD_SHORT_XFER_OK | USBD_NO_COPY,
2039 USBD_NO_TIMEOUT, udav_rxeof);
2040 usbd_transfer(c->udav_xfer);
2041
2042 UDAV_UNLOCK(sc);
2043 return;
2044 }
2045 #endif
Cache object: 62db4c6f5bce34bb53bdc31677d4515f
|