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