1 /* $NetBSD: if_url.c,v 1.34 2009/09/23 19:07:19 plunky Exp $ */
3 * Copyright (c) 2001, 2002
4 * Shingo WATANABE <nabe@nabechan.org>. All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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.
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
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
40 * Interrupt Endpoint support
42 * powerhook() support?
45 #include <sys/cdefs.h>
46 __KERNEL_RCSID(0, "$NetBSD: if_url.c,v 1.34 2009/09/23 19:07:19 plunky Exp $");
52 #include <sys/param.h>
53 #include <sys/systm.h>
54 #include <sys/rwlock.h>
56 #include <sys/kernel.h>
57 #include <sys/socket.h>
59 #include <sys/device.h>
65 #include <net/if_arp.h>
66 #include <net/if_dl.h>
67 #include <net/if_media.h>
72 #define BPF_MTAP(ifp, m) bpf_mtap((ifp)->if_bpf, (m))
74 #include <net/if_ether.h>
76 #include <netinet/in.h>
77 #include <netinet/if_inarp.h>
80 #include <dev/mii/mii.h>
81 #include <dev/mii/miivar.h>
82 #include <dev/mii/urlphyreg.h>
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>
89 #include <dev/usb/if_urlreg.h>
92 /* Function declarations */
93 USB_DECLARE_DRIVER(url
);
95 Static
int url_openpipes(struct url_softc
*);
96 Static
int url_rx_list_init(struct url_softc
*);
97 Static
int url_tx_list_init(struct url_softc
*);
98 Static
int url_newbuf(struct url_softc
*, struct url_chain
*, struct mbuf
*);
99 Static
void url_start(struct ifnet
*);
100 Static
int url_send(struct url_softc
*, struct mbuf
*, int);
101 Static
void url_txeof(usbd_xfer_handle
, usbd_private_handle
, usbd_status
);
102 Static
void url_rxeof(usbd_xfer_handle
, usbd_private_handle
, usbd_status
);
103 Static
void url_tick(void *);
104 Static
void url_tick_task(void *);
105 Static
int url_ioctl(struct ifnet
*, u_long
, void *);
106 Static
void url_stop_task(struct url_softc
*);
107 Static
void url_stop(struct ifnet
*, int);
108 Static
void url_watchdog(struct ifnet
*);
109 Static
int url_ifmedia_change(struct ifnet
*);
110 Static
void url_ifmedia_status(struct ifnet
*, struct ifmediareq
*);
111 Static
void url_lock_mii(struct url_softc
*);
112 Static
void url_unlock_mii(struct url_softc
*);
113 Static
int url_int_miibus_readreg(device_ptr_t
, int, int);
114 Static
void url_int_miibus_writereg(device_ptr_t
, int, int, int);
115 Static
void url_miibus_statchg(device_ptr_t
);
116 Static
int url_init(struct ifnet
*);
117 Static
void url_setmulti(struct url_softc
*);
118 Static
void url_reset(struct url_softc
*);
120 Static
int url_csr_read_1(struct url_softc
*, int);
121 Static
int url_csr_read_2(struct url_softc
*, int);
122 Static
int url_csr_write_1(struct url_softc
*, int, int);
123 Static
int url_csr_write_2(struct url_softc
*, int, int);
124 Static
int url_csr_write_4(struct url_softc
*, int, int);
125 Static
int url_mem(struct url_softc
*, int, int, void *, int);
129 #define DPRINTF(x) if (urldebug) logprintf x
130 #define DPRINTFN(n,x) if (urldebug >= (n)) logprintf x
134 #define DPRINTFN(n,x)
137 #define URL_SETBIT(sc, reg, x) \
138 url_csr_write_1(sc, reg, url_csr_read_1(sc, reg) | (x))
140 #define URL_SETBIT2(sc, reg, x) \
141 url_csr_write_2(sc, reg, url_csr_read_2(sc, reg) | (x))
143 #define URL_CLRBIT(sc, reg, x) \
144 url_csr_write_1(sc, reg, url_csr_read_1(sc, reg) & ~(x))
146 #define URL_CLRBIT2(sc, reg, x) \
147 url_csr_write_2(sc, reg, url_csr_read_2(sc, reg) & ~(x))
149 static const struct url_type
{
150 struct usb_devno url_dev
;
152 #define URL_EXT_PHY 0x0001
155 {{ USB_VENDOR_MELCO
, USB_PRODUCT_MELCO_LUAKTX
}, 0},
156 /* Realtek RTL8150L Generic (GREEN HOUSE USBKR100) */
157 {{ USB_VENDOR_REALTEK
, USB_PRODUCT_REALTEK_RTL8150L
}, 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},
163 {{ USB_VENDOR_OQO
, USB_PRODUCT_OQO_ETHER01
}, 0},
165 #define url_lookup(v, p) ((const struct url_type *)usb_lookup(url_devs, v, p))
171 USB_MATCH_START(url
, uaa
);
173 return (url_lookup(uaa
->vendor
, uaa
->product
) != NULL
?
174 UMATCH_VENDOR_PRODUCT
: UMATCH_NONE
);
179 USB_ATTACH_START(url
, sc
, uaa
);
180 usbd_device_handle dev
= uaa
->device
;
181 usbd_interface_handle iface
;
183 usb_interface_descriptor_t
*id
;
184 usb_endpoint_descriptor_t
*ed
;
187 struct mii_data
*mii
;
188 u_char eaddr
[ETHER_ADDR_LEN
];
196 devinfop
= usbd_devinfo_alloc(dev
, 0);
197 aprint_normal_dev(self
, "%s\n", devinfop
);
198 usbd_devinfo_free(devinfop
);
200 /* Move the device into the configured state. */
201 err
= usbd_set_config_no(dev
, URL_CONFIG_NO
, 1);
203 aprint_error_dev(self
, "setting config no failed\n");
207 usb_init_task(&sc
->sc_tick_task
, url_tick_task
, sc
);
208 rw_init(&sc
->sc_mii_rwlock
);
209 usb_init_task(&sc
->sc_stop_task
, (void (*)(void *)) url_stop_task
, sc
);
211 /* get control interface */
212 err
= usbd_device2interface_handle(dev
, URL_IFACE_INDEX
, &iface
);
214 aprint_error_dev(self
, "failed to get interface, err=%s\n",
220 sc
->sc_ctl_iface
= iface
;
221 sc
->sc_flags
= url_lookup(uaa
->vendor
, uaa
->product
)->url_flags
;
223 /* get interface descriptor */
224 id
= usbd_get_interface_descriptor(sc
->sc_ctl_iface
);
227 sc
->sc_bulkin_no
= sc
->sc_bulkout_no
= sc
->sc_intrin_no
= -1;
228 for (i
= 0; i
< id
->bNumEndpoints
; i
++) {
229 ed
= usbd_interface2endpoint_descriptor(sc
->sc_ctl_iface
, i
);
231 aprint_error_dev(self
,
232 "couldn't get endpoint %d\n", i
);
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 */
246 if (sc
->sc_bulkin_no
== -1 || sc
->sc_bulkout_no
== -1 ||
247 sc
->sc_intrin_no
== -1) {
248 aprint_error_dev(self
, "missing endpoint\n");
254 /* reset the adapter */
257 /* Get Ethernet Address */
258 err
= url_mem(sc
, URL_CMD_READMEM
, URL_IDR0
, (void *)eaddr
,
261 aprint_error_dev(self
, "read MAC address failed\n");
266 /* Print Ethernet Address */
267 aprint_normal_dev(self
, "Ethernet address %s\n", ether_sprintf(eaddr
));
269 /* initialize interface information */
272 ifp
->if_mtu
= ETHERMTU
;
273 strncpy(ifp
->if_xname
, device_xname(self
), 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
;
281 IFQ_SET_READY(&ifp
->if_snd
);
288 mii
->mii_readreg
= url_int_miibus_readreg
;
289 mii
->mii_writereg
= url_int_miibus_writereg
;
291 if (sc
->sc_flags
& URL_EXT_PHY
) {
292 mii
->mii_readreg
= url_ext_miibus_readreg
;
293 mii
->mii_writereg
= url_ext_miibus_writereg
;
296 mii
->mii_statchg
= url_miibus_statchg
;
297 mii
->mii_flags
= MIIF_AUTOTSLEEP
;
298 sc
->sc_ec
.ec_mii
= mii
;
299 ifmedia_init(&mii
->mii_media
, 0,
300 url_ifmedia_change
, url_ifmedia_status
);
301 mii_attach(self
, mii
, 0xffffffff, MII_PHY_ANY
, MII_OFFSET_ANY
, 0);
302 if (LIST_FIRST(&mii
->mii_phys
) == NULL
) {
303 ifmedia_add(&mii
->mii_media
, IFM_ETHER
| IFM_NONE
, 0, NULL
);
304 ifmedia_set(&mii
->mii_media
, IFM_ETHER
| IFM_NONE
);
306 ifmedia_set(&mii
->mii_media
, IFM_ETHER
| IFM_AUTO
);
308 /* attach the interface */
310 Ether_ifattach(ifp
, eaddr
);
313 rnd_attach_source(&sc
->rnd_source
, device_xname(self
),
317 usb_callout_init(sc
->sc_stat_ch
);
321 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH
, dev
, USBDEV(sc
->sc_dev
));
323 USB_ATTACH_SUCCESS_RETURN
;
327 USB_ATTACH_ERROR_RETURN
;
333 USB_DETACH_START(url
, sc
);
334 struct ifnet
*ifp
= GET_IFP(sc
);
337 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc
->sc_dev
), __func__
));
339 /* Detached before attached finished */
340 if (!sc
->sc_attached
)
343 usb_uncallout(sc
->sc_stat_ch
, url_tick
, sc
);
345 /* Remove any pending tasks */
346 usb_rem_task(sc
->sc_udev
, &sc
->sc_tick_task
);
347 usb_rem_task(sc
->sc_udev
, &sc
->sc_stop_task
);
351 if (--sc
->sc_refcnt
>= 0) {
352 /* Wait for processes to go away */
353 usb_detach_wait(USBDEV(sc
->sc_dev
));
356 if (ifp
->if_flags
& IFF_RUNNING
)
357 url_stop(GET_IFP(sc
), 1);
360 rnd_detach_source(&sc
->rnd_source
);
362 mii_detach(&sc
->sc_mii
, MII_PHY_ANY
, MII_OFFSET_ANY
);
363 ifmedia_delete_instance(&sc
->sc_mii
.mii_media
, IFM_INST_ANY
);
368 if (sc
->sc_pipe_tx
!= NULL
)
369 aprint_debug_dev(self
, "detach has active tx endpoint.\n");
370 if (sc
->sc_pipe_rx
!= NULL
)
371 aprint_debug_dev(self
, "detach has active rx endpoint.\n");
372 if (sc
->sc_pipe_intr
!= NULL
)
373 aprint_debug_dev(self
, "detach has active intr endpoint.\n");
380 rw_destroy(&sc
->sc_mii_rwlock
);
381 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH
, sc
->sc_udev
,
387 /* read/write memory */
389 url_mem(struct url_softc
*sc
, int cmd
, int offset
, void *buf
, int len
)
391 usb_device_request_t req
;
398 ("%s: %s: enter\n", USBDEVNAME(sc
->sc_dev
), __func__
));
403 if (cmd
== URL_CMD_READMEM
)
404 req
.bmRequestType
= UT_READ_VENDOR_DEVICE
;
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
);
413 err
= usbd_do_request(sc
->sc_udev
, &req
, buf
);
414 if (--sc
->sc_refcnt
< 0)
415 usb_detach_wakeup(USBDEV(sc
->sc_dev
));
417 DPRINTF(("%s: url_mem(): %s failed. off=%04x, err=%d\n",
418 USBDEVNAME(sc
->sc_dev
),
419 cmd
== URL_CMD_READMEM
? "read" : "write",
426 /* read 1byte from register */
428 url_csr_read_1(struct url_softc
*sc
, int reg
)
433 ("%s: %s: enter\n", USBDEVNAME(sc
->sc_dev
), __func__
));
438 return (url_mem(sc
, URL_CMD_READMEM
, reg
, &val
, 1) ? 0 : val
);
441 /* read 2bytes from register */
443 url_csr_read_2(struct url_softc
*sc
, int reg
)
448 ("%s: %s: enter\n", USBDEVNAME(sc
->sc_dev
), __func__
));
454 return (url_mem(sc
, URL_CMD_READMEM
, reg
, &val
, 2) ? 0 : UGETW(val
));
457 /* write 1byte to register */
459 url_csr_write_1(struct url_softc
*sc
, int reg
, int aval
)
464 ("%s: %s: enter\n", USBDEVNAME(sc
->sc_dev
), __func__
));
469 return (url_mem(sc
, URL_CMD_WRITEMEM
, reg
, &val
, 1) ? -1 : 0);
472 /* write 2bytes to register */
474 url_csr_write_2(struct url_softc
*sc
, int reg
, int aval
)
479 ("%s: %s: enter\n", USBDEVNAME(sc
->sc_dev
), __func__
));
486 return (url_mem(sc
, URL_CMD_WRITEMEM
, reg
, &val
, 2) ? -1 : 0);
489 /* write 4bytes to register */
491 url_csr_write_4(struct url_softc
*sc
, int reg
, int aval
)
496 ("%s: %s: enter\n", USBDEVNAME(sc
->sc_dev
), __func__
));
503 return (url_mem(sc
, URL_CMD_WRITEMEM
, reg
, &val
, 4) ? -1 : 0);
507 url_init(struct ifnet
*ifp
)
509 struct url_softc
*sc
= ifp
->if_softc
;
510 struct mii_data
*mii
= GET_MII(sc
);
514 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc
->sc_dev
), __func__
));
521 /* Cancel pending I/O and free all TX/RX buffers */
524 eaddr
= CLLADDR(ifp
->if_sadl
);
525 for (i
= 0; i
< ETHER_ADDR_LEN
; i
++)
526 url_csr_write_1(sc
, URL_IDR0
+ i
, eaddr
[i
]);
528 /* Init transmission control register */
529 URL_CLRBIT(sc
, URL_TCR
,
530 URL_TCR_TXRR1
| URL_TCR_TXRR0
|
531 URL_TCR_IFG1
| URL_TCR_IFG0
|
534 /* Init receive control register */
535 URL_SETBIT2(sc
, URL_RCR
, URL_RCR_TAIL
| URL_RCR_AD
);
536 if (ifp
->if_flags
& IFF_BROADCAST
)
537 URL_SETBIT2(sc
, URL_RCR
, URL_RCR_AB
);
539 URL_CLRBIT2(sc
, URL_RCR
, URL_RCR_AB
);
541 /* If we want promiscuous mode, accept all physical frames. */
542 if (ifp
->if_flags
& IFF_PROMISC
)
543 URL_SETBIT2(sc
, URL_RCR
, URL_RCR_AAM
|URL_RCR_AAP
);
545 URL_CLRBIT2(sc
, URL_RCR
, URL_RCR_AAM
|URL_RCR_AAP
);
548 /* Initialize transmit ring */
549 if (url_tx_list_init(sc
) == ENOBUFS
) {
550 printf("%s: tx list init failed\n", USBDEVNAME(sc
->sc_dev
));
555 /* Initialize receive ring */
556 if (url_rx_list_init(sc
) == ENOBUFS
) {
557 printf("%s: rx list init failed\n", USBDEVNAME(sc
->sc_dev
));
562 /* Load the multicast filter */
565 /* Enable RX and TX */
566 URL_SETBIT(sc
, URL_CR
, URL_CR_TE
| URL_CR_RE
);
568 if ((rc
= mii_mediachg(mii
)) == ENXIO
)
573 if (sc
->sc_pipe_tx
== NULL
|| sc
->sc_pipe_rx
== NULL
) {
574 if (url_openpipes(sc
)) {
580 ifp
->if_flags
|= IFF_RUNNING
;
581 ifp
->if_flags
&= ~IFF_OACTIVE
;
583 usb_callout(sc
->sc_stat_ch
, hz
, url_tick
, sc
);
591 url_reset(struct url_softc
*sc
)
595 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc
->sc_dev
), __func__
));
600 URL_SETBIT(sc
, URL_CR
, URL_CR_SOFT_RST
);
602 for (i
= 0; i
< URL_TX_TIMEOUT
; i
++) {
603 if (!(url_csr_read_1(sc
, URL_CR
) & URL_CR_SOFT_RST
))
608 delay(10000); /* XXX */
612 url_activate(device_ptr_t self
, enum devact act
)
614 struct url_softc
*sc
= device_private(self
);
616 DPRINTF(("%s: %s: enter, act=%d\n", USBDEVNAME(sc
->sc_dev
),
620 case DVACT_DEACTIVATE
:
621 if_deactivate(&sc
->sc_ec
.ec_if
);
629 #define url_calchash(addr) (ether_crc32_be((addr), ETHER_ADDR_LEN) >> 26)
633 url_setmulti(struct url_softc
*sc
)
636 struct ether_multi
*enm
;
637 struct ether_multistep step
;
638 u_int32_t hashes
[2] = { 0, 0 };
642 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc
->sc_dev
), __func__
));
649 if (ifp
->if_flags
& IFF_PROMISC
) {
650 URL_SETBIT2(sc
, URL_RCR
, URL_RCR_AAM
|URL_RCR_AAP
);
652 } else if (ifp
->if_flags
& IFF_ALLMULTI
) {
654 ifp
->if_flags
|= IFF_ALLMULTI
;
655 URL_SETBIT2(sc
, URL_RCR
, URL_RCR_AAM
);
656 URL_CLRBIT2(sc
, URL_RCR
, URL_RCR_AAP
);
660 /* first, zot all the existing hash bits */
661 url_csr_write_4(sc
, URL_MAR0
, 0);
662 url_csr_write_4(sc
, URL_MAR4
, 0);
664 /* now program new ones */
665 ETHER_FIRST_MULTI(step
, &sc
->sc_ec
, enm
);
666 while (enm
!= NULL
) {
667 if (memcmp(enm
->enm_addrlo
, enm
->enm_addrhi
,
668 ETHER_ADDR_LEN
) != 0)
671 h
= url_calchash(enm
->enm_addrlo
);
673 hashes
[0] |= (1 << h
);
675 hashes
[1] |= (1 << (h
-32));
677 ETHER_NEXT_MULTI(step
, enm
);
680 ifp
->if_flags
&= ~IFF_ALLMULTI
;
682 URL_CLRBIT2(sc
, URL_RCR
, URL_RCR_AAM
|URL_RCR_AAP
);
685 URL_SETBIT2(sc
, URL_RCR
, URL_RCR_AM
);
687 URL_CLRBIT2(sc
, URL_RCR
, URL_RCR_AM
);
689 url_csr_write_4(sc
, URL_MAR0
, hashes
[0]);
690 url_csr_write_4(sc
, URL_MAR4
, hashes
[1]);
694 url_openpipes(struct url_softc
*sc
)
707 err
= usbd_open_pipe(sc
->sc_ctl_iface
, sc
->sc_bulkin_no
,
708 USBD_EXCLUSIVE_USE
, &sc
->sc_pipe_rx
);
710 printf("%s: open rx pipe failed: %s\n",
711 USBDEVNAME(sc
->sc_dev
), usbd_errstr(err
));
717 err
= usbd_open_pipe(sc
->sc_ctl_iface
, sc
->sc_bulkout_no
,
718 USBD_EXCLUSIVE_USE
, &sc
->sc_pipe_tx
);
720 printf("%s: open tx pipe failed: %s\n",
721 USBDEVNAME(sc
->sc_dev
), usbd_errstr(err
));
727 /* XXX: interrupt endpoint is not yet supported */
728 /* Open Interrupt pipe */
729 err
= usbd_open_pipe_intr(sc
->sc_ctl_iface
, sc
->sc_intrin_no
,
730 USBD_EXCLUSIVE_USE
, &sc
->sc_pipe_intr
, sc
,
731 &sc
->sc_cdata
.url_ibuf
, URL_INTR_PKGLEN
,
732 url_intr
, USBD_DEFAULT_INTERVAL
);
734 printf("%s: open intr pipe failed: %s\n",
735 USBDEVNAME(sc
->sc_dev
), usbd_errstr(err
));
742 /* Start up the receive pipe. */
743 for (i
= 0; i
< URL_RX_LIST_CNT
; i
++) {
744 c
= &sc
->sc_cdata
.url_rx_chain
[i
];
745 usbd_setup_xfer(c
->url_xfer
, sc
->sc_pipe_rx
,
746 c
, c
->url_buf
, URL_BUFSZ
,
747 USBD_SHORT_XFER_OK
| USBD_NO_COPY
,
748 USBD_NO_TIMEOUT
, url_rxeof
);
749 (void)usbd_transfer(c
->url_xfer
);
750 DPRINTF(("%s: %s: start read\n", USBDEVNAME(sc
->sc_dev
),
755 if (--sc
->sc_refcnt
< 0)
756 usb_detach_wakeup(USBDEV(sc
->sc_dev
));
762 url_newbuf(struct url_softc
*sc
, struct url_chain
*c
, struct mbuf
*m
)
764 struct mbuf
*m_new
= NULL
;
766 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc
->sc_dev
), __func__
));
769 MGETHDR(m_new
, M_DONTWAIT
, MT_DATA
);
771 printf("%s: no memory for rx list "
772 "-- packet dropped!\n", USBDEVNAME(sc
->sc_dev
));
775 MCLGET(m_new
, M_DONTWAIT
);
776 if (!(m_new
->m_flags
& M_EXT
)) {
777 printf("%s: no memory for rx list "
778 "-- packet dropped!\n", USBDEVNAME(sc
->sc_dev
));
782 m_new
->m_len
= m_new
->m_pkthdr
.len
= MCLBYTES
;
785 m_new
->m_len
= m_new
->m_pkthdr
.len
= MCLBYTES
;
786 m_new
->m_data
= m_new
->m_ext
.ext_buf
;
789 m_adj(m_new
, ETHER_ALIGN
);
797 url_rx_list_init(struct url_softc
*sc
)
799 struct url_cdata
*cd
;
803 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc
->sc_dev
), __func__
));
806 for (i
= 0; i
< URL_RX_LIST_CNT
; i
++) {
807 c
= &cd
->url_rx_chain
[i
];
810 if (url_newbuf(sc
, c
, NULL
) == ENOBUFS
)
812 if (c
->url_xfer
== NULL
) {
813 c
->url_xfer
= usbd_alloc_xfer(sc
->sc_udev
);
814 if (c
->url_xfer
== NULL
)
816 c
->url_buf
= usbd_alloc_buffer(c
->url_xfer
, URL_BUFSZ
);
817 if (c
->url_buf
== NULL
) {
818 usbd_free_xfer(c
->url_xfer
);
828 url_tx_list_init(struct url_softc
*sc
)
830 struct url_cdata
*cd
;
834 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc
->sc_dev
), __func__
));
837 for (i
= 0; i
< URL_TX_LIST_CNT
; i
++) {
838 c
= &cd
->url_tx_chain
[i
];
842 if (c
->url_xfer
== NULL
) {
843 c
->url_xfer
= usbd_alloc_xfer(sc
->sc_udev
);
844 if (c
->url_xfer
== NULL
)
846 c
->url_buf
= usbd_alloc_buffer(c
->url_xfer
, URL_BUFSZ
);
847 if (c
->url_buf
== NULL
) {
848 usbd_free_xfer(c
->url_xfer
);
858 url_start(struct ifnet
*ifp
)
860 struct url_softc
*sc
= ifp
->if_softc
;
861 struct mbuf
*m_head
= NULL
;
863 DPRINTF(("%s: %s: enter, link=%d\n", USBDEVNAME(sc
->sc_dev
),
864 __func__
, sc
->sc_link
));
872 if (ifp
->if_flags
& IFF_OACTIVE
)
875 IFQ_POLL(&ifp
->if_snd
, m_head
);
879 if (url_send(sc
, m_head
, 0)) {
880 ifp
->if_flags
|= IFF_OACTIVE
;
884 IFQ_DEQUEUE(&ifp
->if_snd
, m_head
);
888 bpf_mtap(ifp
->if_bpf
, m_head
);
891 ifp
->if_flags
|= IFF_OACTIVE
;
893 /* Set a timeout in case the chip goes out to lunch. */
898 url_send(struct url_softc
*sc
, struct mbuf
*m
, int idx
)
904 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc
->sc_dev
),__func__
));
906 c
= &sc
->sc_cdata
.url_tx_chain
[idx
];
908 /* Copy the mbuf data into a contiguous buffer */
909 m_copydata(m
, 0, m
->m_pkthdr
.len
, c
->url_buf
);
911 total_len
= m
->m_pkthdr
.len
;
913 if (total_len
< URL_MIN_FRAME_LEN
) {
914 memset(c
->url_buf
+ total_len
, 0,
915 URL_MIN_FRAME_LEN
- total_len
);
916 total_len
= URL_MIN_FRAME_LEN
;
918 usbd_setup_xfer(c
->url_xfer
, sc
->sc_pipe_tx
, c
, c
->url_buf
, total_len
,
919 USBD_FORCE_SHORT_XFER
| USBD_NO_COPY
,
920 URL_TX_TIMEOUT
, url_txeof
);
924 err
= usbd_transfer(c
->url_xfer
);
925 if (--sc
->sc_refcnt
< 0)
926 usb_detach_wakeup(USBDEV(sc
->sc_dev
));
927 if (err
!= USBD_IN_PROGRESS
) {
928 printf("%s: url_send error=%s\n", USBDEVNAME(sc
->sc_dev
),
930 /* Stop the interface */
931 usb_add_task(sc
->sc_udev
, &sc
->sc_stop_task
,
936 DPRINTF(("%s: %s: send %d bytes\n", USBDEVNAME(sc
->sc_dev
),
937 __func__
, total_len
));
939 sc
->sc_cdata
.url_tx_cnt
++;
945 url_txeof(usbd_xfer_handle xfer
, usbd_private_handle priv
,
948 struct url_chain
*c
= priv
;
949 struct url_softc
*sc
= c
->url_sc
;
950 struct ifnet
*ifp
= GET_IFP(sc
);
958 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc
->sc_dev
), __func__
));
961 ifp
->if_flags
&= ~IFF_OACTIVE
;
963 if (status
!= USBD_NORMAL_COMPLETION
) {
964 if (status
== USBD_NOT_STARTED
|| status
== USBD_CANCELLED
) {
969 printf("%s: usb error on tx: %s\n", USBDEVNAME(sc
->sc_dev
),
970 usbd_errstr(status
));
971 if (status
== USBD_STALLED
) {
973 usbd_clear_endpoint_stall_async(sc
->sc_pipe_tx
);
974 if (--sc
->sc_refcnt
< 0)
975 usb_detach_wakeup(USBDEV(sc
->sc_dev
));
983 m_freem(c
->url_mbuf
);
986 if (IFQ_IS_EMPTY(&ifp
->if_snd
) == 0)
993 url_rxeof(usbd_xfer_handle xfer
, usbd_private_handle priv
, usbd_status status
)
995 struct url_chain
*c
= priv
;
996 struct url_softc
*sc
= c
->url_sc
;
997 struct ifnet
*ifp
= GET_IFP(sc
);
1003 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc
->sc_dev
),__func__
));
1008 if (status
!= USBD_NORMAL_COMPLETION
) {
1009 if (status
== USBD_NOT_STARTED
|| status
== USBD_CANCELLED
)
1012 if (usbd_ratecheck(&sc
->sc_rx_notice
)) {
1013 printf("%s: %u usb errors on rx: %s\n",
1014 USBDEVNAME(sc
->sc_dev
), sc
->sc_rx_errs
,
1015 usbd_errstr(status
));
1018 if (status
== USBD_STALLED
) {
1020 usbd_clear_endpoint_stall_async(sc
->sc_pipe_rx
);
1021 if (--sc
->sc_refcnt
< 0)
1022 usb_detach_wakeup(USBDEV(sc
->sc_dev
));
1027 usbd_get_xfer_status(xfer
, NULL
, NULL
, &total_len
, NULL
);
1029 memcpy(mtod(c
->url_mbuf
, char *), c
->url_buf
, total_len
);
1031 if (total_len
<= ETHER_CRC_LEN
) {
1036 memcpy(&rxhdr
, c
->url_buf
+ total_len
- ETHER_CRC_LEN
, sizeof(rxhdr
));
1038 DPRINTF(("%s: RX Status: %dbytes%s%s%s%s packets\n",
1039 USBDEVNAME(sc
->sc_dev
),
1040 UGETW(rxhdr
) & URL_RXHDR_BYTEC_MASK
,
1041 UGETW(rxhdr
) & URL_RXHDR_VALID_MASK
? ", Valid" : "",
1042 UGETW(rxhdr
) & URL_RXHDR_RUNTPKT_MASK
? ", Runt" : "",
1043 UGETW(rxhdr
) & URL_RXHDR_PHYPKT_MASK
? ", Physical match" : "",
1044 UGETW(rxhdr
) & URL_RXHDR_MCASTPKT_MASK
? ", Multicast" : ""));
1046 if ((UGETW(rxhdr
) & URL_RXHDR_VALID_MASK
) == 0) {
1052 total_len
-= ETHER_CRC_LEN
;
1055 m
->m_pkthdr
.len
= m
->m_len
= total_len
;
1056 m
->m_pkthdr
.rcvif
= ifp
;
1060 if (url_newbuf(sc
, c
, NULL
) == ENOBUFS
) {
1070 DPRINTF(("%s: %s: deliver %d\n", USBDEVNAME(sc
->sc_dev
),
1071 __func__
, m
->m_len
));
1078 /* Setup new transfer */
1079 usbd_setup_xfer(xfer
, sc
->sc_pipe_rx
, c
, c
->url_buf
, URL_BUFSZ
,
1080 USBD_SHORT_XFER_OK
| USBD_NO_COPY
,
1081 USBD_NO_TIMEOUT
, url_rxeof
);
1083 usbd_transfer(xfer
);
1084 if (--sc
->sc_refcnt
< 0)
1085 usb_detach_wakeup(USBDEV(sc
->sc_dev
));
1087 DPRINTF(("%s: %s: start rx\n", USBDEVNAME(sc
->sc_dev
), __func__
));
1091 Static
void url_intr(void)
1097 url_ioctl(struct ifnet
*ifp
, u_long cmd
, void *data
)
1099 struct url_softc
*sc
= ifp
->if_softc
;
1102 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc
->sc_dev
), __func__
));
1109 error
= ether_ioctl(ifp
, cmd
, data
);
1110 if (error
== ENETRESET
) {
1111 if (ifp
->if_flags
& IFF_RUNNING
)
1122 url_watchdog(struct ifnet
*ifp
)
1124 struct url_softc
*sc
= ifp
->if_softc
;
1125 struct url_chain
*c
;
1129 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc
->sc_dev
), __func__
));
1132 printf("%s: watchdog timeout\n", USBDEVNAME(sc
->sc_dev
));
1135 c
= &sc
->sc_cdata
.url_tx_chain
[0];
1136 usbd_get_xfer_status(c
->url_xfer
, NULL
, NULL
, NULL
, &stat
);
1137 url_txeof(c
->url_xfer
, c
, stat
);
1139 if (IFQ_IS_EMPTY(&ifp
->if_snd
) == 0)
1145 url_stop_task(struct url_softc
*sc
)
1147 url_stop(GET_IFP(sc
), 1);
1150 /* Stop the adapter and free any mbufs allocated to the RX and TX lists. */
1152 url_stop(struct ifnet
*ifp
, int disable
)
1154 struct url_softc
*sc
= ifp
->if_softc
;
1158 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc
->sc_dev
), __func__
));
1164 usb_uncallout(sc
->sc_stat_ch
, url_tick
, sc
);
1166 /* Stop transfers */
1168 if (sc
->sc_pipe_rx
!= NULL
) {
1169 err
= usbd_abort_pipe(sc
->sc_pipe_rx
);
1171 printf("%s: abort rx pipe failed: %s\n",
1172 USBDEVNAME(sc
->sc_dev
), usbd_errstr(err
));
1173 err
= usbd_close_pipe(sc
->sc_pipe_rx
);
1175 printf("%s: close rx pipe failed: %s\n",
1176 USBDEVNAME(sc
->sc_dev
), usbd_errstr(err
));
1177 sc
->sc_pipe_rx
= NULL
;
1181 if (sc
->sc_pipe_tx
!= NULL
) {
1182 err
= usbd_abort_pipe(sc
->sc_pipe_tx
);
1184 printf("%s: abort tx pipe failed: %s\n",
1185 USBDEVNAME(sc
->sc_dev
), usbd_errstr(err
));
1186 err
= usbd_close_pipe(sc
->sc_pipe_tx
);
1188 printf("%s: close tx pipe failed: %s\n",
1189 USBDEVNAME(sc
->sc_dev
), usbd_errstr(err
));
1190 sc
->sc_pipe_tx
= NULL
;
1194 /* XXX: Interrupt endpoint is not yet supported!! */
1195 /* Interrupt endpoint */
1196 if (sc
->sc_pipe_intr
!= NULL
) {
1197 err
= usbd_abort_pipe(sc
->sc_pipe_intr
);
1199 printf("%s: abort intr pipe failed: %s\n",
1200 USBDEVNAME(sc
->sc_dev
), usbd_errstr(err
));
1201 err
= usbd_close_pipe(sc
->sc_pipe_intr
);
1203 printf("%s: close intr pipe failed: %s\n",
1204 USBDEVNAME(sc
->sc_dev
), usbd_errstr(err
));
1205 sc
->sc_pipe_intr
= NULL
;
1209 /* Free RX resources. */
1210 for (i
= 0; i
< URL_RX_LIST_CNT
; i
++) {
1211 if (sc
->sc_cdata
.url_rx_chain
[i
].url_mbuf
!= NULL
) {
1212 m_freem(sc
->sc_cdata
.url_rx_chain
[i
].url_mbuf
);
1213 sc
->sc_cdata
.url_rx_chain
[i
].url_mbuf
= NULL
;
1215 if (sc
->sc_cdata
.url_rx_chain
[i
].url_xfer
!= NULL
) {
1216 usbd_free_xfer(sc
->sc_cdata
.url_rx_chain
[i
].url_xfer
);
1217 sc
->sc_cdata
.url_rx_chain
[i
].url_xfer
= NULL
;
1221 /* Free TX resources. */
1222 for (i
= 0; i
< URL_TX_LIST_CNT
; i
++) {
1223 if (sc
->sc_cdata
.url_tx_chain
[i
].url_mbuf
!= NULL
) {
1224 m_freem(sc
->sc_cdata
.url_tx_chain
[i
].url_mbuf
);
1225 sc
->sc_cdata
.url_tx_chain
[i
].url_mbuf
= NULL
;
1227 if (sc
->sc_cdata
.url_tx_chain
[i
].url_xfer
!= NULL
) {
1228 usbd_free_xfer(sc
->sc_cdata
.url_tx_chain
[i
].url_xfer
);
1229 sc
->sc_cdata
.url_tx_chain
[i
].url_xfer
= NULL
;
1234 ifp
->if_flags
&= ~(IFF_RUNNING
| IFF_OACTIVE
);
1237 /* Set media options */
1239 url_ifmedia_change(struct ifnet
*ifp
)
1241 struct url_softc
*sc
= ifp
->if_softc
;
1242 struct mii_data
*mii
= GET_MII(sc
);
1245 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc
->sc_dev
), __func__
));
1251 if ((rc
= mii_mediachg(mii
)) == ENXIO
)
1256 /* Report current media status. */
1258 url_ifmedia_status(struct ifnet
*ifp
, struct ifmediareq
*ifmr
)
1260 struct url_softc
*sc
= ifp
->if_softc
;
1262 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc
->sc_dev
), __func__
));
1267 ether_mediastatus(ifp
, ifmr
);
1273 struct url_softc
*sc
= xsc
;
1278 DPRINTFN(0xff, ("%s: %s: enter\n", USBDEVNAME(sc
->sc_dev
),
1284 /* Perform periodic stuff in process context */
1285 usb_add_task(sc
->sc_udev
, &sc
->sc_tick_task
, USB_TASKQ_DRIVER
);
1289 url_tick_task(void *xsc
)
1291 struct url_softc
*sc
= xsc
;
1293 struct mii_data
*mii
;
1299 DPRINTFN(0xff, ("%s: %s: enter\n", USBDEVNAME(sc
->sc_dev
),
1316 if (mii
->mii_media_status
& IFM_ACTIVE
&&
1317 IFM_SUBTYPE(mii
->mii_media_active
) != IFM_NONE
) {
1318 DPRINTF(("%s: %s: got link\n",
1319 USBDEVNAME(sc
->sc_dev
), __func__
));
1321 if (IFQ_IS_EMPTY(&ifp
->if_snd
) == 0)
1326 usb_callout(sc
->sc_stat_ch
, hz
, url_tick
, sc
);
1331 /* Get exclusive access to the MII registers */
1333 url_lock_mii(struct url_softc
*sc
)
1335 DPRINTFN(0xff, ("%s: %s: enter\n", USBDEVNAME(sc
->sc_dev
),
1339 rw_enter(&sc
->sc_mii_rwlock
, RW_WRITER
);
1343 url_unlock_mii(struct url_softc
*sc
)
1345 DPRINTFN(0xff, ("%s: %s: enter\n", USBDEVNAME(sc
->sc_dev
),
1348 rw_exit(&sc
->sc_mii_rwlock
);
1349 if (--sc
->sc_refcnt
< 0)
1350 usb_detach_wakeup(USBDEV(sc
->sc_dev
));
1354 url_int_miibus_readreg(device_ptr_t dev
, int phy
, int reg
)
1356 struct url_softc
*sc
;
1362 sc
= USBGETSOFTC(dev
);
1364 DPRINTFN(0xff, ("%s: %s: enter, phy=%d reg=0x%04x\n",
1365 USBDEVNAME(sc
->sc_dev
), __func__
, phy
, reg
));
1369 printf("%s: %s: dying\n", USBDEVNAME(sc
->sc_dev
),
1375 /* XXX: one PHY only for the RTL8150 internal PHY */
1377 DPRINTFN(0xff, ("%s: %s: phy=%d is not supported\n",
1378 USBDEVNAME(sc
->sc_dev
), __func__
, phy
));
1385 case MII_BMCR
: /* Control Register */
1388 case MII_BMSR
: /* Status Register */
1396 case MII_ANAR
: /* Autonegotiation advertisement */
1399 case MII_ANLPAR
: /* Autonegotiation link partner abilities */
1402 case URLPHY_MSR
: /* Media Status Register */
1406 printf("%s: %s: bad register %04x\n",
1407 USBDEVNAME(sc
->sc_dev
), __func__
, reg
);
1414 val
= url_csr_read_1(sc
, reg
);
1416 val
= url_csr_read_2(sc
, reg
);
1419 DPRINTFN(0xff, ("%s: %s: phy=%d reg=0x%04x => 0x%04x\n",
1420 USBDEVNAME(sc
->sc_dev
), __func__
, phy
, reg
, val
));
1427 url_int_miibus_writereg(device_ptr_t dev
, int phy
, int reg
, int data
)
1429 struct url_softc
*sc
;
1434 sc
= USBGETSOFTC(dev
);
1436 DPRINTFN(0xff, ("%s: %s: enter, phy=%d reg=0x%04x data=0x%04x\n",
1437 USBDEVNAME(sc
->sc_dev
), __func__
, phy
, reg
, data
));
1441 printf("%s: %s: dying\n", USBDEVNAME(sc
->sc_dev
),
1447 /* XXX: one PHY only for the RTL8150 internal PHY */
1449 DPRINTFN(0xff, ("%s: %s: phy=%d is not supported\n",
1450 USBDEVNAME(sc
->sc_dev
), __func__
, phy
));
1457 case MII_BMCR
: /* Control Register */
1460 case MII_BMSR
: /* Status Register */
1467 case MII_ANAR
: /* Autonegotiation advertisement */
1470 case MII_ANLPAR
: /* Autonegotiation link partner abilities */
1473 case URLPHY_MSR
: /* Media Status Register */
1477 printf("%s: %s: bad register %04x\n",
1478 USBDEVNAME(sc
->sc_dev
), __func__
, reg
);
1484 url_csr_write_1(sc
, reg
, data
);
1486 url_csr_write_2(sc
, reg
, data
);
1494 url_miibus_statchg(device_ptr_t dev
)
1497 struct url_softc
*sc
;
1502 sc
= USBGETSOFTC(dev
);
1503 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc
->sc_dev
), __func__
));
1510 * external PHYs support, but not test.
1513 url_ext_miibus_redreg(device_ptr_t dev
, int phy
, int reg
)
1515 struct url_softc
*sc
= USBGETSOFTC(dev
);
1518 DPRINTF(("%s: %s: enter, phy=%d reg=0x%04x\n",
1519 USBDEVNAME(sc
->sc_dev
), __func__
, phy
, reg
));
1523 printf("%s: %s: dying\n", USBDEVNAME(sc
->sc_dev
),
1531 url_csr_write_1(sc
, URL_PHYADD
, phy
& URL_PHYADD_MASK
);
1533 * RTL8150L will initiate a MII management data transaction
1534 * if PHYCNT_OWN bit is set 1 by software. After transaction,
1535 * this bit is auto cleared by TRL8150L.
1537 url_csr_write_1(sc
, URL_PHYCNT
,
1538 (reg
| URL_PHYCNT_PHYOWN
) & ~URL_PHYCNT_RWCR
);
1539 for (i
= 0; i
< URL_TIMEOUT
; i
++) {
1540 if ((url_csr_read_1(sc
, URL_PHYCNT
) & URL_PHYCNT_PHYOWN
) == 0)
1543 if (i
== URL_TIMEOUT
) {
1544 printf("%s: MII read timed out\n", USBDEVNAME(sc
->sc_dev
));
1547 val
= url_csr_read_2(sc
, URL_PHYDAT
);
1549 DPRINTF(("%s: %s: phy=%d reg=0x%04x => 0x%04x\n",
1550 USBDEVNAME(sc
->sc_dev
), __func__
, phy
, reg
, val
));
1557 url_ext_miibus_writereg(device_ptr_t dev
, int phy
, int reg
, int data
)
1559 struct url_softc
*sc
= USBGETSOFTC(dev
);
1561 DPRINTF(("%s: %s: enter, phy=%d reg=0x%04x data=0x%04x\n",
1562 USBDEVNAME(sc
->sc_dev
), __func__
, phy
, reg
, data
));
1566 printf("%s: %s: dying\n", USBDEVNAME(sc
->sc_dev
),
1574 url_csr_write_2(sc
, URL_PHYDAT
, data
);
1575 url_csr_write_1(sc
, URL_PHYADD
, phy
);
1576 url_csr_write_1(sc
, URL_PHYCNT
, reg
| URL_PHYCNT_RWCR
); /* Write */
1578 for (i
=0; i
< URL_TIMEOUT
; i
++) {
1579 if (url_csr_read_1(sc
, URL_PHYCNT
) & URL_PHYCNT_PHYOWN
)
1583 if (i
== URL_TIMEOUT
) {
1584 printf("%s: MII write timed out\n",
1585 USBDEVNAME(sc
->sc_dev
));