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