if_axe.c revision 189275
1139749Simp/*- 2119853Scg * Copyright (c) 1997, 1998, 1999, 2000-2003 3166426Sjoel * Bill Paul <wpaul@windriver.com>. All rights reserved. 429415Sjmg * 529415Sjmg * Redistribution and use in source and binary forms, with or without 629415Sjmg * modification, are permitted provided that the following conditions 729415Sjmg * are met: 850723Scg * 1. Redistributions of source code must retain the above copyright 950723Scg * notice, this list of conditions and the following disclaimer. 1029415Sjmg * 2. Redistributions in binary form must reproduce the above copyright 1129415Sjmg * notice, this list of conditions and the following disclaimer in the 1230869Sjmg * documentation and/or other materials provided with the distribution. 1330869Sjmg * 3. All advertising materials mentioning features or use of this software 1430869Sjmg * must display the following acknowledgement: 1530869Sjmg * This product includes software developed by Bill Paul. 1650723Scg * 4. Neither the name of the author nor the names of any co-contributors 1750723Scg * may be used to endorse or promote products derived from this software 1830869Sjmg * without specific prior written permission. 1950723Scg * 2050723Scg * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND 2150723Scg * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2250723Scg * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2350723Scg * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD 2450723Scg * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2550723Scg * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2650723Scg * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2750723Scg * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2850723Scg * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2950723Scg * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 3029415Sjmg * THE POSSIBILITY OF SUCH DAMAGE. 3129415Sjmg */ 3253465Scg 3329415Sjmg#include <sys/cdefs.h> 3453465Scg__FBSDID("$FreeBSD: head/sys/dev/usb/net/if_axe.c 189275 2009-03-02 05:37:05Z thompsa $"); 3553553Stanimura 3629415Sjmg/* 37110499Snyan * ASIX Electronics AX88172/AX88178/AX88778 USB 2.0 ethernet driver. 38110499Snyan * Used in the LinkSys USB200M and various other adapters. 3970134Scg * 4070134Scg * Manuals available from: 4182180Scg * http://www.asix.com.tw/datasheet/mac/Ax88172.PDF 4282180Scg * Note: you need the manual for the AX88170 chip (USB 1.x ethernet 4367803Scg * controller) to find the definitions for the RX control register. 4455706Scg * http://www.asix.com.tw/datasheet/mac/Ax88170.PDF 4555254Scg * 4667803Scg * Written by Bill Paul <wpaul@windriver.com> 4750723Scg * Senior Engineer 4850723Scg * Wind River Systems 4964881Scg */ 5050723Scg 5174763Scg/* 5229415Sjmg * The AX88172 provides USB ethernet supports at 10 and 100Mbps. 5367803Scg * It uses an external PHY (reference designs use a RealTek chip), 5464881Scg * and has a 64-bit multicast hash filter. There is some information 5550723Scg * missing from the manual which one needs to know in order to make 5664881Scg * the chip function: 5750723Scg * 5874763Scg * - You must set bit 7 in the RX control register, otherwise the 5929415Sjmg * chip won't receive any packets. 6064881Scg * - You must initialize all 3 IPG registers, or you won't be able 6164881Scg * to send any packets. 6264881Scg * 6364881Scg * Note that this device appears to only support loading the station 6464881Scg * address via autload from the EEPROM (i.e. there's no way to manaully 6564881Scg * set it). 6654462Scg * 6774763Scg * (Adam Weinberger wanted me to name this driver if_gir.c.) 6854462Scg */ 6950723Scg 7029415Sjmg/* 7150723Scg * Ax88178 and Ax88772 support backported from the OpenBSD driver. 7250723Scg * 2007/02/12, J.R. Oldroyd, fbsd@opal.com 7374763Scg * 7474763Scg * Manual here: 7567803Scg * http://www.asix.com.tw/FrootAttach/datasheet/AX88178_datasheet_Rev10.pdf 7667803Scg * http://www.asix.com.tw/FrootAttach/datasheet/AX88772_datasheet_Rev10.pdf 7750723Scg */ 7829415Sjmg 7950723Scg#include "usbdevs.h" 8050723Scg#include <dev/usb/usb.h> 8150723Scg#include <dev/usb/usb_mfunc.h> 8254462Scg#include <dev/usb/usb_error.h> 8354462Scg 8465644Scg#define USB_DEBUG_VAR axe_debug 8555706Scg 8629415Sjmg#include <dev/usb/usb_core.h> 8784111Scg#include <dev/usb/usb_lookup.h> 8850723Scg#include <dev/usb/usb_process.h> 8950723Scg#include <dev/usb/usb_debug.h> 9070291Scg#include <dev/usb/usb_request.h> 9150723Scg#include <dev/usb/usb_busdma.h> 9274763Scg#include <dev/usb/usb_util.h> 9350723Scg 9450723Scg#include <dev/usb/net/usb_ethernet.h> 9584111Scg#include <dev/usb/net/if_axereg.h> 9674763Scg 9774763Scg/* 9850723Scg * AXE_178_MAX_FRAME_BURST 9950723Scg * max frame burst size for Ax88178 and Ax88772 10050723Scg * 0 2048 bytes 10167803Scg * 1 4096 bytes 10250723Scg * 2 8192 bytes 10350723Scg * 3 16384 bytes 10450723Scg * use the largest your system can handle without USB stalling. 10550723Scg * 10654462Scg * NB: 88772 parts appear to generate lots of input errors with 10729415Sjmg * a 2K rx buffer and 8K is only slightly faster than 4K on an 10850723Scg * EHCI port on a T42 so change at your own risk. 10984111Scg */ 11050723Scg#define AXE_178_MAX_FRAME_BURST 1 11129415Sjmg 11250723Scg#if USB_DEBUG 11329415Sjmgstatic int axe_debug = 0; 11450723Scg 11550723ScgSYSCTL_NODE(_hw_usb2, OID_AUTO, axe, CTLFLAG_RW, 0, "USB axe"); 11650723ScgSYSCTL_INT(_hw_usb2_axe, OID_AUTO, debug, CTLFLAG_RW, &axe_debug, 0, 11750723Scg "Debug level"); 11829415Sjmg#endif 11929415Sjmg 12084111Scg/* 12184111Scg * Various supported device vendors/products. 12284111Scg */ 12384111Scgstatic const struct usb2_device_id axe_devs[] = { 12484111Scg {USB_VPI(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_UF200, 0)}, 12584111Scg {USB_VPI(USB_VENDOR_ACERCM, USB_PRODUCT_ACERCM_EP1427X2, 0)}, 12684111Scg {USB_VPI(USB_VENDOR_APPLE, USB_PRODUCT_APPLE_ETHERNET, AXE_FLAG_772)}, 127129180Struckman {USB_VPI(USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88172, 0)}, 128129180Struckman {USB_VPI(USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88178, AXE_FLAG_178)}, 129129180Struckman {USB_VPI(USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88772, AXE_FLAG_772)}, 130129180Struckman {USB_VPI(USB_VENDOR_ATEN, USB_PRODUCT_ATEN_UC210T, 0)}, 131129180Struckman {USB_VPI(USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D5055, AXE_FLAG_178)}, 132129180Struckman {USB_VPI(USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USB2AR, 0)}, 13384111Scg {USB_VPI(USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_USB200MV2, AXE_FLAG_772)}, 13484111Scg {USB_VPI(USB_VENDOR_COREGA, USB_PRODUCT_COREGA_FETHER_USB2_TX, 0)}, 13584111Scg {USB_VPI(USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DUBE100, 0)}, 13684111Scg {USB_VPI(USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DUBE100B1, AXE_FLAG_772)}, 13784111Scg {USB_VPI(USB_VENDOR_GOODWAY, USB_PRODUCT_GOODWAY_GWUSB2E, 0)}, 13829415Sjmg {USB_VPI(USB_VENDOR_IODATA, USB_PRODUCT_IODATA_ETGUS2, AXE_FLAG_178)}, 13950723Scg {USB_VPI(USB_VENDOR_JVC, USB_PRODUCT_JVC_MP_PRX1, 0)}, 14029415Sjmg {USB_VPI(USB_VENDOR_LINKSYS2, USB_PRODUCT_LINKSYS2_USB200M, 0)}, 14167803Scg {USB_VPI(USB_VENDOR_LINKSYS4, USB_PRODUCT_LINKSYS4_USB1000, AXE_FLAG_178)}, 14250723Scg {USB_VPI(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUAU2KTX, 0)}, 14329415Sjmg {USB_VPI(USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_FA120, 0)}, 14450723Scg {USB_VPI(USB_VENDOR_OQO, USB_PRODUCT_OQO_ETHER01PLUS, AXE_FLAG_772)}, 14550723Scg {USB_VPI(USB_VENDOR_PLANEX3, USB_PRODUCT_PLANEX3_GU1000T, AXE_FLAG_178)}, 14650723Scg {USB_VPI(USB_VENDOR_SITECOM, USB_PRODUCT_SITECOM_LN029, 0)}, 147108064Ssemenu {USB_VPI(USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_LN028, AXE_FLAG_178)}, 14829415Sjmg {USB_VPI(USB_VENDOR_SYSTEMTALKS, USB_PRODUCT_SYSTEMTALKS_SGCX2UL, 0)}, 14929415Sjmg}; 15029415Sjmg 15150723Scgstatic device_probe_t axe_probe; 15229415Sjmgstatic device_attach_t axe_attach; 15350723Scgstatic device_detach_t axe_detach; 15450723Scgstatic device_shutdown_t axe_shutdown; 15529415Sjmg 15650723Scgstatic usb2_callback_t axe_intr_callback; 15750723Scgstatic usb2_callback_t axe_bulk_read_callback; 15850723Scgstatic usb2_callback_t axe_bulk_write_callback; 15950723Scg 16029415Sjmgstatic miibus_readreg_t axe_miibus_readreg; 16129415Sjmgstatic miibus_writereg_t axe_miibus_writereg; 16250723Scgstatic miibus_statchg_t axe_miibus_statchg; 16350723Scg 16429415Sjmgstatic usb2_ether_fn_t axe_attach_post; 16550723Scgstatic usb2_ether_fn_t axe_init; 16629415Sjmgstatic usb2_ether_fn_t axe_stop; 16750723Scgstatic usb2_ether_fn_t axe_start; 16870134Scgstatic usb2_ether_fn_t axe_tick; 16970134Scgstatic usb2_ether_fn_t axe_setmulti; 17070134Scgstatic usb2_ether_fn_t axe_setpromisc; 17170134Scg 17270134Scgstatic int axe_ifmedia_upd(struct ifnet *); 17350723Scgstatic void axe_ifmedia_sts(struct ifnet *, struct ifmediareq *); 17450723Scgstatic int axe_cmd(struct axe_softc *, int, int, int, void *); 17579116Sgreenstatic void axe_ax88178_init(struct axe_softc *); 17683366Sjulianstatic void axe_ax88772_init(struct axe_softc *); 17774797Scgstatic int axe_get_phyno(struct axe_softc *, int); 17879090Sgreen 17950723Scgstatic const struct usb2_config axe_config[AXE_N_TRANSFER] = { 18050723Scg 18129415Sjmg [AXE_BULK_DT_WR] = { 18250723Scg .type = UE_BULK, 18350723Scg .endpoint = UE_ADDR_ANY, 18450723Scg .direction = UE_DIR_OUT, 18550723Scg .mh.bufsize = AXE_BULK_BUF_SIZE, 18650723Scg .mh.flags = {.pipe_bof = 1,.force_short_xfer = 1,}, 18750723Scg .mh.callback = axe_bulk_write_callback, 18850723Scg .mh.timeout = 10000, /* 10 seconds */ 18950723Scg }, 19029415Sjmg 19167803Scg [AXE_BULK_DT_RD] = { 19250723Scg .type = UE_BULK, 19350723Scg .endpoint = UE_ADDR_ANY, 19450723Scg .direction = UE_DIR_IN, 19550723Scg#if (MCLBYTES < 2048) 19650723Scg#error "(MCLBYTES < 2048)" 19750723Scg#endif 19850723Scg .mh.bufsize = MCLBYTES, 19950723Scg .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,}, 20050723Scg .mh.callback = axe_bulk_read_callback, 20150723Scg .mh.timeout = 0, /* no timeout */ 20267803Scg }, 20329415Sjmg 20450723Scg [AXE_INTR_DT_RD] = { 20550723Scg .type = UE_INTERRUPT, 20650723Scg .endpoint = UE_ADDR_ANY, 20784111Scg .direction = UE_DIR_IN, 20884111Scg .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,}, 20950723Scg .mh.bufsize = 0, /* use wMaxPacketSize */ 21050723Scg .mh.callback = axe_intr_callback, 21150723Scg }, 212135115Struckman}; 21384111Scg 21450723Scgstatic device_method_t axe_methods[] = { 21584111Scg /* Device interface */ 21684111Scg DEVMETHOD(device_probe, axe_probe), 21784111Scg DEVMETHOD(device_attach, axe_attach), 21884111Scg DEVMETHOD(device_detach, axe_detach), 21984111Scg DEVMETHOD(device_shutdown, axe_shutdown), 22084111Scg 22184111Scg /* bus interface */ 22284111Scg DEVMETHOD(bus_print_child, bus_generic_print_child), 22350723Scg DEVMETHOD(bus_driver_added, bus_generic_driver_added), 22429415Sjmg 22550723Scg /* MII interface */ 22650723Scg DEVMETHOD(miibus_readreg, axe_miibus_readreg), 22750723Scg DEVMETHOD(miibus_writereg, axe_miibus_writereg), 22850723Scg DEVMETHOD(miibus_statchg, axe_miibus_statchg), 22950723Scg 23050723Scg {0, 0} 23150723Scg}; 23274763Scg 23350723Scgstatic driver_t axe_driver = { 23450723Scg .name = "axe", 23550723Scg .methods = axe_methods, 23650723Scg .size = sizeof(struct axe_softc), 23774763Scg}; 23850723Scg 23931361Sjmgstatic devclass_t axe_devclass; 24050723Scg 24150723ScgDRIVER_MODULE(axe, uhub, axe_driver, axe_devclass, NULL, 0); 24250723ScgDRIVER_MODULE(miibus, axe, miibus_driver, miibus_devclass, 0, 0); 24350723ScgMODULE_DEPEND(axe, uether, 1, 1, 1); 24429415SjmgMODULE_DEPEND(axe, usb, 1, 1, 1); 245135115StruckmanMODULE_DEPEND(axe, ether, 1, 1, 1); 24650723ScgMODULE_DEPEND(axe, miibus, 1, 1, 1); 24750723Scg 24850723Scgstatic const struct usb2_ether_methods axe_ue_methods = { 24950723Scg .ue_attach_post = axe_attach_post, 25029415Sjmg .ue_start = axe_start, 25150723Scg .ue_init = axe_init, 25250723Scg .ue_stop = axe_stop, 25329415Sjmg .ue_tick = axe_tick, 25450723Scg .ue_setmulti = axe_setmulti, 25550723Scg .ue_setpromisc = axe_setpromisc, 25650723Scg .ue_mii_upd = axe_ifmedia_upd, 25750723Scg .ue_mii_sts = axe_ifmedia_sts, 25829415Sjmg}; 25950723Scg 26050723Scgstatic int 26150723Scgaxe_cmd(struct axe_softc *sc, int cmd, int index, int val, void *buf) 26250723Scg{ 26350723Scg struct usb2_device_request req; 26450723Scg usb2_error_t err; 26550723Scg 26650723Scg AXE_LOCK_ASSERT(sc, MA_OWNED); 26729415Sjmg 26850723Scg req.bmRequestType = (AXE_CMD_IS_WRITE(cmd) ? 26950723Scg UT_WRITE_VENDOR_DEVICE : 27029415Sjmg UT_READ_VENDOR_DEVICE); 27174763Scg req.bRequest = AXE_CMD_CMD(cmd); 27274763Scg USETW(req.wValue, val); 273129180Struckman USETW(req.wIndex, index); 27450723Scg USETW(req.wLength, AXE_CMD_LEN(cmd)); 27550723Scg 27650723Scg err = usb2_ether_do_request(&sc->sc_ue, &req, buf, 1000); 27774763Scg 27874763Scg return (err); 27950723Scg} 28089774Sscottl 28150723Scgstatic int 28250723Scgaxe_miibus_readreg(device_t dev, int phy, int reg) 28350723Scg{ 28429415Sjmg struct axe_softc *sc = device_get_softc(dev); 28529415Sjmg uint16_t val; 28667803Scg int locked; 28767803Scg 28867803Scg if (sc->sc_phyno != phy) 28967803Scg return (0); 29067803Scg 29167803Scg locked = mtx_owned(&sc->sc_mtx); 29267803Scg if (!locked) 29367803Scg AXE_LOCK(sc); 29467803Scg 29567803Scg axe_cmd(sc, AXE_CMD_MII_OPMODE_SW, 0, 0, NULL); 29667803Scg axe_cmd(sc, AXE_CMD_MII_READ_REG, reg, phy, &val); 29767803Scg axe_cmd(sc, AXE_CMD_MII_OPMODE_HW, 0, 0, NULL); 29867803Scg 29967803Scg val = le16toh(val); 30067803Scg if ((sc->sc_flags & AXE_FLAG_772) != 0 && reg == MII_BMSR) { 30167803Scg /* 30267803Scg * BMSR of AX88772 indicates that it supports extended 30367803Scg * capability but the extended status register is 30467803Scg * revered for embedded ethernet PHY. So clear the 30567803Scg * extended capability bit of BMSR. 30667803Scg */ 307100953Ssobomax val &= ~BMSR_EXTCAP; 30867803Scg } 30967803Scg 31067803Scg if (!locked) 31174763Scg AXE_UNLOCK(sc); 31267803Scg return (val); 31367803Scg} 31467803Scg 31567803Scgstatic int 31667803Scgaxe_miibus_writereg(device_t dev, int phy, int reg, int val) 317100953Ssobomax{ 31867803Scg struct axe_softc *sc = device_get_softc(dev); 31967803Scg int locked; 32067803Scg 321100953Ssobomax val = htole16(val); 32267803Scg 32367803Scg if (sc->sc_phyno != phy) 32467803Scg return (0); 32567803Scg 32667803Scg locked = mtx_owned(&sc->sc_mtx); 32767803Scg if (!locked) 32867803Scg AXE_LOCK(sc); 32967803Scg 33067803Scg axe_cmd(sc, AXE_CMD_MII_OPMODE_SW, 0, 0, NULL); 33167803Scg axe_cmd(sc, AXE_CMD_MII_WRITE_REG, reg, phy, &val); 332130472Sjosef axe_cmd(sc, AXE_CMD_MII_OPMODE_HW, 0, 0, NULL); 333130472Sjosef 334130472Sjosef if (!locked) 335130472Sjosef AXE_UNLOCK(sc); 336130472Sjosef return (0); 337130472Sjosef} 338130472Sjosef 339130472Sjosefstatic void 340130472Sjosefaxe_miibus_statchg(device_t dev) 341130472Sjosef{ 342130472Sjosef struct axe_softc *sc = device_get_softc(dev); 343130472Sjosef struct mii_data *mii = GET_MII(sc); 344130472Sjosef struct ifnet *ifp; 34574763Scg uint16_t val; 34667803Scg int err, locked; 34767803Scg 34867803Scg locked = mtx_owned(&sc->sc_mtx); 34967803Scg if (!locked) 35067803Scg AXE_LOCK(sc); 35167803Scg 35267803Scg ifp = usb2_ether_getifp(&sc->sc_ue); 35367803Scg if (mii == NULL || ifp == NULL || 354130472Sjosef (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) 355130472Sjosef goto done; 35667803Scg 35767803Scg sc->sc_flags &= ~AXE_FLAG_LINK; 35867803Scg if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) == 35968376Scg (IFM_ACTIVE | IFM_AVALID)) { 36067803Scg switch (IFM_SUBTYPE(mii->mii_media_active)) { 36167803Scg case IFM_10_T: 36267803Scg case IFM_100_TX: 36367803Scg sc->sc_flags |= AXE_FLAG_LINK; 36467803Scg break; 36567803Scg case IFM_1000_T: 36667803Scg if ((sc->sc_flags & AXE_FLAG_178) == 0) 36767803Scg break; 36867803Scg sc->sc_flags |= AXE_FLAG_LINK; 36967803Scg break; 37074763Scg default: 37167803Scg break; 37267803Scg } 373152418Sariff } 37467803Scg 375152418Sariff /* Lost link, do nothing. */ 376152418Sariff if ((sc->sc_flags & AXE_FLAG_LINK) == 0) 377152418Sariff goto done; 378152418Sariff 379152418Sariff val = 0; 380152418Sariff if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0) 38167803Scg val |= AXE_MEDIA_FULL_DUPLEX; 382152418Sariff if (sc->sc_flags & (AXE_FLAG_178 | AXE_FLAG_772)) { 383152418Sariff val |= AXE_178_MEDIA_RX_EN | AXE_178_MEDIA_MAGIC; 384152418Sariff if ((sc->sc_flags & AXE_FLAG_178) != 0) 385152418Sariff val |= AXE_178_MEDIA_ENCK; 38667803Scg switch (IFM_SUBTYPE(mii->mii_media_active)) { 387152418Sariff case IFM_1000_T: 388152418Sariff val |= AXE_178_MEDIA_GMII | AXE_178_MEDIA_ENCK; 389152418Sariff break; 390152418Sariff case IFM_100_TX: 39167803Scg val |= AXE_178_MEDIA_100TX; 392152418Sariff break; 393152418Sariff case IFM_10_T: 394152418Sariff /* doesn't need to be handled */ 395152418Sariff break; 39667803Scg } 397152418Sariff } 398152418Sariff err = axe_cmd(sc, AXE_CMD_WRITE_MEDIA, 0, val, NULL); 39967803Scg if (err) 400100953Ssobomax device_printf(dev, "media change failed, error %d\n", err); 401100953Ssobomaxdone: 402100953Ssobomax if (!locked) 403100953Ssobomax AXE_UNLOCK(sc); 404100953Ssobomax} 405100953Ssobomax 40667803Scg/* 40767803Scg * Set media options. 40867803Scg */ 40967803Scgstatic int 41067803Scgaxe_ifmedia_upd(struct ifnet *ifp) 41167803Scg{ 41267803Scg struct axe_softc *sc = ifp->if_softc; 41367803Scg struct mii_data *mii = GET_MII(sc); 41467803Scg int error; 41567803Scg 41667803Scg AXE_LOCK_ASSERT(sc, MA_OWNED); 41767803Scg 41867803Scg if (mii->mii_instance) { 41970134Scg struct mii_softc *miisc; 42070134Scg 42170134Scg LIST_FOREACH(miisc, &mii->mii_phys, mii_list) 42270134Scg mii_phy_reset(miisc); 42370134Scg } 42470134Scg error = mii_mediachg(mii); 42570134Scg return (error); 42670134Scg} 42767803Scg 42867803Scg/* 42929415Sjmg * Report current media status. 43067803Scg */ 43129415Sjmgstatic void 43250723Scgaxe_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) 43365644Scg{ 43465644Scg struct axe_softc *sc = ifp->if_softc; 43565644Scg struct mii_data *mii = GET_MII(sc); 43650723Scg 43750723Scg AXE_LOCK(sc); 43884111Scg mii_pollstat(mii); 43984111Scg AXE_UNLOCK(sc); 44084111Scg ifmr->ifm_active = mii->mii_media_active; 44184111Scg ifmr->ifm_status = mii->mii_media_status; 44284111Scg} 44370291Scg 44470291Scgstatic void 44570291Scgaxe_setmulti(struct usb2_ether *ue) 44674364Scg{ 44754462Scg struct axe_softc *sc = usb2_ether_getsc(ue); 44850723Scg struct ifnet *ifp = usb2_ether_getifp(ue); 44950723Scg struct ifmultiaddr *ifma; 45070291Scg uint32_t h = 0; 45154462Scg uint16_t rxmode; 45250723Scg uint8_t hashtbl[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; 45350723Scg 45465644Scg AXE_LOCK_ASSERT(sc, MA_OWNED); 45565644Scg 45665644Scg axe_cmd(sc, AXE_CMD_RXCTL_READ, 0, 0, &rxmode); 45765644Scg rxmode = le16toh(rxmode); 45865644Scg 45950723Scg if (ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC)) { 46029415Sjmg rxmode |= AXE_RXCMD_ALLMULTI; 46150723Scg axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, rxmode, NULL); 46267803Scg return; 46350723Scg } 46454462Scg rxmode &= ~AXE_RXCMD_ALLMULTI; 46554462Scg 46654462Scg IF_ADDR_LOCK(ifp); 46750723Scg TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) 468127135Snjl { 469127135Snjl if (ifma->ifma_addr->sa_family != AF_LINK) 47067803Scg continue; 47154462Scg h = ether_crc32_be(LLADDR((struct sockaddr_dl *) 47250723Scg ifma->ifma_addr), ETHER_ADDR_LEN) >> 26; 473127135Snjl hashtbl[h / 8] |= 1 << (h % 8); 474127135Snjl } 47567803Scg IF_ADDR_UNLOCK(ifp); 47654462Scg 47750723Scg axe_cmd(sc, AXE_CMD_WRITE_MCAST, 0, 0, (void *)&hashtbl); 478127135Snjl axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, rxmode, NULL); 479127135Snjl} 48067803Scg 48154462Scgstatic int 48258756Scgaxe_get_phyno(struct axe_softc *sc, int sel) 483127135Snjl{ 484127135Snjl int phyno; 48529415Sjmg 48650723Scg switch (AXE_PHY_TYPE(sc->sc_phyaddrs[sel])) { 48754462Scg case PHY_TYPE_100_HOME: 48884111Scg case PHY_TYPE_GIG: 48929415Sjmg phyno = AXE_PHY_NO(sc->sc_phyaddrs[sel]); 49050723Scg break; 49154462Scg case PHY_TYPE_SPECIAL: 49284111Scg /* FALLTHROUGH */ 49370291Scg case PHY_TYPE_RSVD: 49470291Scg /* FALLTHROUGH */ 49570291Scg case PHY_TYPE_NON_SUP: 49654462Scg /* FALLTHROUGH */ 49750723Scg default: 49850723Scg phyno = -1; 49929415Sjmg break; 50029415Sjmg } 50174763Scg 50254462Scg return (phyno); 50367803Scg} 50429415Sjmg 50567803Scgstatic void 506149948Snetchildaxe_ax88178_init(struct axe_softc *sc) 50729415Sjmg{ 50867803Scg int gpio0 = 0, phymode = 0; 50967803Scg uint16_t eeprom; 51067803Scg 51167803Scg axe_cmd(sc, AXE_CMD_SROM_WR_ENABLE, 0, 0, NULL); 51229415Sjmg /* XXX magic */ 51367803Scg axe_cmd(sc, AXE_CMD_SROM_READ, 0, 0x0017, &eeprom); 51474763Scg eeprom = le16toh(eeprom); 51567803Scg axe_cmd(sc, AXE_CMD_SROM_WR_DISABLE, 0, 0, NULL); 51674763Scg 51774763Scg /* if EEPROM is invalid we have to use to GPIO0 */ 51841653Sbrian if (eeprom == 0xffff) { 51974763Scg phymode = 0; 52074763Scg gpio0 = 1; 52174763Scg } else { 52274763Scg phymode = eeprom & 7; 52367803Scg gpio0 = (eeprom & 0x80) ? 0 : 1; 52467803Scg } 52567803Scg 52667803Scg axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x008c, NULL); 52729415Sjmg usb2_ether_pause(&sc->sc_ue, hz / 16); 52868414Scg 52968414Scg if ((eeprom >> 8) != 0x01) { 53068414Scg axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x003c, NULL); 53168414Scg usb2_ether_pause(&sc->sc_ue, hz / 32); 53268414Scg 53368414Scg axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x001c, NULL); 53468414Scg usb2_ether_pause(&sc->sc_ue, hz / 3); 53568414Scg 53668414Scg axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x003c, NULL); 53768414Scg usb2_ether_pause(&sc->sc_ue, hz / 32); 53868414Scg } else { 53968414Scg axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x0004, NULL); 54068414Scg usb2_ether_pause(&sc->sc_ue, hz / 32); 54168414Scg 54268414Scg axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x000c, NULL); 54370291Scg usb2_ether_pause(&sc->sc_ue, hz / 32); 54468414Scg } 54570291Scg 54668414Scg /* soft reset */ 54768414Scg axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_CLEAR, NULL); 54868414Scg usb2_ether_pause(&sc->sc_ue, hz / 4); 54970291Scg 55068414Scg axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, 55170291Scg AXE_SW_RESET_PRL | AXE_178_RESET_MAGIC, NULL); 55268414Scg usb2_ether_pause(&sc->sc_ue, hz / 4); 55368414Scg /* Enable MII/GMII/RGMII interface to work with external PHY. */ 55468414Scg axe_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0, 0, NULL); 55550723Scg usb2_ether_pause(&sc->sc_ue, hz / 4); 55650723Scg 55750723Scg axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, 0, NULL); 55867803Scg} 55950723Scg 56067803Scgstatic void 56167803Scgaxe_ax88772_init(struct axe_softc *sc) 56250723Scg{ 56350723Scg axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x00b0, NULL); 56431361Sjmg usb2_ether_pause(&sc->sc_ue, hz / 16); 56550723Scg 56667803Scg if (sc->sc_phyno == AXE_772_PHY_NO_EPHY) { 56750723Scg /* ask for the embedded PHY */ 56867803Scg axe_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0, 0x01, NULL); 56967803Scg usb2_ether_pause(&sc->sc_ue, hz / 64); 57067803Scg 57129415Sjmg /* power down and reset state, pin reset state */ 57274763Scg axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, 57367803Scg AXE_SW_RESET_CLEAR, NULL); 574110499Snyan usb2_ether_pause(&sc->sc_ue, hz / 16); 57567803Scg 576110499Snyan /* power down/reset state, pin operating state */ 57767803Scg axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, 57829415Sjmg AXE_SW_RESET_IPPD | AXE_SW_RESET_PRL, NULL); 57967803Scg usb2_ether_pause(&sc->sc_ue, hz / 4); 58029415Sjmg 58167803Scg /* power up, reset */ 582149948Snetchild axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_PRL, NULL); 58368414Scg 584149948Snetchild /* power up, operating */ 58570291Scg axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, 586110499Snyan AXE_SW_RESET_IPRL | AXE_SW_RESET_PRL, NULL); 58770291Scg } else { 58867803Scg /* ask for external PHY */ 58967803Scg axe_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0, 0x00, NULL); 59067803Scg usb2_ether_pause(&sc->sc_ue, hz / 64); 591110499Snyan 59270291Scg /* power down internal PHY */ 593110499Snyan axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, 59470291Scg AXE_SW_RESET_IPPD | AXE_SW_RESET_PRL, NULL); 59567803Scg } 59667803Scg 597110499Snyan usb2_ether_pause(&sc->sc_ue, hz / 4); 59870291Scg axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, 0, NULL); 599110499Snyan} 60070291Scg 60167803Scgstatic void 602110499Snyanaxe_reset(struct axe_softc *sc) 60370291Scg{ 604110499Snyan struct usb2_config_descriptor *cd; 60570291Scg usb2_error_t err; 60667803Scg 60750723Scg cd = usb2_get_config_descriptor(sc->sc_ue.ue_udev); 60867803Scg 60929415Sjmg err = usb2_req_set_config(sc->sc_ue.ue_udev, &sc->sc_mtx, 610110499Snyan cd->bConfigurationValue); 611110499Snyan if (err) 61229415Sjmg DPRINTF("reset failed (ignored)\n"); 61367803Scg 61468414Scg /* Wait a little while for the chip to get its brains in order. */ 61568414Scg usb2_ether_pause(&sc->sc_ue, hz / 100); 61667803Scg} 61755706Scg 61867803Scgstatic void 61967803Scgaxe_attach_post(struct usb2_ether *ue) 62067803Scg{ 62167803Scg struct axe_softc *sc = usb2_ether_getsc(ue); 62267803Scg 62367803Scg /* 62455706Scg * Load PHY indexes first. Needed by axe_xxx_init(). 62567803Scg */ 62667803Scg axe_cmd(sc, AXE_CMD_READ_PHYID, 0, 0, sc->sc_phyaddrs); 62767803Scg#if 1 62867803Scg device_printf(sc->sc_ue.ue_dev, "PHYADDR 0x%02x:0x%02x\n", 62967803Scg sc->sc_phyaddrs[0], sc->sc_phyaddrs[1]); 63067803Scg#endif 63167803Scg sc->sc_phyno = axe_get_phyno(sc, AXE_PHY_SEL_PRI); 63267803Scg if (sc->sc_phyno == -1) 63367803Scg sc->sc_phyno = axe_get_phyno(sc, AXE_PHY_SEL_SEC); 63467803Scg if (sc->sc_phyno == -1) { 63567803Scg device_printf(sc->sc_ue.ue_dev, 63667803Scg "no valid PHY address found, assuming PHY address 0\n"); 63767803Scg sc->sc_phyno = 0; 63867803Scg } 639110499Snyan 64067803Scg if (sc->sc_flags & AXE_FLAG_178) 64150723Scg axe_ax88178_init(sc); 64250723Scg else if (sc->sc_flags & AXE_FLAG_772) 64367803Scg axe_ax88772_init(sc); 64467803Scg 64567803Scg /* 64667803Scg * Get station address. 64767803Scg */ 64867803Scg if (sc->sc_flags & (AXE_FLAG_178 | AXE_FLAG_772)) 64929415Sjmg axe_cmd(sc, AXE_178_CMD_READ_NODEID, 0, 0, ue->ue_eaddr); 65067803Scg else 65167803Scg axe_cmd(sc, AXE_172_CMD_READ_NODEID, 0, 0, ue->ue_eaddr); 65267803Scg 65367803Scg /* 65467803Scg * Fetch IPG values. 65567803Scg */ 65667803Scg axe_cmd(sc, AXE_CMD_READ_IPG012, 0, 0, sc->sc_ipgs); 65767803Scg} 65867803Scg 65967803Scg/* 66067803Scg * Probe for a AX88172 chip. 66167803Scg */ 66267803Scgstatic int 66367803Scgaxe_probe(device_t dev) 664110499Snyan{ 66567803Scg struct usb2_attach_arg *uaa = device_get_ivars(dev); 66629415Sjmg 66774763Scg if (uaa->usb2_mode != USB_MODE_HOST) 66867803Scg return (ENXIO); 66967803Scg if (uaa->info.bConfigIndex != AXE_CONFIG_IDX) 67050723Scg return (ENXIO); 67129415Sjmg if (uaa->info.bIfaceIndex != AXE_IFACE_IDX) 67255706Scg return (ENXIO); 67355706Scg 67474763Scg return (usb2_lookup_id_by_uaa(axe_devs, sizeof(axe_devs), uaa)); 67555706Scg} 67655706Scg 67755706Scg/* 67855706Scg * Attach the interface. Allocate softc structures, do ifmedia 67955706Scg * setup and ethernet/BPF attach. 68055706Scg */ 68155706Scgstatic int 68267803Scgaxe_attach(device_t dev) 68367803Scg{ 684168847Sariff struct usb2_attach_arg *uaa = device_get_ivars(dev); 68555706Scg struct axe_softc *sc = device_get_softc(dev); 68667803Scg struct usb2_ether *ue = &sc->sc_ue; 68755706Scg uint8_t iface_index; 68855706Scg int error; 68955706Scg 69055706Scg sc->sc_flags = USB_GET_DRIVER_INFO(uaa); 69170134Scg 69255706Scg device_set_usb2_desc(dev); 69355706Scg 69467803Scg mtx_init(&sc->sc_mtx, device_get_nameunit(dev), NULL, MTX_DEF); 69555706Scg 69667803Scg iface_index = AXE_IFACE_IDX; 69767803Scg error = usb2_transfer_setup(uaa->device, &iface_index, sc->sc_xfer, 69867803Scg axe_config, AXE_N_TRANSFER, sc, &sc->sc_mtx); 69967803Scg if (error) { 70055706Scg device_printf(dev, "allocating USB transfers failed!\n"); 70155706Scg goto detach; 70255706Scg } 70355706Scg 70470134Scg ue->ue_sc = sc; 70555706Scg ue->ue_dev = dev; 70655706Scg ue->ue_udev = uaa->device; 70755706Scg ue->ue_mtx = &sc->sc_mtx; 70867803Scg ue->ue_methods = &axe_ue_methods; 70967803Scg 71055706Scg error = usb2_ether_ifattach(ue); 71155706Scg if (error) { 71255706Scg device_printf(dev, "could not attach interface\n"); 71370134Scg goto detach; 71455706Scg } 71555706Scg return (0); /* success */ 71655706Scg 71767803Scgdetach: 71870291Scg axe_detach(dev); 71955706Scg return (ENXIO); /* failure */ 72055706Scg} 72155706Scg 72270134Scgstatic int 72355706Scgaxe_detach(device_t dev) 72455706Scg{ 72567803Scg struct axe_softc *sc = device_get_softc(dev); 72655706Scg struct usb2_ether *ue = &sc->sc_ue; 727170521Sariff 72855706Scg usb2_transfer_unsetup(sc->sc_xfer, AXE_N_TRANSFER); 72955706Scg usb2_ether_ifdetach(ue); 73055706Scg mtx_destroy(&sc->sc_mtx); 73167803Scg 73255706Scg return (0); 73367803Scg} 73468376Scg 73567803Scgstatic void 73667803Scgaxe_intr_callback(struct usb2_xfer *xfer) 73755706Scg{ 73855706Scg switch (USB_GET_STATE(xfer)) { 73955706Scg case USB_ST_TRANSFERRED: 74055706Scg case USB_ST_SETUP: 74170134Scgtr_setup: 74255706Scg xfer->frlengths[0] = xfer->max_data_length; 74355706Scg usb2_start_hardware(xfer); 74455706Scg return; 745110499Snyan 74655706Scg default: /* Error */ 74755706Scg if (xfer->error != USB_ERR_CANCELLED) { 74874763Scg /* try to clear stall first */ 74970134Scg xfer->flags.stall_pipe = 1; 75055706Scg goto tr_setup; 75155706Scg } 75267803Scg return; 75355706Scg } 75467803Scg} 75555706Scg 75655706Scg#if (AXE_BULK_BUF_SIZE >= 0x10000) 75767803Scg#error "Please update axe_bulk_read_callback()!" 75855706Scg#endif 75955706Scg 76029415Sjmgstatic void 76170134Scgaxe_bulk_read_callback(struct usb2_xfer *xfer) 76229415Sjmg{ 76367803Scg struct axe_softc *sc = xfer->priv_sc; 76467803Scg struct usb2_ether *ue = &sc->sc_ue; 76531361Sjmg struct ifnet *ifp = usb2_ether_getifp(ue); 76667803Scg struct axe_sframe_hdr hdr; 76729415Sjmg int error, pos, len, adjust; 76867803Scg 76929415Sjmg switch (USB_GET_STATE(xfer)) { 77029415Sjmg case USB_ST_TRANSFERRED: 77170134Scg pos = 0; 77270134Scg while (1) { 77370134Scg if (sc->sc_flags & (AXE_FLAG_772 | AXE_FLAG_178)) { 77470134Scg if (xfer->actlen < sizeof(hdr)) { 77570134Scg /* too little data */ 77670134Scg break; 77770134Scg } 77870134Scg usb2_copy_out(xfer->frbuffers, pos, &hdr, sizeof(hdr)); 77970134Scg 78070134Scg if ((hdr.len ^ hdr.ilen) != 0xFFFF) { 78170134Scg /* we lost sync */ 78270134Scg break; 78370134Scg } 78467803Scg xfer->actlen -= sizeof(hdr); 78529415Sjmg pos += sizeof(hdr); 78629415Sjmg 78767803Scg len = le16toh(hdr.len); 78853553Stanimura if (len > xfer->actlen) { 78954462Scg /* invalid length */ 79055092Sdfr break; 79153553Stanimura } 79253553Stanimura adjust = (len & 1); 79354462Scg 79454462Scg } else { 79553553Stanimura len = xfer->actlen; 79653553Stanimura adjust = 0; 79754462Scg } 79854791Scg error = usb2_ether_rxbuf(ue, xfer->frbuffers, pos, len); 79954462Scg if (error) 80067803Scg break; 80167803Scg 80267803Scg pos += len; 80367803Scg xfer->actlen -= len; 80467803Scg 80567803Scg if (xfer->actlen <= adjust) { 80658756Scg /* we are finished */ 80753553Stanimura goto tr_setup; 80853553Stanimura } 80953553Stanimura pos += adjust; 81067803Scg xfer->actlen -= adjust; 81153553Stanimura } 81253553Stanimura 81355092Sdfr /* count an error */ 81484111Scg ifp->if_ierrors++; 81553553Stanimura 816170873Sariff /* FALLTHROUGH */ 81774763Scg case USB_ST_SETUP: 81874763Scgtr_setup: 81954462Scg xfer->frlengths[0] = xfer->max_data_length; 82054462Scg usb2_start_hardware(xfer); 82184111Scg usb2_ether_rxflush(ue); 82254462Scg return; 823129181Struckman 82467803Scg default: /* Error */ 825129180Struckman DPRINTF("bulk read error, %s\n", 826129180Struckman usb2_errstr(xfer->error)); 827129180Struckman 82867803Scg if (xfer->error != USB_ERR_CANCELLED) { 829129180Struckman /* try to clear stall first */ 830129180Struckman xfer->flags.stall_pipe = 1; 83170134Scg goto tr_setup; 83267803Scg } 833128232Sgreen return; 83467803Scg 83567803Scg } 83670291Scg} 83767803Scg 83867803Scg#if ((AXE_BULK_BUF_SIZE >= 0x10000) || (AXE_BULK_BUF_SIZE < (MCLBYTES+4))) 83967803Scg#error "Please update axe_bulk_write_callback()!" 84067803Scg#endif 841166904Snetchild 842166904Snetchildstatic void 84367803Scgaxe_bulk_write_callback(struct usb2_xfer *xfer) 84467803Scg{ 84567803Scg struct axe_softc *sc = xfer->priv_sc; 84684111Scg struct axe_sframe_hdr hdr; 847117126Sscottl struct ifnet *ifp = usb2_ether_getifp(&sc->sc_ue); 848117126Sscottl struct mbuf *m; 849117126Sscottl int pos; 85067803Scg 85167803Scg switch (USB_GET_STATE(xfer)) { 85267803Scg case USB_ST_TRANSFERRED: 85367803Scg DPRINTFN(11, "transfer complete\n"); 85470291Scg ifp->if_opackets++; 85584111Scg /* FALLTHROUGH */ 85684111Scg case USB_ST_SETUP: 85784111Scgtr_setup: 85867803Scg if ((sc->sc_flags & AXE_FLAG_LINK) == 0) { 859152418Sariff /* 86084111Scg * don't send anything if there is no link ! 861126695Smatk */ 862126695Smatk return; 86384111Scg } 86467803Scg pos = 0; 86567803Scg 86670134Scg while (1) { 86770134Scg 86867803Scg IFQ_DRV_DEQUEUE(&ifp->if_snd, m); 86967803Scg 87067803Scg if (m == NULL) { 87167803Scg if (pos > 0) 87267803Scg break; /* send out data */ 87367803Scg return; 87467803Scg } 87567803Scg if (m->m_pkthdr.len > MCLBYTES) { 87653553Stanimura m->m_pkthdr.len = MCLBYTES; 87753553Stanimura } 87867803Scg if (sc->sc_flags & (AXE_FLAG_772 | AXE_FLAG_178)) { 87967803Scg 88067803Scg hdr.len = htole16(m->m_pkthdr.len); 88167803Scg hdr.ilen = ~hdr.len; 88267803Scg 88367803Scg usb2_copy_in(xfer->frbuffers, pos, &hdr, sizeof(hdr)); 88467803Scg 88567803Scg pos += sizeof(hdr); 88667803Scg 88767803Scg /* 88867803Scg * NOTE: Some drivers force a short packet 88967803Scg * by appending a dummy header with zero 89067803Scg * length at then end of the USB transfer. 89167803Scg * This driver uses the 89267803Scg * USB_FORCE_SHORT_XFER flag instead. 89367803Scg */ 89453553Stanimura } 89567803Scg usb2_m_copy_in(xfer->frbuffers, pos, 89667803Scg m, 0, m->m_pkthdr.len); 89767803Scg 89853553Stanimura pos += m->m_pkthdr.len; 89953553Stanimura 90053553Stanimura /* 90153553Stanimura * if there's a BPF listener, bounce a copy 90267803Scg * of this frame to him: 90353553Stanimura */ 90467803Scg BPF_MTAP(ifp, m); 90582180Scg 90653553Stanimura m_freem(m); 90753553Stanimura 90867803Scg if (sc->sc_flags & (AXE_FLAG_772 | AXE_FLAG_178)) { 909132236Stanimura if (pos > (AXE_BULK_BUF_SIZE - MCLBYTES - sizeof(hdr))) { 91074763Scg /* send out frame(s) */ 91167803Scg break; 912 } 913 } else { 914 /* send out frame */ 915 break; 916 } 917 } 918 919 xfer->frlengths[0] = pos; 920 usb2_start_hardware(xfer); 921 return; 922 923 default: /* Error */ 924 DPRINTFN(11, "transfer error, %s\n", 925 usb2_errstr(xfer->error)); 926 927 ifp->if_oerrors++; 928 929 if (xfer->error != USB_ERR_CANCELLED) { 930 /* try to clear stall first */ 931 xfer->flags.stall_pipe = 1; 932 goto tr_setup; 933 } 934 return; 935 936 } 937} 938 939static void 940axe_tick(struct usb2_ether *ue) 941{ 942 struct axe_softc *sc = usb2_ether_getsc(ue); 943 struct mii_data *mii = GET_MII(sc); 944 945 AXE_LOCK_ASSERT(sc, MA_OWNED); 946 947 mii_tick(mii); 948 if ((sc->sc_flags & AXE_FLAG_LINK) == 0) { 949 axe_miibus_statchg(ue->ue_dev); 950 if ((sc->sc_flags & AXE_FLAG_LINK) != 0) 951 axe_start(ue); 952 } 953} 954 955static void 956axe_start(struct usb2_ether *ue) 957{ 958 struct axe_softc *sc = usb2_ether_getsc(ue); 959 960 /* 961 * start the USB transfers, if not already started: 962 */ 963 usb2_transfer_start(sc->sc_xfer[AXE_INTR_DT_RD]); 964 usb2_transfer_start(sc->sc_xfer[AXE_BULK_DT_RD]); 965 usb2_transfer_start(sc->sc_xfer[AXE_BULK_DT_WR]); 966} 967 968static void 969axe_init(struct usb2_ether *ue) 970{ 971 struct axe_softc *sc = usb2_ether_getsc(ue); 972 struct ifnet *ifp = usb2_ether_getifp(ue); 973 uint16_t rxmode; 974 975 AXE_LOCK_ASSERT(sc, MA_OWNED); 976 977 /* Cancel pending I/O */ 978 axe_stop(ue); 979 980#ifdef notdef 981 /* Set MAC address */ 982 axe_mac(sc, IF_LLADDR(ifp), 1); 983#endif 984 985 /* Set transmitter IPG values */ 986 if (sc->sc_flags & (AXE_FLAG_178 | AXE_FLAG_772)) { 987 axe_cmd(sc, AXE_178_CMD_WRITE_IPG012, sc->sc_ipgs[2], 988 (sc->sc_ipgs[1] << 8) | (sc->sc_ipgs[0]), NULL); 989 } else { 990 axe_cmd(sc, AXE_172_CMD_WRITE_IPG0, 0, sc->sc_ipgs[0], NULL); 991 axe_cmd(sc, AXE_172_CMD_WRITE_IPG1, 0, sc->sc_ipgs[1], NULL); 992 axe_cmd(sc, AXE_172_CMD_WRITE_IPG2, 0, sc->sc_ipgs[2], NULL); 993 } 994 995 /* Enable receiver, set RX mode */ 996 rxmode = (AXE_RXCMD_MULTICAST | AXE_RXCMD_ENABLE); 997 if (sc->sc_flags & (AXE_FLAG_178 | AXE_FLAG_772)) { 998 rxmode |= AXE_178_RXCMD_MFB_2048; /* chip default */ 999 } else { 1000 rxmode |= AXE_172_RXCMD_UNICAST; 1001 } 1002 1003 /* If we want promiscuous mode, set the allframes bit. */ 1004 if (ifp->if_flags & IFF_PROMISC) 1005 rxmode |= AXE_RXCMD_PROMISC; 1006 1007 if (ifp->if_flags & IFF_BROADCAST) 1008 rxmode |= AXE_RXCMD_BROADCAST; 1009 1010 axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, rxmode, NULL); 1011 1012 /* Load the multicast filter. */ 1013 axe_setmulti(ue); 1014 1015 usb2_transfer_set_stall(sc->sc_xfer[AXE_BULK_DT_WR]); 1016 1017 ifp->if_drv_flags |= IFF_DRV_RUNNING; 1018 axe_start(ue); 1019} 1020 1021static void 1022axe_setpromisc(struct usb2_ether *ue) 1023{ 1024 struct axe_softc *sc = usb2_ether_getsc(ue); 1025 struct ifnet *ifp = usb2_ether_getifp(ue); 1026 uint16_t rxmode; 1027 1028 axe_cmd(sc, AXE_CMD_RXCTL_READ, 0, 0, &rxmode); 1029 1030 rxmode = le16toh(rxmode); 1031 1032 if (ifp->if_flags & IFF_PROMISC) { 1033 rxmode |= AXE_RXCMD_PROMISC; 1034 } else { 1035 rxmode &= ~AXE_RXCMD_PROMISC; 1036 } 1037 1038 axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, rxmode, NULL); 1039 1040 axe_setmulti(ue); 1041} 1042 1043static void 1044axe_stop(struct usb2_ether *ue) 1045{ 1046 struct axe_softc *sc = usb2_ether_getsc(ue); 1047 struct ifnet *ifp = usb2_ether_getifp(ue); 1048 1049 AXE_LOCK_ASSERT(sc, MA_OWNED); 1050 1051 ifp->if_drv_flags &= ~IFF_DRV_RUNNING; 1052 sc->sc_flags &= ~AXE_FLAG_LINK; 1053 1054 /* 1055 * stop all the transfers, if not already stopped: 1056 */ 1057 usb2_transfer_stop(sc->sc_xfer[AXE_BULK_DT_WR]); 1058 usb2_transfer_stop(sc->sc_xfer[AXE_BULK_DT_RD]); 1059 usb2_transfer_stop(sc->sc_xfer[AXE_INTR_DT_RD]); 1060 1061 axe_reset(sc); 1062} 1063 1064/* 1065 * Stop all chip I/O so that the kernel's probe routines don't 1066 * get confused by errant DMAs when rebooting. 1067 */ 1068static int 1069axe_shutdown(device_t dev) 1070{ 1071 struct axe_softc *sc = device_get_softc(dev); 1072 1073 usb2_ether_ifshutdown(&sc->sc_ue); 1074 1075 return (0); 1076} 1077