Home | History | Annotate | Line # | Download | only in usb
if_axe.c revision 1.100
      1  1.100       mrg /*	$NetBSD: if_axe.c,v 1.100 2019/07/15 06:40:21 mrg Exp $	*/
      2   1.76     skrll /*	$OpenBSD: if_axe.c,v 1.137 2016/04/13 11:03:37 mpi Exp $ */
      3   1.35  pgoyette 
      4   1.35  pgoyette /*
      5   1.35  pgoyette  * Copyright (c) 2005, 2006, 2007 Jonathan Gray <jsg (at) openbsd.org>
      6   1.35  pgoyette  *
      7   1.35  pgoyette  * Permission to use, copy, modify, and distribute this software for any
      8   1.35  pgoyette  * purpose with or without fee is hereby granted, provided that the above
      9   1.35  pgoyette  * copyright notice and this permission notice appear in all copies.
     10   1.35  pgoyette  *
     11   1.35  pgoyette  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
     12   1.35  pgoyette  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     13   1.35  pgoyette  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     14   1.35  pgoyette  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     15   1.35  pgoyette  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     16   1.35  pgoyette  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     17   1.35  pgoyette  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     18   1.35  pgoyette  */
     19    1.1  augustss 
     20    1.1  augustss /*
     21    1.1  augustss  * Copyright (c) 1997, 1998, 1999, 2000-2003
     22    1.1  augustss  *	Bill Paul <wpaul (at) windriver.com>.  All rights reserved.
     23    1.1  augustss  *
     24    1.1  augustss  * Redistribution and use in source and binary forms, with or without
     25    1.1  augustss  * modification, are permitted provided that the following conditions
     26    1.1  augustss  * are met:
     27    1.1  augustss  * 1. Redistributions of source code must retain the above copyright
     28    1.1  augustss  *    notice, this list of conditions and the following disclaimer.
     29    1.1  augustss  * 2. Redistributions in binary form must reproduce the above copyright
     30    1.1  augustss  *    notice, this list of conditions and the following disclaimer in the
     31    1.1  augustss  *    documentation and/or other materials provided with the distribution.
     32    1.1  augustss  * 3. All advertising materials mentioning features or use of this software
     33    1.1  augustss  *    must display the following acknowledgement:
     34    1.1  augustss  *	This product includes software developed by Bill Paul.
     35    1.1  augustss  * 4. Neither the name of the author nor the names of any co-contributors
     36    1.1  augustss  *    may be used to endorse or promote products derived from this software
     37    1.1  augustss  *    without specific prior written permission.
     38    1.1  augustss  *
     39    1.1  augustss  * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
     40    1.1  augustss  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     41    1.1  augustss  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     42    1.1  augustss  * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
     43    1.1  augustss  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     44    1.1  augustss  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     45    1.1  augustss  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     46    1.1  augustss  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     47    1.1  augustss  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     48    1.1  augustss  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
     49    1.1  augustss  * THE POSSIBILITY OF SUCH DAMAGE.
     50    1.1  augustss  */
     51    1.1  augustss 
     52    1.1  augustss /*
     53   1.76     skrll  * ASIX Electronics AX88172/AX88178/AX88778 USB 2.0 ethernet driver.
     54   1.76     skrll  * Used in the LinkSys USB200M and various other adapters.
     55    1.1  augustss  *
     56    1.1  augustss  * Written by Bill Paul <wpaul (at) windriver.com>
     57    1.1  augustss  * Senior Engineer
     58    1.1  augustss  * Wind River Systems
     59    1.1  augustss  */
     60    1.1  augustss 
     61    1.1  augustss /*
     62    1.1  augustss  * The AX88172 provides USB ethernet supports at 10 and 100Mbps.
     63    1.1  augustss  * It uses an external PHY (reference designs use a RealTek chip),
     64    1.1  augustss  * and has a 64-bit multicast hash filter. There is some information
     65    1.1  augustss  * missing from the manual which one needs to know in order to make
     66    1.1  augustss  * the chip function:
     67    1.1  augustss  *
     68    1.1  augustss  * - You must set bit 7 in the RX control register, otherwise the
     69    1.1  augustss  *   chip won't receive any packets.
     70    1.1  augustss  * - You must initialize all 3 IPG registers, or you won't be able
     71    1.1  augustss  *   to send any packets.
     72    1.1  augustss  *
     73    1.1  augustss  * Note that this device appears to only support loading the station
     74   1.76     skrll  * address via autoload from the EEPROM (i.e. there's no way to manually
     75    1.1  augustss  * set it).
     76    1.1  augustss  *
     77    1.1  augustss  * (Adam Weinberger wanted me to name this driver if_gir.c.)
     78    1.1  augustss  */
     79    1.1  augustss 
     80    1.1  augustss /*
     81   1.76     skrll  * Ax88178 and Ax88772 support backported from the OpenBSD driver.
     82   1.76     skrll  * 2007/02/12, J.R. Oldroyd, fbsd (at) opal.com
     83   1.76     skrll  *
     84   1.76     skrll  * Manual here:
     85   1.76     skrll  * http://www.asix.com.tw/FrootAttach/datasheet/AX88178_datasheet_Rev10.pdf
     86   1.76     skrll  * http://www.asix.com.tw/FrootAttach/datasheet/AX88772_datasheet_Rev10.pdf
     87    1.1  augustss  */
     88    1.1  augustss 
     89    1.1  augustss #include <sys/cdefs.h>
     90  1.100       mrg __KERNEL_RCSID(0, "$NetBSD: if_axe.c,v 1.100 2019/07/15 06:40:21 mrg Exp $");
     91    1.1  augustss 
     92   1.62  christos #ifdef _KERNEL_OPT
     93    1.1  augustss #include "opt_inet.h"
     94   1.75     skrll #include "opt_usb.h"
     95   1.81   msaitoh #include "opt_net_mpsafe.h"
     96    1.1  augustss #endif
     97    1.1  augustss 
     98    1.1  augustss #include <sys/param.h>
     99   1.35  pgoyette #include <sys/bus.h>
    100   1.35  pgoyette #include <sys/device.h>
    101   1.35  pgoyette #include <sys/kernel.h>
    102   1.35  pgoyette #include <sys/mbuf.h>
    103   1.48  pgoyette #include <sys/module.h>
    104   1.21        ad #include <sys/mutex.h>
    105    1.1  augustss #include <sys/socket.h>
    106   1.35  pgoyette #include <sys/sockio.h>
    107   1.35  pgoyette #include <sys/systm.h>
    108    1.1  augustss 
    109   1.69  riastrad #include <sys/rndsource.h>
    110    1.1  augustss 
    111    1.1  augustss #include <net/if.h>
    112    1.1  augustss #include <net/if_dl.h>
    113   1.35  pgoyette #include <net/if_ether.h>
    114    1.1  augustss #include <net/if_media.h>
    115    1.1  augustss 
    116    1.1  augustss #include <net/bpf.h>
    117    1.1  augustss 
    118    1.1  augustss #include <dev/mii/mii.h>
    119    1.1  augustss #include <dev/mii/miivar.h>
    120    1.1  augustss 
    121    1.1  augustss #include <dev/usb/usb.h>
    122   1.76     skrll #include <dev/usb/usbhist.h>
    123    1.1  augustss #include <dev/usb/usbdi.h>
    124    1.1  augustss #include <dev/usb/usbdi_util.h>
    125   1.35  pgoyette #include <dev/usb/usbdivar.h>
    126    1.1  augustss #include <dev/usb/usbdevs.h>
    127    1.1  augustss 
    128    1.1  augustss #include <dev/usb/if_axereg.h>
    129    1.1  augustss 
    130   1.99       mrg struct axe_type {
    131   1.99       mrg 	struct usb_devno	axe_dev;
    132   1.99       mrg 	uint16_t		axe_flags;
    133   1.99       mrg };
    134   1.99       mrg 
    135   1.99       mrg struct axe_softc;
    136   1.99       mrg 
    137   1.99       mrg struct axe_chain {
    138   1.99       mrg 	struct axe_softc	*axe_sc;
    139   1.99       mrg 	struct usbd_xfer	*axe_xfer;
    140   1.99       mrg 	uint8_t			*axe_buf;
    141   1.99       mrg 	int			axe_accum;
    142   1.99       mrg 	int			axe_idx;
    143   1.99       mrg };
    144   1.99       mrg 
    145   1.99       mrg struct axe_cdata {
    146   1.99       mrg 	struct axe_chain	axe_tx_chain[AXE_TX_LIST_CNT];
    147   1.99       mrg 	struct axe_chain	axe_rx_chain[AXE_RX_LIST_CNT];
    148   1.99       mrg 	int			axe_tx_prod;
    149   1.99       mrg 	int			axe_tx_cons;
    150   1.99       mrg 	int			axe_tx_cnt;
    151   1.99       mrg 	int			axe_rx_prod;
    152   1.99       mrg };
    153   1.99       mrg 
    154   1.99       mrg struct axe_softc {
    155   1.99       mrg 	device_t axe_dev;
    156   1.99       mrg 	struct ethercom		axe_ec;
    157   1.99       mrg 	struct mii_data		axe_mii;
    158   1.99       mrg 	krndsource_t	rnd_source;
    159   1.99       mrg 	struct usbd_device *	axe_udev;
    160   1.99       mrg 	struct usbd_interface *	axe_iface;
    161   1.99       mrg 
    162   1.99       mrg 	uint16_t		axe_vendor;
    163   1.99       mrg 	uint16_t		axe_product;
    164  1.100       mrg 	uint16_t		axe_timer;
    165   1.99       mrg 	uint32_t		axe_flags;	/* copied from axe_type */
    166   1.99       mrg #define AX178		__BIT(0)	/* AX88178 */
    167   1.99       mrg #define AX772		__BIT(1)	/* AX88772 */
    168   1.99       mrg #define AX772A		__BIT(2)	/* AX88772A */
    169   1.99       mrg #define AX772B		__BIT(3)	/* AX88772B */
    170   1.99       mrg #define	AXSTD_FRAME	__BIT(12)
    171   1.99       mrg #define	AXCSUM_FRAME	__BIT(13)
    172   1.99       mrg 
    173   1.99       mrg 	int			axe_ed[AXE_ENDPT_MAX];
    174   1.99       mrg 	struct usbd_pipe *	axe_ep[AXE_ENDPT_MAX];
    175   1.99       mrg 	int			axe_if_flags;
    176   1.99       mrg 	int			axe_phyno;
    177   1.99       mrg 	struct axe_cdata	axe_cdata;
    178  1.100       mrg 	struct callout		axe_stat_ch;
    179   1.99       mrg 
    180   1.99       mrg 	uint8_t			axe_enaddr[ETHER_ADDR_LEN];
    181   1.99       mrg 
    182   1.99       mrg 	int			axe_refcnt;
    183   1.99       mrg 	bool			axe_dying;
    184  1.100       mrg 	bool			axe_stopping;
    185   1.99       mrg 	bool			axe_attached;
    186   1.99       mrg 
    187   1.99       mrg 	struct usb_task		axe_tick_task;
    188   1.99       mrg 
    189  1.100       mrg 	kmutex_t		axe_lock;
    190   1.99       mrg 	kmutex_t		axe_mii_lock;
    191  1.100       mrg 	kmutex_t		axe_rxlock;
    192  1.100       mrg 	kmutex_t		axe_txlock;
    193  1.100       mrg 	kcondvar_t		axe_detachcv;
    194   1.99       mrg 
    195   1.99       mrg 	int			axe_link;
    196   1.99       mrg 
    197   1.99       mrg 	uint8_t			axe_ipgs[3];
    198   1.99       mrg 	uint8_t 		axe_phyaddrs[2];
    199   1.99       mrg 	uint16_t		sc_pwrcfg;
    200   1.99       mrg 	uint16_t		sc_lenmask;
    201   1.99       mrg 
    202   1.99       mrg 	struct timeval		axe_rx_notice;
    203  1.100       mrg 	struct timeval		axe_tx_notice;
    204   1.99       mrg 	int			axe_bufsz;
    205   1.99       mrg 
    206   1.99       mrg #define sc_if	axe_ec.ec_if
    207   1.99       mrg };
    208   1.99       mrg 
    209   1.99       mrg #define	AXE_IS_178_FAMILY(sc)						  \
    210   1.99       mrg 	((sc)->axe_flags & (AX772 | AX772A | AX772B | AX178))
    211   1.99       mrg 
    212   1.99       mrg #define	AXE_IS_772(sc)							  \
    213   1.99       mrg 	((sc)->axe_flags & (AX772 | AX772A | AX772B))
    214   1.99       mrg 
    215   1.99       mrg #define AX_RXCSUM					\
    216   1.99       mrg     (IFCAP_CSUM_IPv4_Rx | 				\
    217   1.99       mrg      IFCAP_CSUM_TCPv4_Rx | IFCAP_CSUM_UDPv4_Rx |	\
    218   1.99       mrg      IFCAP_CSUM_TCPv6_Rx | IFCAP_CSUM_UDPv6_Rx)
    219   1.99       mrg 
    220   1.99       mrg #define AX_TXCSUM					\
    221   1.99       mrg     (IFCAP_CSUM_IPv4_Tx | 				\
    222   1.99       mrg      IFCAP_CSUM_TCPv4_Tx | IFCAP_CSUM_UDPv4_Tx |	\
    223   1.99       mrg      IFCAP_CSUM_TCPv6_Tx | IFCAP_CSUM_UDPv6_Tx)
    224   1.99       mrg 
    225   1.76     skrll /*
    226   1.76     skrll  * AXE_178_MAX_FRAME_BURST
    227   1.76     skrll  * max frame burst size for Ax88178 and Ax88772
    228   1.76     skrll  *	0	2048 bytes
    229   1.76     skrll  *	1	4096 bytes
    230   1.76     skrll  *	2	8192 bytes
    231   1.76     skrll  *	3	16384 bytes
    232   1.76     skrll  * use the largest your system can handle without USB stalling.
    233   1.76     skrll  *
    234   1.76     skrll  * NB: 88772 parts appear to generate lots of input errors with
    235   1.76     skrll  * a 2K rx buffer and 8K is only slightly faster than 4K on an
    236   1.76     skrll  * EHCI port on a T42 so change at your own risk.
    237   1.76     skrll  */
    238   1.76     skrll #define AXE_178_MAX_FRAME_BURST	1
    239   1.76     skrll 
    240   1.76     skrll 
    241   1.76     skrll #ifdef USB_DEBUG
    242   1.76     skrll #ifndef AXE_DEBUG
    243   1.76     skrll #define axedebug 0
    244    1.1  augustss #else
    245   1.76     skrll static int axedebug = 20;
    246   1.76     skrll 
    247   1.76     skrll SYSCTL_SETUP(sysctl_hw_axe_setup, "sysctl hw.axe setup")
    248   1.76     skrll {
    249   1.76     skrll 	int err;
    250   1.76     skrll 	const struct sysctlnode *rnode;
    251   1.76     skrll 	const struct sysctlnode *cnode;
    252   1.76     skrll 
    253   1.76     skrll 	err = sysctl_createv(clog, 0, NULL, &rnode,
    254   1.76     skrll 	    CTLFLAG_PERMANENT, CTLTYPE_NODE, "axe",
    255   1.76     skrll 	    SYSCTL_DESCR("axe global controls"),
    256   1.76     skrll 	    NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL);
    257   1.76     skrll 
    258   1.76     skrll 	if (err)
    259   1.76     skrll 		goto fail;
    260   1.76     skrll 
    261   1.76     skrll 	/* control debugging printfs */
    262   1.76     skrll 	err = sysctl_createv(clog, 0, &rnode, &cnode,
    263   1.96   msaitoh 	    CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT,
    264   1.76     skrll 	    "debug", SYSCTL_DESCR("Enable debugging output"),
    265   1.76     skrll 	    NULL, 0, &axedebug, sizeof(axedebug), CTL_CREATE, CTL_EOL);
    266   1.76     skrll 	if (err)
    267   1.76     skrll 		goto fail;
    268   1.76     skrll 
    269   1.76     skrll 	return;
    270   1.76     skrll fail:
    271   1.76     skrll 	aprint_error("%s: sysctl_createv failed (err = %d)\n", __func__, err);
    272   1.76     skrll }
    273   1.76     skrll 
    274   1.76     skrll #endif /* AXE_DEBUG */
    275   1.76     skrll #endif /* USB_DEBUG */
    276   1.76     skrll 
    277   1.76     skrll #define DPRINTF(FMT,A,B,C,D)	USBHIST_LOGN(axedebug,1,FMT,A,B,C,D)
    278   1.76     skrll #define DPRINTFN(N,FMT,A,B,C,D)	USBHIST_LOGN(axedebug,N,FMT,A,B,C,D)
    279   1.76     skrll #define AXEHIST_FUNC()		USBHIST_FUNC()
    280   1.76     skrll #define AXEHIST_CALLED(name)	USBHIST_CALLED(axedebug)
    281    1.1  augustss 
    282    1.1  augustss /*
    283    1.1  augustss  * Various supported device vendors/products.
    284    1.1  augustss  */
    285   1.35  pgoyette static const struct axe_type axe_devs[] = {
    286   1.35  pgoyette 	{ { USB_VENDOR_ABOCOM,		USB_PRODUCT_ABOCOM_UFE2000}, 0 },
    287   1.35  pgoyette 	{ { USB_VENDOR_ACERCM,		USB_PRODUCT_ACERCM_EP1427X2}, 0 },
    288   1.35  pgoyette 	{ { USB_VENDOR_APPLE,		USB_PRODUCT_APPLE_ETHERNET }, AX772 },
    289    1.1  augustss 	{ { USB_VENDOR_ASIX,		USB_PRODUCT_ASIX_AX88172}, 0 },
    290   1.35  pgoyette 	{ { USB_VENDOR_ASIX,		USB_PRODUCT_ASIX_AX88772}, AX772 },
    291   1.35  pgoyette 	{ { USB_VENDOR_ASIX,		USB_PRODUCT_ASIX_AX88772A}, AX772 },
    292   1.76     skrll 	{ { USB_VENDOR_ASIX,		USB_PRODUCT_ASIX_AX88772B}, AX772B },
    293   1.76     skrll 	{ { USB_VENDOR_ASIX,		USB_PRODUCT_ASIX_AX88772B_1}, AX772B },
    294   1.35  pgoyette 	{ { USB_VENDOR_ASIX,		USB_PRODUCT_ASIX_AX88178}, AX178 },
    295   1.35  pgoyette 	{ { USB_VENDOR_ATEN,		USB_PRODUCT_ATEN_UC210T}, 0 },
    296   1.35  pgoyette 	{ { USB_VENDOR_BELKIN,		USB_PRODUCT_BELKIN_F5D5055 }, AX178 },
    297   1.35  pgoyette 	{ { USB_VENDOR_BILLIONTON,	USB_PRODUCT_BILLIONTON_USB2AR}, 0},
    298   1.76     skrll 	{ { USB_VENDOR_CISCOLINKSYS,	USB_PRODUCT_CISCOLINKSYS_USB200MV2}, AX772A },
    299    1.1  augustss 	{ { USB_VENDOR_COREGA,		USB_PRODUCT_COREGA_FETHER_USB2_TX }, 0},
    300    1.1  augustss 	{ { USB_VENDOR_DLINK,		USB_PRODUCT_DLINK_DUBE100}, 0 },
    301   1.35  pgoyette 	{ { USB_VENDOR_DLINK,		USB_PRODUCT_DLINK_DUBE100B1 }, AX772 },
    302   1.74     skrll 	{ { USB_VENDOR_DLINK2,		USB_PRODUCT_DLINK2_DUBE100B1 }, AX772 },
    303   1.76     skrll 	{ { USB_VENDOR_DLINK,		USB_PRODUCT_DLINK_DUBE100C1 }, AX772B },
    304   1.35  pgoyette 	{ { USB_VENDOR_GOODWAY,		USB_PRODUCT_GOODWAY_GWUSB2E}, 0 },
    305   1.35  pgoyette 	{ { USB_VENDOR_IODATA,		USB_PRODUCT_IODATA_ETGUS2 }, AX178 },
    306   1.35  pgoyette 	{ { USB_VENDOR_JVC,		USB_PRODUCT_JVC_MP_PRX1}, 0 },
    307   1.76     skrll 	{ { USB_VENDOR_LENOVO,		USB_PRODUCT_LENOVO_ETHERNET }, AX772B },
    308   1.97   msaitoh 	{ { USB_VENDOR_LINKSYS,		USB_PRODUCT_LINKSYS_HG20F9}, AX772B },
    309    1.1  augustss 	{ { USB_VENDOR_LINKSYS2,	USB_PRODUCT_LINKSYS2_USB200M}, 0 },
    310   1.35  pgoyette 	{ { USB_VENDOR_LINKSYS4,	USB_PRODUCT_LINKSYS4_USB1000 }, AX178 },
    311   1.35  pgoyette 	{ { USB_VENDOR_LOGITEC,		USB_PRODUCT_LOGITEC_LAN_GTJU2}, AX178 },
    312   1.35  pgoyette 	{ { USB_VENDOR_MELCO,		USB_PRODUCT_MELCO_LUAU2GT}, AX178 },
    313    1.2  augustss 	{ { USB_VENDOR_MELCO,		USB_PRODUCT_MELCO_LUAU2KTX}, 0 },
    314   1.35  pgoyette 	{ { USB_VENDOR_MSI,		USB_PRODUCT_MSI_AX88772A}, AX772 },
    315    1.1  augustss 	{ { USB_VENDOR_NETGEAR,		USB_PRODUCT_NETGEAR_FA120}, 0 },
    316   1.35  pgoyette 	{ { USB_VENDOR_OQO,		USB_PRODUCT_OQO_ETHER01PLUS }, AX772 },
    317   1.35  pgoyette 	{ { USB_VENDOR_PLANEX3,		USB_PRODUCT_PLANEX3_GU1000T }, AX178 },
    318   1.76     skrll 	{ { USB_VENDOR_SITECOM,		USB_PRODUCT_SITECOM_LN029}, 0 },
    319   1.76     skrll 	{ { USB_VENDOR_SITECOMEU,	USB_PRODUCT_SITECOMEU_LN028 }, AX178 },
    320   1.76     skrll 	{ { USB_VENDOR_SITECOMEU,	USB_PRODUCT_SITECOMEU_LN031 }, AX178 },
    321   1.35  pgoyette 	{ { USB_VENDOR_SYSTEMTALKS,	USB_PRODUCT_SYSTEMTALKS_SGCX2UL}, 0 },
    322    1.1  augustss };
    323    1.9  christos #define axe_lookup(v, p) ((const struct axe_type *)usb_lookup(axe_devs, v, p))
    324    1.1  augustss 
    325   1.76     skrll static const struct ax88772b_mfb ax88772b_mfb_table[] = {
    326   1.76     skrll 	{ 0x8000, 0x8001, 2048 },
    327   1.76     skrll 	{ 0x8100, 0x8147, 4096 },
    328   1.76     skrll 	{ 0x8200, 0x81EB, 6144 },
    329   1.76     skrll 	{ 0x8300, 0x83D7, 8192 },
    330   1.76     skrll 	{ 0x8400, 0x851E, 16384 },
    331   1.76     skrll 	{ 0x8500, 0x8666, 20480 },
    332   1.76     skrll 	{ 0x8600, 0x87AE, 24576 },
    333   1.76     skrll 	{ 0x8700, 0x8A3D, 32768 }
    334   1.76     skrll };
    335   1.76     skrll 
    336   1.35  pgoyette int	axe_match(device_t, cfdata_t, void *);
    337   1.35  pgoyette void	axe_attach(device_t, device_t, void *);
    338   1.35  pgoyette int	axe_detach(device_t, int);
    339   1.35  pgoyette int	axe_activate(device_t, devact_t);
    340   1.35  pgoyette 
    341   1.35  pgoyette CFATTACH_DECL_NEW(axe, sizeof(struct axe_softc),
    342   1.35  pgoyette 	axe_match, axe_attach, axe_detach, axe_activate);
    343   1.35  pgoyette 
    344   1.35  pgoyette static int	axe_tx_list_init(struct axe_softc *);
    345   1.35  pgoyette static int	axe_rx_list_init(struct axe_softc *);
    346   1.35  pgoyette static int	axe_encap(struct axe_softc *, struct mbuf *, int);
    347   1.71     skrll static void	axe_rxeof(struct usbd_xfer *, void *, usbd_status);
    348   1.71     skrll static void	axe_txeof(struct usbd_xfer *, void *, usbd_status);
    349   1.35  pgoyette static void	axe_tick(void *);
    350   1.35  pgoyette static void	axe_tick_task(void *);
    351   1.35  pgoyette static void	axe_start(struct ifnet *);
    352  1.100       mrg static void	axe_start_locked(struct ifnet *);
    353   1.35  pgoyette static int	axe_ioctl(struct ifnet *, u_long, void *);
    354   1.35  pgoyette static int	axe_init(struct ifnet *);
    355  1.100       mrg static int	axe_init_locked(struct ifnet *);
    356   1.35  pgoyette static void	axe_stop(struct ifnet *, int);
    357  1.100       mrg static void	axe_stop_locked(struct ifnet *, int);
    358   1.35  pgoyette static void	axe_watchdog(struct ifnet *);
    359  1.100       mrg static int	axe_miibus_readreg(device_t, int, int, uint16_t *);
    360   1.95   msaitoh static int	axe_miibus_readreg_locked(device_t, int, int, uint16_t *);
    361  1.100       mrg static int	axe_miibus_writereg(device_t, int, int, uint16_t);
    362   1.95   msaitoh static int	axe_miibus_writereg_locked(device_t, int, int, uint16_t);
    363   1.56      matt static void	axe_miibus_statchg(struct ifnet *);
    364   1.35  pgoyette static int	axe_cmd(struct axe_softc *, int, int, int, void *);
    365   1.71     skrll static void	axe_reset(struct axe_softc *);
    366   1.35  pgoyette 
    367   1.35  pgoyette static void	axe_setmulti(struct axe_softc *);
    368  1.100       mrg static void	axe_setmulti_locked(struct axe_softc *);
    369   1.71     skrll static void	axe_lock_mii(struct axe_softc *);
    370   1.71     skrll static void	axe_unlock_mii(struct axe_softc *);
    371   1.35  pgoyette 
    372   1.35  pgoyette static void	axe_ax88178_init(struct axe_softc *);
    373   1.35  pgoyette static void	axe_ax88772_init(struct axe_softc *);
    374   1.82     ozaki static void	axe_ax88772a_init(struct axe_softc *);
    375   1.82     ozaki static void	axe_ax88772b_init(struct axe_softc *);
    376    1.1  augustss 
    377    1.1  augustss /* Get exclusive access to the MII registers */
    378   1.35  pgoyette static void
    379    1.1  augustss axe_lock_mii(struct axe_softc *sc)
    380    1.1  augustss {
    381   1.38   tsutsui 
    382  1.100       mrg 	mutex_enter(&sc->axe_lock);
    383  1.100       mrg 	sc->axe_refcnt++;
    384  1.100       mrg 	mutex_exit(&sc->axe_lock);
    385  1.100       mrg 
    386  1.100       mrg 	mutex_enter(&sc->axe_mii_lock);
    387  1.100       mrg }
    388  1.100       mrg 
    389  1.100       mrg static void
    390  1.100       mrg axe_lock_mii_sc_locked(struct axe_softc *sc)
    391  1.100       mrg {
    392  1.100       mrg 	KASSERT(mutex_owned(&sc->axe_lock));
    393  1.100       mrg 
    394    1.1  augustss 	sc->axe_refcnt++;
    395   1.21        ad 	mutex_enter(&sc->axe_mii_lock);
    396    1.1  augustss }
    397    1.1  augustss 
    398   1.35  pgoyette static void
    399    1.1  augustss axe_unlock_mii(struct axe_softc *sc)
    400    1.1  augustss {
    401   1.38   tsutsui 
    402   1.21        ad 	mutex_exit(&sc->axe_mii_lock);
    403  1.100       mrg 	mutex_enter(&sc->axe_lock);
    404    1.1  augustss 	if (--sc->axe_refcnt < 0)
    405  1.100       mrg 		cv_broadcast(&sc->axe_detachcv);
    406  1.100       mrg 	mutex_exit(&sc->axe_lock);
    407  1.100       mrg }
    408  1.100       mrg 
    409  1.100       mrg static void
    410  1.100       mrg axe_unlock_mii_sc_locked(struct axe_softc *sc)
    411  1.100       mrg {
    412  1.100       mrg 	KASSERT(mutex_owned(&sc->axe_lock));
    413  1.100       mrg 
    414  1.100       mrg 	mutex_exit(&sc->axe_mii_lock);
    415  1.100       mrg 	if (--sc->axe_refcnt < 0)
    416  1.100       mrg 		cv_broadcast(&sc->axe_detachcv);
    417    1.1  augustss }
    418    1.1  augustss 
    419   1.35  pgoyette static int
    420    1.1  augustss axe_cmd(struct axe_softc *sc, int cmd, int index, int val, void *buf)
    421    1.1  augustss {
    422   1.76     skrll 	AXEHIST_FUNC(); AXEHIST_CALLED();
    423   1.38   tsutsui 	usb_device_request_t req;
    424   1.38   tsutsui 	usbd_status err;
    425    1.1  augustss 
    426   1.21        ad 	KASSERT(mutex_owned(&sc->axe_mii_lock));
    427   1.21        ad 
    428    1.1  augustss 	if (sc->axe_dying)
    429   1.86  christos 		return -1;
    430    1.1  augustss 
    431   1.83  pgoyette 	DPRINTFN(20, "cmd %#jx index %#jx val %#jx", cmd, index, val, 0);
    432   1.76     skrll 
    433    1.1  augustss 	if (AXE_CMD_DIR(cmd))
    434    1.1  augustss 		req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
    435    1.1  augustss 	else
    436    1.1  augustss 		req.bmRequestType = UT_READ_VENDOR_DEVICE;
    437    1.1  augustss 	req.bRequest = AXE_CMD_CMD(cmd);
    438    1.1  augustss 	USETW(req.wValue, val);
    439    1.1  augustss 	USETW(req.wIndex, index);
    440    1.1  augustss 	USETW(req.wLength, AXE_CMD_LEN(cmd));
    441    1.1  augustss 
    442    1.1  augustss 	err = usbd_do_request(sc->axe_udev, &req, buf);
    443    1.1  augustss 
    444   1.35  pgoyette 	if (err) {
    445   1.83  pgoyette 		DPRINTF("cmd %jd err %jd", cmd, err, 0, 0);
    446   1.35  pgoyette 		return -1;
    447   1.35  pgoyette 	}
    448   1.35  pgoyette 	return 0;
    449    1.1  augustss }
    450    1.1  augustss 
    451   1.35  pgoyette static int
    452   1.95   msaitoh axe_miibus_readreg_locked(device_t dev, int phy, int reg, uint16_t *val)
    453    1.1  augustss {
    454   1.77     skrll 	AXEHIST_FUNC(); AXEHIST_CALLED();
    455   1.28    dyoung 	struct axe_softc *sc = device_private(dev);
    456   1.38   tsutsui 	usbd_status err;
    457   1.95   msaitoh 	uint16_t data;
    458    1.1  augustss 
    459  1.100       mrg 	mutex_enter(&sc->axe_lock);
    460  1.100       mrg 	if (sc->axe_dying || sc->axe_phyno != phy) {
    461  1.100       mrg 		mutex_exit(&sc->axe_lock);
    462  1.100       mrg 		return -1;
    463  1.100       mrg 	}
    464  1.100       mrg 	mutex_exit(&sc->axe_lock);
    465  1.100       mrg 
    466   1.83  pgoyette 	DPRINTFN(30, "phy 0x%jx reg 0x%jx\n", phy, reg, 0, 0);
    467   1.76     skrll 
    468   1.66       roy 	axe_cmd(sc, AXE_CMD_MII_OPMODE_SW, 0, 0, NULL);
    469   1.76     skrll 
    470   1.95   msaitoh 	err = axe_cmd(sc, AXE_CMD_MII_READ_REG, reg, phy, &data);
    471   1.66       roy 	axe_cmd(sc, AXE_CMD_MII_OPMODE_HW, 0, 0, NULL);
    472  1.100       mrg 
    473   1.66       roy 	if (err) {
    474   1.66       roy 		aprint_error_dev(sc->axe_dev, "read PHY failed\n");
    475   1.95   msaitoh 		return err;
    476   1.66       roy 	}
    477   1.66       roy 
    478   1.95   msaitoh 	*val = le16toh(data);
    479   1.76     skrll 	if (AXE_IS_772(sc) && reg == MII_BMSR) {
    480   1.66       roy 		/*
    481   1.76     skrll 		 * BMSR of AX88772 indicates that it supports extended
    482   1.66       roy 		 * capability but the extended status register is
    483   1.76     skrll 		 * reserved for embedded ethernet PHY. So clear the
    484   1.66       roy 		 * extended capability bit of BMSR.
    485   1.66       roy 		 */
    486   1.95   msaitoh 		*val &= ~BMSR_EXTCAP;
    487    1.1  augustss 	}
    488    1.1  augustss 
    489   1.95   msaitoh 	DPRINTFN(30, "phy 0x%jx reg 0x%jx val %#jx", phy, reg, *val, 0);
    490   1.66       roy 
    491   1.95   msaitoh 	return 0;
    492   1.66       roy }
    493   1.66       roy 
    494   1.66       roy static int
    495   1.95   msaitoh axe_miibus_readreg(device_t dev, int phy, int reg, uint16_t *val)
    496   1.66       roy {
    497   1.66       roy 	struct axe_softc *sc = device_private(dev);
    498   1.95   msaitoh 	int rv;
    499   1.66       roy 
    500  1.100       mrg 	mutex_enter(&sc->axe_lock);
    501  1.100       mrg 	if (sc->axe_dying || sc->axe_phyno != phy) {
    502  1.100       mrg 		mutex_exit(&sc->axe_lock);
    503   1.95   msaitoh 		return -1;
    504  1.100       mrg 	}
    505  1.100       mrg 	mutex_exit(&sc->axe_lock);
    506    1.1  augustss 
    507   1.66       roy 	axe_lock_mii(sc);
    508   1.95   msaitoh 	rv = axe_miibus_readreg_locked(dev, phy, reg, val);
    509   1.66       roy 	axe_unlock_mii(sc);
    510    1.1  augustss 
    511   1.95   msaitoh 	return rv;
    512    1.1  augustss }
    513    1.1  augustss 
    514   1.95   msaitoh static int
    515   1.95   msaitoh axe_miibus_writereg_locked(device_t dev, int phy, int reg, uint16_t aval)
    516    1.1  augustss {
    517   1.38   tsutsui 	struct axe_softc *sc = device_private(dev);
    518   1.38   tsutsui 	usbd_status err;
    519   1.38   tsutsui 	uint16_t val;
    520    1.1  augustss 
    521   1.66       roy 	val = htole16(aval);
    522    1.1  augustss 
    523    1.1  augustss 	axe_cmd(sc, AXE_CMD_MII_OPMODE_SW, 0, 0, NULL);
    524   1.86  christos 	err = axe_cmd(sc, AXE_CMD_MII_WRITE_REG, reg, phy, &val);
    525    1.1  augustss 	axe_cmd(sc, AXE_CMD_MII_OPMODE_HW, 0, 0, NULL);
    526    1.1  augustss 
    527    1.1  augustss 	if (err) {
    528   1.25      cube 		aprint_error_dev(sc->axe_dev, "write PHY failed\n");
    529   1.95   msaitoh 		return err;
    530    1.1  augustss 	}
    531   1.95   msaitoh 
    532   1.95   msaitoh 	return 0;
    533    1.1  augustss }
    534    1.1  augustss 
    535   1.95   msaitoh static int
    536   1.95   msaitoh axe_miibus_writereg(device_t dev, int phy, int reg, uint16_t aval)
    537   1.66       roy {
    538   1.66       roy 	struct axe_softc *sc = device_private(dev);
    539   1.95   msaitoh 	int rv;
    540   1.66       roy 
    541  1.100       mrg 	mutex_enter(&sc->axe_lock);
    542  1.100       mrg 	if (sc->axe_dying || sc->axe_phyno != phy) {
    543  1.100       mrg 		mutex_exit(&sc->axe_lock);
    544   1.95   msaitoh 		return -1;
    545  1.100       mrg 	}
    546  1.100       mrg 	mutex_exit(&sc->axe_lock);
    547   1.66       roy 
    548   1.66       roy 	axe_lock_mii(sc);
    549   1.95   msaitoh 	rv = axe_miibus_writereg_locked(dev, phy, reg, aval);
    550   1.66       roy 	axe_unlock_mii(sc);
    551   1.95   msaitoh 
    552   1.95   msaitoh 	return rv;
    553   1.66       roy }
    554   1.66       roy 
    555   1.66       roy static void
    556   1.56      matt axe_miibus_statchg(struct ifnet *ifp)
    557    1.1  augustss {
    558   1.76     skrll 	AXEHIST_FUNC(); AXEHIST_CALLED();
    559   1.76     skrll 
    560  1.100       mrg 	struct axe_softc * const sc = ifp->if_softc;
    561   1.38   tsutsui 	struct mii_data *mii = &sc->axe_mii;
    562    1.5  augustss 	int val, err;
    563    1.5  augustss 
    564  1.100       mrg 	if (sc->axe_dying)
    565  1.100       mrg 		return;
    566  1.100       mrg 
    567   1.76     skrll 	val = 0;
    568   1.76     skrll 	if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0) {
    569   1.76     skrll 		val |= AXE_MEDIA_FULL_DUPLEX;
    570   1.76     skrll 		if (AXE_IS_178_FAMILY(sc)) {
    571   1.76     skrll 			if ((IFM_OPTIONS(mii->mii_media_active) &
    572   1.76     skrll 			    IFM_ETH_TXPAUSE) != 0)
    573   1.76     skrll 				val |= AXE_178_MEDIA_TXFLOW_CONTROL_EN;
    574   1.76     skrll 			if ((IFM_OPTIONS(mii->mii_media_active) &
    575   1.76     skrll 			    IFM_ETH_RXPAUSE) != 0)
    576   1.76     skrll 				val |= AXE_178_MEDIA_RXFLOW_CONTROL_EN;
    577   1.76     skrll 		}
    578   1.76     skrll 	}
    579   1.76     skrll 	if (AXE_IS_178_FAMILY(sc)) {
    580   1.76     skrll 		val |= AXE_178_MEDIA_RX_EN | AXE_178_MEDIA_MAGIC;
    581   1.66       roy 		if (sc->axe_flags & AX178)
    582   1.66       roy 			val |= AXE_178_MEDIA_ENCK;
    583   1.35  pgoyette 		switch (IFM_SUBTYPE(mii->mii_media_active)) {
    584   1.38   tsutsui 		case IFM_1000_T:
    585   1.35  pgoyette 			val |= AXE_178_MEDIA_GMII | AXE_178_MEDIA_ENCK;
    586   1.35  pgoyette 			break;
    587   1.35  pgoyette 		case IFM_100_TX:
    588   1.35  pgoyette 			val |= AXE_178_MEDIA_100TX;
    589   1.35  pgoyette 			break;
    590   1.35  pgoyette 		case IFM_10_T:
    591   1.35  pgoyette 			/* doesn't need to be handled */
    592   1.35  pgoyette 			break;
    593   1.35  pgoyette 		}
    594   1.35  pgoyette 	}
    595   1.35  pgoyette 
    596   1.83  pgoyette 	DPRINTF("val=0x%jx", val, 0, 0, 0);
    597   1.21        ad 	axe_lock_mii(sc);
    598    1.5  augustss 	err = axe_cmd(sc, AXE_CMD_WRITE_MEDIA, 0, val, NULL);
    599   1.21        ad 	axe_unlock_mii(sc);
    600    1.5  augustss 	if (err) {
    601   1.25      cube 		aprint_error_dev(sc->axe_dev, "media change failed\n");
    602    1.5  augustss 		return;
    603    1.5  augustss 	}
    604    1.1  augustss }
    605    1.1  augustss 
    606   1.35  pgoyette static void
    607  1.100       mrg axe_setmulti_locked(struct axe_softc *sc)
    608    1.1  augustss {
    609   1.76     skrll 	AXEHIST_FUNC(); AXEHIST_CALLED();
    610   1.98   msaitoh 	struct ethercom *ec = &sc->axe_ec;
    611   1.38   tsutsui 	struct ifnet *ifp = &sc->sc_if;
    612   1.38   tsutsui 	struct ether_multi *enm;
    613   1.38   tsutsui 	struct ether_multistep step;
    614   1.38   tsutsui 	uint32_t h = 0;
    615   1.38   tsutsui 	uint16_t rxmode;
    616   1.38   tsutsui 	uint8_t hashtbl[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
    617    1.1  augustss 
    618  1.100       mrg 	KASSERT(mutex_owned(&sc->axe_mii_lock));
    619  1.100       mrg 
    620    1.1  augustss 	if (sc->axe_dying)
    621    1.1  augustss 		return;
    622    1.1  augustss 
    623   1.86  christos 	if (axe_cmd(sc, AXE_CMD_RXCTL_READ, 0, 0, &rxmode)) {
    624   1.86  christos 		aprint_error_dev(sc->axe_dev, "can't read rxmode");
    625   1.86  christos 		return;
    626   1.86  christos 	}
    627   1.10      tron 	rxmode = le16toh(rxmode);
    628    1.1  augustss 
    629   1.76     skrll 	rxmode &=
    630   1.76     skrll 	    ~(AXE_RXCMD_ALLMULTI | AXE_RXCMD_PROMISC |
    631   1.76     skrll 	    AXE_RXCMD_BROADCAST | AXE_RXCMD_MULTICAST);
    632   1.76     skrll 
    633   1.76     skrll 	rxmode |=
    634   1.76     skrll 	    (ifp->if_flags & IFF_BROADCAST) ? AXE_RXCMD_BROADCAST : 0;
    635   1.76     skrll 
    636   1.76     skrll 	if (ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC)) {
    637   1.76     skrll 		if (ifp->if_flags & IFF_PROMISC)
    638   1.76     skrll 			rxmode |= AXE_RXCMD_PROMISC;
    639   1.35  pgoyette 		goto allmulti;
    640   1.35  pgoyette 	}
    641    1.1  augustss 
    642   1.35  pgoyette 	/* Now program new ones */
    643   1.98   msaitoh 	ETHER_LOCK(ec);
    644   1.98   msaitoh 	ETHER_FIRST_MULTI(step, ec, enm);
    645    1.1  augustss 	while (enm != NULL) {
    646    1.1  augustss 		if (memcmp(enm->enm_addrlo, enm->enm_addrhi,
    647   1.98   msaitoh 		    ETHER_ADDR_LEN) != 0) {
    648   1.98   msaitoh 			ETHER_UNLOCK(ec);
    649    1.1  augustss 			goto allmulti;
    650   1.98   msaitoh 		}
    651    1.1  augustss 
    652    1.1  augustss 		h = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN) >> 26;
    653   1.35  pgoyette 		hashtbl[h >> 3] |= 1U << (h & 7);
    654    1.1  augustss 		ETHER_NEXT_MULTI(step, enm);
    655    1.1  augustss 	}
    656   1.98   msaitoh 	ETHER_UNLOCK(ec);
    657    1.1  augustss 	ifp->if_flags &= ~IFF_ALLMULTI;
    658   1.76     skrll 	rxmode |= AXE_RXCMD_MULTICAST;
    659   1.76     skrll 
    660   1.86  christos 	axe_cmd(sc, AXE_CMD_WRITE_MCAST, 0, 0, hashtbl);
    661    1.1  augustss 	axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, rxmode, NULL);
    662    1.1  augustss 	return;
    663   1.35  pgoyette 
    664   1.35  pgoyette  allmulti:
    665   1.35  pgoyette 	ifp->if_flags |= IFF_ALLMULTI;
    666   1.35  pgoyette 	rxmode |= AXE_RXCMD_ALLMULTI;
    667   1.35  pgoyette 	axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, rxmode, NULL);
    668  1.100       mrg }
    669  1.100       mrg 
    670  1.100       mrg static void
    671  1.100       mrg axe_setmulti(struct axe_softc *sc)
    672  1.100       mrg {
    673  1.100       mrg 	axe_lock_mii(sc);
    674  1.100       mrg 	axe_setmulti_locked(sc);
    675   1.35  pgoyette 	axe_unlock_mii(sc);
    676    1.1  augustss }
    677    1.1  augustss 
    678   1.88  christos static void
    679   1.88  christos axe_ax_init(struct axe_softc *sc)
    680   1.88  christos {
    681   1.89  christos 	int cmd = AXE_178_CMD_READ_NODEID;
    682   1.89  christos 
    683   1.88  christos 	if (sc->axe_flags & AX178) {
    684   1.88  christos 		axe_ax88178_init(sc);
    685   1.88  christos 	} else if (sc->axe_flags & AX772) {
    686   1.88  christos 		axe_ax88772_init(sc);
    687   1.88  christos 	} else if (sc->axe_flags & AX772A) {
    688   1.88  christos 		axe_ax88772a_init(sc);
    689   1.88  christos 	} else if (sc->axe_flags & AX772B) {
    690   1.88  christos 		axe_ax88772b_init(sc);
    691   1.89  christos 		return;
    692   1.89  christos 	} else {
    693   1.89  christos 		cmd = AXE_172_CMD_READ_NODEID;
    694   1.89  christos 	}
    695   1.89  christos 
    696   1.89  christos 	if (axe_cmd(sc, cmd, 0, 0, sc->axe_enaddr)) {
    697   1.89  christos 		aprint_error_dev(sc->axe_dev,
    698   1.89  christos 		    "failed to read ethernet address\n");
    699   1.88  christos 	}
    700   1.88  christos }
    701   1.88  christos 
    702   1.76     skrll 
    703   1.35  pgoyette static void
    704    1.1  augustss axe_reset(struct axe_softc *sc)
    705    1.1  augustss {
    706   1.38   tsutsui 
    707    1.1  augustss 	if (sc->axe_dying)
    708    1.1  augustss 		return;
    709   1.76     skrll 
    710   1.76     skrll 	/*
    711   1.76     skrll 	 * softnet_lock can be taken when NET_MPAFE is not defined when calling
    712  1.100       mrg 	 * if_addr_init -> if_init.  This doesn't mix well with the
    713   1.76     skrll 	 * usbd_delay_ms calls in the init routines as things like nd6_slowtimo
    714   1.76     skrll 	 * can fire during the wait and attempt to take softnet_lock and then
    715   1.76     skrll 	 * block the softclk thread meaing the wait never ends.
    716   1.76     skrll 	 */
    717   1.76     skrll #ifndef NET_MPSAFE
    718    1.1  augustss 	/* XXX What to reset? */
    719    1.1  augustss 
    720    1.1  augustss 	/* Wait a little while for the chip to get its brains in order. */
    721    1.1  augustss 	DELAY(1000);
    722   1.76     skrll #else
    723   1.76     skrll 	axe_lock_mii(sc);
    724   1.76     skrll 
    725   1.88  christos 	axe_ax_init(sc);
    726   1.88  christos 
    727   1.76     skrll 	axe_unlock_mii(sc);
    728   1.76     skrll #endif
    729    1.1  augustss }
    730    1.1  augustss 
    731   1.66       roy static int
    732   1.66       roy axe_get_phyno(struct axe_softc *sc, int sel)
    733   1.66       roy {
    734   1.66       roy 	int phyno;
    735   1.66       roy 
    736   1.66       roy 	switch (AXE_PHY_TYPE(sc->axe_phyaddrs[sel])) {
    737   1.66       roy 	case PHY_TYPE_100_HOME:
    738   1.66       roy 		/* FALLTHROUGH */
    739   1.66       roy 	case PHY_TYPE_GIG:
    740   1.66       roy 		phyno = AXE_PHY_NO(sc->axe_phyaddrs[sel]);
    741   1.66       roy 		break;
    742   1.66       roy 	case PHY_TYPE_SPECIAL:
    743   1.66       roy 		/* FALLTHROUGH */
    744   1.66       roy 	case PHY_TYPE_RSVD:
    745   1.66       roy 		/* FALLTHROUGH */
    746   1.66       roy 	case PHY_TYPE_NON_SUP:
    747   1.66       roy 		/* FALLTHROUGH */
    748   1.66       roy 	default:
    749   1.66       roy 		phyno = -1;
    750   1.66       roy 		break;
    751   1.66       roy 	}
    752   1.66       roy 
    753   1.66       roy 	return phyno;
    754   1.66       roy }
    755   1.66       roy 
    756   1.66       roy #define	AXE_GPIO_WRITE(x, y)	do {				\
    757   1.66       roy 	axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, (x), NULL);		\
    758   1.66       roy 	usbd_delay_ms(sc->axe_udev, hztoms(y));			\
    759   1.66       roy } while (0)
    760   1.66       roy 
    761   1.35  pgoyette static void
    762   1.35  pgoyette axe_ax88178_init(struct axe_softc *sc)
    763   1.35  pgoyette {
    764   1.76     skrll 	AXEHIST_FUNC(); AXEHIST_CALLED();
    765   1.66       roy 	int gpio0, ledmode, phymode;
    766   1.66       roy 	uint16_t eeprom, val;
    767   1.35  pgoyette 
    768   1.35  pgoyette 	axe_cmd(sc, AXE_CMD_SROM_WR_ENABLE, 0, 0, NULL);
    769   1.35  pgoyette 	/* XXX magic */
    770   1.86  christos 	if (axe_cmd(sc, AXE_CMD_SROM_READ, 0, 0x0017, &eeprom) != 0)
    771   1.86  christos 		eeprom = 0xffff;
    772   1.35  pgoyette 	axe_cmd(sc, AXE_CMD_SROM_WR_DISABLE, 0, 0, NULL);
    773   1.35  pgoyette 
    774   1.35  pgoyette 	eeprom = le16toh(eeprom);
    775   1.35  pgoyette 
    776   1.83  pgoyette 	DPRINTF("EEPROM is 0x%jx", eeprom, 0, 0, 0);
    777   1.35  pgoyette 
    778   1.35  pgoyette 	/* if EEPROM is invalid we have to use to GPIO0 */
    779   1.35  pgoyette 	if (eeprom == 0xffff) {
    780   1.66       roy 		phymode = AXE_PHY_MODE_MARVELL;
    781   1.35  pgoyette 		gpio0 = 1;
    782   1.66       roy 		ledmode = 0;
    783   1.35  pgoyette 	} else {
    784   1.66       roy 		phymode = eeprom & 0x7f;
    785   1.35  pgoyette 		gpio0 = (eeprom & 0x80) ? 0 : 1;
    786   1.66       roy 		ledmode = eeprom >> 8;
    787   1.35  pgoyette 	}
    788   1.35  pgoyette 
    789   1.83  pgoyette 	DPRINTF("use gpio0: %jd, phymode %jd", gpio0, phymode, 0, 0);
    790   1.35  pgoyette 
    791   1.66       roy 	/* Program GPIOs depending on PHY hardware. */
    792   1.66       roy 	switch (phymode) {
    793   1.66       roy 	case AXE_PHY_MODE_MARVELL:
    794   1.66       roy 		if (gpio0 == 1) {
    795   1.66       roy 			AXE_GPIO_WRITE(AXE_GPIO_RELOAD_EEPROM | AXE_GPIO0_EN,
    796   1.66       roy 			    hz / 32);
    797   1.66       roy 			AXE_GPIO_WRITE(AXE_GPIO0_EN | AXE_GPIO2 | AXE_GPIO2_EN,
    798   1.66       roy 			    hz / 32);
    799   1.66       roy 			AXE_GPIO_WRITE(AXE_GPIO0_EN | AXE_GPIO2_EN, hz / 4);
    800   1.66       roy 			AXE_GPIO_WRITE(AXE_GPIO0_EN | AXE_GPIO2 | AXE_GPIO2_EN,
    801   1.66       roy 			    hz / 32);
    802   1.66       roy 		} else {
    803   1.66       roy 			AXE_GPIO_WRITE(AXE_GPIO_RELOAD_EEPROM | AXE_GPIO1 |
    804   1.66       roy 			    AXE_GPIO1_EN, hz / 3);
    805   1.66       roy 			if (ledmode == 1) {
    806   1.66       roy 				AXE_GPIO_WRITE(AXE_GPIO1_EN, hz / 3);
    807   1.66       roy 				AXE_GPIO_WRITE(AXE_GPIO1 | AXE_GPIO1_EN,
    808   1.66       roy 				    hz / 3);
    809   1.66       roy 			} else {
    810   1.66       roy 				AXE_GPIO_WRITE(AXE_GPIO1 | AXE_GPIO1_EN |
    811   1.66       roy 				    AXE_GPIO2 | AXE_GPIO2_EN, hz / 32);
    812   1.66       roy 				AXE_GPIO_WRITE(AXE_GPIO1 | AXE_GPIO1_EN |
    813   1.66       roy 				    AXE_GPIO2_EN, hz / 4);
    814   1.66       roy 				AXE_GPIO_WRITE(AXE_GPIO1 | AXE_GPIO1_EN |
    815   1.66       roy 				    AXE_GPIO2 | AXE_GPIO2_EN, hz / 32);
    816   1.66       roy 			}
    817   1.66       roy 		}
    818   1.66       roy 		break;
    819   1.66       roy 	case AXE_PHY_MODE_CICADA:
    820   1.66       roy 	case AXE_PHY_MODE_CICADA_V2:
    821   1.66       roy 	case AXE_PHY_MODE_CICADA_V2_ASIX:
    822   1.66       roy 		if (gpio0 == 1)
    823   1.66       roy 			AXE_GPIO_WRITE(AXE_GPIO_RELOAD_EEPROM | AXE_GPIO0 |
    824   1.66       roy 			    AXE_GPIO0_EN, hz / 32);
    825   1.66       roy 		else
    826   1.66       roy 			AXE_GPIO_WRITE(AXE_GPIO_RELOAD_EEPROM | AXE_GPIO1 |
    827   1.66       roy 			    AXE_GPIO1_EN, hz / 32);
    828   1.66       roy 		break;
    829   1.66       roy 	case AXE_PHY_MODE_AGERE:
    830   1.66       roy 		AXE_GPIO_WRITE(AXE_GPIO_RELOAD_EEPROM | AXE_GPIO1 |
    831   1.66       roy 		    AXE_GPIO1_EN, hz / 32);
    832   1.66       roy 		AXE_GPIO_WRITE(AXE_GPIO1 | AXE_GPIO1_EN | AXE_GPIO2 |
    833   1.66       roy 		    AXE_GPIO2_EN, hz / 32);
    834   1.66       roy 		AXE_GPIO_WRITE(AXE_GPIO1 | AXE_GPIO1_EN | AXE_GPIO2_EN, hz / 4);
    835   1.66       roy 		AXE_GPIO_WRITE(AXE_GPIO1 | AXE_GPIO1_EN | AXE_GPIO2 |
    836   1.66       roy 		    AXE_GPIO2_EN, hz / 32);
    837   1.66       roy 		break;
    838   1.66       roy 	case AXE_PHY_MODE_REALTEK_8211CL:
    839   1.66       roy 	case AXE_PHY_MODE_REALTEK_8211BN:
    840   1.66       roy 	case AXE_PHY_MODE_REALTEK_8251CL:
    841   1.66       roy 		val = gpio0 == 1 ? AXE_GPIO0 | AXE_GPIO0_EN :
    842   1.66       roy 		    AXE_GPIO1 | AXE_GPIO1_EN;
    843   1.66       roy 		AXE_GPIO_WRITE(val, hz / 32);
    844   1.66       roy 		AXE_GPIO_WRITE(val | AXE_GPIO2 | AXE_GPIO2_EN, hz / 32);
    845   1.66       roy 		AXE_GPIO_WRITE(val | AXE_GPIO2_EN, hz / 4);
    846   1.66       roy 		AXE_GPIO_WRITE(val | AXE_GPIO2 | AXE_GPIO2_EN, hz / 32);
    847   1.66       roy 		if (phymode == AXE_PHY_MODE_REALTEK_8211CL) {
    848   1.66       roy 			axe_miibus_writereg_locked(sc->axe_dev,
    849   1.66       roy 			    sc->axe_phyno, 0x1F, 0x0005);
    850   1.66       roy 			axe_miibus_writereg_locked(sc->axe_dev,
    851   1.66       roy 			    sc->axe_phyno, 0x0C, 0x0000);
    852   1.95   msaitoh 			axe_miibus_readreg_locked(sc->axe_dev,
    853   1.95   msaitoh 			    sc->axe_phyno, 0x0001, &val);
    854   1.66       roy 			axe_miibus_writereg_locked(sc->axe_dev,
    855   1.66       roy 			    sc->axe_phyno, 0x01, val | 0x0080);
    856   1.66       roy 			axe_miibus_writereg_locked(sc->axe_dev,
    857   1.66       roy 			    sc->axe_phyno, 0x1F, 0x0000);
    858   1.66       roy 		}
    859   1.66       roy 		break;
    860   1.66       roy 	default:
    861   1.66       roy 		/* Unknown PHY model or no need to program GPIOs. */
    862   1.66       roy 		break;
    863   1.35  pgoyette 	}
    864   1.35  pgoyette 
    865   1.35  pgoyette 	/* soft reset */
    866   1.35  pgoyette 	axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_CLEAR, NULL);
    867   1.35  pgoyette 	usbd_delay_ms(sc->axe_udev, 150);
    868   1.35  pgoyette 	axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0,
    869   1.35  pgoyette 	    AXE_SW_RESET_PRL | AXE_178_RESET_MAGIC, NULL);
    870   1.35  pgoyette 	usbd_delay_ms(sc->axe_udev, 150);
    871   1.76     skrll 	/* Enable MII/GMII/RGMII interface to work with external PHY. */
    872   1.35  pgoyette 	axe_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0, 0, NULL);
    873   1.35  pgoyette 	usbd_delay_ms(sc->axe_udev, 10);
    874   1.35  pgoyette 	axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, 0, NULL);
    875   1.35  pgoyette }
    876   1.35  pgoyette 
    877   1.35  pgoyette static void
    878   1.35  pgoyette axe_ax88772_init(struct axe_softc *sc)
    879   1.35  pgoyette {
    880   1.76     skrll 	AXEHIST_FUNC(); AXEHIST_CALLED();
    881   1.35  pgoyette 
    882   1.35  pgoyette 	axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x00b0, NULL);
    883   1.35  pgoyette 	usbd_delay_ms(sc->axe_udev, 40);
    884   1.35  pgoyette 
    885   1.66       roy 	if (sc->axe_phyno == AXE_772_PHY_NO_EPHY) {
    886   1.35  pgoyette 		/* ask for the embedded PHY */
    887   1.76     skrll 		axe_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0,
    888   1.76     skrll 		    AXE_SW_PHY_SELECT_EMBEDDED, NULL);
    889   1.35  pgoyette 		usbd_delay_ms(sc->axe_udev, 10);
    890   1.35  pgoyette 
    891   1.35  pgoyette 		/* power down and reset state, pin reset state */
    892   1.35  pgoyette 		axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_CLEAR, NULL);
    893   1.35  pgoyette 		usbd_delay_ms(sc->axe_udev, 60);
    894   1.35  pgoyette 
    895   1.35  pgoyette 		/* power down/reset state, pin operating state */
    896   1.35  pgoyette 		axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0,
    897   1.35  pgoyette 		    AXE_SW_RESET_IPPD | AXE_SW_RESET_PRL, NULL);
    898   1.35  pgoyette 		usbd_delay_ms(sc->axe_udev, 150);
    899   1.35  pgoyette 
    900   1.35  pgoyette 		/* power up, reset */
    901   1.35  pgoyette 		axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_PRL, NULL);
    902   1.35  pgoyette 
    903   1.35  pgoyette 		/* power up, operating */
    904   1.35  pgoyette 		axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0,
    905   1.35  pgoyette 		    AXE_SW_RESET_IPRL | AXE_SW_RESET_PRL, NULL);
    906   1.35  pgoyette 	} else {
    907   1.35  pgoyette 		/* ask for external PHY */
    908   1.76     skrll 		axe_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0, AXE_SW_PHY_SELECT_EXT,
    909   1.76     skrll 		    NULL);
    910   1.35  pgoyette 		usbd_delay_ms(sc->axe_udev, 10);
    911   1.35  pgoyette 
    912   1.35  pgoyette 		/* power down internal PHY */
    913   1.35  pgoyette 		axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0,
    914   1.35  pgoyette 		    AXE_SW_RESET_IPPD | AXE_SW_RESET_PRL, NULL);
    915   1.35  pgoyette 	}
    916   1.35  pgoyette 
    917   1.35  pgoyette 	usbd_delay_ms(sc->axe_udev, 150);
    918   1.35  pgoyette 	axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, 0, NULL);
    919   1.35  pgoyette }
    920   1.35  pgoyette 
    921   1.76     skrll static void
    922   1.76     skrll axe_ax88772_phywake(struct axe_softc *sc)
    923   1.76     skrll {
    924   1.76     skrll 	AXEHIST_FUNC(); AXEHIST_CALLED();
    925   1.76     skrll 
    926   1.76     skrll 	if (sc->axe_phyno == AXE_772_PHY_NO_EPHY) {
    927   1.76     skrll 		/* Manually select internal(embedded) PHY - MAC mode. */
    928   1.76     skrll 		axe_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0,
    929   1.86  christos 		    AXE_SW_PHY_SELECT_EMBEDDED, NULL);
    930   1.76     skrll 		usbd_delay_ms(sc->axe_udev, hztoms(hz / 32));
    931   1.76     skrll 	} else {
    932   1.76     skrll 		/*
    933   1.76     skrll 		 * Manually select external PHY - MAC mode.
    934   1.76     skrll 		 * Reverse MII/RMII is for AX88772A PHY mode.
    935   1.76     skrll 		 */
    936   1.76     skrll 		axe_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0, AXE_SW_PHY_SELECT_SS_ENB |
    937   1.76     skrll 		    AXE_SW_PHY_SELECT_EXT | AXE_SW_PHY_SELECT_SS_MII, NULL);
    938   1.76     skrll 		usbd_delay_ms(sc->axe_udev, hztoms(hz / 32));
    939   1.76     skrll 	}
    940   1.76     skrll 
    941   1.76     skrll 	axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_IPPD |
    942   1.76     skrll 	    AXE_SW_RESET_IPRL, NULL);
    943   1.76     skrll 
    944   1.76     skrll 	/* T1 = min 500ns everywhere */
    945   1.76     skrll 	usbd_delay_ms(sc->axe_udev, 150);
    946   1.76     skrll 
    947   1.76     skrll 	/* Take PHY out of power down. */
    948   1.76     skrll 	if (sc->axe_phyno == AXE_772_PHY_NO_EPHY) {
    949   1.76     skrll 		axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_IPRL, NULL);
    950   1.76     skrll 	} else {
    951   1.76     skrll 		axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_PRTE, NULL);
    952   1.76     skrll 	}
    953   1.76     skrll 
    954   1.76     skrll 	/* 772 T2 is 60ms. 772A T2 is 160ms, 772B T2 is 600ms */
    955   1.76     skrll 	usbd_delay_ms(sc->axe_udev, 600);
    956   1.76     skrll 
    957   1.76     skrll 	axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_CLEAR, NULL);
    958   1.76     skrll 
    959   1.76     skrll 	/* T3 = 500ns everywhere */
    960   1.76     skrll 	usbd_delay_ms(sc->axe_udev, hztoms(hz / 32));
    961   1.76     skrll 	axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_IPRL, NULL);
    962   1.76     skrll 	usbd_delay_ms(sc->axe_udev, hztoms(hz / 32));
    963   1.76     skrll }
    964   1.76     skrll 
    965   1.76     skrll static void
    966   1.76     skrll axe_ax88772a_init(struct axe_softc *sc)
    967   1.76     skrll {
    968   1.76     skrll 	AXEHIST_FUNC(); AXEHIST_CALLED();
    969   1.76     skrll 
    970   1.76     skrll 	/* Reload EEPROM. */
    971   1.76     skrll 	AXE_GPIO_WRITE(AXE_GPIO_RELOAD_EEPROM, hz / 32);
    972   1.76     skrll 	axe_ax88772_phywake(sc);
    973   1.76     skrll 	/* Stop MAC. */
    974   1.76     skrll 	axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, 0, NULL);
    975   1.76     skrll }
    976   1.76     skrll 
    977   1.76     skrll static void
    978   1.76     skrll axe_ax88772b_init(struct axe_softc *sc)
    979   1.76     skrll {
    980   1.76     skrll 	AXEHIST_FUNC(); AXEHIST_CALLED();
    981   1.76     skrll 	uint16_t eeprom;
    982   1.76     skrll 	int i;
    983   1.76     skrll 
    984   1.76     skrll 	/* Reload EEPROM. */
    985   1.76     skrll 	AXE_GPIO_WRITE(AXE_GPIO_RELOAD_EEPROM , hz / 32);
    986   1.76     skrll 
    987   1.76     skrll 	/*
    988   1.76     skrll 	 * Save PHY power saving configuration(high byte) and
    989   1.76     skrll 	 * clear EEPROM checksum value(low byte).
    990   1.76     skrll 	 */
    991   1.86  christos 	if (axe_cmd(sc, AXE_CMD_SROM_READ, 0, AXE_EEPROM_772B_PHY_PWRCFG,
    992   1.86  christos 	    &eeprom)) {
    993   1.86  christos 		aprint_error_dev(sc->axe_dev, "failed to read eeprom\n");
    994   1.86  christos 		return;
    995   1.86  christos 	}
    996   1.86  christos 
    997   1.76     skrll 	sc->sc_pwrcfg = le16toh(eeprom) & 0xFF00;
    998   1.76     skrll 
    999   1.76     skrll 	/*
   1000   1.76     skrll 	 * Auto-loaded default station address from internal ROM is
   1001   1.76     skrll 	 * 00:00:00:00:00:00 such that an explicit access to EEPROM
   1002   1.76     skrll 	 * is required to get real station address.
   1003   1.76     skrll 	 */
   1004   1.76     skrll 	uint8_t *eaddr = sc->axe_enaddr;
   1005   1.76     skrll 	for (i = 0; i < ETHER_ADDR_LEN / 2; i++) {
   1006   1.86  christos 		if (axe_cmd(sc, AXE_CMD_SROM_READ, 0,
   1007   1.86  christos 		    AXE_EEPROM_772B_NODE_ID + i, &eeprom)) {
   1008   1.86  christos 			aprint_error_dev(sc->axe_dev,
   1009   1.86  christos 			    "failed to read eeprom\n");
   1010   1.86  christos 		    eeprom = 0;
   1011   1.86  christos 		}
   1012   1.76     skrll 		eeprom = le16toh(eeprom);
   1013   1.76     skrll 		*eaddr++ = (uint8_t)(eeprom & 0xFF);
   1014   1.76     skrll 		*eaddr++ = (uint8_t)((eeprom >> 8) & 0xFF);
   1015   1.76     skrll 	}
   1016   1.76     skrll 	/* Wakeup PHY. */
   1017   1.76     skrll 	axe_ax88772_phywake(sc);
   1018   1.76     skrll 	/* Stop MAC. */
   1019   1.76     skrll 	axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, 0, NULL);
   1020   1.76     skrll }
   1021   1.76     skrll 
   1022   1.76     skrll #undef	AXE_GPIO_WRITE
   1023   1.76     skrll 
   1024    1.1  augustss /*
   1025    1.1  augustss  * Probe for a AX88172 chip.
   1026    1.1  augustss  */
   1027   1.27    dyoung int
   1028   1.27    dyoung axe_match(device_t parent, cfdata_t match, void *aux)
   1029    1.1  augustss {
   1030   1.27    dyoung 	struct usb_attach_arg *uaa = aux;
   1031    1.1  augustss 
   1032   1.71     skrll 	return axe_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL ?
   1033   1.38   tsutsui 	    UMATCH_VENDOR_PRODUCT : UMATCH_NONE;
   1034    1.1  augustss }
   1035    1.1  augustss 
   1036    1.1  augustss /*
   1037    1.1  augustss  * Attach the interface. Allocate softc structures, do ifmedia
   1038    1.1  augustss  * setup and ethernet/BPF attach.
   1039    1.1  augustss  */
   1040   1.27    dyoung void
   1041   1.27    dyoung axe_attach(device_t parent, device_t self, void *aux)
   1042    1.1  augustss {
   1043   1.76     skrll 	AXEHIST_FUNC(); AXEHIST_CALLED();
   1044   1.27    dyoung 	struct axe_softc *sc = device_private(self);
   1045   1.27    dyoung 	struct usb_attach_arg *uaa = aux;
   1046   1.71     skrll 	struct usbd_device *dev = uaa->uaa_device;
   1047    1.1  augustss 	usbd_status err;
   1048    1.1  augustss 	usb_interface_descriptor_t *id;
   1049    1.1  augustss 	usb_endpoint_descriptor_t *ed;
   1050    1.1  augustss 	struct mii_data	*mii;
   1051    1.8  augustss 	char *devinfop;
   1052   1.25      cube 	const char *devname = device_xname(self);
   1053    1.1  augustss 	struct ifnet *ifp;
   1054  1.100       mrg 	int i;
   1055    1.1  augustss 
   1056   1.28    dyoung 	aprint_naive("\n");
   1057   1.28    dyoung 	aprint_normal("\n");
   1058   1.29    plunky 
   1059   1.35  pgoyette 	sc->axe_dev = self;
   1060   1.35  pgoyette 	sc->axe_udev = dev;
   1061   1.35  pgoyette 
   1062   1.29    plunky 	devinfop = usbd_devinfo_alloc(dev, 0);
   1063   1.29    plunky 	aprint_normal_dev(self, "%s\n", devinfop);
   1064   1.29    plunky 	usbd_devinfo_free(devinfop);
   1065    1.1  augustss 
   1066    1.1  augustss 	err = usbd_set_config_no(dev, AXE_CONFIG_NO, 1);
   1067    1.1  augustss 	if (err) {
   1068   1.61     skrll 		aprint_error_dev(self, "failed to set configuration"
   1069   1.61     skrll 		    ", err=%s\n", usbd_errstr(err));
   1070   1.28    dyoung 		return;
   1071    1.1  augustss 	}
   1072    1.1  augustss 
   1073   1.71     skrll 	sc->axe_flags = axe_lookup(uaa->uaa_vendor, uaa->uaa_product)->axe_flags;
   1074   1.35  pgoyette 
   1075  1.100       mrg 	usb_init_task(&sc->axe_tick_task, axe_tick_task, sc, USB_TASKQ_MPSAFE);
   1076    1.1  augustss 
   1077    1.1  augustss 	err = usbd_device2interface_handle(dev, AXE_IFACE_IDX, &sc->axe_iface);
   1078    1.1  augustss 	if (err) {
   1079   1.25      cube 		aprint_error_dev(self, "getting interface handle failed\n");
   1080   1.28    dyoung 		return;
   1081    1.1  augustss 	}
   1082    1.1  augustss 
   1083   1.71     skrll 	sc->axe_product = uaa->uaa_product;
   1084   1.71     skrll 	sc->axe_vendor = uaa->uaa_vendor;
   1085    1.1  augustss 
   1086    1.1  augustss 	id = usbd_get_interface_descriptor(sc->axe_iface);
   1087    1.1  augustss 
   1088   1.35  pgoyette 	/* decide on what our bufsize will be */
   1089   1.76     skrll 	if (AXE_IS_178_FAMILY(sc))
   1090   1.71     skrll 		sc->axe_bufsz = (sc->axe_udev->ud_speed == USB_SPEED_HIGH) ?
   1091   1.35  pgoyette 		    AXE_178_MAX_BUFSZ : AXE_178_MIN_BUFSZ;
   1092   1.35  pgoyette 	else
   1093   1.35  pgoyette 		sc->axe_bufsz = AXE_172_BUFSZ;
   1094   1.35  pgoyette 
   1095   1.76     skrll 	sc->axe_ed[AXE_ENDPT_RX] = -1;
   1096   1.76     skrll 	sc->axe_ed[AXE_ENDPT_TX] = -1;
   1097   1.76     skrll 	sc->axe_ed[AXE_ENDPT_INTR] = -1;
   1098   1.76     skrll 
   1099    1.1  augustss 	/* Find endpoints. */
   1100    1.1  augustss 	for (i = 0; i < id->bNumEndpoints; i++) {
   1101    1.1  augustss 		ed = usbd_interface2endpoint_descriptor(sc->axe_iface, i);
   1102   1.38   tsutsui 		if (ed == NULL) {
   1103   1.25      cube 			aprint_error_dev(self, "couldn't get ep %d\n", i);
   1104   1.28    dyoung 			return;
   1105    1.1  augustss 		}
   1106   1.76     skrll 		const uint8_t xt = UE_GET_XFERTYPE(ed->bmAttributes);
   1107   1.76     skrll 		const uint8_t dir = UE_GET_DIR(ed->bEndpointAddress);
   1108   1.76     skrll 
   1109   1.76     skrll 		if (dir == UE_DIR_IN && xt == UE_BULK &&
   1110   1.76     skrll 		    sc->axe_ed[AXE_ENDPT_RX] == -1) {
   1111    1.1  augustss 			sc->axe_ed[AXE_ENDPT_RX] = ed->bEndpointAddress;
   1112   1.76     skrll 		} else if (dir == UE_DIR_OUT && xt == UE_BULK &&
   1113   1.76     skrll 		    sc->axe_ed[AXE_ENDPT_TX] == -1) {
   1114    1.1  augustss 			sc->axe_ed[AXE_ENDPT_TX] = ed->bEndpointAddress;
   1115   1.76     skrll 		} else if (dir == UE_DIR_IN && xt == UE_INTERRUPT) {
   1116    1.1  augustss 			sc->axe_ed[AXE_ENDPT_INTR] = ed->bEndpointAddress;
   1117    1.1  augustss 		}
   1118    1.1  augustss 	}
   1119    1.1  augustss 
   1120  1.100       mrg 	/* Set these up now for axe_cmd().  */
   1121  1.100       mrg 	mutex_init(&sc->axe_mii_lock, MUTEX_DEFAULT, IPL_NONE);
   1122  1.100       mrg 	mutex_init(&sc->axe_txlock, MUTEX_DEFAULT, IPL_SOFTUSB);
   1123  1.100       mrg 	mutex_init(&sc->axe_rxlock, MUTEX_DEFAULT, IPL_SOFTUSB);
   1124  1.100       mrg 	mutex_init(&sc->axe_lock, MUTEX_DEFAULT, IPL_NONE);
   1125  1.100       mrg 	cv_init(&sc->axe_detachcv, "axedet");
   1126    1.1  augustss 
   1127   1.35  pgoyette 	/* We need the PHYID for init dance in some cases */
   1128   1.35  pgoyette 	axe_lock_mii(sc);
   1129   1.86  christos 	if (axe_cmd(sc, AXE_CMD_READ_PHYID, 0, 0, &sc->axe_phyaddrs)) {
   1130   1.86  christos 		aprint_error_dev(self, "failed to read phyaddrs\n");
   1131  1.100       mrg 
   1132  1.100       mrg 		cv_destroy(&sc->axe_detachcv);
   1133  1.100       mrg 		mutex_destroy(&sc->axe_lock);
   1134  1.100       mrg 		mutex_destroy(&sc->axe_rxlock);
   1135  1.100       mrg 		mutex_destroy(&sc->axe_txlock);
   1136  1.100       mrg 		mutex_destroy(&sc->axe_mii_lock);
   1137  1.100       mrg 
   1138   1.86  christos 		return;
   1139   1.86  christos 	}
   1140   1.35  pgoyette 
   1141   1.83  pgoyette 	DPRINTF(" phyaddrs[0]: %jx phyaddrs[1]: %jx",
   1142   1.76     skrll 	    sc->axe_phyaddrs[0], sc->axe_phyaddrs[1], 0, 0);
   1143   1.66       roy 	sc->axe_phyno = axe_get_phyno(sc, AXE_PHY_SEL_PRI);
   1144   1.66       roy 	if (sc->axe_phyno == -1)
   1145   1.66       roy 		sc->axe_phyno = axe_get_phyno(sc, AXE_PHY_SEL_SEC);
   1146   1.66       roy 	if (sc->axe_phyno == -1) {
   1147   1.76     skrll 		DPRINTF(" no valid PHY address found, assuming PHY address 0",
   1148   1.76     skrll 		    0, 0, 0, 0);
   1149   1.66       roy 		sc->axe_phyno = 0;
   1150   1.66       roy 	}
   1151   1.35  pgoyette 
   1152   1.76     skrll 	/* Initialize controller and get station address. */
   1153   1.76     skrll 
   1154   1.88  christos 	axe_ax_init(sc);
   1155   1.86  christos 
   1156    1.1  augustss 	/*
   1157   1.76     skrll 	 * Fetch IPG values.
   1158    1.1  augustss 	 */
   1159   1.76     skrll 	if (sc->axe_flags & (AX772A | AX772B)) {
   1160   1.76     skrll 		/* Set IPG values. */
   1161   1.76     skrll 		sc->axe_ipgs[0] = AXE_IPG0_DEFAULT;
   1162   1.76     skrll 		sc->axe_ipgs[1] = AXE_IPG1_DEFAULT;
   1163   1.76     skrll 		sc->axe_ipgs[2] = AXE_IPG2_DEFAULT;
   1164   1.86  christos 	} else {
   1165   1.86  christos 		if (axe_cmd(sc, AXE_CMD_READ_IPG012, 0, 0, sc->axe_ipgs)) {
   1166   1.86  christos 			aprint_error_dev(self, "failed to read ipg\n");
   1167  1.100       mrg 
   1168  1.100       mrg 			cv_destroy(&sc->axe_detachcv);
   1169  1.100       mrg 			mutex_destroy(&sc->axe_lock);
   1170  1.100       mrg 			mutex_destroy(&sc->axe_rxlock);
   1171  1.100       mrg 			mutex_destroy(&sc->axe_txlock);
   1172  1.100       mrg 			mutex_destroy(&sc->axe_mii_lock);
   1173  1.100       mrg 
   1174   1.86  christos 			return;
   1175   1.86  christos 		}
   1176   1.86  christos 	}
   1177    1.1  augustss 
   1178   1.21        ad 	axe_unlock_mii(sc);
   1179    1.1  augustss 
   1180    1.1  augustss 	/*
   1181    1.1  augustss 	 * An ASIX chip was detected. Inform the world.
   1182    1.1  augustss 	 */
   1183   1.76     skrll 	aprint_normal_dev(self, "Ethernet address %s\n",
   1184   1.76     skrll 	    ether_sprintf(sc->axe_enaddr));
   1185    1.1  augustss 
   1186    1.1  augustss 	/* Initialize interface info.*/
   1187   1.35  pgoyette 	ifp = &sc->sc_if;
   1188    1.1  augustss 	ifp->if_softc = sc;
   1189   1.80      maya 	strlcpy(ifp->if_xname, devname, IFNAMSIZ);
   1190    1.1  augustss 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
   1191  1.100       mrg 	ifp->if_extflags = IFEF_MPSAFE;
   1192    1.1  augustss 	ifp->if_ioctl = axe_ioctl;
   1193    1.1  augustss 	ifp->if_start = axe_start;
   1194   1.35  pgoyette 	ifp->if_init = axe_init;
   1195   1.35  pgoyette 	ifp->if_stop = axe_stop;
   1196    1.1  augustss 	ifp->if_watchdog = axe_watchdog;
   1197    1.1  augustss 
   1198   1.35  pgoyette 	IFQ_SET_READY(&ifp->if_snd);
   1199    1.1  augustss 
   1200   1.76     skrll 	if (AXE_IS_178_FAMILY(sc))
   1201   1.76     skrll 		sc->axe_ec.ec_capabilities = ETHERCAP_VLAN_MTU;
   1202   1.76     skrll 	if (sc->axe_flags & AX772B) {
   1203   1.76     skrll 		ifp->if_capabilities =
   1204   1.76     skrll 		    IFCAP_CSUM_IPv4_Rx |
   1205   1.76     skrll 		    IFCAP_CSUM_TCPv4_Rx | IFCAP_CSUM_UDPv4_Rx |
   1206   1.76     skrll 		    IFCAP_CSUM_TCPv6_Rx | IFCAP_CSUM_UDPv6_Rx;
   1207   1.76     skrll 		/*
   1208   1.76     skrll 		 * Checksum offloading of AX88772B also works with VLAN
   1209   1.76     skrll 		 * tagged frames but there is no way to take advantage
   1210   1.76     skrll 		 * of the feature because vlan(4) assumes
   1211   1.76     skrll 		 * IFCAP_VLAN_HWTAGGING is prerequisite condition to
   1212   1.76     skrll 		 * support checksum offloading with VLAN. VLAN hardware
   1213   1.76     skrll 		 * tagging support of AX88772B is very limited so it's
   1214   1.76     skrll 		 * not possible to announce IFCAP_VLAN_HWTAGGING.
   1215   1.76     skrll 		 */
   1216   1.76     skrll 	}
   1217   1.76     skrll 	u_int adv_pause;
   1218   1.76     skrll 	if (sc->axe_flags & (AX772A | AX772B | AX178))
   1219   1.76     skrll 		adv_pause = MIIF_DOPAUSE;
   1220   1.76     skrll 	else
   1221   1.76     skrll 		adv_pause = 0;
   1222   1.76     skrll 	adv_pause = 0;
   1223    1.1  augustss 
   1224    1.1  augustss 	/* Initialize MII/media info. */
   1225    1.1  augustss 	mii = &sc->axe_mii;
   1226    1.1  augustss 	mii->mii_ifp = ifp;
   1227    1.1  augustss 	mii->mii_readreg = axe_miibus_readreg;
   1228    1.1  augustss 	mii->mii_writereg = axe_miibus_writereg;
   1229    1.1  augustss 	mii->mii_statchg = axe_miibus_statchg;
   1230    1.1  augustss 	mii->mii_flags = MIIF_AUTOTSLEEP;
   1231    1.1  augustss 
   1232   1.22    dyoung 	sc->axe_ec.ec_mii = mii;
   1233   1.76     skrll 	ifmedia_init(&mii->mii_media, 0, ether_mediachange, ether_mediastatus);
   1234   1.35  pgoyette 
   1235   1.35  pgoyette 	mii_attach(sc->axe_dev, mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY,
   1236   1.76     skrll 	    adv_pause);
   1237    1.1  augustss 
   1238   1.22    dyoung 	if (LIST_EMPTY(&mii->mii_phys)) {
   1239    1.1  augustss 		ifmedia_add(&mii->mii_media, IFM_ETHER | IFM_NONE, 0, NULL);
   1240    1.1  augustss 		ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_NONE);
   1241    1.1  augustss 	} else
   1242    1.1  augustss 		ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_AUTO);
   1243    1.1  augustss 
   1244    1.1  augustss 	/* Attach the interface. */
   1245    1.1  augustss 	if_attach(ifp);
   1246   1.76     skrll 	ether_ifattach(ifp, sc->axe_enaddr);
   1247   1.28    dyoung 	rnd_attach_source(&sc->rnd_source, device_xname(sc->axe_dev),
   1248   1.67       tls 	    RND_TYPE_NET, RND_FLAG_DEFAULT);
   1249    1.1  augustss 
   1250  1.100       mrg 	callout_init(&sc->axe_stat_ch, CALLOUT_MPSAFE);
   1251   1.35  pgoyette 	callout_setfunc(&sc->axe_stat_ch, axe_tick, sc);
   1252    1.1  augustss 
   1253   1.45   tsutsui 	sc->axe_attached = true;
   1254    1.1  augustss 
   1255   1.28    dyoung 	usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->axe_udev, sc->axe_dev);
   1256   1.68    nonaka 
   1257   1.68    nonaka 	if (!pmf_device_register(self, NULL, NULL))
   1258   1.68    nonaka 		aprint_error_dev(self, "couldn't establish power handler\n");
   1259    1.1  augustss }
   1260    1.1  augustss 
   1261   1.27    dyoung int
   1262   1.27    dyoung axe_detach(device_t self, int flags)
   1263    1.1  augustss {
   1264   1.76     skrll 	AXEHIST_FUNC(); AXEHIST_CALLED();
   1265   1.38   tsutsui 	struct axe_softc *sc = device_private(self);
   1266   1.38   tsutsui 	struct ifnet *ifp = &sc->sc_if;
   1267    1.1  augustss 
   1268  1.100       mrg 	mutex_enter(&sc->axe_lock);
   1269  1.100       mrg 	sc->axe_dying = true;
   1270  1.100       mrg 	mutex_exit(&sc->axe_lock);
   1271  1.100       mrg 
   1272    1.1  augustss 	/* Detached before attached finished, so just bail out. */
   1273    1.1  augustss 	if (!sc->axe_attached)
   1274   1.35  pgoyette 		return 0;
   1275    1.1  augustss 
   1276   1.68    nonaka 	pmf_device_deregister(self);
   1277   1.68    nonaka 
   1278   1.91  riastrad 	callout_halt(&sc->axe_stat_ch, NULL);
   1279   1.92  riastrad 	usb_rem_task_wait(sc->axe_udev, &sc->axe_tick_task, USB_TASKQ_DRIVER,
   1280   1.92  riastrad 	    NULL);
   1281    1.1  augustss 
   1282  1.100       mrg 	if (ifp->if_flags & IFF_RUNNING) {
   1283  1.100       mrg 		IFNET_LOCK(ifp);
   1284  1.100       mrg 		axe_stop(ifp, 1);
   1285  1.100       mrg 		IFNET_UNLOCK(ifp);
   1286  1.100       mrg 	}
   1287    1.1  augustss 
   1288  1.100       mrg 	mutex_enter(&sc->axe_lock);
   1289  1.100       mrg 	sc->axe_refcnt--;
   1290  1.100       mrg 	while (sc->axe_refcnt > 0) {
   1291  1.100       mrg 		/* Wait for processes to go away */
   1292  1.100       mrg 		cv_wait(&sc->axe_detachcv, &sc->axe_lock);
   1293  1.100       mrg 	}
   1294    1.1  augustss 
   1295  1.100       mrg #ifdef DIAGNOSTIC
   1296  1.100       mrg 	if (sc->axe_ep[AXE_ENDPT_TX] != NULL ||
   1297  1.100       mrg 	    sc->axe_ep[AXE_ENDPT_RX] != NULL ||
   1298  1.100       mrg 	    sc->axe_ep[AXE_ENDPT_INTR] != NULL)
   1299  1.100       mrg 		aprint_debug_dev(self, "detach has active endpoints\n");
   1300  1.100       mrg #endif
   1301   1.76     skrll 
   1302  1.100       mrg 	mutex_exit(&sc->axe_lock);
   1303   1.76     skrll 
   1304   1.36   tsutsui 	callout_destroy(&sc->axe_stat_ch);
   1305    1.1  augustss 	rnd_detach_source(&sc->rnd_source);
   1306    1.1  augustss 	mii_detach(&sc->axe_mii, MII_PHY_ANY, MII_OFFSET_ANY);
   1307    1.1  augustss 	ifmedia_delete_instance(&sc->axe_mii.mii_media, IFM_INST_ANY);
   1308    1.1  augustss 	ether_ifdetach(ifp);
   1309    1.1  augustss 	if_detach(ifp);
   1310    1.1  augustss 
   1311   1.45   tsutsui 	sc->axe_attached = false;
   1312    1.1  augustss 
   1313  1.100       mrg 	usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->axe_udev, sc->axe_dev);
   1314    1.1  augustss 
   1315  1.100       mrg 	cv_destroy(&sc->axe_detachcv);
   1316  1.100       mrg 	mutex_destroy(&sc->axe_lock);
   1317  1.100       mrg 	mutex_destroy(&sc->axe_rxlock);
   1318  1.100       mrg 	mutex_destroy(&sc->axe_txlock);
   1319  1.100       mrg 	mutex_destroy(&sc->axe_mii_lock);
   1320    1.1  augustss 
   1321   1.35  pgoyette 	return 0;
   1322    1.1  augustss }
   1323    1.1  augustss 
   1324    1.1  augustss int
   1325   1.35  pgoyette axe_activate(device_t self, devact_t act)
   1326    1.1  augustss {
   1327   1.76     skrll 	AXEHIST_FUNC(); AXEHIST_CALLED();
   1328   1.25      cube 	struct axe_softc *sc = device_private(self);
   1329    1.1  augustss 
   1330    1.1  augustss 	switch (act) {
   1331    1.1  augustss 	case DVACT_DEACTIVATE:
   1332    1.1  augustss 		if_deactivate(&sc->axe_ec.ec_if);
   1333  1.100       mrg 
   1334  1.100       mrg 		mutex_enter(&sc->axe_lock);
   1335   1.45   tsutsui 		sc->axe_dying = true;
   1336  1.100       mrg 		mutex_exit(&sc->axe_lock);
   1337  1.100       mrg 
   1338  1.100       mrg 		mutex_enter(&sc->axe_rxlock);
   1339  1.100       mrg 		mutex_enter(&sc->axe_txlock);
   1340  1.100       mrg 		sc->axe_stopping = true;
   1341  1.100       mrg 		mutex_exit(&sc->axe_txlock);
   1342  1.100       mrg 		mutex_exit(&sc->axe_rxlock);
   1343  1.100       mrg 
   1344   1.30    dyoung 		return 0;
   1345   1.30    dyoung 	default:
   1346   1.30    dyoung 		return EOPNOTSUPP;
   1347    1.1  augustss 	}
   1348    1.1  augustss }
   1349    1.1  augustss 
   1350   1.35  pgoyette static int
   1351    1.1  augustss axe_rx_list_init(struct axe_softc *sc)
   1352    1.1  augustss {
   1353   1.76     skrll 	AXEHIST_FUNC(); AXEHIST_CALLED();
   1354   1.76     skrll 
   1355    1.1  augustss 	struct axe_cdata *cd;
   1356    1.1  augustss 	struct axe_chain *c;
   1357    1.1  augustss 	int i;
   1358    1.1  augustss 
   1359    1.1  augustss 	cd = &sc->axe_cdata;
   1360    1.1  augustss 	for (i = 0; i < AXE_RX_LIST_CNT; i++) {
   1361    1.1  augustss 		c = &cd->axe_rx_chain[i];
   1362    1.1  augustss 		c->axe_sc = sc;
   1363    1.1  augustss 		c->axe_idx = i;
   1364    1.1  augustss 		if (c->axe_xfer == NULL) {
   1365   1.71     skrll 			int err = usbd_create_xfer(sc->axe_ep[AXE_ENDPT_RX],
   1366   1.84     skrll 			    sc->axe_bufsz, 0, 0, &c->axe_xfer);
   1367   1.71     skrll 			if (err)
   1368   1.71     skrll 				return err;
   1369   1.71     skrll 			c->axe_buf = usbd_get_buffer(c->axe_xfer);
   1370    1.1  augustss 		}
   1371    1.1  augustss 	}
   1372    1.1  augustss 
   1373   1.35  pgoyette 	return 0;
   1374    1.1  augustss }
   1375    1.1  augustss 
   1376   1.35  pgoyette static int
   1377    1.1  augustss axe_tx_list_init(struct axe_softc *sc)
   1378    1.1  augustss {
   1379   1.76     skrll 	AXEHIST_FUNC(); AXEHIST_CALLED();
   1380    1.1  augustss 	struct axe_cdata *cd;
   1381    1.1  augustss 	struct axe_chain *c;
   1382    1.1  augustss 	int i;
   1383    1.1  augustss 
   1384    1.1  augustss 	cd = &sc->axe_cdata;
   1385    1.1  augustss 	for (i = 0; i < AXE_TX_LIST_CNT; i++) {
   1386    1.1  augustss 		c = &cd->axe_tx_chain[i];
   1387    1.1  augustss 		c->axe_sc = sc;
   1388    1.1  augustss 		c->axe_idx = i;
   1389    1.1  augustss 		if (c->axe_xfer == NULL) {
   1390   1.71     skrll 			int err = usbd_create_xfer(sc->axe_ep[AXE_ENDPT_TX],
   1391   1.71     skrll 			    sc->axe_bufsz, USBD_FORCE_SHORT_XFER, 0,
   1392   1.71     skrll 			    &c->axe_xfer);
   1393   1.71     skrll 			if (err)
   1394   1.71     skrll 				return err;
   1395   1.71     skrll 			c->axe_buf = usbd_get_buffer(c->axe_xfer);
   1396    1.1  augustss 		}
   1397    1.1  augustss 	}
   1398    1.1  augustss 
   1399  1.100       mrg 	cd->axe_tx_cnt = 0;
   1400  1.100       mrg 
   1401   1.35  pgoyette 	return 0;
   1402    1.1  augustss }
   1403    1.1  augustss 
   1404    1.1  augustss /*
   1405    1.1  augustss  * A frame has been uploaded: pass the resulting mbuf chain up to
   1406    1.1  augustss  * the higher level protocols.
   1407    1.1  augustss  */
   1408   1.35  pgoyette static void
   1409   1.71     skrll axe_rxeof(struct usbd_xfer *xfer, void * priv, usbd_status status)
   1410    1.1  augustss {
   1411   1.76     skrll 	AXEHIST_FUNC(); AXEHIST_CALLED();
   1412  1.100       mrg 	struct axe_chain *c = (struct axe_chain *)priv;
   1413  1.100       mrg 	struct axe_softc * const sc = c->axe_sc;
   1414  1.100       mrg 	struct ifnet *ifp = &sc->sc_if;
   1415  1.100       mrg 	uint8_t *buf = c->axe_buf;
   1416   1.38   tsutsui 	uint32_t total_len;
   1417   1.38   tsutsui 	struct mbuf *m;
   1418    1.1  augustss 
   1419  1.100       mrg 	mutex_enter(&sc->axe_rxlock);
   1420    1.1  augustss 
   1421  1.100       mrg 	if (sc->axe_dying || sc->axe_stopping ||
   1422  1.100       mrg 	    status == USBD_INVAL || status == USBD_NOT_STARTED ||
   1423  1.100       mrg 	    status == USBD_CANCELLED || !(ifp->if_flags & IFF_RUNNING)) {
   1424  1.100       mrg 		mutex_exit(&sc->axe_rxlock);
   1425    1.1  augustss 		return;
   1426  1.100       mrg 	}
   1427    1.1  augustss 
   1428    1.1  augustss 	if (status != USBD_NORMAL_COMPLETION) {
   1429   1.76     skrll 		if (usbd_ratecheck(&sc->axe_rx_notice)) {
   1430   1.35  pgoyette 			aprint_error_dev(sc->axe_dev, "usb errors on rx: %s\n",
   1431   1.35  pgoyette 			    usbd_errstr(status));
   1432   1.76     skrll 		}
   1433    1.1  augustss 		if (status == USBD_STALLED)
   1434   1.12  augustss 			usbd_clear_endpoint_stall_async(sc->axe_ep[AXE_ENDPT_RX]);
   1435    1.1  augustss 		goto done;
   1436    1.1  augustss 	}
   1437    1.1  augustss 
   1438    1.1  augustss 	usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
   1439    1.1  augustss 
   1440   1.35  pgoyette 	do {
   1441   1.76     skrll 		u_int pktlen = 0;
   1442   1.76     skrll 		u_int rxlen = 0;
   1443   1.76     skrll 		int flags = 0;
   1444   1.76     skrll 		if ((sc->axe_flags & AXSTD_FRAME) != 0) {
   1445   1.76     skrll 			struct axe_sframe_hdr hdr;
   1446   1.76     skrll 
   1447   1.35  pgoyette 			if (total_len < sizeof(hdr)) {
   1448   1.35  pgoyette 				ifp->if_ierrors++;
   1449   1.35  pgoyette 				goto done;
   1450   1.35  pgoyette 			}
   1451   1.35  pgoyette 
   1452   1.94       rin #if !defined(__NO_STRICT_ALIGNMENT) && __GNUC_PREREQ__(6, 1)
   1453   1.94       rin 			/*
   1454   1.94       rin 			 * XXX hdr is 2-byte aligned in buf, not 4-byte.
   1455   1.94       rin 			 * For some architectures, __builtin_memcpy() of
   1456   1.94       rin 			 * GCC 6 attempts to copy sizeof(hdr) = 4 bytes
   1457   1.94       rin 			 * at onece, which results in alignment error.
   1458   1.94       rin 			 */
   1459   1.94       rin 			hdr.len = *(uint16_t *)buf;
   1460   1.94       rin 			hdr.ilen = *(uint16_t *)(buf + sizeof(uint16_t));
   1461   1.94       rin #else
   1462   1.35  pgoyette 			memcpy(&hdr, buf, sizeof(hdr));
   1463   1.94       rin #endif
   1464   1.76     skrll 
   1465   1.83  pgoyette 			DPRINTFN(20, "total_len %#jx len %jx ilen %#jx",
   1466   1.76     skrll 			    total_len,
   1467   1.76     skrll 			    (le16toh(hdr.len) & AXE_RH1M_RXLEN_MASK),
   1468   1.76     skrll 			    (le16toh(hdr.ilen) & AXE_RH1M_RXLEN_MASK), 0);
   1469   1.76     skrll 
   1470   1.35  pgoyette 			total_len -= sizeof(hdr);
   1471   1.42   tsutsui 			buf += sizeof(hdr);
   1472   1.35  pgoyette 
   1473   1.58  christos 			if (((le16toh(hdr.len) & AXE_RH1M_RXLEN_MASK) ^
   1474   1.62  christos 			    (le16toh(hdr.ilen) & AXE_RH1M_RXLEN_MASK)) !=
   1475   1.62  christos 			    AXE_RH1M_RXLEN_MASK) {
   1476   1.35  pgoyette 				ifp->if_ierrors++;
   1477   1.35  pgoyette 				goto done;
   1478   1.35  pgoyette 			}
   1479   1.42   tsutsui 
   1480   1.63  christos 			rxlen = le16toh(hdr.len) & AXE_RH1M_RXLEN_MASK;
   1481   1.42   tsutsui 			if (total_len < rxlen) {
   1482   1.42   tsutsui 				pktlen = total_len;
   1483   1.42   tsutsui 				total_len = 0;
   1484   1.42   tsutsui 			} else {
   1485   1.43   tsutsui 				pktlen = rxlen;
   1486   1.43   tsutsui 				rxlen = roundup2(rxlen, 2);
   1487   1.42   tsutsui 				total_len -= rxlen;
   1488   1.35  pgoyette 			}
   1489   1.35  pgoyette 
   1490   1.76     skrll 		} else if ((sc->axe_flags & AXCSUM_FRAME) != 0) {
   1491   1.76     skrll 			struct axe_csum_hdr csum_hdr;
   1492   1.76     skrll 
   1493   1.97   msaitoh 			if (total_len <	 sizeof(csum_hdr)) {
   1494   1.76     skrll 				ifp->if_ierrors++;
   1495   1.76     skrll 				goto done;
   1496   1.76     skrll 			}
   1497   1.76     skrll 
   1498   1.76     skrll 			memcpy(&csum_hdr, buf, sizeof(csum_hdr));
   1499   1.76     skrll 
   1500   1.76     skrll 			csum_hdr.len = le16toh(csum_hdr.len);
   1501   1.76     skrll 			csum_hdr.ilen = le16toh(csum_hdr.ilen);
   1502   1.76     skrll 			csum_hdr.cstatus = le16toh(csum_hdr.cstatus);
   1503   1.76     skrll 
   1504   1.83  pgoyette 			DPRINTFN(20, "total_len %#jx len %#jx ilen %#jx"
   1505   1.83  pgoyette 			    " cstatus %#jx", total_len,
   1506   1.76     skrll 			    csum_hdr.len, csum_hdr.ilen, csum_hdr.cstatus);
   1507   1.76     skrll 
   1508   1.76     skrll 			if ((AXE_CSUM_RXBYTES(csum_hdr.len) ^
   1509   1.76     skrll 			    AXE_CSUM_RXBYTES(csum_hdr.ilen)) !=
   1510   1.76     skrll 			    sc->sc_lenmask) {
   1511   1.76     skrll 				/* we lost sync */
   1512   1.76     skrll 				ifp->if_ierrors++;
   1513   1.83  pgoyette 				DPRINTFN(20, "len %#jx ilen %#jx lenmask %#jx "
   1514   1.83  pgoyette 				    "err",
   1515   1.76     skrll 				    AXE_CSUM_RXBYTES(csum_hdr.len),
   1516   1.76     skrll 				    AXE_CSUM_RXBYTES(csum_hdr.ilen),
   1517   1.76     skrll 				    sc->sc_lenmask, 0);
   1518   1.76     skrll 				goto done;
   1519   1.76     skrll 			}
   1520   1.76     skrll 			/*
   1521   1.76     skrll 			 * Get total transferred frame length including
   1522   1.76     skrll 			 * checksum header.  The length should be multiple
   1523   1.76     skrll 			 * of 4.
   1524   1.76     skrll 			 */
   1525   1.76     skrll 			pktlen = AXE_CSUM_RXBYTES(csum_hdr.len);
   1526   1.78     skrll 			u_int len = sizeof(csum_hdr) + pktlen;
   1527   1.76     skrll 			len = (len + 3) & ~3;
   1528   1.76     skrll 			if (total_len < len) {
   1529   1.83  pgoyette 				DPRINTFN(20, "total_len %#jx < len %#jx",
   1530   1.76     skrll 				    total_len, len, 0, 0);
   1531   1.76     skrll 				/* invalid length */
   1532   1.76     skrll 				ifp->if_ierrors++;
   1533   1.76     skrll 				goto done;
   1534   1.76     skrll 			}
   1535   1.76     skrll 			buf += sizeof(csum_hdr);
   1536   1.76     skrll 
   1537   1.76     skrll 			const uint16_t cstatus = csum_hdr.cstatus;
   1538   1.76     skrll 
   1539   1.76     skrll 			if (cstatus & AXE_CSUM_HDR_L3_TYPE_IPV4) {
   1540   1.76     skrll 				if (cstatus & AXE_CSUM_HDR_L4_CSUM_ERR)
   1541   1.76     skrll 					flags |= M_CSUM_TCP_UDP_BAD;
   1542   1.76     skrll 				if (cstatus & AXE_CSUM_HDR_L3_CSUM_ERR)
   1543   1.76     skrll 					flags |= M_CSUM_IPv4_BAD;
   1544   1.76     skrll 
   1545   1.76     skrll 				const uint16_t l4type =
   1546   1.76     skrll 				    cstatus & AXE_CSUM_HDR_L4_TYPE_MASK;
   1547   1.76     skrll 
   1548   1.76     skrll 				if (l4type == AXE_CSUM_HDR_L4_TYPE_TCP)
   1549   1.76     skrll 					flags |= M_CSUM_TCPv4;
   1550   1.76     skrll 				if (l4type == AXE_CSUM_HDR_L4_TYPE_UDP)
   1551   1.76     skrll 					flags |= M_CSUM_UDPv4;
   1552   1.76     skrll 			}
   1553   1.76     skrll 			if (total_len < len) {
   1554   1.76     skrll 				pktlen = total_len;
   1555   1.76     skrll 				total_len = 0;
   1556   1.76     skrll 			} else {
   1557   1.76     skrll 				total_len -= len;
   1558   1.76     skrll 				rxlen = len - sizeof(csum_hdr);
   1559   1.76     skrll 			}
   1560   1.83  pgoyette 			DPRINTFN(20, "total_len %#jx len %#jx pktlen %#jx"
   1561   1.83  pgoyette 			    " rxlen %#jx", total_len, len, pktlen, rxlen);
   1562   1.35  pgoyette 		} else { /* AX172 */
   1563   1.42   tsutsui 			pktlen = rxlen = total_len;
   1564   1.35  pgoyette 			total_len = 0;
   1565   1.35  pgoyette 		}
   1566   1.35  pgoyette 
   1567   1.44   tsutsui 		MGETHDR(m, M_DONTWAIT, MT_DATA);
   1568   1.44   tsutsui 		if (m == NULL) {
   1569   1.35  pgoyette 			ifp->if_ierrors++;
   1570   1.35  pgoyette 			goto done;
   1571   1.35  pgoyette 		}
   1572    1.1  augustss 
   1573   1.44   tsutsui 		if (pktlen > MHLEN - ETHER_ALIGN) {
   1574   1.44   tsutsui 			MCLGET(m, M_DONTWAIT);
   1575   1.44   tsutsui 			if ((m->m_flags & M_EXT) == 0) {
   1576   1.44   tsutsui 				m_freem(m);
   1577   1.44   tsutsui 				ifp->if_ierrors++;
   1578   1.44   tsutsui 				goto done;
   1579   1.44   tsutsui 			}
   1580   1.44   tsutsui 		}
   1581   1.44   tsutsui 		m->m_data += ETHER_ALIGN;
   1582   1.44   tsutsui 
   1583   1.72     ozaki 		m_set_rcvif(m, ifp);
   1584   1.35  pgoyette 		m->m_pkthdr.len = m->m_len = pktlen;
   1585   1.76     skrll 		m->m_pkthdr.csum_flags = flags;
   1586    1.1  augustss 
   1587   1.45   tsutsui 		memcpy(mtod(m, uint8_t *), buf, pktlen);
   1588   1.42   tsutsui 		buf += rxlen;
   1589    1.1  augustss 
   1590   1.83  pgoyette 		DPRINTFN(10, "deliver %jd (%#jx)", m->m_len, m->m_len, 0, 0);
   1591   1.76     skrll 
   1592  1.100       mrg 		mutex_exit(&sc->axe_rxlock);
   1593    1.1  augustss 
   1594   1.70     ozaki 		if_percpuq_enqueue((ifp)->if_percpuq, (m));
   1595    1.1  augustss 
   1596  1.100       mrg 		mutex_enter(&sc->axe_rxlock);
   1597  1.100       mrg 		if (sc->axe_dying || sc->axe_stopping) {
   1598  1.100       mrg 			mutex_exit(&sc->axe_rxlock);
   1599  1.100       mrg 			return;
   1600  1.100       mrg 		}
   1601    1.1  augustss 
   1602   1.35  pgoyette 	} while (total_len > 0);
   1603    1.1  augustss 
   1604    1.1  augustss  done:
   1605    1.1  augustss 
   1606  1.100       mrg 	if (sc->axe_dying || sc->axe_stopping) {
   1607  1.100       mrg 		mutex_exit(&sc->axe_rxlock);
   1608  1.100       mrg 		return;
   1609  1.100       mrg 	}
   1610  1.100       mrg 
   1611  1.100       mrg 	mutex_exit(&sc->axe_rxlock);
   1612  1.100       mrg 
   1613    1.1  augustss 	/* Setup new transfer. */
   1614   1.71     skrll 	usbd_setup_xfer(xfer, c, c->axe_buf, sc->axe_bufsz,
   1615   1.71     skrll 	    USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, axe_rxeof);
   1616    1.1  augustss 	usbd_transfer(xfer);
   1617    1.1  augustss 
   1618   1.76     skrll 	DPRINTFN(10, "start rx", 0, 0, 0, 0);
   1619    1.1  augustss }
   1620    1.1  augustss 
   1621    1.1  augustss /*
   1622    1.1  augustss  * A frame was downloaded to the chip. It's safe for us to clean up
   1623    1.1  augustss  * the list buffers.
   1624    1.1  augustss  */
   1625    1.1  augustss 
   1626   1.35  pgoyette static void
   1627   1.71     skrll axe_txeof(struct usbd_xfer *xfer, void * priv, usbd_status status)
   1628    1.1  augustss {
   1629   1.76     skrll 	AXEHIST_FUNC(); AXEHIST_CALLED();
   1630   1.76     skrll 	struct axe_chain *c = priv;
   1631   1.76     skrll 	struct axe_softc *sc = c->axe_sc;
   1632  1.100       mrg 	struct axe_cdata *cd = &sc->axe_cdata;
   1633   1.76     skrll 	struct ifnet *ifp = &sc->sc_if;
   1634    1.1  augustss 
   1635  1.100       mrg 	mutex_enter(&sc->axe_txlock);
   1636  1.100       mrg 	if (sc->axe_stopping || sc->axe_dying) {
   1637  1.100       mrg 		mutex_exit(&sc->axe_txlock);
   1638  1.100       mrg 		return;
   1639  1.100       mrg 	}
   1640  1.100       mrg 
   1641  1.100       mrg 	KASSERT(cd->axe_tx_cnt == 1);
   1642  1.100       mrg 	cd->axe_tx_cnt--;
   1643    1.1  augustss 
   1644  1.100       mrg 	sc->axe_timer = 0;
   1645    1.1  augustss 
   1646  1.100       mrg 	switch (status) {
   1647  1.100       mrg 	case USBD_NOT_STARTED:
   1648  1.100       mrg 	case USBD_CANCELLED:
   1649  1.100       mrg 		break;
   1650    1.1  augustss 
   1651  1.100       mrg 	case USBD_NORMAL_COMPLETION:
   1652  1.100       mrg 		ifp->if_opackets++;
   1653  1.100       mrg 		if (!IFQ_IS_EMPTY(&ifp->if_snd))
   1654  1.100       mrg 			axe_start_locked(ifp);
   1655  1.100       mrg 		break;
   1656  1.100       mrg 
   1657  1.100       mrg 	default:
   1658   1.66       roy 
   1659    1.1  augustss 		ifp->if_oerrors++;
   1660  1.100       mrg 		if (usbd_ratecheck(&sc->axe_tx_notice))
   1661  1.100       mrg 			aprint_error_dev(sc->axe_dev, "usb error on tx: %s\n",
   1662  1.100       mrg 			    usbd_errstr(status));
   1663    1.1  augustss 		if (status == USBD_STALLED)
   1664   1.12  augustss 			usbd_clear_endpoint_stall_async(sc->axe_ep[AXE_ENDPT_TX]);
   1665  1.100       mrg 		break;
   1666    1.1  augustss 	}
   1667    1.1  augustss 
   1668  1.100       mrg 	mutex_exit(&sc->axe_txlock);
   1669    1.1  augustss }
   1670    1.1  augustss 
   1671   1.35  pgoyette static void
   1672    1.1  augustss axe_tick(void *xsc)
   1673    1.1  augustss {
   1674   1.76     skrll 	AXEHIST_FUNC(); AXEHIST_CALLED();
   1675    1.1  augustss 	struct axe_softc *sc = xsc;
   1676    1.1  augustss 
   1677    1.1  augustss 	if (sc == NULL)
   1678    1.1  augustss 		return;
   1679    1.1  augustss 
   1680  1.100       mrg 	mutex_enter(&sc->axe_lock);
   1681  1.100       mrg 	if (!sc->axe_stopping && !sc->axe_dying) {
   1682  1.100       mrg 		/* Perform periodic stuff in process context */
   1683  1.100       mrg 		usb_add_task(sc->axe_udev, &sc->axe_tick_task, USB_TASKQ_DRIVER);
   1684  1.100       mrg 	}
   1685  1.100       mrg 	mutex_exit(&sc->axe_lock);
   1686    1.1  augustss 
   1687    1.1  augustss }
   1688    1.1  augustss 
   1689   1.35  pgoyette static void
   1690    1.1  augustss axe_tick_task(void *xsc)
   1691    1.1  augustss {
   1692   1.76     skrll 	AXEHIST_FUNC(); AXEHIST_CALLED();
   1693   1.76     skrll 	struct axe_softc *sc = xsc;
   1694   1.38   tsutsui 	struct ifnet *ifp;
   1695   1.38   tsutsui 	struct mii_data *mii;
   1696    1.1  augustss 
   1697    1.1  augustss 	if (sc == NULL)
   1698    1.1  augustss 		return;
   1699    1.1  augustss 
   1700  1.100       mrg 	mutex_enter(&sc->axe_lock);
   1701  1.100       mrg 	if (sc->axe_stopping || sc->axe_dying) {
   1702  1.100       mrg 		mutex_exit(&sc->axe_lock);
   1703    1.1  augustss 		return;
   1704  1.100       mrg 	}
   1705    1.1  augustss 
   1706   1.35  pgoyette 	ifp = &sc->sc_if;
   1707   1.35  pgoyette 	mii = &sc->axe_mii;
   1708   1.35  pgoyette 
   1709  1.100       mrg 	if (mii == NULL) {
   1710  1.100       mrg 		mutex_exit(&sc->axe_lock);
   1711    1.1  augustss 		return;
   1712  1.100       mrg 	}
   1713  1.100       mrg 
   1714  1.100       mrg 	sc->axe_refcnt++;
   1715  1.100       mrg 	mutex_exit(&sc->axe_lock);
   1716    1.1  augustss 
   1717  1.100       mrg 	if (sc->axe_timer != 0 && --sc->axe_timer == 0)
   1718  1.100       mrg 		axe_watchdog(ifp);
   1719    1.1  augustss 
   1720    1.1  augustss 	mii_tick(mii);
   1721  1.100       mrg 
   1722   1.38   tsutsui 	if (sc->axe_link == 0 &&
   1723   1.38   tsutsui 	    (mii->mii_media_status & IFM_ACTIVE) != 0 &&
   1724   1.35  pgoyette 	    IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
   1725   1.76     skrll 		DPRINTF("got link", 0, 0, 0, 0);
   1726   1.35  pgoyette 		sc->axe_link++;
   1727   1.36   tsutsui 		if (!IFQ_IS_EMPTY(&ifp->if_snd))
   1728   1.35  pgoyette 			axe_start(ifp);
   1729   1.35  pgoyette 	}
   1730    1.1  augustss 
   1731    1.1  augustss 
   1732  1.100       mrg 	mutex_enter(&sc->axe_lock);
   1733  1.100       mrg 	if (--sc->axe_refcnt < 0)
   1734  1.100       mrg 		cv_broadcast(&sc->axe_detachcv);
   1735  1.100       mrg 	if (!sc->axe_stopping && !sc->axe_dying)
   1736  1.100       mrg 		callout_schedule(&sc->axe_stat_ch, hz);
   1737  1.100       mrg 	mutex_exit(&sc->axe_lock);
   1738    1.1  augustss }
   1739    1.1  augustss 
   1740   1.35  pgoyette static int
   1741    1.1  augustss axe_encap(struct axe_softc *sc, struct mbuf *m, int idx)
   1742    1.1  augustss {
   1743   1.38   tsutsui 	struct ifnet *ifp = &sc->sc_if;
   1744   1.38   tsutsui 	struct axe_chain *c;
   1745   1.38   tsutsui 	usbd_status err;
   1746   1.38   tsutsui 	int length, boundary;
   1747    1.1  augustss 
   1748  1.100       mrg 	KASSERT(mutex_owned(&sc->axe_txlock));
   1749  1.100       mrg 
   1750    1.1  augustss 	c = &sc->axe_cdata.axe_tx_chain[idx];
   1751    1.1  augustss 
   1752    1.1  augustss 	/*
   1753    1.1  augustss 	 * Copy the mbuf data into a contiguous buffer, leaving two
   1754    1.1  augustss 	 * bytes at the beginning to hold the frame length.
   1755    1.1  augustss 	 */
   1756   1.76     skrll 	if (AXE_IS_178_FAMILY(sc)) {
   1757   1.97   msaitoh 		struct axe_sframe_hdr hdr;
   1758   1.76     skrll 
   1759   1.71     skrll 		boundary = (sc->axe_udev->ud_speed == USB_SPEED_HIGH) ? 512 : 64;
   1760   1.35  pgoyette 
   1761   1.35  pgoyette 		hdr.len = htole16(m->m_pkthdr.len);
   1762   1.35  pgoyette 		hdr.ilen = ~hdr.len;
   1763   1.35  pgoyette 
   1764   1.35  pgoyette 		memcpy(c->axe_buf, &hdr, sizeof(hdr));
   1765   1.35  pgoyette 		length = sizeof(hdr);
   1766   1.35  pgoyette 
   1767   1.35  pgoyette 		m_copydata(m, 0, m->m_pkthdr.len, c->axe_buf + length);
   1768   1.35  pgoyette 		length += m->m_pkthdr.len;
   1769   1.35  pgoyette 
   1770   1.35  pgoyette 		if ((length % boundary) == 0) {
   1771   1.35  pgoyette 			hdr.len = 0x0000;
   1772   1.35  pgoyette 			hdr.ilen = 0xffff;
   1773   1.35  pgoyette 			memcpy(c->axe_buf + length, &hdr, sizeof(hdr));
   1774   1.35  pgoyette 			length += sizeof(hdr);
   1775   1.35  pgoyette 		}
   1776   1.35  pgoyette 	} else {
   1777   1.35  pgoyette 		m_copydata(m, 0, m->m_pkthdr.len, c->axe_buf);
   1778   1.35  pgoyette 		length = m->m_pkthdr.len;
   1779   1.35  pgoyette 	}
   1780    1.1  augustss 
   1781   1.71     skrll 	usbd_setup_xfer(c->axe_xfer, c, c->axe_buf, length,
   1782   1.71     skrll 	    USBD_FORCE_SHORT_XFER, 10000, axe_txeof);
   1783    1.1  augustss 
   1784    1.1  augustss 	/* Transmit */
   1785    1.1  augustss 	err = usbd_transfer(c->axe_xfer);
   1786    1.1  augustss 	if (err != USBD_IN_PROGRESS) {
   1787  1.100       mrg 		/* XXXSMP IFNET_LOCK */
   1788   1.35  pgoyette 		axe_stop(ifp, 0);
   1789   1.35  pgoyette 		return EIO;
   1790    1.1  augustss 	}
   1791    1.1  augustss 
   1792    1.1  augustss 	sc->axe_cdata.axe_tx_cnt++;
   1793    1.1  augustss 
   1794   1.35  pgoyette 	return 0;
   1795    1.1  augustss }
   1796    1.1  augustss 
   1797   1.76     skrll 
   1798   1.76     skrll static void
   1799   1.76     skrll axe_csum_cfg(struct axe_softc *sc)
   1800   1.76     skrll {
   1801   1.76     skrll 	struct ifnet *ifp = &sc->sc_if;
   1802   1.76     skrll 	uint16_t csum1, csum2;
   1803   1.76     skrll 
   1804   1.76     skrll 	if ((sc->axe_flags & AX772B) != 0) {
   1805   1.76     skrll 		csum1 = 0;
   1806   1.76     skrll 		csum2 = 0;
   1807   1.76     skrll 		if ((ifp->if_capenable & IFCAP_CSUM_IPv4_Tx) != 0)
   1808   1.76     skrll 			csum1 |= AXE_TXCSUM_IP;
   1809   1.76     skrll 		if ((ifp->if_capenable & IFCAP_CSUM_TCPv4_Tx) != 0)
   1810   1.76     skrll 			csum1 |= AXE_TXCSUM_TCP;
   1811   1.76     skrll 		if ((ifp->if_capenable & IFCAP_CSUM_UDPv4_Tx) != 0)
   1812   1.76     skrll 			csum1 |= AXE_TXCSUM_UDP;
   1813   1.76     skrll 		if ((ifp->if_capenable & IFCAP_CSUM_TCPv6_Tx) != 0)
   1814   1.76     skrll 			csum1 |= AXE_TXCSUM_TCPV6;
   1815   1.76     skrll 		if ((ifp->if_capenable & IFCAP_CSUM_UDPv6_Tx) != 0)
   1816   1.76     skrll 			csum1 |= AXE_TXCSUM_UDPV6;
   1817   1.76     skrll 		axe_cmd(sc, AXE_772B_CMD_WRITE_TXCSUM, csum2, csum1, NULL);
   1818   1.76     skrll 		csum1 = 0;
   1819   1.76     skrll 		csum2 = 0;
   1820   1.76     skrll 
   1821   1.76     skrll 		if ((ifp->if_capenable & IFCAP_CSUM_IPv4_Rx) != 0)
   1822   1.76     skrll 			csum1 |= AXE_RXCSUM_IP;
   1823   1.76     skrll 		if ((ifp->if_capenable & IFCAP_CSUM_TCPv4_Rx) != 0)
   1824   1.76     skrll 			csum1 |= AXE_RXCSUM_TCP;
   1825   1.76     skrll 		if ((ifp->if_capenable & IFCAP_CSUM_UDPv4_Rx) != 0)
   1826   1.76     skrll 			csum1 |= AXE_RXCSUM_UDP;
   1827   1.76     skrll 		if ((ifp->if_capenable & IFCAP_CSUM_TCPv6_Rx) != 0)
   1828   1.76     skrll 			csum1 |= AXE_RXCSUM_TCPV6;
   1829   1.76     skrll 		if ((ifp->if_capenable & IFCAP_CSUM_UDPv6_Rx) != 0)
   1830   1.76     skrll 			csum1 |= AXE_RXCSUM_UDPV6;
   1831   1.76     skrll 		axe_cmd(sc, AXE_772B_CMD_WRITE_RXCSUM, csum2, csum1, NULL);
   1832   1.76     skrll 	}
   1833   1.76     skrll }
   1834   1.76     skrll 
   1835   1.35  pgoyette static void
   1836  1.100       mrg axe_start_locked(struct ifnet *ifp)
   1837    1.1  augustss {
   1838  1.100       mrg 	struct axe_softc *sc = ifp->if_softc;
   1839   1.46   tsutsui 	struct mbuf *m;
   1840  1.100       mrg 	struct axe_cdata *cd = &sc->axe_cdata;
   1841    1.1  augustss 
   1842  1.100       mrg 	KASSERT(mutex_owned(&sc->axe_txlock));
   1843  1.100       mrg 
   1844  1.100       mrg 	if (cd->axe_tx_cnt != 0)
   1845  1.100       mrg 		return;
   1846    1.1  augustss 
   1847  1.100       mrg 	if (sc->axe_link == 0 || (ifp->if_flags & IFF_RUNNING) == 0)
   1848    1.1  augustss 		return;
   1849    1.1  augustss 
   1850   1.46   tsutsui 	IFQ_POLL(&ifp->if_snd, m);
   1851   1.46   tsutsui 	if (m == NULL) {
   1852    1.1  augustss 		return;
   1853    1.1  augustss 	}
   1854    1.1  augustss 
   1855   1.46   tsutsui 	if (axe_encap(sc, m, 0)) {
   1856    1.1  augustss 		return;
   1857    1.1  augustss 	}
   1858   1.46   tsutsui 	IFQ_DEQUEUE(&ifp->if_snd, m);
   1859    1.1  augustss 
   1860    1.1  augustss 	/*
   1861    1.1  augustss 	 * If there's a BPF listener, bounce a copy of this frame
   1862    1.1  augustss 	 * to him.
   1863    1.1  augustss 	 */
   1864   1.90   msaitoh 	bpf_mtap(ifp, m, BPF_D_OUT);
   1865   1.46   tsutsui 	m_freem(m);
   1866    1.1  augustss 
   1867    1.1  augustss 	/*
   1868    1.1  augustss 	 * Set a timeout in case the chip goes out to lunch.
   1869    1.1  augustss 	 */
   1870  1.100       mrg 	sc->axe_timer = 5;
   1871    1.1  augustss 
   1872    1.1  augustss 	return;
   1873    1.1  augustss }
   1874    1.1  augustss 
   1875  1.100       mrg static void
   1876  1.100       mrg axe_start(struct ifnet *ifp)
   1877  1.100       mrg {
   1878  1.100       mrg 	struct axe_softc * const sc = ifp->if_softc;
   1879  1.100       mrg 
   1880  1.100       mrg 	mutex_enter(&sc->axe_txlock);
   1881  1.100       mrg 	if (!sc->axe_stopping)
   1882  1.100       mrg 		axe_start_locked(ifp);
   1883  1.100       mrg 	mutex_exit(&sc->axe_txlock);
   1884  1.100       mrg }
   1885  1.100       mrg 
   1886   1.35  pgoyette static int
   1887  1.100       mrg axe_init_locked(struct ifnet *ifp)
   1888    1.1  augustss {
   1889   1.76     skrll 	AXEHIST_FUNC(); AXEHIST_CALLED();
   1890   1.38   tsutsui 	struct axe_softc *sc = ifp->if_softc;
   1891   1.38   tsutsui 	struct axe_chain *c;
   1892   1.38   tsutsui 	usbd_status err;
   1893   1.38   tsutsui 	int rxmode;
   1894  1.100       mrg 	int i;
   1895   1.35  pgoyette 
   1896  1.100       mrg 	KASSERT(mutex_owned(&sc->axe_lock));
   1897  1.100       mrg 
   1898  1.100       mrg 	if (sc->axe_dying)
   1899  1.100       mrg 		return EIO;
   1900    1.1  augustss 
   1901  1.100       mrg 	/* Cancel pending I/O */
   1902  1.100       mrg 	axe_stop_locked(ifp, 0);
   1903    1.1  augustss 
   1904  1.100       mrg 	/* Reset the ethernet interface. */
   1905    1.1  augustss 	axe_reset(sc);
   1906    1.1  augustss 
   1907  1.100       mrg 	axe_lock_mii_sc_locked(sc);
   1908   1.35  pgoyette 
   1909   1.76     skrll #if 0
   1910   1.76     skrll 	ret = asix_write_gpio(dev, AX_GPIO_RSE | AX_GPIO_GPO_2 |
   1911   1.76     skrll 			      AX_GPIO_GPO2EN, 5, in_pm);
   1912   1.76     skrll #endif
   1913   1.76     skrll 	/* Set MAC address and transmitter IPG values. */
   1914   1.76     skrll 	if (AXE_IS_178_FAMILY(sc)) {
   1915   1.76     skrll 		axe_cmd(sc, AXE_178_CMD_WRITE_NODEID, 0, 0, sc->axe_enaddr);
   1916   1.35  pgoyette 		axe_cmd(sc, AXE_178_CMD_WRITE_IPG012, sc->axe_ipgs[2],
   1917   1.35  pgoyette 		    (sc->axe_ipgs[1] << 8) | (sc->axe_ipgs[0]), NULL);
   1918   1.76     skrll 	} else {
   1919   1.76     skrll 		axe_cmd(sc, AXE_172_CMD_WRITE_NODEID, 0, 0, sc->axe_enaddr);
   1920   1.35  pgoyette 		axe_cmd(sc, AXE_172_CMD_WRITE_IPG0, 0, sc->axe_ipgs[0], NULL);
   1921   1.35  pgoyette 		axe_cmd(sc, AXE_172_CMD_WRITE_IPG1, 0, sc->axe_ipgs[1], NULL);
   1922   1.35  pgoyette 		axe_cmd(sc, AXE_172_CMD_WRITE_IPG2, 0, sc->axe_ipgs[2], NULL);
   1923   1.35  pgoyette 	}
   1924   1.76     skrll 	if (AXE_IS_178_FAMILY(sc)) {
   1925   1.76     skrll 		sc->axe_flags &= ~(AXSTD_FRAME | AXCSUM_FRAME);
   1926   1.76     skrll 		if ((sc->axe_flags & AX772B) != 0 &&
   1927   1.76     skrll 		    (ifp->if_capenable & AX_RXCSUM) != 0) {
   1928   1.76     skrll 			sc->sc_lenmask = AXE_CSUM_HDR_LEN_MASK;
   1929   1.76     skrll 			sc->axe_flags |= AXCSUM_FRAME;
   1930   1.76     skrll 		} else {
   1931   1.76     skrll 			sc->sc_lenmask = AXE_HDR_LEN_MASK;
   1932   1.76     skrll 			sc->axe_flags |= AXSTD_FRAME;
   1933   1.76     skrll 		}
   1934   1.76     skrll 	}
   1935   1.76     skrll 
   1936   1.76     skrll 	/* Configure TX/RX checksum offloading. */
   1937   1.76     skrll 	axe_csum_cfg(sc);
   1938    1.1  augustss 
   1939   1.76     skrll 	if (sc->axe_flags & AX772B) {
   1940   1.76     skrll 		/* AX88772B uses different maximum frame burst configuration. */
   1941   1.76     skrll 		axe_cmd(sc, AXE_772B_CMD_RXCTL_WRITE_CFG,
   1942   1.76     skrll 		    ax88772b_mfb_table[AX88772B_MFB_16K].threshold,
   1943   1.76     skrll 		    ax88772b_mfb_table[AX88772B_MFB_16K].byte_cnt, NULL);
   1944   1.76     skrll 	}
   1945    1.1  augustss 	/* Enable receiver, set RX mode */
   1946   1.76     skrll 	rxmode = (AXE_RXCMD_MULTICAST | AXE_RXCMD_ENABLE);
   1947   1.76     skrll 	if (AXE_IS_178_FAMILY(sc)) {
   1948   1.76     skrll 		if (sc->axe_flags & AX772B) {
   1949   1.76     skrll 			/*
   1950   1.76     skrll 			 * Select RX header format type 1.  Aligning IP
   1951   1.76     skrll 			 * header on 4 byte boundary is not needed when
   1952   1.76     skrll 			 * checksum offloading feature is not used
   1953   1.76     skrll 			 * because we always copy the received frame in
   1954   1.76     skrll 			 * RX handler.  When RX checksum offloading is
   1955   1.76     skrll 			 * active, aligning IP header is required to
   1956   1.76     skrll 			 * reflect actual frame length including RX
   1957   1.76     skrll 			 * header size.
   1958   1.76     skrll 			 */
   1959   1.76     skrll 			rxmode |= AXE_772B_RXCMD_HDR_TYPE_1;
   1960   1.76     skrll 			if (sc->axe_flags & AXCSUM_FRAME)
   1961   1.76     skrll 				rxmode |= AXE_772B_RXCMD_IPHDR_ALIGN;
   1962   1.76     skrll 		} else {
   1963   1.76     skrll 			/*
   1964   1.76     skrll 			 * Default Rx buffer size is too small to get
   1965   1.76     skrll 			 * maximum performance.
   1966   1.76     skrll 			 */
   1967   1.76     skrll #if 0
   1968   1.76     skrll 			if (sc->axe_udev->ud_speed == USB_SPEED_HIGH) {
   1969   1.76     skrll 				/* Largest possible USB buffer size for AX88178 */
   1970  1.100       mrg 			}
   1971   1.76     skrll #endif
   1972   1.76     skrll 			rxmode |= AXE_178_RXCMD_MFB_16384;
   1973   1.35  pgoyette 		}
   1974   1.76     skrll 	} else {
   1975   1.35  pgoyette 		rxmode |= AXE_172_RXCMD_UNICAST;
   1976   1.76     skrll 	}
   1977   1.76     skrll 
   1978    1.1  augustss 
   1979    1.1  augustss 	/* If we want promiscuous mode, set the allframes bit. */
   1980    1.1  augustss 	if (ifp->if_flags & IFF_PROMISC)
   1981    1.1  augustss 		rxmode |= AXE_RXCMD_PROMISC;
   1982    1.1  augustss 
   1983    1.1  augustss 	if (ifp->if_flags & IFF_BROADCAST)
   1984    1.1  augustss 		rxmode |= AXE_RXCMD_BROADCAST;
   1985    1.1  augustss 
   1986   1.83  pgoyette 	DPRINTF("rxmode 0x%#jx", rxmode, 0, 0, 0);
   1987   1.76     skrll 
   1988    1.1  augustss 	axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, rxmode, NULL);
   1989    1.1  augustss 
   1990    1.1  augustss 	/* Load the multicast filter. */
   1991  1.100       mrg 	axe_setmulti_locked(sc);
   1992  1.100       mrg 
   1993  1.100       mrg 	axe_unlock_mii_sc_locked(sc);
   1994    1.1  augustss 
   1995    1.1  augustss 	/* Open RX and TX pipes. */
   1996    1.1  augustss 	err = usbd_open_pipe(sc->axe_iface, sc->axe_ed[AXE_ENDPT_RX],
   1997  1.100       mrg 	    USBD_EXCLUSIVE_USE | USBD_MPSAFE, &sc->axe_ep[AXE_ENDPT_RX]);
   1998    1.1  augustss 	if (err) {
   1999   1.35  pgoyette 		aprint_error_dev(sc->axe_dev, "open rx pipe failed: %s\n",
   2000   1.35  pgoyette 		    usbd_errstr(err));
   2001   1.35  pgoyette 		return EIO;
   2002    1.1  augustss 	}
   2003    1.1  augustss 
   2004    1.1  augustss 	err = usbd_open_pipe(sc->axe_iface, sc->axe_ed[AXE_ENDPT_TX],
   2005  1.100       mrg 	    USBD_EXCLUSIVE_USE | USBD_MPSAFE, &sc->axe_ep[AXE_ENDPT_TX]);
   2006    1.1  augustss 	if (err) {
   2007   1.35  pgoyette 		aprint_error_dev(sc->axe_dev, "open tx pipe failed: %s\n",
   2008   1.35  pgoyette 		    usbd_errstr(err));
   2009   1.35  pgoyette 		return EIO;
   2010    1.1  augustss 	}
   2011    1.1  augustss 
   2012   1.71     skrll 	/* Init RX ring. */
   2013   1.71     skrll 	if (axe_rx_list_init(sc) != 0) {
   2014   1.71     skrll 		aprint_error_dev(sc->axe_dev, "rx list init failed\n");
   2015   1.71     skrll 		return ENOBUFS;
   2016   1.71     skrll 	}
   2017   1.71     skrll 
   2018   1.71     skrll 	/* Init TX ring. */
   2019   1.71     skrll 	if (axe_tx_list_init(sc) != 0) {
   2020   1.71     skrll 		aprint_error_dev(sc->axe_dev, "tx list init failed\n");
   2021   1.71     skrll 		return ENOBUFS;
   2022   1.71     skrll 	}
   2023   1.71     skrll 
   2024  1.100       mrg 	mutex_enter(&sc->axe_rxlock);
   2025  1.100       mrg 	mutex_enter(&sc->axe_txlock);
   2026  1.100       mrg 	sc->axe_stopping = false;
   2027  1.100       mrg 
   2028    1.1  augustss 	/* Start up the receive pipe. */
   2029    1.1  augustss 	for (i = 0; i < AXE_RX_LIST_CNT; i++) {
   2030    1.1  augustss 		c = &sc->axe_cdata.axe_rx_chain[i];
   2031   1.71     skrll 		usbd_setup_xfer(c->axe_xfer, c, c->axe_buf, sc->axe_bufsz,
   2032   1.71     skrll 		    USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, axe_rxeof);
   2033    1.1  augustss 		usbd_transfer(c->axe_xfer);
   2034    1.1  augustss 	}
   2035    1.1  augustss 
   2036  1.100       mrg 	mutex_exit(&sc->axe_txlock);
   2037  1.100       mrg 	mutex_exit(&sc->axe_rxlock);
   2038  1.100       mrg 
   2039  1.100       mrg 	/* Indicate we are up and running. */
   2040  1.100       mrg 	KASSERT(IFNET_LOCKED(ifp));
   2041    1.1  augustss 	ifp->if_flags |= IFF_RUNNING;
   2042    1.1  augustss 
   2043   1.35  pgoyette 	callout_schedule(&sc->axe_stat_ch, hz);
   2044   1.35  pgoyette 	return 0;
   2045    1.1  augustss }
   2046    1.1  augustss 
   2047   1.35  pgoyette static int
   2048  1.100       mrg axe_init(struct ifnet *ifp)
   2049  1.100       mrg {
   2050  1.100       mrg 	struct axe_softc * const sc = ifp->if_softc;
   2051  1.100       mrg 
   2052  1.100       mrg 	mutex_enter(&sc->axe_lock);
   2053  1.100       mrg 	int ret = axe_init_locked(ifp);
   2054  1.100       mrg 	mutex_exit(&sc->axe_lock);
   2055  1.100       mrg 
   2056  1.100       mrg 	return ret;
   2057  1.100       mrg }
   2058  1.100       mrg 
   2059  1.100       mrg static int
   2060   1.18  christos axe_ioctl(struct ifnet *ifp, u_long cmd, void *data)
   2061    1.1  augustss {
   2062   1.38   tsutsui 	struct axe_softc *sc = ifp->if_softc;
   2063   1.38   tsutsui 	int error = 0;
   2064    1.1  augustss 
   2065   1.96   msaitoh 	switch (cmd) {
   2066   1.35  pgoyette 	case SIOCSIFFLAGS:
   2067   1.38   tsutsui 		if ((error = ifioctl_common(ifp, cmd, data)) != 0)
   2068   1.38   tsutsui 			break;
   2069   1.35  pgoyette 
   2070   1.35  pgoyette 		switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) {
   2071   1.35  pgoyette 		case IFF_RUNNING:
   2072   1.35  pgoyette 			axe_stop(ifp, 1);
   2073   1.35  pgoyette 			break;
   2074   1.35  pgoyette 		case IFF_UP:
   2075   1.35  pgoyette 			axe_init(ifp);
   2076   1.35  pgoyette 			break;
   2077   1.35  pgoyette 		case IFF_UP | IFF_RUNNING:
   2078   1.35  pgoyette 			if ((ifp->if_flags ^ sc->axe_if_flags) == IFF_PROMISC)
   2079   1.35  pgoyette 				axe_setmulti(sc);
   2080   1.35  pgoyette 			else
   2081   1.35  pgoyette 				axe_init(ifp);
   2082    1.1  augustss 			break;
   2083    1.1  augustss 		}
   2084  1.100       mrg 		mutex_enter(&sc->axe_rxlock);
   2085  1.100       mrg 		mutex_enter(&sc->axe_txlock);
   2086   1.35  pgoyette 		sc->axe_if_flags = ifp->if_flags;
   2087  1.100       mrg 		mutex_exit(&sc->axe_txlock);
   2088  1.100       mrg 		mutex_exit(&sc->axe_rxlock);
   2089    1.1  augustss 		break;
   2090    1.1  augustss 
   2091   1.35  pgoyette 	default:
   2092   1.35  pgoyette 		if ((error = ether_ioctl(ifp, cmd, data)) != ENETRESET)
   2093   1.26    dyoung 			break;
   2094    1.1  augustss 
   2095    1.1  augustss 		error = 0;
   2096   1.35  pgoyette 
   2097   1.35  pgoyette 		if (cmd == SIOCADDMULTI || cmd == SIOCDELMULTI)
   2098   1.35  pgoyette 			axe_setmulti(sc);
   2099   1.35  pgoyette 
   2100    1.1  augustss 	}
   2101    1.1  augustss 
   2102   1.35  pgoyette 	return error;
   2103    1.1  augustss }
   2104    1.1  augustss 
   2105   1.35  pgoyette static void
   2106    1.1  augustss axe_watchdog(struct ifnet *ifp)
   2107    1.1  augustss {
   2108  1.100       mrg 	struct axe_softc * const sc = ifp->if_softc;
   2109   1.38   tsutsui 	struct axe_chain *c;
   2110   1.38   tsutsui 	usbd_status stat;
   2111    1.1  augustss 
   2112    1.1  augustss 	ifp->if_oerrors++;
   2113   1.35  pgoyette 	aprint_error_dev(sc->axe_dev, "watchdog timeout\n");
   2114    1.1  augustss 
   2115    1.1  augustss 	c = &sc->axe_cdata.axe_tx_chain[0];
   2116    1.1  augustss 	usbd_get_xfer_status(c->axe_xfer, NULL, NULL, NULL, &stat);
   2117    1.1  augustss 	axe_txeof(c->axe_xfer, c, stat);
   2118    1.1  augustss 
   2119   1.35  pgoyette 	if (!IFQ_IS_EMPTY(&ifp->if_snd))
   2120    1.1  augustss 		axe_start(ifp);
   2121    1.1  augustss }
   2122    1.1  augustss 
   2123    1.1  augustss /*
   2124    1.1  augustss  * Stop the adapter and free any mbufs allocated to the
   2125    1.1  augustss  * RX and TX lists.
   2126    1.1  augustss  */
   2127   1.35  pgoyette static void
   2128  1.100       mrg axe_stop_locked(struct ifnet *ifp, int disable)
   2129    1.1  augustss {
   2130  1.100       mrg 	struct axe_softc * const sc = ifp->if_softc;
   2131   1.38   tsutsui 	usbd_status err;
   2132   1.38   tsutsui 	int i;
   2133    1.1  augustss 
   2134  1.100       mrg 	KASSERT(mutex_owned(&sc->axe_lock));
   2135  1.100       mrg 
   2136  1.100       mrg 	mutex_enter(&sc->axe_rxlock);
   2137  1.100       mrg 	mutex_enter(&sc->axe_txlock);
   2138  1.100       mrg 	sc->axe_stopping = true;
   2139  1.100       mrg 	mutex_exit(&sc->axe_txlock);
   2140  1.100       mrg 	mutex_exit(&sc->axe_rxlock);
   2141  1.100       mrg 
   2142  1.100       mrg 	/*
   2143  1.100       mrg 	 * XXXSMP Would like to
   2144  1.100       mrg 	 *	KASSERT(IFNET_LOCKED(ifp))
   2145  1.100       mrg 	 * here but the locking order is:
   2146  1.100       mrg 	 *	ifnet -> sc lock -> rxlock -> txlock
   2147  1.100       mrg 	 * and sc lock is already held.
   2148  1.100       mrg 	 */
   2149  1.100       mrg 	ifp->if_flags &= ~IFF_RUNNING;
   2150  1.100       mrg 	sc->axe_timer = 0;
   2151    1.1  augustss 
   2152   1.47    dyoung 	callout_stop(&sc->axe_stat_ch);
   2153  1.100       mrg 	sc->axe_link = 0;
   2154    1.1  augustss 
   2155    1.1  augustss 	/* Stop transfers. */
   2156    1.1  augustss 	if (sc->axe_ep[AXE_ENDPT_RX] != NULL) {
   2157    1.1  augustss 		err = usbd_abort_pipe(sc->axe_ep[AXE_ENDPT_RX]);
   2158    1.1  augustss 		if (err) {
   2159   1.35  pgoyette 			aprint_error_dev(sc->axe_dev,
   2160   1.35  pgoyette 			    "abort rx pipe failed: %s\n", usbd_errstr(err));
   2161    1.1  augustss 		}
   2162    1.1  augustss 	}
   2163    1.1  augustss 
   2164    1.1  augustss 	if (sc->axe_ep[AXE_ENDPT_TX] != NULL) {
   2165    1.1  augustss 		err = usbd_abort_pipe(sc->axe_ep[AXE_ENDPT_TX]);
   2166    1.1  augustss 		if (err) {
   2167   1.35  pgoyette 			aprint_error_dev(sc->axe_dev,
   2168   1.35  pgoyette 			    "abort tx pipe failed: %s\n", usbd_errstr(err));
   2169    1.1  augustss 		}
   2170    1.1  augustss 	}
   2171    1.1  augustss 
   2172    1.1  augustss 	if (sc->axe_ep[AXE_ENDPT_INTR] != NULL) {
   2173    1.1  augustss 		err = usbd_abort_pipe(sc->axe_ep[AXE_ENDPT_INTR]);
   2174    1.1  augustss 		if (err) {
   2175   1.35  pgoyette 			aprint_error_dev(sc->axe_dev,
   2176   1.35  pgoyette 			    "abort intr pipe failed: %s\n", usbd_errstr(err));
   2177    1.1  augustss 		}
   2178    1.1  augustss 	}
   2179    1.1  augustss 
   2180   1.76     skrll 	axe_reset(sc);
   2181   1.76     skrll 
   2182    1.1  augustss 	/* Free RX resources. */
   2183    1.1  augustss 	for (i = 0; i < AXE_RX_LIST_CNT; i++) {
   2184    1.1  augustss 		if (sc->axe_cdata.axe_rx_chain[i].axe_xfer != NULL) {
   2185   1.71     skrll 			usbd_destroy_xfer(sc->axe_cdata.axe_rx_chain[i].axe_xfer);
   2186    1.1  augustss 			sc->axe_cdata.axe_rx_chain[i].axe_xfer = NULL;
   2187    1.1  augustss 		}
   2188    1.1  augustss 	}
   2189    1.1  augustss 
   2190    1.1  augustss 	/* Free TX resources. */
   2191    1.1  augustss 	for (i = 0; i < AXE_TX_LIST_CNT; i++) {
   2192    1.1  augustss 		if (sc->axe_cdata.axe_tx_chain[i].axe_xfer != NULL) {
   2193   1.71     skrll 			usbd_destroy_xfer(sc->axe_cdata.axe_tx_chain[i].axe_xfer);
   2194    1.1  augustss 			sc->axe_cdata.axe_tx_chain[i].axe_xfer = NULL;
   2195    1.1  augustss 		}
   2196    1.1  augustss 	}
   2197    1.1  augustss 
   2198   1.71     skrll 	/* Close pipes. */
   2199   1.71     skrll 	if (sc->axe_ep[AXE_ENDPT_RX] != NULL) {
   2200   1.71     skrll 		err = usbd_close_pipe(sc->axe_ep[AXE_ENDPT_RX]);
   2201   1.71     skrll 		if (err) {
   2202   1.71     skrll 			aprint_error_dev(sc->axe_dev,
   2203   1.71     skrll 			    "close rx pipe failed: %s\n", usbd_errstr(err));
   2204   1.71     skrll 		}
   2205   1.71     skrll 		sc->axe_ep[AXE_ENDPT_RX] = NULL;
   2206   1.71     skrll 	}
   2207   1.71     skrll 
   2208   1.71     skrll 	if (sc->axe_ep[AXE_ENDPT_TX] != NULL) {
   2209   1.71     skrll 		err = usbd_close_pipe(sc->axe_ep[AXE_ENDPT_TX]);
   2210   1.71     skrll 		if (err) {
   2211   1.71     skrll 			aprint_error_dev(sc->axe_dev,
   2212   1.71     skrll 			    "close tx pipe failed: %s\n", usbd_errstr(err));
   2213   1.71     skrll 		}
   2214   1.71     skrll 		sc->axe_ep[AXE_ENDPT_TX] = NULL;
   2215   1.71     skrll 	}
   2216   1.71     skrll 
   2217   1.71     skrll 	if (sc->axe_ep[AXE_ENDPT_INTR] != NULL) {
   2218   1.71     skrll 		err = usbd_close_pipe(sc->axe_ep[AXE_ENDPT_INTR]);
   2219   1.71     skrll 		if (err) {
   2220   1.71     skrll 			aprint_error_dev(sc->axe_dev,
   2221   1.71     skrll 			    "close intr pipe failed: %s\n", usbd_errstr(err));
   2222   1.71     skrll 		}
   2223   1.71     skrll 		sc->axe_ep[AXE_ENDPT_INTR] = NULL;
   2224   1.71     skrll 	}
   2225  1.100       mrg }
   2226   1.71     skrll 
   2227  1.100       mrg static void
   2228  1.100       mrg axe_stop(struct ifnet *ifp, int disable)
   2229  1.100       mrg {
   2230  1.100       mrg 	struct axe_softc * const sc = ifp->if_softc;
   2231  1.100       mrg 
   2232  1.100       mrg 	mutex_enter(&sc->axe_lock);
   2233  1.100       mrg 	axe_stop_locked(ifp, disable);
   2234  1.100       mrg 	mutex_exit(&sc->axe_lock);
   2235    1.1  augustss }
   2236   1.48  pgoyette 
   2237   1.93  christos MODULE(MODULE_CLASS_DRIVER, if_axe, NULL);
   2238   1.48  pgoyette 
   2239   1.48  pgoyette #ifdef _MODULE
   2240   1.48  pgoyette #include "ioconf.c"
   2241   1.48  pgoyette #endif
   2242   1.48  pgoyette 
   2243   1.48  pgoyette static int
   2244   1.48  pgoyette if_axe_modcmd(modcmd_t cmd, void *aux)
   2245   1.48  pgoyette {
   2246   1.48  pgoyette 	int error = 0;
   2247   1.48  pgoyette 
   2248   1.48  pgoyette 	switch (cmd) {
   2249   1.48  pgoyette 	case MODULE_CMD_INIT:
   2250   1.48  pgoyette #ifdef _MODULE
   2251   1.49  pgoyette 		error = config_init_component(cfdriver_ioconf_axe,
   2252   1.49  pgoyette 		    cfattach_ioconf_axe, cfdata_ioconf_axe);
   2253   1.48  pgoyette #endif
   2254   1.48  pgoyette 		return error;
   2255   1.48  pgoyette 	case MODULE_CMD_FINI:
   2256   1.48  pgoyette #ifdef _MODULE
   2257   1.49  pgoyette 		error = config_fini_component(cfdriver_ioconf_axe,
   2258   1.49  pgoyette 		    cfattach_ioconf_axe, cfdata_ioconf_axe);
   2259   1.48  pgoyette #endif
   2260   1.48  pgoyette 		return error;
   2261   1.48  pgoyette 	default:
   2262   1.48  pgoyette 		return ENOTTY;
   2263   1.48  pgoyette 	}
   2264   1.48  pgoyette }
   2265