svn commit: r277124 - projects/ifnet/sys/dev/xl
Gleb Smirnoff
glebius at FreeBSD.org
Tue Jan 13 09:09:41 UTC 2015
Author: glebius
Date: Tue Jan 13 09:09:40 2015
New Revision: 277124
URL: https://svnweb.freebsd.org/changeset/base/277124
Log:
Convert xl(4) to opaque ifnet API.
Committed via: xl0
Sponsored by: Nginx, Inc.
Modified:
projects/ifnet/sys/dev/xl/if_xl.c
projects/ifnet/sys/dev/xl/if_xlreg.h
Modified: projects/ifnet/sys/dev/xl/if_xl.c
==============================================================================
--- projects/ifnet/sys/dev/xl/if_xl.c Tue Jan 13 09:05:49 2015 (r277123)
+++ projects/ifnet/sys/dev/xl/if_xl.c Tue Jan 13 09:09:40 2015 (r277124)
@@ -108,19 +108,16 @@ __FBSDID("$FreeBSD$");
#include <sys/endian.h>
#include <sys/mbuf.h>
#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
#include <sys/module.h>
#include <sys/socket.h>
#include <sys/taskqueue.h>
#include <net/if.h>
-#include <net/if_var.h>
-#include <net/if_arp.h>
#include <net/ethernet.h>
#include <net/if_dl.h>
#include <net/if_media.h>
-#include <net/if_types.h>
-
-#include <net/bpf.h>
#include <machine/bus.h>
#include <machine/resource.h>
@@ -237,10 +234,10 @@ static void xl_txeof(struct xl_softc *);
static void xl_txeof_90xB(struct xl_softc *);
static void xl_txeoc(struct xl_softc *);
static void xl_intr(void *);
-static void xl_start(struct ifnet *);
-static void xl_start_locked(struct ifnet *);
-static void xl_start_90xB_locked(struct ifnet *);
-static int xl_ioctl(struct ifnet *, u_long, caddr_t);
+static int xl_transmit(if_t, struct mbuf *);
+static void xl_start_locked(struct xl_softc *);
+static void xl_start_90xB_locked(struct xl_softc *);
+static int xl_ioctl(if_t, u_long, caddr_t);
static void xl_init(void *);
static void xl_init_locked(struct xl_softc *);
static void xl_stop(struct xl_softc *);
@@ -251,12 +248,12 @@ static int xl_resume(device_t);
static void xl_setwol(struct xl_softc *);
#ifdef DEVICE_POLLING
-static int xl_poll(struct ifnet *ifp, enum poll_cmd cmd, int count);
-static int xl_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count);
+static int xl_poll(if_t, enum poll_cmd cmd, int count);
+static int xl_poll_locked(if_t, enum poll_cmd cmd, int count);
#endif
-static int xl_ifmedia_upd(struct ifnet *);
-static void xl_ifmedia_sts(struct ifnet *, struct ifmediareq *);
+static int xl_ifmedia_upd(if_t);
+static void xl_ifmedia_sts(if_t, struct ifmediareq *);
static int xl_eeprom_wait(struct xl_softc *);
static int xl_read_eeprom(struct xl_softc *, caddr_t, int, int, int);
@@ -282,6 +279,7 @@ static void xl_testpacket(struct xl_soft
static int xl_miibus_readreg(device_t, int, int);
static int xl_miibus_writereg(device_t, int, int, int);
static void xl_miibus_statchg(device_t);
+static void xl_miibus_linkchg(device_t);
static void xl_miibus_mediainit(device_t);
/*
@@ -315,6 +313,7 @@ static device_method_t xl_methods[] = {
DEVMETHOD(miibus_readreg, xl_miibus_readreg),
DEVMETHOD(miibus_writereg, xl_miibus_writereg),
DEVMETHOD(miibus_statchg, xl_miibus_statchg),
+ DEVMETHOD(miibus_linkchg, xl_miibus_linkchg),
DEVMETHOD(miibus_mediainit, xl_miibus_mediainit),
DEVMETHOD_END
@@ -332,6 +331,18 @@ DRIVER_MODULE_ORDERED(xl, pci, xl_driver
SI_ORDER_ANY);
DRIVER_MODULE(miibus, xl, miibus_driver, miibus_devclass, NULL, NULL);
+static struct ifdriver xl_ifdrv = {
+ .ifdrv_ops = {
+ .ifop_origin = IFOP_ORIGIN_DRIVER,
+ .ifop_ioctl = xl_ioctl,
+ .ifop_transmit = xl_transmit,
+ .ifop_init = xl_init,
+ },
+ .ifdrv_name = "xl",
+ .ifdrv_type = IFT_ETHER,
+ .ifdrv_maxqlen = XL_TX_LIST_CNT - 1,
+};
+
static void
xl_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nseg, int error)
{
@@ -466,6 +477,25 @@ xl_miibus_statchg(device_t dev)
macctl &= ~XL_MACCTRL_FLOW_CONTROL_ENB;
}
CSR_WRITE_1(sc, XL_W3_MAC_CTRL, macctl);
+ if (sc->xl_ifp != NULL)
+ if_set(sc->xl_ifp, IF_BAUDRATE,
+ ifmedia_baudrate(mii->mii_media_active));
+}
+
+static void
+xl_miibus_linkchg(device_t dev)
+{
+ struct xl_softc *sc;
+ struct mii_data *mii;
+ if_t ifp;
+
+ sc = device_get_softc(dev);
+ mii = device_get_softc(sc->xl_miibus);
+ ifp = sc->xl_ifp;
+
+ if (ifp != NULL)
+ if_link_state_change(ifp,
+ ifmedia_link_state(mii->mii_media_status));
}
/*
@@ -602,15 +632,25 @@ xl_rxfilter(struct xl_softc *sc)
* is to enable reception of all multicast frames.
*/
static void
+xl_check_maddr_90x(void *arg, struct sockaddr *maddr)
+{
+ struct sockaddr *sa = (struct sockaddr *)maddr;
+ uint8_t *rxfilt = arg;
+
+ if (sa->sa_family == AF_LINK)
+ *rxfilt |= XL_RXFILTER_ALLMULTI;
+}
+static void
xl_rxfilter_90x(struct xl_softc *sc)
{
- struct ifnet *ifp;
- struct ifmultiaddr *ifma;
- u_int8_t rxfilt;
+ if_t ifp;
+ uint32_t flags;
+ uint8_t rxfilt;
XL_LOCK_ASSERT(sc);
ifp = sc->xl_ifp;
+ flags = if_get(ifp, IF_FLAGS);
XL_SEL_WIN(5);
rxfilt = CSR_READ_1(sc, XL_W5_RX_FILTER);
@@ -620,25 +660,17 @@ xl_rxfilter_90x(struct xl_softc *sc)
/* Set the individual bit to receive frames for this host only. */
rxfilt |= XL_RXFILTER_INDIVIDUAL;
/* Set capture broadcast bit to capture broadcast frames. */
- if (ifp->if_flags & IFF_BROADCAST)
+ if (flags & IFF_BROADCAST)
rxfilt |= XL_RXFILTER_BROADCAST;
/* If we want promiscuous mode, set the allframes bit. */
- if (ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI)) {
- if (ifp->if_flags & IFF_PROMISC)
+ if (flags & (IFF_PROMISC | IFF_ALLMULTI)) {
+ if (flags & IFF_PROMISC)
rxfilt |= XL_RXFILTER_ALLFRAMES;
- if (ifp->if_flags & IFF_ALLMULTI)
- rxfilt |= XL_RXFILTER_ALLMULTI;
- } else {
- if_maddr_rlock(ifp);
- TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
- if (ifma->ifma_addr->sa_family != AF_LINK)
- continue;
+ if (flags & IFF_ALLMULTI)
rxfilt |= XL_RXFILTER_ALLMULTI;
- break;
- }
- if_maddr_runlock(ifp);
- }
+ } else
+ if_foreach_maddr(ifp, xl_check_maddr_90x, &rxfilt);
CSR_WRITE_2(sc, XL_COMMAND, rxfilt | XL_CMD_RX_SET_FILT);
XL_SEL_WIN(7);
@@ -646,19 +678,38 @@ xl_rxfilter_90x(struct xl_softc *sc)
/*
* 3c905B adapters have a hash filter that we can program.
- */
+ * Note: the 3c905B currently only supports a 64-bit hash table, which means
+ * we really only need 6 bits, but the manual indicates that future chip
+ * revisions will have a 256-bit hash table, hence the routine is set up to
+ * calculate 8 bits of position info in case we need it some day.
+ * Note II, The Sequel: _CURRENT_ versions of the 3c905B have a 256 bit hash
+ * table. This means we have to use all 8 bits regardless. On older cards,
+ * the upper 2 bits will be ignored. Grrrr....
+ */
+static void
+xl_check_maddr_90xB(void *arg, struct sockaddr *maddr)
+{
+ struct sockaddr_dl *sdl = (struct sockaddr_dl *)maddr;
+ struct xl_softc *sc = arg;
+ uint16_t h;
+
+ if (sdl->sdl_family != AF_LINK)
+ return;
+
+ h = ether_crc32_be(LLADDR(sdl), ETHER_ADDR_LEN) & 0xFF;
+ CSR_WRITE_2(sc, XL_COMMAND, h | XL_CMD_RX_SET_HASH | XL_HASH_SET);
+}
static void
xl_rxfilter_90xB(struct xl_softc *sc)
{
- struct ifnet *ifp;
- struct ifmultiaddr *ifma;
- int i, mcnt;
- u_int16_t h;
- u_int8_t rxfilt;
+ if_t ifp;
+ uint32_t flags;
+ uint8_t rxfilt;
XL_LOCK_ASSERT(sc);
ifp = sc->xl_ifp;
+ flags = if_get(ifp, IF_FLAGS);
XL_SEL_WIN(5);
rxfilt = CSR_READ_1(sc, XL_W5_RX_FILTER);
@@ -669,47 +720,27 @@ xl_rxfilter_90xB(struct xl_softc *sc)
/* Set the individual bit to receive frames for this host only. */
rxfilt |= XL_RXFILTER_INDIVIDUAL;
/* Set capture broadcast bit to capture broadcast frames. */
- if (ifp->if_flags & IFF_BROADCAST)
+ if (flags & IFF_BROADCAST)
rxfilt |= XL_RXFILTER_BROADCAST;
/* If we want promiscuous mode, set the allframes bit. */
- if (ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI)) {
- if (ifp->if_flags & IFF_PROMISC)
+ if (flags & (IFF_PROMISC | IFF_ALLMULTI)) {
+ if (flags & IFF_PROMISC)
rxfilt |= XL_RXFILTER_ALLFRAMES;
- if (ifp->if_flags & IFF_ALLMULTI)
+ if (flags & IFF_ALLMULTI)
rxfilt |= XL_RXFILTER_ALLMULTI;
} else {
/* First, zot all the existing hash bits. */
- for (i = 0; i < XL_HASHFILT_SIZE; i++)
+ for (int i = 0; i < XL_HASHFILT_SIZE; i++)
CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_SET_HASH | i);
/* Now program new ones. */
- mcnt = 0;
- if_maddr_rlock(ifp);
- TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
- if (ifma->ifma_addr->sa_family != AF_LINK)
- continue;
- /*
- * Note: the 3c905B currently only supports a 64-bit
- * hash table, which means we really only need 6 bits,
- * but the manual indicates that future chip revisions
- * will have a 256-bit hash table, hence the routine
- * is set up to calculate 8 bits of position info in
- * case we need it some day.
- * Note II, The Sequel: _CURRENT_ versions of the
- * 3c905B have a 256 bit hash table. This means we have
- * to use all 8 bits regardless. On older cards, the
- * upper 2 bits will be ignored. Grrrr....
- */
- h = ether_crc32_be(LLADDR((struct sockaddr_dl *)
- ifma->ifma_addr), ETHER_ADDR_LEN) & 0xFF;
- CSR_WRITE_2(sc, XL_COMMAND,
- h | XL_CMD_RX_SET_HASH | XL_HASH_SET);
- mcnt++;
- }
- if_maddr_runlock(ifp);
- if (mcnt > 0)
- rxfilt |= XL_RXFILTER_MULTIHASH;
+ if_foreach_maddr(ifp, xl_check_maddr_90xB, sc);
+ /*
+ * XXXGL: a bit dirty, but easier then make a context
+ * containing softc and rxfilt.
+ */
+ if_foreach_maddr(ifp, xl_check_maddr_90x, &rxfilt);
}
CSR_WRITE_2(sc, XL_COMMAND, rxfilt | XL_CMD_RX_SET_FILT);
@@ -1062,12 +1093,18 @@ xl_choose_xcvr(struct xl_softc *sc, int
static int
xl_attach(device_t dev)
{
+ struct if_attach_args ifat = {
+ .ifat_version = IF_ATTACH_VERSION,
+ .ifat_drv = &xl_ifdrv,
+ .ifat_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST,
+ .ifat_capabilities = IFCAP_VLAN_MTU | IFCAP_LINKSTATE,
+ };
u_char eaddr[ETHER_ADDR_LEN];
u_int16_t sinfo2, xcvr[2];
struct xl_softc *sc;
- struct ifnet *ifp;
+ if_t ifp;
int media, pmcap;
- int error = 0, phy, rid, res, unit;
+ int error = 0, rid, res, unit;
uint16_t did;
sc = device_get_softc(dev);
@@ -1191,16 +1228,6 @@ xl_attach(device_t dev)
goto fail;
}
- /* Initialize interface name. */
- ifp = sc->xl_ifp = if_alloc(IFT_ETHER);
- if (ifp == NULL) {
- device_printf(dev, "can not if_alloc()\n");
- error = ENOSPC;
- goto fail;
- }
- ifp->if_softc = sc;
- if_initname(ifp, device_get_name(dev), device_get_unit(dev));
-
/* Reset the adapter. */
XL_LOCK(sc);
xl_reset(sc);
@@ -1338,29 +1365,6 @@ xl_attach(device_t dev)
/* Set the TX start threshold for best performance. */
sc->xl_tx_thresh = XL_MIN_FRAMELEN;
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
- ifp->if_ioctl = xl_ioctl;
- ifp->if_capabilities = IFCAP_VLAN_MTU;
- if (sc->xl_type == XL_TYPE_905B) {
- ifp->if_hwassist = XL905B_CSUM_FEATURES;
-#ifdef XL905B_TXCSUM_BROKEN
- ifp->if_capabilities |= IFCAP_RXCSUM;
-#else
- ifp->if_capabilities |= IFCAP_HWCSUM;
-#endif
- }
- if ((sc->xl_flags & XL_FLAG_WOL) != 0)
- ifp->if_capabilities |= IFCAP_WOL_MAGIC;
- ifp->if_capenable = ifp->if_capabilities;
-#ifdef DEVICE_POLLING
- ifp->if_capabilities |= IFCAP_POLLING;
-#endif
- ifp->if_start = xl_start;
- ifp->if_init = xl_init;
- IFQ_SET_MAXLEN(&ifp->if_snd, XL_TX_LIST_CNT - 1);
- ifp->if_snd.ifq_drv_maxlen = XL_TX_LIST_CNT - 1;
- IFQ_SET_READY(&ifp->if_snd);
-
/*
* Now we have to see what sort of media we have.
* This includes probing for an MII interace and a
@@ -1381,6 +1385,9 @@ xl_attach(device_t dev)
if (sc->xl_media & XL_MEDIAOPT_MII ||
sc->xl_media & XL_MEDIAOPT_BTX ||
sc->xl_media & XL_MEDIAOPT_BT4) {
+ struct mii_data *mii;
+ int phy;
+
if (bootverbose)
device_printf(dev, "found MII/AUTO\n");
xl_setcfg(sc);
@@ -1393,14 +1400,16 @@ xl_attach(device_t dev)
phy = MII_PHY_ANY;
if ((sc->xl_flags & XL_FLAG_PHYOK) == 0)
phy = 24;
- error = mii_attach(dev, &sc->xl_miibus, ifp, xl_ifmedia_upd,
+ error = mii_attach(dev, &sc->xl_miibus, xl_ifmedia_upd,
xl_ifmedia_sts, BMSR_DEFCAPMASK, phy, MII_OFFSET_ANY,
sc->xl_type == XL_TYPE_905B ? MIIF_DOPAUSE : 0);
if (error != 0) {
device_printf(dev, "attaching PHYs failed\n");
goto fail;
}
- goto done;
+ mii = device_get_softc(sc->xl_miibus);
+ ifat.ifat_baudrate = ifmedia_baudrate(mii->mii_media_active);
+ goto media_done;
}
/*
@@ -1462,29 +1471,45 @@ xl_attach(device_t dev)
if (sc->xl_miibus == NULL)
ifmedia_set(&sc->ifmedia, media);
+ ifat.ifat_baudrate = ifmedia_baudrate(sc->ifmedia.ifm_media);
-done:
+media_done:
if (sc->xl_flags & XL_FLAG_NO_XCVR_PWR) {
XL_SEL_WIN(0);
CSR_WRITE_2(sc, XL_W0_MFG_ID, XL_NO_XCVR_PWR_MAGICBITS);
}
- /*
- * Call MI attach routine.
- */
- ether_ifattach(ifp, eaddr);
-
error = bus_setup_intr(dev, sc->xl_irq, INTR_TYPE_NET | INTR_MPSAFE,
NULL, xl_intr, sc, &sc->xl_intrhand);
if (error) {
device_printf(dev, "couldn't set up irq\n");
- ether_ifdetach(ifp);
goto fail;
}
+ /* Initialize interface. */
+ ifat.ifat_softc = sc;
+ ifat.ifat_dunit = device_get_unit(dev);
+ ifat.ifat_lla = eaddr;
+ if (sc->xl_type == XL_TYPE_905B) {
+ ifat.ifat_hwassist = XL905B_CSUM_FEATURES;
+#ifdef XL905B_TXCSUM_BROKEN
+ ifat.ifat_capabilities |= IFCAP_RXCSUM;
+#else
+ ifat.ifat_capabilities |= IFCAP_HWCSUM;
+#endif
+ }
+ if ((sc->xl_flags & XL_FLAG_WOL) != 0)
+ ifat.ifat_capabilities |= IFCAP_WOL_MAGIC;
+ ifat.ifat_capenable = ifat.ifat_capabilities;
+#ifdef DEVICE_POLLING
+ ifat.ifat_capabilities |= IFCAP_POLLING;
+#endif
+ ifp = sc->xl_ifp = if_attach(&ifat);
+
+ return (0);
+
fail:
- if (error)
- xl_detach(dev);
+ xl_detach(dev);
return (error);
}
@@ -1553,7 +1578,7 @@ static int
xl_detach(device_t dev)
{
struct xl_softc *sc;
- struct ifnet *ifp;
+ if_t ifp;
int rid, res;
sc = device_get_softc(dev);
@@ -1581,7 +1606,7 @@ xl_detach(device_t dev)
XL_UNLOCK(sc);
taskqueue_drain(taskqueue_swi, &sc->xl_task);
callout_drain(&sc->xl_tick_callout);
- ether_ifdetach(ifp);
+ if_detach(ifp);
}
if (sc->xl_miibus)
device_delete_child(dev, sc->xl_miibus);
@@ -1598,9 +1623,6 @@ xl_detach(device_t dev)
if (sc->xl_res)
bus_release_resource(dev, res, rid, sc->xl_res);
- if (ifp)
- if_free(ifp);
-
if (sc->xl_mtag) {
bus_dmamap_destroy(sc->xl_mtag, sc->xl_tmpmap);
bus_dma_tag_destroy(sc->xl_mtag);
@@ -1914,7 +1936,7 @@ again:
m->m_pkthdr.rcvif = ifp;
m->m_pkthdr.len = m->m_len = total_len;
- if (ifp->if_capenable & IFCAP_RXCSUM) {
+ if (if_get(ifp, IF_CAPENABLE) & IFCAP_RXCSUM) {
/* Do IP checksum checking. */
if (rxstat & XL_RXSTAT_IPCKOK)
m->m_pkthdr.csum_flags |= CSUM_IP_CHECKED;
@@ -1931,7 +1953,7 @@ again:
}
XL_UNLOCK(sc);
- (*ifp->if_input)(ifp, m);
+ if_input(ifp, m);
XL_LOCK(sc);
/*
@@ -1939,7 +1961,7 @@ again:
* might have been stopped while we were passing the last
* packet up the network stack.
*/
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
+ if (!(sc->xl_flags & XL_FLAG_RUNNING))
return (rx_npkts);
}
@@ -1976,7 +1998,7 @@ xl_rxeof_task(void *arg, int pending)
struct xl_softc *sc = (struct xl_softc *)arg;
XL_LOCK(sc);
- if (sc->xl_ifp->if_drv_flags & IFF_DRV_RUNNING)
+ if (sc->xl_flags & XL_FLAG_RUNNING)
xl_rxeof(sc);
XL_UNLOCK(sc);
}
@@ -1989,7 +2011,6 @@ static void
xl_txeof(struct xl_softc *sc)
{
struct xl_chain *cur_tx;
- struct ifnet *ifp = sc->xl_ifp;
XL_LOCK_ASSERT(sc);
@@ -2012,11 +2033,9 @@ xl_txeof(struct xl_softc *sc)
bus_dmamap_sync(sc->xl_mtag, cur_tx->xl_map,
BUS_DMASYNC_POSTWRITE);
bus_dmamap_unload(sc->xl_mtag, cur_tx->xl_map);
+ if_inc_txcounters(sc->xl_ifp, cur_tx->xl_mbuf);
m_freem(cur_tx->xl_mbuf);
cur_tx->xl_mbuf = NULL;
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
-
cur_tx->xl_next = sc->xl_cdata.xl_tx_free;
sc->xl_cdata.xl_tx_free = cur_tx;
}
@@ -2038,7 +2057,6 @@ static void
xl_txeof_90xB(struct xl_softc *sc)
{
struct xl_chain *cur_tx = NULL;
- struct ifnet *ifp = sc->xl_ifp;
int idx;
XL_LOCK_ASSERT(sc);
@@ -2057,12 +2075,11 @@ xl_txeof_90xB(struct xl_softc *sc)
bus_dmamap_sync(sc->xl_mtag, cur_tx->xl_map,
BUS_DMASYNC_POSTWRITE);
bus_dmamap_unload(sc->xl_mtag, cur_tx->xl_map);
+ if_inc_txcounters(sc->xl_ifp, cur_tx->xl_mbuf);
m_freem(cur_tx->xl_mbuf);
cur_tx->xl_mbuf = NULL;
}
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
-
sc->xl_cdata.xl_tx_cnt--;
XL_INC(idx, XL_TX_LIST_CNT);
}
@@ -2070,9 +2087,6 @@ xl_txeof_90xB(struct xl_softc *sc)
if (sc->xl_cdata.xl_tx_cnt == 0)
sc->xl_wdog_timer = 0;
sc->xl_cdata.xl_tx_cons = idx;
-
- if (cur_tx != NULL)
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
}
/*
@@ -2167,7 +2181,7 @@ xl_intr(void *arg)
break;
CSR_WRITE_2(sc, XL_COMMAND,
XL_CMD_INTR_ACK|(status & XL_INTRS));
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+ if ((sc->xl_flags & XL_FLAG_RUNNING) == 0)
break;
if (status & XL_STAT_UP_COMPLETE) {
@@ -2190,7 +2204,7 @@ xl_intr(void *arg)
}
if (status & XL_STAT_ADFAIL) {
- ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
+ sc->xl_flags &= ~XL_FLAG_RUNNING;
xl_init_locked(sc);
break;
}
@@ -2199,12 +2213,11 @@ xl_intr(void *arg)
xl_stats_update(sc);
}
- if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd) &&
- ifp->if_drv_flags & IFF_DRV_RUNNING) {
+ if (if_snd_len(ifp) && sc->xl_flags & XL_FLAG_RUNNING) {
if (sc->xl_type == XL_TYPE_905B)
- xl_start_90xB_locked(ifp);
+ xl_start_90xB_locked(sc);
else
- xl_start_locked(ifp);
+ xl_start_locked(sc);
}
XL_UNLOCK(sc);
@@ -2218,7 +2231,7 @@ xl_poll(struct ifnet *ifp, enum poll_cmd
int rx_npkts = 0;
XL_LOCK(sc);
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+ if (sc->xl_flags & XL_FLAG_RUNNING)
rx_npkts = xl_poll_locked(ifp, cmd, count);
XL_UNLOCK(sc);
return (rx_npkts);
@@ -2239,7 +2252,7 @@ xl_poll_locked(struct ifnet *ifp, enum p
else
xl_txeof(sc);
- if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
+ if (if_snd_len(ifp)) {
if (sc->xl_type == XL_TYPE_905B)
xl_start_90xB_locked(ifp);
else
@@ -2260,7 +2273,7 @@ xl_poll_locked(struct ifnet *ifp, enum p
}
if (status & XL_STAT_ADFAIL) {
- ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
+ sc->xl_flags &= ~XL_FLAG_RUNNING;
xl_init_locked(sc);
}
@@ -2429,25 +2442,29 @@ xl_encap(struct xl_softc *sc, struct xl_
* physical addresses.
*/
-static void
-xl_start(struct ifnet *ifp)
+static int
+xl_transmit(if_t ifp, struct mbuf *m)
{
- struct xl_softc *sc = ifp->if_softc;
+ struct xl_softc *sc;
+ int error;
- XL_LOCK(sc);
+ if ((error = if_snd_enqueue(ifp, m)) != 0)
+ return (error);
+ sc = if_getsoftc(ifp, IF_DRIVER_SOFTC);
+ if (XL_TRY_LOCK(sc) == 0)
+ return (0);
if (sc->xl_type == XL_TYPE_905B)
- xl_start_90xB_locked(ifp);
+ xl_start_90xB_locked(sc);
else
- xl_start_locked(ifp);
-
+ xl_start_locked(sc);
XL_UNLOCK(sc);
+ return (0);
}
static void
-xl_start_locked(struct ifnet *ifp)
+xl_start_locked(struct xl_softc *sc)
{
- struct xl_softc *sc = ifp->if_softc;
struct mbuf *m_head;
struct xl_chain *prev = NULL, *cur_tx = NULL, *start_tx;
struct xl_chain *prev_tx;
@@ -2455,8 +2472,7 @@ xl_start_locked(struct ifnet *ifp)
XL_LOCK_ASSERT(sc);
- if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
- IFF_DRV_RUNNING)
+ if ((sc->xl_flags & XL_FLAG_RUNNING) != XL_FLAG_RUNNING)
return;
/*
* Check for an available queue slot. If there are none,
@@ -2465,20 +2481,14 @@ xl_start_locked(struct ifnet *ifp)
if (sc->xl_cdata.xl_tx_free == NULL) {
xl_txeoc(sc);
xl_txeof(sc);
- if (sc->xl_cdata.xl_tx_free == NULL) {
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+ if (sc->xl_cdata.xl_tx_free == NULL)
return;
- }
}
start_tx = sc->xl_cdata.xl_tx_free;
- for (; !IFQ_DRV_IS_EMPTY(&ifp->if_snd) &&
- sc->xl_cdata.xl_tx_free != NULL;) {
- IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head);
- if (m_head == NULL)
- break;
-
+ while (sc->xl_cdata.xl_tx_free != NULL &&
+ ((m_head = if_snd_dequeue(sc->xl_ifp)) != NULL)) {
/* Pick a descriptor off the free list. */
prev_tx = cur_tx;
cur_tx = sc->xl_cdata.xl_tx_free;
@@ -2489,8 +2499,7 @@ xl_start_locked(struct ifnet *ifp)
cur_tx = prev_tx;
if (m_head == NULL)
break;
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- IFQ_DRV_PREPEND(&ifp->if_snd, m_head);
+ if_snd_prepend(sc->xl_ifp, m_head);
break;
}
@@ -2508,7 +2517,7 @@ xl_start_locked(struct ifnet *ifp)
* If there's a BPF listener, bounce a copy of this frame
* to him.
*/
- BPF_MTAP(ifp, cur_tx->xl_mbuf);
+ if_mtap(sc->xl_ifp, cur_tx->xl_mbuf, NULL, 0);
}
/*
@@ -2577,9 +2586,8 @@ xl_start_locked(struct ifnet *ifp)
}
static void
-xl_start_90xB_locked(struct ifnet *ifp)
+xl_start_90xB_locked(struct xl_softc *sc)
{
- struct xl_softc *sc = ifp->if_softc;
struct mbuf *m_head;
struct xl_chain *prev = NULL, *cur_tx = NULL, *start_tx;
struct xl_chain *prev_tx;
@@ -2587,24 +2595,15 @@ xl_start_90xB_locked(struct ifnet *ifp)
XL_LOCK_ASSERT(sc);
- if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
- IFF_DRV_RUNNING)
+ if ((sc->xl_flags & XL_FLAG_RUNNING) != XL_FLAG_RUNNING)
return;
idx = sc->xl_cdata.xl_tx_prod;
start_tx = &sc->xl_cdata.xl_tx_chain[idx];
- for (; !IFQ_DRV_IS_EMPTY(&ifp->if_snd) &&
- sc->xl_cdata.xl_tx_chain[idx].xl_mbuf == NULL;) {
- if ((XL_TX_LIST_CNT - sc->xl_cdata.xl_tx_cnt) < 3) {
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- break;
- }
-
- IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head);
- if (m_head == NULL)
- break;
-
+ while (sc->xl_cdata.xl_tx_chain[idx].xl_mbuf == NULL &&
+ ((XL_TX_LIST_CNT - sc->xl_cdata.xl_tx_cnt) >= 3) &&
+ ((m_head = if_snd_dequeue(sc->xl_ifp)) != NULL)) {
prev_tx = cur_tx;
cur_tx = &sc->xl_cdata.xl_tx_chain[idx];
@@ -2614,8 +2613,7 @@ xl_start_90xB_locked(struct ifnet *ifp)
cur_tx = prev_tx;
if (m_head == NULL)
break;
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- IFQ_DRV_PREPEND(&ifp->if_snd, m_head);
+ if_snd_prepend(sc->xl_ifp, m_head);
break;
}
@@ -2628,7 +2626,7 @@ xl_start_90xB_locked(struct ifnet *ifp)
* If there's a BPF listener, bounce a copy of this frame
* to him.
*/
- BPF_MTAP(ifp, cur_tx->xl_mbuf);
+ if_mtap(sc->xl_ifp, cur_tx->xl_mbuf, NULL, 0);
XL_INC(idx, XL_TX_LIST_CNT);
sc->xl_cdata.xl_tx_cnt++;
@@ -2674,13 +2672,12 @@ xl_init(void *xsc)
static void
xl_init_locked(struct xl_softc *sc)
{
- struct ifnet *ifp = sc->xl_ifp;
int error, i;
struct mii_data *mii = NULL;
XL_LOCK_ASSERT(sc);
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
+ if ((sc->xl_flags & XL_FLAG_RUNNING) != 0)
return;
/*
* Cancel pending I/O and free all RX/TX buffers.
@@ -2714,7 +2711,7 @@ xl_init_locked(struct xl_softc *sc)
XL_SEL_WIN(2);
for (i = 0; i < ETHER_ADDR_LEN; i++) {
CSR_WRITE_1(sc, XL_W2_STATION_ADDR_LO + i,
- IF_LLADDR(sc->xl_ifp)[i]);
+ if_lladdr(sc->xl_ifp)[i]);
}
/* Clear the station mask. */
@@ -2869,8 +2866,7 @@ xl_init_locked(struct xl_softc *sc)
/* Select window 7 for normal operations. */
XL_SEL_WIN(7);
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+ sc->xl_flags |= XL_FLAG_RUNNING;
sc->xl_wdog_timer = 0;
callout_reset(&sc->xl_tick_callout, hz, xl_tick, sc);
@@ -2882,10 +2878,11 @@ xl_init_locked(struct xl_softc *sc)
static int
xl_ifmedia_upd(struct ifnet *ifp)
{
- struct xl_softc *sc = ifp->if_softc;
+ struct xl_softc *sc;
struct ifmedia *ifm = NULL;
struct mii_data *mii = NULL;
+ sc = if_getsoftc(ifp, IF_DRIVER_SOFTC);
XL_LOCK(sc);
if (sc->xl_miibus != NULL)
@@ -2908,7 +2905,7 @@ xl_ifmedia_upd(struct ifnet *ifp)
if (sc->xl_media & XL_MEDIAOPT_MII ||
sc->xl_media & XL_MEDIAOPT_BTX ||
sc->xl_media & XL_MEDIAOPT_BT4) {
- ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
+ sc->xl_flags &= ~XL_FLAG_RUNNING;
xl_init_locked(sc);
} else {
xl_setmode(sc, ifm->ifm_media);
@@ -2925,11 +2922,12 @@ xl_ifmedia_upd(struct ifnet *ifp)
static void
xl_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
{
- struct xl_softc *sc = ifp->if_softc;
+ struct xl_softc *sc;
u_int32_t icfg;
u_int16_t status = 0;
struct mii_data *mii = NULL;
+ sc = if_getsoftc(ifp, IF_DRIVER_SOFTC);
XL_LOCK(sc);
if (sc->xl_miibus != NULL)
@@ -2997,33 +2995,37 @@ xl_ifmedia_sts(struct ifnet *ifp, struct
static int
xl_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
{
- struct xl_softc *sc = ifp->if_softc;
+ struct xl_softc *sc;
struct ifreq *ifr = (struct ifreq *) data;
- int error = 0, mask;
+ uint32_t flags, mask;
+ int error = 0;
struct mii_data *mii = NULL;
+ sc = if_getsoftc(ifp, IF_DRIVER_SOFTC);
+
switch (command) {
case SIOCSIFFLAGS:
XL_LOCK(sc);
- if (ifp->if_flags & IFF_UP) {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
- (ifp->if_flags ^ sc->xl_if_flags) &
+ flags = if_get(ifp, IF_FLAGS);
+ if (flags & IFF_UP) {
+ if (sc->xl_flags & XL_FLAG_RUNNING &&
+ (flags ^ sc->xl_if_flags) &
(IFF_PROMISC | IFF_ALLMULTI))
xl_rxfilter(sc);
else
xl_init_locked(sc);
} else {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+ if (sc->xl_flags & XL_FLAG_RUNNING)
xl_stop(sc);
}
- sc->xl_if_flags = ifp->if_flags;
+ sc->xl_if_flags = flags;
XL_UNLOCK(sc);
break;
case SIOCADDMULTI:
case SIOCDELMULTI:
/* XXX Downcall from if_addmulti() possibly with locks held. */
XL_LOCK(sc);
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+ if (sc->xl_flags & XL_FLAG_RUNNING)
xl_rxfilter(sc);
XL_UNLOCK(sc);
break;
@@ -3039,19 +3041,19 @@ xl_ioctl(struct ifnet *ifp, u_long comma
&mii->mii_media, command);
break;
case SIOCSIFCAP:
- mask = ifr->ifr_reqcap ^ ifp->if_capenable;
+ mask = ifr->ifr_reqcap ^ if_get(ifp, IF_CAPENABLE);
#ifdef DEVICE_POLLING
if ((mask & IFCAP_POLLING) != 0 &&
- (ifp->if_capabilities & IFCAP_POLLING) != 0) {
- ifp->if_capenable ^= IFCAP_POLLING;
- if ((ifp->if_capenable & IFCAP_POLLING) != 0) {
+ (if_get(ifp, IF_CAPABILITIES) & IFCAP_POLLING) != 0) {
+ if_xorflags(ifp, IF_CAPENABLE, IFCAP_POLLING);
+ if ((if_get(ifp, IF_CAPENABLE) & IFCAP_POLLING) != 0) {
error = ether_poll_register(xl_poll, ifp);
if (error)
break;
XL_LOCK(sc);
/* Disable interrupts */
CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ENB|0);
- ifp->if_capenable |= IFCAP_POLLING;
+ if_addflags(ifp, IF_CAPENABLE, IFCAP_POLLING);
XL_UNLOCK(sc);
} else {
error = ether_poll_deregister(ifp);
@@ -3070,23 +3072,25 @@ xl_ioctl(struct ifnet *ifp, u_long comma
#endif /* DEVICE_POLLING */
XL_LOCK(sc);
if ((mask & IFCAP_TXCSUM) != 0 &&
- (ifp->if_capabilities & IFCAP_TXCSUM) != 0) {
- ifp->if_capenable ^= IFCAP_TXCSUM;
- if ((ifp->if_capenable & IFCAP_TXCSUM) != 0)
- ifp->if_hwassist |= XL905B_CSUM_FEATURES;
+ (if_get(ifp, IF_CAPABILITIES) & IFCAP_TXCSUM) != 0) {
+ if_xorflags(ifp, IF_CAPENABLE, IFCAP_TXCSUM);
+ if ((if_get(ifp, IF_CAPENABLE) & IFCAP_TXCSUM) != 0)
+ if_addflags(ifp, IF_HWASSIST,
+ XL905B_CSUM_FEATURES);
else
- ifp->if_hwassist &= ~XL905B_CSUM_FEATURES;
+ if_clrflags(ifp, IF_HWASSIST,
+ XL905B_CSUM_FEATURES);
}
if ((mask & IFCAP_RXCSUM) != 0 &&
- (ifp->if_capabilities & IFCAP_RXCSUM) != 0)
- ifp->if_capenable ^= IFCAP_RXCSUM;
+ (if_get(ifp, IF_CAPABILITIES) & IFCAP_RXCSUM) != 0)
+ if_xorflags(ifp, IF_CAPENABLE, IFCAP_RXCSUM);
if ((mask & IFCAP_WOL_MAGIC) != 0 &&
- (ifp->if_capabilities & IFCAP_WOL_MAGIC) != 0)
- ifp->if_capenable ^= IFCAP_WOL_MAGIC;
+ (if_get(ifp, IF_CAPABILITIES) & IFCAP_WOL_MAGIC) != 0)
+ if_xorflags(ifp, IF_CAPENABLE, IFCAP_WOL_MAGIC);
XL_UNLOCK(sc);
break;
default:
- error = ether_ioctl(ifp, command, data);
+ error = EOPNOTSUPP;
break;
}
@@ -3132,14 +3136,14 @@ xl_watchdog(struct xl_softc *sc)
device_printf(sc->xl_dev,
"no carrier - transceiver cable problem?\n");
- ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
+ sc->xl_flags &= ~XL_FLAG_RUNNING;
xl_init_locked(sc);
- if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
+ if (if_snd_len(ifp)) {
if (sc->xl_type == XL_TYPE_905B)
- xl_start_90xB_locked(ifp);
+ xl_start_90xB_locked(sc);
else
- xl_start_locked(ifp);
+ xl_start_locked(sc);
}
return (EJUSTRETURN);
@@ -3153,7 +3157,6 @@ static void
xl_stop(struct xl_softc *sc)
{
register int i;
- struct ifnet *ifp = sc->xl_ifp;
XL_LOCK_ASSERT(sc);
@@ -3215,7 +3218,7 @@ xl_stop(struct xl_softc *sc)
if (sc->xl_ldata.xl_tx_list != NULL)
bzero(sc->xl_ldata.xl_tx_list, XL_TX_LIST_SZ);
- ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+ sc->xl_flags &= ~XL_FLAG_RUNNING;
}
/*
@@ -3255,8 +3258,8 @@ xl_resume(device_t dev)
XL_LOCK(sc);
- if (ifp->if_flags & IFF_UP) {
- ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
+ if (if_get(ifp, IF_FLAGS) & IFF_UP) {
+ sc->xl_flags &= ~XL_FLAG_RUNNING;
xl_init_locked(sc);
}
@@ -3279,16 +3282,16 @@ xl_setwol(struct xl_softc *sc)
/* Clear any pending PME events. */
CSR_READ_2(sc, XL_W7_BM_PME);
cfg = 0;
- if ((ifp->if_capenable & IFCAP_WOL_MAGIC) != 0)
+ if ((if_get(ifp, IF_CAPENABLE) & IFCAP_WOL_MAGIC) != 0)
cfg |= XL_BM_PME_MAGIC;
CSR_WRITE_2(sc, XL_W7_BM_PME, cfg);
/* Enable RX. */
- if ((ifp->if_capenable & IFCAP_WOL_MAGIC) != 0)
+ if ((if_get(ifp, IF_CAPENABLE) & IFCAP_WOL_MAGIC) != 0)
CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_ENABLE);
/* Request PME. */
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-projects
mailing list