if_axe.c revision 215969
165543Scg/*-
265543Scg * Copyright (c) 1997, 1998, 1999, 2000-2003
365543Scg *	Bill Paul <wpaul@windriver.com>.  All rights reserved.
465543Scg *
565543Scg * Redistribution and use in source and binary forms, with or without
665543Scg * modification, are permitted provided that the following conditions
765543Scg * are met:
865543Scg * 1. Redistributions of source code must retain the above copyright
965543Scg *    notice, this list of conditions and the following disclaimer.
1065543Scg * 2. Redistributions in binary form must reproduce the above copyright
1165543Scg *    notice, this list of conditions and the following disclaimer in the
1265543Scg *    documentation and/or other materials provided with the distribution.
1365543Scg * 3. All advertising materials mentioning features or use of this software
1465543Scg *    must display the following acknowledgement:
1565543Scg *	This product includes software developed by Bill Paul.
1665543Scg * 4. Neither the name of the author nor the names of any co-contributors
1765543Scg *    may be used to endorse or promote products derived from this software
1865543Scg *    without specific prior written permission.
1965543Scg *
2065543Scg * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
2165543Scg * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2265543Scg * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2365543Scg * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
2465543Scg * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2565543Scg * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2665543Scg * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2765543Scg * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2865543Scg * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2965543Scg * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
3065543Scg * THE POSSIBILITY OF SUCH DAMAGE.
3165543Scg */
3265543Scg
3365543Scg#include <sys/cdefs.h>
3465543Scg__FBSDID("$FreeBSD: head/sys/dev/usb/net/if_axe.c 215969 2010-11-28 01:56:44Z yongari $");
3565543Scg
3665543Scg/*
3765543Scg * ASIX Electronics AX88172/AX88178/AX88778 USB 2.0 ethernet driver.
3865543Scg * Used in the LinkSys USB200M and various other adapters.
3965543Scg *
4065543Scg * Manuals available from:
4165543Scg * http://www.asix.com.tw/datasheet/mac/Ax88172.PDF
4265543Scg * Note: you need the manual for the AX88170 chip (USB 1.x ethernet
4365543Scg * controller) to find the definitions for the RX control register.
4465543Scg * http://www.asix.com.tw/datasheet/mac/Ax88170.PDF
4565543Scg *
4665543Scg * Written by Bill Paul <wpaul@windriver.com>
4765543Scg * Senior Engineer
4865543Scg * Wind River Systems
4965543Scg */
5065543Scg
5165543Scg/*
5265543Scg * The AX88172 provides USB ethernet supports at 10 and 100Mbps.
5365543Scg * It uses an external PHY (reference designs use a RealTek chip),
5482180Scg * and has a 64-bit multicast hash filter. There is some information
5582180Scg * missing from the manual which one needs to know in order to make
5665543Scg * the chip function:
5765543Scg *
5865543Scg * - You must set bit 7 in the RX control register, otherwise the
5965543Scg *   chip won't receive any packets.
6065543Scg * - You must initialize all 3 IPG registers, or you won't be able
6165543Scg *   to send any packets.
6265543Scg *
6365543Scg * Note that this device appears to only support loading the station
6465543Scg * address via autload from the EEPROM (i.e. there's no way to manaully
6565543Scg * set it).
6665543Scg *
6765543Scg * (Adam Weinberger wanted me to name this driver if_gir.c.)
6865543Scg */
6965543Scg
7065543Scg/*
7165543Scg * Ax88178 and Ax88772 support backported from the OpenBSD driver.
7265543Scg * 2007/02/12, J.R. Oldroyd, fbsd@opal.com
7365543Scg *
7465543Scg * Manual here:
7565543Scg * http://www.asix.com.tw/FrootAttach/datasheet/AX88178_datasheet_Rev10.pdf
7665543Scg * http://www.asix.com.tw/FrootAttach/datasheet/AX88772_datasheet_Rev10.pdf
7784658Scg */
7865543Scg
7965543Scg#include <sys/stdint.h>
8065543Scg#include <sys/stddef.h>
8165543Scg#include <sys/param.h>
8265543Scg#include <sys/queue.h>
8365543Scg#include <sys/types.h>
8465543Scg#include <sys/systm.h>
8574763Scg#include <sys/kernel.h>
8674763Scg#include <sys/bus.h>
8765543Scg#include <sys/linker_set.h>
8865543Scg#include <sys/module.h>
8970291Scg#include <sys/lock.h>
9065543Scg#include <sys/mutex.h>
9165543Scg#include <sys/condvar.h>
9265543Scg#include <sys/sysctl.h>
9365543Scg#include <sys/sx.h>
9465543Scg#include <sys/unistd.h>
9565543Scg#include <sys/callout.h>
9665543Scg#include <sys/malloc.h>
9765543Scg#include <sys/priv.h>
9865543Scg
9965543Scg#include <dev/usb/usb.h>
10065543Scg#include <dev/usb/usbdi.h>
10165543Scg#include <dev/usb/usbdi_util.h>
10265543Scg#include "usbdevs.h"
10365543Scg
10465543Scg#define	USB_DEBUG_VAR axe_debug
10565543Scg#include <dev/usb/usb_debug.h>
10665543Scg#include <dev/usb/usb_process.h>
10765543Scg
10865543Scg#include <dev/usb/net/usb_ethernet.h>
10965543Scg#include <dev/usb/net/if_axereg.h>
11065543Scg
11165543Scg/*
11265543Scg * AXE_178_MAX_FRAME_BURST
11374763Scg * max frame burst size for Ax88178 and Ax88772
11465543Scg *	0	2048 bytes
11584658Scg *	1	4096 bytes
11665543Scg *	2	8192 bytes
11765543Scg *	3	16384 bytes
11865543Scg * use the largest your system can handle without USB stalling.
11965543Scg *
12065543Scg * NB: 88772 parts appear to generate lots of input errors with
12165543Scg * a 2K rx buffer and 8K is only slightly faster than 4K on an
12265543Scg * EHCI port on a T42 so change at your own risk.
12365543Scg */
12465543Scg#define AXE_178_MAX_FRAME_BURST	1
12565543Scg
12665543Scg#ifdef USB_DEBUG
12765543Scgstatic int axe_debug = 0;
12865543Scg
12965543ScgSYSCTL_NODE(_hw_usb, OID_AUTO, axe, CTLFLAG_RW, 0, "USB axe");
13065543ScgSYSCTL_INT(_hw_usb_axe, OID_AUTO, debug, CTLFLAG_RW, &axe_debug, 0,
13165543Scg    "Debug level");
13265543Scg#endif
13365543Scg
13465543Scg/*
13565543Scg * Various supported device vendors/products.
13665543Scg */
13765543Scgstatic const struct usb_device_id axe_devs[] = {
13865543Scg#define	AXE_DEV(v,p,i) { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, i) }
13965543Scg	AXE_DEV(ABOCOM, UF200, 0),
14065543Scg	AXE_DEV(ACERCM, EP1427X2, 0),
14165543Scg	AXE_DEV(APPLE, ETHERNET, AXE_FLAG_772),
14265543Scg	AXE_DEV(ASIX, AX88172, 0),
14365543Scg	AXE_DEV(ASIX, AX88178, AXE_FLAG_178),
14465543Scg	AXE_DEV(ASIX, AX88772, AXE_FLAG_772),
14565543Scg	AXE_DEV(ASIX, AX88772A, AXE_FLAG_772A),
14665543Scg	AXE_DEV(ATEN, UC210T, 0),
14765543Scg	AXE_DEV(BELKIN, F5D5055, AXE_FLAG_178),
14865543Scg	AXE_DEV(BILLIONTON, USB2AR, 0),
14965543Scg	AXE_DEV(CISCOLINKSYS, USB200MV2, AXE_FLAG_772A),
15065543Scg	AXE_DEV(COREGA, FETHER_USB2_TX, 0),
15165543Scg	AXE_DEV(DLINK, DUBE100, 0),
15265543Scg	AXE_DEV(DLINK, DUBE100B1, AXE_FLAG_772),
15365543Scg	AXE_DEV(GOODWAY, GWUSB2E, 0),
15465543Scg	AXE_DEV(IODATA, ETGUS2, AXE_FLAG_178),
15565543Scg	AXE_DEV(JVC, MP_PRX1, 0),
15665543Scg	AXE_DEV(LINKSYS2, USB200M, 0),
15765543Scg	AXE_DEV(LINKSYS4, USB1000, AXE_FLAG_178),
15865543Scg	AXE_DEV(LOGITEC, LAN_GTJU2A, AXE_FLAG_178),
15965543Scg	AXE_DEV(MELCO, LUAU2KTX, 0),
16065543Scg	AXE_DEV(MELCO, LUA3U2AGT, AXE_FLAG_178),
16165543Scg	AXE_DEV(NETGEAR, FA120, 0),
16265543Scg	AXE_DEV(OQO, ETHER01PLUS, AXE_FLAG_772),
16365543Scg	AXE_DEV(PLANEX3, GU1000T, AXE_FLAG_178),
16465543Scg	AXE_DEV(SITECOM, LN029, 0),
16570134Scg	AXE_DEV(SITECOMEU, LN028, AXE_FLAG_178),
16670134Scg	AXE_DEV(SYSTEMTALKS, SGCX2UL, 0),
16765543Scg#undef AXE_DEV
16870134Scg};
16965543Scg
17065543Scgstatic device_probe_t axe_probe;
17170134Scgstatic device_attach_t axe_attach;
17270134Scgstatic device_detach_t axe_detach;
17370134Scg
17470134Scgstatic usb_callback_t axe_bulk_read_callback;
17570134Scgstatic usb_callback_t axe_bulk_write_callback;
17670134Scg
17770134Scgstatic miibus_readreg_t axe_miibus_readreg;
17870134Scgstatic miibus_writereg_t axe_miibus_writereg;
17965543Scgstatic miibus_statchg_t axe_miibus_statchg;
18065543Scg
18165543Scgstatic uether_fn_t axe_attach_post;
18265543Scgstatic uether_fn_t axe_init;
18365543Scgstatic uether_fn_t axe_stop;
18465543Scgstatic uether_fn_t axe_start;
18565543Scgstatic uether_fn_t axe_tick;
18665543Scgstatic uether_fn_t axe_setmulti;
18765543Scgstatic uether_fn_t axe_setpromisc;
18865543Scg
18965543Scgstatic int	axe_ifmedia_upd(struct ifnet *);
19065543Scgstatic void	axe_ifmedia_sts(struct ifnet *, struct ifmediareq *);
19165543Scgstatic int	axe_cmd(struct axe_softc *, int, int, int, void *);
19265543Scgstatic void	axe_ax88178_init(struct axe_softc *);
19365543Scgstatic void	axe_ax88772_init(struct axe_softc *);
19465543Scgstatic void	axe_ax88772a_init(struct axe_softc *);
19565543Scgstatic int	axe_get_phyno(struct axe_softc *, int);
19665543Scg
19765543Scgstatic const struct usb_config axe_config[AXE_N_TRANSFER] = {
19865543Scg
19965543Scg	[AXE_BULK_DT_WR] = {
20065543Scg		.type = UE_BULK,
20165543Scg		.endpoint = UE_ADDR_ANY,
20265543Scg		.direction = UE_DIR_OUT,
20365543Scg		.bufsize = AXE_BULK_BUF_SIZE,
20465543Scg		.flags = {.pipe_bof = 1,.force_short_xfer = 1,},
20565543Scg		.callback = axe_bulk_write_callback,
20665543Scg		.timeout = 10000,	/* 10 seconds */
20765543Scg	},
20865543Scg
20970134Scg	[AXE_BULK_DT_RD] = {
21070134Scg		.type = UE_BULK,
21165543Scg		.endpoint = UE_ADDR_ANY,
21265543Scg		.direction = UE_DIR_IN,
21365543Scg		.bufsize = 16384,	/* bytes */
21465543Scg		.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
21565543Scg		.callback = axe_bulk_read_callback,
21665543Scg		.timeout = 0,	/* no timeout */
21765543Scg	},
21865543Scg};
21965543Scg
22065543Scgstatic device_method_t axe_methods[] = {
22165543Scg	/* Device interface */
22265543Scg	DEVMETHOD(device_probe, axe_probe),
22365543Scg	DEVMETHOD(device_attach, axe_attach),
22465543Scg	DEVMETHOD(device_detach, axe_detach),
22570134Scg
22665543Scg	/* bus interface */
22765543Scg	DEVMETHOD(bus_print_child, bus_generic_print_child),
22865543Scg	DEVMETHOD(bus_driver_added, bus_generic_driver_added),
22965543Scg
23065543Scg	/* MII interface */
23170134Scg	DEVMETHOD(miibus_readreg, axe_miibus_readreg),
23270134Scg	DEVMETHOD(miibus_writereg, axe_miibus_writereg),
23365543Scg	DEVMETHOD(miibus_statchg, axe_miibus_statchg),
23465543Scg
23570134Scg	{0, 0}
23670134Scg};
23770134Scg
23870134Scgstatic driver_t axe_driver = {
23970134Scg	.name = "axe",
24070134Scg	.methods = axe_methods,
24170134Scg	.size = sizeof(struct axe_softc),
24270134Scg};
24370134Scg
24470134Scgstatic devclass_t axe_devclass;
24565543Scg
24665543ScgDRIVER_MODULE(axe, uhub, axe_driver, axe_devclass, NULL, 0);
24765543ScgDRIVER_MODULE(miibus, axe, miibus_driver, miibus_devclass, 0, 0);
24865543ScgMODULE_DEPEND(axe, uether, 1, 1, 1);
24965543ScgMODULE_DEPEND(axe, usb, 1, 1, 1);
25065543ScgMODULE_DEPEND(axe, ether, 1, 1, 1);
25165543ScgMODULE_DEPEND(axe, miibus, 1, 1, 1);
25265543ScgMODULE_VERSION(axe, 1);
25365543Scg
25465543Scgstatic const struct usb_ether_methods axe_ue_methods = {
25565543Scg	.ue_attach_post = axe_attach_post,
25665543Scg	.ue_start = axe_start,
25765543Scg	.ue_init = axe_init,
25865543Scg	.ue_stop = axe_stop,
25965543Scg	.ue_tick = axe_tick,
26065543Scg	.ue_setmulti = axe_setmulti,
26165543Scg	.ue_setpromisc = axe_setpromisc,
26265543Scg	.ue_mii_upd = axe_ifmedia_upd,
26365543Scg	.ue_mii_sts = axe_ifmedia_sts,
26465543Scg};
26565543Scg
26665543Scgstatic int
26765543Scgaxe_cmd(struct axe_softc *sc, int cmd, int index, int val, void *buf)
26865543Scg{
26965543Scg	struct usb_device_request req;
27065543Scg	usb_error_t err;
27165543Scg
27265543Scg	AXE_LOCK_ASSERT(sc, MA_OWNED);
27365543Scg
27465543Scg	req.bmRequestType = (AXE_CMD_IS_WRITE(cmd) ?
27565543Scg	    UT_WRITE_VENDOR_DEVICE :
27665543Scg	    UT_READ_VENDOR_DEVICE);
27765543Scg	req.bRequest = AXE_CMD_CMD(cmd);
27865543Scg	USETW(req.wValue, val);
27965543Scg	USETW(req.wIndex, index);
28065543Scg	USETW(req.wLength, AXE_CMD_LEN(cmd));
28165543Scg
28265543Scg	err = uether_do_request(&sc->sc_ue, &req, buf, 1000);
28365543Scg
28465543Scg	return (err);
28565543Scg}
28665543Scg
28765543Scgstatic int
28865543Scgaxe_miibus_readreg(device_t dev, int phy, int reg)
28965543Scg{
29065543Scg	struct axe_softc *sc = device_get_softc(dev);
29165543Scg	uint16_t val;
29265543Scg	int locked;
29365543Scg
29465543Scg	if (sc->sc_phyno != phy)
29565543Scg		return (0);
29665543Scg
29765543Scg	locked = mtx_owned(&sc->sc_mtx);
29865543Scg	if (!locked)
29965543Scg		AXE_LOCK(sc);
30065543Scg
30165543Scg	axe_cmd(sc, AXE_CMD_MII_OPMODE_SW, 0, 0, NULL);
30265543Scg	axe_cmd(sc, AXE_CMD_MII_READ_REG, reg, phy, &val);
30365543Scg	axe_cmd(sc, AXE_CMD_MII_OPMODE_HW, 0, 0, NULL);
30465543Scg
30565543Scg	val = le16toh(val);
30665543Scg	if (AXE_IS_772(sc) && reg == MII_BMSR) {
30765543Scg		/*
30865543Scg		 * BMSR of AX88772 indicates that it supports extended
30965543Scg		 * capability but the extended status register is
31065543Scg		 * revered for embedded ethernet PHY. So clear the
31165543Scg		 * extended capability bit of BMSR.
31265543Scg		 */
31365543Scg		val &= ~BMSR_EXTCAP;
31465543Scg	}
31565543Scg
31665543Scg	if (!locked)
31765543Scg		AXE_UNLOCK(sc);
31865543Scg	return (val);
31965543Scg}
32065543Scg
32165543Scgstatic int
32265543Scgaxe_miibus_writereg(device_t dev, int phy, int reg, int val)
32365543Scg{
32465543Scg	struct axe_softc *sc = device_get_softc(dev);
32565543Scg	int locked;
32665543Scg
32765543Scg	val = htole32(val);
32865543Scg
32965543Scg	if (sc->sc_phyno != phy)
33065543Scg		return (0);
33165543Scg
33265543Scg	locked = mtx_owned(&sc->sc_mtx);
33365543Scg	if (!locked)
33465543Scg		AXE_LOCK(sc);
33565543Scg
33665543Scg	axe_cmd(sc, AXE_CMD_MII_OPMODE_SW, 0, 0, NULL);
33765543Scg	axe_cmd(sc, AXE_CMD_MII_WRITE_REG, reg, phy, &val);
33865543Scg	axe_cmd(sc, AXE_CMD_MII_OPMODE_HW, 0, 0, NULL);
33965543Scg
34065543Scg	if (!locked)
34165543Scg		AXE_UNLOCK(sc);
34265543Scg	return (0);
34365543Scg}
34465543Scg
34565543Scgstatic void
34665543Scgaxe_miibus_statchg(device_t dev)
34765543Scg{
34865543Scg	struct axe_softc *sc = device_get_softc(dev);
34965543Scg	struct mii_data *mii = GET_MII(sc);
35065543Scg	struct ifnet *ifp;
35165543Scg	uint16_t val;
35265543Scg	int err, locked;
35365543Scg
35465543Scg	locked = mtx_owned(&sc->sc_mtx);
35565543Scg	if (!locked)
35665543Scg		AXE_LOCK(sc);
35765543Scg
35865543Scg	ifp = uether_getifp(&sc->sc_ue);
35965543Scg	if (mii == NULL || ifp == NULL ||
36065543Scg	    (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
36165543Scg		goto done;
36265543Scg
36365543Scg	sc->sc_flags &= ~AXE_FLAG_LINK;
36465543Scg	if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) ==
36565543Scg	    (IFM_ACTIVE | IFM_AVALID)) {
36665543Scg		switch (IFM_SUBTYPE(mii->mii_media_active)) {
36765543Scg		case IFM_10_T:
36865543Scg		case IFM_100_TX:
36965543Scg			sc->sc_flags |= AXE_FLAG_LINK;
37065543Scg			break;
37165543Scg		case IFM_1000_T:
37265543Scg			if ((sc->sc_flags & AXE_FLAG_178) == 0)
37365543Scg				break;
37465543Scg			sc->sc_flags |= AXE_FLAG_LINK;
37565543Scg			break;
37665543Scg		default:
37765543Scg			break;
37865543Scg		}
37965543Scg	}
38065543Scg
38165543Scg	/* Lost link, do nothing. */
38265543Scg	if ((sc->sc_flags & AXE_FLAG_LINK) == 0)
38365543Scg		goto done;
38465543Scg
38565543Scg	val = 0;
38665543Scg	if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0)
38765543Scg		val |= AXE_MEDIA_FULL_DUPLEX;
38865543Scg	if (AXE_IS_178_FAMILY(sc)) {
38965543Scg		val |= AXE_178_MEDIA_RX_EN | AXE_178_MEDIA_MAGIC;
39065543Scg		if ((sc->sc_flags & AXE_FLAG_178) != 0)
39165543Scg			val |= AXE_178_MEDIA_ENCK;
39265543Scg		switch (IFM_SUBTYPE(mii->mii_media_active)) {
39365543Scg		case IFM_1000_T:
39465543Scg			val |= AXE_178_MEDIA_GMII | AXE_178_MEDIA_ENCK;
39565543Scg			break;
39665543Scg		case IFM_100_TX:
39765543Scg			val |= AXE_178_MEDIA_100TX;
39865543Scg			break;
39965543Scg		case IFM_10_T:
40065543Scg			/* doesn't need to be handled */
40165543Scg			break;
40265543Scg		}
40365543Scg	}
40465543Scg	err = axe_cmd(sc, AXE_CMD_WRITE_MEDIA, 0, val, NULL);
40565543Scg	if (err)
40665543Scg		device_printf(dev, "media change failed, error %d\n", err);
40765543Scgdone:
40865543Scg	if (!locked)
40965543Scg		AXE_UNLOCK(sc);
41065543Scg}
41170134Scg
41265543Scg/*
41365543Scg * Set media options.
41465543Scg */
41565543Scgstatic int
41665543Scgaxe_ifmedia_upd(struct ifnet *ifp)
41765543Scg{
41865543Scg	struct axe_softc *sc = ifp->if_softc;
41965543Scg	struct mii_data *mii = GET_MII(sc);
42065543Scg	int error;
42165543Scg
42265543Scg	AXE_LOCK_ASSERT(sc, MA_OWNED);
42365543Scg
42465543Scg	if (mii->mii_instance) {
42565543Scg		struct mii_softc *miisc;
42665543Scg
42765543Scg		LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
42865543Scg			mii_phy_reset(miisc);
42965543Scg	}
43065543Scg	error = mii_mediachg(mii);
43165543Scg	return (error);
43265543Scg}
43365543Scg
43465543Scg/*
43565543Scg * Report current media status.
43665543Scg */
43765543Scgstatic void
43865543Scgaxe_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
43965543Scg{
44065543Scg	struct axe_softc *sc = ifp->if_softc;
44165543Scg	struct mii_data *mii = GET_MII(sc);
44265543Scg
44365543Scg	AXE_LOCK(sc);
44465543Scg	mii_pollstat(mii);
44565543Scg	AXE_UNLOCK(sc);
44665543Scg	ifmr->ifm_active = mii->mii_media_active;
44765543Scg	ifmr->ifm_status = mii->mii_media_status;
44865543Scg}
44965543Scg
45065543Scgstatic void
45165543Scgaxe_setmulti(struct usb_ether *ue)
45265543Scg{
45365543Scg	struct axe_softc *sc = uether_getsc(ue);
45465543Scg	struct ifnet *ifp = uether_getifp(ue);
45565543Scg	struct ifmultiaddr *ifma;
45665543Scg	uint32_t h = 0;
45765543Scg	uint16_t rxmode;
45865543Scg	uint8_t hashtbl[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
45965543Scg
46065543Scg	AXE_LOCK_ASSERT(sc, MA_OWNED);
46165543Scg
46265543Scg	axe_cmd(sc, AXE_CMD_RXCTL_READ, 0, 0, &rxmode);
46365543Scg	rxmode = le16toh(rxmode);
46465543Scg
46565543Scg	if (ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC)) {
46665543Scg		rxmode |= AXE_RXCMD_ALLMULTI;
46765543Scg		axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, rxmode, NULL);
46865543Scg		return;
46970619Sjhb	}
47065543Scg	rxmode &= ~AXE_RXCMD_ALLMULTI;
47170619Sjhb
47265543Scg	if_maddr_rlock(ifp);
47365543Scg	TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link)
47465543Scg	{
47565543Scg		if (ifma->ifma_addr->sa_family != AF_LINK)
47665543Scg			continue;
47765543Scg		h = ether_crc32_be(LLADDR((struct sockaddr_dl *)
47865543Scg		    ifma->ifma_addr), ETHER_ADDR_LEN) >> 26;
47965543Scg		hashtbl[h / 8] |= 1 << (h % 8);
48065543Scg	}
48165543Scg	if_maddr_runlock(ifp);
48265543Scg
48365543Scg	axe_cmd(sc, AXE_CMD_WRITE_MCAST, 0, 0, (void *)&hashtbl);
48465543Scg	axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, rxmode, NULL);
48565543Scg}
48665543Scg
48765543Scgstatic int
48865543Scgaxe_get_phyno(struct axe_softc *sc, int sel)
48965543Scg{
49065543Scg	int phyno;
49165543Scg
49265543Scg	switch (AXE_PHY_TYPE(sc->sc_phyaddrs[sel])) {
49365543Scg	case PHY_TYPE_100_HOME:
49465543Scg	case PHY_TYPE_GIG:
49565543Scg		phyno = AXE_PHY_NO(sc->sc_phyaddrs[sel]);
49665543Scg		break;
49765543Scg	case PHY_TYPE_SPECIAL:
49865543Scg		/* FALLTHROUGH */
49965543Scg	case PHY_TYPE_RSVD:
50065543Scg		/* FALLTHROUGH */
50165543Scg	case PHY_TYPE_NON_SUP:
50265543Scg		/* FALLTHROUGH */
50365543Scg	default:
50465543Scg		phyno = -1;
50565543Scg		break;
50665543Scg	}
50765543Scg
50865543Scg	return (phyno);
50965543Scg}
51065543Scg
51165543Scg#define	AXE_GPIO_WRITE(x, y)	do {				\
51265543Scg	axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, (x), NULL);		\
51365543Scg	uether_pause(ue, (y));					\
51465543Scg} while (0)
51565543Scg
51665543Scgstatic void
51765543Scgaxe_ax88178_init(struct axe_softc *sc)
51865543Scg{
51965543Scg	struct usb_ether *ue;
52065543Scg	int gpio0, phymode;
52165543Scg	uint16_t eeprom, val;
52265543Scg
52365543Scg	ue = &sc->sc_ue;
52484658Scg	axe_cmd(sc, AXE_CMD_SROM_WR_ENABLE, 0, 0, NULL);
52570291Scg	/* XXX magic */
52665543Scg	axe_cmd(sc, AXE_CMD_SROM_READ, 0, 0x0017, &eeprom);
52770291Scg	eeprom = le16toh(eeprom);
52865543Scg	axe_cmd(sc, AXE_CMD_SROM_WR_DISABLE, 0, 0, NULL);
52965543Scg
53065543Scg	/* if EEPROM is invalid we have to use to GPIO0 */
53165543Scg	if (eeprom == 0xffff) {
53265543Scg		phymode = AXE_PHY_MODE_MARVELL;
53365543Scg		gpio0 = 1;
53465543Scg	} else {
53565543Scg		phymode = eeprom & 0x7f;
53665543Scg		gpio0 = (eeprom & 0x80) ? 0 : 1;
53765543Scg	}
53865543Scg
53965543Scg	if (bootverbose)
54065543Scg		device_printf(sc->sc_ue.ue_dev,
54165543Scg		    "EEPROM data : 0x%04x, phymode : 0x%02x\n", eeprom,
54265543Scg		    phymode);
54365543Scg	/* Program GPIOs depending on PHY hardware. */
54465543Scg	switch (phymode) {
54565543Scg	case AXE_PHY_MODE_MARVELL:
54665543Scg		if (gpio0 == 1) {
54765543Scg			AXE_GPIO_WRITE(AXE_GPIO_RELOAD_EEPROM | AXE_GPIO0_EN,
54865543Scg			    hz / 32);
54965543Scg			AXE_GPIO_WRITE(AXE_GPIO0_EN | AXE_GPIO2 | AXE_GPIO2_EN,
55065543Scg			    hz / 32);
55165543Scg			AXE_GPIO_WRITE(AXE_GPIO0_EN | AXE_GPIO2_EN, hz / 4);
55265543Scg			AXE_GPIO_WRITE(AXE_GPIO0_EN | AXE_GPIO2 | AXE_GPIO2_EN,
55365543Scg			    hz / 32);
55465543Scg		} else
55565543Scg			AXE_GPIO_WRITE(AXE_GPIO_RELOAD_EEPROM | AXE_GPIO1 |
55665543Scg			    AXE_GPIO1_EN, hz / 32);
55765543Scg		break;
55865543Scg	case AXE_PHY_MODE_CICADA:
55965543Scg	case AXE_PHY_MODE_CICADA_V2:
56065543Scg	case AXE_PHY_MODE_CICADA_V2_ASIX:
56165543Scg		if (gpio0 == 1)
56265543Scg			AXE_GPIO_WRITE(AXE_GPIO_RELOAD_EEPROM | AXE_GPIO0 |
56365543Scg			    AXE_GPIO0_EN, hz / 32);
56465543Scg		else
56565543Scg			AXE_GPIO_WRITE(AXE_GPIO_RELOAD_EEPROM | AXE_GPIO1 |
56665543Scg			    AXE_GPIO1_EN, hz / 32);
56765543Scg		break;
56865543Scg	case AXE_PHY_MODE_AGERE:
56965543Scg		AXE_GPIO_WRITE(AXE_GPIO_RELOAD_EEPROM | AXE_GPIO1 |
57065543Scg		    AXE_GPIO1_EN, hz / 32);
57165543Scg		AXE_GPIO_WRITE(AXE_GPIO1 | AXE_GPIO1_EN | AXE_GPIO2 |
57265543Scg		    AXE_GPIO2_EN, hz / 32);
57365543Scg		AXE_GPIO_WRITE(AXE_GPIO1 | AXE_GPIO1_EN | AXE_GPIO2_EN, hz / 4);
57465543Scg		AXE_GPIO_WRITE(AXE_GPIO1 | AXE_GPIO1_EN | AXE_GPIO2 |
57565543Scg		    AXE_GPIO2_EN, hz / 32);
57665543Scg		break;
57765543Scg	case AXE_PHY_MODE_REALTEK_8211CL:
57865543Scg	case AXE_PHY_MODE_REALTEK_8211BN:
57965543Scg	case AXE_PHY_MODE_REALTEK_8251CL:
58065543Scg		val = gpio0 == 1 ? AXE_GPIO0 | AXE_GPIO0_EN :
58165543Scg		    AXE_GPIO1 | AXE_GPIO1_EN;
58265543Scg		AXE_GPIO_WRITE(val, hz / 32);
58365543Scg		AXE_GPIO_WRITE(val | AXE_GPIO2 | AXE_GPIO2_EN, hz / 32);
58465543Scg		AXE_GPIO_WRITE(val | AXE_GPIO2_EN, hz / 4);
58565543Scg		AXE_GPIO_WRITE(val | AXE_GPIO2 | AXE_GPIO2_EN, hz / 32);
58665543Scg		if (phymode == AXE_PHY_MODE_REALTEK_8211CL) {
58765543Scg			axe_miibus_writereg(ue->ue_dev, sc->sc_phyno,
58865543Scg			    0x1F, 0x0005);
58965543Scg			axe_miibus_writereg(ue->ue_dev, sc->sc_phyno,
59065543Scg			    0x0C, 0x0000);
59165543Scg			val = axe_miibus_readreg(ue->ue_dev, sc->sc_phyno,
59265543Scg			    0x0001);
59365543Scg			axe_miibus_writereg(ue->ue_dev, sc->sc_phyno,
59465543Scg			    0x01, val | 0x0080);
59565543Scg			axe_miibus_writereg(ue->ue_dev, sc->sc_phyno,
59665543Scg			    0x1F, 0x0000);
59784658Scg		}
59865543Scg		break;
59965543Scg	default:
60065543Scg		/* Unknown PHY model or no need to program GPIOs. */
60165543Scg		break;
60265543Scg	}
60365543Scg
60465543Scg	/* soft reset */
60565543Scg	axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_CLEAR, NULL);
60665543Scg	uether_pause(ue, hz / 4);
60765543Scg
60865543Scg	axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0,
60965543Scg	    AXE_SW_RESET_PRL | AXE_178_RESET_MAGIC, NULL);
61065543Scg	uether_pause(ue, hz / 4);
61165543Scg	/* Enable MII/GMII/RGMII interface to work with external PHY. */
61265543Scg	axe_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0, 0, NULL);
61365543Scg	uether_pause(ue, hz / 4);
61465543Scg
61565543Scg	axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, 0, NULL);
61665543Scg}
61765543Scg
61865543Scgstatic void
61965543Scgaxe_ax88772_init(struct axe_softc *sc)
62070291Scg{
62165543Scg	axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x00b0, NULL);
62265543Scg	uether_pause(&sc->sc_ue, hz / 16);
62365543Scg
62465543Scg	if (sc->sc_phyno == AXE_772_PHY_NO_EPHY) {
62565543Scg		/* ask for the embedded PHY */
62665543Scg		axe_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0, 0x01, NULL);
62765543Scg		uether_pause(&sc->sc_ue, hz / 64);
62865543Scg
62965543Scg		/* power down and reset state, pin reset state */
63065543Scg		axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0,
63165543Scg		    AXE_SW_RESET_CLEAR, NULL);
63265543Scg		uether_pause(&sc->sc_ue, hz / 16);
63365543Scg
63465543Scg		/* power down/reset state, pin operating state */
63565543Scg		axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0,
63665543Scg		    AXE_SW_RESET_IPPD | AXE_SW_RESET_PRL, NULL);
63765543Scg		uether_pause(&sc->sc_ue, hz / 4);
63865543Scg
63965543Scg		/* power up, reset */
64065543Scg		axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_PRL, NULL);
64165543Scg
64265543Scg		/* power up, operating */
64374763Scg		axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0,
64465543Scg		    AXE_SW_RESET_IPRL | AXE_SW_RESET_PRL, NULL);
64565543Scg	} else {
64665543Scg		/* ask for external PHY */
64765543Scg		axe_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0, 0x00, NULL);
64870291Scg		uether_pause(&sc->sc_ue, hz / 64);
64965543Scg
65065543Scg		/* power down internal PHY */
65165543Scg		axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0,
65265543Scg		    AXE_SW_RESET_IPPD | AXE_SW_RESET_PRL, NULL);
65365543Scg	}
65465543Scg
65565543Scg	uether_pause(&sc->sc_ue, hz / 4);
65665543Scg	axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, 0, NULL);
65765543Scg}
65884658Scg
65970291Scgstatic void
66065543Scgaxe_ax88772a_init(struct axe_softc *sc)
66184658Scg{
66265543Scg	struct usb_ether *ue;
66365543Scg	uint16_t eeprom;
66465543Scg
66565543Scg	ue = &sc->sc_ue;
66665543Scg	axe_cmd(sc, AXE_CMD_SROM_READ, 0, 0x0017, &eeprom);
66774763Scg	eeprom = le16toh(eeprom);
66865543Scg	/* Reload EEPROM. */
66965543Scg	AXE_GPIO_WRITE(AXE_GPIO_RELOAD_EEPROM, hz / 32);
67065543Scg	if (sc->sc_phyno == AXE_772_PHY_NO_EPHY) {
67165543Scg		/* Manually select internal(embedded) PHY - MAC mode. */
67265543Scg		axe_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0, AXE_SW_PHY_SELECT_SS_ENB |
67365543Scg		    AXE_SW_PHY_SELECT_EMBEDDED | AXE_SW_PHY_SELECT_SS_MII,
67465543Scg		    NULL);
67565543Scg		uether_pause(&sc->sc_ue, hz / 32);
67665543Scg	} else {
67765543Scg		/*
67865543Scg		 * Manually select external PHY - MAC mode.
67965543Scg		 * Reverse MII/RMII is for AX88772A PHY mode.
68065543Scg		 */
68165543Scg		axe_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0, AXE_SW_PHY_SELECT_SS_ENB |
68265543Scg		    AXE_SW_PHY_SELECT_EXT | AXE_SW_PHY_SELECT_SS_MII, NULL);
68365543Scg		uether_pause(&sc->sc_ue, hz / 32);
68470134Scg	}
68565543Scg	/* Take PHY out of power down. */
68665543Scg	axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_IPPD |
68765543Scg	    AXE_SW_RESET_IPRL, NULL);
68865543Scg	uether_pause(&sc->sc_ue, hz / 4);
68965543Scg	axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_IPRL, NULL);
69070291Scg	uether_pause(&sc->sc_ue, hz);
69165543Scg	axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_CLEAR, NULL);
69265543Scg	uether_pause(&sc->sc_ue, hz / 32);
69365543Scg	axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_IPRL, NULL);
69465543Scg	uether_pause(&sc->sc_ue, hz / 32);
69565543Scg	axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, 0, NULL);
69665543Scg}
69770134Scg
69865543Scg#undef	AXE_GPIO_WRITE
69965543Scg
70065543Scgstatic void
70165543Scgaxe_reset(struct axe_softc *sc)
70265543Scg{
70365543Scg	struct usb_config_descriptor *cd;
70465543Scg	usb_error_t err;
70565543Scg
70665543Scg	cd = usbd_get_config_descriptor(sc->sc_ue.ue_udev);
70765543Scg
70865543Scg	err = usbd_req_set_config(sc->sc_ue.ue_udev, &sc->sc_mtx,
70965543Scg	    cd->bConfigurationValue);
71065543Scg	if (err)
71165543Scg		DPRINTF("reset failed (ignored)\n");
71265543Scg
71365543Scg	/* Wait a little while for the chip to get its brains in order. */
71465543Scg	uether_pause(&sc->sc_ue, hz / 100);
71565543Scg
71665543Scg	/* Reinitialize controller to achieve full reset. */
71765543Scg	if (sc->sc_flags & AXE_FLAG_178)
71865543Scg		axe_ax88178_init(sc);
71965543Scg	else if (sc->sc_flags & AXE_FLAG_772)
72089887Sscottl		axe_ax88772_init(sc);
72165543Scg	else if (sc->sc_flags & AXE_FLAG_772A)
72265543Scg		axe_ax88772a_init(sc);
72365543Scg}
72470134Scg
72565543Scgstatic void
72670291Scgaxe_attach_post(struct usb_ether *ue)
72770291Scg{
72870291Scg	struct axe_softc *sc = uether_getsc(ue);
72970291Scg
73065543Scg	/*
73165543Scg	 * Load PHY indexes first. Needed by axe_xxx_init().
73265543Scg	 */
73370134Scg	axe_cmd(sc, AXE_CMD_READ_PHYID, 0, 0, sc->sc_phyaddrs);
73465543Scg	if (bootverbose)
73565543Scg		device_printf(sc->sc_ue.ue_dev, "PHYADDR 0x%02x:0x%02x\n",
73665543Scg		    sc->sc_phyaddrs[0], sc->sc_phyaddrs[1]);
73765543Scg	sc->sc_phyno = axe_get_phyno(sc, AXE_PHY_SEL_PRI);
73865543Scg	if (sc->sc_phyno == -1)
73970134Scg		sc->sc_phyno = axe_get_phyno(sc, AXE_PHY_SEL_SEC);
74065543Scg	if (sc->sc_phyno == -1) {
74165543Scg		device_printf(sc->sc_ue.ue_dev,
74265543Scg		    "no valid PHY address found, assuming PHY address 0\n");
74365543Scg		sc->sc_phyno = 0;
74465543Scg	}
74565543Scg
74665543Scg	if (sc->sc_flags & AXE_FLAG_178) {
74765543Scg		axe_ax88178_init(sc);
74865543Scg		sc->sc_tx_bufsz = 16 * 1024;
74965543Scg	} else if (sc->sc_flags & AXE_FLAG_772) {
75065543Scg		axe_ax88772_init(sc);
75165543Scg		sc->sc_tx_bufsz = 8 * 1024;
75265543Scg	} else if (sc->sc_flags & AXE_FLAG_772A) {
75365543Scg		axe_ax88772a_init(sc);
75465543Scg		sc->sc_tx_bufsz = 8 * 1024;
75565543Scg	}
75665543Scg
75765543Scg	/*
75865543Scg	 * Get station address.
75965543Scg	 */
76065543Scg	if (AXE_IS_178_FAMILY(sc))
76165543Scg		axe_cmd(sc, AXE_178_CMD_READ_NODEID, 0, 0, ue->ue_eaddr);
76265543Scg	else
76365543Scg		axe_cmd(sc, AXE_172_CMD_READ_NODEID, 0, 0, ue->ue_eaddr);
76465543Scg
76565543Scg	/*
76665543Scg	 * Fetch IPG values.
76765543Scg	 */
76865543Scg	if (sc->sc_flags & AXE_FLAG_772A) {
76965543Scg		/* Set IPG values. */
77065543Scg		sc->sc_ipgs[0] = 0x15;
77165543Scg		sc->sc_ipgs[1] = 0x16;
77265543Scg		sc->sc_ipgs[2] = 0x1A;
77365543Scg	} else
77465543Scg		axe_cmd(sc, AXE_CMD_READ_IPG012, 0, 0, sc->sc_ipgs);
77565543Scg}
77665543Scg
77770134Scg/*
77865543Scg * Probe for a AX88172 chip.
77965543Scg */
78065543Scgstatic int
78165543Scgaxe_probe(device_t dev)
78265543Scg{
78365543Scg	struct usb_attach_arg *uaa = device_get_ivars(dev);
78465543Scg
78565543Scg	if (uaa->usb_mode != USB_MODE_HOST)
78665543Scg		return (ENXIO);
78765543Scg	if (uaa->info.bConfigIndex != AXE_CONFIG_IDX)
78865543Scg		return (ENXIO);
78965543Scg	if (uaa->info.bIfaceIndex != AXE_IFACE_IDX)
79065543Scg		return (ENXIO);
79174763Scg
79270134Scg	return (usbd_lookup_id_by_uaa(axe_devs, sizeof(axe_devs), uaa));
79365543Scg}
79465543Scg
79565543Scg/*
79665543Scg * Attach the interface. Allocate softc structures, do ifmedia
79765543Scg * setup and ethernet/BPF attach.
79865543Scg */
79965543Scgstatic int
80065543Scgaxe_attach(device_t dev)
80165543Scg{
80265543Scg	struct usb_attach_arg *uaa = device_get_ivars(dev);
80374763Scg	struct axe_softc *sc = device_get_softc(dev);
80465543Scg	struct usb_ether *ue = &sc->sc_ue;
80565543Scg	uint8_t iface_index;
80665543Scg	int error;
80765543Scg
80865543Scg	sc->sc_flags = USB_GET_DRIVER_INFO(uaa);
80965543Scg
81065543Scg	device_set_usb_desc(dev);
81165543Scg
81274763Scg	mtx_init(&sc->sc_mtx, device_get_nameunit(dev), NULL, MTX_DEF);
81365543Scg
81465543Scg	iface_index = AXE_IFACE_IDX;
81565543Scg	error = usbd_transfer_setup(uaa->device, &iface_index, sc->sc_xfer,
81665543Scg	    axe_config, AXE_N_TRANSFER, sc, &sc->sc_mtx);
81765543Scg	if (error) {
81870134Scg		device_printf(dev, "allocating USB transfers failed\n");
81970134Scg		goto detach;
82070134Scg	}
82170134Scg
82270134Scg	ue->ue_sc = sc;
82370134Scg	ue->ue_dev = dev;
82470134Scg	ue->ue_udev = uaa->device;
82570134Scg	ue->ue_mtx = &sc->sc_mtx;
82670134Scg	ue->ue_methods = &axe_ue_methods;
82770134Scg
82870134Scg	error = uether_ifattach(ue);
82970134Scg	if (error) {
83065543Scg		device_printf(dev, "could not attach interface\n");
83165543Scg		goto detach;
83265543Scg	}
83365543Scg	return (0);			/* success */
83465543Scg
83565543Scgdetach:
83665543Scg	axe_detach(dev);
83765543Scg	return (ENXIO);			/* failure */
83865543Scg}
83965543Scg
84065543Scgstatic int
84165543Scgaxe_detach(device_t dev)
84265543Scg{
84365543Scg	struct axe_softc *sc = device_get_softc(dev);
84465543Scg	struct usb_ether *ue = &sc->sc_ue;
84565543Scg
84665543Scg	usbd_transfer_unsetup(sc->sc_xfer, AXE_N_TRANSFER);
84765543Scg	uether_ifdetach(ue);
84870619Sjhb	mtx_destroy(&sc->sc_mtx);
84970619Sjhb
85065543Scg	return (0);
85170619Sjhb}
85270619Sjhb
85370619Sjhb#if (AXE_BULK_BUF_SIZE >= 0x10000)
85470619Sjhb#error "Please update axe_bulk_read_callback()!"
85570619Sjhb#endif
85670945Sjhb
85770619Sjhbstatic void
85870619Sjhbaxe_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error)
85970945Sjhb{
86070619Sjhb	struct axe_softc *sc = usbd_xfer_softc(xfer);
86170619Sjhb	struct usb_ether *ue = &sc->sc_ue;
86270945Sjhb	struct ifnet *ifp = uether_getifp(ue);
86370619Sjhb	struct axe_sframe_hdr hdr;
86470619Sjhb	struct usb_page_cache *pc;
86570619Sjhb	int err, pos, len;
86670619Sjhb	int actlen;
86770619Sjhb
86870619Sjhb	usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
86965543Scg
87070619Sjhb	switch (USB_GET_STATE(xfer)) {
87170619Sjhb	case USB_ST_TRANSFERRED:
87265543Scg		pos = 0;
87365543Scg		len = 0;
87465543Scg		err = 0;
87565543Scg
87665543Scg		pc = usbd_xfer_get_frame(xfer, 0);
87765543Scg		if (AXE_IS_178_FAMILY(sc)) {
87865543Scg			while (pos < actlen) {
87965543Scg				if ((pos + sizeof(hdr)) > actlen) {
88065543Scg					/* too little data */
88165543Scg					err = EINVAL;
88265543Scg					break;
88365543Scg				}
88465543Scg				usbd_copy_out(pc, pos, &hdr, sizeof(hdr));
88565543Scg
88665543Scg				if ((hdr.len ^ hdr.ilen) != 0xFFFF) {
88765543Scg					/* we lost sync */
88865543Scg					err = EINVAL;
88965543Scg					break;
89065543Scg				}
89165543Scg				pos += sizeof(hdr);
89265543Scg
89365543Scg				len = le16toh(hdr.len);
89465543Scg				if ((pos + len) > actlen) {
89565543Scg					/* invalid length */
89665543Scg					err = EINVAL;
89765543Scg					break;
89865543Scg				}
89965543Scg				uether_rxbuf(ue, pc, pos, len);
90065543Scg
90165543Scg				pos += len + (len % 2);
90265543Scg			}
90365543Scg		} else
90465543Scg			uether_rxbuf(ue, pc, 0, actlen);
90565543Scg
90665543Scg		if (err != 0)
90765543Scg			ifp->if_ierrors++;
90865543Scg
90965543Scg		/* FALLTHROUGH */
91065543Scg	case USB_ST_SETUP:
91165543Scgtr_setup:
91265543Scg		usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer));
91365543Scg		usbd_transfer_submit(xfer);
91465543Scg		uether_rxflush(ue);
91565543Scg		return;
91665543Scg
91765543Scg	default:			/* Error */
91865543Scg		DPRINTF("bulk read error, %s\n", usbd_errstr(error));
91965543Scg
92065543Scg		if (error != USB_ERR_CANCELLED) {
92165543Scg			/* try to clear stall first */
92265543Scg			usbd_xfer_set_stall(xfer);
92365543Scg			goto tr_setup;
92465543Scg		}
92565543Scg		return;
92665543Scg
92765543Scg	}
92865543Scg}
92965543Scg
93065543Scg#if ((AXE_BULK_BUF_SIZE >= 0x10000) || (AXE_BULK_BUF_SIZE < (MCLBYTES+4)))
93165543Scg#error "Please update axe_bulk_write_callback()!"
93265543Scg#endif
93365543Scg
93465543Scgstatic void
93565543Scgaxe_bulk_write_callback(struct usb_xfer *xfer, usb_error_t error)
93665543Scg{
93765543Scg	struct axe_softc *sc = usbd_xfer_softc(xfer);
93865543Scg	struct axe_sframe_hdr hdr;
93965543Scg	struct ifnet *ifp = uether_getifp(&sc->sc_ue);
94065543Scg	struct usb_page_cache *pc;
94165543Scg	struct mbuf *m;
94265543Scg	int pos;
94365543Scg
94465543Scg	switch (USB_GET_STATE(xfer)) {
94565543Scg	case USB_ST_TRANSFERRED:
94665543Scg		DPRINTFN(11, "transfer complete\n");
94765543Scg		ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
94865543Scg		/* FALLTHROUGH */
94965543Scg	case USB_ST_SETUP:
95065543Scgtr_setup:
95165543Scg		if ((sc->sc_flags & AXE_FLAG_LINK) == 0 ||
95265543Scg		    (ifp->if_drv_flags & IFF_DRV_OACTIVE) != 0) {
95365543Scg			/*
95465543Scg			 * Don't send anything if there is no link or
95565543Scg			 * controller is busy.
95665543Scg			 */
95765543Scg			return;
95865543Scg		}
95965543Scg		pos = 0;
96065543Scg		pc = usbd_xfer_get_frame(xfer, 0);
96178564Sgreid
96265543Scg		while (1) {
96365543Scg
96465543Scg			IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
96565543Scg
96665543Scg			if (m == NULL) {
96784658Scg				if (pos > 0)
96884658Scg					break;	/* send out data */
96965543Scg				return;
97065543Scg			}
97165543Scg			if (m->m_pkthdr.len > MCLBYTES) {
97265543Scg				m->m_pkthdr.len = MCLBYTES;
97365543Scg			}
97484658Scg			if (AXE_IS_178_FAMILY(sc)) {
97565543Scg
97665543Scg				hdr.len = htole16(m->m_pkthdr.len);
97765543Scg				hdr.ilen = ~hdr.len;
97865543Scg
97965543Scg				usbd_copy_in(pc, pos, &hdr, sizeof(hdr));
98084658Scg
98165543Scg				pos += sizeof(hdr);
98265543Scg
98365543Scg				/*
98465543Scg				 * NOTE: Some drivers force a short packet
98565543Scg				 * by appending a dummy header with zero
98665543Scg				 * length at then end of the USB transfer.
98765543Scg				 * This driver uses the
98865543Scg				 * USB_FORCE_SHORT_XFER flag instead.
98965543Scg				 */
99065543Scg			}
99165543Scg			usbd_m_copy_in(pc, pos, m, 0, m->m_pkthdr.len);
99265543Scg			pos += m->m_pkthdr.len;
99365543Scg
99465543Scg			/*
99565543Scg			 * XXX
99665543Scg			 * Update TX packet counter here. This is not
99765543Scg			 * correct way but it seems that there is no way
99865543Scg			 * to know how many packets are sent at the end
99965543Scg			 * of transfer because controller combines
100065543Scg			 * multiple writes into single one if there is
100165543Scg			 * room in TX buffer of controller.
100265543Scg			 */
100365543Scg			ifp->if_opackets++;
100465543Scg
100565543Scg			/*
100665543Scg			 * if there's a BPF listener, bounce a copy
100765543Scg			 * of this frame to him:
100865543Scg			 */
100965543Scg			BPF_MTAP(ifp, m);
101065543Scg
101165543Scg			m_freem(m);
101265543Scg
101370134Scg			if (AXE_IS_178_FAMILY(sc)) {
101465543Scg				if (pos > (AXE_BULK_BUF_SIZE - MCLBYTES - sizeof(hdr))) {
101565543Scg					/* send out frame(s) */
101665543Scg					break;
101770134Scg				}
101865543Scg			} else {
101965543Scg				/* send out frame */
102070134Scg				break;
102165543Scg			}
102265543Scg		}
102365543Scg
102465543Scg		usbd_xfer_set_frame_len(xfer, 0, pos);
102565543Scg		usbd_transfer_submit(xfer);
102674763Scg		ifp->if_drv_flags |= IFF_DRV_OACTIVE;
102765543Scg		return;
102865543Scg
102965543Scg	default:			/* Error */
103065543Scg		DPRINTFN(11, "transfer error, %s\n",
103165543Scg		    usbd_errstr(error));
103265543Scg
103365543Scg		ifp->if_oerrors++;
103465543Scg		ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
103565543Scg
103665543Scg		if (error != USB_ERR_CANCELLED) {
103765543Scg			/* try to clear stall first */
103865543Scg			usbd_xfer_set_stall(xfer);
103965543Scg			goto tr_setup;
104070945Sjhb		}
104165543Scg		return;
104270134Scg
104365543Scg	}
104470134Scg}
104565543Scg
104665543Scgstatic void
104765543Scgaxe_tick(struct usb_ether *ue)
104865543Scg{
104965543Scg	struct axe_softc *sc = uether_getsc(ue);
105065543Scg	struct mii_data *mii = GET_MII(sc);
105165644Scg
105265644Scg	AXE_LOCK_ASSERT(sc, MA_OWNED);
105365543Scg
105465543Scg	mii_tick(mii);
105565543Scg	if ((sc->sc_flags & AXE_FLAG_LINK) == 0) {
105665543Scg		axe_miibus_statchg(ue->ue_dev);
105765543Scg		if ((sc->sc_flags & AXE_FLAG_LINK) != 0)
105865543Scg			axe_start(ue);
105965543Scg	}
106065543Scg}
106165543Scg
106265543Scgstatic void
106365543Scgaxe_start(struct usb_ether *ue)
106465543Scg{
106565543Scg	struct axe_softc *sc = uether_getsc(ue);
106665543Scg
106765543Scg	/*
106865543Scg	 * start the USB transfers, if not already started:
106965543Scg	 */
107065543Scg	usbd_transfer_start(sc->sc_xfer[AXE_BULK_DT_RD]);
107165543Scg	usbd_transfer_start(sc->sc_xfer[AXE_BULK_DT_WR]);
107265543Scg}
107365543Scg
107465543Scgstatic void
107565543Scgaxe_init(struct usb_ether *ue)
107665543Scg{
107765543Scg	struct axe_softc *sc = uether_getsc(ue);
107865543Scg	struct ifnet *ifp = uether_getifp(ue);
107965543Scg	uint16_t rxmode;
108065543Scg
108165543Scg	AXE_LOCK_ASSERT(sc, MA_OWNED);
108265543Scg
108365543Scg	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
108465543Scg		return;
108570134Scg
108665543Scg	/* Cancel pending I/O */
108765543Scg	axe_stop(ue);
108865543Scg
108965543Scg	axe_reset(sc);
109065543Scg
109165543Scg	/* Set MAC address. */
109265543Scg	if (AXE_IS_178_FAMILY(sc))
109365543Scg		axe_cmd(sc, AXE_178_CMD_WRITE_NODEID, 0, 0, IF_LLADDR(ifp));
109465543Scg	else
109565543Scg		axe_cmd(sc, AXE_172_CMD_WRITE_NODEID, 0, 0, IF_LLADDR(ifp));
109665543Scg
109765543Scg	/* Set transmitter IPG values */
109865543Scg	if (AXE_IS_178_FAMILY(sc))
109965543Scg		axe_cmd(sc, AXE_178_CMD_WRITE_IPG012, sc->sc_ipgs[2],
110065543Scg		    (sc->sc_ipgs[1] << 8) | (sc->sc_ipgs[0]), NULL);
110165543Scg	else {
110265543Scg		axe_cmd(sc, AXE_172_CMD_WRITE_IPG0, 0, sc->sc_ipgs[0], NULL);
110365543Scg		axe_cmd(sc, AXE_172_CMD_WRITE_IPG1, 0, sc->sc_ipgs[1], NULL);
110465543Scg		axe_cmd(sc, AXE_172_CMD_WRITE_IPG2, 0, sc->sc_ipgs[2], NULL);
110565543Scg	}
110665543Scg
110765543Scg	/* Enable receiver, set RX mode */
110865543Scg	rxmode = (AXE_RXCMD_MULTICAST | AXE_RXCMD_ENABLE);
110965543Scg	if (AXE_IS_178_FAMILY(sc)) {
111065543Scg#if 0
111165543Scg		rxmode |= AXE_178_RXCMD_MFB_2048;	/* chip default */
111265543Scg#else
111365543Scg		/*
111465543Scg		 * Default Rx buffer size is too small to get
111565543Scg		 * maximum performance.
111670134Scg		 */
111765543Scg		rxmode |= AXE_178_RXCMD_MFB_16384;
111865543Scg#endif
111965543Scg	} else {
112065543Scg		rxmode |= AXE_172_RXCMD_UNICAST;
112165543Scg	}
112265543Scg
112365543Scg	/* If we want promiscuous mode, set the allframes bit. */
112465543Scg	if (ifp->if_flags & IFF_PROMISC)
112565543Scg		rxmode |= AXE_RXCMD_PROMISC;
112665543Scg
112765543Scg	if (ifp->if_flags & IFF_BROADCAST)
112865543Scg		rxmode |= AXE_RXCMD_BROADCAST;
112965543Scg
113065543Scg	axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, rxmode, NULL);
113165543Scg
113265543Scg	/* Load the multicast filter. */
113365543Scg	axe_setmulti(ue);
113465543Scg
113565543Scg	usbd_xfer_set_stall(sc->sc_xfer[AXE_BULK_DT_WR]);
113665543Scg
113765543Scg	ifp->if_drv_flags |= IFF_DRV_RUNNING;
113865543Scg	/* Switch to selected media. */
113965543Scg	axe_ifmedia_upd(ifp);
114065543Scg	axe_start(ue);
114165543Scg}
114265543Scg
114365543Scgstatic void
114465543Scgaxe_setpromisc(struct usb_ether *ue)
114565543Scg{
114665543Scg	struct axe_softc *sc = uether_getsc(ue);
114765543Scg	struct ifnet *ifp = uether_getifp(ue);
114865543Scg	uint16_t rxmode;
114965543Scg
115065543Scg	axe_cmd(sc, AXE_CMD_RXCTL_READ, 0, 0, &rxmode);
115165543Scg
115265543Scg	rxmode = le16toh(rxmode);
115365543Scg
115465543Scg	if (ifp->if_flags & IFF_PROMISC) {
115565543Scg		rxmode |= AXE_RXCMD_PROMISC;
115665543Scg	} else {
115765543Scg		rxmode &= ~AXE_RXCMD_PROMISC;
115865543Scg	}
115965543Scg
116065543Scg	axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, rxmode, NULL);
116165543Scg
116265543Scg	axe_setmulti(ue);
116365543Scg}
116465543Scg
116565543Scgstatic void
116665543Scgaxe_stop(struct usb_ether *ue)
116765543Scg{
116865543Scg	struct axe_softc *sc = uether_getsc(ue);
116965543Scg	struct ifnet *ifp = uether_getifp(ue);
117065543Scg
117165543Scg	AXE_LOCK_ASSERT(sc, MA_OWNED);
117265543Scg
117365543Scg	ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
117465543Scg	sc->sc_flags &= ~AXE_FLAG_LINK;
117565543Scg
117665543Scg	/*
117765543Scg	 * stop all the transfers, if not already stopped:
117865543Scg	 */
117965543Scg	usbd_transfer_stop(sc->sc_xfer[AXE_BULK_DT_WR]);
118065543Scg	usbd_transfer_stop(sc->sc_xfer[AXE_BULK_DT_RD]);
118165543Scg}
118265543Scg