1155324Simp/*- 2155324Simp * Copyright (c) 2006 M. Warner Losh. All rights reserved. 3213496Scognet * Copyright (c) 2009 Greg Ansley. All rights reserved. 4155324Simp * 5155324Simp * Redistribution and use in source and binary forms, with or without 6155324Simp * modification, are permitted provided that the following conditions 7155324Simp * are met: 8155324Simp * 1. Redistributions of source code must retain the above copyright 9155324Simp * notice, this list of conditions and the following disclaimer. 10155324Simp * 2. Redistributions in binary form must reproduce the above copyright 11155324Simp * notice, this list of conditions and the following disclaimer in the 12155324Simp * documentation and/or other materials provided with the distribution. 13155324Simp * 14185267Simp * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15185267Simp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16185267Simp * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17185267Simp * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 18185267Simp * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19185267Simp * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20185267Simp * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21185267Simp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22185267Simp * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23185267Simp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24185267Simp * SUCH DAMAGE. 25155324Simp */ 26155324Simp 27192018Sstas/* TODO 28155324Simp * 29192018Sstas * 1) Turn on the clock in pmc? Turn off? 30192018Sstas * 2) GPIO initializtion in board setup code. 31155324Simp */ 32155324Simp 33266196Sian#include "opt_platform.h" 34266196Sian 35155324Simp#include <sys/cdefs.h> 36155324Simp__FBSDID("$FreeBSD$"); 37155324Simp 38155324Simp#include <sys/param.h> 39155324Simp#include <sys/systm.h> 40155324Simp#include <sys/bus.h> 41155324Simp#include <sys/kernel.h> 42213496Scognet#include <sys/malloc.h> 43155324Simp#include <sys/mbuf.h> 44155324Simp#include <sys/module.h> 45155324Simp#include <sys/rman.h> 46155324Simp#include <sys/socket.h> 47155324Simp#include <sys/sockio.h> 48163522Simp#include <sys/sysctl.h> 49213496Scognet 50155324Simp#include <machine/bus.h> 51155324Simp 52155324Simp#include <net/ethernet.h> 53155324Simp#include <net/if.h> 54155324Simp#include <net/if_arp.h> 55155324Simp#include <net/if_dl.h> 56155324Simp#include <net/if_media.h> 57155324Simp#include <net/if_mib.h> 58155324Simp#include <net/if_types.h> 59259342Sian#include <net/if_var.h> 60155324Simp 61155324Simp#ifdef INET 62155324Simp#include <netinet/in.h> 63155324Simp#include <netinet/in_systm.h> 64155324Simp#include <netinet/in_var.h> 65155324Simp#include <netinet/ip.h> 66155324Simp#endif 67155324Simp 68155324Simp#include <net/bpf.h> 69155324Simp#include <net/bpfdesc.h> 70155324Simp 71155324Simp#include <dev/mii/mii.h> 72155324Simp#include <dev/mii/miivar.h> 73213496Scognet 74213496Scognet#include "opt_at91.h" 75213496Scognet#include <arm/at91/at91reg.h> 76213496Scognet#include <arm/at91/at91var.h> 77155324Simp#include <arm/at91/if_atereg.h> 78155324Simp 79266196Sian#ifdef FDT 80266196Sian#include <dev/fdt/fdt_common.h> 81266196Sian#include <dev/ofw/ofw_bus.h> 82266196Sian#include <dev/ofw/ofw_bus_subr.h> 83266196Sian#endif 84266196Sian 85155324Simp#include "miibus_if.h" 86155324Simp 87191959Sstas/* 88191959Sstas * Driver-specific flags. 89191959Sstas */ 90213496Scognet#define ATE_FLAG_DETACHING 0x01 91213496Scognet#define ATE_FLAG_MULTICAST 0x02 92191959Sstas 93213496Scognet/* 94213496Scognet * Old EMAC assumes whole packet fits in one buffer; 95213496Scognet * new EBACB assumes all receive buffers are 128 bytes 96213496Scognet */ 97213496Scognet#define RX_BUF_SIZE(sc) (sc->is_emacb ? 128 : MCLBYTES) 98213496Scognet 99213496Scognet/* 100213496Scognet * EMACB has an 11 bit counter for Rx/Tx Descriptors 101213496Scognet * for max total of 1024 decriptors each. 102213496Scognet */ 103213496Scognet#define ATE_MAX_RX_DESCR 1024 104213496Scognet#define ATE_MAX_TX_DESCR 1024 105213496Scognet 106213496Scognet/* How many buffers to allocate */ 107213496Scognet#define ATE_MAX_TX_BUFFERS 4 /* We have ping-pong tx buffers */ 108213496Scognet 109213496Scognet/* How much memory to use for rx buffers */ 110213496Scognet#define ATE_RX_MEMORY (ATE_MAX_RX_DESCR * 128) 111213496Scognet 112213496Scognet/* Actual number of descriptors we allocate */ 113213496Scognet#define ATE_NUM_RX_DESCR ATE_MAX_RX_DESCR 114213496Scognet#define ATE_NUM_TX_DESCR ATE_MAX_TX_BUFFERS 115213496Scognet 116213496Scognet#if ATE_NUM_TX_DESCR > ATE_MAX_TX_DESCR 117213496Scognet#error "Can't have more TX buffers that descriptors" 118213496Scognet#endif 119213496Scognet#if ATE_NUM_RX_DESCR > ATE_MAX_RX_DESCR 120213496Scognet#error "Can't have more RX buffers that descriptors" 121213496Scognet#endif 122213496Scognet 123213496Scognet/* Wrap indexes the same way the hardware does */ 124213496Scognet#define NEXT_RX_IDX(sc, cur) \ 125213496Scognet ((sc->rx_descs[cur].addr & ETH_WRAP_BIT) ? 0 : (cur + 1)) 126213496Scognet 127213496Scognet#define NEXT_TX_IDX(sc, cur) \ 128213496Scognet ((sc->tx_descs[cur].status & ETHB_TX_WRAP) ? 0 : (cur + 1)) 129213496Scognet 130155324Simpstruct ate_softc 131155324Simp{ 132234281Smarius struct ifnet *ifp; /* ifnet pointer */ 133234281Smarius struct mtx sc_mtx; /* Basically a perimeter lock */ 134234281Smarius device_t dev; /* Myself */ 135234281Smarius device_t miibus; /* My child miibus */ 136234281Smarius struct resource *irq_res; /* IRQ resource */ 137234281Smarius struct resource *mem_res; /* Memory resource */ 138234281Smarius struct callout tick_ch; /* Tick callout */ 139192063Sstas struct ifmib_iso_8802_3 mibdata; /* Stuff for network mgmt */ 140234281Smarius bus_dma_tag_t mtag; /* bus dma tag for mbufs */ 141213496Scognet bus_dma_tag_t rx_tag; 142213496Scognet bus_dma_tag_t rx_desc_tag; 143213496Scognet bus_dmamap_t rx_desc_map; 144213496Scognet bus_dmamap_t rx_map[ATE_MAX_RX_DESCR]; 145234281Smarius bus_addr_t rx_desc_phys; /* PA of rx descriptors */ 146234281Smarius eth_rx_desc_t *rx_descs; /* VA of rx descriptors */ 147234281Smarius void *rx_buf[ATE_NUM_RX_DESCR]; /* RX buffer space */ 148234281Smarius int rxhead; /* Current RX map/desc index */ 149234281Smarius uint32_t rx_buf_size; /* Size of Rx buffers */ 150213496Scognet 151213496Scognet bus_dma_tag_t tx_desc_tag; 152213496Scognet bus_dmamap_t tx_desc_map; 153213496Scognet bus_dmamap_t tx_map[ATE_MAX_TX_BUFFERS]; 154234281Smarius bus_addr_t tx_desc_phys; /* PA of tx descriptors */ 155234281Smarius eth_tx_desc_t *tx_descs; /* VA of tx descriptors */ 156234281Smarius int txhead; /* Current TX map/desc index */ 157234281Smarius int txtail; /* Current TX map/desc index */ 158234281Smarius struct mbuf *sent_mbuf[ATE_MAX_TX_BUFFERS]; /* Sent mbufs */ 159234281Smarius void *intrhand; /* Interrupt handle */ 160234281Smarius int flags; 161234281Smarius int if_flags; 162234281Smarius int use_rmii; 163234281Smarius int is_emacb; /* SAM9x hardware version */ 164155324Simp}; 165155324Simp 166155324Simpstatic inline uint32_t 167155324SimpRD4(struct ate_softc *sc, bus_size_t off) 168155324Simp{ 169192063Sstas 170192063Sstas return (bus_read_4(sc->mem_res, off)); 171155324Simp} 172155324Simp 173155324Simpstatic inline void 174155324SimpWR4(struct ate_softc *sc, bus_size_t off, uint32_t val) 175155324Simp{ 176192063Sstas 177155324Simp bus_write_4(sc->mem_res, off, val); 178155324Simp} 179155324Simp 180192027Sstasstatic inline void 181192027SstasBARRIER(struct ate_softc *sc, bus_size_t off, bus_size_t len, int flags) 182192027Sstas{ 183192027Sstas 184192027Sstas bus_barrier(sc->mem_res, off, len, flags); 185192027Sstas} 186192027Sstas 187192063Sstas#define ATE_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx) 188155324Simp#define ATE_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx) 189192063Sstas#define ATE_LOCK_INIT(_sc) \ 190192063Sstas mtx_init(&_sc->sc_mtx, device_get_nameunit(_sc->dev), \ 191155324Simp MTX_NETWORK_LOCK, MTX_DEF) 192192063Sstas#define ATE_LOCK_DESTROY(_sc) mtx_destroy(&_sc->sc_mtx); 193192063Sstas#define ATE_ASSERT_LOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_OWNED); 194192063Sstas#define ATE_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_NOTOWNED); 195155324Simp 196155324Simpstatic devclass_t ate_devclass; 197155324Simp 198192063Sstas/* 199192063Sstas * ifnet entry points. 200192063Sstas */ 201192063Sstasstatic void ateinit_locked(void *); 202192063Sstasstatic void atestart_locked(struct ifnet *); 203155324Simp 204192063Sstasstatic void ateinit(void *); 205192063Sstasstatic void atestart(struct ifnet *); 206192063Sstasstatic void atestop(struct ate_softc *); 207192063Sstasstatic int ateioctl(struct ifnet * ifp, u_long, caddr_t); 208155324Simp 209192063Sstas/* 210192063Sstas * Bus entry points. 211192063Sstas */ 212192063Sstasstatic int ate_probe(device_t dev); 213192063Sstasstatic int ate_attach(device_t dev); 214192063Sstasstatic int ate_detach(device_t dev); 215192063Sstasstatic void ate_intr(void *); 216155324Simp 217192063Sstas/* 218192063Sstas * Helper routines. 219192063Sstas */ 220192063Sstasstatic int ate_activate(device_t dev); 221192063Sstasstatic void ate_deactivate(struct ate_softc *sc); 222192063Sstasstatic int ate_ifmedia_upd(struct ifnet *ifp); 223192063Sstasstatic void ate_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr); 224192063Sstasstatic int ate_get_mac(struct ate_softc *sc, u_char *eaddr); 225192063Sstasstatic void ate_set_mac(struct ate_softc *sc, u_char *eaddr); 226191959Sstasstatic void ate_rxfilter(struct ate_softc *sc); 227155324Simp 228213496Scognetstatic int ate_miibus_readreg(device_t dev, int phy, int reg); 229213496Scognet 230213496Scognetstatic int ate_miibus_writereg(device_t dev, int phy, int reg, int data); 231155324Simp/* 232213496Scognet * The AT91 family of products has the ethernet interface called EMAC. 233213496Scognet * However, it isn't self identifying. It is anticipated that the parent bus 234155324Simp * code will take care to only add ate devices where they really are. As 235155324Simp * such, we do nothing here to identify the device and just set its name. 236155324Simp */ 237155324Simpstatic int 238155324Simpate_probe(device_t dev) 239155324Simp{ 240266196Sian#ifdef FDT 241266196Sian if (!ofw_bus_is_compatible(dev, "cdns,at32ap7000-macb")) 242266196Sian return (ENXIO); 243266196Sian#endif 244155324Simp device_set_desc(dev, "EMAC"); 245155324Simp return (0); 246155324Simp} 247155324Simp 248155324Simpstatic int 249155324Simpate_attach(device_t dev) 250155324Simp{ 251192063Sstas struct ate_softc *sc; 252155324Simp struct ifnet *ifp = NULL; 253163522Simp struct sysctl_ctx_list *sctx; 254163522Simp struct sysctl_oid *soid; 255182477Sstas u_char eaddr[ETHER_ADDR_LEN]; 256182477Sstas uint32_t rnd; 257192018Sstas int rid, err; 258155324Simp 259192063Sstas sc = device_get_softc(dev); 260155324Simp sc->dev = dev; 261192018Sstas ATE_LOCK_INIT(sc); 262234281Smarius 263192018Sstas rid = 0; 264192018Sstas sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 265192018Sstas RF_ACTIVE); 266192018Sstas if (sc->mem_res == NULL) { 267192018Sstas device_printf(dev, "could not allocate memory resources.\n"); 268192018Sstas err = ENOMEM; 269192018Sstas goto out; 270192018Sstas } 271192018Sstas rid = 0; 272192018Sstas sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 273192018Sstas RF_ACTIVE); 274192018Sstas if (sc->irq_res == NULL) { 275192018Sstas device_printf(dev, "could not allocate interrupt resources.\n"); 276192018Sstas err = ENOMEM; 277192018Sstas goto out; 278192018Sstas } 279192018Sstas 280213496Scognet /* New or old version, chooses buffer size. */ 281234291Smarius sc->is_emacb = at91_is_sam9() || at91_is_sam9xe(); 282213496Scognet sc->rx_buf_size = RX_BUF_SIZE(sc); 283213496Scognet 284155324Simp err = ate_activate(dev); 285155324Simp if (err) 286155324Simp goto out; 287155324Simp 288213496Scognet /* Default to what boot rom did */ 289213496Scognet if (!sc->is_emacb) 290213496Scognet sc->use_rmii = 291213496Scognet (RD4(sc, ETH_CFG) & ETH_CFG_RMII) == ETH_CFG_RMII; 292213496Scognet else 293213496Scognet sc->use_rmii = 294213496Scognet (RD4(sc, ETHB_UIO) & ETHB_UIO_RMII) == ETHB_UIO_RMII; 295159708Simp 296213496Scognet#ifdef AT91_ATE_USE_RMII 297213496Scognet /* Compile time override */ 298213496Scognet sc->use_rmii = 1; 299213496Scognet#endif 300182476Sstas /* Sysctls */ 301163522Simp sctx = device_get_sysctl_ctx(dev); 302163522Simp soid = device_get_sysctl_tree(dev); 303163522Simp SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "rmii", 304213496Scognet CTLFLAG_RW, &sc->use_rmii, 0, "rmii in use"); 305163522Simp 306192063Sstas /* Calling atestop before ifp is set is OK. */ 307192018Sstas ATE_LOCK(sc); 308155324Simp atestop(sc); 309192018Sstas ATE_UNLOCK(sc); 310213496Scognet callout_init_mtx(&sc->tick_ch, &sc->sc_mtx, 0); 311155324Simp 312166573Simp if ((err = ate_get_mac(sc, eaddr)) != 0) { 313213496Scognet /* No MAC address configured. Generate the random one. */ 314213496Scognet if (bootverbose) 315182477Sstas device_printf(dev, 316182524Sstas "Generating random ethernet address.\n"); 317182477Sstas rnd = arc4random(); 318182477Sstas 319182477Sstas /* 320182555Simp * Set OUI to convenient locally assigned address. 'b' 321182555Simp * is 0x62, which has the locally assigned bit set, and 322182555Simp * the broadcast/multicast bit clear. 323182477Sstas */ 324182555Simp eaddr[0] = 'b'; 325182555Simp eaddr[1] = 's'; 326182555Simp eaddr[2] = 'd'; 327182477Sstas eaddr[3] = (rnd >> 16) & 0xff; 328213496Scognet eaddr[4] = (rnd >> 8) & 0xff; 329213496Scognet eaddr[5] = (rnd >> 0) & 0xff; 330166573Simp } 331155324Simp 332155405Scognet sc->ifp = ifp = if_alloc(IFT_ETHER); 333213894Smarius err = mii_attach(dev, &sc->miibus, ifp, ate_ifmedia_upd, 334213894Smarius ate_ifmedia_sts, BMSR_DEFCAPMASK, MII_PHY_ANY, MII_OFFSET_ANY, 0); 335213894Smarius if (err != 0) { 336213894Smarius device_printf(dev, "attaching PHYs failed\n"); 337155324Simp goto out; 338155324Simp } 339213496Scognet /* 340234281Smarius * XXX: Clear the isolate bit, or we won't get up, 341234281Smarius * at least on the HL201 342213496Scognet */ 343213496Scognet ate_miibus_writereg(dev, 0, 0, 0x3000); 344155324Simp 345155324Simp ifp->if_softc = sc; 346155324Simp if_initname(ifp, device_get_name(dev), device_get_unit(dev)); 347155324Simp ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 348165779Sticso ifp->if_capabilities |= IFCAP_VLAN_MTU; 349192063Sstas ifp->if_capenable |= IFCAP_VLAN_MTU; /* The hw bits already set. */ 350155324Simp ifp->if_start = atestart; 351155324Simp ifp->if_ioctl = ateioctl; 352155324Simp ifp->if_init = ateinit; 353155324Simp ifp->if_baudrate = 10000000; 354213496Scognet IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); 355213496Scognet ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN; 356155324Simp IFQ_SET_READY(&ifp->if_snd); 357155324Simp ifp->if_linkmib = &sc->mibdata; 358155324Simp ifp->if_linkmiblen = sizeof(sc->mibdata); 359155324Simp sc->mibdata.dot3Compliance = DOT3COMPLIANCE_COLLS; 360191959Sstas sc->if_flags = ifp->if_flags; 361155324Simp 362155324Simp ether_ifattach(ifp, eaddr); 363155324Simp 364213496Scognet /* Activate the interrupt. */ 365155324Simp err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET | INTR_MPSAFE, 366166901Spiso NULL, ate_intr, sc, &sc->intrhand); 367155324Simp if (err) { 368192018Sstas device_printf(dev, "could not establish interrupt handler.\n"); 369155324Simp ether_ifdetach(ifp); 370192018Sstas goto out; 371155324Simp } 372192018Sstas 373192018Sstasout: 374155324Simp if (err) 375192018Sstas ate_detach(dev); 376155324Simp return (err); 377155324Simp} 378155324Simp 379155324Simpstatic int 380155324Simpate_detach(device_t dev) 381155324Simp{ 382192018Sstas struct ate_softc *sc; 383192018Sstas struct ifnet *ifp; 384192018Sstas 385192018Sstas sc = device_get_softc(dev); 386192018Sstas KASSERT(sc != NULL, ("[ate: %d]: sc is NULL", __LINE__)); 387192018Sstas ifp = sc->ifp; 388192018Sstas if (device_is_attached(dev)) { 389192018Sstas ATE_LOCK(sc); 390213496Scognet sc->flags |= ATE_FLAG_DETACHING; 391213496Scognet atestop(sc); 392192018Sstas ATE_UNLOCK(sc); 393192018Sstas callout_drain(&sc->tick_ch); 394213496Scognet ether_ifdetach(ifp); 395192018Sstas } 396192018Sstas if (sc->miibus != NULL) { 397192018Sstas device_delete_child(dev, sc->miibus); 398192018Sstas sc->miibus = NULL; 399192018Sstas } 400192018Sstas bus_generic_detach(sc->dev); 401192018Sstas ate_deactivate(sc); 402192018Sstas if (sc->intrhand != NULL) { 403192018Sstas bus_teardown_intr(dev, sc->irq_res, sc->intrhand); 404192018Sstas sc->intrhand = NULL; 405192018Sstas } 406192018Sstas if (ifp != NULL) { 407192018Sstas if_free(ifp); 408192018Sstas sc->ifp = NULL; 409192018Sstas } 410192018Sstas if (sc->mem_res != NULL) { 411192018Sstas bus_release_resource(dev, SYS_RES_IOPORT, 412192018Sstas rman_get_rid(sc->mem_res), sc->mem_res); 413192018Sstas sc->mem_res = NULL; 414192018Sstas } 415192018Sstas if (sc->irq_res != NULL) { 416192018Sstas bus_release_resource(dev, SYS_RES_IRQ, 417192018Sstas rman_get_rid(sc->irq_res), sc->irq_res); 418192018Sstas sc->irq_res = NULL; 419192018Sstas } 420192018Sstas ATE_LOCK_DESTROY(sc); 421192018Sstas return (0); 422155324Simp} 423155324Simp 424155324Simpstatic void 425155324Simpate_getaddr(void *arg, bus_dma_segment_t *segs, int nsegs, int error) 426155324Simp{ 427155324Simp 428155324Simp if (error != 0) 429155324Simp return; 430213496Scognet *(bus_addr_t *)arg = segs[0].ds_addr; 431155324Simp} 432155324Simp 433157562Simpstatic void 434157562Simpate_load_rx_buf(void *arg, bus_dma_segment_t *segs, int nsegs, int error) 435157562Simp{ 436157562Simp struct ate_softc *sc; 437157562Simp 438157562Simp if (error != 0) 439157562Simp return; 440157562Simp sc = (struct ate_softc *)arg; 441157562Simp 442163937Simp bus_dmamap_sync(sc->rx_desc_tag, sc->rx_desc_map, BUS_DMASYNC_PREWRITE); 443213496Scognet sc->rx_descs[sc->rxhead].addr = segs[0].ds_addr; 444213496Scognet sc->rx_descs[sc->rxhead].status = 0; 445163937Simp bus_dmamap_sync(sc->rx_desc_tag, sc->rx_desc_map, BUS_DMASYNC_POSTWRITE); 446157562Simp} 447157562Simp 448218387Sticsostatic uint32_t 449218387Sticsoate_mac_hash(const uint8_t *buf) 450218387Sticso{ 451218387Sticso uint32_t index = 0; 452218387Sticso for (int i = 0; i < 48; i++) { 453218387Sticso index ^= ((buf[i >> 3] >> (i & 7)) & 1) << (i % 6); 454218387Sticso } 455218387Sticso return (index); 456218387Sticso} 457218387Sticso 458155324Simp/* 459213251Sticso * Compute the multicast filter for this device. 460155324Simp */ 461191960Sstasstatic int 462155324Simpate_setmcast(struct ate_softc *sc) 463155324Simp{ 464155324Simp uint32_t index; 465155324Simp uint32_t mcaf[2]; 466155324Simp u_char *af = (u_char *) mcaf; 467155324Simp struct ifmultiaddr *ifma; 468191960Sstas struct ifnet *ifp; 469155324Simp 470191960Sstas ifp = sc->ifp; 471191960Sstas 472191960Sstas if ((ifp->if_flags & IFF_PROMISC) != 0) 473191960Sstas return (0); 474191960Sstas if ((ifp->if_flags & IFF_ALLMULTI) != 0) { 475191960Sstas WR4(sc, ETH_HSL, 0xffffffff); 476191960Sstas WR4(sc, ETH_HSH, 0xffffffff); 477191960Sstas return (1); 478191960Sstas } 479191960Sstas 480213496Scognet /* Compute the multicast hash. */ 481155324Simp mcaf[0] = 0; 482155324Simp mcaf[1] = 0; 483195049Srwatson if_maddr_rlock(ifp); 484191960Sstas TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { 485155324Simp if (ifma->ifma_addr->sa_family != AF_LINK) 486155324Simp continue; 487218387Sticso index = ate_mac_hash(LLADDR((struct sockaddr_dl *) 488218387Sticso ifma->ifma_addr)); 489155324Simp af[index >> 3] |= 1 << (index & 7); 490155324Simp } 491195049Srwatson if_maddr_runlock(ifp); 492155324Simp 493155324Simp /* 494155324Simp * Write the hash to the hash register. This card can also 495155324Simp * accept unicast packets as well as multicast packets using this 496155324Simp * register for easier bridging operations, but we don't take 497155324Simp * advantage of that. Locks here are to avoid LOR with the 498195049Srwatson * if_maddr_rlock, but might not be strictly necessary. 499155324Simp */ 500155324Simp WR4(sc, ETH_HSL, mcaf[0]); 501155324Simp WR4(sc, ETH_HSH, mcaf[1]); 502191960Sstas return (mcaf[0] || mcaf[1]); 503155324Simp} 504155324Simp 505155324Simpstatic int 506155324Simpate_activate(device_t dev) 507155324Simp{ 508155324Simp struct ate_softc *sc; 509213496Scognet int i; 510155324Simp 511155324Simp sc = device_get_softc(dev); 512192063Sstas 513213496Scognet /* Allocate DMA tags and maps for TX mbufs */ 514213496Scognet if (bus_dma_tag_create(bus_get_dma_tag(dev), 1, 0, 515183670Simp BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES, 516213496Scognet 1, MCLBYTES, 0, busdma_lock_mutex, &sc->sc_mtx, &sc->mtag)) 517155324Simp goto errout; 518155324Simp for (i = 0; i < ATE_MAX_TX_BUFFERS; i++) { 519213496Scognet if ( bus_dmamap_create(sc->mtag, 0, &sc->tx_map[i])) 520155324Simp goto errout; 521155324Simp } 522192063Sstas 523155324Simp 524213496Scognet /* DMA tag and map for the RX descriptors. */ 525213496Scognet if (bus_dma_tag_create(bus_get_dma_tag(dev), sizeof(eth_rx_desc_t), 526183670Simp 0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, 527213496Scognet ATE_NUM_RX_DESCR * sizeof(eth_rx_desc_t), 1, 528213496Scognet ATE_NUM_RX_DESCR * sizeof(eth_rx_desc_t), 0, busdma_lock_mutex, 529213496Scognet &sc->sc_mtx, &sc->rx_desc_tag)) 530155324Simp goto errout; 531156831Simp if (bus_dmamem_alloc(sc->rx_desc_tag, (void **)&sc->rx_descs, 532156831Simp BUS_DMA_NOWAIT | BUS_DMA_COHERENT, &sc->rx_desc_map) != 0) 533155324Simp goto errout; 534157562Simp if (bus_dmamap_load(sc->rx_desc_tag, sc->rx_desc_map, 535213496Scognet sc->rx_descs, ATE_NUM_RX_DESCR * sizeof(eth_rx_desc_t), 536213496Scognet ate_getaddr, &sc->rx_desc_phys, 0) != 0) 537155324Simp goto errout; 538192063Sstas 539213496Scognet /* Allocate DMA tags and maps for RX. buffers */ 540213496Scognet if (bus_dma_tag_create(bus_get_dma_tag(dev), 1, 0, 541213496Scognet BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, 542213496Scognet sc->rx_buf_size, 1, sc->rx_buf_size, 0, 543213496Scognet busdma_lock_mutex, &sc->sc_mtx, &sc->rx_tag)) 544213496Scognet goto errout; 545213496Scognet 546192063Sstas /* 547213496Scognet * Allocate our RX buffers. 548213496Scognet * This chip has a RX structure that's filled in. 549213496Scognet * XXX On MACB (SAM9 part) we should receive directly into mbuf 550213496Scognet * to avoid the copy. XXX 551192063Sstas */ 552213496Scognet sc->rxhead = 0; 553213496Scognet for (sc->rxhead = 0; sc->rxhead < ATE_RX_MEMORY/sc->rx_buf_size; 554213496Scognet sc->rxhead++) { 555213496Scognet if (bus_dmamem_alloc(sc->rx_tag, 556213496Scognet (void **)&sc->rx_buf[sc->rxhead], BUS_DMA_NOWAIT, 557213496Scognet &sc->rx_map[sc->rxhead]) != 0) 558155324Simp goto errout; 559213496Scognet 560213496Scognet if (bus_dmamap_load(sc->rx_tag, sc->rx_map[sc->rxhead], 561213496Scognet sc->rx_buf[sc->rxhead], sc->rx_buf_size, 562213496Scognet ate_load_rx_buf, sc, 0) != 0) { 563213496Scognet printf("bus_dmamem_load\n"); 564157562Simp goto errout; 565213496Scognet } 566213496Scognet bus_dmamap_sync(sc->rx_tag, sc->rx_map[sc->rxhead], BUS_DMASYNC_PREREAD); 567155324Simp } 568213496Scognet 569213496Scognet /* 570213496Scognet * For the last buffer, set the wrap bit so the controller 571213496Scognet * restarts from the first descriptor. 572213496Scognet */ 573213496Scognet sc->rx_descs[--sc->rxhead].addr |= ETH_WRAP_BIT; 574213496Scognet sc->rxhead = 0; 575213496Scognet 576192063Sstas /* Flush the memory for the EMAC rx descriptor. */ 577155324Simp bus_dmamap_sync(sc->rx_desc_tag, sc->rx_desc_map, BUS_DMASYNC_PREWRITE); 578213496Scognet 579155324Simp /* Write the descriptor queue address. */ 580155324Simp WR4(sc, ETH_RBQP, sc->rx_desc_phys); 581213496Scognet 582213496Scognet /* 583213496Scognet * DMA tag and map for the TX descriptors. 584213496Scognet */ 585213496Scognet if (bus_dma_tag_create(bus_get_dma_tag(dev), sizeof(eth_tx_desc_t), 586213496Scognet 0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, 587213496Scognet ATE_MAX_TX_BUFFERS * sizeof(eth_tx_desc_t), 1, 588213496Scognet ATE_MAX_TX_BUFFERS * sizeof(eth_tx_desc_t), 0, busdma_lock_mutex, 589213496Scognet &sc->sc_mtx, &sc->tx_desc_tag) != 0) 590213496Scognet goto errout; 591213496Scognet 592213496Scognet if (bus_dmamem_alloc(sc->tx_desc_tag, (void **)&sc->tx_descs, 593213496Scognet BUS_DMA_NOWAIT | BUS_DMA_COHERENT, &sc->tx_desc_map) != 0) 594213496Scognet goto errout; 595213496Scognet 596213496Scognet if (bus_dmamap_load(sc->tx_desc_tag, sc->tx_desc_map, 597213496Scognet sc->tx_descs, ATE_MAX_TX_BUFFERS * sizeof(eth_tx_desc_t), 598213496Scognet ate_getaddr, &sc->tx_desc_phys, 0) != 0) 599213496Scognet goto errout; 600213496Scognet 601213496Scognet /* Initilize descriptors; mark all empty */ 602213496Scognet for (i = 0; i < ATE_MAX_TX_BUFFERS; i++) { 603213496Scognet sc->tx_descs[i].addr =0; 604213496Scognet sc->tx_descs[i].status = ETHB_TX_USED; 605213496Scognet sc->sent_mbuf[i] = NULL; 606213496Scognet } 607213496Scognet 608213496Scognet /* Mark last entry to cause wrap when indexing through */ 609213496Scognet sc->tx_descs[ATE_MAX_TX_BUFFERS - 1].status = 610213496Scognet ETHB_TX_WRAP | ETHB_TX_USED; 611213496Scognet 612213496Scognet /* Flush the memory for the EMAC tx descriptor. */ 613213496Scognet bus_dmamap_sync(sc->tx_desc_tag, sc->tx_desc_map, BUS_DMASYNC_PREWRITE); 614213496Scognet 615213496Scognet sc->txhead = sc->txtail = 0; 616213496Scognet if (sc->is_emacb) { 617213496Scognet /* Write the descriptor queue address. */ 618213496Scognet WR4(sc, ETHB_TBQP, sc->tx_desc_phys); 619213496Scognet 620238895Simp /* EMACB: Enable transceiver input clock */ 621213496Scognet WR4(sc, ETHB_UIO, RD4(sc, ETHB_UIO) | ETHB_UIO_CLKE); 622238895Simp } 623213496Scognet 624155324Simp return (0); 625192018Sstas 626155324Simperrout: 627155324Simp return (ENOMEM); 628155324Simp} 629155324Simp 630155324Simpstatic void 631192018Sstasate_deactivate(struct ate_softc *sc) 632155324Simp{ 633192018Sstas int i; 634155324Simp 635192018Sstas KASSERT(sc != NULL, ("[ate, %d]: sc is NULL!", __LINE__)); 636192018Sstas if (sc->mtag != NULL) { 637192018Sstas for (i = 0; i < ATE_MAX_TX_BUFFERS; i++) { 638192018Sstas if (sc->sent_mbuf[i] != NULL) { 639192018Sstas bus_dmamap_sync(sc->mtag, sc->tx_map[i], 640192018Sstas BUS_DMASYNC_POSTWRITE); 641192018Sstas bus_dmamap_unload(sc->mtag, sc->tx_map[i]); 642192018Sstas m_freem(sc->sent_mbuf[i]); 643155324Simp } 644192018Sstas bus_dmamap_destroy(sc->mtag, sc->tx_map[i]); 645192018Sstas sc->sent_mbuf[i] = NULL; 646192018Sstas sc->tx_map[i] = NULL; 647155324Simp } 648192018Sstas bus_dma_tag_destroy(sc->mtag); 649192018Sstas } 650192018Sstas if (sc->rx_desc_tag != NULL) { 651192018Sstas if (sc->rx_descs != NULL) { 652192018Sstas if (sc->rx_desc_phys != 0) { 653192018Sstas bus_dmamap_sync(sc->rx_desc_tag, 654192018Sstas sc->rx_desc_map, BUS_DMASYNC_POSTREAD); 655192018Sstas bus_dmamap_unload(sc->rx_desc_tag, 656192018Sstas sc->rx_desc_map); 657192018Sstas sc->rx_desc_phys = 0; 658155324Simp } 659155324Simp } 660155324Simp } 661213496Scognet if (sc->rx_tag != NULL) { 662213496Scognet for (i = 0; sc->rx_buf[i] != NULL; i++) { 663213496Scognet if (sc->rx_descs[i].addr != 0) { 664213496Scognet bus_dmamap_sync(sc->rx_tag, 665213496Scognet sc->rx_map[i], 666213496Scognet BUS_DMASYNC_POSTREAD); 667213496Scognet bus_dmamap_unload(sc->rx_tag, 668192018Sstas sc->rx_map[i]); 669213496Scognet sc->rx_descs[i].addr = 0; 670192018Sstas } 671213496Scognet bus_dmamem_free(sc->rx_tag, sc->rx_buf[i], 672213496Scognet sc->rx_map[i]); 673213496Scognet sc->rx_buf[i] = NULL; 674213496Scognet sc->rx_map[i] = NULL; 675192018Sstas } 676213496Scognet bus_dma_tag_destroy(sc->rx_tag); 677192018Sstas } 678192018Sstas if (sc->rx_desc_tag != NULL) { 679192018Sstas if (sc->rx_descs != NULL) 680192018Sstas bus_dmamem_free(sc->rx_desc_tag, sc->rx_descs, 681192018Sstas sc->rx_desc_map); 682192018Sstas bus_dma_tag_destroy(sc->rx_desc_tag); 683192018Sstas sc->rx_descs = NULL; 684192018Sstas sc->rx_desc_tag = NULL; 685192018Sstas } 686213496Scognet 687213496Scognet if (sc->is_emacb) 688238895Simp WR4(sc, ETHB_UIO, RD4(sc, ETHB_UIO) & ~ETHB_UIO_CLKE); 689155324Simp} 690155324Simp 691155324Simp/* 692155324Simp * Change media according to request. 693155324Simp */ 694155324Simpstatic int 695155324Simpate_ifmedia_upd(struct ifnet *ifp) 696155324Simp{ 697155324Simp struct ate_softc *sc = ifp->if_softc; 698155324Simp struct mii_data *mii; 699155324Simp 700155324Simp mii = device_get_softc(sc->miibus); 701155324Simp ATE_LOCK(sc); 702155324Simp mii_mediachg(mii); 703155324Simp ATE_UNLOCK(sc); 704155324Simp return (0); 705155324Simp} 706155324Simp 707155324Simp/* 708155324Simp * Notify the world which media we're using. 709155324Simp */ 710155324Simpstatic void 711155324Simpate_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) 712155324Simp{ 713155324Simp struct ate_softc *sc = ifp->if_softc; 714155324Simp struct mii_data *mii; 715155324Simp 716155324Simp mii = device_get_softc(sc->miibus); 717155324Simp ATE_LOCK(sc); 718155324Simp mii_pollstat(mii); 719155324Simp ifmr->ifm_active = mii->mii_media_active; 720155324Simp ifmr->ifm_status = mii->mii_media_status; 721155324Simp ATE_UNLOCK(sc); 722155324Simp} 723155324Simp 724155324Simpstatic void 725163937Simpate_stat_update(struct ate_softc *sc, int active) 726163937Simp{ 727192027Sstas uint32_t reg; 728192027Sstas 729163937Simp /* 730163937Simp * The speed and full/half-duplex state needs to be reflected 731163937Simp * in the ETH_CFG register. 732163937Simp */ 733192027Sstas reg = RD4(sc, ETH_CFG); 734192027Sstas reg &= ~(ETH_CFG_SPD | ETH_CFG_FD); 735192027Sstas if (IFM_SUBTYPE(active) != IFM_10_T) 736192027Sstas reg |= ETH_CFG_SPD; 737163937Simp if (active & IFM_FDX) 738192027Sstas reg |= ETH_CFG_FD; 739192027Sstas WR4(sc, ETH_CFG, reg); 740163937Simp} 741163937Simp 742163937Simpstatic void 743155324Simpate_tick(void *xsc) 744155324Simp{ 745155324Simp struct ate_softc *sc = xsc; 746163937Simp struct ifnet *ifp = sc->ifp; 747155324Simp struct mii_data *mii; 748155324Simp int active; 749163937Simp uint32_t c; 750155324Simp 751155324Simp /* 752155324Simp * The KB920x boot loader tests ETH_SR & ETH_SR_LINK and will ask 753155324Simp * the MII if there's a link if this bit is clear. Not sure if we 754155324Simp * should do the same thing here or not. 755155324Simp */ 756155324Simp ATE_ASSERT_LOCKED(sc); 757155324Simp if (sc->miibus != NULL) { 758155324Simp mii = device_get_softc(sc->miibus); 759155324Simp active = mii->mii_media_active; 760155324Simp mii_tick(mii); 761155324Simp if (mii->mii_media_status & IFM_ACTIVE && 762234281Smarius active != mii->mii_media_active) 763163937Simp ate_stat_update(sc, mii->mii_media_active); 764155324Simp } 765155324Simp 766155324Simp /* 767155324Simp * Update the stats as best we can. When we're done, clear 768155324Simp * the status counters and start over. We're supposed to read these 769155324Simp * registers often enough that they won't overflow. Hopefully 770155324Simp * once a second is often enough. Some don't map well to 771155324Simp * the dot3Stats mib, so for those we just count them as general 772155324Simp * errors. Stats for iframes, ibutes, oframes and obytes are 773155324Simp * collected elsewhere. These registers zero on a read to prevent 774163937Simp * races. For all the collision stats, also update the collision 775163937Simp * stats for the interface. 776155324Simp */ 777155324Simp sc->mibdata.dot3StatsAlignmentErrors += RD4(sc, ETH_ALE); 778155324Simp sc->mibdata.dot3StatsFCSErrors += RD4(sc, ETH_SEQE); 779163937Simp c = RD4(sc, ETH_SCOL); 780163937Simp ifp->if_collisions += c; 781163937Simp sc->mibdata.dot3StatsSingleCollisionFrames += c; 782163937Simp c = RD4(sc, ETH_MCOL); 783163937Simp sc->mibdata.dot3StatsMultipleCollisionFrames += c; 784163937Simp ifp->if_collisions += c; 785155324Simp sc->mibdata.dot3StatsSQETestErrors += RD4(sc, ETH_SQEE); 786155324Simp sc->mibdata.dot3StatsDeferredTransmissions += RD4(sc, ETH_DTE); 787163937Simp c = RD4(sc, ETH_LCOL); 788163937Simp sc->mibdata.dot3StatsLateCollisions += c; 789163937Simp ifp->if_collisions += c; 790163937Simp c = RD4(sc, ETH_ECOL); 791163937Simp sc->mibdata.dot3StatsExcessiveCollisions += c; 792163937Simp ifp->if_collisions += c; 793155324Simp sc->mibdata.dot3StatsCarrierSenseErrors += RD4(sc, ETH_CSE); 794155324Simp sc->mibdata.dot3StatsFrameTooLongs += RD4(sc, ETH_ELR); 795155324Simp sc->mibdata.dot3StatsInternalMacReceiveErrors += RD4(sc, ETH_DRFC); 796192063Sstas 797155324Simp /* 798192063Sstas * Not sure where to lump these, so count them against the errors 799155324Simp * for the interface. 800155324Simp */ 801163937Simp sc->ifp->if_oerrors += RD4(sc, ETH_TUE); 802155324Simp sc->ifp->if_ierrors += RD4(sc, ETH_CDE) + RD4(sc, ETH_RJB) + 803155324Simp RD4(sc, ETH_USF); 804155324Simp 805213496Scognet /* Schedule another timeout one second from now. */ 806155324Simp callout_reset(&sc->tick_ch, hz, ate_tick, sc); 807155324Simp} 808155324Simp 809155324Simpstatic void 810155445Scognetate_set_mac(struct ate_softc *sc, u_char *eaddr) 811155445Scognet{ 812192063Sstas 813155445Scognet WR4(sc, ETH_SA1L, (eaddr[3] << 24) | (eaddr[2] << 16) | 814155445Scognet (eaddr[1] << 8) | eaddr[0]); 815155445Scognet WR4(sc, ETH_SA1H, (eaddr[5] << 8) | (eaddr[4])); 816155445Scognet} 817155445Scognet 818166573Simpstatic int 819155324Simpate_get_mac(struct ate_softc *sc, u_char *eaddr) 820155324Simp{ 821182477Sstas bus_size_t sa_low_reg[] = { ETH_SA1L, ETH_SA2L, ETH_SA3L, ETH_SA4L }; 822182477Sstas bus_size_t sa_high_reg[] = { ETH_SA1H, ETH_SA2H, ETH_SA3H, ETH_SA4H }; 823166573Simp uint32_t low, high; 824182477Sstas int i; 825155324Simp 826166573Simp /* 827213496Scognet * The boot loader may setup the MAC with an address(es), grab the 828213496Scognet * first MAC address from the SA[1-4][HL] registers. 829166573Simp */ 830182477Sstas for (i = 0; i < 4; i++) { 831182477Sstas low = RD4(sc, sa_low_reg[i]); 832182477Sstas high = RD4(sc, sa_high_reg[i]); 833182477Sstas if ((low | (high & 0xffff)) != 0) { 834182477Sstas eaddr[0] = low & 0xff; 835182477Sstas eaddr[1] = (low >> 8) & 0xff; 836182477Sstas eaddr[2] = (low >> 16) & 0xff; 837182477Sstas eaddr[3] = (low >> 24) & 0xff; 838182477Sstas eaddr[4] = high & 0xff; 839182477Sstas eaddr[5] = (high >> 8) & 0xff; 840182477Sstas return (0); 841182477Sstas } 842182477Sstas } 843182477Sstas return (ENXIO); 844155324Simp} 845155324Simp 846155324Simpstatic void 847155324Simpate_intr(void *xsc) 848155324Simp{ 849155324Simp struct ate_softc *sc = xsc; 850163937Simp struct ifnet *ifp = sc->ifp; 851192027Sstas struct mbuf *mb; 852213496Scognet eth_rx_desc_t *rxdhead; 853213496Scognet uint32_t status, reg, idx; 854213496Scognet int remain, count, done; 855156831Simp 856155324Simp status = RD4(sc, ETH_ISR); 857155324Simp if (status == 0) 858155324Simp return; 859213496Scognet 860155324Simp if (status & ETH_ISR_RCOM) { 861238895Simp bus_dmamap_sync(sc->rx_desc_tag, sc->rx_desc_map, 862155324Simp BUS_DMASYNC_POSTREAD); 863213496Scognet 864238895Simp rxdhead = &sc->rx_descs[sc->rxhead]; 865238895Simp while (rxdhead->addr & ETH_CPU_OWNER) { 866213496Scognet if (!sc->is_emacb) { 867213496Scognet /* 868213496Scognet * Simulate SAM9 FIRST/LAST bits for RM9200. 869213496Scognet * RM9200 EMAC has only on Rx buffer per packet. 870213496Scognet * But sometime we are handed a zero lenght packet. 871213496Scognet */ 872213496Scognet if ((rxdhead->status & ETH_LEN_MASK) == 0) 873213496Scognet rxdhead->status = 0; /* Mark error */ 874213496Scognet else 875213496Scognet rxdhead->status |= ETH_BUF_FIRST | ETH_BUF_LAST; 876213496Scognet } 877213496Scognet 878213496Scognet if ((rxdhead->status & ETH_BUF_FIRST) == 0) { 879213496Scognet /* Something went wrong during RX so 880213496Scognet release back to EMAC all buffers of invalid packets. 881213496Scognet */ 882213496Scognet rxdhead->status = 0; 883213496Scognet rxdhead->addr &= ~ETH_CPU_OWNER; 884213496Scognet sc->rxhead = NEXT_RX_IDX(sc, sc->rxhead); 885213496Scognet rxdhead = &sc->rx_descs[sc->rxhead]; 886156831Simp continue; 887155324Simp } 888163937Simp 889213496Scognet /* Find end of packet or start of next */ 890213496Scognet idx = sc->rxhead; 891213496Scognet if ((sc->rx_descs[idx].status & ETH_BUF_LAST) == 0) { 892213496Scognet idx = NEXT_RX_IDX(sc, idx); 893213496Scognet 894213496Scognet while ((sc->rx_descs[idx].addr & ETH_CPU_OWNER) && 895213496Scognet ((sc->rx_descs[idx].status & 896213496Scognet (ETH_BUF_FIRST|ETH_BUF_LAST))== 0)) 897213496Scognet idx = NEXT_RX_IDX(sc, idx); 898213496Scognet } 899213496Scognet 900213496Scognet /* Packet NOT yet completely in memory; we are done */ 901213496Scognet if ((sc->rx_descs[idx].addr & ETH_CPU_OWNER) == 0 || 902213496Scognet ((sc->rx_descs[idx].status & (ETH_BUF_FIRST|ETH_BUF_LAST))== 0)) 903213496Scognet break; 904213496Scognet 905213496Scognet /* Packets with no end descriptor are invalid. */ 906213496Scognet if ((sc->rx_descs[idx].status & ETH_BUF_LAST) == 0) { 907213496Scognet rxdhead->status &= ~ETH_BUF_FIRST; 908213496Scognet continue; 909213496Scognet } 910213496Scognet 911213496Scognet /* FCS is not coppied into mbuf. */ 912213496Scognet remain = (sc->rx_descs[idx].status & ETH_LEN_MASK) - 4; 913213496Scognet 914248189Sglebius /* Get an appropriately sized mbuf. */ 915248207Sglebius mb = m_get2(remain + ETHER_ALIGN, M_NOWAIT, MT_DATA, 916248207Sglebius M_PKTHDR); 917213496Scognet if (mb == NULL) { 918213496Scognet sc->ifp->if_iqdrops++; 919213496Scognet rxdhead->status = 0; 920213496Scognet continue; 921213496Scognet } 922213496Scognet mb->m_data += ETHER_ALIGN; 923213496Scognet mb->m_pkthdr.rcvif = ifp; 924213496Scognet 925213496Scognet WR4(sc, ETH_RSR, RD4(sc, ETH_RSR)); /* Reset status */ 926213496Scognet 927213496Scognet /* Now we process the buffers that make up the packet */ 928213496Scognet do { 929213496Scognet 930213496Scognet /* Last buffer may just be 1-4 bytes of FCS so remain 931213496Scognet * may be zero for last decriptor. */ 932213496Scognet if (remain > 0) { 933213496Scognet /* Make sure we get the current bytes */ 934213496Scognet bus_dmamap_sync(sc->rx_tag, sc->rx_map[sc->rxhead], 935213496Scognet BUS_DMASYNC_POSTREAD); 936213496Scognet 937213496Scognet count = MIN(remain, sc->rx_buf_size); 938213496Scognet 939213496Scognet /* XXX Performance robbing copy. Could 940213496Scognet * recieve directly to mbufs if not an 941238895Simp * RM9200. And even then we could likely 942238895Simp * copy just the protocol headers. XXX */ 943213496Scognet m_append(mb, count, sc->rx_buf[sc->rxhead]); 944213496Scognet remain -= count; 945213496Scognet } 946213496Scognet 947213496Scognet done = (rxdhead->status & ETH_BUF_LAST) != 0; 948213496Scognet 949213496Scognet /* Return the descriptor to the EMAC */ 950213496Scognet rxdhead->status = 0; 951213496Scognet rxdhead->addr &= ~ETH_CPU_OWNER; 952213496Scognet bus_dmamap_sync(sc->rx_desc_tag, sc->rx_desc_map, 953213496Scognet BUS_DMASYNC_PREWRITE); 954213496Scognet 955213496Scognet /* Move on to next descriptor with wrap */ 956213496Scognet sc->rxhead = NEXT_RX_IDX(sc, sc->rxhead); 957213496Scognet rxdhead = &sc->rx_descs[sc->rxhead]; 958213496Scognet 959213496Scognet } while (!done); 960213496Scognet 961259381Sian ifp->if_ipackets++; 962259381Sian (*ifp->if_input)(ifp, mb); 963155324Simp } 964155324Simp } 965213496Scognet 966213496Scognet 967155324Simp if (status & ETH_ISR_TCOM) { 968213496Scognet bus_dmamap_sync(sc->tx_desc_tag, sc->tx_desc_map, 969213496Scognet BUS_DMASYNC_POSTREAD); 970213496Scognet 971156831Simp ATE_LOCK(sc); 972163937Simp /* XXX TSR register should be cleared */ 973234281Smarius if (!sc->is_emacb) { 974213496Scognet /* Simulate Transmit descriptor table */ 975213496Scognet 976213496Scognet /* First packet done */ 977213496Scognet if (sc->txtail < sc->txhead) 978213496Scognet sc->tx_descs[sc->txtail].status |= ETHB_TX_USED; 979213496Scognet 980213496Scognet /* Second Packet done */ 981213496Scognet if (sc->txtail + 1 < sc->txhead && 982213496Scognet RD4(sc, ETH_TSR) & ETH_TSR_IDLE) 983213496Scognet sc->tx_descs[sc->txtail + 1].status |= ETHB_TX_USED; 984213496Scognet } 985213496Scognet 986259381Sian while ((sc->tx_descs[sc->txtail].status & ETHB_TX_USED) && 987259381Sian sc->sent_mbuf[sc->txtail] != NULL) { 988213496Scognet bus_dmamap_sync(sc->mtag, sc->tx_map[sc->txtail], 989163937Simp BUS_DMASYNC_POSTWRITE); 990213496Scognet bus_dmamap_unload(sc->mtag, sc->tx_map[sc->txtail]); 991213496Scognet m_freem(sc->sent_mbuf[sc->txtail]); 992213496Scognet sc->tx_descs[sc->txtail].addr = 0; 993213496Scognet sc->sent_mbuf[sc->txtail] = NULL; 994163937Simp ifp->if_opackets++; 995213496Scognet sc->txtail = NEXT_TX_IDX(sc, sc->txtail); 996156831Simp } 997213496Scognet 998213496Scognet /* Flush descriptors to EMAC */ 999213496Scognet bus_dmamap_sync(sc->tx_desc_tag, sc->tx_desc_map, BUS_DMASYNC_PREWRITE); 1000213496Scognet 1001156831Simp /* 1002156831Simp * We're no longer busy, so clear the busy flag and call the 1003156831Simp * start routine to xmit more packets. 1004156831Simp */ 1005156831Simp sc->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 1006156831Simp atestart_locked(sc->ifp); 1007156831Simp ATE_UNLOCK(sc); 1008155324Simp } 1009213496Scognet 1010155324Simp if (status & ETH_ISR_RBNA) { 1011213496Scognet /* Workaround RM9200 Errata #11 */ 1012192028Sstas if (bootverbose) 1013192028Sstas device_printf(sc->dev, "RBNA workaround\n"); 1014192027Sstas reg = RD4(sc, ETH_CTL); 1015192027Sstas WR4(sc, ETH_CTL, reg & ~ETH_CTL_RE); 1016192027Sstas BARRIER(sc, ETH_CTL, 4, BUS_SPACE_BARRIER_WRITE); 1017192027Sstas WR4(sc, ETH_CTL, reg | ETH_CTL_RE); 1018155324Simp } 1019238895Simp 1020238895Simp /* XXX need to work around SAM9260 errata 43.2.4.1: 1021238895Simp * disable the mac, reset tx buffer, enable mac on TUND */ 1022155324Simp} 1023155324Simp 1024155324Simp/* 1025192063Sstas * Reset and initialize the chip. 1026155324Simp */ 1027155324Simpstatic void 1028155324Simpateinit_locked(void *xsc) 1029155324Simp{ 1030155324Simp struct ate_softc *sc = xsc; 1031155324Simp struct ifnet *ifp = sc->ifp; 1032213496Scognet struct mii_data *mii; 1033192064Sstas uint8_t eaddr[ETHER_ADDR_LEN]; 1034192027Sstas uint32_t reg; 1035155324Simp 1036155324Simp ATE_ASSERT_LOCKED(sc); 1037155324Simp 1038155324Simp /* 1039155324Simp * XXX TODO(3) 1040155324Simp * we need to turn on the EMAC clock in the pmc. With the 1041155324Simp * default boot loader, this is already turned on. However, we 1042155324Simp * need to think about how best to turn it on/off as the interface 1043155324Simp * is brought up/down, as well as dealing with the mii bus... 1044155324Simp * 1045213496Scognet * We also need to multiplex the pins correctly (in board_xxx.c). 1046155324Simp */ 1047155324Simp 1048155324Simp /* 1049155324Simp * There are two different ways that the mii bus is connected 1050213496Scognet * to this chip mii or rmii. 1051155324Simp */ 1052213496Scognet if (!sc->is_emacb) { 1053213496Scognet /* RM9200 */ 1054213496Scognet reg = RD4(sc, ETH_CFG); 1055213496Scognet if (sc->use_rmii) 1056213496Scognet reg |= ETH_CFG_RMII; 1057213496Scognet else 1058213496Scognet reg &= ~ETH_CFG_RMII; 1059213496Scognet WR4(sc, ETH_CFG, reg); 1060213496Scognet } else { 1061213496Scognet /* SAM9 */ 1062213496Scognet reg = ETHB_UIO_CLKE; 1063234281Smarius reg |= (sc->use_rmii) ? ETHB_UIO_RMII : 0; 1064213496Scognet WR4(sc, ETHB_UIO, reg); 1065213496Scognet } 1066159708Simp 1067191960Sstas ate_rxfilter(sc); 1068191960Sstas 1069191960Sstas /* 1070192064Sstas * Set the chip MAC address. 1071192064Sstas */ 1072192064Sstas bcopy(IF_LLADDR(ifp), eaddr, ETHER_ADDR_LEN); 1073192064Sstas ate_set_mac(sc, eaddr); 1074192064Sstas 1075213496Scognet /* Make sure we know state of TX queue */ 1076213496Scognet sc->txhead = sc->txtail = 0; 1077213496Scognet if (sc->is_emacb) { 1078213496Scognet /* Write the descriptor queue address. */ 1079213496Scognet WR4(sc, ETHB_TBQP, sc->tx_desc_phys); 1080213496Scognet } 1081213496Scognet 1082192064Sstas /* 1083191960Sstas * Turn on MACs and interrupt processing. 1084191960Sstas */ 1085155324Simp WR4(sc, ETH_CTL, RD4(sc, ETH_CTL) | ETH_CTL_TE | ETH_CTL_RE); 1086156831Simp WR4(sc, ETH_IER, ETH_ISR_RCOM | ETH_ISR_TCOM | ETH_ISR_RBNA); 1087155324Simp 1088192063Sstas /* Enable big packets. */ 1089165779Sticso WR4(sc, ETH_CFG, RD4(sc, ETH_CFG) | ETH_CFG_BIG); 1090165779Sticso 1091155324Simp /* 1092155324Simp * Set 'running' flag, and clear output active flag 1093192063Sstas * and attempt to start the output. 1094155324Simp */ 1095155324Simp ifp->if_drv_flags |= IFF_DRV_RUNNING; 1096155324Simp ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 1097163937Simp 1098163937Simp mii = device_get_softc(sc->miibus); 1099163937Simp mii_pollstat(mii); 1100163937Simp ate_stat_update(sc, mii->mii_media_active); 1101155324Simp atestart_locked(ifp); 1102155324Simp 1103155324Simp callout_reset(&sc->tick_ch, hz, ate_tick, sc); 1104155324Simp} 1105155324Simp 1106155324Simp/* 1107192063Sstas * Dequeue packets and transmit. 1108155324Simp */ 1109155324Simpstatic void 1110155324Simpatestart_locked(struct ifnet *ifp) 1111155324Simp{ 1112155324Simp struct ate_softc *sc = ifp->if_softc; 1113155324Simp struct mbuf *m, *mdefrag; 1114155324Simp bus_dma_segment_t segs[1]; 1115163937Simp int nseg, e; 1116155324Simp 1117155324Simp ATE_ASSERT_LOCKED(sc); 1118155324Simp if (ifp->if_drv_flags & IFF_DRV_OACTIVE) 1119155324Simp return; 1120155324Simp 1121213496Scognet while (sc->tx_descs[sc->txhead].status & ETHB_TX_USED) { 1122156831Simp /* 1123192063Sstas * Check to see if there's room to put another packet into the 1124213496Scognet * xmit queue. The old EMAC version has a ping-pong buffer for 1125213496Scognet * xmit packets. We use OACTIVE to indicate "we can stuff more 1126213496Scognet * into our buffers (clear) or not (set)." 1127156831Simp */ 1128259381Sian /* RM9200 has only two hardware entries */ 1129259381Sian if (!sc->is_emacb && (RD4(sc, ETH_TSR) & ETH_TSR_BNQ) == 0) { 1130259381Sian ifp->if_drv_flags |= IFF_DRV_OACTIVE; 1131259381Sian return; 1132156831Simp } 1133213496Scognet 1134156831Simp IFQ_DRV_DEQUEUE(&ifp->if_snd, m); 1135213496Scognet if (m == 0) 1136213496Scognet break; 1137213496Scognet 1138213496Scognet e = bus_dmamap_load_mbuf_sg(sc->mtag, sc->tx_map[sc->txhead], m, 1139163937Simp segs, &nseg, 0); 1140163937Simp if (e == EFBIG) { 1141243882Sglebius mdefrag = m_defrag(m, M_NOWAIT); 1142163937Simp if (mdefrag == NULL) { 1143163937Simp IFQ_DRV_PREPEND(&ifp->if_snd, m); 1144163937Simp return; 1145163937Simp } 1146163937Simp m = mdefrag; 1147163937Simp e = bus_dmamap_load_mbuf_sg(sc->mtag, 1148213496Scognet sc->tx_map[sc->txhead], m, segs, &nseg, 0); 1149156831Simp } 1150163937Simp if (e != 0) { 1151156831Simp m_freem(m); 1152156831Simp continue; 1153156831Simp } 1154259381Sian 1155259381Sian /* 1156259381Sian * There's a small race between the loop in ate_intr finishing 1157259381Sian * and the check above to see if the packet was finished, as well 1158259381Sian * as when atestart gets called via other paths. Lose the race 1159259381Sian * gracefully and free the mbuf... 1160259381Sian */ 1161259381Sian if (sc->sent_mbuf[sc->txhead] != NULL) { 1162259381Sian bus_dmamap_sync(sc->mtag, sc->tx_map[sc->txtail], 1163259381Sian BUS_DMASYNC_POSTWRITE); 1164259381Sian bus_dmamap_unload(sc->mtag, sc->tx_map[sc->txtail]); 1165259381Sian m_free(sc->sent_mbuf[sc->txhead]); 1166259381Sian ifp->if_opackets++; 1167259381Sian } 1168259381Sian 1169213496Scognet sc->sent_mbuf[sc->txhead] = m; 1170213496Scognet 1171213496Scognet bus_dmamap_sync(sc->mtag, sc->tx_map[sc->txhead], 1172156831Simp BUS_DMASYNC_PREWRITE); 1173155324Simp 1174213496Scognet /* Tell the hardware to xmit the packet. */ 1175213496Scognet if (!sc->is_emacb) { 1176213496Scognet WR4(sc, ETH_TAR, segs[0].ds_addr); 1177213496Scognet BARRIER(sc, ETH_TAR, 4, BUS_SPACE_BARRIER_WRITE); 1178213496Scognet WR4(sc, ETH_TCR, segs[0].ds_len); 1179213496Scognet } else { 1180213496Scognet bus_dmamap_sync(sc->tx_desc_tag, sc->tx_desc_map, 1181213496Scognet BUS_DMASYNC_POSTWRITE); 1182213496Scognet sc->tx_descs[sc->txhead].addr = segs[0].ds_addr; 1183213496Scognet sc->tx_descs[sc->txhead].status = segs[0].ds_len | 1184213496Scognet (sc->tx_descs[sc->txhead].status & ETHB_TX_WRAP) | 1185213496Scognet ETHB_TX_BUF_LAST; 1186213496Scognet bus_dmamap_sync(sc->tx_desc_tag, sc->tx_desc_map, 1187213496Scognet BUS_DMASYNC_PREWRITE); 1188213496Scognet WR4(sc, ETH_CTL, RD4(sc, ETH_CTL) | ETHB_CTL_TGO); 1189213496Scognet } 1190213496Scognet sc->txhead = NEXT_TX_IDX(sc, sc->txhead); 1191234281Smarius 1192213496Scognet /* Tap off here if there is a bpf listener. */ 1193156831Simp BPF_MTAP(ifp, m); 1194213496Scognet } 1195155324Simp 1196213496Scognet if ((sc->tx_descs[sc->txhead].status & ETHB_TX_USED) == 0) 1197213496Scognet ifp->if_drv_flags |= IFF_DRV_OACTIVE; 1198155324Simp} 1199155324Simp 1200155324Simpstatic void 1201155324Simpateinit(void *xsc) 1202155324Simp{ 1203155324Simp struct ate_softc *sc = xsc; 1204192063Sstas 1205155324Simp ATE_LOCK(sc); 1206155324Simp ateinit_locked(sc); 1207155324Simp ATE_UNLOCK(sc); 1208155324Simp} 1209155324Simp 1210155324Simpstatic void 1211155324Simpatestart(struct ifnet *ifp) 1212155324Simp{ 1213155324Simp struct ate_softc *sc = ifp->if_softc; 1214192063Sstas 1215155324Simp ATE_LOCK(sc); 1216155324Simp atestart_locked(ifp); 1217155324Simp ATE_UNLOCK(sc); 1218155324Simp} 1219155324Simp 1220155324Simp/* 1221192063Sstas * Turn off interrupts, and stop the NIC. Can be called with sc->ifp NULL, 1222155324Simp * so be careful. 1223155324Simp */ 1224155324Simpstatic void 1225155324Simpatestop(struct ate_softc *sc) 1226155324Simp{ 1227192018Sstas struct ifnet *ifp; 1228192018Sstas int i; 1229155324Simp 1230192018Sstas ATE_ASSERT_LOCKED(sc); 1231192018Sstas ifp = sc->ifp; 1232155324Simp if (ifp) { 1233213496Scognet //ifp->if_timer = 0; 1234155324Simp ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); 1235155324Simp } 1236155324Simp 1237155324Simp callout_stop(&sc->tick_ch); 1238155324Simp 1239155324Simp /* 1240155324Simp * Enable some parts of the MAC that are needed always (like the 1241155324Simp * MII bus. This turns off the RE and TE bits, which will remain 1242155405Scognet * off until ateinit() is called to turn them on. With RE and TE 1243155324Simp * turned off, there's no DMA to worry about after this write. 1244155324Simp */ 1245155324Simp WR4(sc, ETH_CTL, ETH_CTL_MPE); 1246155324Simp 1247155324Simp /* 1248155324Simp * Turn off all the configured options and revert to defaults. 1249155324Simp */ 1250155324Simp 1251213496Scognet /* Make sure thate the MDIO clk is less than 1252213496Scognet * 2.5 Mhz. Can no longer default to /32 since 1253213496Scognet * SAM9 family may have MCK > 80 Mhz */ 1254213496Scognet if (at91_master_clock <= 2000000) 1255213496Scognet WR4(sc, ETH_CFG, ETH_CFG_CLK_8); 1256213496Scognet else if (at91_master_clock <= 4000000) 1257213496Scognet WR4(sc, ETH_CFG, ETH_CFG_CLK_16); 1258213496Scognet else if (at91_master_clock <= 800000) 1259213496Scognet WR4(sc, ETH_CFG, ETH_CFG_CLK_32); 1260213496Scognet else 1261213496Scognet WR4(sc, ETH_CFG, ETH_CFG_CLK_64); 1262213496Scognet 1263155324Simp /* 1264155324Simp * Turn off all the interrupts, and ack any pending ones by reading 1265155324Simp * the ISR. 1266155324Simp */ 1267155324Simp WR4(sc, ETH_IDR, 0xffffffff); 1268155324Simp RD4(sc, ETH_ISR); 1269155324Simp 1270155324Simp /* 1271155324Simp * Clear out the Transmit and Receiver Status registers of any 1272155324Simp * errors they may be reporting 1273155324Simp */ 1274155324Simp WR4(sc, ETH_TSR, 0xffffffff); 1275155324Simp WR4(sc, ETH_RSR, 0xffffffff); 1276155324Simp 1277213496Scognet /* Release TX resources. */ 1278192018Sstas for (i = 0; i < ATE_MAX_TX_BUFFERS; i++) { 1279192018Sstas if (sc->sent_mbuf[i] != NULL) { 1280192018Sstas bus_dmamap_sync(sc->mtag, sc->tx_map[i], 1281192018Sstas BUS_DMASYNC_POSTWRITE); 1282192018Sstas bus_dmamap_unload(sc->mtag, sc->tx_map[i]); 1283192018Sstas m_freem(sc->sent_mbuf[i]); 1284192018Sstas sc->sent_mbuf[i] = NULL; 1285192018Sstas } 1286192018Sstas } 1287155324Simp 1288213496Scognet /* Turn off transeiver input clock */ 1289213496Scognet if (sc->is_emacb) 1290238895Simp WR4(sc, ETHB_UIO, RD4(sc, ETHB_UIO) & ~ETHB_UIO_CLKE); 1291213496Scognet 1292155324Simp /* 1293155324Simp * XXX we should power down the EMAC if it isn't in use, after 1294155324Simp * putting it into loopback mode. This saves about 400uA according 1295155324Simp * to the datasheet. 1296155324Simp */ 1297155324Simp} 1298155324Simp 1299191959Sstasstatic void 1300191959Sstasate_rxfilter(struct ate_softc *sc) 1301191959Sstas{ 1302191959Sstas struct ifnet *ifp; 1303191959Sstas uint32_t reg; 1304191960Sstas int enabled; 1305191959Sstas 1306191959Sstas KASSERT(sc != NULL, ("[ate, %d]: sc is NULL!", __LINE__)); 1307191959Sstas ATE_ASSERT_LOCKED(sc); 1308191959Sstas ifp = sc->ifp; 1309191959Sstas 1310213496Scognet /* Wipe out old filter settings. */ 1311191959Sstas reg = RD4(sc, ETH_CFG); 1312191959Sstas reg &= ~(ETH_CFG_CAF | ETH_CFG_MTI | ETH_CFG_UNI); 1313191959Sstas reg |= ETH_CFG_NBC; 1314191960Sstas sc->flags &= ~ATE_FLAG_MULTICAST; 1315191959Sstas 1316213496Scognet /* Set new parameters. */ 1317191959Sstas if ((ifp->if_flags & IFF_BROADCAST) != 0) 1318191959Sstas reg &= ~ETH_CFG_NBC; 1319191960Sstas if ((ifp->if_flags & IFF_PROMISC) != 0) { 1320191959Sstas reg |= ETH_CFG_CAF; 1321191960Sstas } else { 1322191960Sstas enabled = ate_setmcast(sc); 1323191960Sstas if (enabled != 0) { 1324191960Sstas reg |= ETH_CFG_MTI; 1325191960Sstas sc->flags |= ATE_FLAG_MULTICAST; 1326191960Sstas } 1327191960Sstas } 1328191959Sstas WR4(sc, ETH_CFG, reg); 1329191959Sstas} 1330191959Sstas 1331155324Simpstatic int 1332155324Simpateioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 1333155324Simp{ 1334155324Simp struct ate_softc *sc = ifp->if_softc; 1335213496Scognet struct mii_data *mii; 1336234281Smarius struct ifreq *ifr = (struct ifreq *)data; 1337191959Sstas int drv_flags, flags; 1338191960Sstas int mask, error, enabled; 1339155324Simp 1340191960Sstas error = 0; 1341191959Sstas flags = ifp->if_flags; 1342191959Sstas drv_flags = ifp->if_drv_flags; 1343155324Simp switch (cmd) { 1344155324Simp case SIOCSIFFLAGS: 1345155324Simp ATE_LOCK(sc); 1346191959Sstas if ((flags & IFF_UP) != 0) { 1347191959Sstas if ((drv_flags & IFF_DRV_RUNNING) != 0) { 1348191959Sstas if (((flags ^ sc->if_flags) 1349191959Sstas & (IFF_PROMISC | IFF_ALLMULTI)) != 0) 1350191959Sstas ate_rxfilter(sc); 1351191959Sstas } else { 1352213496Scognet if ((sc->flags & ATE_FLAG_DETACHING) == 0) 1353213496Scognet ateinit_locked(sc); 1354191959Sstas } 1355191959Sstas } else if ((drv_flags & IFF_DRV_RUNNING) != 0) { 1356213496Scognet ifp->if_drv_flags &= ~IFF_DRV_RUNNING; 1357155324Simp atestop(sc); 1358155324Simp } 1359191959Sstas sc->if_flags = flags; 1360155324Simp ATE_UNLOCK(sc); 1361155324Simp break; 1362155324Simp 1363155324Simp case SIOCADDMULTI: 1364155324Simp case SIOCDELMULTI: 1365191960Sstas if ((drv_flags & IFF_DRV_RUNNING) != 0) { 1366191960Sstas ATE_LOCK(sc); 1367191960Sstas enabled = ate_setmcast(sc); 1368191960Sstas if (enabled != (sc->flags & ATE_FLAG_MULTICAST)) 1369191960Sstas ate_rxfilter(sc); 1370191960Sstas ATE_UNLOCK(sc); 1371191960Sstas } 1372155324Simp break; 1373155324Simp 1374213496Scognet case SIOCSIFMEDIA: 1375213496Scognet case SIOCGIFMEDIA: 1376213496Scognet mii = device_get_softc(sc->miibus); 1377213496Scognet error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, cmd); 1378213496Scognet break; 1379165779Sticso case SIOCSIFCAP: 1380165779Sticso mask = ifp->if_capenable ^ ifr->ifr_reqcap; 1381165779Sticso if (mask & IFCAP_VLAN_MTU) { 1382165779Sticso ATE_LOCK(sc); 1383165779Sticso if (ifr->ifr_reqcap & IFCAP_VLAN_MTU) { 1384165779Sticso WR4(sc, ETH_CFG, RD4(sc, ETH_CFG) | ETH_CFG_BIG); 1385165779Sticso ifp->if_capenable |= IFCAP_VLAN_MTU; 1386165779Sticso } else { 1387165779Sticso WR4(sc, ETH_CFG, RD4(sc, ETH_CFG) & ~ETH_CFG_BIG); 1388165779Sticso ifp->if_capenable &= ~IFCAP_VLAN_MTU; 1389165779Sticso } 1390165779Sticso ATE_UNLOCK(sc); 1391165779Sticso } 1392155324Simp default: 1393155324Simp error = ether_ioctl(ifp, cmd, data); 1394155324Simp break; 1395155324Simp } 1396155324Simp return (error); 1397155324Simp} 1398155324Simp 1399155324Simpstatic void 1400155324Simpate_child_detached(device_t dev, device_t child) 1401155324Simp{ 1402155324Simp struct ate_softc *sc; 1403155324Simp 1404155324Simp sc = device_get_softc(dev); 1405155324Simp if (child == sc->miibus) 1406155324Simp sc->miibus = NULL; 1407155324Simp} 1408155324Simp 1409155324Simp/* 1410155324Simp * MII bus support routines. 1411155324Simp */ 1412155324Simpstatic int 1413155324Simpate_miibus_readreg(device_t dev, int phy, int reg) 1414155324Simp{ 1415155324Simp struct ate_softc *sc; 1416155324Simp int val; 1417155324Simp 1418155324Simp /* 1419155324Simp * XXX if we implement agressive power savings, then we need 1420155324Simp * XXX to make sure that the clock to the emac is on here 1421155324Simp */ 1422155324Simp 1423155324Simp sc = device_get_softc(dev); 1424155324Simp DELAY(1); /* Hangs w/o this delay really 30.5us atm */ 1425155324Simp WR4(sc, ETH_MAN, ETH_MAN_REG_RD(phy, reg)); 1426155324Simp while ((RD4(sc, ETH_SR) & ETH_SR_IDLE) == 0) 1427155324Simp continue; 1428155324Simp val = RD4(sc, ETH_MAN) & ETH_MAN_VALUE_MASK; 1429155324Simp 1430155324Simp return (val); 1431155324Simp} 1432155324Simp 1433194015Savgstatic int 1434155324Simpate_miibus_writereg(device_t dev, int phy, int reg, int data) 1435155324Simp{ 1436155324Simp struct ate_softc *sc; 1437234281Smarius 1438155324Simp /* 1439155324Simp * XXX if we implement agressive power savings, then we need 1440155324Simp * XXX to make sure that the clock to the emac is on here 1441155324Simp */ 1442155324Simp 1443155324Simp sc = device_get_softc(dev); 1444155324Simp WR4(sc, ETH_MAN, ETH_MAN_REG_WR(phy, reg, data)); 1445155324Simp while ((RD4(sc, ETH_SR) & ETH_SR_IDLE) == 0) 1446155324Simp continue; 1447194015Savg return (0); 1448155324Simp} 1449155324Simp 1450155324Simpstatic device_method_t ate_methods[] = { 1451155324Simp /* Device interface */ 1452155324Simp DEVMETHOD(device_probe, ate_probe), 1453155324Simp DEVMETHOD(device_attach, ate_attach), 1454155324Simp DEVMETHOD(device_detach, ate_detach), 1455155324Simp 1456155324Simp /* Bus interface */ 1457155324Simp DEVMETHOD(bus_child_detached, ate_child_detached), 1458155324Simp 1459155324Simp /* MII interface */ 1460155324Simp DEVMETHOD(miibus_readreg, ate_miibus_readreg), 1461155324Simp DEVMETHOD(miibus_writereg, ate_miibus_writereg), 1462155324Simp 1463234281Smarius DEVMETHOD_END 1464155324Simp}; 1465155324Simp 1466155324Simpstatic driver_t ate_driver = { 1467155324Simp "ate", 1468155324Simp ate_methods, 1469155324Simp sizeof(struct ate_softc), 1470155324Simp}; 1471155324Simp 1472266196Sian#ifdef FDT 1473266196SianDRIVER_MODULE(ate, simplebus, ate_driver, ate_devclass, NULL, NULL); 1474266196Sian#else 1475234281SmariusDRIVER_MODULE(ate, atmelarm, ate_driver, ate_devclass, NULL, NULL); 1476266196Sian#endif 1477234281SmariusDRIVER_MODULE(miibus, ate, miibus_driver, miibus_devclass, NULL, NULL); 1478155324SimpMODULE_DEPEND(ate, miibus, 1, 1, 1); 1479155324SimpMODULE_DEPEND(ate, ether, 1, 1, 1); 1480