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