FreeBSD/Linux Kernel Cross Reference
sys/dev/usb/if_uax.c
1 /* $NetBSD: if_uax.c,v 1.10 2003/12/22 10:27:51 sekiya Exp $ */
2
3 /*
4 * Copyright (c) 2003 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Lennart Augustsson (lennart@augustsson.net).
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the NetBSD
21 * Foundation, Inc. and its contributors.
22 * 4. Neither the name of The NetBSD Foundation nor the names of its
23 * contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 */
38
39 /*
40 * TODO:
41 * toggle link LED
42 * do something in interrupt routine
43 */
44
45 /*
46 * Driver for the ASIX AX88172 Fast Ethernet USB 2.0 adapter.
47 * Data sheet at
48 * http://www.asix.com.tw/datasheet/mac/Ax88172.PDF
49 * There AX88170 datasheet contains RX control register definitions.
50 * http://www.asix.com.tw/datasheet/mac/Ax88170.PDF
51 */
52
53 #include <sys/cdefs.h>
54 __KERNEL_RCSID(0, "$NetBSD: if_uax.c,v 1.10 2003/12/22 10:27:51 sekiya Exp $");
55
56 #include "opt_inet.h"
57 #include "opt_ns.h"
58 #include "bpfilter.h"
59 #include "rnd.h"
60
61 #include <sys/param.h>
62 #include <sys/systm.h>
63 #include <sys/sockio.h>
64 #include <sys/mbuf.h>
65 #include <sys/malloc.h>
66 #include <sys/kernel.h>
67 #include <sys/socket.h>
68
69 #include <sys/device.h>
70 #if NRND > 0
71 #include <sys/rnd.h>
72 #endif
73
74 #include <net/if.h>
75 #include <net/if_arp.h>
76 #include <net/if_dl.h>
77 #include <net/if_media.h>
78
79 #define BPF_MTAP(ifp, m) bpf_mtap((ifp)->if_bpf, (m))
80
81 #if NBPFILTER > 0
82 #include <net/bpf.h>
83 #endif
84
85 #include <net/if_ether.h>
86 #ifdef INET
87 #include <netinet/in.h>
88 #include <netinet/if_inarp.h>
89 #endif
90
91 #ifdef NS
92 #include <netns/ns.h>
93 #include <netns/ns_if.h>
94 #endif
95
96 #include <dev/mii/mii.h>
97 #include <dev/mii/miivar.h>
98
99 #include <dev/usb/usb.h>
100 #include <dev/usb/usbdi.h>
101 #include <dev/usb/usbdi_util.h>
102 #include <dev/usb/usbdevs.h>
103
104 #include <dev/usb/if_uaxreg.h>
105
106 #ifdef UAX_DEBUG
107 #define DPRINTF(x) if (uaxdebug) logprintf x
108 #define DPRINTFN(n,x) if (uaxdebug >= (n)) logprintf x
109 int uaxdebug = 0;
110 #else
111 #define DPRINTF(x)
112 #define DPRINTFN(n,x)
113 #endif
114
115 #define ETHER_ALIGN 2
116
117 /********** if_uaxvar.h ***********/
118
119 #define UAX_ENDPT_RX 0
120 #define UAX_ENDPT_TX 1
121 #define UAX_ENDPT_INTR 2
122 #define UAX_ENDPT_MAX 3
123
124 /* XXX Must be 1 for now */
125 #define UAX_TX_LIST_CNT 1
126 #define UAX_RX_LIST_CNT 2
127
128 struct uax_softc;
129
130 struct uax_chain {
131 struct uax_softc *uch_sc;
132 usbd_xfer_handle uch_xfer;
133 char *uch_buf;
134 struct mbuf *uch_mbuf;
135 int uch_idx;
136 };
137
138 struct uax_phy_info {
139 int phy;
140 int phy_type;
141 int phy_present;
142 };
143
144 struct uax_softc {
145 USBBASEDEVICE sc_dev;
146
147 struct ethercom sc_ec;
148 struct mii_data sc_mii;
149 #if NRND > 0
150 rndsource_element_t sc_rnd_source;
151 #endif
152 #define GET_IFP(sc) (&(sc)->sc_ec.ec_if)
153 #define GET_MII(sc) (&(sc)->sc_mii)
154
155 usb_callout_t sc_stat_ch;
156
157 usbd_device_handle sc_udev;
158 usbd_interface_handle sc_iface;
159 u_int16_t sc_vendor;
160 u_int16_t sc_product;
161 int sc_ed[UAX_ENDPT_MAX];
162 usbd_pipe_handle sc_ep[UAX_ENDPT_MAX];
163
164 u_int8_t sc_link;
165
166 int sc_chip_version;
167 struct uax_phy_info sc_phys[UAX_MAX_PHYS];
168 int sc_nphys;
169 int sc_pna; /* XXX never set */
170
171 u_int8_t sc_mcast[UAX_MULTI_FILTER_SIZE];
172 u_int8_t sc_packet_filter;
173
174 int sc_sw_mii;
175
176 /* Tx info */
177 struct uax_chain sc_tx_chain[UAX_TX_LIST_CNT];
178 #if 0
179 int sc_tx_prod;
180 int sc_tx_cons;
181 #endif
182 int sc_tx_cnt;
183
184 /* Rx info */
185 struct uax_chain sc_rx_chain[UAX_RX_LIST_CNT];
186 u_int sc_rx_errs;
187 struct timeval sc_rx_notice;
188
189 /* Interrupt info */
190 struct uax_intrpkt sc_ibuf;
191 u_int sc_intr_errs;
192
193 struct usb_task sc_tick_task;
194 struct usb_task sc_stop_task;
195
196 int sc_refcnt;
197 char sc_dying;
198 char sc_attached;
199 };
200
201 Static const struct usb_devno uax_devs[] = {
202 { USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_UFE2000 },
203 { USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88172 },
204 { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DUBE100},
205 { USB_VENDOR_LINKSYS2, USB_PRODUCT_LINKSYS2_USB200M },
206 { USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUAU2KTX },
207 { USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_FA120 },
208
209 };
210 #define uax_lookup(v, p) ((struct uax_type *)usb_lookup(uax_devs, v, p))
211
212 Static void uax_start(struct ifnet *);
213 Static int uax_ioctl(struct ifnet *, u_long, caddr_t);
214 Static void uax_stop(struct ifnet *, int);
215 Static int uax_init(struct ifnet *);
216 Static void uax_watchdog(struct ifnet *);
217
218 Static void uax_stop_wrap(void *v);
219 Static void uax_tick(void *);
220 Static void uax_tick_task(void *);
221
222 Static int uax_miibus_readreg(device_ptr_t, int, int);
223 Static void uax_miibus_writereg(device_ptr_t, int, int, int);
224 Static void uax_miibus_statchg(device_ptr_t);
225 Static int uax_ifmedia_upd(struct ifnet *);
226 Static void uax_ifmedia_sts(struct ifnet *, struct ifmediareq *);
227
228 /*Static void uax_reset(struct uax_softc *sc);*/
229 Static void uax_setup(struct uax_softc *sc);
230 Static void uax_phy_init(struct uax_softc *sc, int i);
231 Static void uax_setup_phy(struct uax_softc *sc);
232 Static void uax_read_mac(struct uax_softc *, u_char *);
233 Static void uax_grab_mii(struct uax_softc *sc);
234 Static void uax_ungrab_mii(struct uax_softc *sc);
235
236 Static int uax_send(struct uax_softc *, struct mbuf *, int);
237 Static void uax_intr(usbd_xfer_handle, usbd_private_handle, usbd_status);
238 Static void uax_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
239 Static void uax_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
240 Static int uax_tx_list_init(struct uax_softc *);
241 Static int uax_rx_list_init(struct uax_softc *);
242 Static int uax_newbuf(struct uax_softc *, struct uax_chain *, struct mbuf *);
243 Static int uax_openpipes(struct uax_softc *);
244 Static u_int32_t uax_crc(u_int8_t *eaddr);
245 Static void uax_setmulti(struct uax_softc *sc);
246
247 static inline usbd_status
248 uax_request(struct uax_softc *sc, uint type, uint req,
249 uint value, uint index, uint len, void *data);
250 static inline usbd_status
251 uax_request(struct uax_softc *sc, uint type, uint rq,
252 uint value, uint indx, uint len, void *data)
253 {
254 usb_device_request_t req;
255
256 req.bmRequestType = type;
257 req.bRequest = rq;
258 USETW(req.wValue, value);
259 USETW(req.wIndex, indx);
260 USETW(req.wLength, len);
261
262 return (usbd_do_request(sc->sc_udev, &req, data));
263 }
264
265 /*******/
266
267 USB_DECLARE_DRIVER(uax);
268
269 USB_MATCH(uax)
270 {
271 USB_MATCH_START(uax, uaa);
272
273 if (uaa->iface != NULL)
274 return (UMATCH_NONE);
275
276 return (uax_lookup(uaa->vendor, uaa->product) != NULL ?
277 UMATCH_VENDOR_PRODUCT : UMATCH_NONE);
278 }
279
280 /*
281 * Attach the interface. Allocate softc structures, do ifmedia
282 * setup and ethernet/BPF attach.
283 */
284 USB_ATTACH(uax)
285 {
286 USB_ATTACH_START(uax, sc, uaa);
287 char devinfo[1024];
288 int s;
289 u_char eaddr[ETHER_ADDR_LEN];
290 struct ifnet *ifp;
291 struct mii_data *mii;
292 usbd_device_handle dev = uaa->device;
293 usbd_interface_handle iface;
294 usbd_status err;
295 usb_interface_descriptor_t *id;
296 usb_endpoint_descriptor_t *ed;
297 int i;
298
299 DPRINTFN(5,(" : uax_attach: sc=%p", sc));
300
301 usbd_devinfo(dev, 0, devinfo);
302 USB_ATTACH_SETUP;
303 printf("%s: %s\n", USBDEVNAME(sc->sc_dev), devinfo);
304
305 err = usbd_set_config_no(dev, UAX_CONFIG_NO, 1);
306 if (err) {
307 printf("%s: setting config no failed\n",
308 USBDEVNAME(sc->sc_dev));
309 USB_ATTACH_ERROR_RETURN;
310 }
311
312 ifp = GET_IFP(sc);
313 usb_init_task(&sc->sc_tick_task, uax_tick_task, sc);
314 usb_init_task(&sc->sc_stop_task, uax_stop_wrap, ifp);
315
316 err = usbd_device2interface_handle(dev, UAX_IFACE_IDX, &iface);
317 if (err) {
318 printf("%s: getting interface handle failed\n",
319 USBDEVNAME(sc->sc_dev));
320 USB_ATTACH_ERROR_RETURN;
321 }
322
323 sc->sc_udev = dev;
324 sc->sc_iface = iface;
325 sc->sc_product = uaa->product;
326 sc->sc_vendor = uaa->vendor;
327
328 id = usbd_get_interface_descriptor(iface);
329
330 /* Find endpoints. */
331 for (i = 0; i < id->bNumEndpoints; i++) {
332 ed = usbd_interface2endpoint_descriptor(iface, i);
333 if (ed == NULL) {
334 printf("%s: couldn't get endpoint descriptor %d\n",
335 USBDEVNAME(sc->sc_dev), i);
336 USB_ATTACH_ERROR_RETURN;
337 }
338 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
339 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
340 sc->sc_ed[UAX_ENDPT_RX] = ed->bEndpointAddress;
341 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
342 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
343 sc->sc_ed[UAX_ENDPT_TX] = ed->bEndpointAddress;
344 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
345 UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
346 sc->sc_ed[UAX_ENDPT_INTR] = ed->bEndpointAddress;
347 }
348 }
349
350 if (sc->sc_ed[UAX_ENDPT_RX] == 0 || sc->sc_ed[UAX_ENDPT_TX] == 0 ||
351 sc->sc_ed[UAX_ENDPT_INTR] == 0) {
352 printf("%s: missing endpoint\n", USBDEVNAME(sc->sc_dev));
353 USB_ATTACH_ERROR_RETURN;
354 }
355
356 /* Get data from chip and set up hw. */
357 uax_setup(sc);
358 uax_setup_phy(sc);
359 printf("%s: chip version %d\n", USBDEVNAME(sc->sc_dev),
360 sc->sc_chip_version);
361 #if UAX_DEBUG
362 if (uaxdebug) {
363 for (i = 0; i < UAX_MAX_PHYS; i++) {
364 printf("%s: phy%d present=%d id=%d type=%d\n",
365 USBDEVNAME(sc->sc_dev), i,
366 sc->sc_phys[i].phy_present,
367 sc->sc_phys[i].phy,
368 sc->sc_phys[i].phy_type);
369 }
370 }
371 #endif
372
373 s = splnet();
374
375 /*
376 * Get station address from the EEPROM.
377 */
378 uax_read_mac(sc, eaddr);
379
380 /*
381 * A Pegasus chip was detected. Inform the world.
382 */
383 printf("%s: Ethernet address %s\n", USBDEVNAME(sc->sc_dev),
384 ether_sprintf(eaddr));
385
386 /* Initialize interface info.*/
387 ifp->if_softc = sc;
388 ifp->if_mtu = ETHERMTU;
389 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
390 ifp->if_ioctl = uax_ioctl;
391 ifp->if_start = uax_start;
392 ifp->if_watchdog = uax_watchdog;
393 ifp->if_init = uax_init;
394 ifp->if_stop = uax_stop;
395 strncpy(ifp->if_xname, USBDEVNAME(sc->sc_dev), IFNAMSIZ);
396
397 IFQ_SET_READY(&ifp->if_snd);
398
399 /* Initialize MII/media info. */
400 mii = &sc->sc_mii;
401 mii->mii_ifp = ifp;
402 mii->mii_readreg = uax_miibus_readreg;
403 mii->mii_writereg = uax_miibus_writereg;
404 mii->mii_statchg = uax_miibus_statchg;
405 mii->mii_flags = MIIF_AUTOTSLEEP;
406 ifmedia_init(&mii->mii_media, 0, uax_ifmedia_upd, uax_ifmedia_sts);
407
408 uax_grab_mii(sc);
409 mii_attach(self, mii, ~0, MII_PHY_ANY, MII_OFFSET_ANY, 0);
410 uax_ungrab_mii(sc);
411
412 if (LIST_FIRST(&mii->mii_phys) == NULL) {
413 ifmedia_add(&mii->mii_media, IFM_ETHER | IFM_NONE, 0, NULL);
414 ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_NONE);
415 } else
416 ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_AUTO);
417
418 /* Attach the interface. */
419 if_attach(ifp);
420 Ether_ifattach(ifp, eaddr);
421 #if NRND > 0
422 rnd_attach_source(&sc->sc_rnd_source, USBDEVNAME(sc->sc_dev),
423 RND_TYPE_NET, 0);
424 #endif
425
426 usb_callout_init(sc->sc_stat_ch);
427
428 sc->sc_attached = 1;
429 splx(s);
430
431 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
432 USBDEV(sc->sc_dev));
433
434 USB_ATTACH_SUCCESS_RETURN;
435 }
436
437 USB_DETACH(uax)
438 {
439 USB_DETACH_START(uax, sc);
440 struct ifnet *ifp = GET_IFP(sc);
441 int s;
442
443 DPRINTFN(2,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
444
445 if (!sc->sc_attached) {
446 /* Detached before attached finished, so just bail out. */
447 return (0);
448 }
449
450 usb_uncallout(sc->sc_stat_ch, uax_tick, sc);
451 /*
452 * Remove any pending tasks. They cannot be executing because they run
453 * in the same thread as detach.
454 */
455 usb_rem_task(sc->sc_udev, &sc->sc_tick_task);
456 usb_rem_task(sc->sc_udev, &sc->sc_stop_task);
457
458 s = splusb();
459
460 if (ifp->if_flags & IFF_RUNNING)
461 uax_stop(ifp, 1);
462
463 #if NRND > 0
464 rnd_detach_source(&sc->sc_rnd_source);
465 #endif
466 mii_detach(&sc->sc_mii, MII_PHY_ANY, MII_OFFSET_ANY);
467 ifmedia_delete_instance(&sc->sc_mii.mii_media, IFM_INST_ANY);
468 ether_ifdetach(ifp);
469
470 if_detach(ifp);
471
472 #ifdef DIAGNOSTIC
473 if (sc->sc_ep[UAX_ENDPT_TX] != NULL ||
474 sc->sc_ep[UAX_ENDPT_RX] != NULL ||
475 sc->sc_ep[UAX_ENDPT_INTR] != NULL)
476 printf("%s: detach has active endpoints\n",
477 USBDEVNAME(sc->sc_dev));
478 #endif
479
480 sc->sc_attached = 0;
481
482 if (--sc->sc_refcnt >= 0) {
483 /* Wait for processes to go away. */
484 usb_detach_wait(USBDEV(sc->sc_dev));
485 }
486 splx(s);
487
488 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
489 USBDEV(sc->sc_dev));
490
491 return (0);
492 }
493
494 int
495 uax_activate(device_ptr_t self, enum devact act)
496 {
497 struct uax_softc *sc = (struct uax_softc *)self;
498
499 DPRINTFN(2,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
500
501 switch (act) {
502 case DVACT_ACTIVATE:
503 return (EOPNOTSUPP);
504 break;
505
506 case DVACT_DEACTIVATE:
507 if_deactivate(&sc->sc_ec.ec_if);
508 sc->sc_dying = 1;
509 break;
510 }
511 return (0);
512 }
513
514 Static void
515 uax_setup(struct uax_softc *sc)
516 {
517 uByte version;
518 uByte mii_data[2];
519
520 /* Get chip version */
521 version = 0;
522 (void)uax_request(sc, UT_READ_VENDOR_DEVICE, UAX_GET_MONITOR_MODE,
523 0, 0, sizeof version, &version);
524 sc->sc_chip_version = version;
525
526 /* Get PHY id */
527 (void)uax_request(sc, UT_READ_VENDOR_DEVICE, UAX_READ_PHYID,
528 0, 0, sizeof mii_data, &mii_data);
529 sc->sc_phys[0].phy = UAX_GET_PHY(mii_data[1]);
530 sc->sc_phys[0].phy_type = UAX_GET_PHY_TYPE(mii_data[1]);
531 sc->sc_phys[1].phy = UAX_GET_PHY(mii_data[0]);
532 sc->sc_phys[1].phy_type = UAX_GET_PHY_TYPE(mii_data[0]);
533
534 /* Read multicast filter array */
535 (void)uax_request(sc, UT_READ_VENDOR_DEVICE, UAX_READ_MULTI_FILTER,
536 0, 0, sizeof sc->sc_mcast, &sc->sc_mcast);
537
538 sc->sc_packet_filter = UAX_RX_BROADCAST | UAX_RX_DIRECTED;
539 }
540
541 Static void
542 uax_phy_init(struct uax_softc *sc, int i)
543 {
544 struct uax_phy_info *p = &sc->sc_phys[i];
545
546 DPRINTF(("uax_phy_init: i=%d\n", i));
547 if (p->phy || p->phy_type != 7) {
548 u_int16_t v1, v2;
549 v1 = uax_miibus_readreg(&sc->sc_dev, p->phy, MII_BMSR);
550 v2 = uax_miibus_readreg(&sc->sc_dev, p->phy, MII_BMCR);
551 if ((v1 & v2) != 0xffff) {
552 #if 0
553 /*
554 * The data sheet and the Windows driver isolates and
555 * power down the PHY at this point, but doing so
556 * makes mii_attach() fail often.
557 */
558 uax_miibus_writereg(&sc->sc_dev, p->phy, MII_BMCR,
559 BMCR_ISO | BMCR_PDOWN);
560 #endif
561 p->phy_present = 1;
562 sc->sc_nphys++;
563 }
564 }
565 DPRINTF(("uax_phy_init: i=%d done\n", i));
566 }
567
568 /* Switch to software PHY access mode. */
569 Static void
570 uax_grab_mii(struct uax_softc *sc)
571 {
572 if (sc->sc_sw_mii++ > 0)
573 return;
574 (void)uax_request(sc, UT_WRITE_VENDOR_DEVICE, UAX_SOFTWARE_MII,
575 0, 0, 0, NULL);
576 }
577
578 /* Switch to hardware PHY access mode. */
579 Static void
580 uax_ungrab_mii(struct uax_softc *sc)
581 {
582 if (--sc->sc_sw_mii > 0)
583 return;
584 (void)uax_request(sc, UT_WRITE_VENDOR_DEVICE, UAX_HARDWARE_MII,
585 0, 0, 0, NULL);
586 }
587
588 #define PHY_TIMEOUT 10000
589
590 /* Magic taken from the Windows driver. */
591 Static void
592 uax_setup_phy(struct uax_softc *sc)
593 {
594 uByte status;
595 int i;
596
597 uax_grab_mii(sc);
598
599 for (i = 0; i < PHY_TIMEOUT; i++) {
600 delay(50);
601 status = 0;
602 uax_request(sc, UT_READ_VENDOR_DEVICE, UAX_READ_MII_OPMODE,
603 0, 0, sizeof status, &status);
604 if (status & 1)
605 break;
606 }
607 if (i >= PHY_TIMEOUT)
608 printf("%s: mii status read timeout\n",USBDEVNAME(sc->sc_dev));
609
610 for (i = 0; i < UAX_MAX_PHYS; i++)
611 uax_phy_init(sc, i);
612
613 uax_ungrab_mii(sc);
614
615 (void)uax_request(sc, UT_WRITE_VENDOR_DEVICE, UAX_WRITE_IPG,
616 sc->sc_pna ? 0x17 : 0x15, 0, 0, NULL);
617 (void)uax_request(sc, UT_WRITE_VENDOR_DEVICE, UAX_WRITE_IPG1,
618 0x0c, 0, 0, NULL);
619 (void)uax_request(sc, UT_WRITE_VENDOR_DEVICE, UAX_WRITE_IPG2,
620 sc->sc_pna ? 0x14 : 0x12, 0, 0, NULL);
621 }
622
623 Static void
624 uax_read_mac(struct uax_softc *sc, u_char *dest)
625 {
626 usbd_status err;
627
628 if (sc->sc_dying)
629 return;
630
631 err = uax_request(sc, UT_READ_VENDOR_DEVICE, UAX_READ_NODEID,
632 0, 0, ETHER_ADDR_LEN, dest);
633 if (err) {
634 DPRINTF(("%s: uax_read_mac error=%s\n",
635 USBDEVNAME(sc->sc_dev), usbd_errstr(err)));
636 }
637 }
638
639 /*
640 * uax_ioctl: [ifnet interface function]
641 *
642 * Handle control requests from the operator.
643 */
644 int
645 uax_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
646 {
647 struct uax_softc *sc = ifp->if_softc;
648 struct ifreq *ifr = (struct ifreq *)data;
649 int s, error;
650
651 s = splnet();
652
653 switch (cmd) {
654 case SIOCSIFMEDIA:
655 case SIOCGIFMEDIA:
656 error = ifmedia_ioctl(ifp, ifr, &sc->sc_mii.mii_media, cmd);
657 break;
658
659 default:
660 error = ether_ioctl(ifp, cmd, data);
661 if (error == ENETRESET) {
662 /*
663 * Multicast list has changed. Set the
664 * hardware filter accordingly.
665 */
666 uax_setmulti(sc);
667 error = 0;
668 }
669 break;
670 }
671
672 /* Try to get more packets going. */
673 if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
674 uax_start(ifp);
675
676 splx(s);
677 return (error);
678 }
679
680 Static void
681 uax_watchdog(struct ifnet *ifp)
682 {
683 struct uax_softc *sc = ifp->if_softc;
684 struct uax_chain *c;
685 usbd_status stat;
686 int s;
687
688 DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
689
690 ifp->if_oerrors++;
691 printf("%s: watchdog timeout\n", USBDEVNAME(sc->sc_dev));
692
693 s = splusb();
694 c = &sc->sc_tx_chain[0];
695 usbd_get_xfer_status(c->uch_xfer, NULL, NULL, NULL, &stat);
696 uax_txeof(c->uch_xfer, c, stat);
697
698 if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
699 uax_start(ifp);
700 splx(s);
701 }
702
703 /*
704 * Set media options.
705 */
706 Static int
707 uax_ifmedia_upd(struct ifnet *ifp)
708 {
709 struct uax_softc *sc = ifp->if_softc;
710 struct mii_data *mii = GET_MII(sc);
711
712 DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
713
714 if (sc->sc_dying)
715 return (0);
716
717 sc->sc_link = 0;
718 if (mii->mii_instance) {
719 struct mii_softc *miisc;
720 for (miisc = LIST_FIRST(&mii->mii_phys); miisc != NULL;
721 miisc = LIST_NEXT(miisc, mii_list))
722 mii_phy_reset(miisc);
723 }
724 mii_mediachg(mii);
725
726 return (0);
727 }
728
729 /*
730 * Report current media status.
731 */
732 Static void
733 uax_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
734 {
735 struct uax_softc *sc = ifp->if_softc;
736 struct mii_data *mii = GET_MII(sc);
737
738 DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
739
740 mii_pollstat(mii);
741 ifmr->ifm_active = mii->mii_media_active;
742 ifmr->ifm_status = mii->mii_media_status;
743 }
744
745 Static int
746 uax_miibus_readreg(device_ptr_t dev, int phy, int reg)
747 {
748 struct uax_softc *sc = USBGETSOFTC(dev);
749 uWord val;
750 usbd_status err;
751
752 if (sc->sc_dying)
753 return (0);
754
755 /* We must limit the PHY address to avoid false hits. */
756 if (phy >= sc->sc_nphys)
757 return (0);
758
759 uax_grab_mii(sc);
760 err = uax_request(sc, UT_READ_VENDOR_DEVICE, UAX_READ_MII_REG,
761 phy, reg, sizeof val, &val);
762 uax_ungrab_mii(sc);
763 if (err) {
764 DPRINTF(("%s: uax_miibus_readreg error=%s\n",
765 USBDEVNAME(sc->sc_dev), usbd_errstr(err)));
766 return (0);
767 }
768
769 DPRINTFN(4,("uax_miibus_readreg: phy=%d reg=0x%x data=0x%08x\n", phy,
770 reg, UGETW(val)));
771 return (UGETW(val));
772 }
773
774 Static void
775 uax_miibus_writereg(device_ptr_t dev, int phy, int reg, int data)
776 {
777 struct uax_softc *sc = USBGETSOFTC(dev);
778 uWord val;
779 usbd_status err;
780
781 if (sc->sc_dying)
782 return;
783
784 uax_grab_mii(sc);
785 err = uax_request(sc, UT_WRITE_VENDOR_DEVICE, UAX_WRITE_MII_REG,
786 phy, reg, sizeof val, &val);
787 uax_ungrab_mii(sc);
788 if (err) {
789 DPRINTF(("%s: uax_miibus_writereg error=%s\n",
790 USBDEVNAME(sc->sc_dev), usbd_errstr(err)));
791 }
792 }
793
794 Static void
795 uax_miibus_statchg(device_ptr_t dev)
796 {
797 struct uax_softc *sc = USBGETSOFTC(dev);
798 /*struct mii_data *mii = GET_MII(sc);
799 uint val;*/
800 #if 0
801 usbd_status err;
802 #endif
803
804 DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
805
806 if (sc->sc_dying)
807 return;
808
809 #if 0
810 if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX)
811 val = 0x02;
812 else
813 val = 0x00;
814 err = uax_request(sc, UT_WRITE_VENDOR_DEVICE, UAX_WRITE_MEDIUM_STATUS,
815 val, 0, 0, NULL);
816 if (err) {
817 DPRINTF(("%s: uax_miibus_statchg error=%s\n",
818 USBDEVNAME(sc->sc_dev), usbd_errstr(err)));
819 }
820 #endif
821 /* Nothing to do */
822 }
823
824 Static int
825 uax_send(struct uax_softc *sc, struct mbuf *m, int idx)
826 {
827 struct uax_chain *c;
828 usbd_status err;
829
830 DPRINTFN(10,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev),__func__));
831
832 c = &sc->sc_tx_chain[idx];
833
834 /* Copy data to tx buffer. */
835 KASSERT(m->m_pkthdr.len <= UAX_BUFSZ);
836 m_copydata(m, 0, m->m_pkthdr.len, c->uch_buf);
837 c->uch_mbuf = m;
838
839 /* XXX Should we zero tail of buffer for short packets? */
840
841 usbd_setup_xfer(c->uch_xfer, sc->sc_ep[UAX_ENDPT_TX],
842 c, c->uch_buf, m->m_pkthdr.len,
843 USBD_FORCE_SHORT_XFER | USBD_NO_COPY,
844 UAX_TX_TIMEOUT, uax_txeof);
845
846 DPRINTF(("%s: sending %d bytes\n", USBDEVNAME(sc->sc_dev),
847 m->m_pkthdr.len));
848 /* Transmit */
849 err = usbd_transfer(c->uch_xfer);
850 if (err != USBD_IN_PROGRESS) {
851 printf("%s: uax_send error=%s\n", USBDEVNAME(sc->sc_dev),
852 usbd_errstr(err));
853 /* Stop the interface from process context. */
854 usb_add_task(sc->sc_udev, &sc->sc_stop_task);
855 return (EIO);
856 }
857 DPRINTFN(5,("%s: %s: send %d bytes\n", USBDEVNAME(sc->sc_dev),
858 __func__, m->m_pkthdr.len));
859
860 sc->sc_tx_cnt++;
861
862 return (0);
863 }
864
865 /*
866 * A frame was downloaded to the chip. It's safe for us to clean up
867 * the list buffers.
868 */
869 Static void
870 uax_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
871 {
872 struct uax_chain *c = priv;
873 struct uax_softc *sc = c->uch_sc;
874 struct ifnet *ifp = GET_IFP(sc);
875 int s;
876
877 if (sc->sc_dying)
878 return;
879
880 DPRINTF(("uax_txoef: frame sent\n"));
881
882 s = splnet();
883
884 DPRINTFN(10,("%s: %s: enter status=%d\n", USBDEVNAME(sc->sc_dev),
885 __func__, status));
886
887 ifp->if_timer = 0;
888 ifp->if_flags &= ~IFF_OACTIVE;
889
890 if (status != USBD_NORMAL_COMPLETION) {
891 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
892 splx(s);
893 return;
894 }
895 ifp->if_oerrors++;
896 printf("%s: usb error on tx: %s\n", USBDEVNAME(sc->sc_dev),
897 usbd_errstr(status));
898 if (status == USBD_STALLED)
899 usbd_clear_endpoint_stall(sc->sc_ep[UAX_ENDPT_TX]);
900 splx(s);
901 return;
902 }
903
904 ifp->if_opackets++;
905
906 m_freem(c->uch_mbuf);
907 c->uch_mbuf = NULL;
908
909 if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
910 uax_start(ifp);
911
912 splx(s);
913 }
914
915 Static void
916 uax_start(struct ifnet *ifp)
917 {
918 struct uax_softc *sc = ifp->if_softc;
919 struct mbuf *m_head = NULL;
920
921 DPRINTFN(5,("%s: %s: enter, link=%d\n", USBDEVNAME(sc->sc_dev),
922 __func__, sc->sc_link));
923
924 if (sc->sc_dying)
925 return;
926
927 if (!sc->sc_link)
928 return;
929
930 if (ifp->if_flags & IFF_OACTIVE)
931 return;
932
933 IFQ_POLL(&ifp->if_snd, m_head);
934 if (m_head == NULL)
935 return;
936
937 if (uax_send(sc, m_head, 0)) {
938 ifp->if_flags |= IFF_OACTIVE;
939 return;
940 }
941
942 IFQ_DEQUEUE(&ifp->if_snd, m_head);
943
944 #if NBPFILTER > 0
945 /*
946 * If there's a BPF listener, bounce a copy of this frame
947 * to him.
948 */
949 if (ifp->if_bpf)
950 BPF_MTAP(ifp, m_head);
951 #endif
952
953 ifp->if_flags |= IFF_OACTIVE;
954
955 /*
956 * Set a timeout in case the chip goes out to lunch.
957 */
958 ifp->if_timer = 5;
959 }
960
961 Static void
962 uax_stop_wrap(void *v)
963 {
964 uax_stop(v, 0);
965 }
966
967 Static void
968 uax_stop(struct ifnet *ifp, int disable)
969 {
970 struct uax_softc *sc = ifp->if_softc;
971 usbd_status err;
972 int i;
973
974 DPRINTFN(5,("%s: %s: enter disable=%d\n", USBDEVNAME(sc->sc_dev),
975 __func__, disable));
976
977 ifp->if_timer = 0;
978
979 /* XXX How do we stop the chip? */
980 sc->sc_packet_filter &= ~UAX_RX_ALTERNATE;
981 (void)uax_request(sc, UT_WRITE_VENDOR_DEVICE, UAX_WRITE_RX_CTRL,
982 sc->sc_packet_filter, 0, 0, NULL);
983 /* XXX do more */
984
985 usb_uncallout(sc->sc_stat_ch, uax_tick, sc);
986
987 /* Stop transfers. */
988 if (sc->sc_ep[UAX_ENDPT_RX] != NULL) {
989 err = usbd_abort_pipe(sc->sc_ep[UAX_ENDPT_RX]);
990 if (err) {
991 printf("%s: abort rx pipe failed: %s\n",
992 USBDEVNAME(sc->sc_dev), usbd_errstr(err));
993 }
994 err = usbd_close_pipe(sc->sc_ep[UAX_ENDPT_RX]);
995 if (err) {
996 printf("%s: close rx pipe failed: %s\n",
997 USBDEVNAME(sc->sc_dev), usbd_errstr(err));
998 }
999 sc->sc_ep[UAX_ENDPT_RX] = NULL;
1000 }
1001
1002 if (sc->sc_ep[UAX_ENDPT_TX] != NULL) {
1003 err = usbd_abort_pipe(sc->sc_ep[UAX_ENDPT_TX]);
1004 if (err) {
1005 printf("%s: abort tx pipe failed: %s\n",
1006 USBDEVNAME(sc->sc_dev), usbd_errstr(err));
1007 }
1008 err = usbd_close_pipe(sc->sc_ep[UAX_ENDPT_TX]);
1009 if (err) {
1010 printf("%s: close tx pipe failed: %s\n",
1011 USBDEVNAME(sc->sc_dev), usbd_errstr(err));
1012 }
1013 sc->sc_ep[UAX_ENDPT_TX] = NULL;
1014 }
1015
1016 if (sc->sc_ep[UAX_ENDPT_INTR] != NULL) {
1017 err = usbd_abort_pipe(sc->sc_ep[UAX_ENDPT_INTR]);
1018 if (err) {
1019 printf("%s: abort intr pipe failed: %s\n",
1020 USBDEVNAME(sc->sc_dev), usbd_errstr(err));
1021 }
1022 err = usbd_close_pipe(sc->sc_ep[UAX_ENDPT_INTR]);
1023 if (err) {
1024 printf("%s: close intr pipe failed: %s\n",
1025 USBDEVNAME(sc->sc_dev), usbd_errstr(err));
1026 }
1027 sc->sc_ep[UAX_ENDPT_INTR] = NULL;
1028 }
1029
1030 /* Free RX resources. */
1031 for (i = 0; i < UAX_RX_LIST_CNT; i++) {
1032 if (sc->sc_rx_chain[i].uch_mbuf != NULL) {
1033 m_freem(sc->sc_rx_chain[i].uch_mbuf);
1034 sc->sc_rx_chain[i].uch_mbuf = NULL;
1035 }
1036 if (sc->sc_rx_chain[i].uch_xfer != NULL) {
1037 usbd_free_xfer(sc->sc_rx_chain[i].uch_xfer);
1038 sc->sc_rx_chain[i].uch_xfer = NULL;
1039 }
1040 }
1041
1042 /* Free TX resources. */
1043 for (i = 0; i < UAX_TX_LIST_CNT; i++) {
1044 if (sc->sc_tx_chain[i].uch_mbuf != NULL) {
1045 m_freem(sc->sc_tx_chain[i].uch_mbuf);
1046 sc->sc_tx_chain[i].uch_mbuf = NULL;
1047 }
1048 if (sc->sc_tx_chain[i].uch_xfer != NULL) {
1049 usbd_free_xfer(sc->sc_tx_chain[i].uch_xfer);
1050 sc->sc_tx_chain[i].uch_xfer = NULL;
1051 }
1052 }
1053
1054 sc->sc_link = 0;
1055
1056 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
1057 }
1058
1059 /*
1060 * A frame has been uploaded: pass the resulting mbuf chain up to
1061 * the higher level protocols.
1062 */
1063 Static void
1064 uax_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
1065 {
1066 struct uax_chain *c = priv;
1067 struct uax_softc *sc = c->uch_sc;
1068 struct ifnet *ifp = GET_IFP(sc);
1069 struct mbuf *m;
1070 u_int32_t total_len;
1071 int s;
1072
1073 DPRINTFN(10,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
1074
1075 if (sc->sc_dying)
1076 return;
1077
1078 if (!(ifp->if_flags & IFF_RUNNING))
1079 return;
1080
1081 if (status != USBD_NORMAL_COMPLETION) {
1082 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
1083 return;
1084 sc->sc_rx_errs++;
1085 if (usbd_ratecheck(&sc->sc_rx_notice)) {
1086 printf("%s: %u usb errors on rx: %s\n",
1087 USBDEVNAME(sc->sc_dev), sc->sc_rx_errs,
1088 usbd_errstr(status));
1089 sc->sc_rx_errs = 0;
1090 }
1091 if (status == USBD_STALLED)
1092 usbd_clear_endpoint_stall(sc->sc_ep[UAX_ENDPT_RX]);
1093 goto done;
1094 }
1095
1096 usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
1097
1098 DPRINTF(("%s: got %d bytes\n", USBDEVNAME(sc->sc_dev), total_len));
1099 memcpy(mtod(c->uch_mbuf, char *), c->uch_buf, total_len);
1100
1101 if (total_len == 0) {
1102 ifp->if_ierrors++;
1103 goto done;
1104 }
1105
1106 /* No errors; receive the packet. */
1107 m = c->uch_mbuf;
1108 m->m_pkthdr.len = m->m_len = total_len;
1109 ifp->if_ipackets++;
1110
1111 m->m_pkthdr.rcvif = ifp;
1112
1113 s = splnet();
1114
1115 /* XXX ugly */
1116 if (uax_newbuf(sc, c, NULL) == ENOBUFS) {
1117 ifp->if_ierrors++;
1118 goto done1;
1119 }
1120
1121 #if NBPFILTER > 0
1122 /*
1123 * Handle BPF listeners. Let the BPF user see the packet, but
1124 * don't pass it up to the ether_input() layer unless it's
1125 * a broadcast packet, multicast packet, matches our ethernet
1126 * address or the interface is in promiscuous mode.
1127 */
1128 if (ifp->if_bpf)
1129 BPF_MTAP(ifp, m);
1130 #endif
1131
1132 DPRINTFN(10,("%s: %s: deliver %d\n", USBDEVNAME(sc->sc_dev),
1133 __func__, m->m_len));
1134 IF_INPUT(ifp, m);
1135 done1:
1136 splx(s);
1137
1138 done:
1139
1140 /* Setup new transfer. */
1141 usbd_setup_xfer(xfer, sc->sc_ep[UAX_ENDPT_RX],
1142 c, c->uch_buf, UAX_BUFSZ,
1143 USBD_SHORT_XFER_OK | USBD_NO_COPY,
1144 USBD_NO_TIMEOUT, uax_rxeof);
1145 usbd_transfer(xfer);
1146
1147 DPRINTFN(10,("%s: %s: start rx\n", USBDEVNAME(sc->sc_dev),
1148 __func__));
1149 }
1150
1151 /*
1152 * Initialize an RX descriptor and attach an MBUF cluster.
1153 */
1154 Static int
1155 uax_newbuf(struct uax_softc *sc, struct uax_chain *c, struct mbuf *m)
1156 {
1157 struct mbuf *m_new = NULL;
1158
1159 DPRINTFN(10,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev),__func__));
1160
1161 if (m == NULL) {
1162 MGETHDR(m_new, M_DONTWAIT, MT_DATA);
1163 if (m_new == NULL) {
1164 printf("%s: no memory for rx list "
1165 "-- packet dropped!\n", USBDEVNAME(sc->sc_dev));
1166 return (ENOBUFS);
1167 }
1168
1169 MCLGET(m_new, M_DONTWAIT);
1170 if (!(m_new->m_flags & M_EXT)) {
1171 printf("%s: no memory for rx list "
1172 "-- packet dropped!\n", USBDEVNAME(sc->sc_dev));
1173 m_freem(m_new);
1174 return (ENOBUFS);
1175 }
1176 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
1177 } else {
1178 m_new = m;
1179 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
1180 m_new->m_data = m_new->m_ext.ext_buf;
1181 }
1182
1183 m_adj(m_new, ETHER_ALIGN);
1184 c->uch_mbuf = m_new;
1185
1186 return (0);
1187 }
1188
1189 Static int
1190 uax_rx_list_init(struct uax_softc *sc)
1191 {
1192 struct uax_chain *c;
1193 int i;
1194
1195 DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
1196
1197 for (i = 0; i < UAX_RX_LIST_CNT; i++) {
1198 c = &sc->sc_rx_chain[i];
1199 c->uch_sc = sc;
1200 c->uch_idx = i;
1201 if (uax_newbuf(sc, c, NULL) == ENOBUFS)
1202 return (ENOBUFS);
1203 if (c->uch_xfer == NULL) {
1204 c->uch_xfer = usbd_alloc_xfer(sc->sc_udev);
1205 if (c->uch_xfer == NULL)
1206 return (ENOBUFS);
1207 c->uch_buf = usbd_alloc_buffer(c->uch_xfer, UAX_BUFSZ);
1208 if (c->uch_buf == NULL) {
1209 usbd_free_xfer(c->uch_xfer);
1210 c->uch_xfer = NULL;
1211 return (ENOBUFS);
1212 }
1213 }
1214 }
1215
1216 return (0);
1217 }
1218
1219 Static int
1220 uax_tx_list_init(struct uax_softc *sc)
1221 {
1222 struct uax_chain *c;
1223 int i;
1224
1225 DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
1226
1227 for (i = 0; i < UAX_TX_LIST_CNT; i++) {
1228 c = &sc->sc_tx_chain[i];
1229 c->uch_sc = sc;
1230 c->uch_idx = i;
1231 c->uch_mbuf = NULL;
1232 if (c->uch_xfer == NULL) {
1233 c->uch_xfer = usbd_alloc_xfer(sc->sc_udev);
1234 if (c->uch_xfer == NULL)
1235 return (ENOBUFS);
1236 c->uch_buf = usbd_alloc_buffer(c->uch_xfer, UAX_BUFSZ);
1237 if (c->uch_buf == NULL) {
1238 usbd_free_xfer(c->uch_xfer);
1239 c->uch_xfer = NULL;
1240 return (ENOBUFS);
1241 }
1242 }
1243 }
1244
1245 return (0);
1246 }
1247
1248 Static int
1249 uax_init(struct ifnet *ifp)
1250 {
1251 struct uax_softc *sc = ifp->if_softc;
1252
1253 DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
1254
1255 if (sc->sc_dying)
1256 return (EIO);
1257
1258 uax_stop(ifp, 0);
1259
1260 /* Load the multicast filter. */
1261 uax_setmulti(sc);
1262
1263 /* Init TX ring. */
1264 if (uax_tx_list_init(sc) == ENOBUFS) {
1265 printf("%s: tx list init failed\n", USBDEVNAME(sc->sc_dev));
1266 return (EIO);
1267 }
1268
1269 /* Init RX ring. */
1270 if (uax_rx_list_init(sc) == ENOBUFS) {
1271 printf("%s: rx list init failed\n", USBDEVNAME(sc->sc_dev));
1272 return (EIO);
1273 }
1274
1275 if (sc->sc_ep[UAX_ENDPT_RX] == NULL) {
1276 if (uax_openpipes(sc)) {
1277 return (EIO);
1278 }
1279 }
1280
1281 ifp->if_flags |= IFF_RUNNING;
1282 ifp->if_flags &= ~IFF_OACTIVE;
1283
1284 usb_callout(sc->sc_stat_ch, hz, uax_tick, sc);
1285
1286 sc->sc_packet_filter |= UAX_RX_ALTERNATE;
1287 (void)uax_request(sc, UT_WRITE_VENDOR_DEVICE, UAX_WRITE_RX_CTRL,
1288 sc->sc_packet_filter, 0, 0, NULL);
1289
1290 return (0);
1291 }
1292
1293 Static void
1294 uax_tick(void *xsc)
1295 {
1296 struct uax_softc *sc = xsc;
1297
1298 DPRINTFN(15,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev),__func__));
1299
1300 if (sc == NULL)
1301 return;
1302
1303 if (sc->sc_dying)
1304 return;
1305
1306 /* Perform periodic stuff in process context. */
1307 usb_add_task(sc->sc_udev, &sc->sc_tick_task);
1308 }
1309
1310 Static void
1311 uax_tick_task(void *xsc)
1312 {
1313 struct uax_softc *sc = xsc;
1314 struct ifnet *ifp;
1315 struct mii_data *mii;
1316 int s;
1317
1318 DPRINTFN(15,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev),__func__));
1319
1320 if (sc->sc_dying)
1321 return;
1322
1323 ifp = GET_IFP(sc);
1324 mii = GET_MII(sc);
1325 if (mii == NULL)
1326 return;
1327
1328 s = splnet();
1329
1330 mii_tick(mii);
1331 if (!sc->sc_link) {
1332 mii_pollstat(mii); /* XXX FreeBSD has removed this call */
1333 if (mii->mii_media_status & IFM_ACTIVE &&
1334 IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
1335 DPRINTFN(2,("%s: %s: got link\n",
1336 USBDEVNAME(sc->sc_dev),__func__));
1337 sc->sc_link++;
1338 if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
1339 uax_start(ifp);
1340 }
1341 }
1342
1343 usb_callout(sc->sc_stat_ch, hz, uax_tick, sc);
1344
1345 splx(s);
1346 }
1347
1348 Static int
1349 uax_openpipes(struct uax_softc *sc)
1350 {
1351 struct uax_chain *c;
1352 usbd_status err;
1353 int i;
1354
1355 /* Open RX and TX pipes. */
1356 err = usbd_open_pipe(sc->sc_iface, sc->sc_ed[UAX_ENDPT_RX],
1357 USBD_EXCLUSIVE_USE, &sc->sc_ep[UAX_ENDPT_RX]);
1358 if (err) {
1359 printf("%s: open rx pipe failed: %s\n",
1360 USBDEVNAME(sc->sc_dev), usbd_errstr(err));
1361 return (EIO);
1362 }
1363 err = usbd_open_pipe(sc->sc_iface, sc->sc_ed[UAX_ENDPT_TX],
1364 USBD_EXCLUSIVE_USE, &sc->sc_ep[UAX_ENDPT_TX]);
1365 if (err) {
1366 printf("%s: open tx pipe failed: %s\n",
1367 USBDEVNAME(sc->sc_dev), usbd_errstr(err));
1368 return (EIO);
1369 }
1370 err = usbd_open_pipe_intr(sc->sc_iface, sc->sc_ed[UAX_ENDPT_INTR],
1371 USBD_EXCLUSIVE_USE, &sc->sc_ep[UAX_ENDPT_INTR], sc,
1372 &sc->sc_ibuf, UAX_INTR_PKTLEN, uax_intr,
1373 UAX_INTR_INTERVAL);
1374 if (err) {
1375 printf("%s: open intr pipe failed: %s\n",
1376 USBDEVNAME(sc->sc_dev), usbd_errstr(err));
1377 return (EIO);
1378 }
1379
1380 /* Start up the receive pipe. */
1381 for (i = 0; i < UAX_RX_LIST_CNT; i++) {
1382 c = &sc->sc_rx_chain[i];
1383 usbd_setup_xfer(c->uch_xfer, sc->sc_ep[UAX_ENDPT_RX],
1384 c, c->uch_buf, UAX_BUFSZ,
1385 USBD_SHORT_XFER_OK | USBD_NO_COPY, USBD_NO_TIMEOUT,
1386 uax_rxeof);
1387 (void)usbd_transfer(c->uch_xfer); /* XXX */
1388 DPRINTFN(5,("%s: %s: start read\n", USBDEVNAME(sc->sc_dev),
1389 __func__));
1390
1391 }
1392 return (0);
1393 }
1394
1395 Static void
1396 uax_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
1397 {
1398 struct uax_softc *sc = priv;
1399 struct ifnet *ifp = GET_IFP(sc);
1400 /*struct uax_intrpkt *p = &sc->sc_ibuf;*/
1401
1402 DPRINTFN(15,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev),__func__));
1403
1404 if (sc->sc_dying)
1405 return;
1406
1407 if (!(ifp->if_flags & IFF_RUNNING))
1408 return;
1409
1410 if (status != USBD_NORMAL_COMPLETION) {
1411 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
1412 return;
1413 }
1414 sc->sc_intr_errs++;
1415 if (usbd_ratecheck(&sc->sc_rx_notice)) {
1416 printf("%s: %u usb errors on intr: %s\n",
1417 USBDEVNAME(sc->sc_dev), sc->sc_intr_errs,
1418 usbd_errstr(status));
1419 sc->sc_intr_errs = 0;
1420 }
1421 if (status == USBD_STALLED)
1422 usbd_clear_endpoint_stall(sc->sc_ep[UAX_ENDPT_RX]);
1423 return;
1424 }
1425
1426 }
1427
1428 /* Polynomial calculation taken from the Windows driver. */
1429 Static u_int32_t
1430 uax_crc(u_int8_t *eaddr)
1431 {
1432 u_int32_t crc32;
1433 u_int8_t byte, carry;
1434 int i, j;
1435
1436 crc32 = 0xffffffff;
1437 for (i = 0; i < ETHER_ADDR_LEN; i++) {
1438 byte = eaddr[i];
1439 for (j = 0; j < 8; j++) {
1440 carry = byte & 1;
1441 if (crc32 & 0x80000000)
1442 carry ^= 1;
1443 crc32 <<= 1;
1444 byte >>= 1;
1445 if (carry)
1446 crc32 ^= 0x04c11db7;
1447 }
1448 }
1449 return (crc32);
1450 }
1451
1452 Static void
1453 uax_setmulti(struct uax_softc *sc)
1454 {
1455 struct ifnet *ifp;
1456 struct ether_multi *enm;
1457 struct ether_multistep step;
1458 u_int32_t h;
1459 int nmcast;
1460
1461 DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
1462
1463 ifp = GET_IFP(sc);
1464
1465 sc->sc_packet_filter &= ~(UAX_RX_PROMISCUOUS |
1466 UAX_RX_ALL_MULTICAST |
1467 UAX_RX_MULTICAST);
1468 if (ifp->if_flags & IFF_PROMISC) {
1469 sc->sc_packet_filter |= UAX_RX_PROMISCUOUS;
1470 } else {
1471 ifp->if_flags &= ~IFF_ALLMULTI;
1472
1473 memset(sc->sc_mcast, 0, sizeof sc->sc_mcast);
1474 nmcast = 0;
1475 ETHER_FIRST_MULTI(step, &sc->sc_ec, enm);
1476 while (enm != NULL) {
1477 if (memcmp(enm->enm_addrlo,
1478 enm->enm_addrhi, ETHER_ADDR_LEN) != 0) {
1479 ifp->if_flags |= IFF_ALLMULTI;
1480 sc->sc_packet_filter |= UAX_RX_ALL_MULTICAST;
1481 nmcast = 0;
1482 break;
1483 }
1484 h = (uax_crc(enm->enm_addrlo) >> 26) & 0x3f;
1485 sc->sc_mcast[h / 8] |= 1 << (h % 8);
1486
1487 ETHER_NEXT_MULTI(step, enm);
1488 nmcast++;
1489 }
1490 if (nmcast > 0)
1491 sc->sc_packet_filter |= UAX_RX_MULTICAST;
1492 }
1493 /* Set the multicast filter. */
1494 (void)uax_request(sc, UT_WRITE_VENDOR_DEVICE, UAX_WRITE_MULTI_FILTER,
1495 0, 0, sizeof sc->sc_mcast, &sc->sc_mcast);
1496 /* And tell the chip which mode we want. */
1497 (void)uax_request(sc, UT_WRITE_VENDOR_DEVICE, UAX_WRITE_RX_CTRL,
1498 sc->sc_packet_filter, 0, 0, NULL);
1499 }
1500
Cache object: 6e22baf125f677dbcfb9df39c2d59f92
|