if_url.c revision 1.24.10.2 1 /* $NetBSD: if_url.c,v 1.24.10.2 2007/06/13 04:13:01 itohy Exp $ */
2 /*
3 * Copyright (c) 2001, 2002
4 * Shingo WATANABE <nabe (at) nabechan.org>. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of the author nor the names of any co-contributors
15 * may be used to endorse or promote products derived from this software
16 * without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 *
30 */
31
32 /*
33 * The RTL8150L(Realtek USB to fast ethernet controller) spec can be found at
34 * ftp://ftp.realtek.com.tw/lancard/data_sheet/8150/8150v14.pdf
35 * ftp://152.104.125.40/lancard/data_sheet/8150/8150v14.pdf
36 */
37
38 /*
39 * TODO:
40 * Interrupt Endpoint support
41 * External PHYs
42 * powerhook() support?
43 */
44
45 #include <sys/cdefs.h>
46 __KERNEL_RCSID(0, "$NetBSD: if_url.c,v 1.24.10.2 2007/06/13 04:13:01 itohy Exp $");
47
48 #include "opt_inet.h"
49 #include "bpfilter.h"
50 #include "rnd.h"
51
52 #include <sys/param.h>
53 #include <sys/systm.h>
54 #include <sys/lock.h>
55 #include <sys/mbuf.h>
56 #include <sys/kernel.h>
57 #include <sys/socket.h>
58
59 #include <sys/device.h>
60 #if NRND > 0
61 #include <sys/rnd.h>
62 #endif
63
64 #include <net/if.h>
65 #include <net/if_arp.h>
66 #include <net/if_dl.h>
67 #include <net/if_media.h>
68
69 #if NBPFILTER > 0
70 #include <net/bpf.h>
71 #endif
72 #define BPF_MTAP(ifp, m) bpf_mtap((ifp)->if_bpf, (m))
73
74 #include <net/if_ether.h>
75 #ifdef INET
76 #include <netinet/in.h>
77 #include <netinet/if_inarp.h>
78 #endif
79
80 #include <dev/mii/mii.h>
81 #include <dev/mii/miivar.h>
82 #include <dev/mii/urlphyreg.h>
83
84 #include <dev/usb/usb.h>
85 #include <dev/usb/usbdi.h>
86 #include <dev/usb/usbdi_util.h>
87 #include <dev/usb/usbdevs.h>
88 #include <dev/usb/usb_ethersubr.h>
89
90 #include <dev/usb/if_urlreg.h>
91
92
93 /* Function declarations */
94 USB_DECLARE_DRIVER(url);
95
96 Static int url_openpipes(struct url_softc *);
97 Static void url_start(struct ifnet *);
98 Static int url_send(struct url_softc *, struct mbuf *, int);
99 Static void url_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
100 Static void url_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
101 Static void url_tick(void *);
102 Static void url_tick_task(void *);
103 Static int url_ioctl(struct ifnet *, u_long, caddr_t);
104 Static void url_stop_task(struct url_softc *);
105 Static void url_stop(struct ifnet *, int);
106 Static void url_watchdog(struct ifnet *);
107 Static int url_ifmedia_change(struct ifnet *);
108 Static void url_ifmedia_status(struct ifnet *, struct ifmediareq *);
109 Static void url_lock_mii(struct url_softc *);
110 Static void url_unlock_mii(struct url_softc *);
111 Static int url_int_miibus_readreg(device_ptr_t, int, int);
112 Static void url_int_miibus_writereg(device_ptr_t, int, int, int);
113 Static void url_miibus_statchg(device_ptr_t);
114 Static int url_init(struct ifnet *);
115 Static void url_setmulti(struct url_softc *);
116 Static void url_reset(struct url_softc *);
117
118 Static int url_csr_read_1(struct url_softc *, int);
119 Static int url_csr_read_2(struct url_softc *, int);
120 Static int url_csr_write_1(struct url_softc *, int, int);
121 Static int url_csr_write_2(struct url_softc *, int, int);
122 Static int url_csr_write_4(struct url_softc *, int, int);
123 Static int url_mem(struct url_softc *, int, int, void *, int);
124
125 /* Macros */
126 #ifdef URL_DEBUG
127 #define DPRINTF(x) if (urldebug) logprintf x
128 #define DPRINTFN(n,x) if (urldebug >= (n)) logprintf x
129 int urldebug = 0;
130 #else
131 #define DPRINTF(x)
132 #define DPRINTFN(n,x)
133 #endif
134
135 #define URL_SETBIT(sc, reg, x) \
136 url_csr_write_1(sc, reg, url_csr_read_1(sc, reg) | (x))
137
138 #define URL_SETBIT2(sc, reg, x) \
139 url_csr_write_2(sc, reg, url_csr_read_2(sc, reg) | (x))
140
141 #define URL_CLRBIT(sc, reg, x) \
142 url_csr_write_1(sc, reg, url_csr_read_1(sc, reg) & ~(x))
143
144 #define URL_CLRBIT2(sc, reg, x) \
145 url_csr_write_2(sc, reg, url_csr_read_2(sc, reg) & ~(x))
146
147 static const struct url_type {
148 struct usb_devno url_dev;
149 u_int16_t url_flags;
150 #define URL_EXT_PHY 0x0001
151 } url_devs [] = {
152 /* MELCO LUA-KTX */
153 {{ USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUAKTX }, 0},
154 /* Realtek RTL8150L Generic (GREEN HOUSE USBKR100) */
155 {{ USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8150L}, 0},
156 /* Longshine LCS-8138TX */
157 {{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_LCS8138TX}, 0},
158 /* Micronet SP128AR */
159 {{ USB_VENDOR_MICRONET, USB_PRODUCT_MICRONET_SP128AR}, 0},
160 /* OQO model 01 */
161 {{ USB_VENDOR_OQO, USB_PRODUCT_OQO_ETHER01}, 0},
162 };
163 #define url_lookup(v, p) ((const struct url_type *)usb_lookup(url_devs, v, p))
164
165 char zeros[URL_MIN_FRAME_LEN]; /* XXX */
166
167 /* Probe */
168 USB_MATCH(url)
169 {
170 USB_MATCH_START(url, uaa);
171
172 if (uaa->iface != NULL)
173 return (UMATCH_NONE);
174
175 return (url_lookup(uaa->vendor, uaa->product) != NULL ?
176 UMATCH_VENDOR_PRODUCT : UMATCH_NONE);
177 }
178 /* Attach */
179 USB_ATTACH(url)
180 {
181 USB_ATTACH_START(url, sc, uaa);
182 usbd_device_handle dev = uaa->device;
183 usbd_interface_handle iface;
184 usbd_status err;
185 usb_interface_descriptor_t *id;
186 usb_endpoint_descriptor_t *ed;
187 char *devinfop;
188 char *devname = USBDEVNAME(sc->sc_dev);
189 struct ifnet *ifp;
190 struct mii_data *mii;
191 u_char eaddr[ETHER_ADDR_LEN];
192 int i, s;
193
194 devinfop = usbd_devinfo_alloc(dev, 0);
195 USB_ATTACH_SETUP;
196 printf("%s: %s\n", devname, devinfop);
197 usbd_devinfo_free(devinfop);
198
199 /* Move the device into the configured state. */
200 err = usbd_set_config_no(dev, URL_CONFIG_NO, 1);
201 if (err) {
202 printf("%s: setting config no failed\n", devname);
203 goto bad;
204 }
205
206 usb_init_task(&sc->sc_tick_task, url_tick_task, sc);
207 lockinit(&sc->sc_mii_lock, PZERO, "urlmii", 0, 0);
208 usb_init_task(&sc->sc_stop_task, (void (*)(void *)) url_stop_task, sc);
209
210 /* get control interface */
211 err = usbd_device2interface_handle(dev, URL_IFACE_INDEX, &iface);
212 if (err) {
213 printf("%s: failed to get interface, err=%s\n", devname,
214 usbd_errstr(err));
215 goto bad;
216 }
217
218 sc->sc_udev = dev;
219 sc->sc_ctl_iface = iface;
220 sc->sc_flags = url_lookup(uaa->vendor, uaa->product)->url_flags;
221
222 /* get interface descriptor */
223 id = usbd_get_interface_descriptor(sc->sc_ctl_iface);
224
225 /* find endpoints */
226 sc->sc_bulkin_no = sc->sc_bulkout_no = sc->sc_intrin_no = -1;
227 for (i = 0; i < id->bNumEndpoints; i++) {
228 ed = usbd_interface2endpoint_descriptor(sc->sc_ctl_iface, i);
229 if (ed == NULL) {
230 printf("%s: couldn't get endpoint %d\n", devname, i);
231 goto bad;
232 }
233 if ((ed->bmAttributes & UE_XFERTYPE) == UE_BULK &&
234 UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN)
235 sc->sc_bulkin_no = ed->bEndpointAddress; /* RX */
236 else if ((ed->bmAttributes & UE_XFERTYPE) == UE_BULK &&
237 UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT)
238 sc->sc_bulkout_no = ed->bEndpointAddress; /* TX */
239 else if ((ed->bmAttributes & UE_XFERTYPE) == UE_INTERRUPT &&
240 UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN)
241 sc->sc_intrin_no = ed->bEndpointAddress; /* Status */
242 }
243
244 if (sc->sc_bulkin_no == -1 || sc->sc_bulkout_no == -1 ||
245 sc->sc_intrin_no == -1) {
246 printf("%s: missing endpoint\n", devname);
247 goto bad;
248 }
249
250 s = splnet();
251
252 /* reset the adapter */
253 url_reset(sc);
254
255 /* Get Ethernet Address */
256 err = url_mem(sc, URL_CMD_READMEM, URL_IDR0, (void *)eaddr,
257 ETHER_ADDR_LEN);
258 if (err) {
259 printf("%s: read MAC address failed\n", devname);
260 splx(s);
261 goto bad;
262 }
263
264 /* Print Ethernet Address */
265 printf("%s: Ethernet address %s\n", devname, ether_sprintf(eaddr));
266
267 /* initialize interface information */
268 ifp = GET_IFP(sc);
269 ifp->if_softc = sc;
270 ifp->if_mtu = ETHERMTU;
271 strncpy(ifp->if_xname, devname, IFNAMSIZ);
272 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
273 ifp->if_start = url_start;
274 ifp->if_ioctl = url_ioctl;
275 ifp->if_watchdog = url_watchdog;
276 ifp->if_init = url_init;
277 ifp->if_stop = url_stop;
278
279 IFQ_SET_READY(&ifp->if_snd);
280
281 /*
282 * Do ifmedia setup.
283 */
284 mii = &sc->sc_mii;
285 mii->mii_ifp = ifp;
286 mii->mii_readreg = url_int_miibus_readreg;
287 mii->mii_writereg = url_int_miibus_writereg;
288 #if 0
289 if (sc->sc_flags & URL_EXT_PHY) {
290 mii->mii_readreg = url_ext_miibus_readreg;
291 mii->mii_writereg = url_ext_miibus_writereg;
292 }
293 #endif
294 mii->mii_statchg = url_miibus_statchg;
295 mii->mii_flags = MIIF_AUTOTSLEEP;
296 ifmedia_init(&mii->mii_media, 0,
297 url_ifmedia_change, url_ifmedia_status);
298 mii_attach(self, mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, 0);
299 if (LIST_FIRST(&mii->mii_phys) == NULL) {
300 ifmedia_add(&mii->mii_media, IFM_ETHER | IFM_NONE, 0, NULL);
301 ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_NONE);
302 } else
303 ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_AUTO);
304
305 /* attach the interface */
306 if_attach(ifp);
307 Ether_ifattach(ifp, eaddr);
308
309 #if NRND > 0
310 rnd_attach_source(&sc->rnd_source, devname, RND_TYPE_NET, 0);
311 #endif
312
313 usb_callout_init(sc->sc_stat_ch);
314 sc->sc_attached = 1;
315 splx(s);
316
317 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, dev, USBDEV(sc->sc_dev));
318
319 USB_ATTACH_SUCCESS_RETURN;
320
321 bad:
322 sc->sc_dying = 1;
323 USB_ATTACH_ERROR_RETURN;
324 }
325
326 /* detach */
327 USB_DETACH(url)
328 {
329 USB_DETACH_START(url, sc);
330 struct ifnet *ifp = GET_IFP(sc);
331 int s;
332
333 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
334
335 /* Detached before attached finished */
336 if (!sc->sc_attached)
337 return (0);
338
339 usb_uncallout(sc->sc_stat_ch, url_tick, sc);
340
341 /* Remove any pending tasks */
342 usb_rem_task(sc->sc_udev, &sc->sc_tick_task);
343 usb_rem_task(sc->sc_udev, &sc->sc_stop_task);
344
345 s = splusb();
346
347 if (--sc->sc_refcnt >= 0) {
348 /* Wait for processes to go away */
349 usb_detach_wait(USBDEV(sc->sc_dev));
350 }
351
352 if (ifp->if_flags & IFF_RUNNING)
353 url_stop(ifp, 1);
354
355 #if NRND > 0
356 rnd_detach_source(&sc->rnd_source);
357 #endif
358 mii_detach(&sc->sc_mii, MII_PHY_ANY, MII_OFFSET_ANY);
359 ifmedia_delete_instance(&sc->sc_mii.mii_media, IFM_INST_ANY);
360 ether_ifdetach(ifp);
361 if_detach(ifp);
362
363 #ifdef DIAGNOSTIC
364 if (sc->sc_pipe_tx != NULL)
365 printf("%s: detach has active tx endpoint.\n",
366 USBDEVNAME(sc->sc_dev));
367 if (sc->sc_pipe_rx != NULL)
368 printf("%s: detach has active rx endpoint.\n",
369 USBDEVNAME(sc->sc_dev));
370 if (sc->sc_pipe_intr != NULL)
371 printf("%s: detach has active intr endpoint.\n",
372 USBDEVNAME(sc->sc_dev));
373 #endif
374
375 sc->sc_attached = 0;
376
377 splx(s);
378
379 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
380 USBDEV(sc->sc_dev));
381
382 return (0);
383 }
384
385 /* read/write memory */
386 Static int
387 url_mem(struct url_softc *sc, int cmd, int offset, void *buf, int len)
388 {
389 usb_device_request_t req;
390 usbd_status err;
391
392 if (sc == NULL)
393 return (0);
394
395 DPRINTFN(0x200,
396 ("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
397
398 if (sc->sc_dying)
399 return (0);
400
401 if (cmd == URL_CMD_READMEM)
402 req.bmRequestType = UT_READ_VENDOR_DEVICE;
403 else
404 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
405 req.bRequest = URL_REQ_MEM;
406 USETW(req.wValue, offset);
407 USETW(req.wIndex, 0x0000);
408 USETW(req.wLength, len);
409
410 sc->sc_refcnt++;
411 err = usbd_do_request(sc->sc_udev, &req, buf);
412 if (--sc->sc_refcnt < 0)
413 usb_detach_wakeup(USBDEV(sc->sc_dev));
414 if (err) {
415 DPRINTF(("%s: url_mem(): %s failed. off=%04x, err=%d\n",
416 USBDEVNAME(sc->sc_dev),
417 cmd == URL_CMD_READMEM ? "read" : "write",
418 offset, err));
419 }
420
421 return (err);
422 }
423
424 /* read 1byte from register */
425 Static int
426 url_csr_read_1(struct url_softc *sc, int reg)
427 {
428 u_int8_t val = 0;
429
430 DPRINTFN(0x100,
431 ("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
432
433 if (sc->sc_dying)
434 return (0);
435
436 return (url_mem(sc, URL_CMD_READMEM, reg, &val, 1) ? 0 : val);
437 }
438
439 /* read 2bytes from register */
440 Static int
441 url_csr_read_2(struct url_softc *sc, int reg)
442 {
443 uWord val;
444
445 DPRINTFN(0x100,
446 ("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
447
448 if (sc->sc_dying)
449 return (0);
450
451 USETW(val, 0);
452 return (url_mem(sc, URL_CMD_READMEM, reg, &val, 2) ? 0 : UGETW(val));
453 }
454
455 /* write 1byte to register */
456 Static int
457 url_csr_write_1(struct url_softc *sc, int reg, int aval)
458 {
459 u_int8_t val = aval;
460
461 DPRINTFN(0x100,
462 ("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
463
464 if (sc->sc_dying)
465 return (0);
466
467 return (url_mem(sc, URL_CMD_WRITEMEM, reg, &val, 1) ? -1 : 0);
468 }
469
470 /* write 2bytes to register */
471 Static int
472 url_csr_write_2(struct url_softc *sc, int reg, int aval)
473 {
474 uWord val;
475
476 DPRINTFN(0x100,
477 ("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
478
479 USETW(val, aval);
480
481 if (sc->sc_dying)
482 return (0);
483
484 return (url_mem(sc, URL_CMD_WRITEMEM, reg, &val, 2) ? -1 : 0);
485 }
486
487 /* write 4bytes to register */
488 Static int
489 url_csr_write_4(struct url_softc *sc, int reg, int aval)
490 {
491 uDWord val;
492
493 DPRINTFN(0x100,
494 ("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
495
496 USETDW(val, aval);
497
498 if (sc->sc_dying)
499 return (0);
500
501 return (url_mem(sc, URL_CMD_WRITEMEM, reg, &val, 4) ? -1 : 0);
502 }
503
504 Static int
505 url_init(struct ifnet *ifp)
506 {
507 struct url_softc *sc = ifp->if_softc;
508 struct mii_data *mii = GET_MII(sc);
509 u_char *eaddr;
510 int i, s;
511 struct ue_chain *c;
512
513 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
514
515 if (sc->sc_dying)
516 return (EIO);
517
518 s = splnet();
519
520 /* Cancel pending I/O and free all TX/RX buffers */
521 url_stop(ifp, 1);
522
523 eaddr = LLADDR(ifp->if_sadl);
524 for (i = 0; i < ETHER_ADDR_LEN; i++)
525 url_csr_write_1(sc, URL_IDR0 + i, eaddr[i]);
526
527 /* Init transmission control register */
528 URL_CLRBIT(sc, URL_TCR,
529 URL_TCR_TXRR1 | URL_TCR_TXRR0 |
530 URL_TCR_IFG1 | URL_TCR_IFG0 |
531 URL_TCR_NOCRC);
532
533 /* Init receive control register */
534 URL_SETBIT2(sc, URL_RCR, URL_RCR_TAIL | URL_RCR_AD);
535 if (ifp->if_flags & IFF_BROADCAST)
536 URL_SETBIT2(sc, URL_RCR, URL_RCR_AB);
537 else
538 URL_CLRBIT2(sc, URL_RCR, URL_RCR_AB);
539
540 /* If we want promiscuous mode, accept all physical frames. */
541 if (ifp->if_flags & IFF_PROMISC)
542 URL_SETBIT2(sc, URL_RCR, URL_RCR_AAM|URL_RCR_AAP);
543 else
544 URL_CLRBIT2(sc, URL_RCR, URL_RCR_AAM|URL_RCR_AAP);
545
546 if (sc->sc_pipe_tx == NULL || sc->sc_pipe_rx == NULL) {
547 if (url_openpipes(sc)) {
548 splx(s);
549 return (EIO);
550 }
551 }
552
553 /* Initialize transmit ring */
554 if (usb_ether_tx_list_init(USBDEV(sc->sc_dev),
555 sc->sc_cdata.url_tx_chain, URL_TX_LIST_CNT,
556 sc->sc_udev, sc->sc_pipe_tx, NULL)) {
557 printf("%s: tx list init failed\n", USBDEVNAME(sc->sc_dev));
558 splx(s);
559 return (EIO);
560 }
561
562 /* Initialize receive ring */
563 if (usb_ether_rx_list_init(USBDEV(sc->sc_dev),
564 sc->sc_cdata.url_rx_chain, URL_RX_LIST_CNT,
565 sc->sc_udev, sc->sc_pipe_rx)) {
566 printf("%s: rx list init failed\n", USBDEVNAME(sc->sc_dev));
567 splx(s);
568 return (EIO);
569 }
570
571 /* Load the multicast filter */
572 url_setmulti(sc);
573
574 /* Enable RX and TX */
575 URL_SETBIT(sc, URL_CR, URL_CR_TE | URL_CR_RE);
576
577 mii_mediachg(mii);
578
579 /* Start up the receive pipe. */
580 for (i = 0; i < URL_RX_LIST_CNT; i++) {
581 c = &sc->sc_cdata.url_rx_chain[i];
582 (void)usbd_map_buffer_mbuf(c->ue_xfer, c->ue_mbuf);
583 usbd_setup_xfer(c->ue_xfer, sc->sc_pipe_rx,
584 c, NULL /* XXX buf */, URL_BUFSZ,
585 USBD_SHORT_XFER_OK | USBD_NO_COPY,
586 USBD_NO_TIMEOUT, url_rxeof);
587 (void)usbd_transfer(c->ue_xfer);
588 DPRINTF(("%s: %s: start read\n", USBDEVNAME(sc->sc_dev),
589 __func__));
590 }
591
592 ifp->if_flags |= IFF_RUNNING;
593 ifp->if_flags &= ~IFF_OACTIVE;
594
595 splx(s);
596
597 usb_callout(sc->sc_stat_ch, hz, url_tick, sc);
598
599 return (0);
600 }
601
602 Static void
603 url_reset(struct url_softc *sc)
604 {
605 int i;
606
607 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
608
609 if (sc->sc_dying)
610 return;
611
612 URL_SETBIT(sc, URL_CR, URL_CR_SOFT_RST);
613
614 for (i = 0; i < URL_TX_TIMEOUT; i++) {
615 if (!(url_csr_read_1(sc, URL_CR) & URL_CR_SOFT_RST))
616 break;
617 delay(10); /* XXX */
618 }
619
620 delay(10000); /* XXX */
621 }
622
623 int
624 url_activate(device_ptr_t self, enum devact act)
625 {
626 struct url_softc *sc = (struct url_softc *)self;
627
628 DPRINTF(("%s: %s: enter, act=%d\n", USBDEVNAME(sc->sc_dev),
629 __func__, act));
630
631 switch (act) {
632 case DVACT_ACTIVATE:
633 return (EOPNOTSUPP);
634 break;
635
636 case DVACT_DEACTIVATE:
637 if_deactivate(&sc->sc_ec.ec_if);
638 sc->sc_dying = 1;
639 break;
640 }
641
642 return (0);
643 }
644
645 #define url_calchash(addr) (ether_crc32_be((addr), ETHER_ADDR_LEN) >> 26)
646
647
648 Static void
649 url_setmulti(struct url_softc *sc)
650 {
651 struct ifnet *ifp;
652 struct ether_multi *enm;
653 struct ether_multistep step;
654 u_int32_t hashes[2] = { 0, 0 };
655 int h = 0;
656 int mcnt = 0;
657
658 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
659
660 if (sc->sc_dying)
661 return;
662
663 ifp = GET_IFP(sc);
664
665 if (ifp->if_flags & IFF_PROMISC) {
666 URL_SETBIT2(sc, URL_RCR, URL_RCR_AAM|URL_RCR_AAP);
667 return;
668 } else if (ifp->if_flags & IFF_ALLMULTI) {
669 allmulti:
670 ifp->if_flags |= IFF_ALLMULTI;
671 URL_SETBIT2(sc, URL_RCR, URL_RCR_AAM);
672 URL_CLRBIT2(sc, URL_RCR, URL_RCR_AAP);
673 return;
674 }
675
676 /* first, zot all the existing hash bits */
677 url_csr_write_4(sc, URL_MAR0, 0);
678 url_csr_write_4(sc, URL_MAR4, 0);
679
680 /* now program new ones */
681 ETHER_FIRST_MULTI(step, &sc->sc_ec, enm);
682 while (enm != NULL) {
683 if (memcmp(enm->enm_addrlo, enm->enm_addrhi,
684 ETHER_ADDR_LEN) != 0)
685 goto allmulti;
686
687 h = url_calchash(enm->enm_addrlo);
688 if (h < 32)
689 hashes[0] |= (1 << h);
690 else
691 hashes[1] |= (1 << (h -32));
692 mcnt++;
693 ETHER_NEXT_MULTI(step, enm);
694 }
695
696 ifp->if_flags &= ~IFF_ALLMULTI;
697
698 URL_CLRBIT2(sc, URL_RCR, URL_RCR_AAM|URL_RCR_AAP);
699
700 if (mcnt){
701 URL_SETBIT2(sc, URL_RCR, URL_RCR_AM);
702 } else {
703 URL_CLRBIT2(sc, URL_RCR, URL_RCR_AM);
704 }
705 url_csr_write_4(sc, URL_MAR0, hashes[0]);
706 url_csr_write_4(sc, URL_MAR4, hashes[1]);
707 }
708
709 Static int
710 url_openpipes(struct url_softc *sc)
711 {
712 usbd_status err;
713 int error = 0;
714
715 if (sc->sc_dying)
716 return (EIO);
717
718 sc->sc_refcnt++;
719
720 /* Open RX pipe */
721 err = usbd_open_pipe(sc->sc_ctl_iface, sc->sc_bulkin_no,
722 USBD_EXCLUSIVE_USE, &sc->sc_pipe_rx);
723 if (err) {
724 printf("%s: open rx pipe failed: %s\n",
725 USBDEVNAME(sc->sc_dev), usbd_errstr(err));
726 error = EIO;
727 goto done;
728 }
729
730 /* Open TX pipe */
731 err = usbd_open_pipe(sc->sc_ctl_iface, sc->sc_bulkout_no,
732 USBD_EXCLUSIVE_USE, &sc->sc_pipe_tx);
733 if (err) {
734 printf("%s: open tx pipe failed: %s\n",
735 USBDEVNAME(sc->sc_dev), usbd_errstr(err));
736 error = EIO;
737 goto done;
738 }
739
740 #if 0
741 /* XXX: interrupt endpoint is not yet supported */
742 /* Open Interrupt pipe */
743 err = usbd_open_pipe_intr(sc->sc_ctl_iface, sc->sc_intrin_no,
744 USBD_EXCLUSIVE_USE, &sc->sc_pipe_intr, sc,
745 &sc->sc_cdata.url_ibuf, URL_INTR_PKGLEN,
746 url_intr, USBD_DEFAULT_INTERVAL);
747 if (err) {
748 printf("%s: open intr pipe failed: %s\n",
749 USBDEVNAME(sc->sc_dev), usbd_errstr(err));
750 error = EIO;
751 goto done;
752 }
753 #endif
754
755 done:
756 if (--sc->sc_refcnt < 0)
757 usb_detach_wakeup(USBDEV(sc->sc_dev));
758
759 return (error);
760 }
761
762 Static void
763 url_start(struct ifnet *ifp)
764 {
765 struct url_softc *sc = ifp->if_softc;
766 struct mbuf *m_head = NULL;
767
768 DPRINTF(("%s: %s: enter, link=%d\n", USBDEVNAME(sc->sc_dev),
769 __func__, sc->sc_link));
770
771 if (sc->sc_dying)
772 return;
773
774 if (!sc->sc_link)
775 return;
776
777 if (ifp->if_flags & IFF_OACTIVE)
778 return;
779
780 IFQ_POLL(&ifp->if_snd, m_head);
781 if (m_head == NULL)
782 return;
783
784 IFQ_DEQUEUE(&ifp->if_snd, m_head);
785
786 #if NBPFILTER > 0
787 if (ifp->if_bpf)
788 bpf_mtap(ifp->if_bpf, m_head);
789 #endif
790
791 if (url_send(sc, m_head, 0)) {
792 ifp->if_flags |= IFF_OACTIVE;
793 return;
794 }
795
796 ifp->if_flags |= IFF_OACTIVE;
797
798 /* Set a timeout in case the chip goes out to lunch. */
799 ifp->if_timer = 5;
800 }
801
802 Static int
803 url_send(struct url_softc *sc, struct mbuf *m, int idx)
804 {
805 int total_len;
806 struct ue_chain *c;
807 usbd_status err;
808 int ret;
809
810 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev),__func__));
811
812 c = &sc->sc_cdata.url_tx_chain[idx];
813
814 total_len = m->m_pkthdr.len;
815
816 if (total_len < URL_MIN_FRAME_LEN) {
817 /* expand mbuf chain with zeros */
818 m_copyback(m, total_len, URL_MIN_FRAME_LEN - total_len,
819 zeros);
820 total_len = URL_MIN_FRAME_LEN;
821 if (m->m_pkthdr.len != total_len) {
822 m_freem(m);
823 return (ENOBUFS);
824 }
825 }
826
827 ret = usb_ether_map_tx_buffer_mbuf(c, m);
828 if (ret) {
829 m_freem(m);
830 return (ret);
831 }
832
833 usbd_setup_xfer(c->ue_xfer, sc->sc_pipe_tx, c, NULL /* XXX buf */, total_len,
834 USBD_FORCE_SHORT_XFER | USBD_NO_COPY,
835 URL_TX_TIMEOUT, url_txeof);
836
837 /* Transmit */
838 sc->sc_refcnt++;
839 err = usbd_transfer(c->ue_xfer);
840 if (--sc->sc_refcnt < 0)
841 usb_detach_wakeup(USBDEV(sc->sc_dev));
842 if (err != USBD_IN_PROGRESS) {
843 c->ue_mbuf = NULL;
844 m_freem(m);
845 printf("%s: url_send error=%s\n", USBDEVNAME(sc->sc_dev),
846 usbd_errstr(err));
847 /* Stop the interface */
848 usb_add_task(sc->sc_udev, &sc->sc_stop_task,
849 USB_TASKQ_DRIVER);
850 return (EIO);
851 }
852
853 DPRINTF(("%s: %s: send %d bytes\n", USBDEVNAME(sc->sc_dev),
854 __func__, total_len));
855
856 sc->sc_cdata.url_tx_cnt++;
857
858 return (0);
859 }
860
861 Static void
862 url_txeof(usbd_xfer_handle xfer, usbd_private_handle priv,
863 usbd_status status)
864 {
865 struct ue_chain *c = priv;
866 struct url_softc *sc = (void *)c->ue_dev;
867 struct ifnet *ifp = GET_IFP(sc);
868 int s;
869
870 if (sc->sc_dying)
871 return;
872
873 s = splnet();
874
875 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
876
877 ifp->if_timer = 0;
878 ifp->if_flags &= ~IFF_OACTIVE;
879
880 usbd_unmap_buffer(xfer);
881
882 if (status != USBD_NORMAL_COMPLETION) {
883 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
884 splx(s);
885 return;
886 }
887 ifp->if_oerrors++;
888 printf("%s: usb error on tx: %s\n", USBDEVNAME(sc->sc_dev),
889 usbd_errstr(status));
890 if (status == USBD_STALLED) {
891 sc->sc_refcnt++;
892 usbd_clear_endpoint_stall_async(sc->sc_pipe_tx);
893 if (--sc->sc_refcnt < 0)
894 usb_detach_wakeup(USBDEV(sc->sc_dev));
895 }
896 splx(s);
897 return;
898 }
899
900 ifp->if_opackets++;
901
902 m_freem(c->ue_mbuf);
903 c->ue_mbuf = NULL;
904
905 if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
906 url_start(ifp);
907
908 splx(s);
909 }
910
911 Static void
912 url_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
913 {
914 struct ue_chain *c = priv;
915 struct url_softc *sc = (void *)c->ue_dev;
916 struct ifnet *ifp = GET_IFP(sc);
917 struct mbuf *m;
918 u_int32_t total_len;
919 url_rxhdr_t rxhdr;
920 int s;
921
922 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev),__func__));
923
924 if (sc->sc_dying)
925 return;
926
927 usbd_unmap_buffer(xfer);
928
929 if (status != USBD_NORMAL_COMPLETION) {
930 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
931 return;
932 sc->sc_rx_errs++;
933 if (usbd_ratecheck(&sc->sc_rx_notice)) {
934 printf("%s: %u usb errors on rx: %s\n",
935 USBDEVNAME(sc->sc_dev), sc->sc_rx_errs,
936 usbd_errstr(status));
937 sc->sc_rx_errs = 0;
938 }
939 if (status == USBD_STALLED) {
940 sc->sc_refcnt++;
941 usbd_clear_endpoint_stall_async(sc->sc_pipe_rx);
942 if (--sc->sc_refcnt < 0)
943 usb_detach_wakeup(USBDEV(sc->sc_dev));
944 }
945 goto done;
946 }
947
948 usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
949
950 if (total_len <= ETHER_CRC_LEN) {
951 ifp->if_ierrors++;
952 goto done;
953 }
954
955 m = c->ue_mbuf;
956
957 memcpy(&rxhdr, mtod(m, char *) + total_len - ETHER_CRC_LEN,
958 sizeof(rxhdr));
959
960 DPRINTF(("%s: RX Status: %dbytes%s%s%s%s packets\n",
961 USBDEVNAME(sc->sc_dev),
962 UGETW(rxhdr) & URL_RXHDR_BYTEC_MASK,
963 UGETW(rxhdr) & URL_RXHDR_VALID_MASK ? ", Valid" : "",
964 UGETW(rxhdr) & URL_RXHDR_RUNTPKT_MASK ? ", Runt" : "",
965 UGETW(rxhdr) & URL_RXHDR_PHYPKT_MASK ? ", Physical match" : "",
966 UGETW(rxhdr) & URL_RXHDR_MCASTPKT_MASK ? ", Multicast" : ""));
967
968 if ((UGETW(rxhdr) & URL_RXHDR_VALID_MASK) == 0) {
969 ifp->if_ierrors++;
970 goto done;
971 }
972
973 /*
974 * Allocate new mbuf cluster for the next transfer.
975 * If that failed, discard current packet and recycle the mbuf.
976 */
977 if ((c->ue_mbuf = usb_ether_newbuf(NULL)) == NULL) {
978 printf("%s: no memory for rx list -- packet dropped!\n",
979 USBDEVNAME(sc->sc_dev));
980 ifp->if_ierrors++;
981 c->ue_mbuf = usb_ether_newbuf(m);
982 goto done;
983 }
984
985 ifp->if_ipackets++;
986 total_len -= ETHER_CRC_LEN;
987
988 m->m_pkthdr.len = m->m_len = total_len;
989 m->m_pkthdr.rcvif = ifp;
990
991 s = splnet();
992
993 #if NBPFILTER > 0
994 if (ifp->if_bpf)
995 BPF_MTAP(ifp, m);
996 #endif
997
998 DPRINTF(("%s: %s: deliver %d\n", USBDEVNAME(sc->sc_dev),
999 __func__, m->m_len));
1000 IF_INPUT(ifp, m);
1001
1002 splx(s);
1003
1004 done:
1005 /* Setup new transfer */
1006 (void)usbd_map_buffer_mbuf(xfer, c->ue_mbuf);
1007 usbd_setup_xfer(xfer, sc->sc_pipe_rx, c, NULL /* XXX buf */, URL_BUFSZ,
1008 USBD_SHORT_XFER_OK | USBD_NO_COPY,
1009 USBD_NO_TIMEOUT, url_rxeof);
1010 sc->sc_refcnt++;
1011 usbd_transfer(xfer);
1012 if (--sc->sc_refcnt < 0)
1013 usb_detach_wakeup(USBDEV(sc->sc_dev));
1014
1015 DPRINTF(("%s: %s: start rx\n", USBDEVNAME(sc->sc_dev), __func__));
1016 }
1017
1018 #if 0
1019 Static void url_intr()
1020 {
1021 }
1022 #endif
1023
1024 Static int
1025 url_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
1026 {
1027 struct url_softc *sc = ifp->if_softc;
1028 struct ifreq *ifr = (struct ifreq *)data;
1029 struct mii_data *mii;
1030 int s, error = 0;
1031
1032 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
1033
1034 if (sc->sc_dying)
1035 return (EIO);
1036
1037 s = splnet();
1038
1039 switch (cmd) {
1040 case SIOCGIFMEDIA:
1041 case SIOCSIFMEDIA:
1042 mii = GET_MII(sc);
1043 error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, cmd);
1044 break;
1045
1046 default:
1047 error = ether_ioctl(ifp, cmd, data);
1048 if (error == ENETRESET) {
1049 if (ifp->if_flags & IFF_RUNNING)
1050 url_setmulti(sc);
1051 error = 0;
1052 }
1053 break;
1054 }
1055
1056 splx(s);
1057
1058 return (error);
1059 }
1060
1061 Static void
1062 url_watchdog(struct ifnet *ifp)
1063 {
1064 struct url_softc *sc = ifp->if_softc;
1065 struct ue_chain *c;
1066 usbd_status stat;
1067 int s;
1068
1069 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
1070
1071 ifp->if_oerrors++;
1072 printf("%s: watchdog timeout\n", USBDEVNAME(sc->sc_dev));
1073
1074 s = splusb();
1075 c = &sc->sc_cdata.url_tx_chain[0];
1076 usbd_get_xfer_status(c->ue_xfer, NULL, NULL, NULL, &stat);
1077 url_txeof(c->ue_xfer, c, stat);
1078
1079 if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
1080 url_start(ifp);
1081 splx(s);
1082 }
1083
1084 Static void
1085 url_stop_task(struct url_softc *sc)
1086 {
1087 url_stop(GET_IFP(sc), 1);
1088 }
1089
1090 /* Stop the adapter and free any mbufs allocated to the RX and TX lists. */
1091 Static void
1092 url_stop(struct ifnet *ifp, int disable)
1093 {
1094 struct url_softc *sc = ifp->if_softc;
1095 usbd_status err;
1096
1097 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
1098
1099 ifp->if_timer = 0;
1100
1101 url_reset(sc);
1102
1103 usb_uncallout(sc->sc_stat_ch, url_tick, sc);
1104
1105 /* Stop transfers */
1106 /* RX endpoint */
1107 if (sc->sc_pipe_rx != NULL) {
1108 err = usbd_abort_pipe(sc->sc_pipe_rx);
1109 if (err)
1110 printf("%s: abort rx pipe failed: %s\n",
1111 USBDEVNAME(sc->sc_dev), usbd_errstr(err));
1112 }
1113
1114 /* TX endpoint */
1115 if (sc->sc_pipe_tx != NULL) {
1116 err = usbd_abort_pipe(sc->sc_pipe_tx);
1117 if (err)
1118 printf("%s: abort tx pipe failed: %s\n",
1119 USBDEVNAME(sc->sc_dev), usbd_errstr(err));
1120 }
1121
1122 #if 0
1123 /* XXX: Interrupt endpoint is not yet supported!! */
1124 /* Interrupt endpoint */
1125 if (sc->sc_pipe_intr != NULL) {
1126 err = usbd_abort_pipe(sc->sc_pipe_intr);
1127 if (err)
1128 printf("%s: abort intr pipe failed: %s\n",
1129 USBDEVNAME(sc->sc_dev), usbd_errstr(err));
1130 #endif
1131
1132 /* Free RX/TX resources. */
1133 usb_ether_rx_list_free(sc->sc_cdata.url_rx_chain, URL_RX_LIST_CNT);
1134 usb_ether_tx_list_free(sc->sc_cdata.url_tx_chain, URL_TX_LIST_CNT);
1135
1136 /* Close pipes. */
1137 /* RX endpoint */
1138 if (sc->sc_pipe_rx != NULL) {
1139 err = usbd_close_pipe(sc->sc_pipe_rx);
1140 if (err)
1141 printf("%s: close rx pipe failed: %s\n",
1142 USBDEVNAME(sc->sc_dev), usbd_errstr(err));
1143 sc->sc_pipe_rx = NULL;
1144 }
1145
1146 /* TX endpoint */
1147 if (sc->sc_pipe_tx != NULL) {
1148 err = usbd_close_pipe(sc->sc_pipe_tx);
1149 if (err)
1150 printf("%s: close tx pipe failed: %s\n",
1151 USBDEVNAME(sc->sc_dev), usbd_errstr(err));
1152 sc->sc_pipe_tx = NULL;
1153 }
1154
1155 #if 0
1156 /* XXX: Interrupt endpoint is not yet supported!! */
1157 /* Interrupt endpoint */
1158 if (sc->sc_pipe_intr != NULL) {
1159 err = usbd_close_pipe(sc->sc_pipe_intr);
1160 if (err)
1161 printf("%s: close intr pipe failed: %s\n",
1162 USBDEVNAME(sc->sc_dev), usbd_errstr(err));
1163 sc->sc_pipe_intr = NULL;
1164 }
1165 #endif
1166
1167 sc->sc_link = 0;
1168 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
1169 }
1170
1171 /* Set media options */
1172 Static int
1173 url_ifmedia_change(struct ifnet *ifp)
1174 {
1175 struct url_softc *sc = ifp->if_softc;
1176 struct mii_data *mii = GET_MII(sc);
1177
1178 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
1179
1180 if (sc->sc_dying)
1181 return (0);
1182
1183 sc->sc_link = 0;
1184 if (mii->mii_instance) {
1185 struct mii_softc *miisc;
1186 for (miisc = LIST_FIRST(&mii->mii_phys); miisc != NULL;
1187 miisc = LIST_NEXT(miisc, mii_list))
1188 mii_phy_reset(miisc);
1189 }
1190
1191 return (mii_mediachg(mii));
1192 }
1193
1194 /* Report current media status. */
1195 Static void
1196 url_ifmedia_status(struct ifnet *ifp, struct ifmediareq *ifmr)
1197 {
1198 struct url_softc *sc = ifp->if_softc;
1199 struct mii_data *mii = GET_MII(sc);
1200
1201 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
1202
1203 if (sc->sc_dying)
1204 return;
1205
1206 if ((ifp->if_flags & IFF_RUNNING) == 0) {
1207 ifmr->ifm_active = IFM_ETHER | IFM_NONE;
1208 ifmr->ifm_status = 0;
1209 return;
1210 }
1211
1212 mii_pollstat(mii);
1213 ifmr->ifm_active = mii->mii_media_active;
1214 ifmr->ifm_status = mii->mii_media_status;
1215 }
1216
1217 Static void
1218 url_tick(void *xsc)
1219 {
1220 struct url_softc *sc = xsc;
1221
1222 if (sc == NULL)
1223 return;
1224
1225 DPRINTFN(0xff, ("%s: %s: enter\n", USBDEVNAME(sc->sc_dev),
1226 __func__));
1227
1228 if (sc->sc_dying)
1229 return;
1230
1231 /* Perform periodic stuff in process context */
1232 usb_add_task(sc->sc_udev, &sc->sc_tick_task, USB_TASKQ_DRIVER);
1233 }
1234
1235 Static void
1236 url_tick_task(void *xsc)
1237 {
1238 struct url_softc *sc = xsc;
1239 struct ifnet *ifp;
1240 struct mii_data *mii;
1241 int s;
1242
1243 if (sc == NULL)
1244 return;
1245
1246 DPRINTFN(0xff, ("%s: %s: enter\n", USBDEVNAME(sc->sc_dev),
1247 __func__));
1248
1249 if (sc->sc_dying)
1250 return;
1251
1252 ifp = GET_IFP(sc);
1253 mii = GET_MII(sc);
1254
1255 if (mii == NULL)
1256 return;
1257
1258 s = splnet();
1259
1260 mii_tick(mii);
1261 if (!sc->sc_link) {
1262 mii_pollstat(mii);
1263 if (mii->mii_media_status & IFM_ACTIVE &&
1264 IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
1265 DPRINTF(("%s: %s: got link\n",
1266 USBDEVNAME(sc->sc_dev), __func__));
1267 sc->sc_link++;
1268 if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
1269 url_start(ifp);
1270 }
1271 }
1272
1273 usb_callout(sc->sc_stat_ch, hz, url_tick, sc);
1274
1275 splx(s);
1276 }
1277
1278 /* Get exclusive access to the MII registers */
1279 Static void
1280 url_lock_mii(struct url_softc *sc)
1281 {
1282 DPRINTFN(0xff, ("%s: %s: enter\n", USBDEVNAME(sc->sc_dev),
1283 __func__));
1284
1285 sc->sc_refcnt++;
1286 lockmgr(&sc->sc_mii_lock, LK_EXCLUSIVE, NULL);
1287 }
1288
1289 Static void
1290 url_unlock_mii(struct url_softc *sc)
1291 {
1292 DPRINTFN(0xff, ("%s: %s: enter\n", USBDEVNAME(sc->sc_dev),
1293 __func__));
1294
1295 lockmgr(&sc->sc_mii_lock, LK_RELEASE, NULL);
1296 if (--sc->sc_refcnt < 0)
1297 usb_detach_wakeup(USBDEV(sc->sc_dev));
1298 }
1299
1300 Static int
1301 url_int_miibus_readreg(device_ptr_t dev, int phy, int reg)
1302 {
1303 struct url_softc *sc;
1304 u_int16_t val;
1305
1306 if (dev == NULL)
1307 return (0);
1308
1309 sc = USBGETSOFTC(dev);
1310
1311 DPRINTFN(0xff, ("%s: %s: enter, phy=%d reg=0x%04x\n",
1312 USBDEVNAME(sc->sc_dev), __func__, phy, reg));
1313
1314 if (sc->sc_dying) {
1315 #ifdef DIAGNOSTIC
1316 printf("%s: %s: dying\n", USBDEVNAME(sc->sc_dev),
1317 __func__);
1318 #endif
1319 return (0);
1320 }
1321
1322 /* XXX: one PHY only for the RTL8150 internal PHY */
1323 if (phy != 0) {
1324 DPRINTFN(0xff, ("%s: %s: phy=%d is not supported\n",
1325 USBDEVNAME(sc->sc_dev), __func__, phy));
1326 return (0);
1327 }
1328
1329 url_lock_mii(sc);
1330
1331 switch (reg) {
1332 case MII_BMCR: /* Control Register */
1333 reg = URL_BMCR;
1334 break;
1335 case MII_BMSR: /* Status Register */
1336 reg = URL_BMSR;
1337 break;
1338 case MII_PHYIDR1:
1339 case MII_PHYIDR2:
1340 val = 0;
1341 goto R_DONE;
1342 break;
1343 case MII_ANAR: /* Autonegotiation advertisement */
1344 reg = URL_ANAR;
1345 break;
1346 case MII_ANLPAR: /* Autonegotiation link partner abilities */
1347 reg = URL_ANLP;
1348 break;
1349 case URLPHY_MSR: /* Media Status Register */
1350 reg = URL_MSR;
1351 break;
1352 default:
1353 printf("%s: %s: bad register %04x\n",
1354 USBDEVNAME(sc->sc_dev), __func__, reg);
1355 val = 0;
1356 goto R_DONE;
1357 break;
1358 }
1359
1360 if (reg == URL_MSR)
1361 val = url_csr_read_1(sc, reg);
1362 else
1363 val = url_csr_read_2(sc, reg);
1364
1365 R_DONE:
1366 DPRINTFN(0xff, ("%s: %s: phy=%d reg=0x%04x => 0x%04x\n",
1367 USBDEVNAME(sc->sc_dev), __func__, phy, reg, val));
1368
1369 url_unlock_mii(sc);
1370 return (val);
1371 }
1372
1373 Static void
1374 url_int_miibus_writereg(device_ptr_t dev, int phy, int reg, int data)
1375 {
1376 struct url_softc *sc;
1377
1378 if (dev == NULL)
1379 return;
1380
1381 sc = USBGETSOFTC(dev);
1382
1383 DPRINTFN(0xff, ("%s: %s: enter, phy=%d reg=0x%04x data=0x%04x\n",
1384 USBDEVNAME(sc->sc_dev), __func__, phy, reg, data));
1385
1386 if (sc->sc_dying) {
1387 #ifdef DIAGNOSTIC
1388 printf("%s: %s: dying\n", USBDEVNAME(sc->sc_dev),
1389 __func__);
1390 #endif
1391 return;
1392 }
1393
1394 /* XXX: one PHY only for the RTL8150 internal PHY */
1395 if (phy != 0) {
1396 DPRINTFN(0xff, ("%s: %s: phy=%d is not supported\n",
1397 USBDEVNAME(sc->sc_dev), __func__, phy));
1398 return;
1399 }
1400
1401 url_lock_mii(sc);
1402
1403 switch (reg) {
1404 case MII_BMCR: /* Control Register */
1405 reg = URL_BMCR;
1406 break;
1407 case MII_BMSR: /* Status Register */
1408 reg = URL_BMSR;
1409 break;
1410 case MII_PHYIDR1:
1411 case MII_PHYIDR2:
1412 goto W_DONE;
1413 break;
1414 case MII_ANAR: /* Autonegotiation advertisement */
1415 reg = URL_ANAR;
1416 break;
1417 case MII_ANLPAR: /* Autonegotiation link partner abilities */
1418 reg = URL_ANLP;
1419 break;
1420 case URLPHY_MSR: /* Media Status Register */
1421 reg = URL_MSR;
1422 break;
1423 default:
1424 printf("%s: %s: bad register %04x\n",
1425 USBDEVNAME(sc->sc_dev), __func__, reg);
1426 goto W_DONE;
1427 break;
1428 }
1429
1430 if (reg == URL_MSR)
1431 url_csr_write_1(sc, reg, data);
1432 else
1433 url_csr_write_2(sc, reg, data);
1434 W_DONE:
1435
1436 url_unlock_mii(sc);
1437 return;
1438 }
1439
1440 Static void
1441 url_miibus_statchg(device_ptr_t dev)
1442 {
1443 #ifdef URL_DEBUG
1444 struct url_softc *sc;
1445
1446 if (dev == NULL)
1447 return;
1448
1449 sc = USBGETSOFTC(dev);
1450 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
1451 #endif
1452 /* Nothing to do */
1453 }
1454
1455 #if 0
1456 /*
1457 * external PHYs support, but not test.
1458 */
1459 Static int
1460 url_ext_miibus_redreg(device_ptr_t dev, int phy, int reg)
1461 {
1462 struct url_softc *sc = USBGETSOFTC(dev);
1463 u_int16_t val;
1464
1465 DPRINTF(("%s: %s: enter, phy=%d reg=0x%04x\n",
1466 USBDEVNAME(sc->sc_dev), __func__, phy, reg));
1467
1468 if (sc->sc_dying) {
1469 #ifdef DIAGNOSTIC
1470 printf("%s: %s: dying\n", USBDEVNAME(sc->sc_dev),
1471 __func__);
1472 #endif
1473 return (0);
1474 }
1475
1476 url_lock_mii(sc);
1477
1478 url_csr_write_1(sc, URL_PHYADD, phy & URL_PHYADD_MASK);
1479 /*
1480 * RTL8150L will initiate a MII management data transaction
1481 * if PHYCNT_OWN bit is set 1 by software. After transaction,
1482 * this bit is auto cleared by TRL8150L.
1483 */
1484 url_csr_write_1(sc, URL_PHYCNT,
1485 (reg | URL_PHYCNT_PHYOWN) & ~URL_PHYCNT_RWCR);
1486 for (i = 0; i < URL_TIMEOUT; i++) {
1487 if ((url_csr_read_1(sc, URL_PHYCNT) & URL_PHYCNT_PHYOWN) == 0)
1488 break;
1489 }
1490 if (i == URL_TIMEOUT) {
1491 printf("%s: MII read timed out\n", USBDEVNAME(sc->sc_dev));
1492 }
1493
1494 val = url_csr_read_2(sc, URL_PHYDAT);
1495
1496 DPRINTF(("%s: %s: phy=%d reg=0x%04x => 0x%04x\n",
1497 USBDEVNAME(sc->sc_dev), __func__, phy, reg, val));
1498
1499 url_unlock_mii(sc);
1500 return (val);
1501 }
1502
1503 Static void
1504 url_ext_miibus_writereg(device_ptr_t dev, int phy, int reg, int data)
1505 {
1506 struct url_softc *sc = USBGETSOFTC(dev);
1507
1508 DPRINTF(("%s: %s: enter, phy=%d reg=0x%04x data=0x%04x\n",
1509 USBDEVNAME(sc->sc_dev), __func__, phy, reg, data));
1510
1511 if (sc->sc_dying) {
1512 #ifdef DIAGNOSTIC
1513 printf("%s: %s: dying\n", USBDEVNAME(sc->sc_dev),
1514 __func__);
1515 #endif
1516 return;
1517 }
1518
1519 url_lock_mii(sc);
1520
1521 url_csr_write_2(sc, URL_PHYDAT, data);
1522 url_csr_write_1(sc, URL_PHYADD, phy);
1523 url_csr_write_1(sc, URL_PHYCNT, reg | URL_PHYCNT_RWCR); /* Write */
1524
1525 for (i=0; i < URL_TIMEOUT; i++) {
1526 if (url_csr_read_1(sc, URL_PHYCNT) & URL_PHYCNT_PHYOWN)
1527 break;
1528 }
1529
1530 if (i == URL_TIMEOUT) {
1531 printf("%s: MII write timed out\n",
1532 USBDEVNAME(sc->sc_dev));
1533 }
1534
1535 url_unlock_mii(sc);
1536 return;
1537 }
1538 #endif
1539
1540