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