if_url.c revision 1.40 1 /* $NetBSD: if_url.c,v 1.40 2011/12/23 00:51:44 jakllsch 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.40 2011/12/23 00:51:44 jakllsch Exp $");
47
48 #include "opt_inet.h"
49 #include "rnd.h"
50
51 #include <sys/param.h>
52 #include <sys/systm.h>
53 #include <sys/rwlock.h>
54 #include <sys/mbuf.h>
55 #include <sys/kernel.h>
56 #include <sys/socket.h>
57
58 #include <sys/device.h>
59 #if NRND > 0
60 #include <sys/rnd.h>
61 #endif
62
63 #include <net/if.h>
64 #include <net/if_arp.h>
65 #include <net/if_dl.h>
66 #include <net/if_media.h>
67
68 #include <net/bpf.h>
69
70 #include <net/if_ether.h>
71 #ifdef INET
72 #include <netinet/in.h>
73 #include <netinet/if_inarp.h>
74 #endif
75
76 #include <dev/mii/mii.h>
77 #include <dev/mii/miivar.h>
78 #include <dev/mii/urlphyreg.h>
79
80 #include <dev/usb/usb.h>
81 #include <dev/usb/usbdi.h>
82 #include <dev/usb/usbdi_util.h>
83 #include <dev/usb/usbdevs.h>
84
85 #include <dev/usb/if_urlreg.h>
86
87
88 /* Function declarations */
89 int url_match(device_t, cfdata_t, void *);
90 void url_attach(device_t, device_t, void *);
91 int url_detach(device_t, int);
92 int url_activate(device_t, enum devact);
93 extern struct cfdriver url_cd;
94 CFATTACH_DECL_NEW(url, sizeof(struct url_softc), url_match, url_attach, url_detach, url_activate);
95
96 Static int url_openpipes(struct url_softc *);
97 Static int url_rx_list_init(struct url_softc *);
98 Static int url_tx_list_init(struct url_softc *);
99 Static int url_newbuf(struct url_softc *, struct url_chain *, struct mbuf *);
100 Static void url_start(struct ifnet *);
101 Static int url_send(struct url_softc *, struct mbuf *, int);
102 Static void url_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
103 Static void url_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
104 Static void url_tick(void *);
105 Static void url_tick_task(void *);
106 Static int url_ioctl(struct ifnet *, u_long, void *);
107 Static void url_stop_task(struct url_softc *);
108 Static void url_stop(struct ifnet *, int);
109 Static void url_watchdog(struct ifnet *);
110 Static int url_ifmedia_change(struct ifnet *);
111 Static void url_ifmedia_status(struct ifnet *, struct ifmediareq *);
112 Static void url_lock_mii(struct url_softc *);
113 Static void url_unlock_mii(struct url_softc *);
114 Static int url_int_miibus_readreg(device_t, int, int);
115 Static void url_int_miibus_writereg(device_t, int, int, int);
116 Static void url_miibus_statchg(device_t);
117 Static int url_init(struct ifnet *);
118 Static void url_setmulti(struct url_softc *);
119 Static void url_reset(struct url_softc *);
120
121 Static int url_csr_read_1(struct url_softc *, int);
122 Static int url_csr_read_2(struct url_softc *, int);
123 Static int url_csr_write_1(struct url_softc *, int, int);
124 Static int url_csr_write_2(struct url_softc *, int, int);
125 Static int url_csr_write_4(struct url_softc *, int, int);
126 Static int url_mem(struct url_softc *, int, int, void *, int);
127
128 /* Macros */
129 #ifdef URL_DEBUG
130 #define DPRINTF(x) if (urldebug) printf x
131 #define DPRINTFN(n,x) if (urldebug >= (n)) printf x
132 int urldebug = 0;
133 #else
134 #define DPRINTF(x)
135 #define DPRINTFN(n,x)
136 #endif
137
138 #define URL_SETBIT(sc, reg, x) \
139 url_csr_write_1(sc, reg, url_csr_read_1(sc, reg) | (x))
140
141 #define URL_SETBIT2(sc, reg, x) \
142 url_csr_write_2(sc, reg, url_csr_read_2(sc, reg) | (x))
143
144 #define URL_CLRBIT(sc, reg, x) \
145 url_csr_write_1(sc, reg, url_csr_read_1(sc, reg) & ~(x))
146
147 #define URL_CLRBIT2(sc, reg, x) \
148 url_csr_write_2(sc, reg, url_csr_read_2(sc, reg) & ~(x))
149
150 static const struct url_type {
151 struct usb_devno url_dev;
152 u_int16_t url_flags;
153 #define URL_EXT_PHY 0x0001
154 } url_devs [] = {
155 /* MELCO LUA-KTX */
156 {{ USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUAKTX }, 0},
157 /* Realtek RTL8150L Generic (GREEN HOUSE USBKR100) */
158 {{ USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8150L}, 0},
159 /* Longshine LCS-8138TX */
160 {{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_LCS8138TX}, 0},
161 /* Micronet SP128AR */
162 {{ USB_VENDOR_MICRONET, USB_PRODUCT_MICRONET_SP128AR}, 0},
163 /* OQO model 01 */
164 {{ USB_VENDOR_OQO, USB_PRODUCT_OQO_ETHER01}, 0},
165 };
166 #define url_lookup(v, p) ((const struct url_type *)usb_lookup(url_devs, v, p))
167
168
169 /* Probe */
170 int
171 url_match(device_t parent, cfdata_t match, void *aux)
172 {
173 struct usb_attach_arg *uaa = aux;
174
175 return (url_lookup(uaa->vendor, uaa->product) != NULL ?
176 UMATCH_VENDOR_PRODUCT : UMATCH_NONE);
177 }
178 /* Attach */
179 void
180 url_attach(device_t parent, device_t self, void *aux)
181 {
182 struct url_softc *sc = device_private(self);
183 struct usb_attach_arg *uaa = aux;
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 struct ifnet *ifp;
191 struct mii_data *mii;
192 u_char eaddr[ETHER_ADDR_LEN];
193 int i, s;
194
195 sc->sc_dev = self;
196
197 aprint_naive("\n");
198 aprint_normal("\n");
199
200 devinfop = usbd_devinfo_alloc(dev, 0);
201 aprint_normal_dev(self, "%s\n", devinfop);
202 usbd_devinfo_free(devinfop);
203
204 /* Move the device into the configured state. */
205 err = usbd_set_config_no(dev, URL_CONFIG_NO, 1);
206 if (err) {
207 aprint_error_dev(self, "setting config no failed\n");
208 goto bad;
209 }
210
211 usb_init_task(&sc->sc_tick_task, url_tick_task, sc);
212 rw_init(&sc->sc_mii_rwlock);
213 usb_init_task(&sc->sc_stop_task, (void (*)(void *)) url_stop_task, sc);
214
215 /* get control interface */
216 err = usbd_device2interface_handle(dev, URL_IFACE_INDEX, &iface);
217 if (err) {
218 aprint_error_dev(self, "failed to get interface, err=%s\n",
219 usbd_errstr(err));
220 goto bad;
221 }
222
223 sc->sc_udev = dev;
224 sc->sc_ctl_iface = iface;
225 sc->sc_flags = url_lookup(uaa->vendor, uaa->product)->url_flags;
226
227 /* get interface descriptor */
228 id = usbd_get_interface_descriptor(sc->sc_ctl_iface);
229
230 /* find endpoints */
231 sc->sc_bulkin_no = sc->sc_bulkout_no = sc->sc_intrin_no = -1;
232 for (i = 0; i < id->bNumEndpoints; i++) {
233 ed = usbd_interface2endpoint_descriptor(sc->sc_ctl_iface, i);
234 if (ed == NULL) {
235 aprint_error_dev(self,
236 "couldn't get endpoint %d\n", 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 aprint_error_dev(self, "missing endpoint\n");
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 aprint_error_dev(self, "read MAC address failed\n");
266 splx(s);
267 goto bad;
268 }
269
270 /* Print Ethernet Address */
271 aprint_normal_dev(self, "Ethernet address %s\n", 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, device_xname(self), 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 sc->sc_ec.ec_mii = mii;
303 ifmedia_init(&mii->mii_media, 0,
304 url_ifmedia_change, url_ifmedia_status);
305 mii_attach(self, mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, 0);
306 if (LIST_FIRST(&mii->mii_phys) == NULL) {
307 ifmedia_add(&mii->mii_media, IFM_ETHER | IFM_NONE, 0, NULL);
308 ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_NONE);
309 } else
310 ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_AUTO);
311
312 /* attach the interface */
313 if_attach(ifp);
314 ether_ifattach(ifp, eaddr);
315
316 #if NRND > 0
317 rnd_attach_source(&sc->rnd_source, device_xname(self),
318 RND_TYPE_NET, 0);
319 #endif
320
321 callout_init(&sc->sc_stat_ch, 0);
322 sc->sc_attached = 1;
323 splx(s);
324
325 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, dev, sc->sc_dev);
326
327 return;
328
329 bad:
330 sc->sc_dying = 1;
331 return;
332 }
333
334 /* detach */
335 int
336 url_detach(device_t self, int flags)
337 {
338 struct url_softc *sc = device_private(self);
339 struct ifnet *ifp = GET_IFP(sc);
340 int s;
341
342 DPRINTF(("%s: %s: enter\n", device_xname(sc->sc_dev), __func__));
343
344 /* Detached before attached finished */
345 if (!sc->sc_attached)
346 return (0);
347
348 callout_stop(&sc->sc_stat_ch);
349
350 /* Remove any pending tasks */
351 usb_rem_task(sc->sc_udev, &sc->sc_tick_task);
352 usb_rem_task(sc->sc_udev, &sc->sc_stop_task);
353
354 s = splusb();
355
356 if (--sc->sc_refcnt >= 0) {
357 /* Wait for processes to go away */
358 usb_detach_wait(sc->sc_dev);
359 }
360
361 if (ifp->if_flags & IFF_RUNNING)
362 url_stop(GET_IFP(sc), 1);
363
364 #if NRND > 0
365 rnd_detach_source(&sc->rnd_source);
366 #endif
367 mii_detach(&sc->sc_mii, MII_PHY_ANY, MII_OFFSET_ANY);
368 ifmedia_delete_instance(&sc->sc_mii.mii_media, IFM_INST_ANY);
369 ether_ifdetach(ifp);
370 if_detach(ifp);
371
372 #ifdef DIAGNOSTIC
373 if (sc->sc_pipe_tx != NULL)
374 aprint_debug_dev(self, "detach has active tx endpoint.\n");
375 if (sc->sc_pipe_rx != NULL)
376 aprint_debug_dev(self, "detach has active rx endpoint.\n");
377 if (sc->sc_pipe_intr != NULL)
378 aprint_debug_dev(self, "detach has active intr endpoint.\n");
379 #endif
380
381 sc->sc_attached = 0;
382
383 splx(s);
384
385 rw_destroy(&sc->sc_mii_rwlock);
386 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
387 sc->sc_dev);
388
389 return (0);
390 }
391
392 /* read/write memory */
393 Static int
394 url_mem(struct url_softc *sc, int cmd, int offset, void *buf, int len)
395 {
396 usb_device_request_t req;
397 usbd_status err;
398
399 if (sc == NULL)
400 return (0);
401
402 DPRINTFN(0x200,
403 ("%s: %s: enter\n", device_xname(sc->sc_dev), __func__));
404
405 if (sc->sc_dying)
406 return (0);
407
408 if (cmd == URL_CMD_READMEM)
409 req.bmRequestType = UT_READ_VENDOR_DEVICE;
410 else
411 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
412 req.bRequest = URL_REQ_MEM;
413 USETW(req.wValue, offset);
414 USETW(req.wIndex, 0x0000);
415 USETW(req.wLength, len);
416
417 sc->sc_refcnt++;
418 err = usbd_do_request(sc->sc_udev, &req, buf);
419 if (--sc->sc_refcnt < 0)
420 usb_detach_wakeup(sc->sc_dev);
421 if (err) {
422 DPRINTF(("%s: url_mem(): %s failed. off=%04x, err=%d\n",
423 device_xname(sc->sc_dev),
424 cmd == URL_CMD_READMEM ? "read" : "write",
425 offset, err));
426 }
427
428 return (err);
429 }
430
431 /* read 1byte from register */
432 Static int
433 url_csr_read_1(struct url_softc *sc, int reg)
434 {
435 u_int8_t val = 0;
436
437 DPRINTFN(0x100,
438 ("%s: %s: enter\n", device_xname(sc->sc_dev), __func__));
439
440 if (sc->sc_dying)
441 return (0);
442
443 return (url_mem(sc, URL_CMD_READMEM, reg, &val, 1) ? 0 : val);
444 }
445
446 /* read 2bytes from register */
447 Static int
448 url_csr_read_2(struct url_softc *sc, int reg)
449 {
450 uWord val;
451
452 DPRINTFN(0x100,
453 ("%s: %s: enter\n", device_xname(sc->sc_dev), __func__));
454
455 if (sc->sc_dying)
456 return (0);
457
458 USETW(val, 0);
459 return (url_mem(sc, URL_CMD_READMEM, reg, &val, 2) ? 0 : UGETW(val));
460 }
461
462 /* write 1byte to register */
463 Static int
464 url_csr_write_1(struct url_softc *sc, int reg, int aval)
465 {
466 u_int8_t val = aval;
467
468 DPRINTFN(0x100,
469 ("%s: %s: enter\n", device_xname(sc->sc_dev), __func__));
470
471 if (sc->sc_dying)
472 return (0);
473
474 return (url_mem(sc, URL_CMD_WRITEMEM, reg, &val, 1) ? -1 : 0);
475 }
476
477 /* write 2bytes to register */
478 Static int
479 url_csr_write_2(struct url_softc *sc, int reg, int aval)
480 {
481 uWord val;
482
483 DPRINTFN(0x100,
484 ("%s: %s: enter\n", device_xname(sc->sc_dev), __func__));
485
486 USETW(val, aval);
487
488 if (sc->sc_dying)
489 return (0);
490
491 return (url_mem(sc, URL_CMD_WRITEMEM, reg, &val, 2) ? -1 : 0);
492 }
493
494 /* write 4bytes to register */
495 Static int
496 url_csr_write_4(struct url_softc *sc, int reg, int aval)
497 {
498 uDWord val;
499
500 DPRINTFN(0x100,
501 ("%s: %s: enter\n", device_xname(sc->sc_dev), __func__));
502
503 USETDW(val, aval);
504
505 if (sc->sc_dying)
506 return (0);
507
508 return (url_mem(sc, URL_CMD_WRITEMEM, reg, &val, 4) ? -1 : 0);
509 }
510
511 Static int
512 url_init(struct ifnet *ifp)
513 {
514 struct url_softc *sc = ifp->if_softc;
515 struct mii_data *mii = GET_MII(sc);
516 const u_char *eaddr;
517 int i, rc, s;
518
519 DPRINTF(("%s: %s: enter\n", device_xname(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 = CLLADDR(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
553 /* Initialize transmit ring */
554 if (url_tx_list_init(sc) == ENOBUFS) {
555 printf("%s: tx list init failed\n", device_xname(sc->sc_dev));
556 splx(s);
557 return (EIO);
558 }
559
560 /* Initialize receive ring */
561 if (url_rx_list_init(sc) == ENOBUFS) {
562 printf("%s: rx list init failed\n", device_xname(sc->sc_dev));
563 splx(s);
564 return (EIO);
565 }
566
567 /* Load the multicast filter */
568 url_setmulti(sc);
569
570 /* Enable RX and TX */
571 URL_SETBIT(sc, URL_CR, URL_CR_TE | URL_CR_RE);
572
573 if ((rc = mii_mediachg(mii)) == ENXIO)
574 rc = 0;
575 else if (rc != 0)
576 goto out;
577
578 if (sc->sc_pipe_tx == NULL || sc->sc_pipe_rx == NULL) {
579 if (url_openpipes(sc)) {
580 splx(s);
581 return (EIO);
582 }
583 }
584
585 ifp->if_flags |= IFF_RUNNING;
586 ifp->if_flags &= ~IFF_OACTIVE;
587
588 callout_reset(&sc->sc_stat_ch, hz, url_tick, sc);
589
590 out:
591 splx(s);
592 return rc;
593 }
594
595 Static void
596 url_reset(struct url_softc *sc)
597 {
598 int i;
599
600 DPRINTF(("%s: %s: enter\n", device_xname(sc->sc_dev), __func__));
601
602 if (sc->sc_dying)
603 return;
604
605 URL_SETBIT(sc, URL_CR, URL_CR_SOFT_RST);
606
607 for (i = 0; i < URL_TX_TIMEOUT; i++) {
608 if (!(url_csr_read_1(sc, URL_CR) & URL_CR_SOFT_RST))
609 break;
610 delay(10); /* XXX */
611 }
612
613 delay(10000); /* XXX */
614 }
615
616 int
617 url_activate(device_t self, enum devact act)
618 {
619 struct url_softc *sc = device_private(self);
620
621 DPRINTF(("%s: %s: enter, act=%d\n", device_xname(sc->sc_dev),
622 __func__, act));
623
624 switch (act) {
625 case DVACT_DEACTIVATE:
626 if_deactivate(&sc->sc_ec.ec_if);
627 sc->sc_dying = 1;
628 return 0;
629 default:
630 return EOPNOTSUPP;
631 }
632 }
633
634 #define url_calchash(addr) (ether_crc32_be((addr), ETHER_ADDR_LEN) >> 26)
635
636
637 Static void
638 url_setmulti(struct url_softc *sc)
639 {
640 struct ifnet *ifp;
641 struct ether_multi *enm;
642 struct ether_multistep step;
643 u_int32_t hashes[2] = { 0, 0 };
644 int h = 0;
645 int mcnt = 0;
646
647 DPRINTF(("%s: %s: enter\n", device_xname(sc->sc_dev), __func__));
648
649 if (sc->sc_dying)
650 return;
651
652 ifp = GET_IFP(sc);
653
654 if (ifp->if_flags & IFF_PROMISC) {
655 URL_SETBIT2(sc, URL_RCR, URL_RCR_AAM|URL_RCR_AAP);
656 return;
657 } else if (ifp->if_flags & IFF_ALLMULTI) {
658 allmulti:
659 ifp->if_flags |= IFF_ALLMULTI;
660 URL_SETBIT2(sc, URL_RCR, URL_RCR_AAM);
661 URL_CLRBIT2(sc, URL_RCR, URL_RCR_AAP);
662 return;
663 }
664
665 /* first, zot all the existing hash bits */
666 url_csr_write_4(sc, URL_MAR0, 0);
667 url_csr_write_4(sc, URL_MAR4, 0);
668
669 /* now program new ones */
670 ETHER_FIRST_MULTI(step, &sc->sc_ec, enm);
671 while (enm != NULL) {
672 if (memcmp(enm->enm_addrlo, enm->enm_addrhi,
673 ETHER_ADDR_LEN) != 0)
674 goto allmulti;
675
676 h = url_calchash(enm->enm_addrlo);
677 if (h < 32)
678 hashes[0] |= (1 << h);
679 else
680 hashes[1] |= (1 << (h -32));
681 mcnt++;
682 ETHER_NEXT_MULTI(step, enm);
683 }
684
685 ifp->if_flags &= ~IFF_ALLMULTI;
686
687 URL_CLRBIT2(sc, URL_RCR, URL_RCR_AAM|URL_RCR_AAP);
688
689 if (mcnt){
690 URL_SETBIT2(sc, URL_RCR, URL_RCR_AM);
691 } else {
692 URL_CLRBIT2(sc, URL_RCR, URL_RCR_AM);
693 }
694 url_csr_write_4(sc, URL_MAR0, hashes[0]);
695 url_csr_write_4(sc, URL_MAR4, hashes[1]);
696 }
697
698 Static int
699 url_openpipes(struct url_softc *sc)
700 {
701 struct url_chain *c;
702 usbd_status err;
703 int i;
704 int error = 0;
705
706 if (sc->sc_dying)
707 return (EIO);
708
709 sc->sc_refcnt++;
710
711 /* Open RX pipe */
712 err = usbd_open_pipe(sc->sc_ctl_iface, sc->sc_bulkin_no,
713 USBD_EXCLUSIVE_USE, &sc->sc_pipe_rx);
714 if (err) {
715 printf("%s: open rx pipe failed: %s\n",
716 device_xname(sc->sc_dev), usbd_errstr(err));
717 error = EIO;
718 goto done;
719 }
720
721 /* Open TX pipe */
722 err = usbd_open_pipe(sc->sc_ctl_iface, sc->sc_bulkout_no,
723 USBD_EXCLUSIVE_USE, &sc->sc_pipe_tx);
724 if (err) {
725 printf("%s: open tx pipe failed: %s\n",
726 device_xname(sc->sc_dev), usbd_errstr(err));
727 error = EIO;
728 goto done;
729 }
730
731 #if 0
732 /* XXX: interrupt endpoint is not yet supported */
733 /* Open Interrupt pipe */
734 err = usbd_open_pipe_intr(sc->sc_ctl_iface, sc->sc_intrin_no,
735 USBD_EXCLUSIVE_USE, &sc->sc_pipe_intr, sc,
736 &sc->sc_cdata.url_ibuf, URL_INTR_PKGLEN,
737 url_intr, USBD_DEFAULT_INTERVAL);
738 if (err) {
739 printf("%s: open intr pipe failed: %s\n",
740 device_xname(sc->sc_dev), usbd_errstr(err));
741 error = EIO;
742 goto done;
743 }
744 #endif
745
746
747 /* Start up the receive pipe. */
748 for (i = 0; i < URL_RX_LIST_CNT; i++) {
749 c = &sc->sc_cdata.url_rx_chain[i];
750 usbd_setup_xfer(c->url_xfer, sc->sc_pipe_rx,
751 c, c->url_buf, URL_BUFSZ,
752 USBD_SHORT_XFER_OK | USBD_NO_COPY,
753 USBD_NO_TIMEOUT, url_rxeof);
754 (void)usbd_transfer(c->url_xfer);
755 DPRINTF(("%s: %s: start read\n", device_xname(sc->sc_dev),
756 __func__));
757 }
758
759 done:
760 if (--sc->sc_refcnt < 0)
761 usb_detach_wakeup(sc->sc_dev);
762
763 return (error);
764 }
765
766 Static int
767 url_newbuf(struct url_softc *sc, struct url_chain *c, struct mbuf *m)
768 {
769 struct mbuf *m_new = NULL;
770
771 DPRINTF(("%s: %s: enter\n", device_xname(sc->sc_dev), __func__));
772
773 if (m == NULL) {
774 MGETHDR(m_new, M_DONTWAIT, MT_DATA);
775 if (m_new == NULL) {
776 printf("%s: no memory for rx list "
777 "-- packet dropped!\n", device_xname(sc->sc_dev));
778 return (ENOBUFS);
779 }
780 MCLGET(m_new, M_DONTWAIT);
781 if (!(m_new->m_flags & M_EXT)) {
782 printf("%s: no memory for rx list "
783 "-- packet dropped!\n", device_xname(sc->sc_dev));
784 m_freem(m_new);
785 return (ENOBUFS);
786 }
787 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
788 } else {
789 m_new = m;
790 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
791 m_new->m_data = m_new->m_ext.ext_buf;
792 }
793
794 m_adj(m_new, ETHER_ALIGN);
795 c->url_mbuf = m_new;
796
797 return (0);
798 }
799
800
801 Static int
802 url_rx_list_init(struct url_softc *sc)
803 {
804 struct url_cdata *cd;
805 struct url_chain *c;
806 int i;
807
808 DPRINTF(("%s: %s: enter\n", device_xname(sc->sc_dev), __func__));
809
810 cd = &sc->sc_cdata;
811 for (i = 0; i < URL_RX_LIST_CNT; i++) {
812 c = &cd->url_rx_chain[i];
813 c->url_sc = sc;
814 c->url_idx = i;
815 if (url_newbuf(sc, c, NULL) == ENOBUFS)
816 return (ENOBUFS);
817 if (c->url_xfer == NULL) {
818 c->url_xfer = usbd_alloc_xfer(sc->sc_udev);
819 if (c->url_xfer == NULL)
820 return (ENOBUFS);
821 c->url_buf = usbd_alloc_buffer(c->url_xfer, URL_BUFSZ);
822 if (c->url_buf == NULL) {
823 usbd_free_xfer(c->url_xfer);
824 return (ENOBUFS);
825 }
826 }
827 }
828
829 return (0);
830 }
831
832 Static int
833 url_tx_list_init(struct url_softc *sc)
834 {
835 struct url_cdata *cd;
836 struct url_chain *c;
837 int i;
838
839 DPRINTF(("%s: %s: enter\n", device_xname(sc->sc_dev), __func__));
840
841 cd = &sc->sc_cdata;
842 for (i = 0; i < URL_TX_LIST_CNT; i++) {
843 c = &cd->url_tx_chain[i];
844 c->url_sc = sc;
845 c->url_idx = i;
846 c->url_mbuf = NULL;
847 if (c->url_xfer == NULL) {
848 c->url_xfer = usbd_alloc_xfer(sc->sc_udev);
849 if (c->url_xfer == NULL)
850 return (ENOBUFS);
851 c->url_buf = usbd_alloc_buffer(c->url_xfer, URL_BUFSZ);
852 if (c->url_buf == NULL) {
853 usbd_free_xfer(c->url_xfer);
854 return (ENOBUFS);
855 }
856 }
857 }
858
859 return (0);
860 }
861
862 Static void
863 url_start(struct ifnet *ifp)
864 {
865 struct url_softc *sc = ifp->if_softc;
866 struct mbuf *m_head = NULL;
867
868 DPRINTF(("%s: %s: enter, link=%d\n", device_xname(sc->sc_dev),
869 __func__, sc->sc_link));
870
871 if (sc->sc_dying)
872 return;
873
874 if (!sc->sc_link)
875 return;
876
877 if (ifp->if_flags & IFF_OACTIVE)
878 return;
879
880 IFQ_POLL(&ifp->if_snd, m_head);
881 if (m_head == NULL)
882 return;
883
884 if (url_send(sc, m_head, 0)) {
885 ifp->if_flags |= IFF_OACTIVE;
886 return;
887 }
888
889 IFQ_DEQUEUE(&ifp->if_snd, m_head);
890
891 bpf_mtap(ifp, m_head);
892
893 ifp->if_flags |= IFF_OACTIVE;
894
895 /* Set a timeout in case the chip goes out to lunch. */
896 ifp->if_timer = 5;
897 }
898
899 Static int
900 url_send(struct url_softc *sc, struct mbuf *m, int idx)
901 {
902 int total_len;
903 struct url_chain *c;
904 usbd_status err;
905
906 DPRINTF(("%s: %s: enter\n", device_xname(sc->sc_dev),__func__));
907
908 c = &sc->sc_cdata.url_tx_chain[idx];
909
910 /* Copy the mbuf data into a contiguous buffer */
911 m_copydata(m, 0, m->m_pkthdr.len, c->url_buf);
912 c->url_mbuf = m;
913 total_len = m->m_pkthdr.len;
914
915 if (total_len < URL_MIN_FRAME_LEN) {
916 memset(c->url_buf + total_len, 0,
917 URL_MIN_FRAME_LEN - total_len);
918 total_len = URL_MIN_FRAME_LEN;
919 }
920 usbd_setup_xfer(c->url_xfer, sc->sc_pipe_tx, c, c->url_buf, total_len,
921 USBD_FORCE_SHORT_XFER | USBD_NO_COPY,
922 URL_TX_TIMEOUT, url_txeof);
923
924 /* Transmit */
925 sc->sc_refcnt++;
926 err = usbd_transfer(c->url_xfer);
927 if (--sc->sc_refcnt < 0)
928 usb_detach_wakeup(sc->sc_dev);
929 if (err != USBD_IN_PROGRESS) {
930 printf("%s: url_send error=%s\n", device_xname(sc->sc_dev),
931 usbd_errstr(err));
932 /* Stop the interface */
933 usb_add_task(sc->sc_udev, &sc->sc_stop_task,
934 USB_TASKQ_DRIVER);
935 return (EIO);
936 }
937
938 DPRINTF(("%s: %s: send %d bytes\n", device_xname(sc->sc_dev),
939 __func__, total_len));
940
941 sc->sc_cdata.url_tx_cnt++;
942
943 return (0);
944 }
945
946 Static void
947 url_txeof(usbd_xfer_handle xfer, usbd_private_handle priv,
948 usbd_status status)
949 {
950 struct url_chain *c = priv;
951 struct url_softc *sc = c->url_sc;
952 struct ifnet *ifp = GET_IFP(sc);
953 int s;
954
955 if (sc->sc_dying)
956 return;
957
958 s = splnet();
959
960 DPRINTF(("%s: %s: enter\n", device_xname(sc->sc_dev), __func__));
961
962 ifp->if_timer = 0;
963 ifp->if_flags &= ~IFF_OACTIVE;
964
965 if (status != USBD_NORMAL_COMPLETION) {
966 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
967 splx(s);
968 return;
969 }
970 ifp->if_oerrors++;
971 printf("%s: usb error on tx: %s\n", device_xname(sc->sc_dev),
972 usbd_errstr(status));
973 if (status == USBD_STALLED) {
974 sc->sc_refcnt++;
975 usbd_clear_endpoint_stall_async(sc->sc_pipe_tx);
976 if (--sc->sc_refcnt < 0)
977 usb_detach_wakeup(sc->sc_dev);
978 }
979 splx(s);
980 return;
981 }
982
983 ifp->if_opackets++;
984
985 m_freem(c->url_mbuf);
986 c->url_mbuf = NULL;
987
988 if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
989 url_start(ifp);
990
991 splx(s);
992 }
993
994 Static void
995 url_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
996 {
997 struct url_chain *c = priv;
998 struct url_softc *sc = c->url_sc;
999 struct ifnet *ifp = GET_IFP(sc);
1000 struct mbuf *m;
1001 u_int32_t total_len;
1002 url_rxhdr_t rxhdr;
1003 int s;
1004
1005 DPRINTF(("%s: %s: enter\n", device_xname(sc->sc_dev),__func__));
1006
1007 if (sc->sc_dying)
1008 return;
1009
1010 if (status != USBD_NORMAL_COMPLETION) {
1011 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
1012 return;
1013 sc->sc_rx_errs++;
1014 if (usbd_ratecheck(&sc->sc_rx_notice)) {
1015 printf("%s: %u usb errors on rx: %s\n",
1016 device_xname(sc->sc_dev), sc->sc_rx_errs,
1017 usbd_errstr(status));
1018 sc->sc_rx_errs = 0;
1019 }
1020 if (status == USBD_STALLED) {
1021 sc->sc_refcnt++;
1022 usbd_clear_endpoint_stall_async(sc->sc_pipe_rx);
1023 if (--sc->sc_refcnt < 0)
1024 usb_detach_wakeup(sc->sc_dev);
1025 }
1026 goto done;
1027 }
1028
1029 usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
1030
1031 memcpy(mtod(c->url_mbuf, char *), c->url_buf, total_len);
1032
1033 if (total_len <= ETHER_CRC_LEN) {
1034 ifp->if_ierrors++;
1035 goto done;
1036 }
1037
1038 memcpy(&rxhdr, c->url_buf + total_len - ETHER_CRC_LEN, sizeof(rxhdr));
1039
1040 DPRINTF(("%s: RX Status: %dbytes%s%s%s%s packets\n",
1041 device_xname(sc->sc_dev),
1042 UGETW(rxhdr) & URL_RXHDR_BYTEC_MASK,
1043 UGETW(rxhdr) & URL_RXHDR_VALID_MASK ? ", Valid" : "",
1044 UGETW(rxhdr) & URL_RXHDR_RUNTPKT_MASK ? ", Runt" : "",
1045 UGETW(rxhdr) & URL_RXHDR_PHYPKT_MASK ? ", Physical match" : "",
1046 UGETW(rxhdr) & URL_RXHDR_MCASTPKT_MASK ? ", Multicast" : ""));
1047
1048 if ((UGETW(rxhdr) & URL_RXHDR_VALID_MASK) == 0) {
1049 ifp->if_ierrors++;
1050 goto done;
1051 }
1052
1053 ifp->if_ipackets++;
1054 total_len -= ETHER_CRC_LEN;
1055
1056 m = c->url_mbuf;
1057 m->m_pkthdr.len = m->m_len = total_len;
1058 m->m_pkthdr.rcvif = ifp;
1059
1060 s = splnet();
1061
1062 if (url_newbuf(sc, c, NULL) == ENOBUFS) {
1063 ifp->if_ierrors++;
1064 goto done1;
1065 }
1066
1067 bpf_mtap(ifp, m);
1068
1069 DPRINTF(("%s: %s: deliver %d\n", device_xname(sc->sc_dev),
1070 __func__, m->m_len));
1071 (*(ifp)->if_input)((ifp), (m));
1072
1073 done1:
1074 splx(s);
1075
1076 done:
1077 /* Setup new transfer */
1078 usbd_setup_xfer(xfer, sc->sc_pipe_rx, c, c->url_buf, URL_BUFSZ,
1079 USBD_SHORT_XFER_OK | USBD_NO_COPY,
1080 USBD_NO_TIMEOUT, url_rxeof);
1081 sc->sc_refcnt++;
1082 usbd_transfer(xfer);
1083 if (--sc->sc_refcnt < 0)
1084 usb_detach_wakeup(sc->sc_dev);
1085
1086 DPRINTF(("%s: %s: start rx\n", device_xname(sc->sc_dev), __func__));
1087 }
1088
1089 #if 0
1090 Static void url_intr(void)
1091 {
1092 }
1093 #endif
1094
1095 Static int
1096 url_ioctl(struct ifnet *ifp, u_long cmd, void *data)
1097 {
1098 struct url_softc *sc = ifp->if_softc;
1099 int s, error = 0;
1100
1101 DPRINTF(("%s: %s: enter\n", device_xname(sc->sc_dev), __func__));
1102
1103 if (sc->sc_dying)
1104 return (EIO);
1105
1106 s = splnet();
1107
1108 error = ether_ioctl(ifp, cmd, data);
1109 if (error == ENETRESET) {
1110 if (ifp->if_flags & IFF_RUNNING)
1111 url_setmulti(sc);
1112 error = 0;
1113 }
1114
1115 splx(s);
1116
1117 return (error);
1118 }
1119
1120 Static void
1121 url_watchdog(struct ifnet *ifp)
1122 {
1123 struct url_softc *sc = ifp->if_softc;
1124 struct url_chain *c;
1125 usbd_status stat;
1126 int s;
1127
1128 DPRINTF(("%s: %s: enter\n", device_xname(sc->sc_dev), __func__));
1129
1130 ifp->if_oerrors++;
1131 printf("%s: watchdog timeout\n", device_xname(sc->sc_dev));
1132
1133 s = splusb();
1134 c = &sc->sc_cdata.url_tx_chain[0];
1135 usbd_get_xfer_status(c->url_xfer, NULL, NULL, NULL, &stat);
1136 url_txeof(c->url_xfer, c, stat);
1137
1138 if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
1139 url_start(ifp);
1140 splx(s);
1141 }
1142
1143 Static void
1144 url_stop_task(struct url_softc *sc)
1145 {
1146 url_stop(GET_IFP(sc), 1);
1147 }
1148
1149 /* Stop the adapter and free any mbufs allocated to the RX and TX lists. */
1150 Static void
1151 url_stop(struct ifnet *ifp, int disable)
1152 {
1153 struct url_softc *sc = ifp->if_softc;
1154 usbd_status err;
1155 int i;
1156
1157 DPRINTF(("%s: %s: enter\n", device_xname(sc->sc_dev), __func__));
1158
1159 ifp->if_timer = 0;
1160
1161 url_reset(sc);
1162
1163 callout_stop(&sc->sc_stat_ch);
1164
1165 /* Stop transfers */
1166 /* RX endpoint */
1167 if (sc->sc_pipe_rx != NULL) {
1168 err = usbd_abort_pipe(sc->sc_pipe_rx);
1169 if (err)
1170 printf("%s: abort rx pipe failed: %s\n",
1171 device_xname(sc->sc_dev), usbd_errstr(err));
1172 err = usbd_close_pipe(sc->sc_pipe_rx);
1173 if (err)
1174 printf("%s: close rx pipe failed: %s\n",
1175 device_xname(sc->sc_dev), usbd_errstr(err));
1176 sc->sc_pipe_rx = NULL;
1177 }
1178
1179 /* TX endpoint */
1180 if (sc->sc_pipe_tx != NULL) {
1181 err = usbd_abort_pipe(sc->sc_pipe_tx);
1182 if (err)
1183 printf("%s: abort tx pipe failed: %s\n",
1184 device_xname(sc->sc_dev), usbd_errstr(err));
1185 err = usbd_close_pipe(sc->sc_pipe_tx);
1186 if (err)
1187 printf("%s: close tx pipe failed: %s\n",
1188 device_xname(sc->sc_dev), usbd_errstr(err));
1189 sc->sc_pipe_tx = NULL;
1190 }
1191
1192 #if 0
1193 /* XXX: Interrupt endpoint is not yet supported!! */
1194 /* Interrupt endpoint */
1195 if (sc->sc_pipe_intr != NULL) {
1196 err = usbd_abort_pipe(sc->sc_pipe_intr);
1197 if (err)
1198 printf("%s: abort intr pipe failed: %s\n",
1199 device_xname(sc->sc_dev), usbd_errstr(err));
1200 err = usbd_close_pipe(sc->sc_pipe_intr);
1201 if (err)
1202 printf("%s: close intr pipe failed: %s\n",
1203 device_xname(sc->sc_dev), usbd_errstr(err));
1204 sc->sc_pipe_intr = NULL;
1205 }
1206 #endif
1207
1208 /* Free RX resources. */
1209 for (i = 0; i < URL_RX_LIST_CNT; i++) {
1210 if (sc->sc_cdata.url_rx_chain[i].url_mbuf != NULL) {
1211 m_freem(sc->sc_cdata.url_rx_chain[i].url_mbuf);
1212 sc->sc_cdata.url_rx_chain[i].url_mbuf = NULL;
1213 }
1214 if (sc->sc_cdata.url_rx_chain[i].url_xfer != NULL) {
1215 usbd_free_xfer(sc->sc_cdata.url_rx_chain[i].url_xfer);
1216 sc->sc_cdata.url_rx_chain[i].url_xfer = NULL;
1217 }
1218 }
1219
1220 /* Free TX resources. */
1221 for (i = 0; i < URL_TX_LIST_CNT; i++) {
1222 if (sc->sc_cdata.url_tx_chain[i].url_mbuf != NULL) {
1223 m_freem(sc->sc_cdata.url_tx_chain[i].url_mbuf);
1224 sc->sc_cdata.url_tx_chain[i].url_mbuf = NULL;
1225 }
1226 if (sc->sc_cdata.url_tx_chain[i].url_xfer != NULL) {
1227 usbd_free_xfer(sc->sc_cdata.url_tx_chain[i].url_xfer);
1228 sc->sc_cdata.url_tx_chain[i].url_xfer = NULL;
1229 }
1230 }
1231
1232 sc->sc_link = 0;
1233 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
1234 }
1235
1236 /* Set media options */
1237 Static int
1238 url_ifmedia_change(struct ifnet *ifp)
1239 {
1240 struct url_softc *sc = ifp->if_softc;
1241 struct mii_data *mii = GET_MII(sc);
1242 int rc;
1243
1244 DPRINTF(("%s: %s: enter\n", device_xname(sc->sc_dev), __func__));
1245
1246 if (sc->sc_dying)
1247 return (0);
1248
1249 sc->sc_link = 0;
1250 if ((rc = mii_mediachg(mii)) == ENXIO)
1251 return 0;
1252 return rc;
1253 }
1254
1255 /* Report current media status. */
1256 Static void
1257 url_ifmedia_status(struct ifnet *ifp, struct ifmediareq *ifmr)
1258 {
1259 struct url_softc *sc = ifp->if_softc;
1260
1261 DPRINTF(("%s: %s: enter\n", device_xname(sc->sc_dev), __func__));
1262
1263 if (sc->sc_dying)
1264 return;
1265
1266 ether_mediastatus(ifp, ifmr);
1267 }
1268
1269 Static void
1270 url_tick(void *xsc)
1271 {
1272 struct url_softc *sc = xsc;
1273
1274 if (sc == NULL)
1275 return;
1276
1277 DPRINTFN(0xff, ("%s: %s: enter\n", device_xname(sc->sc_dev),
1278 __func__));
1279
1280 if (sc->sc_dying)
1281 return;
1282
1283 /* Perform periodic stuff in process context */
1284 usb_add_task(sc->sc_udev, &sc->sc_tick_task, USB_TASKQ_DRIVER);
1285 }
1286
1287 Static void
1288 url_tick_task(void *xsc)
1289 {
1290 struct url_softc *sc = xsc;
1291 struct ifnet *ifp;
1292 struct mii_data *mii;
1293 int s;
1294
1295 if (sc == NULL)
1296 return;
1297
1298 DPRINTFN(0xff, ("%s: %s: enter\n", device_xname(sc->sc_dev),
1299 __func__));
1300
1301 if (sc->sc_dying)
1302 return;
1303
1304 ifp = GET_IFP(sc);
1305 mii = GET_MII(sc);
1306
1307 if (mii == NULL)
1308 return;
1309
1310 s = splnet();
1311
1312 mii_tick(mii);
1313 if (!sc->sc_link) {
1314 mii_pollstat(mii);
1315 if (mii->mii_media_status & IFM_ACTIVE &&
1316 IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
1317 DPRINTF(("%s: %s: got link\n",
1318 device_xname(sc->sc_dev), __func__));
1319 sc->sc_link++;
1320 if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
1321 url_start(ifp);
1322 }
1323 }
1324
1325 callout_reset(&sc->sc_stat_ch, hz, url_tick, sc);
1326
1327 splx(s);
1328 }
1329
1330 /* Get exclusive access to the MII registers */
1331 Static void
1332 url_lock_mii(struct url_softc *sc)
1333 {
1334 DPRINTFN(0xff, ("%s: %s: enter\n", device_xname(sc->sc_dev),
1335 __func__));
1336
1337 sc->sc_refcnt++;
1338 rw_enter(&sc->sc_mii_rwlock, RW_WRITER);
1339 }
1340
1341 Static void
1342 url_unlock_mii(struct url_softc *sc)
1343 {
1344 DPRINTFN(0xff, ("%s: %s: enter\n", device_xname(sc->sc_dev),
1345 __func__));
1346
1347 rw_exit(&sc->sc_mii_rwlock);
1348 if (--sc->sc_refcnt < 0)
1349 usb_detach_wakeup(sc->sc_dev);
1350 }
1351
1352 Static int
1353 url_int_miibus_readreg(device_t dev, int phy, int reg)
1354 {
1355 struct url_softc *sc;
1356 u_int16_t val;
1357
1358 if (dev == NULL)
1359 return (0);
1360
1361 sc = device_private(dev);
1362
1363 DPRINTFN(0xff, ("%s: %s: enter, phy=%d reg=0x%04x\n",
1364 device_xname(sc->sc_dev), __func__, phy, reg));
1365
1366 if (sc->sc_dying) {
1367 #ifdef DIAGNOSTIC
1368 printf("%s: %s: dying\n", device_xname(sc->sc_dev),
1369 __func__);
1370 #endif
1371 return (0);
1372 }
1373
1374 /* XXX: one PHY only for the RTL8150 internal PHY */
1375 if (phy != 0) {
1376 DPRINTFN(0xff, ("%s: %s: phy=%d is not supported\n",
1377 device_xname(sc->sc_dev), __func__, phy));
1378 return (0);
1379 }
1380
1381 url_lock_mii(sc);
1382
1383 switch (reg) {
1384 case MII_BMCR: /* Control Register */
1385 reg = URL_BMCR;
1386 break;
1387 case MII_BMSR: /* Status Register */
1388 reg = URL_BMSR;
1389 break;
1390 case MII_PHYIDR1:
1391 case MII_PHYIDR2:
1392 val = 0;
1393 goto R_DONE;
1394 break;
1395 case MII_ANAR: /* Autonegotiation advertisement */
1396 reg = URL_ANAR;
1397 break;
1398 case MII_ANLPAR: /* Autonegotiation link partner abilities */
1399 reg = URL_ANLP;
1400 break;
1401 case URLPHY_MSR: /* Media Status Register */
1402 reg = URL_MSR;
1403 break;
1404 default:
1405 printf("%s: %s: bad register %04x\n",
1406 device_xname(sc->sc_dev), __func__, reg);
1407 val = 0;
1408 goto R_DONE;
1409 break;
1410 }
1411
1412 if (reg == URL_MSR)
1413 val = url_csr_read_1(sc, reg);
1414 else
1415 val = url_csr_read_2(sc, reg);
1416
1417 R_DONE:
1418 DPRINTFN(0xff, ("%s: %s: phy=%d reg=0x%04x => 0x%04x\n",
1419 device_xname(sc->sc_dev), __func__, phy, reg, val));
1420
1421 url_unlock_mii(sc);
1422 return (val);
1423 }
1424
1425 Static void
1426 url_int_miibus_writereg(device_t dev, int phy, int reg, int data)
1427 {
1428 struct url_softc *sc;
1429
1430 if (dev == NULL)
1431 return;
1432
1433 sc = device_private(dev);
1434
1435 DPRINTFN(0xff, ("%s: %s: enter, phy=%d reg=0x%04x data=0x%04x\n",
1436 device_xname(sc->sc_dev), __func__, phy, reg, data));
1437
1438 if (sc->sc_dying) {
1439 #ifdef DIAGNOSTIC
1440 printf("%s: %s: dying\n", device_xname(sc->sc_dev),
1441 __func__);
1442 #endif
1443 return;
1444 }
1445
1446 /* XXX: one PHY only for the RTL8150 internal PHY */
1447 if (phy != 0) {
1448 DPRINTFN(0xff, ("%s: %s: phy=%d is not supported\n",
1449 device_xname(sc->sc_dev), __func__, phy));
1450 return;
1451 }
1452
1453 url_lock_mii(sc);
1454
1455 switch (reg) {
1456 case MII_BMCR: /* Control Register */
1457 reg = URL_BMCR;
1458 break;
1459 case MII_BMSR: /* Status Register */
1460 reg = URL_BMSR;
1461 break;
1462 case MII_PHYIDR1:
1463 case MII_PHYIDR2:
1464 goto W_DONE;
1465 break;
1466 case MII_ANAR: /* Autonegotiation advertisement */
1467 reg = URL_ANAR;
1468 break;
1469 case MII_ANLPAR: /* Autonegotiation link partner abilities */
1470 reg = URL_ANLP;
1471 break;
1472 case URLPHY_MSR: /* Media Status Register */
1473 reg = URL_MSR;
1474 break;
1475 default:
1476 printf("%s: %s: bad register %04x\n",
1477 device_xname(sc->sc_dev), __func__, reg);
1478 goto W_DONE;
1479 break;
1480 }
1481
1482 if (reg == URL_MSR)
1483 url_csr_write_1(sc, reg, data);
1484 else
1485 url_csr_write_2(sc, reg, data);
1486 W_DONE:
1487
1488 url_unlock_mii(sc);
1489 return;
1490 }
1491
1492 Static void
1493 url_miibus_statchg(device_t dev)
1494 {
1495 #ifdef URL_DEBUG
1496 struct url_softc *sc;
1497
1498 if (dev == NULL)
1499 return;
1500
1501 sc = device_private(dev);
1502 DPRINTF(("%s: %s: enter\n", device_xname(sc->sc_dev), __func__));
1503 #endif
1504 /* Nothing to do */
1505 }
1506
1507 #if 0
1508 /*
1509 * external PHYs support, but not test.
1510 */
1511 Static int
1512 url_ext_miibus_redreg(device_t dev, int phy, int reg)
1513 {
1514 struct url_softc *sc = device_private(dev);
1515 u_int16_t val;
1516
1517 DPRINTF(("%s: %s: enter, phy=%d reg=0x%04x\n",
1518 device_xname(sc->sc_dev), __func__, phy, reg));
1519
1520 if (sc->sc_dying) {
1521 #ifdef DIAGNOSTIC
1522 printf("%s: %s: dying\n", device_xname(sc->sc_dev),
1523 __func__);
1524 #endif
1525 return (0);
1526 }
1527
1528 url_lock_mii(sc);
1529
1530 url_csr_write_1(sc, URL_PHYADD, phy & URL_PHYADD_MASK);
1531 /*
1532 * RTL8150L will initiate a MII management data transaction
1533 * if PHYCNT_OWN bit is set 1 by software. After transaction,
1534 * this bit is auto cleared by TRL8150L.
1535 */
1536 url_csr_write_1(sc, URL_PHYCNT,
1537 (reg | URL_PHYCNT_PHYOWN) & ~URL_PHYCNT_RWCR);
1538 for (i = 0; i < URL_TIMEOUT; i++) {
1539 if ((url_csr_read_1(sc, URL_PHYCNT) & URL_PHYCNT_PHYOWN) == 0)
1540 break;
1541 }
1542 if (i == URL_TIMEOUT) {
1543 printf("%s: MII read timed out\n", device_xname(sc->sc_dev));
1544 }
1545
1546 val = url_csr_read_2(sc, URL_PHYDAT);
1547
1548 DPRINTF(("%s: %s: phy=%d reg=0x%04x => 0x%04x\n",
1549 device_xname(sc->sc_dev), __func__, phy, reg, val));
1550
1551 url_unlock_mii(sc);
1552 return (val);
1553 }
1554
1555 Static void
1556 url_ext_miibus_writereg(device_t dev, int phy, int reg, int data)
1557 {
1558 struct url_softc *sc = device_private(dev);
1559
1560 DPRINTF(("%s: %s: enter, phy=%d reg=0x%04x data=0x%04x\n",
1561 device_xname(sc->sc_dev), __func__, phy, reg, data));
1562
1563 if (sc->sc_dying) {
1564 #ifdef DIAGNOSTIC
1565 printf("%s: %s: dying\n", device_xname(sc->sc_dev),
1566 __func__);
1567 #endif
1568 return;
1569 }
1570
1571 url_lock_mii(sc);
1572
1573 url_csr_write_2(sc, URL_PHYDAT, data);
1574 url_csr_write_1(sc, URL_PHYADD, phy);
1575 url_csr_write_1(sc, URL_PHYCNT, reg | URL_PHYCNT_RWCR); /* Write */
1576
1577 for (i=0; i < URL_TIMEOUT; i++) {
1578 if (url_csr_read_1(sc, URL_PHYCNT) & URL_PHYCNT_PHYOWN)
1579 break;
1580 }
1581
1582 if (i == URL_TIMEOUT) {
1583 printf("%s: MII write timed out\n",
1584 device_xname(sc->sc_dev));
1585 }
1586
1587 url_unlock_mii(sc);
1588 return;
1589 }
1590 #endif
1591
1592