From owner-svn-src-projects@FreeBSD.ORG Wed Mar 25 21:31:37 2015 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id A5A00960; Wed, 25 Mar 2015 21:31:37 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 90A156CB; Wed, 25 Mar 2015 21:31:37 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t2PLVbBC015352; Wed, 25 Mar 2015 21:31:37 GMT (envelope-from glebius@FreeBSD.org) Received: (from glebius@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id t2PLVbdj015351; Wed, 25 Mar 2015 21:31:37 GMT (envelope-from glebius@FreeBSD.org) Message-Id: <201503252131.t2PLVbdj015351@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: glebius set sender to glebius@FreeBSD.org using -f From: Gleb Smirnoff Date: Wed, 25 Mar 2015 21:31:37 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r280633 - projects/ifnet/sys/dev/cadence X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 25 Mar 2015 21:31:37 -0000 Author: glebius Date: Wed Mar 25 21:31:36 2015 New Revision: 280633 URL: https://svnweb.freebsd.org/changeset/base/280633 Log: Convert to new ifnet KPI. Big thanks to Thomas for this submission! Submitted by: Thomas Skibo Modified: projects/ifnet/sys/dev/cadence/if_cgem.c Modified: projects/ifnet/sys/dev/cadence/if_cgem.c ============================================================================== --- projects/ifnet/sys/dev/cadence/if_cgem.c Wed Mar 25 20:57:54 2015 (r280632) +++ projects/ifnet/sys/dev/cadence/if_cgem.c Wed Mar 25 21:31:36 2015 (r280633) @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2012-2014 Thomas Skibo + * Copyright (c) 2012-2015 Thomas Skibo * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -52,7 +52,6 @@ __FBSDID("$FreeBSD$"); #include #include -#include #include #include #include @@ -96,13 +95,19 @@ __FBSDID("$FreeBSD$"); #define CGEM_CKSUM_ASSIST (CSUM_IP | CSUM_TCP | CSUM_UDP | \ CSUM_TCP_IPV6 | CSUM_UDP_IPV6) +#define CGEM_DRV_RUNNING 0x0001 +#define CGEM_DRV_OACTIVE 0x0002 + struct cgem_softc { if_t ifp; struct mtx sc_mtx; device_t dev; device_t miibus; u_int mii_media_active; /* last active media */ - int if_old_flags; + int cgem_if_flags; + int cgem_drv_flags; + uint32_t cgem_capenable; + uint64_t cgem_hwassist; struct resource *mem_res; struct resource *irq_res; void *intrhand; @@ -207,8 +212,6 @@ struct cgem_softc { /* Allow platforms to optionally provide a way to set the reference clock. */ int cgem_set_ref_clk(int unit, int frequency); -static devclass_t cgem_devclass; - static int cgem_probe(device_t dev); static int cgem_attach(device_t dev); static int cgem_detach(device_t dev); @@ -276,9 +279,12 @@ cgem_get_mac(struct cgem_softc *sc, u_ch * Reference Manual. Bits 0-5 in the hash are the exclusive-or of * every sixth bit in the destination address. */ -static int -cgem_mac_hash(u_char eaddr[]) +static void +cgem_mac_hash(void *arg, struct sockaddr *maddr) { + struct sockaddr_dl *sdl = (struct sockaddr_dl *)maddr; + u_char *eaddr = LLADDR(sdl); + uint64_t *hashmask = arg; int hash; int i, j; @@ -288,7 +294,7 @@ cgem_mac_hash(u_char eaddr[]) if ((eaddr[j >> 3] & (1 << (j & 7))) != 0) hash ^= (1 << i); - return hash; + *hashmask |= (1ull << hash); } /* After any change in rx flags or multi-cast addresses, set up @@ -297,58 +303,32 @@ cgem_mac_hash(u_char eaddr[]) static void cgem_rx_filter(struct cgem_softc *sc) { - if_t ifp = sc->ifp; - u_char *mta; - - int index, i, mcnt; - uint32_t hash_hi, hash_lo; + uint64_t hashmask = 0; uint32_t net_cfg; - hash_hi = 0; - hash_lo = 0; - net_cfg = RD4(sc, CGEM_NET_CFG); net_cfg &= ~(CGEM_NET_CFG_MULTI_HASH_EN | CGEM_NET_CFG_NO_BCAST | CGEM_NET_CFG_COPY_ALL); - if ((if_getflags(ifp) & IFF_PROMISC) != 0) + if ((sc->cgem_if_flags & IFF_PROMISC) != 0) net_cfg |= CGEM_NET_CFG_COPY_ALL; else { - if ((if_getflags(ifp) & IFF_BROADCAST) == 0) + if ((sc->cgem_if_flags & IFF_BROADCAST) == 0) net_cfg |= CGEM_NET_CFG_NO_BCAST; - if ((if_getflags(ifp) & IFF_ALLMULTI) != 0) { - hash_hi = 0xffffffff; - hash_lo = 0xffffffff; - } else { - mcnt = if_multiaddr_count(ifp, -1); - mta = malloc(ETHER_ADDR_LEN * mcnt, M_DEVBUF, - M_NOWAIT); - if (mta == NULL) { - device_printf(sc->dev, - "failed to allocate temp mcast list\n"); - return; - } - if_multiaddr_array(ifp, mta, &mcnt, mcnt); - for (i = 0; i < mcnt; i++) { - index = cgem_mac_hash( - LLADDR((struct sockaddr_dl *) - (mta + (i * ETHER_ADDR_LEN)))); - if (index > 31) - hash_hi |= (1 << (index - 32)); - else - hash_lo |= (1 << index); - } - free(mta, M_DEVBUF); - } - if (hash_hi != 0 || hash_lo != 0) + if ((sc->cgem_if_flags & IFF_ALLMULTI) != 0) + hashmask = (uint64_t)-1; + else + if_foreach_maddr(sc->ifp, cgem_mac_hash, &hashmask); + + if (hashmask != 0) net_cfg |= CGEM_NET_CFG_MULTI_HASH_EN; } - WR4(sc, CGEM_HASH_TOP, hash_hi); - WR4(sc, CGEM_HASH_BOT, hash_lo); + WR4(sc, CGEM_HASH_TOP, hashmask >> 32); + WR4(sc, CGEM_HASH_BOT, hashmask & 0xffffffff); WR4(sc, CGEM_NET_CFG, net_cfg); } @@ -583,7 +563,7 @@ cgem_recv(struct cgem_softc *sc) /* Are we using hardware checksumming? Check the * status in the receive descriptor. */ - if ((if_getcapenable(ifp) & IFCAP_RXCSUM) != 0) { + if ((sc->cgem_capenable & IFCAP_RXCSUM) != 0) { /* TCP or UDP checks out, IP checks out too. */ if ((ctl & CGEM_RXDESC_CKSUM_STAT_MASK) == CGEM_RXDESC_CKSUM_STAT_TCP_GOOD || @@ -617,6 +597,7 @@ cgem_recv(struct cgem_softc *sc) m_hd = m_hd->m_next; m->m_next = NULL; if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1); + if_inc_counter(ifp, IFCOUNTER_IBYTES, m->m_pkthdr.len); if_input(ifp, m); } CGEM_LOCK(sc); @@ -648,10 +629,8 @@ cgem_clean_tx(struct cgem_softc *sc) sc->txring_m_dmamap[sc->txring_tl_ptr]); sc->txring_m_dmamap[sc->txring_tl_ptr] = NULL; - /* Free up the mbuf. */ m = sc->txring_m[sc->txring_tl_ptr]; sc->txring_m[sc->txring_tl_ptr] = NULL; - m_freem(m); /* Check the status. */ if ((ctl & CGEM_TXDESC_AHB_ERR) != 0) { @@ -663,7 +642,9 @@ cgem_clean_tx(struct cgem_softc *sc) CGEM_TXDESC_LATE_COLL)) != 0) { if_inc_counter(sc->ifp, IFCOUNTER_OERRORS, 1); } else - if_inc_counter(sc->ifp, IFCOUNTER_OPACKETS, 1); + if_inc_txcounters(sc->ifp, m); + + m_freem(m); /* If the packet spanned more than one tx descriptor, * skip descriptors until we find the end so that only @@ -689,15 +670,15 @@ cgem_clean_tx(struct cgem_softc *sc) sc->txring_tl_ptr++; sc->txring_queued--; - if_setdrvflagbits(sc->ifp, 0, IFF_DRV_OACTIVE); + sc->cgem_drv_flags &= ~CGEM_DRV_OACTIVE; } } /* Start transmits. */ static void -cgem_start_locked(if_t ifp) +cgem_start_locked(struct cgem_softc *sc) { - struct cgem_softc *sc = (struct cgem_softc *) if_getsoftc(ifp); + if_t ifp = sc->ifp; struct mbuf *m; bus_dma_segment_t segs[TX_MAX_DMA_SEGS]; uint32_t ctl; @@ -705,7 +686,7 @@ cgem_start_locked(if_t ifp) CGEM_ASSERT_LOCKED(sc); - if ((if_getdrvflags(ifp) & IFF_DRV_OACTIVE) != 0) + if ((sc->cgem_drv_flags & CGEM_DRV_OACTIVE) != 0) return; for (;;) { @@ -719,14 +700,14 @@ cgem_start_locked(if_t ifp) /* Still no room? */ if (sc->txring_queued >= CGEM_NUM_TX_DESCS - TX_MAX_DMA_SEGS * 2) { - if_setdrvflagbits(ifp, IFF_DRV_OACTIVE, 0); + sc->cgem_drv_flags |= CGEM_DRV_OACTIVE; sc->txfull++; break; } } /* Grab next transmit packet. */ - m = if_dequeue(ifp); + m = if_snd_dequeue(ifp); if (m == NULL) break; @@ -809,20 +790,24 @@ cgem_start_locked(if_t ifp) WR4(sc, CGEM_NET_CTRL, sc->net_ctl_shadow | CGEM_NET_CTRL_START_TX); - /* If there is a BPF listener, bounce a copy to to him. */ - ETHER_BPF_MTAP(ifp, m); + if_mtap(ifp, m, NULL, 0); } } -static void -cgem_start(if_t ifp) +static int +cgem_transmit(if_t ifp, struct mbuf *m) { - struct cgem_softc *sc = (struct cgem_softc *) if_getsoftc(ifp); + struct cgem_softc *sc = if_getsoftc(ifp, IF_DRIVER_SOFTC); + int error; + if ((error = if_snd_enqueue(ifp, m)) != 0) + return error; CGEM_LOCK(sc); - cgem_start_locked(ifp); + cgem_start_locked(sc); CGEM_UNLOCK(sc); + return (0); } + static void cgem_poll_hw_stats(struct cgem_softc *sc) @@ -934,7 +919,7 @@ cgem_intr(void *arg) CGEM_LOCK(sc); - if ((if_getdrvflags(ifp) & IFF_DRV_RUNNING) == 0) { + if ((sc->cgem_drv_flags & CGEM_DRV_RUNNING) == 0) { CGEM_UNLOCK(sc); return; } @@ -973,8 +958,8 @@ cgem_intr(void *arg) } /* Restart transmitter if needed. */ - if (!if_sendq_empty(ifp)) - cgem_start_locked(ifp); + if (!if_snd_len(ifp)) + cgem_start_locked(sc); CGEM_UNLOCK(sc); } @@ -1013,7 +998,7 @@ cgem_config(struct cgem_softc *sc) if_t ifp = sc->ifp; uint32_t net_cfg; uint32_t dma_cfg; - u_char *eaddr = if_getlladdr(ifp); + uint8_t *eaddr = if_lladdr(ifp); CGEM_ASSERT_LOCKED(sc); @@ -1028,7 +1013,7 @@ cgem_config(struct cgem_softc *sc) CGEM_NET_CFG_SPEED100; /* Enable receive checksum offloading? */ - if ((if_getcapenable(ifp) & IFCAP_RXCSUM) != 0) + if ((sc->cgem_capenable & IFCAP_RXCSUM) != 0) net_cfg |= CGEM_NET_CFG_RX_CHKSUM_OFFLD_EN; WR4(sc, CGEM_NET_CFG, net_cfg); @@ -1041,7 +1026,7 @@ cgem_config(struct cgem_softc *sc) CGEM_DMA_CFG_DISC_WHEN_NO_AHB; /* Enable transmit checksum offloading? */ - if ((if_getcapenable(ifp) & IFCAP_TXCSUM) != 0) + if ((sc->cgem_capenable & IFCAP_TXCSUM) != 0) dma_cfg |= CGEM_DMA_CFG_CHKSUM_GEN_OFFLOAD_EN; WR4(sc, CGEM_DMA_CFG, dma_cfg); @@ -1074,13 +1059,13 @@ cgem_init_locked(struct cgem_softc *sc) CGEM_ASSERT_LOCKED(sc); - if ((if_getdrvflags(sc->ifp) & IFF_DRV_RUNNING) != 0) + if ((sc->cgem_drv_flags & CGEM_DRV_RUNNING) != 0) return; cgem_config(sc); cgem_fill_rqueue(sc); - if_setdrvflagbits(sc->ifp, IFF_DRV_RUNNING, IFF_DRV_OACTIVE); + sc->cgem_drv_flags = CGEM_DRV_RUNNING; mii = device_get_softc(sc->miibus); mii_mediachg(mii); @@ -1088,16 +1073,6 @@ cgem_init_locked(struct cgem_softc *sc) callout_reset(&sc->tick_ch, hz, cgem_tick, sc); } -static void -cgem_init(void *arg) -{ - struct cgem_softc *sc = (struct cgem_softc *)arg; - - CGEM_LOCK(sc); - cgem_init_locked(sc); - CGEM_UNLOCK(sc); -} - /* Turn off interface. Free up any buffers in transmit or receive queues. */ static void cgem_stop(struct cgem_softc *sc) @@ -1160,37 +1135,36 @@ cgem_stop(struct cgem_softc *sc) static int -cgem_ioctl(if_t ifp, u_long cmd, caddr_t data) +cgem_ioctl(if_t ifp, u_long cmd, void *data, struct thread *td) { - struct cgem_softc *sc = if_getsoftc(ifp); + struct cgem_softc *sc = if_getsoftc(ifp, IF_DRIVER_SOFTC); struct ifreq *ifr = (struct ifreq *)data; struct mii_data *mii; - int error = 0, mask; + int oflags, error = 0, mask; switch (cmd) { case SIOCSIFFLAGS: CGEM_LOCK(sc); - if ((if_getflags(ifp) & IFF_UP) != 0) { - if ((if_getdrvflags(ifp) & IFF_DRV_RUNNING) != 0) { - if (((if_getflags(ifp) ^ sc->if_old_flags) & - (IFF_PROMISC | IFF_ALLMULTI)) != 0) { + oflags = sc->cgem_if_flags; + sc->cgem_if_flags = ifr->ifr_flags; + if ((sc->cgem_if_flags & IFF_UP) != 0) { + if ((sc->cgem_drv_flags & CGEM_DRV_RUNNING) != 0) { + if (((oflags ^ sc->cgem_if_flags) & + (IFF_PROMISC | IFF_ALLMULTI)) != 0) cgem_rx_filter(sc); - } - } else { + } else cgem_init_locked(sc); - } - } else if ((if_getdrvflags(ifp) & IFF_DRV_RUNNING) != 0) { - if_setdrvflagbits(ifp, 0, IFF_DRV_RUNNING); + } else if ((sc->cgem_drv_flags & CGEM_DRV_RUNNING) != 0) { + sc->cgem_drv_flags &= ~CGEM_DRV_RUNNING; cgem_stop(sc); } - sc->if_old_flags = if_getflags(ifp); CGEM_UNLOCK(sc); break; case SIOCADDMULTI: case SIOCDELMULTI: /* Set up multi-cast filters. */ - if ((if_getdrvflags(ifp) & IFF_DRV_RUNNING) != 0) { + if ((sc->cgem_drv_flags & CGEM_DRV_RUNNING) != 0) { CGEM_LOCK(sc); cgem_rx_filter(sc); CGEM_UNLOCK(sc); @@ -1205,23 +1179,23 @@ cgem_ioctl(if_t ifp, u_long cmd, caddr_t case SIOCSIFCAP: CGEM_LOCK(sc); - mask = if_getcapenable(ifp) ^ ifr->ifr_reqcap; + mask = sc->cgem_capenable ^ ifr->ifr_reqcap; if ((mask & IFCAP_TXCSUM) != 0) { if ((ifr->ifr_reqcap & IFCAP_TXCSUM) != 0) { /* Turn on TX checksumming. */ - if_setcapenablebit(ifp, IFCAP_TXCSUM | - IFCAP_TXCSUM_IPV6, 0); - if_sethwassistbits(ifp, CGEM_CKSUM_ASSIST, 0); + sc->cgem_capenable |= IFCAP_TXCSUM | + IFCAP_TXCSUM_IPV6; + sc->cgem_hwassist |= CGEM_CKSUM_ASSIST; WR4(sc, CGEM_DMA_CFG, RD4(sc, CGEM_DMA_CFG) | CGEM_DMA_CFG_CHKSUM_GEN_OFFLOAD_EN); } else { /* Turn off TX checksumming. */ - if_setcapenablebit(ifp, 0, IFCAP_TXCSUM | - IFCAP_TXCSUM_IPV6); - if_sethwassistbits(ifp, 0, CGEM_CKSUM_ASSIST); + sc->cgem_capenable &= ~(IFCAP_TXCSUM | + IFCAP_TXCSUM_IPV6); + sc->cgem_hwassist &= ~CGEM_CKSUM_ASSIST; WR4(sc, CGEM_DMA_CFG, RD4(sc, CGEM_DMA_CFG) & @@ -1231,30 +1205,25 @@ cgem_ioctl(if_t ifp, u_long cmd, caddr_t if ((mask & IFCAP_RXCSUM) != 0) { if ((ifr->ifr_reqcap & IFCAP_RXCSUM) != 0) { /* Turn on RX checksumming. */ - if_setcapenablebit(ifp, IFCAP_RXCSUM | - IFCAP_RXCSUM_IPV6, 0); + sc->cgem_capenable |= IFCAP_RXCSUM | + IFCAP_RXCSUM_IPV6; + WR4(sc, CGEM_NET_CFG, RD4(sc, CGEM_NET_CFG) | CGEM_NET_CFG_RX_CHKSUM_OFFLD_EN); } else { /* Turn off RX checksumming. */ - if_setcapenablebit(ifp, 0, IFCAP_RXCSUM | - IFCAP_RXCSUM_IPV6); + sc->cgem_capenable &= ~(IFCAP_RXCSUM | + IFCAP_RXCSUM_IPV6); WR4(sc, CGEM_NET_CFG, RD4(sc, CGEM_NET_CFG) & ~CGEM_NET_CFG_RX_CHKSUM_OFFLD_EN); } } - if ((if_getcapenable(ifp) & (IFCAP_RXCSUM | IFCAP_TXCSUM)) == - (IFCAP_RXCSUM | IFCAP_TXCSUM)) - if_setcapenablebit(ifp, IFCAP_VLAN_HWCSUM, 0); - else - if_setcapenablebit(ifp, 0, IFCAP_VLAN_HWCSUM); - CGEM_UNLOCK(sc); break; default: - error = ether_ioctl(ifp, cmd, data); + error = EOPNOTSUPP; break; } @@ -1275,14 +1244,14 @@ cgem_child_detached(device_t dev, device static int cgem_ifmedia_upd(if_t ifp) { - struct cgem_softc *sc = (struct cgem_softc *) if_getsoftc(ifp); + struct cgem_softc *sc = if_getsoftc(ifp, IF_DRIVER_SOFTC); struct mii_data *mii; struct mii_softc *miisc; int error = 0; mii = device_get_softc(sc->miibus); CGEM_LOCK(sc); - if ((if_getflags(ifp) & IFF_UP) != 0) { + if ((sc->cgem_if_flags & IFF_UP) != 0) { LIST_FOREACH(miisc, &mii->mii_phys, mii_list) PHY_RESET(miisc); error = mii_mediachg(mii); @@ -1295,7 +1264,7 @@ cgem_ifmedia_upd(if_t ifp) static void cgem_ifmedia_sts(if_t ifp, struct ifmediareq *ifmr) { - struct cgem_softc *sc = (struct cgem_softc *) if_getsoftc(ifp); + struct cgem_softc *sc = if_getsoftc(ifp, IF_DRIVER_SOFTC); struct mii_data *mii; mii = device_get_softc(sc->miibus); @@ -1380,18 +1349,15 @@ cgem_miibus_statchg(device_t dev) cgem_mediachange(sc, mii); } -static void -cgem_miibus_linkchg(device_t dev) +static uint64_t +cgem_miibus_readvar(device_t dev, int var) { - struct cgem_softc *sc = device_get_softc(dev); - struct mii_data *mii = device_get_softc(sc->miibus); - - CGEM_ASSERT_LOCKED(sc); - - if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) == - (IFM_ACTIVE | IFM_AVALID) && - sc->mii_media_active != mii->mii_media_active) - cgem_mediachange(sc, mii); + switch (var) { + case MIIVAR_MTU: + return (ETHERMTU); + default: + return (0); + } } /* @@ -1637,11 +1603,28 @@ cgem_probe(device_t dev) return (0); } +static struct ifdriver cgem_ifdrv = { + .ifdrv_ops = { + .ifop_ioctl = cgem_ioctl, + .ifop_transmit = cgem_transmit, + }, + .ifdrv_name = IF_CGEM_NAME, + .ifdrv_type = IFT_ETHER, + .ifdrv_hdrlen = sizeof(struct ether_vlan_header), + .ifdrv_maxqlen = CGEM_NUM_TX_DESCS, +}; + static int cgem_attach(device_t dev) { + struct if_attach_args ifat = { + .ifat_version = IF_ATTACH_VERSION, + .ifat_drv = &cgem_ifdrv, + .ifat_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST, + .ifat_capabilities = IFCAP_HWCSUM | IFCAP_HWCSUM_IPV6 | + IFCAP_VLAN_MTU | IFCAP_VLAN_HWCSUM, + }; struct cgem_softc *sc = device_get_softc(dev); - if_t ifp = NULL; phandle_t node; pcell_t cell; int rid, err; @@ -1675,40 +1658,13 @@ cgem_attach(device_t dev) return (ENOMEM); } - /* Set up ifnet structure. */ - ifp = sc->ifp = if_alloc(IFT_ETHER); - if (ifp == NULL) { - device_printf(dev, "could not allocate ifnet structure\n"); - cgem_detach(dev); - return (ENOMEM); - } - if_setsoftc(ifp, sc); - if_initname(ifp, IF_CGEM_NAME, device_get_unit(dev)); - if_setflags(ifp, IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST); - if_setinitfn(ifp, cgem_init); - if_setioctlfn(ifp, cgem_ioctl); - if_setstartfn(ifp, cgem_start); - if_setcapabilitiesbit(ifp, IFCAP_HWCSUM | IFCAP_HWCSUM_IPV6 | - IFCAP_VLAN_MTU | IFCAP_VLAN_HWCSUM, 0); - if_setsendqlen(ifp, CGEM_NUM_TX_DESCS); - if_setsendqready(ifp); - - /* Disable hardware checksumming by default. */ - if_sethwassist(ifp, 0); - if_setcapenable(ifp, if_getcapabilities(ifp) & - ~(IFCAP_HWCSUM | IFCAP_HWCSUM_IPV6 | IFCAP_VLAN_HWCSUM)); - - sc->if_old_flags = if_getflags(ifp); - sc->rxbufs = DEFAULT_NUM_RX_BUFS; - sc->rxhangwar = 1; - /* Reset hardware. */ CGEM_LOCK(sc); cgem_reset(sc); CGEM_UNLOCK(sc); /* Attach phy to mii bus. */ - err = mii_attach(dev, &sc->miibus, ifp, + err = mii_attach(dev, &sc->miibus, cgem_ifmedia_upd, cgem_ifmedia_sts, BMSR_DEFCAPMASK, MII_PHY_ANY, MII_OFFSET_ANY, 0); if (err) { @@ -1717,6 +1673,20 @@ cgem_attach(device_t dev) return (err); } + /* Disable hardware checksumming by default. */ + sc->cgem_hwassist = 0; + sc->cgem_capenable = IFCAP_VLAN_MTU; + + sc->rxbufs = DEFAULT_NUM_RX_BUFS; + sc->rxhangwar = 1; + + ifat.ifat_softc = sc; + ifat.ifat_dunit = device_get_unit(dev); + ifat.ifat_lla =eaddr; + ifat.ifat_hwassist = sc->cgem_hwassist; + ifat.ifat_capenable = sc->cgem_capenable; + sc->ifp = if_attach(&ifat); + /* Set up TX and RX descriptor area. */ err = cgem_setup_descs(sc); if (err) { @@ -1731,13 +1701,10 @@ cgem_attach(device_t dev) /* Start ticks. */ callout_init_mtx(&sc->tick_ch, &sc->sc_mtx, 0); - ether_ifattach(ifp, eaddr); - err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET | INTR_MPSAFE | INTR_EXCL, NULL, cgem_intr, sc, &sc->intrhand); if (err) { device_printf(dev, "could not set interrupt handler.\n"); - ether_ifdetach(ifp); cgem_detach(dev); return (err); } @@ -1761,8 +1728,7 @@ cgem_detach(device_t dev) cgem_stop(sc); CGEM_UNLOCK(sc); callout_drain(&sc->tick_ch); - if_setflagbits(sc->ifp, 0, IFF_UP); - ether_ifdetach(sc->ifp); + sc->cgem_if_flags &= ~IFF_UP; } if (sc->miibus != NULL) { @@ -1846,17 +1812,19 @@ static device_method_t cgem_methods[] = DEVMETHOD(miibus_readreg, cgem_miibus_readreg), DEVMETHOD(miibus_writereg, cgem_miibus_writereg), DEVMETHOD(miibus_statchg, cgem_miibus_statchg), - DEVMETHOD(miibus_linkchg, cgem_miibus_linkchg), + DEVMETHOD(miibus_readvar, cgem_miibus_readvar), DEVMETHOD_END }; static driver_t cgem_driver = { - "cgem", + IF_CGEM_NAME, cgem_methods, sizeof(struct cgem_softc), }; +static devclass_t cgem_devclass; + DRIVER_MODULE(cgem, simplebus, cgem_driver, cgem_devclass, NULL, NULL); DRIVER_MODULE(miibus, cgem, miibus_driver, miibus_devclass, NULL, NULL); MODULE_DEPEND(cgem, miibus, 1, 1, 1);