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