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