xref: /openbsd/sys/dev/usb/if_udav.c (revision 81508fe3)
1 /*	$OpenBSD: if_udav.c,v 1.86 2024/05/23 03:21:09 jsg Exp $ */
2 /*	$NetBSD: if_udav.c,v 1.3 2004/04/23 17:25:25 itojun Exp $	*/
3 /*	$nabe: if_udav.c,v 1.3 2003/08/21 16:57:19 nabe Exp $	*/
4 /*
5  * Copyright (c) 2003
6  *     Shingo WATANABE <nabe@nabechan.org>.  All rights reserved.
7  * Copyright (c) 2014
8  *     Takayoshi SASANO <uaa@uaa.org.uk> (RD9700 support)
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://www.meworks.net/userfile/24247/DM9601-DS-P03-102908.pdf
40  */
41 
42 /*
43  * TODO:
44  *	Interrupt Endpoint support
45  *	External PHYs
46  */
47 
48 #include "bpfilter.h"
49 
50 #include <sys/param.h>
51 #include <sys/systm.h>
52 #include <sys/rwlock.h>
53 #include <sys/mbuf.h>
54 
55 #include <sys/device.h>
56 
57 #include <net/if.h>
58 #include <net/if_media.h>
59 
60 #if NBPFILTER > 0
61 #include <net/bpf.h>
62 #endif
63 
64 #include <netinet/in.h>
65 #include <netinet/if_ether.h>
66 
67 #include <dev/mii/miivar.h>
68 
69 #include <dev/usb/usb.h>
70 #include <dev/usb/usbdi.h>
71 #include <dev/usb/usbdi_util.h>
72 #include <dev/usb/usbdevs.h>
73 
74 #include <dev/usb/if_udavreg.h>
75 
76 int udav_match(struct device *, void *, void *);
77 void udav_attach(struct device *, struct device *, void *);
78 int udav_detach(struct device *, int);
79 
80 struct cfdriver udav_cd = {
81 	NULL, "udav", DV_IFNET
82 };
83 
84 const struct cfattach udav_ca = {
85 	sizeof(struct udav_softc), udav_match, udav_attach, udav_detach
86 };
87 
88 int udav_openpipes(struct udav_softc *);
89 int udav_rx_list_init(struct udav_softc *);
90 int udav_tx_list_init(struct udav_softc *);
91 int udav_newbuf(struct udav_softc *, struct udav_chain *, struct mbuf *);
92 void udav_start(struct ifnet *);
93 int udav_send(struct udav_softc *, struct mbuf *, int);
94 void udav_txeof(struct usbd_xfer *, void *, usbd_status);
95 void udav_rxeof(struct usbd_xfer *, void *, usbd_status);
96 void udav_tick(void *);
97 void udav_tick_task(void *);
98 int udav_ioctl(struct ifnet *, u_long, caddr_t);
99 void udav_stop_task(struct udav_softc *);
100 void udav_stop(struct ifnet *, int);
101 void udav_watchdog(struct ifnet *);
102 int udav_ifmedia_change(struct ifnet *);
103 void udav_ifmedia_status(struct ifnet *, struct ifmediareq *);
104 void udav_lock_mii(struct udav_softc *);
105 void udav_unlock_mii(struct udav_softc *);
106 int udav_miibus_readreg(struct device *, int, int);
107 void udav_miibus_writereg(struct device *, int, int, int);
108 void udav_miibus_statchg(struct device *);
109 int udav_init(struct ifnet *);
110 void udav_iff(struct udav_softc *);
111 void udav_reset(struct udav_softc *);
112 
113 int udav_csr_read(struct udav_softc *, int, void *, int);
114 int udav_csr_write(struct udav_softc *, int, void *, int);
115 int udav_csr_read1(struct udav_softc *, int);
116 int udav_csr_write1(struct udav_softc *, int, unsigned char);
117 
118 #if 0
119 int udav_mem_read(struct udav_softc *, int, void *, int);
120 int udav_mem_write(struct udav_softc *, int, void *, int);
121 int udav_mem_write1(struct udav_softc *, int, unsigned char);
122 #endif
123 
124 /* Macros */
125 #ifdef UDAV_DEBUG
126 #define DPRINTF(x)	do { if (udavdebug) printf x; } while(0)
127 #define DPRINTFN(n,x)	do { if (udavdebug >= (n)) printf x; } while(0)
128 int udavdebug = 0;
129 #else
130 #define DPRINTF(x)
131 #define DPRINTFN(n,x)
132 #endif
133 
134 #define	UDAV_SETBIT(sc, reg, x)	\
135 	udav_csr_write1(sc, reg, udav_csr_read1(sc, reg) | (x))
136 
137 #define	UDAV_CLRBIT(sc, reg, x)	\
138 	udav_csr_write1(sc, reg, udav_csr_read1(sc, reg) & ~(x))
139 
140 static const struct udav_type {
141 	struct usb_devno udav_dev;
142 	u_int16_t udav_flags;
143 #define UDAV_EXT_PHY	0x0001
144 #define UDAV_RD9700	0x0002
145 } udav_devs [] = {
146 	{{ USB_VENDOR_COREGA, USB_PRODUCT_COREGA_FETHER_USB_TXC }, 0 },
147 	{{ USB_VENDOR_DAVICOM, USB_PRODUCT_DAVICOM_DM9601 }, 0 },
148 	{{ USB_VENDOR_DAVICOM, USB_PRODUCT_DAVICOM_WK668 }, 0 },
149 	{{ USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_DM9601 }, 0 },
150 	{{ USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_ST268 }, 0 },
151 	{{ USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_ZT6688 }, 0 },
152 	{{ USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_ADM8515 }, 0 },
153 	{{ USB_VENDOR_UNKNOWN4, USB_PRODUCT_UNKNOWN4_DM9601 }, 0 },
154 	{{ USB_VENDOR_UNKNOWN6, USB_PRODUCT_UNKNOWN6_DM9601 }, 0 },
155 	{{ USB_VENDOR_UNKNOWN4, USB_PRODUCT_UNKNOWN4_RD9700 }, UDAV_RD9700 },
156 };
157 #define udav_lookup(v, p) ((struct udav_type *)usb_lookup(udav_devs, v, p))
158 
159 
160 /* Probe */
161 int
udav_match(struct device * parent,void * match,void * aux)162 udav_match(struct device *parent, void *match, void *aux)
163 {
164 	struct usb_attach_arg *uaa = aux;
165 
166 	if (uaa->iface == NULL || uaa->configno != 1)
167 		return (UMATCH_NONE);
168 
169 	return (udav_lookup(uaa->vendor, uaa->product) != NULL ?
170 		UMATCH_VENDOR_PRODUCT_CONF_IFACE : UMATCH_NONE);
171 }
172 
173 /* Attach */
174 void
udav_attach(struct device * parent,struct device * self,void * aux)175 udav_attach(struct device *parent, struct device *self, void *aux)
176 {
177 	struct udav_softc *sc = (struct udav_softc *)self;
178 	struct usb_attach_arg *uaa = aux;
179 	struct usbd_device *dev = uaa->device;
180 	struct usbd_interface *iface = uaa->iface;
181 	usbd_status err;
182 	usb_interface_descriptor_t *id;
183 	usb_endpoint_descriptor_t *ed;
184 	char *devname = sc->sc_dev.dv_xname;
185 	struct ifnet *ifp;
186 	struct mii_data *mii;
187 	u_char eaddr[ETHER_ADDR_LEN];
188 	int i, s;
189 
190 	printf("%s: ", devname);
191 
192 	sc->sc_udev = dev;
193 
194 	usb_init_task(&sc->sc_tick_task, udav_tick_task, sc,
195 	    USB_TASK_TYPE_GENERIC);
196 	rw_init(&sc->sc_mii_lock, "udavmii");
197 	usb_init_task(&sc->sc_stop_task, (void (*)(void *)) udav_stop_task, sc,
198 	    USB_TASK_TYPE_GENERIC);
199 
200 	sc->sc_ctl_iface = iface;
201 	sc->sc_flags = udav_lookup(uaa->vendor, uaa->product)->udav_flags;
202 
203 	/* get interface descriptor */
204 	id = usbd_get_interface_descriptor(sc->sc_ctl_iface);
205 
206 	/* find endpoints */
207 	sc->sc_bulkin_no = sc->sc_bulkout_no = sc->sc_intrin_no = -1;
208 	for (i = 0; i < id->bNumEndpoints; i++) {
209 		ed = usbd_interface2endpoint_descriptor(sc->sc_ctl_iface, i);
210 		if (ed == NULL) {
211 			printf("couldn't get endpoint %d\n", i);
212 			goto bad;
213 		}
214 		if (UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK &&
215 		    UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN)
216 			sc->sc_bulkin_no = ed->bEndpointAddress; /* RX */
217 		else if (UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK &&
218 			 UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT)
219 			sc->sc_bulkout_no = ed->bEndpointAddress; /* TX */
220 		else if (UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT &&
221 			 UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN)
222 			sc->sc_intrin_no = ed->bEndpointAddress; /* Status */
223 	}
224 
225 	if (sc->sc_bulkin_no == -1 || sc->sc_bulkout_no == -1 ||
226 	    sc->sc_intrin_no == -1) {
227 		printf("missing endpoint\n");
228 		goto bad;
229 	}
230 
231 	s = splnet();
232 
233 	/* reset the adapter */
234 	udav_reset(sc);
235 
236 	/* Get Ethernet Address */
237 	err = udav_csr_read(sc, UDAV_PAR, (void *)eaddr, ETHER_ADDR_LEN);
238 	if (err) {
239 		printf("read MAC address failed\n");
240 		splx(s);
241 		goto bad;
242 	}
243 
244 	/* Print Ethernet Address */
245 	printf("address %s\n", ether_sprintf(eaddr));
246 
247         bcopy(eaddr, (char *)&sc->sc_ac.ac_enaddr, ETHER_ADDR_LEN);
248 
249 	/* initialize interface information */
250 	ifp = GET_IFP(sc);
251 	ifp->if_softc = sc;
252 	strlcpy(ifp->if_xname, devname, IFNAMSIZ);
253 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
254 	ifp->if_start = udav_start;
255 	ifp->if_ioctl = udav_ioctl;
256 	ifp->if_watchdog = udav_watchdog;
257 
258 	/*
259 	 * Do ifmedia setup.
260 	 */
261 	mii = &sc->sc_mii;
262 	mii->mii_ifp = ifp;
263 	mii->mii_readreg = udav_miibus_readreg;
264 	mii->mii_writereg = udav_miibus_writereg;
265 	mii->mii_statchg = udav_miibus_statchg;
266 	mii->mii_flags = MIIF_AUTOTSLEEP;
267 	ifmedia_init(&mii->mii_media, 0,
268 		     udav_ifmedia_change, udav_ifmedia_status);
269 	if (sc->sc_flags & UDAV_RD9700) {
270 		/* no MII-PHY */
271 		ifmedia_add(&mii->mii_media, IFM_ETHER | IFM_NONE, 0, NULL);
272 		ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_NONE);
273 	} else {
274 		mii_attach(self, mii, 0xffffffff,
275 			   MII_PHY_ANY, MII_OFFSET_ANY, 0);
276 		if (LIST_FIRST(&mii->mii_phys) == NULL) {
277 			ifmedia_add(&mii->mii_media, IFM_ETHER | IFM_NONE,
278 				    0, NULL);
279 			ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_NONE);
280 		} else
281 			ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_AUTO);
282 	}
283 
284 	/* attach the interface */
285 	if_attach(ifp);
286 	ether_ifattach(ifp);
287 
288 	timeout_set(&sc->sc_stat_ch, udav_tick, sc);
289 
290 	splx(s);
291 
292 	return;
293 
294  bad:
295 	usbd_deactivate(sc->sc_udev);
296 }
297 
298 /* detach */
299 int
udav_detach(struct device * self,int flags)300 udav_detach(struct device *self, int flags)
301 {
302 	struct udav_softc *sc = (struct udav_softc *)self;
303 	struct ifnet *ifp = GET_IFP(sc);
304 	int s;
305 
306 	DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__));
307 
308 
309 	if (timeout_initialized(&sc->sc_stat_ch))
310 		timeout_del(&sc->sc_stat_ch);
311 
312 	/* Remove any pending tasks */
313 	usb_rem_task(sc->sc_udev, &sc->sc_tick_task);
314 	usb_rem_task(sc->sc_udev, &sc->sc_stop_task);
315 
316 	s = splusb();
317 
318 	if (--sc->sc_refcnt >= 0) {
319 		/* Wait for processes to go away */
320 		usb_detach_wait(&sc->sc_dev);
321 	}
322 	if (ifp->if_flags & IFF_RUNNING)
323 		udav_stop(GET_IFP(sc), 1);
324 
325 	if (!(sc->sc_flags & UDAV_RD9700))
326 		mii_detach(&sc->sc_mii, MII_PHY_ANY, MII_OFFSET_ANY);
327 	ifmedia_delete_instance(&sc->sc_mii.mii_media, IFM_INST_ANY);
328 	if (ifp->if_softc != NULL) {
329 		ether_ifdetach(ifp);
330 		if_detach(ifp);
331 	}
332 
333 #ifdef DIAGNOSTIC
334 	if (sc->sc_pipe_tx != NULL)
335 		printf("%s: detach has active tx endpoint.\n",
336 		       sc->sc_dev.dv_xname);
337 	if (sc->sc_pipe_rx != NULL)
338 		printf("%s: detach has active rx endpoint.\n",
339 		       sc->sc_dev.dv_xname);
340 	if (sc->sc_pipe_intr != NULL)
341 		printf("%s: detach has active intr endpoint.\n",
342 		       sc->sc_dev.dv_xname);
343 #endif
344 	splx(s);
345 
346 	return (0);
347 }
348 
349 #if 0
350 /* read memory */
351 int
352 udav_mem_read(struct udav_softc *sc, int offset, void *buf, int len)
353 {
354 	usb_device_request_t req;
355 	usbd_status err;
356 
357 	if (sc == NULL)
358 		return (0);
359 
360 	DPRINTFN(0x200,
361 		("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__));
362 
363 	if (usbd_is_dying(sc->sc_udev))
364 		return (0);
365 
366 	offset &= 0xffff;
367 	len &= 0xff;
368 
369 	req.bmRequestType = UT_READ_VENDOR_DEVICE;
370 	req.bRequest = UDAV_REQ_MEM_READ;
371 	USETW(req.wValue, 0x0000);
372 	USETW(req.wIndex, offset);
373 	USETW(req.wLength, len);
374 
375 	sc->sc_refcnt++;
376 	err = usbd_do_request(sc->sc_udev, &req, buf);
377 	if (--sc->sc_refcnt < 0)
378 		usb_detach_wakeup(&sc->sc_dev);
379 	if (err) {
380 		DPRINTF(("%s: %s: read failed. off=%04x, err=%d\n",
381 			 sc->sc_dev.dv_xname, __func__, offset, err));
382 	}
383 
384 	return (err);
385 }
386 
387 /* write memory */
388 int
389 udav_mem_write(struct udav_softc *sc, int offset, void *buf, int len)
390 {
391 	usb_device_request_t req;
392 	usbd_status err;
393 
394 	if (sc == NULL)
395 		return (0);
396 
397 	DPRINTFN(0x200,
398 		("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__));
399 
400 	if (usbd_is_dying(sc->sc_udev))
401 		return (0);
402 
403 	offset &= 0xffff;
404 	len &= 0xff;
405 
406 	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
407 	req.bRequest = UDAV_REQ_MEM_WRITE;
408 	USETW(req.wValue, 0x0000);
409 	USETW(req.wIndex, offset);
410 	USETW(req.wLength, len);
411 
412 	sc->sc_refcnt++;
413 	err = usbd_do_request(sc->sc_udev, &req, buf);
414 	if (--sc->sc_refcnt < 0)
415 		usb_detach_wakeup(&sc->sc_dev);
416 	if (err) {
417 		DPRINTF(("%s: %s: write failed. off=%04x, err=%d\n",
418 			 sc->sc_dev.dv_xname, __func__, offset, err));
419 	}
420 
421 	return (err);
422 }
423 
424 /* write memory */
425 int
426 udav_mem_write1(struct udav_softc *sc, int offset, unsigned char ch)
427 {
428 	usb_device_request_t req;
429 	usbd_status err;
430 
431 	if (sc == NULL)
432 		return (0);
433 
434 	DPRINTFN(0x200,
435 		("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__));
436 
437 	if (usbd_is_dying(sc->sc_udev))
438 		return (0);
439 
440 	offset &= 0xffff;
441 
442 	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
443 	req.bRequest = UDAV_REQ_MEM_WRITE1;
444 	USETW(req.wValue, ch);
445 	USETW(req.wIndex, offset);
446 	USETW(req.wLength, 0x0000);
447 
448 	sc->sc_refcnt++;
449 	err = usbd_do_request(sc->sc_udev, &req, NULL);
450 	if (--sc->sc_refcnt < 0)
451 		usb_detach_wakeup(&sc->sc_dev);
452 	if (err) {
453 		DPRINTF(("%s: %s: write failed. off=%04x, err=%d\n",
454 			 sc->sc_dev.dv_xname, __func__, offset, err));
455 	}
456 
457 	return (err);
458 }
459 #endif
460 
461 /* read register(s) */
462 int
udav_csr_read(struct udav_softc * sc,int offset,void * buf,int len)463 udav_csr_read(struct udav_softc *sc, int offset, void *buf, int len)
464 {
465 	usb_device_request_t req;
466 	usbd_status err;
467 
468 	if (sc == NULL)
469 		return (0);
470 
471 	DPRINTFN(0x200,
472 		("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__));
473 
474 	if (usbd_is_dying(sc->sc_udev))
475 		return (0);
476 
477 	offset &= 0xff;
478 	len &= 0xff;
479 
480 	req.bmRequestType = UT_READ_VENDOR_DEVICE;
481 	req.bRequest = UDAV_REQ_REG_READ;
482 	USETW(req.wValue, 0x0000);
483 	USETW(req.wIndex, offset);
484 	USETW(req.wLength, len);
485 
486 	sc->sc_refcnt++;
487 	err = usbd_do_request(sc->sc_udev, &req, buf);
488 	if (--sc->sc_refcnt < 0)
489 		usb_detach_wakeup(&sc->sc_dev);
490 	if (err) {
491 		DPRINTF(("%s: %s: read failed. off=%04x, err=%d\n",
492 			 sc->sc_dev.dv_xname, __func__, offset, err));
493 	}
494 
495 	return (err);
496 }
497 
498 /* write register(s) */
499 int
udav_csr_write(struct udav_softc * sc,int offset,void * buf,int len)500 udav_csr_write(struct udav_softc *sc, int offset, void *buf, int len)
501 {
502 	usb_device_request_t req;
503 	usbd_status err;
504 
505 	if (sc == NULL)
506 		return (0);
507 
508 	DPRINTFN(0x200,
509 		("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__));
510 
511 	if (usbd_is_dying(sc->sc_udev))
512 		return (0);
513 
514 	offset &= 0xff;
515 	len &= 0xff;
516 
517 	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
518 	req.bRequest = UDAV_REQ_REG_WRITE;
519 	USETW(req.wValue, 0x0000);
520 	USETW(req.wIndex, offset);
521 	USETW(req.wLength, len);
522 
523 	sc->sc_refcnt++;
524 	err = usbd_do_request(sc->sc_udev, &req, buf);
525 	if (--sc->sc_refcnt < 0)
526 		usb_detach_wakeup(&sc->sc_dev);
527 	if (err) {
528 		DPRINTF(("%s: %s: write failed. off=%04x, err=%d\n",
529 			 sc->sc_dev.dv_xname, __func__, offset, err));
530 	}
531 
532 	return (err);
533 }
534 
535 int
udav_csr_read1(struct udav_softc * sc,int offset)536 udav_csr_read1(struct udav_softc *sc, int offset)
537 {
538 	u_int8_t val = 0;
539 
540 	if (sc == NULL)
541 		return (0);
542 
543 	DPRINTFN(0x200,
544 		("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__));
545 
546 	return (udav_csr_read(sc, offset, &val, 1) ? 0 : val);
547 }
548 
549 /* write a register */
550 int
udav_csr_write1(struct udav_softc * sc,int offset,unsigned char ch)551 udav_csr_write1(struct udav_softc *sc, int offset, unsigned char ch)
552 {
553 	usb_device_request_t req;
554 	usbd_status err;
555 
556 	if (sc == NULL)
557 		return (0);
558 
559 	DPRINTFN(0x200,
560 		("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__));
561 
562 	if (usbd_is_dying(sc->sc_udev))
563 		return (0);
564 
565 	offset &= 0xff;
566 
567 	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
568 	req.bRequest = UDAV_REQ_REG_WRITE1;
569 	USETW(req.wValue, ch);
570 	USETW(req.wIndex, offset);
571 	USETW(req.wLength, 0x0000);
572 
573 	sc->sc_refcnt++;
574 	err = usbd_do_request(sc->sc_udev, &req, NULL);
575 	if (--sc->sc_refcnt < 0)
576 		usb_detach_wakeup(&sc->sc_dev);
577 	if (err) {
578 		DPRINTF(("%s: %s: write failed. off=%04x, err=%d\n",
579 			 sc->sc_dev.dv_xname, __func__, offset, err));
580 	}
581 
582 	return (err);
583 }
584 
585 int
udav_init(struct ifnet * ifp)586 udav_init(struct ifnet *ifp)
587 {
588 	struct udav_softc *sc = ifp->if_softc;
589 	struct mii_data *mii = GET_MII(sc);
590 	u_char *eaddr;
591 	int s;
592 
593 	DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__));
594 
595 	s = splnet();
596 
597 	/* Cancel pending I/O and free all TX/RX buffers */
598 	udav_stop(ifp, 1);
599 
600         eaddr = sc->sc_ac.ac_enaddr;
601 	udav_csr_write(sc, UDAV_PAR, eaddr, ETHER_ADDR_LEN);
602 
603 	/* Initialize network control register */
604 	/*  Disable loopback  */
605 	UDAV_CLRBIT(sc, UDAV_NCR, UDAV_NCR_LBK0 | UDAV_NCR_LBK1);
606 
607 	/* Initialize RX control register */
608 	UDAV_SETBIT(sc, UDAV_RCR, UDAV_RCR_DIS_LONG | UDAV_RCR_DIS_CRC);
609 
610 	/* Initialize transmit ring */
611 	if (udav_tx_list_init(sc) == ENOBUFS) {
612 		printf("%s: tx list init failed\n", sc->sc_dev.dv_xname);
613 		splx(s);
614 		return (EIO);
615 	}
616 
617 	/* Initialize receive ring */
618 	if (udav_rx_list_init(sc) == ENOBUFS) {
619 		printf("%s: rx list init failed\n", sc->sc_dev.dv_xname);
620 		splx(s);
621 		return (EIO);
622 	}
623 
624 	/* Program promiscuous mode and multicast filters */
625 	udav_iff(sc);
626 
627 	/* Enable RX */
628 	UDAV_SETBIT(sc, UDAV_RCR, UDAV_RCR_RXEN);
629 
630 	/* clear POWER_DOWN state of internal PHY */
631 	UDAV_SETBIT(sc, UDAV_GPCR, UDAV_GPCR_GEP_CNTL0);
632 	UDAV_CLRBIT(sc, UDAV_GPR, UDAV_GPR_GEPIO0);
633 
634 	if (!(sc->sc_flags & UDAV_RD9700))
635 		mii_mediachg(mii);
636 
637 	if (sc->sc_pipe_tx == NULL || sc->sc_pipe_rx == NULL) {
638 		if (udav_openpipes(sc)) {
639 			splx(s);
640 			return (EIO);
641 		}
642 	}
643 
644 	ifp->if_flags |= IFF_RUNNING;
645 	ifq_clr_oactive(&ifp->if_snd);
646 
647 	splx(s);
648 
649 	timeout_add_sec(&sc->sc_stat_ch, 1);
650 
651 	return (0);
652 }
653 
654 void
udav_reset(struct udav_softc * sc)655 udav_reset(struct udav_softc *sc)
656 {
657 	int i;
658 
659 	DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__));
660 
661 	if (usbd_is_dying(sc->sc_udev))
662 		return;
663 
664 	/* Select PHY */
665 #if 1
666 	/*
667 	 * XXX: force select internal phy.
668 	 *	external phy routines are not tested.
669 	 */
670 	UDAV_CLRBIT(sc, UDAV_NCR, UDAV_NCR_EXT_PHY);
671 #else
672 	if (sc->sc_flags & UDAV_EXT_PHY) {
673 		UDAV_SETBIT(sc, UDAV_NCR, UDAV_NCR_EXT_PHY);
674 	} else {
675 		UDAV_CLRBIT(sc, UDAV_NCR, UDAV_NCR_EXT_PHY);
676 	}
677 #endif
678 
679 	UDAV_SETBIT(sc, UDAV_NCR, UDAV_NCR_RST);
680 
681 	for (i = 0; i < UDAV_TX_TIMEOUT; i++) {
682 		if (!(udav_csr_read1(sc, UDAV_NCR) & UDAV_NCR_RST))
683 			break;
684 		delay(10);	/* XXX */
685 	}
686 	delay(10000);		/* XXX */
687 }
688 
689 #define UDAV_BITS	6
690 
691 void
udav_iff(struct udav_softc * sc)692 udav_iff(struct udav_softc *sc)
693 {
694 	struct ifnet *ifp = GET_IFP(sc);
695 	struct arpcom *ac = &sc->sc_ac;
696 	struct ether_multi *enm;
697 	struct ether_multistep step;
698 	u_int8_t hashes[8];
699 	int h = 0;
700 
701 	DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__));
702 
703 	if (usbd_is_dying(sc->sc_udev))
704 		return;
705 
706 	UDAV_CLRBIT(sc, UDAV_RCR, UDAV_RCR_ALL | UDAV_RCR_PRMSC);
707 	memset(hashes, 0x00, sizeof(hashes));
708 	ifp->if_flags &= ~IFF_ALLMULTI;
709 
710 	if (ifp->if_flags & IFF_PROMISC || ac->ac_multirangecnt > 0) {
711 		ifp->if_flags |= IFF_ALLMULTI;
712 		UDAV_SETBIT(sc, UDAV_RCR, UDAV_RCR_ALL);
713 		if (ifp->if_flags & IFF_PROMISC)
714 			UDAV_SETBIT(sc, UDAV_RCR, UDAV_RCR_PRMSC);
715 	} else {
716 		hashes[7] |= 0x80;	/* broadcast address */
717 
718 		/* now program new ones */
719 		ETHER_FIRST_MULTI(step, ac, enm);
720 		while (enm != NULL) {
721 			h = ether_crc32_le(enm->enm_addrlo, ETHER_ADDR_LEN) &
722 			    ((1 << UDAV_BITS) - 1);
723 
724 			hashes[h>>3] |= 1 << (h & 0x7);
725 
726 			ETHER_NEXT_MULTI(step, enm);
727 		}
728 	}
729 
730 	udav_csr_write(sc, UDAV_MAR, hashes, sizeof(hashes));
731 }
732 
733 int
udav_openpipes(struct udav_softc * sc)734 udav_openpipes(struct udav_softc *sc)
735 {
736 	struct udav_chain *c;
737 	usbd_status err;
738 	int i;
739 	int error = 0;
740 
741 	if (usbd_is_dying(sc->sc_udev))
742 		return (EIO);
743 
744 	sc->sc_refcnt++;
745 
746 	/* Open RX pipe */
747 	err = usbd_open_pipe(sc->sc_ctl_iface, sc->sc_bulkin_no,
748 			     USBD_EXCLUSIVE_USE, &sc->sc_pipe_rx);
749 	if (err) {
750 		printf("%s: open rx pipe failed: %s\n",
751 		       sc->sc_dev.dv_xname, usbd_errstr(err));
752 		error = EIO;
753 		goto done;
754 	}
755 
756 	/* Open TX pipe */
757 	err = usbd_open_pipe(sc->sc_ctl_iface, sc->sc_bulkout_no,
758 			     USBD_EXCLUSIVE_USE, &sc->sc_pipe_tx);
759 	if (err) {
760 		printf("%s: open tx pipe failed: %s\n",
761 		       sc->sc_dev.dv_xname, usbd_errstr(err));
762 		error = EIO;
763 		goto done;
764 	}
765 
766 #if 0
767 	/* XXX: interrupt endpoint is not yet supported */
768 	/* Open Interrupt pipe */
769 	err = usbd_open_pipe_intr(sc->sc_ctl_iface, sc->sc_intrin_no,
770 				  0, &sc->sc_pipe_intr, sc,
771 				  &sc->sc_cdata.udav_ibuf, UDAV_INTR_PKGLEN,
772 				  udav_intr, UDAV_INTR_INTERVAL);
773 	if (err) {
774 		printf("%s: open intr pipe failed: %s\n",
775 		       sc->sc_dev.dv_xname, usbd_errstr(err));
776 		error = EIO;
777 		goto done;
778 	}
779 #endif
780 
781 
782 	/* Start up the receive pipe. */
783 	for (i = 0; i < UDAV_RX_LIST_CNT; i++) {
784 		c = &sc->sc_cdata.udav_rx_chain[i];
785 		usbd_setup_xfer(c->udav_xfer, sc->sc_pipe_rx,
786 				c, c->udav_buf, UDAV_BUFSZ,
787 				USBD_SHORT_XFER_OK | USBD_NO_COPY,
788 				USBD_NO_TIMEOUT, udav_rxeof);
789 		(void)usbd_transfer(c->udav_xfer);
790 		DPRINTF(("%s: %s: start read\n", sc->sc_dev.dv_xname,
791 			 __func__));
792 	}
793 
794  done:
795 	if (--sc->sc_refcnt < 0)
796 		usb_detach_wakeup(&sc->sc_dev);
797 
798 	return (error);
799 }
800 
801 int
udav_newbuf(struct udav_softc * sc,struct udav_chain * c,struct mbuf * m)802 udav_newbuf(struct udav_softc *sc, struct udav_chain *c, struct mbuf *m)
803 {
804 	struct mbuf *m_new = NULL;
805 
806 	DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__));
807 
808 	if (m == NULL) {
809 		MGETHDR(m_new, M_DONTWAIT, MT_DATA);
810 		if (m_new == NULL) {
811 			printf("%s: no memory for rx list "
812 			       "-- packet dropped!\n", sc->sc_dev.dv_xname);
813 			return (ENOBUFS);
814 		}
815 		MCLGET(m_new, M_DONTWAIT);
816 		if (!(m_new->m_flags & M_EXT)) {
817 			printf("%s: no memory for rx list "
818 			       "-- packet dropped!\n", sc->sc_dev.dv_xname);
819 			m_freem(m_new);
820 			return (ENOBUFS);
821 		}
822 		m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
823 	} else {
824 		m_new = m;
825 		m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
826 		m_new->m_data = m_new->m_ext.ext_buf;
827 	}
828 
829 	m_adj(m_new, ETHER_ALIGN);
830 	c->udav_mbuf = m_new;
831 
832 	return (0);
833 }
834 
835 
836 int
udav_rx_list_init(struct udav_softc * sc)837 udav_rx_list_init(struct udav_softc *sc)
838 {
839 	struct udav_cdata *cd;
840 	struct udav_chain *c;
841 	int i;
842 
843 	DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__));
844 
845 	cd = &sc->sc_cdata;
846 	for (i = 0; i < UDAV_RX_LIST_CNT; i++) {
847 		c = &cd->udav_rx_chain[i];
848 		c->udav_sc = sc;
849 		c->udav_idx = i;
850 		if (udav_newbuf(sc, c, NULL) == ENOBUFS)
851 			return (ENOBUFS);
852 		if (c->udav_xfer == NULL) {
853 			c->udav_xfer = usbd_alloc_xfer(sc->sc_udev);
854 			if (c->udav_xfer == NULL)
855 				return (ENOBUFS);
856 			c->udav_buf = usbd_alloc_buffer(c->udav_xfer, UDAV_BUFSZ);
857 			if (c->udav_buf == NULL) {
858 				usbd_free_xfer(c->udav_xfer);
859 				return (ENOBUFS);
860 			}
861 		}
862 	}
863 
864 	return (0);
865 }
866 
867 int
udav_tx_list_init(struct udav_softc * sc)868 udav_tx_list_init(struct udav_softc *sc)
869 {
870 	struct udav_cdata *cd;
871 	struct udav_chain *c;
872 	int i;
873 
874 	DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__));
875 
876 	cd = &sc->sc_cdata;
877 	for (i = 0; i < UDAV_TX_LIST_CNT; i++) {
878 		c = &cd->udav_tx_chain[i];
879 		c->udav_sc = sc;
880 		c->udav_idx = i;
881 		c->udav_mbuf = NULL;
882 		if (c->udav_xfer == NULL) {
883 			c->udav_xfer = usbd_alloc_xfer(sc->sc_udev);
884 			if (c->udav_xfer == NULL)
885 				return (ENOBUFS);
886 			c->udav_buf = usbd_alloc_buffer(c->udav_xfer, UDAV_BUFSZ);
887 			if (c->udav_buf == NULL) {
888 				usbd_free_xfer(c->udav_xfer);
889 				return (ENOBUFS);
890 			}
891 		}
892 	}
893 
894 	return (0);
895 }
896 
897 void
udav_start(struct ifnet * ifp)898 udav_start(struct ifnet *ifp)
899 {
900 	struct udav_softc *sc = ifp->if_softc;
901 	struct mbuf *m_head = NULL;
902 
903 	DPRINTF(("%s: %s: enter, link=%d\n", sc->sc_dev.dv_xname,
904 		 __func__, sc->sc_link));
905 
906 	if (usbd_is_dying(sc->sc_udev))
907 		return;
908 
909 	if (!sc->sc_link)
910 		return;
911 
912 	if (ifq_is_oactive(&ifp->if_snd))
913 		return;
914 
915 	m_head = ifq_deq_begin(&ifp->if_snd);
916 	if (m_head == NULL)
917 		return;
918 
919 	if (udav_send(sc, m_head, 0)) {
920 		ifq_deq_rollback(&ifp->if_snd, m_head);
921 		ifq_set_oactive(&ifp->if_snd);
922 		return;
923 	}
924 
925 	ifq_deq_commit(&ifp->if_snd, m_head);
926 
927 #if NBPFILTER > 0
928 	if (ifp->if_bpf)
929 		bpf_mtap(ifp->if_bpf, m_head, BPF_DIRECTION_OUT);
930 #endif
931 
932 	ifq_set_oactive(&ifp->if_snd);
933 
934 	/* Set a timeout in case the chip goes out to lunch. */
935 	ifp->if_timer = 5;
936 }
937 
938 int
udav_send(struct udav_softc * sc,struct mbuf * m,int idx)939 udav_send(struct udav_softc *sc, struct mbuf *m, int idx)
940 {
941 	int total_len;
942 	struct udav_chain *c;
943 	usbd_status err;
944 
945 	DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname,__func__));
946 
947 	c = &sc->sc_cdata.udav_tx_chain[idx];
948 
949 	/* Copy the mbuf data into a contiguous buffer */
950 	/*  first 2 bytes are packet length */
951 	m_copydata(m, 0, m->m_pkthdr.len, c->udav_buf + 2);
952 	c->udav_mbuf = m;
953 	total_len = m->m_pkthdr.len;
954 	if (total_len < UDAV_MIN_FRAME_LEN) {
955 		memset(c->udav_buf + 2 + total_len, 0,
956 		    UDAV_MIN_FRAME_LEN - total_len);
957 		total_len = UDAV_MIN_FRAME_LEN;
958 	}
959 
960 	/* Frame length is specified in the first 2bytes of the buffer */
961 	c->udav_buf[0] = (u_int8_t)total_len;
962 	c->udav_buf[1] = (u_int8_t)(total_len >> 8);
963 	total_len += 2;
964 
965 	usbd_setup_xfer(c->udav_xfer, sc->sc_pipe_tx, c, c->udav_buf, total_len,
966 			USBD_FORCE_SHORT_XFER | USBD_NO_COPY,
967 			UDAV_TX_TIMEOUT, udav_txeof);
968 
969 	/* Transmit */
970 	sc->sc_refcnt++;
971 	err = usbd_transfer(c->udav_xfer);
972 	if (--sc->sc_refcnt < 0)
973 		usb_detach_wakeup(&sc->sc_dev);
974 	if (err != USBD_IN_PROGRESS) {
975 		printf("%s: udav_send error=%s\n", sc->sc_dev.dv_xname,
976 		       usbd_errstr(err));
977 		/* Stop the interface */
978 		usb_add_task(sc->sc_udev, &sc->sc_stop_task);
979 		return (EIO);
980 	}
981 
982 	DPRINTF(("%s: %s: send %d bytes\n", sc->sc_dev.dv_xname,
983 		 __func__, total_len));
984 
985 	sc->sc_cdata.udav_tx_cnt++;
986 
987 	return (0);
988 }
989 
990 void
udav_txeof(struct usbd_xfer * xfer,void * priv,usbd_status status)991 udav_txeof(struct usbd_xfer *xfer, void *priv, usbd_status status)
992 {
993 	struct udav_chain *c = priv;
994 	struct udav_softc *sc = c->udav_sc;
995 	struct ifnet *ifp = GET_IFP(sc);
996 	int s;
997 
998 	if (usbd_is_dying(sc->sc_udev))
999 		return;
1000 
1001 	s = splnet();
1002 
1003 	DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__));
1004 
1005 	ifp->if_timer = 0;
1006 	ifq_clr_oactive(&ifp->if_snd);
1007 
1008 	if (status != USBD_NORMAL_COMPLETION) {
1009 		if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
1010 			splx(s);
1011 			return;
1012 		}
1013 		ifp->if_oerrors++;
1014 		printf("%s: usb error on tx: %s\n", sc->sc_dev.dv_xname,
1015 		       usbd_errstr(status));
1016 		if (status == USBD_STALLED) {
1017 			sc->sc_refcnt++;
1018 			usbd_clear_endpoint_stall_async(sc->sc_pipe_tx);
1019 			if (--sc->sc_refcnt < 0)
1020 				usb_detach_wakeup(&sc->sc_dev);
1021 		}
1022 		splx(s);
1023 		return;
1024 	}
1025 
1026 	m_freem(c->udav_mbuf);
1027 	c->udav_mbuf = NULL;
1028 
1029 	if (ifq_empty(&ifp->if_snd) == 0)
1030 		udav_start(ifp);
1031 
1032 	splx(s);
1033 }
1034 
1035 void
udav_rxeof(struct usbd_xfer * xfer,void * priv,usbd_status status)1036 udav_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status)
1037 {
1038 	struct udav_chain *c = priv;
1039 	struct udav_softc *sc = c->udav_sc;
1040 	struct ifnet *ifp = GET_IFP(sc);
1041 	struct udav_rx_hdr *h;
1042 	struct mbuf_list ml = MBUF_LIST_INITIALIZER();
1043 	struct mbuf *m;
1044 	u_int32_t total_len;
1045 	int s;
1046 
1047 	DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname,__func__));
1048 
1049 	if (usbd_is_dying(sc->sc_udev))
1050 		return;
1051 
1052 	if (status != USBD_NORMAL_COMPLETION) {
1053 		if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
1054 			return;
1055 		sc->sc_rx_errs++;
1056 		if (usbd_ratecheck(&sc->sc_rx_notice)) {
1057 			printf("%s: %u usb errors on rx: %s\n",
1058 			       sc->sc_dev.dv_xname, sc->sc_rx_errs,
1059 			       usbd_errstr(status));
1060 			sc->sc_rx_errs = 0;
1061 		}
1062 		if (status == USBD_STALLED) {
1063 			sc->sc_refcnt++;
1064 			usbd_clear_endpoint_stall_async(sc->sc_pipe_rx);
1065 			if (--sc->sc_refcnt < 0)
1066 				usb_detach_wakeup(&sc->sc_dev);
1067 		}
1068 		goto done;
1069 	}
1070 
1071 	usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
1072 
1073 	if (total_len < UDAV_RX_HDRLEN) {
1074 		ifp->if_ierrors++;
1075 		goto done;
1076 	}
1077 
1078 	h = (struct udav_rx_hdr *)c->udav_buf;
1079 	total_len = UGETW(h->length) - ETHER_CRC_LEN;
1080 
1081 	DPRINTF(("%s: RX Status: 0x%02x\n", sc->sc_dev.dv_xname, h->pktstat));
1082 
1083 	if (h->pktstat & UDAV_RSR_LCS) {
1084 		ifp->if_collisions++;
1085 		goto done;
1086 	}
1087 
1088 	/* RX status may still be correct but total_len is bogus */
1089 	if (total_len < sizeof(struct ether_header) ||
1090 	    h->pktstat & UDAV_RSR_ERR ||
1091 	    total_len > UDAV_BUFSZ ) {
1092 		ifp->if_ierrors++;
1093 		goto done;
1094 	}
1095 
1096 	/* copy data to mbuf */
1097 	m = c->udav_mbuf;
1098 	memcpy(mtod(m, char *), c->udav_buf + UDAV_RX_HDRLEN, total_len);
1099 
1100 	m->m_pkthdr.len = m->m_len = total_len;
1101 	ml_enqueue(&ml, m);
1102 
1103 	if (udav_newbuf(sc, c, NULL) == ENOBUFS) {
1104 		ifp->if_ierrors++;
1105 		goto done;
1106 	}
1107 
1108 	s = splnet();
1109 	if_input(ifp, &ml);
1110 	splx(s);
1111 
1112  done:
1113 	/* Setup new transfer */
1114 	usbd_setup_xfer(xfer, sc->sc_pipe_rx, c, c->udav_buf, UDAV_BUFSZ,
1115 			USBD_SHORT_XFER_OK | USBD_NO_COPY,
1116 			USBD_NO_TIMEOUT, udav_rxeof);
1117 	sc->sc_refcnt++;
1118 	usbd_transfer(xfer);
1119 	if (--sc->sc_refcnt < 0)
1120 		usb_detach_wakeup(&sc->sc_dev);
1121 
1122 	DPRINTF(("%s: %s: start rx\n", sc->sc_dev.dv_xname, __func__));
1123 }
1124 
1125 int
udav_ioctl(struct ifnet * ifp,u_long cmd,caddr_t data)1126 udav_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
1127 {
1128 	struct udav_softc *sc = ifp->if_softc;
1129 	struct ifreq *ifr = (struct ifreq *)data;
1130 	int s, error = 0;
1131 
1132 	DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__));
1133 
1134 	if (usbd_is_dying(sc->sc_udev))
1135 		return ENXIO;
1136 
1137 	s = splnet();
1138 
1139 	switch (cmd) {
1140 	case SIOCSIFADDR:
1141 		ifp->if_flags |= IFF_UP;
1142 		if (!(ifp->if_flags & IFF_RUNNING))
1143 			udav_init(ifp);
1144 		break;
1145 
1146 	case SIOCSIFFLAGS:
1147 		if (ifp->if_flags & IFF_UP) {
1148 			if (ifp->if_flags & IFF_RUNNING)
1149 				error = ENETRESET;
1150 			else
1151 				udav_init(ifp);
1152 		} else {
1153 			if (ifp->if_flags & IFF_RUNNING)
1154 				udav_stop(ifp, 1);
1155 		}
1156 		break;
1157 
1158 	case SIOCGIFMEDIA:
1159 	case SIOCSIFMEDIA:
1160 		error = ifmedia_ioctl(ifp, ifr, &sc->sc_mii.mii_media, cmd);
1161 		break;
1162 
1163 	default:
1164 		error = ether_ioctl(ifp, &sc->sc_ac, cmd, data);
1165 	}
1166 
1167 	if (error == ENETRESET) {
1168 		if (ifp->if_flags & IFF_RUNNING)
1169 			udav_iff(sc);
1170 		error = 0;
1171 	}
1172 
1173 	splx(s);
1174 	return (error);
1175 }
1176 
1177 void
udav_watchdog(struct ifnet * ifp)1178 udav_watchdog(struct ifnet *ifp)
1179 {
1180 	struct udav_softc *sc = ifp->if_softc;
1181 	struct udav_chain *c;
1182 	usbd_status stat;
1183 	int s;
1184 
1185 	DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__));
1186 
1187 	ifp->if_oerrors++;
1188 	printf("%s: watchdog timeout\n", sc->sc_dev.dv_xname);
1189 
1190 	s = splusb();
1191 	c = &sc->sc_cdata.udav_tx_chain[0];
1192 	usbd_get_xfer_status(c->udav_xfer, NULL, NULL, NULL, &stat);
1193 	udav_txeof(c->udav_xfer, c, stat);
1194 
1195 	if (ifq_empty(&ifp->if_snd) == 0)
1196 		udav_start(ifp);
1197 	splx(s);
1198 }
1199 
1200 void
udav_stop_task(struct udav_softc * sc)1201 udav_stop_task(struct udav_softc *sc)
1202 {
1203 	udav_stop(GET_IFP(sc), 1);
1204 }
1205 
1206 /* Stop the adapter and free any mbufs allocated to the RX and TX lists. */
1207 void
udav_stop(struct ifnet * ifp,int disable)1208 udav_stop(struct ifnet *ifp, int disable)
1209 {
1210 	struct udav_softc *sc = ifp->if_softc;
1211 	usbd_status err;
1212 	int i;
1213 
1214 	DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__));
1215 
1216 	ifp->if_timer = 0;
1217 	ifp->if_flags &= ~IFF_RUNNING;
1218 	ifq_clr_oactive(&ifp->if_snd);
1219 
1220 	udav_reset(sc);
1221 
1222 	timeout_del(&sc->sc_stat_ch);
1223 
1224 	/* Stop transfers */
1225 	/* RX endpoint */
1226 	if (sc->sc_pipe_rx != NULL) {
1227 		err = usbd_close_pipe(sc->sc_pipe_rx);
1228 		if (err)
1229 			printf("%s: close rx pipe failed: %s\n",
1230 			       sc->sc_dev.dv_xname, usbd_errstr(err));
1231 		sc->sc_pipe_rx = NULL;
1232 	}
1233 
1234 	/* TX endpoint */
1235 	if (sc->sc_pipe_tx != NULL) {
1236 		err = usbd_close_pipe(sc->sc_pipe_tx);
1237 		if (err)
1238 			printf("%s: close tx pipe failed: %s\n",
1239 			       sc->sc_dev.dv_xname, usbd_errstr(err));
1240 		sc->sc_pipe_tx = NULL;
1241 	}
1242 
1243 #if 0
1244 	/* XXX: Interrupt endpoint is not yet supported!! */
1245 	/* Interrupt endpoint */
1246 	if (sc->sc_pipe_intr != NULL) {
1247 		err = usbd_close_pipe(sc->sc_pipe_intr);
1248 		if (err)
1249 			printf("%s: close intr pipe failed: %s\n",
1250 			       sc->sc_dev.dv_xname, usbd_errstr(err));
1251 		sc->sc_pipe_intr = NULL;
1252 	}
1253 #endif
1254 
1255 	/* Free RX resources. */
1256 	for (i = 0; i < UDAV_RX_LIST_CNT; i++) {
1257 		if (sc->sc_cdata.udav_rx_chain[i].udav_mbuf != NULL) {
1258 			m_freem(sc->sc_cdata.udav_rx_chain[i].udav_mbuf);
1259 			sc->sc_cdata.udav_rx_chain[i].udav_mbuf = NULL;
1260 		}
1261 		if (sc->sc_cdata.udav_rx_chain[i].udav_xfer != NULL) {
1262 			usbd_free_xfer(sc->sc_cdata.udav_rx_chain[i].udav_xfer);
1263 			sc->sc_cdata.udav_rx_chain[i].udav_xfer = NULL;
1264 		}
1265 	}
1266 
1267 	/* Free TX resources. */
1268 	for (i = 0; i < UDAV_TX_LIST_CNT; i++) {
1269 		if (sc->sc_cdata.udav_tx_chain[i].udav_mbuf != NULL) {
1270 			m_freem(sc->sc_cdata.udav_tx_chain[i].udav_mbuf);
1271 			sc->sc_cdata.udav_tx_chain[i].udav_mbuf = NULL;
1272 		}
1273 		if (sc->sc_cdata.udav_tx_chain[i].udav_xfer != NULL) {
1274 			usbd_free_xfer(sc->sc_cdata.udav_tx_chain[i].udav_xfer);
1275 			sc->sc_cdata.udav_tx_chain[i].udav_xfer = NULL;
1276 		}
1277 	}
1278 
1279 	sc->sc_link = 0;
1280 }
1281 
1282 /* Set media options */
1283 int
udav_ifmedia_change(struct ifnet * ifp)1284 udav_ifmedia_change(struct ifnet *ifp)
1285 {
1286 	struct udav_softc *sc = ifp->if_softc;
1287 	struct mii_data *mii = GET_MII(sc);
1288 
1289 	DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__));
1290 
1291 	if (usbd_is_dying(sc->sc_udev))
1292 		return (0);
1293 
1294 	sc->sc_link = 0;
1295 
1296 	if (sc->sc_flags & UDAV_RD9700)
1297 		return (0);
1298 
1299 	if (mii->mii_instance) {
1300 		struct mii_softc *miisc;
1301 		LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
1302 			mii_phy_reset(miisc);
1303 	}
1304 
1305 	return (mii_mediachg(mii));
1306 }
1307 
1308 /* Report current media status. */
1309 void
udav_ifmedia_status(struct ifnet * ifp,struct ifmediareq * ifmr)1310 udav_ifmedia_status(struct ifnet *ifp, struct ifmediareq *ifmr)
1311 {
1312 	struct udav_softc *sc = ifp->if_softc;
1313 	struct mii_data *mii = GET_MII(sc);
1314 
1315 	DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__));
1316 
1317 	if (usbd_is_dying(sc->sc_udev))
1318 		return;
1319 
1320 	if ((ifp->if_flags & IFF_RUNNING) == 0) {
1321 		ifmr->ifm_active = IFM_ETHER | IFM_NONE;
1322 		ifmr->ifm_status = 0;
1323 		return;
1324 	}
1325 
1326 	if (sc->sc_flags & UDAV_RD9700) {
1327 		ifmr->ifm_active = IFM_ETHER | IFM_10_T;
1328 		ifmr->ifm_status = IFM_AVALID;
1329 		if (sc->sc_link) ifmr->ifm_status |= IFM_ACTIVE;
1330 		return;
1331 	}
1332 
1333 	mii_pollstat(mii);
1334 	ifmr->ifm_active = mii->mii_media_active;
1335 	ifmr->ifm_status = mii->mii_media_status;
1336 }
1337 
1338 void
udav_tick(void * xsc)1339 udav_tick(void *xsc)
1340 {
1341 	struct udav_softc *sc = xsc;
1342 
1343 	if (sc == NULL)
1344 		return;
1345 
1346 	DPRINTFN(0xff, ("%s: %s: enter\n", sc->sc_dev.dv_xname,
1347 			__func__));
1348 
1349 	/* Perform periodic stuff in process context */
1350 	usb_add_task(sc->sc_udev, &sc->sc_tick_task);
1351 }
1352 
1353 void
udav_tick_task(void * xsc)1354 udav_tick_task(void *xsc)
1355 {
1356 	struct udav_softc *sc = xsc;
1357 	struct ifnet *ifp;
1358 	struct mii_data *mii;
1359 	int s, sts;
1360 
1361 	if (sc == NULL)
1362 		return;
1363 
1364 	DPRINTFN(0xff, ("%s: %s: enter\n", sc->sc_dev.dv_xname,
1365 			__func__));
1366 
1367 	if (usbd_is_dying(sc->sc_udev))
1368 		return;
1369 
1370 	ifp = GET_IFP(sc);
1371 	mii = GET_MII(sc);
1372 
1373 	if (mii == NULL)
1374 		return;
1375 
1376 	s = splnet();
1377 
1378 	if (sc->sc_flags & UDAV_RD9700) {
1379 		sts = udav_csr_read1(sc, UDAV_NSR) & UDAV_NSR_LINKST;
1380 		if (!sts)
1381 			sc->sc_link = 0;
1382 	} else {
1383 		mii_tick(mii);
1384 		sts = (mii->mii_media_status & IFM_ACTIVE &&
1385 		       IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) ? 1 : 0;
1386 	}
1387 
1388 	if (!sc->sc_link && sts) {
1389 		DPRINTF(("%s: %s: got link\n",
1390 			 sc->sc_dev.dv_xname, __func__));
1391 		sc->sc_link++;
1392 		if (ifq_empty(&ifp->if_snd) == 0)
1393 			   udav_start(ifp);
1394 	}
1395 
1396 	timeout_add_sec(&sc->sc_stat_ch, 1);
1397 
1398 	splx(s);
1399 }
1400 
1401 /* Get exclusive access to the MII registers */
1402 void
udav_lock_mii(struct udav_softc * sc)1403 udav_lock_mii(struct udav_softc *sc)
1404 {
1405 	DPRINTFN(0xff, ("%s: %s: enter\n", sc->sc_dev.dv_xname,
1406 			__func__));
1407 
1408 	sc->sc_refcnt++;
1409 	rw_enter_write(&sc->sc_mii_lock);
1410 }
1411 
1412 void
udav_unlock_mii(struct udav_softc * sc)1413 udav_unlock_mii(struct udav_softc *sc)
1414 {
1415 	DPRINTFN(0xff, ("%s: %s: enter\n", sc->sc_dev.dv_xname,
1416 		       __func__));
1417 
1418 	rw_exit_write(&sc->sc_mii_lock);
1419 	if (--sc->sc_refcnt < 0)
1420 		usb_detach_wakeup(&sc->sc_dev);
1421 }
1422 
1423 int
udav_miibus_readreg(struct device * dev,int phy,int reg)1424 udav_miibus_readreg(struct device *dev, int phy, int reg)
1425 {
1426 	struct udav_softc *sc;
1427 	u_int8_t val[2];
1428 	u_int16_t data16;
1429 
1430 	if (dev == NULL)
1431 		return (0);
1432 
1433 	sc = (void *)dev;
1434 
1435 	DPRINTFN(0xff, ("%s: %s: enter, phy=%d reg=0x%04x\n",
1436 		 sc->sc_dev.dv_xname, __func__, phy, reg));
1437 
1438 	if (usbd_is_dying(sc->sc_udev)) {
1439 #ifdef DIAGNOSTIC
1440 		printf("%s: %s: dying\n", sc->sc_dev.dv_xname,
1441 		       __func__);
1442 #endif
1443 		return (0);
1444 	}
1445 
1446 	/* XXX: one PHY only for the internal PHY */
1447 	if (phy != 0) {
1448 		DPRINTFN(0xff, ("%s: %s: phy=%d is not supported\n",
1449 			 sc->sc_dev.dv_xname, __func__, phy));
1450 		return (0);
1451 	}
1452 
1453 	udav_lock_mii(sc);
1454 
1455 	/* select internal PHY and set PHY register address */
1456 	udav_csr_write1(sc, UDAV_EPAR,
1457 			UDAV_EPAR_PHY_ADR0 | (reg & UDAV_EPAR_EROA_MASK));
1458 
1459 	/* select PHY operation and start read command */
1460 	udav_csr_write1(sc, UDAV_EPCR, UDAV_EPCR_EPOS | UDAV_EPCR_ERPRR);
1461 
1462 	/* XXX: should be wait? */
1463 
1464 	/* end read command */
1465 	UDAV_CLRBIT(sc, UDAV_EPCR, UDAV_EPCR_ERPRR);
1466 
1467 	/* retrieve the result from data registers */
1468 	udav_csr_read(sc, UDAV_EPDRL, val, 2);
1469 
1470 	udav_unlock_mii(sc);
1471 
1472 	data16 = val[0] | (val[1] << 8);
1473 
1474 	DPRINTFN(0xff, ("%s: %s: phy=%d reg=0x%04x => 0x%04x\n",
1475 		 sc->sc_dev.dv_xname, __func__, phy, reg, data16));
1476 
1477 	return (data16);
1478 }
1479 
1480 void
udav_miibus_writereg(struct device * dev,int phy,int reg,int data)1481 udav_miibus_writereg(struct device *dev, int phy, int reg, int data)
1482 {
1483 	struct udav_softc *sc;
1484 	u_int8_t val[2];
1485 
1486 	if (dev == NULL)
1487 		return;
1488 
1489 	sc = (void *)dev;
1490 
1491 	DPRINTFN(0xff, ("%s: %s: enter, phy=%d reg=0x%04x data=0x%04x\n",
1492 		 sc->sc_dev.dv_xname, __func__, phy, reg, data));
1493 
1494 	if (usbd_is_dying(sc->sc_udev)) {
1495 #ifdef DIAGNOSTIC
1496 		printf("%s: %s: dying\n", sc->sc_dev.dv_xname,
1497 		       __func__);
1498 #endif
1499 		return;
1500 	}
1501 
1502 	/* XXX: one PHY only for the internal PHY */
1503 	if (phy != 0) {
1504 		DPRINTFN(0xff, ("%s: %s: phy=%d is not supported\n",
1505 			 sc->sc_dev.dv_xname, __func__, phy));
1506 		return;
1507 	}
1508 
1509 	udav_lock_mii(sc);
1510 
1511 	/* select internal PHY and set PHY register address */
1512 	udav_csr_write1(sc, UDAV_EPAR,
1513 			UDAV_EPAR_PHY_ADR0 | (reg & UDAV_EPAR_EROA_MASK));
1514 
1515 	/* put the value to the data registers */
1516 	val[0] = data & 0xff;
1517 	val[1] = (data >> 8) & 0xff;
1518 	udav_csr_write(sc, UDAV_EPDRL, val, 2);
1519 
1520 	/* select PHY operation and start write command */
1521 	udav_csr_write1(sc, UDAV_EPCR, UDAV_EPCR_EPOS | UDAV_EPCR_ERPRW);
1522 
1523 	/* XXX: should be wait? */
1524 
1525 	/* end write command */
1526 	UDAV_CLRBIT(sc, UDAV_EPCR, UDAV_EPCR_ERPRW);
1527 
1528 	udav_unlock_mii(sc);
1529 
1530 	return;
1531 }
1532 
1533 void
udav_miibus_statchg(struct device * dev)1534 udav_miibus_statchg(struct device *dev)
1535 {
1536 #ifdef UDAV_DEBUG
1537 	struct udav_softc *sc;
1538 
1539 	if (dev == NULL)
1540 		return;
1541 
1542 	sc = (void *)dev;
1543 	DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__));
1544 #endif
1545 	/* Nothing to do */
1546 }
1547