Merge from vendor branch GCC:
[dragonfly.git] / sys / dev / netif / axe / if_axe.c
1 /*
2  * Copyright (c) 1997, 1998, 1999, 2000-2003
3  *      Bill Paul <wpaul@windriver.com>.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *      This product includes software developed by Bill Paul.
16  * 4. Neither the name of the author nor the names of any co-contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
24  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
30  * THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  * $FreeBSD: src/sys/dev/usb/if_axe.c,v 1.10 2003/12/08 07:54:14 obrien Exp $
33  * $DragonFly: src/sys/dev/netif/axe/if_axe.c,v 1.17 2005/09/10 11:51:36 sephe Exp $
34  */
35 /*
36  * ASIX Electronics AX88172 USB 2.0 ethernet driver. Used in the
37  * LinkSys USB200M and various other adapters.
38  *
39  * Manuals available from:
40  * http://www.asix.com.tw/datasheet/mac/Ax88172.PDF
41  * Note: you need the manual for the AX88170 chip (USB 1.x ethernet
42  * controller) to find the definitions for the RX control register.
43  * http://www.asix.com.tw/datasheet/mac/Ax88170.PDF
44  *
45  * Written by Bill Paul <wpaul@windriver.com>
46  * Senior Engineer
47  * Wind River Systems
48  */
49
50 /*
51  * The AX88172 provides USB ethernet supports at 10 and 100Mbps.
52  * It uses an external PHY (reference designs use a RealTek chip),
53  * and has a 64-bit multicast hash filter. There is some information
54  * missing from the manual which one needs to know in order to make
55  * the chip function:
56  *
57  * - You must set bit 7 in the RX control register, otherwise the
58  *   chip won't receive any packets.
59  * - You must initialize all 3 IPG registers, or you won't be able
60  *   to send any packets.
61  *
62  * Note that this device appears to only support loading the station
63  * address via autload from the EEPROM (i.e. there's no way to manaully
64  * set it).
65  *
66  * (Adam Weinberger wanted me to name this driver if_gir.c.)
67  */
68
69 #include <sys/param.h>
70 #include <sys/systm.h>
71 #include <sys/sockio.h>
72 #include <sys/mbuf.h>
73 #include <sys/malloc.h>
74 #include <sys/kernel.h>
75 #include <sys/socket.h>
76 #include <sys/thread2.h>
77
78 #include <net/if.h>
79 #include <net/ifq_var.h>
80 #include <net/if_arp.h>
81 #include <net/ethernet.h>
82 #include <net/if_dl.h>
83 #include <net/if_media.h>
84
85 #include <net/bpf.h>
86
87 #include <sys/bus.h>
88 #include <machine/bus.h>
89
90 #include <bus/usb/usb.h>
91 #include <bus/usb/usbdi.h>
92 #include <bus/usb/usbdi_util.h>
93 #include <bus/usb/usbdivar.h>
94 #include <bus/usb/usbdevs.h>
95 #include <bus/usb/usb_ethersubr.h>
96
97 #include "../mii_layer//mii.h"
98 #include "../mii_layer/miivar.h"
99
100 /* "controller miibus0" required.  See GENERIC if you get errors here. */
101 #include "miibus_if.h"
102
103 #include "if_axereg.h"
104
105 /*
106  * Various supported device vendors/products.
107  */
108 Static struct axe_type axe_devs[] = {
109         { USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88172 },
110         { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DUBE100 },
111         { USB_VENDOR_JVC, USB_PRODUCT_JVC_MP_PRX1 },
112         { USB_VENDOR_LINKSYS2, USB_PRODUCT_LINKSYS2_USB200M },
113         { USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUAU2KTX },
114         { USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_FA120 },
115         { USB_VENDOR_SYSTEMTALKS, USB_PRODUCT_SYSTEMTALKS_SGCX2UL },
116         { USB_VENDOR_SITECOM, USB_PRODUCT_SITECOM_LN029 },
117         { 0, 0 }
118 };
119
120 Static int axe_match(device_ptr_t);
121 Static int axe_attach(device_ptr_t);
122 Static int axe_detach(device_ptr_t);
123
124 Static int axe_tx_list_init(struct axe_softc *);
125 Static int axe_rx_list_init(struct axe_softc *);
126 Static int axe_newbuf(struct axe_softc *, struct axe_chain *, struct mbuf *);
127 Static int axe_encap(struct axe_softc *, struct mbuf *, int);
128 Static void axe_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
129 Static void axe_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
130 Static void axe_tick(void *);
131 Static void axe_rxstart(struct ifnet *);
132 Static void axe_start(struct ifnet *);
133 Static int axe_ioctl(struct ifnet *, u_long, caddr_t, struct ucred *);
134 Static void axe_init(void *);
135 Static void axe_stop(struct axe_softc *);
136 Static void axe_watchdog(struct ifnet *);
137 Static void axe_shutdown(device_ptr_t);
138 Static int axe_miibus_readreg(device_ptr_t, int, int);
139 Static int axe_miibus_writereg(device_ptr_t, int, int, int);
140 Static void axe_miibus_statchg(device_ptr_t);
141 Static int axe_cmd(struct axe_softc *, int, int, int, void *);
142 Static int axe_ifmedia_upd(struct ifnet *);
143 Static void axe_ifmedia_sts(struct ifnet *, struct ifmediareq *);
144
145 Static void axe_setmulti(struct axe_softc *);
146
147 Static device_method_t axe_methods[] = {
148         /* Device interface */
149         DEVMETHOD(device_probe,         axe_match),
150         DEVMETHOD(device_attach,        axe_attach),
151         DEVMETHOD(device_detach,        axe_detach),
152         DEVMETHOD(device_shutdown,      axe_shutdown),
153
154         /* bus interface */
155         DEVMETHOD(bus_print_child,      bus_generic_print_child),
156         DEVMETHOD(bus_driver_added,     bus_generic_driver_added),
157
158         /* MII interface */
159         DEVMETHOD(miibus_readreg,       axe_miibus_readreg),
160         DEVMETHOD(miibus_writereg,      axe_miibus_writereg),
161         DEVMETHOD(miibus_statchg,       axe_miibus_statchg),
162
163         { 0, 0 }
164 };
165
166 Static driver_t axe_driver = {
167         "axe",
168         axe_methods,
169         sizeof(struct axe_softc)
170 };
171
172 Static devclass_t axe_devclass;
173
174 DRIVER_MODULE(axe, uhub, axe_driver, axe_devclass, usbd_driver_load, 0);
175 DRIVER_MODULE(miibus, axe, miibus_driver, miibus_devclass, 0, 0);
176 MODULE_DEPEND(axe, usb, 1, 1, 1);
177 MODULE_DEPEND(axe, miibus, 1, 1, 1);
178
179 Static int
180 axe_cmd(struct axe_softc *sc, int cmd, int index, int val, void *buf)
181 {
182         usb_device_request_t    req;
183         usbd_status             err;
184
185         if (sc->axe_dying)
186                 return(0);
187
188         if (AXE_CMD_DIR(cmd))
189                 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
190         else
191                 req.bmRequestType = UT_READ_VENDOR_DEVICE;
192         req.bRequest = AXE_CMD_CMD(cmd);
193         USETW(req.wValue, val);
194         USETW(req.wIndex, index);
195         USETW(req.wLength, AXE_CMD_LEN(cmd));
196
197         err = usbd_do_request(sc->axe_udev, &req, buf);
198
199         if (err)
200                 return(-1);
201
202         return(0);
203 }
204
205 Static int
206 axe_miibus_readreg(device_ptr_t dev, int phy, int reg)
207 {
208         struct axe_softc        *sc = USBGETSOFTC(dev);
209         usbd_status             err;
210         u_int16_t               val;
211
212         crit_enter();
213
214         if (sc->axe_dying) {
215                 crit_exit();
216                 return(0);
217         }
218
219 #ifdef notdef
220         /*
221          * The chip tells us the MII address of any supported
222          * PHYs attached to the chip, so only read from those.
223          */
224
225         if (sc->axe_phyaddrs[0] != AXE_NOPHY && phy != sc->axe_phyaddrs[0]) {
226                 crit_exit();
227                 return (0);
228         }
229
230         if (sc->axe_phyaddrs[1] != AXE_NOPHY && phy != sc->axe_phyaddrs[1]) {
231                 crit_exit();
232                 return (0);
233         }
234 #endif
235         if (sc->axe_phyaddrs[0] != 0xFF && sc->axe_phyaddrs[0] != phy) {
236                 crit_exit();
237                 return (0);
238         }
239
240         axe_cmd(sc, AXE_CMD_MII_OPMODE_SW, 0, 0, NULL);
241         err = axe_cmd(sc, AXE_CMD_MII_READ_REG, reg, phy, (void *)&val);
242         axe_cmd(sc, AXE_CMD_MII_OPMODE_HW, 0, 0, NULL);
243
244         crit_exit();
245
246         if (err) {
247                 if_printf(&sc->arpcom.ac_if, "read PHY failed\n");
248                 return(-1);
249         }
250
251         if (val)
252                 sc->axe_phyaddrs[0] = phy;
253
254         return (val);
255 }
256
257 Static int
258 axe_miibus_writereg(device_ptr_t dev, int phy, int reg, int val)
259 {
260         struct axe_softc        *sc = USBGETSOFTC(dev);
261         usbd_status             err;
262
263         crit_enter();
264
265         if (sc->axe_dying) {
266                 crit_exit();
267                 return(0);
268         }
269
270         axe_cmd(sc, AXE_CMD_MII_OPMODE_SW, 0, 0, NULL);
271         err = axe_cmd(sc, AXE_CMD_MII_WRITE_REG, reg, phy, (void *)&val);
272         axe_cmd(sc, AXE_CMD_MII_OPMODE_HW, 0, 0, NULL);
273
274         crit_exit();
275
276         if (err) {
277                 if_printf(&sc->arpcom.ac_if, "write PHY failed\n");
278                 return(-1);
279         }
280
281         return (0);
282 }
283
284 Static void
285 axe_miibus_statchg(device_ptr_t dev)
286 {
287 #ifdef notdef
288         struct axe_softc        *sc = USBGETSOFTC(dev);
289         struct mii_data         *mii = GET_MII(sc);
290 #endif
291         /* doesn't seem to be necessary */
292
293         return;
294 }
295
296 /*
297  * Set media options.
298  */
299 Static int
300 axe_ifmedia_upd(struct ifnet *ifp)
301 {
302         struct axe_softc        *sc = ifp->if_softc;
303         struct mii_data         *mii = GET_MII(sc);
304
305         sc->axe_link = 0;
306         if (mii->mii_instance) {
307                 struct mii_softc        *miisc;
308                 LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
309                          mii_phy_reset(miisc);
310         }
311         mii_mediachg(mii);
312
313         return (0);
314 }
315
316 /*
317  * Report current media status.
318  */
319 Static void
320 axe_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
321 {
322         struct axe_softc        *sc = ifp->if_softc;
323         struct mii_data         *mii = GET_MII(sc);
324
325         mii_pollstat(mii);
326         ifmr->ifm_active = mii->mii_media_active;
327         ifmr->ifm_status = mii->mii_media_status;
328
329         return;
330 }
331
332 Static void
333 axe_setmulti(struct axe_softc *sc)
334 {
335         struct ifnet *ifp = &sc->arpcom.ac_if;
336         struct ifmultiaddr      *ifma;
337         u_int32_t               h = 0;
338         u_int16_t               rxmode;
339         u_int8_t                hashtbl[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
340
341         crit_enter();
342
343         axe_cmd(sc, AXE_CMD_RXCTL_READ, 0, 0, (void *)&rxmode);
344
345         if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
346                 rxmode |= AXE_RXCMD_ALLMULTI;
347                 axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, rxmode, NULL);
348                 crit_exit();
349                 return;
350         } else
351                 rxmode &= ~AXE_RXCMD_ALLMULTI;
352
353         LIST_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
354                 if (ifma->ifma_addr->sa_family != AF_LINK)
355                         continue;
356                 h = ether_crc32_be(
357                         LLADDR((struct sockaddr_dl *)ifma->ifma_addr),
358                         ETHER_ADDR_LEN);
359                 /* the filter bit position */
360                 h = (h >> 26) & 0x0000003F;
361                 hashtbl[h / 8] |= 1 << (h % 8);
362         }
363
364         axe_cmd(sc, AXE_CMD_WRITE_MCAST, 0, 0, (void *)&hashtbl);
365         axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, rxmode, NULL);
366
367         crit_exit();
368 }
369
370 Static void
371 axe_reset(struct axe_softc *sc)
372 {
373         if (sc->axe_dying)
374                 return;
375
376         if (usbd_set_config_no(sc->axe_udev, AXE_CONFIG_NO, 1) ||
377             usbd_device2interface_handle(sc->axe_udev, AXE_IFACE_IDX,
378             &sc->axe_iface)) {
379                 if_printf(&sc->arpcom.ac_if,
380                           "getting interface handle failed\n");
381         }
382
383         /* Wait a little while for the chip to get its brains in order. */
384         DELAY(1000);
385         return;
386 }
387
388 /*
389  * Probe for a AX88172 chip.
390  */
391 USB_MATCH(axe)
392 {
393         USB_MATCH_START(axe, uaa);
394         struct axe_type                 *t;
395
396         if (!uaa->iface)
397                 return(UMATCH_NONE);
398
399         t = axe_devs;
400         while(t->axe_vid) {
401                 if (uaa->vendor == t->axe_vid &&
402                     uaa->product == t->axe_did) {
403                         return(UMATCH_VENDOR_PRODUCT);
404                 }
405                 t++;
406         }
407
408         return(UMATCH_NONE);
409 }
410
411 /*
412  * Attach the interface. Allocate softc structures, do ifmedia
413  * setup and ethernet/BPF attach.
414  */
415 USB_ATTACH(axe)
416 {
417         USB_ATTACH_START(axe, sc, uaa);
418         char                    devinfo[1024];
419         u_char                  eaddr[ETHER_ADDR_LEN];
420         struct ifnet            *ifp;
421         usb_interface_descriptor_t      *id;
422         usb_endpoint_descriptor_t       *ed;
423         int                     i;
424
425         sc->axe_udev = uaa->device;
426         callout_init(&sc->axe_stat_timer);
427
428         if (usbd_set_config_no(sc->axe_udev, AXE_CONFIG_NO, 1)) {
429                 device_printf(self, "setting config no %d failed\n",
430                     AXE_CONFIG_NO);
431                 USB_ATTACH_ERROR_RETURN;
432         }
433
434         if (usbd_device2interface_handle(uaa->device,
435             AXE_IFACE_IDX, &sc->axe_iface)) {
436                 device_printf(self, "getting interface handle failed\n");
437                 USB_ATTACH_ERROR_RETURN;
438         }
439
440         id = usbd_get_interface_descriptor(sc->axe_iface);
441
442         usbd_devinfo(uaa->device, 0, devinfo);
443         device_set_desc_copy(self, devinfo);
444         device_printf(self, "%s\n", devinfo);
445
446         /* Find endpoints. */
447         for (i = 0; i < id->bNumEndpoints; i++) {
448                 ed = usbd_interface2endpoint_descriptor(sc->axe_iface, i);
449                 if (!ed) {
450                         device_printf(self, "couldn't get ep %d\n", i);
451                         USB_ATTACH_ERROR_RETURN;
452                 }
453                 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
454                     UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
455                         sc->axe_ed[AXE_ENDPT_RX] = ed->bEndpointAddress;
456                 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
457                            UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
458                         sc->axe_ed[AXE_ENDPT_TX] = ed->bEndpointAddress;
459                 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
460                            UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
461                         sc->axe_ed[AXE_ENDPT_INTR] = ed->bEndpointAddress;
462                 }
463         }
464
465         /*
466          * Get station address.
467          */
468         axe_cmd(sc, AXE_CMD_READ_NODEID, 0, 0, &eaddr);
469
470         /*
471          * Load IPG values and PHY indexes.
472          */
473         axe_cmd(sc, AXE_CMD_READ_IPG012, 0, 0, (void *)&sc->axe_ipgs);
474         axe_cmd(sc, AXE_CMD_READ_PHYID, 0, 0, (void *)&sc->axe_phyaddrs);
475
476         /*
477          * Work around broken adapters that appear to lie about
478          * their PHY addresses.
479          */
480         sc->axe_phyaddrs[0] = sc->axe_phyaddrs[1] = 0xFF;
481
482         ifp = &sc->arpcom.ac_if;
483         ifp->if_softc = sc;
484         if_initname(ifp, device_get_name(self), device_get_unit(self));
485         ifp->if_mtu = ETHERMTU;
486         ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
487         ifp->if_ioctl = axe_ioctl;
488         ifp->if_start = axe_start;
489         ifp->if_watchdog = axe_watchdog;
490         ifp->if_init = axe_init;
491         ifp->if_baudrate = 10000000;
492         ifq_set_maxlen(&ifp->if_snd, IFQ_MAXLEN);
493         ifq_set_ready(&ifp->if_snd);
494
495         if (mii_phy_probe(self, &sc->axe_miibus,
496             axe_ifmedia_upd, axe_ifmedia_sts)) {
497                 device_printf(self, "MII without any PHY!\n");
498                 USB_ATTACH_ERROR_RETURN;
499         }
500
501         /*
502          * Call MI attach routine.
503          */
504
505         ether_ifattach(ifp, eaddr);
506
507         sc->axe_dying = 0;
508
509         usb_register_netisr();
510
511         USB_ATTACH_SUCCESS_RETURN;
512 }
513
514 Static int
515 axe_detach(device_ptr_t dev)
516 {
517         struct axe_softc *sc = device_get_softc(dev);
518         struct ifnet *ifp = &sc->arpcom.ac_if;
519
520         crit_enter();
521
522         sc->axe_dying = 1;
523         callout_stop(&sc->axe_stat_timer);
524         ether_ifdetach(ifp);
525
526         if (sc->axe_ep[AXE_ENDPT_TX] != NULL)
527                 usbd_abort_pipe(sc->axe_ep[AXE_ENDPT_TX]);
528         if (sc->axe_ep[AXE_ENDPT_RX] != NULL)
529                 usbd_abort_pipe(sc->axe_ep[AXE_ENDPT_RX]);
530         if (sc->axe_ep[AXE_ENDPT_INTR] != NULL)
531                 usbd_abort_pipe(sc->axe_ep[AXE_ENDPT_INTR]);
532
533         crit_exit();
534
535         return(0);
536 }
537
538 /*
539  * Initialize an RX descriptor and attach an MBUF cluster.
540  */
541 Static int
542 axe_newbuf(struct axe_softc *sc, struct axe_chain *c, struct mbuf *m)
543 {
544         struct mbuf             *m_new = NULL;
545
546         if (m == NULL) {
547                 m_new = m_getcl(MB_DONTWAIT, MT_DATA, M_PKTHDR);
548                 if (m_new == NULL) {
549                         if_printf(&sc->arpcom.ac_if, "no memory for rx list "
550                             "-- packet dropped!\n");
551                         return(ENOBUFS);
552                 }
553                 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
554         } else {
555                 m_new = m;
556                 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
557                 m_new->m_data = m_new->m_ext.ext_buf;
558         }
559
560         m_adj(m_new, ETHER_ALIGN);
561         c->axe_mbuf = m_new;
562
563         return(0);
564 }
565
566 Static int
567 axe_rx_list_init(struct axe_softc *sc)
568 {
569         struct axe_cdata        *cd;
570         struct axe_chain        *c;
571         int                     i;
572
573         cd = &sc->axe_cdata;
574         for (i = 0; i < AXE_RX_LIST_CNT; i++) {
575                 c = &cd->axe_rx_chain[i];
576                 c->axe_sc = sc;
577                 c->axe_idx = i;
578                 if (axe_newbuf(sc, c, NULL) == ENOBUFS)
579                         return(ENOBUFS);
580                 if (c->axe_xfer == NULL) {
581                         c->axe_xfer = usbd_alloc_xfer(sc->axe_udev);
582                         if (c->axe_xfer == NULL)
583                                 return(ENOBUFS);
584                 }
585         }
586
587         return(0);
588 }
589
590 Static int
591 axe_tx_list_init(struct axe_softc *sc)
592 {
593         struct axe_cdata        *cd;
594         struct axe_chain        *c;
595         int                     i;
596
597         cd = &sc->axe_cdata;
598         for (i = 0; i < AXE_TX_LIST_CNT; i++) {
599                 c = &cd->axe_tx_chain[i];
600                 c->axe_sc = sc;
601                 c->axe_idx = i;
602                 c->axe_mbuf = NULL;
603                 if (c->axe_xfer == NULL) {
604                         c->axe_xfer = usbd_alloc_xfer(sc->axe_udev);
605                         if (c->axe_xfer == NULL)
606                                 return(ENOBUFS);
607                 }
608                 c->axe_buf = malloc(AXE_BUFSZ, M_USBDEV, M_WAITOK);
609                 if (c->axe_buf == NULL)
610                         return(ENOBUFS);
611         }
612
613         return(0);
614 }
615
616 Static void
617 axe_rxstart(struct ifnet *ifp)
618 {
619         struct axe_softc *sc = ifp->if_softc;
620         struct axe_chain *c;
621
622         crit_enter();
623         c = &sc->axe_cdata.axe_rx_chain[sc->axe_cdata.axe_rx_prod];
624
625         if (axe_newbuf(sc, c, NULL) == ENOBUFS) {
626                 ifp->if_ierrors++;
627                 crit_exit();
628                 return;
629         }
630
631         /* Setup new transfer. */
632         usbd_setup_xfer(c->axe_xfer, sc->axe_ep[AXE_ENDPT_RX],
633             c, mtod(c->axe_mbuf, char *), AXE_BUFSZ, USBD_SHORT_XFER_OK,
634             USBD_NO_TIMEOUT, axe_rxeof);
635         usbd_transfer(c->axe_xfer);
636
637         crit_exit();
638 }
639
640 /*
641  * A frame has been uploaded: pass the resulting mbuf chain up to
642  * the higher level protocols.
643  */
644 Static void
645 axe_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
646 {
647         struct axe_chain *c = priv;
648         struct axe_softc *sc = c->axe_sc;
649         struct ifnet *ifp = &sc->arpcom.ac_if;
650         struct mbuf *m;
651         int total_len = 0;
652
653         crit_enter();
654
655         if (!(ifp->if_flags & IFF_RUNNING)) {
656                 crit_exit();
657                 return;
658         }
659
660         if (status != USBD_NORMAL_COMPLETION) {
661                 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
662                         crit_exit();
663                         return;
664                 }
665                 if (usbd_ratecheck(&sc->axe_rx_notice)) {
666                         if_printf(ifp, "usb error on rx: %s\n",
667                             usbd_errstr(status));
668                 }
669                 if (status == USBD_STALLED)
670                         usbd_clear_endpoint_stall(sc->axe_ep[AXE_ENDPT_RX]);
671                 goto done;
672         }
673
674         usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
675
676         m = c->axe_mbuf;
677
678         if (total_len < sizeof(struct ether_header)) {
679                 ifp->if_ierrors++;
680                 goto done;
681         }
682
683         ifp->if_ipackets++;
684         m->m_pkthdr.rcvif = ifp;
685         m->m_pkthdr.len = m->m_len = total_len;
686
687         /* Put the packet on the special USB input queue. */
688         usb_ether_input(m);
689         axe_rxstart(ifp);
690
691         crit_exit();
692         return;
693 done:
694         /* Setup new transfer. */
695         usbd_setup_xfer(c->axe_xfer, sc->axe_ep[AXE_ENDPT_RX],
696             c, mtod(c->axe_mbuf, char *), AXE_BUFSZ, USBD_SHORT_XFER_OK,
697             USBD_NO_TIMEOUT, axe_rxeof);
698         usbd_transfer(c->axe_xfer);
699
700         crit_exit();
701 }
702
703 /*
704  * A frame was downloaded to the chip. It's safe for us to clean up
705  * the list buffers.
706  */
707
708 Static void
709 axe_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
710 {
711         struct axe_chain *c = priv;
712         struct axe_softc *sc = c->axe_sc;
713         struct ifnet *ifp = &sc->arpcom.ac_if;
714         usbd_status err;
715
716         crit_enter();
717
718         if (status != USBD_NORMAL_COMPLETION) {
719                 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
720                         crit_exit();
721                         return;
722                 }
723                 if_printf(ifp, "usb error on tx: %s\n", usbd_errstr(status));
724                 if (status == USBD_STALLED)
725                         usbd_clear_endpoint_stall(sc->axe_ep[AXE_ENDPT_TX]);
726                 crit_exit();
727                 return;
728         }
729
730         ifp->if_timer = 0;
731         ifp->if_flags &= ~IFF_OACTIVE;
732         usbd_get_xfer_status(c->axe_xfer, NULL, NULL, NULL, &err);
733
734         if (c->axe_mbuf != NULL) {
735                 m_freem(c->axe_mbuf);
736                 c->axe_mbuf = NULL;
737         }
738
739         if (err)
740                 ifp->if_oerrors++;
741         else
742                 ifp->if_opackets++;
743
744         if (!ifq_is_empty(&ifp->if_snd))
745                 (*ifp->if_start)(ifp);
746
747         crit_exit();
748 }
749
750 Static void
751 axe_tick(void *xsc)
752 {
753         struct axe_softc *sc = xsc;
754         struct ifnet *ifp = &sc->arpcom.ac_if;
755         struct mii_data         *mii;
756
757         mii = GET_MII(sc);
758         if (mii == NULL)
759                 return;
760
761         crit_enter();
762
763         mii_tick(mii);
764         if (!sc->axe_link && mii->mii_media_status & IFM_ACTIVE &&
765             IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
766                 sc->axe_link++;
767                 if (!ifq_is_empty(&ifp->if_snd))
768                         axe_start(ifp);
769         }
770
771         callout_reset(&sc->axe_stat_timer, hz, axe_tick, sc);
772
773         crit_exit();
774 }
775
776 Static int
777 axe_encap(struct axe_softc *sc, struct mbuf *m, int idx)
778 {
779         struct axe_chain        *c;
780         usbd_status             err;
781
782         c = &sc->axe_cdata.axe_tx_chain[idx];
783
784         /*
785          * Copy the mbuf data into a contiguous buffer, leaving two
786          * bytes at the beginning to hold the frame length.
787          */
788         m_copydata(m, 0, m->m_pkthdr.len, c->axe_buf);
789         c->axe_mbuf = m;
790
791         usbd_setup_xfer(c->axe_xfer, sc->axe_ep[AXE_ENDPT_TX],
792             c, c->axe_buf, m->m_pkthdr.len, USBD_FORCE_SHORT_XFER,
793             10000, axe_txeof);
794
795         /* Transmit */
796         err = usbd_transfer(c->axe_xfer);
797         if (err != USBD_IN_PROGRESS) {
798                 axe_stop(sc);
799                 return(EIO);
800         }
801
802         sc->axe_cdata.axe_tx_cnt++;
803
804         return(0);
805 }
806
807 Static void
808 axe_start(struct ifnet *ifp)
809 {
810         struct axe_softc *sc = ifp->if_softc;
811         struct mbuf *m_head = NULL;
812
813         crit_enter();
814
815         if (!sc->axe_link) {
816                 crit_exit();
817                 return;
818         }
819
820         if (ifp->if_flags & IFF_OACTIVE) {
821                 crit_exit();
822                 return;
823         }
824
825         m_head = ifq_poll(&ifp->if_snd);
826         if (m_head == NULL) {
827                 crit_exit();
828                 return;
829         }
830
831         if (axe_encap(sc, m_head, 0)) {
832                 ifp->if_flags |= IFF_OACTIVE;
833                 crit_exit();
834                 return;
835         }
836         m_head = ifq_dequeue(&ifp->if_snd);
837
838         /*
839          * If there's a BPF listener, bounce a copy of this frame
840          * to him.
841          */
842         BPF_MTAP(ifp, m_head);
843
844         ifp->if_flags |= IFF_OACTIVE;
845
846         /*
847          * Set a timeout in case the chip goes out to lunch.
848          */
849         ifp->if_timer = 5;
850
851         crit_exit();
852 }
853
854 Static void
855 axe_init(void *xsc)
856 {
857         struct axe_softc        *sc = xsc;
858         struct ifnet            *ifp = &sc->arpcom.ac_if;
859         struct axe_chain        *c;
860         usbd_status             err;
861         int i, rxmode;
862
863         crit_enter();
864
865         if (ifp->if_flags & IFF_RUNNING) {
866                 crit_exit();
867                 return;
868         }
869
870         /*
871          * Cancel pending I/O and free all RX/TX buffers.
872          */
873
874         axe_reset(sc);
875
876 #ifdef notdef
877         /* Set MAC address */
878         axe_mac(sc, sc->arpcom.ac_enaddr, 1);
879 #endif
880
881         /* Enable RX logic. */
882
883         /* Init TX ring. */
884         if (axe_tx_list_init(sc) == ENOBUFS) {
885                 crit_exit();
886                 if_printf(ifp, "tx list init failed\n");
887                 return;
888         }
889
890         /* Init RX ring. */
891         if (axe_rx_list_init(sc) == ENOBUFS) {
892                 crit_exit();
893                 if_printf(ifp, "rx list init failed\n");
894                 return;
895         }
896
897         /* Set transmitter IPG values */
898         axe_cmd(sc, AXE_CMD_WRITE_IPG0, 0, sc->axe_ipgs[0], NULL);
899         axe_cmd(sc, AXE_CMD_WRITE_IPG1, 0, sc->axe_ipgs[1], NULL);
900         axe_cmd(sc, AXE_CMD_WRITE_IPG2, 0, sc->axe_ipgs[2], NULL);
901
902         /* Enable receiver, set RX mode */
903         rxmode = AXE_RXCMD_UNICAST|AXE_RXCMD_MULTICAST|AXE_RXCMD_ENABLE;
904
905         /* If we want promiscuous mode, set the allframes bit. */
906         if (ifp->if_flags & IFF_PROMISC)
907                 rxmode |= AXE_RXCMD_PROMISC;
908
909         if (ifp->if_flags & IFF_BROADCAST)
910                 rxmode |= AXE_RXCMD_BROADCAST;
911
912         axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, rxmode, NULL);
913
914         /* Load the multicast filter. */
915         axe_setmulti(sc);
916
917         /* Open RX and TX pipes. */
918         err = usbd_open_pipe(sc->axe_iface, sc->axe_ed[AXE_ENDPT_RX],
919             USBD_EXCLUSIVE_USE, &sc->axe_ep[AXE_ENDPT_RX]);
920         if (err) {
921                 crit_exit();
922                 if_printf(ifp, "open rx pipe failed: %s\n", usbd_errstr(err));
923                 return;
924         }
925
926         err = usbd_open_pipe(sc->axe_iface, sc->axe_ed[AXE_ENDPT_TX],
927             USBD_EXCLUSIVE_USE, &sc->axe_ep[AXE_ENDPT_TX]);
928         if (err) {
929                 crit_exit();
930                 if_printf(ifp, "open tx pipe failed: %s\n", usbd_errstr(err));
931                 return;
932         }
933
934         /* Start up the receive pipe. */
935         for (i = 0; i < AXE_RX_LIST_CNT; i++) {
936                 c = &sc->axe_cdata.axe_rx_chain[i];
937                 usbd_setup_xfer(c->axe_xfer, sc->axe_ep[AXE_ENDPT_RX],
938                     c, mtod(c->axe_mbuf, char *), AXE_BUFSZ,
939                     USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, axe_rxeof);
940                 usbd_transfer(c->axe_xfer);
941         }
942
943         ifp->if_flags |= IFF_RUNNING;
944         ifp->if_flags &= ~IFF_OACTIVE;
945
946         callout_reset(&sc->axe_stat_timer, hz, axe_tick, sc);
947
948         crit_exit();
949 }
950
951 Static int
952 axe_ioctl(struct ifnet *ifp, u_long command, caddr_t data, struct ucred *cr)
953 {
954         struct axe_softc        *sc = ifp->if_softc;
955         struct ifreq            *ifr = (struct ifreq *)data;
956         struct mii_data         *mii;
957         u_int16_t               rxmode;
958         int error = 0;
959
960         crit_enter();
961
962         switch(command) {
963         case SIOCSIFFLAGS:
964                 if (ifp->if_flags & IFF_UP) {
965                         if (ifp->if_flags & IFF_RUNNING &&
966                             ifp->if_flags & IFF_PROMISC &&
967                             !(sc->axe_if_flags & IFF_PROMISC)) {
968                                 axe_cmd(sc, AXE_CMD_RXCTL_READ,
969                                         0, 0, (void *)&rxmode);
970                                 rxmode |= AXE_RXCMD_PROMISC;
971                                 axe_cmd(sc, AXE_CMD_RXCTL_WRITE,
972                                         0, rxmode, NULL);
973                                 axe_setmulti(sc);
974                         } else if (ifp->if_flags & IFF_RUNNING &&
975                             !(ifp->if_flags & IFF_PROMISC) &&
976                             sc->axe_if_flags & IFF_PROMISC) {
977                                 axe_cmd(sc, AXE_CMD_RXCTL_READ,
978                                         0, 0, (void *)&rxmode);
979                                 rxmode &= ~AXE_RXCMD_PROMISC;
980                                 axe_cmd(sc, AXE_CMD_RXCTL_WRITE,
981                                         0, rxmode, NULL);
982                                 axe_setmulti(sc);
983                         } else if (!(ifp->if_flags & IFF_RUNNING))
984                                 axe_init(sc);
985                 } else {
986                         if (ifp->if_flags & IFF_RUNNING)
987                                 axe_stop(sc);
988                 }
989                 sc->axe_if_flags = ifp->if_flags;
990                 error = 0;
991                 break;
992         case SIOCADDMULTI:
993         case SIOCDELMULTI:
994                 axe_setmulti(sc);
995                 error = 0;
996                 break;
997         case SIOCGIFMEDIA:
998         case SIOCSIFMEDIA:
999                 mii = GET_MII(sc);
1000                 error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command);
1001                 break;
1002
1003         default:
1004                 error = ether_ioctl(ifp, command, data);
1005                 break;
1006         }
1007
1008         crit_exit();
1009
1010         return(error);
1011 }
1012
1013 Static void
1014 axe_watchdog(struct ifnet *ifp)
1015 {
1016         struct axe_softc *sc = ifp->if_softc;
1017         struct axe_chain *c;
1018         usbd_status stat;
1019
1020         crit_enter();
1021
1022         ifp->if_oerrors++;
1023         if_printf(ifp, "watchdog timeout\n");
1024
1025         c = &sc->axe_cdata.axe_tx_chain[0];
1026         usbd_get_xfer_status(c->axe_xfer, NULL, NULL, NULL, &stat);
1027         axe_txeof(c->axe_xfer, c, stat);
1028
1029         if (!ifq_is_empty(&ifp->if_snd))
1030                 axe_start(ifp);
1031
1032         crit_exit();
1033 }
1034
1035 /*
1036  * Stop the adapter and free any mbufs allocated to the
1037  * RX and TX lists.
1038  */
1039 Static void
1040 axe_stop(struct axe_softc *sc)
1041 {
1042         usbd_status             err;
1043         struct ifnet            *ifp;
1044         int i;
1045
1046         crit_enter();
1047
1048         ifp = &sc->arpcom.ac_if;
1049         ifp->if_timer = 0;
1050
1051         callout_stop(&sc->axe_stat_timer);
1052
1053         /* Stop transfers. */
1054         if (sc->axe_ep[AXE_ENDPT_RX] != NULL) {
1055                 err = usbd_abort_pipe(sc->axe_ep[AXE_ENDPT_RX]);
1056                 if (err) {
1057                         if_printf(ifp, "abort rx pipe failed: %s\n",
1058                             usbd_errstr(err));
1059                 }
1060                 err = usbd_close_pipe(sc->axe_ep[AXE_ENDPT_RX]);
1061                 if (err) {
1062                         if_printf(ifp, "close rx pipe failed: %s\n",
1063                             usbd_errstr(err));
1064                 }
1065                 sc->axe_ep[AXE_ENDPT_RX] = NULL;
1066         }
1067
1068         if (sc->axe_ep[AXE_ENDPT_TX] != NULL) {
1069                 err = usbd_abort_pipe(sc->axe_ep[AXE_ENDPT_TX]);
1070                 if (err) {
1071                         if_printf(ifp, "abort tx pipe failed: %s\n",
1072                             usbd_errstr(err));
1073                 }
1074                 err = usbd_close_pipe(sc->axe_ep[AXE_ENDPT_TX]);
1075                 if (err) {
1076                         if_printf(ifp, "close tx pipe failed: %s\n",
1077                             usbd_errstr(err));
1078                 }
1079                 sc->axe_ep[AXE_ENDPT_TX] = NULL;
1080         }
1081
1082         if (sc->axe_ep[AXE_ENDPT_INTR] != NULL) {
1083                 err = usbd_abort_pipe(sc->axe_ep[AXE_ENDPT_INTR]);
1084                 if (err) {
1085                         if_printf(ifp, "abort intr pipe failed: %s\n",
1086                             usbd_errstr(err));
1087                 }
1088                 err = usbd_close_pipe(sc->axe_ep[AXE_ENDPT_INTR]);
1089                 if (err) {
1090                         if_printf(ifp, "close intr pipe failed: %s\n",
1091                             usbd_errstr(err));
1092                 }
1093                 sc->axe_ep[AXE_ENDPT_INTR] = NULL;
1094         }
1095
1096         axe_reset(sc);
1097
1098         /* Free RX resources. */
1099         for (i = 0; i < AXE_RX_LIST_CNT; i++) {
1100                 if (sc->axe_cdata.axe_rx_chain[i].axe_buf != NULL) {
1101                         free(sc->axe_cdata.axe_rx_chain[i].axe_buf, M_USBDEV);
1102                         sc->axe_cdata.axe_rx_chain[i].axe_buf = NULL;
1103                 }
1104                 if (sc->axe_cdata.axe_rx_chain[i].axe_mbuf != NULL) {
1105                         m_freem(sc->axe_cdata.axe_rx_chain[i].axe_mbuf);
1106                         sc->axe_cdata.axe_rx_chain[i].axe_mbuf = NULL;
1107                 }
1108                 if (sc->axe_cdata.axe_rx_chain[i].axe_xfer != NULL) {
1109                         usbd_free_xfer(sc->axe_cdata.axe_rx_chain[i].axe_xfer);
1110                         sc->axe_cdata.axe_rx_chain[i].axe_xfer = NULL;
1111                 }
1112         }
1113
1114         /* Free TX resources. */
1115         for (i = 0; i < AXE_TX_LIST_CNT; i++) {
1116                 if (sc->axe_cdata.axe_tx_chain[i].axe_buf != NULL) {
1117                         free(sc->axe_cdata.axe_tx_chain[i].axe_buf, M_USBDEV);
1118                         sc->axe_cdata.axe_tx_chain[i].axe_buf = NULL;
1119                 }
1120                 if (sc->axe_cdata.axe_tx_chain[i].axe_mbuf != NULL) {
1121                         m_freem(sc->axe_cdata.axe_tx_chain[i].axe_mbuf);
1122                         sc->axe_cdata.axe_tx_chain[i].axe_mbuf = NULL;
1123                 }
1124                 if (sc->axe_cdata.axe_tx_chain[i].axe_xfer != NULL) {
1125                         usbd_free_xfer(sc->axe_cdata.axe_tx_chain[i].axe_xfer);
1126                         sc->axe_cdata.axe_tx_chain[i].axe_xfer = NULL;
1127                 }
1128         }
1129
1130         ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
1131         sc->axe_link = 0;
1132
1133         crit_exit();
1134 }
1135
1136 /*
1137  * Stop all chip I/O so that the kernel's probe routines don't
1138  * get confused by errant DMAs when rebooting.
1139  */
1140 Static void
1141 axe_shutdown(device_ptr_t dev)
1142 {
1143         struct axe_softc        *sc;
1144
1145         sc = device_get_softc(dev);
1146
1147         axe_stop(sc);
1148 }