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