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