svn commit: r367883 - head/sys/arm/allwinner

Emmanuel Vadot manu at FreeBSD.org
Fri Nov 20 11:29:38 UTC 2020


Author: manu
Date: Fri Nov 20 11:29:37 2020
New Revision: 367883
URL: https://svnweb.freebsd.org/changeset/base/367883

Log:
  if_awg: Reorder functions and sort them by usage
  
  No functional changes intended

Modified:
  head/sys/arm/allwinner/if_awg.c

Modified: head/sys/arm/allwinner/if_awg.c
==============================================================================
--- head/sys/arm/allwinner/if_awg.c	Fri Nov 20 11:29:20 2020	(r367882)
+++ head/sys/arm/allwinner/if_awg.c	Fri Nov 20 11:29:37 2020	(r367883)
@@ -217,7 +217,10 @@ static struct resource_spec awg_spec[] = {
 };
 
 static void awg_txeof(struct awg_softc *sc);
+static void awg_start_locked(struct awg_softc *sc);
 
+static void awg_tick(void *softc);
+
 static int awg_parse_delay(device_t dev, uint32_t *tx_delay,
     uint32_t *rx_delay);
 static uint32_t syscon_read_emac_clk_reg(device_t dev);
@@ -225,6 +228,10 @@ static void syscon_write_emac_clk_reg(device_t dev, ui
 static phandle_t awg_get_phy_node(device_t dev);
 static bool awg_has_internal_phy(device_t dev);
 
+/*
+ * MII functions
+ */
+
 static int
 awg_miibus_readreg(device_t dev, int phy, int reg)
 {
@@ -346,6 +353,10 @@ awg_miibus_statchg(device_t dev)
 	WR4(sc, EMAC_TX_FLOW_CTL, val);
 }
 
+/*
+ * Media functions
+ */
+
 static void
 awg_media_status(if_t ifp, struct ifmediareq *ifmr)
 {
@@ -379,6 +390,217 @@ awg_media_change(if_t ifp)
 	return (error);
 }
 
+/*
+ * Core functions
+ */
+
+/* Bit Reversal - http://aggregate.org/MAGIC/#Bit%20Reversal */
+static uint32_t
+bitrev32(uint32_t x)
+{
+	x = (((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1));
+	x = (((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2));
+	x = (((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4));
+	x = (((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8));
+
+	return (x >> 16) | (x << 16);
+}
+
+static u_int
+awg_hash_maddr(void *arg, struct sockaddr_dl *sdl, u_int cnt)
+{
+	uint32_t crc, hashreg, hashbit, *hash = arg;
+
+	crc = ether_crc32_le(LLADDR(sdl), ETHER_ADDR_LEN) & 0x7f;
+	crc = bitrev32(~crc) >> 26;
+	hashreg = (crc >> 5);
+	hashbit = (crc & 0x1f);
+	hash[hashreg] |= (1 << hashbit);
+
+	return (1);
+}
+
+static void
+awg_setup_rxfilter(struct awg_softc *sc)
+{
+	uint32_t val, hash[2], machi, maclo;
+	uint8_t *eaddr;
+	if_t ifp;
+
+	AWG_ASSERT_LOCKED(sc);
+
+	ifp = sc->ifp;
+	val = 0;
+	hash[0] = hash[1] = 0;
+
+	if (if_getflags(ifp) & IFF_PROMISC)
+		val |= DIS_ADDR_FILTER;
+	else if (if_getflags(ifp) & IFF_ALLMULTI) {
+		val |= RX_ALL_MULTICAST;
+		hash[0] = hash[1] = ~0;
+	} else if (if_foreach_llmaddr(ifp, awg_hash_maddr, hash) > 0)
+		val |= HASH_MULTICAST;
+
+	/* Write our unicast address */
+	eaddr = IF_LLADDR(ifp);
+	machi = (eaddr[5] << 8) | eaddr[4];
+	maclo = (eaddr[3] << 24) | (eaddr[2] << 16) | (eaddr[1] << 8) |
+	   (eaddr[0] << 0);
+	WR4(sc, EMAC_ADDR_HIGH(0), machi);
+	WR4(sc, EMAC_ADDR_LOW(0), maclo);
+
+	/* Multicast hash filters */
+	WR4(sc, EMAC_RX_HASH_0, hash[1]);
+	WR4(sc, EMAC_RX_HASH_1, hash[0]);
+
+	/* RX frame filter config */
+	WR4(sc, EMAC_RX_FRM_FLT, val);
+}
+
+static void
+awg_setup_core(struct awg_softc *sc)
+{
+	uint32_t val;
+
+	AWG_ASSERT_LOCKED(sc);
+	/* Configure DMA burst length and priorities */
+	val = awg_burst_len << BASIC_CTL_BURST_LEN_SHIFT;
+	if (awg_rx_tx_pri)
+		val |= BASIC_CTL_RX_TX_PRI;
+	WR4(sc, EMAC_BASIC_CTL_1, val);
+
+}
+
+static void
+awg_enable_mac(struct awg_softc *sc, bool enable)
+{
+	uint32_t tx, rx;
+
+	AWG_ASSERT_LOCKED(sc);
+
+	tx = RD4(sc, EMAC_TX_CTL_0);
+	rx = RD4(sc, EMAC_RX_CTL_0);
+	if (enable) {
+		tx |= TX_EN;
+		rx |= RX_EN | CHECK_CRC;
+	} else {
+		tx &= ~TX_EN;
+		rx &= ~(RX_EN | CHECK_CRC);
+	}
+
+	WR4(sc, EMAC_TX_CTL_0, tx);
+	WR4(sc, EMAC_RX_CTL_0, rx);
+}
+
+static void 
+awg_get_eaddr(device_t dev, uint8_t *eaddr)
+{
+	struct awg_softc *sc;
+	uint32_t maclo, machi, rnd;
+	u_char rootkey[16];
+	uint32_t rootkey_size;
+
+	sc = device_get_softc(dev);
+
+	machi = RD4(sc, EMAC_ADDR_HIGH(0)) & 0xffff;
+	maclo = RD4(sc, EMAC_ADDR_LOW(0));
+
+	rootkey_size = sizeof(rootkey);
+	if (maclo == 0xffffffff && machi == 0xffff) {
+		/* MAC address in hardware is invalid, create one */
+		if (aw_sid_get_fuse(AW_SID_FUSE_ROOTKEY, rootkey,
+		    &rootkey_size) == 0 &&
+		    (rootkey[3] | rootkey[12] | rootkey[13] | rootkey[14] |
+		     rootkey[15]) != 0) {
+			/* MAC address is derived from the root key in SID */
+			maclo = (rootkey[13] << 24) | (rootkey[12] << 16) |
+				(rootkey[3] << 8) | 0x02;
+			machi = (rootkey[15] << 8) | rootkey[14];
+		} else {
+			/* Create one */
+			rnd = arc4random();
+			maclo = 0x00f2 | (rnd & 0xffff0000);
+			machi = rnd & 0xffff;
+		}
+	}
+
+	eaddr[0] = maclo & 0xff;
+	eaddr[1] = (maclo >> 8) & 0xff;
+	eaddr[2] = (maclo >> 16) & 0xff;
+	eaddr[3] = (maclo >> 24) & 0xff;
+	eaddr[4] = machi & 0xff;
+	eaddr[5] = (machi >> 8) & 0xff;
+}
+
+/*
+ * DMA functions
+ */
+
+static void
+awg_enable_dma_intr(struct awg_softc *sc)
+{
+	/* Enable interrupts */
+	WR4(sc, EMAC_INT_EN, RX_INT_EN | TX_INT_EN | TX_BUF_UA_INT_EN);
+}
+
+static void
+awg_disable_dma_intr(struct awg_softc *sc)
+{
+	/* Disable interrupts */
+	WR4(sc, EMAC_INT_EN, 0);
+}
+
+static void
+awg_init_dma(struct awg_softc *sc)
+{
+	uint32_t val;
+
+	AWG_ASSERT_LOCKED(sc);
+
+	/* Enable interrupts */
+#ifdef DEVICE_POLLING
+	if ((if_getcapenable(sc->ifp) & IFCAP_POLLING) == 0)
+		awg_enable_dma_intr(sc);
+	else
+		awg_disable_dma_intr(sc);
+#else
+	awg_enable_dma_intr(sc);
+#endif
+
+	/* Enable transmit DMA */
+	val = RD4(sc, EMAC_TX_CTL_1);
+	WR4(sc, EMAC_TX_CTL_1, val | TX_DMA_EN | TX_MD | TX_NEXT_FRAME);
+
+	/* Enable receive DMA */
+	val = RD4(sc, EMAC_RX_CTL_1);
+	WR4(sc, EMAC_RX_CTL_1, val | RX_DMA_EN | RX_MD);
+}
+
+static void
+awg_stop_dma(struct awg_softc *sc)
+{
+	uint32_t val;
+
+	AWG_ASSERT_LOCKED(sc);
+
+	/* Stop transmit DMA and flush data in the TX FIFO */
+	val = RD4(sc, EMAC_TX_CTL_1);
+	val &= ~TX_DMA_EN;
+	val |= FLUSH_TX_FIFO;
+	WR4(sc, EMAC_TX_CTL_1, val);
+
+	/* Disable interrupts */
+	awg_disable_dma_intr(sc);
+
+	/* Disable transmit DMA */
+	val = RD4(sc, EMAC_TX_CTL_1);
+	WR4(sc, EMAC_TX_CTL_1, val & ~TX_DMA_EN);
+
+	/* Disable receive DMA */
+	val = RD4(sc, EMAC_RX_CTL_1);
+	WR4(sc, EMAC_RX_CTL_1, val & ~RX_DMA_EN);
+}
+
 static int
 awg_encap(struct awg_softc *sc, struct mbuf **mp)
 {
@@ -560,6 +782,170 @@ awg_newbuf_rx(struct awg_softc *sc, int index)
 }
 
 static void
+awg_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error)
+{
+	if (error != 0)
+		return;
+	*(bus_addr_t *)arg = segs[0].ds_addr;
+}
+
+static int
+awg_setup_dma(device_t dev)
+{
+	struct awg_softc *sc;
+	int error, i;
+
+	sc = device_get_softc(dev);
+
+	/* Setup TX ring */
+	error = bus_dma_tag_create(
+	    bus_get_dma_tag(dev),	/* Parent tag */
+	    DESC_ALIGN, 0,		/* alignment, boundary */
+	    BUS_SPACE_MAXADDR_32BIT,	/* lowaddr */
+	    BUS_SPACE_MAXADDR,		/* highaddr */
+	    NULL, NULL,			/* filter, filterarg */
+	    TX_DESC_SIZE, 1,		/* maxsize, nsegs */
+	    TX_DESC_SIZE,		/* maxsegsize */
+	    0,				/* flags */
+	    NULL, NULL,			/* lockfunc, lockarg */
+	    &sc->tx.desc_tag);
+	if (error != 0) {
+		device_printf(dev, "cannot create TX descriptor ring tag\n");
+		return (error);
+	}
+
+	error = bus_dmamem_alloc(sc->tx.desc_tag, (void **)&sc->tx.desc_ring,
+	    BUS_DMA_COHERENT | BUS_DMA_WAITOK | BUS_DMA_ZERO, &sc->tx.desc_map);
+	if (error != 0) {
+		device_printf(dev, "cannot allocate TX descriptor ring\n");
+		return (error);
+	}
+
+	error = bus_dmamap_load(sc->tx.desc_tag, sc->tx.desc_map,
+	    sc->tx.desc_ring, TX_DESC_SIZE, awg_dmamap_cb,
+	    &sc->tx.desc_ring_paddr, 0);
+	if (error != 0) {
+		device_printf(dev, "cannot load TX descriptor ring\n");
+		return (error);
+	}
+
+	for (i = 0; i < TX_DESC_COUNT; i++)
+		sc->tx.desc_ring[i].next =
+		    htole32(sc->tx.desc_ring_paddr + DESC_OFF(TX_NEXT(i)));
+
+	error = bus_dma_tag_create(
+	    bus_get_dma_tag(dev),	/* Parent tag */
+	    1, 0,			/* alignment, boundary */
+	    BUS_SPACE_MAXADDR_32BIT,	/* lowaddr */
+	    BUS_SPACE_MAXADDR,		/* highaddr */
+	    NULL, NULL,			/* filter, filterarg */
+	    MCLBYTES, TX_MAX_SEGS,	/* maxsize, nsegs */
+	    MCLBYTES,			/* maxsegsize */
+	    0,				/* flags */
+	    NULL, NULL,			/* lockfunc, lockarg */
+	    &sc->tx.buf_tag);
+	if (error != 0) {
+		device_printf(dev, "cannot create TX buffer tag\n");
+		return (error);
+	}
+
+	sc->tx.queued = 0;
+	for (i = 0; i < TX_DESC_COUNT; i++) {
+		error = bus_dmamap_create(sc->tx.buf_tag, 0,
+		    &sc->tx.buf_map[i].map);
+		if (error != 0) {
+			device_printf(dev, "cannot create TX buffer map\n");
+			return (error);
+		}
+	}
+
+	/* Setup RX ring */
+	error = bus_dma_tag_create(
+	    bus_get_dma_tag(dev),	/* Parent tag */
+	    DESC_ALIGN, 0,		/* alignment, boundary */
+	    BUS_SPACE_MAXADDR_32BIT,	/* lowaddr */
+	    BUS_SPACE_MAXADDR,		/* highaddr */
+	    NULL, NULL,			/* filter, filterarg */
+	    RX_DESC_SIZE, 1,		/* maxsize, nsegs */
+	    RX_DESC_SIZE,		/* maxsegsize */
+	    0,				/* flags */
+	    NULL, NULL,			/* lockfunc, lockarg */
+	    &sc->rx.desc_tag);
+	if (error != 0) {
+		device_printf(dev, "cannot create RX descriptor ring tag\n");
+		return (error);
+	}
+
+	error = bus_dmamem_alloc(sc->rx.desc_tag, (void **)&sc->rx.desc_ring,
+	    BUS_DMA_COHERENT | BUS_DMA_WAITOK | BUS_DMA_ZERO, &sc->rx.desc_map);
+	if (error != 0) {
+		device_printf(dev, "cannot allocate RX descriptor ring\n");
+		return (error);
+	}
+
+	error = bus_dmamap_load(sc->rx.desc_tag, sc->rx.desc_map,
+	    sc->rx.desc_ring, RX_DESC_SIZE, awg_dmamap_cb,
+	    &sc->rx.desc_ring_paddr, 0);
+	if (error != 0) {
+		device_printf(dev, "cannot load RX descriptor ring\n");
+		return (error);
+	}
+
+	error = bus_dma_tag_create(
+	    bus_get_dma_tag(dev),	/* Parent tag */
+	    1, 0,			/* alignment, boundary */
+	    BUS_SPACE_MAXADDR_32BIT,	/* lowaddr */
+	    BUS_SPACE_MAXADDR,		/* highaddr */
+	    NULL, NULL,			/* filter, filterarg */
+	    MCLBYTES, 1,		/* maxsize, nsegs */
+	    MCLBYTES,			/* maxsegsize */
+	    0,				/* flags */
+	    NULL, NULL,			/* lockfunc, lockarg */
+	    &sc->rx.buf_tag);
+	if (error != 0) {
+		device_printf(dev, "cannot create RX buffer tag\n");
+		return (error);
+	}
+
+	error = bus_dmamap_create(sc->rx.buf_tag, 0, &sc->rx.buf_spare_map);
+	if (error != 0) {
+		device_printf(dev,
+		    "cannot create RX buffer spare map\n");
+		return (error);
+	}
+
+	for (i = 0; i < RX_DESC_COUNT; i++) {
+		sc->rx.desc_ring[i].next =
+		    htole32(sc->rx.desc_ring_paddr + DESC_OFF(RX_NEXT(i)));
+
+		error = bus_dmamap_create(sc->rx.buf_tag, 0,
+		    &sc->rx.buf_map[i].map);
+		if (error != 0) {
+			device_printf(dev, "cannot create RX buffer map\n");
+			return (error);
+		}
+		sc->rx.buf_map[i].mbuf = NULL;
+		error = awg_newbuf_rx(sc, i);
+		if (error != 0) {
+			device_printf(dev, "cannot create RX buffer\n");
+			return (error);
+		}
+	}
+	bus_dmamap_sync(sc->rx.desc_tag, sc->rx.desc_map,
+	    BUS_DMASYNC_PREWRITE);
+
+	/* Write transmit and receive descriptor base address registers */
+	WR4(sc, EMAC_TX_DMA_LIST, sc->tx.desc_ring_paddr);
+	WR4(sc, EMAC_RX_DMA_LIST, sc->rx.desc_ring_paddr);
+
+	return (0);
+}
+
+/*
+ * if_ functions
+ */
+
+static void
 awg_start_locked(struct awg_softc *sc)
 {
 	struct mbuf *m;
@@ -617,195 +1003,6 @@ awg_start(if_t ifp)
 }
 
 static void
-awg_tick(void *softc)
-{
-	struct awg_softc *sc;
-	struct mii_data *mii;
-	if_t ifp;
-	int link;
-
-	sc = softc;
-	ifp = sc->ifp;
-	mii = device_get_softc(sc->miibus);
-
-	AWG_ASSERT_LOCKED(sc);
-
-	if ((if_getdrvflags(ifp) & IFF_DRV_RUNNING) == 0)
-		return;
-
-	link = sc->link;
-	mii_tick(mii);
-	if (sc->link && !link)
-		awg_start_locked(sc);
-
-	callout_reset(&sc->stat_ch, hz, awg_tick, sc);
-}
-
-/* Bit Reversal - http://aggregate.org/MAGIC/#Bit%20Reversal */
-static uint32_t
-bitrev32(uint32_t x)
-{
-	x = (((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1));
-	x = (((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2));
-	x = (((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4));
-	x = (((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8));
-
-	return (x >> 16) | (x << 16);
-}
-
-static u_int
-awg_hash_maddr(void *arg, struct sockaddr_dl *sdl, u_int cnt)
-{
-	uint32_t crc, hashreg, hashbit, *hash = arg;
-
-	crc = ether_crc32_le(LLADDR(sdl), ETHER_ADDR_LEN) & 0x7f;
-	crc = bitrev32(~crc) >> 26;
-	hashreg = (crc >> 5);
-	hashbit = (crc & 0x1f);
-	hash[hashreg] |= (1 << hashbit);
-
-	return (1);
-}
-
-static void
-awg_setup_rxfilter(struct awg_softc *sc)
-{
-	uint32_t val, hash[2], machi, maclo;
-	uint8_t *eaddr;
-	if_t ifp;
-
-	AWG_ASSERT_LOCKED(sc);
-
-	ifp = sc->ifp;
-	val = 0;
-	hash[0] = hash[1] = 0;
-
-	if (if_getflags(ifp) & IFF_PROMISC)
-		val |= DIS_ADDR_FILTER;
-	else if (if_getflags(ifp) & IFF_ALLMULTI) {
-		val |= RX_ALL_MULTICAST;
-		hash[0] = hash[1] = ~0;
-	} else if (if_foreach_llmaddr(ifp, awg_hash_maddr, hash) > 0)
-		val |= HASH_MULTICAST;
-
-	/* Write our unicast address */
-	eaddr = IF_LLADDR(ifp);
-	machi = (eaddr[5] << 8) | eaddr[4];
-	maclo = (eaddr[3] << 24) | (eaddr[2] << 16) | (eaddr[1] << 8) |
-	   (eaddr[0] << 0);
-	WR4(sc, EMAC_ADDR_HIGH(0), machi);
-	WR4(sc, EMAC_ADDR_LOW(0), maclo);
-
-	/* Multicast hash filters */
-	WR4(sc, EMAC_RX_HASH_0, hash[1]);
-	WR4(sc, EMAC_RX_HASH_1, hash[0]);
-
-	/* RX frame filter config */
-	WR4(sc, EMAC_RX_FRM_FLT, val);
-}
-
-static void
-awg_setup_core(struct awg_softc *sc)
-{
-	uint32_t val;
-
-	AWG_ASSERT_LOCKED(sc);
-	/* Configure DMA burst length and priorities */
-	val = awg_burst_len << BASIC_CTL_BURST_LEN_SHIFT;
-	if (awg_rx_tx_pri)
-		val |= BASIC_CTL_RX_TX_PRI;
-	WR4(sc, EMAC_BASIC_CTL_1, val);
-
-}
-
-static void
-awg_enable_mac(struct awg_softc *sc, bool enable)
-{
-	uint32_t tx, rx;
-
-	AWG_ASSERT_LOCKED(sc);
-
-	tx = RD4(sc, EMAC_TX_CTL_0);
-	rx = RD4(sc, EMAC_RX_CTL_0);
-	if (enable) {
-		tx |= TX_EN;
-		rx |= RX_EN | CHECK_CRC;
-	} else {
-		tx &= ~TX_EN;
-		rx &= ~(RX_EN | CHECK_CRC);
-	}
-
-	WR4(sc, EMAC_TX_CTL_0, tx);
-	WR4(sc, EMAC_RX_CTL_0, rx);
-}
-
-
-static void
-awg_enable_dma_intr(struct awg_softc *sc)
-{
-	/* Enable interrupts */
-	WR4(sc, EMAC_INT_EN, RX_INT_EN | TX_INT_EN | TX_BUF_UA_INT_EN);
-}
-
-static void
-awg_disable_dma_intr(struct awg_softc *sc)
-{
-	/* Disable interrupts */
-	WR4(sc, EMAC_INT_EN, 0);
-}
-
-static void
-awg_init_dma(struct awg_softc *sc)
-{
-	uint32_t val;
-
-	AWG_ASSERT_LOCKED(sc);
-
-	/* Enable interrupts */
-#ifdef DEVICE_POLLING
-	if ((if_getcapenable(sc->ifp) & IFCAP_POLLING) == 0)
-		awg_enable_dma_intr(sc);
-	else
-		awg_disable_dma_intr(sc);
-#else
-	awg_enable_dma_intr(sc);
-#endif
-
-	/* Enable transmit DMA */
-	val = RD4(sc, EMAC_TX_CTL_1);
-	WR4(sc, EMAC_TX_CTL_1, val | TX_DMA_EN | TX_MD | TX_NEXT_FRAME);
-
-	/* Enable receive DMA */
-	val = RD4(sc, EMAC_RX_CTL_1);
-	WR4(sc, EMAC_RX_CTL_1, val | RX_DMA_EN | RX_MD);
-}
-
-static void
-awg_stop_dma(struct awg_softc *sc)
-{
-	uint32_t val;
-
-	AWG_ASSERT_LOCKED(sc);
-
-	/* Stop transmit DMA and flush data in the TX FIFO */
-	val = RD4(sc, EMAC_TX_CTL_1);
-	val &= ~TX_DMA_EN;
-	val |= FLUSH_TX_FIFO;
-	WR4(sc, EMAC_TX_CTL_1, val);
-
-	/* Disable interrupts */
-	awg_disable_dma_intr(sc);
-
-	/* Disable transmit DMA */
-	val = RD4(sc, EMAC_TX_CTL_1);
-	WR4(sc, EMAC_TX_CTL_1, val & ~TX_DMA_EN);
-
-	/* Disable receive DMA */
-	val = RD4(sc, EMAC_RX_CTL_1);
-	WR4(sc, EMAC_RX_CTL_1, val & ~RX_DMA_EN);
-}
-
-static void
 awg_init_locked(struct awg_softc *sc)
 {
 	struct mii_data *mii;
@@ -897,6 +1094,92 @@ awg_stop(struct awg_softc *sc)
 }
 
 static int
+awg_ioctl(if_t ifp, u_long cmd, caddr_t data)
+{
+	struct awg_softc *sc;
+	struct mii_data *mii;
+	struct ifreq *ifr;
+	int flags, mask, error;
+
+	sc = if_getsoftc(ifp);
+	mii = device_get_softc(sc->miibus);
+	ifr = (struct ifreq *)data;
+	error = 0;
+
+	switch (cmd) {
+	case SIOCSIFFLAGS:
+		AWG_LOCK(sc);
+		if (if_getflags(ifp) & IFF_UP) {
+			if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) {
+				flags = if_getflags(ifp) ^ sc->if_flags;
+				if ((flags & (IFF_PROMISC|IFF_ALLMULTI)) != 0)
+					awg_setup_rxfilter(sc);
+			} else
+				awg_init_locked(sc);
+		} else {
+			if (if_getdrvflags(ifp) & IFF_DRV_RUNNING)
+				awg_stop(sc);
+		}
+		sc->if_flags = if_getflags(ifp);
+		AWG_UNLOCK(sc);
+		break;
+	case SIOCADDMULTI:
+	case SIOCDELMULTI:
+		if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) {
+			AWG_LOCK(sc);
+			awg_setup_rxfilter(sc);
+			AWG_UNLOCK(sc);
+		}
+		break;
+	case SIOCSIFMEDIA:
+	case SIOCGIFMEDIA:
+		error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, cmd);
+		break;
+	case SIOCSIFCAP:
+		mask = ifr->ifr_reqcap ^ if_getcapenable(ifp);
+#ifdef DEVICE_POLLING
+		if (mask & IFCAP_POLLING) {
+			if ((ifr->ifr_reqcap & IFCAP_POLLING) != 0) {
+				error = ether_poll_register(awg_poll, ifp);
+				if (error != 0)
+					break;
+				AWG_LOCK(sc);
+				awg_disable_dma_intr(sc);
+				if_setcapenablebit(ifp, IFCAP_POLLING, 0);
+				AWG_UNLOCK(sc);
+			} else {
+				error = ether_poll_deregister(ifp);
+				AWG_LOCK(sc);
+				awg_enable_dma_intr(sc);
+				if_setcapenablebit(ifp, 0, IFCAP_POLLING);
+				AWG_UNLOCK(sc);
+			}
+		}
+#endif
+		if (mask & IFCAP_VLAN_MTU)
+			if_togglecapenable(ifp, IFCAP_VLAN_MTU);
+		if (mask & IFCAP_RXCSUM)
+			if_togglecapenable(ifp, IFCAP_RXCSUM);
+		if (mask & IFCAP_TXCSUM)
+			if_togglecapenable(ifp, IFCAP_TXCSUM);
+		if ((if_getcapenable(ifp) & IFCAP_TXCSUM) != 0)
+			if_sethwassistbits(ifp, CSUM_IP | CSUM_UDP | CSUM_TCP, 0);
+		else
+			if_sethwassistbits(ifp, 0, CSUM_IP | CSUM_UDP | CSUM_TCP);
+		break;
+	default:
+		error = ether_ioctl(ifp, cmd, data);
+		break;
+	}
+
+	return (error);
+}
+
+/*
+ * Interrupts functions
+ */
+
+static int
 awg_rxintr(struct awg_softc *sc)
 {
 	if_t ifp;
@@ -1085,88 +1368,9 @@ awg_poll(if_t ifp, enum poll_cmd cmd, int count)
 }
 #endif
 
-static int
-awg_ioctl(if_t ifp, u_long cmd, caddr_t data)
-{
-	struct awg_softc *sc;
-	struct mii_data *mii;
-	struct ifreq *ifr;
-	int flags, mask, error;
-
-	sc = if_getsoftc(ifp);
-	mii = device_get_softc(sc->miibus);
-	ifr = (struct ifreq *)data;
-	error = 0;
-
-	switch (cmd) {
-	case SIOCSIFFLAGS:
-		AWG_LOCK(sc);
-		if (if_getflags(ifp) & IFF_UP) {
-			if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) {
-				flags = if_getflags(ifp) ^ sc->if_flags;
-				if ((flags & (IFF_PROMISC|IFF_ALLMULTI)) != 0)
-					awg_setup_rxfilter(sc);
-			} else
-				awg_init_locked(sc);
-		} else {
-			if (if_getdrvflags(ifp) & IFF_DRV_RUNNING)
-				awg_stop(sc);
-		}
-		sc->if_flags = if_getflags(ifp);
-		AWG_UNLOCK(sc);
-		break;
-	case SIOCADDMULTI:
-	case SIOCDELMULTI:
-		if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) {
-			AWG_LOCK(sc);
-			awg_setup_rxfilter(sc);
-			AWG_UNLOCK(sc);
-		}
-		break;
-	case SIOCSIFMEDIA:
-	case SIOCGIFMEDIA:
-		error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, cmd);
-		break;
-	case SIOCSIFCAP:
-		mask = ifr->ifr_reqcap ^ if_getcapenable(ifp);
-#ifdef DEVICE_POLLING
-		if (mask & IFCAP_POLLING) {
-			if ((ifr->ifr_reqcap & IFCAP_POLLING) != 0) {
-				error = ether_poll_register(awg_poll, ifp);
-				if (error != 0)
-					break;
-				AWG_LOCK(sc);
-				awg_disable_dma_intr(sc);
-				if_setcapenablebit(ifp, IFCAP_POLLING, 0);
-				AWG_UNLOCK(sc);
-			} else {
-				error = ether_poll_deregister(ifp);
-				AWG_LOCK(sc);
-				awg_enable_dma_intr(sc);
-				if_setcapenablebit(ifp, 0, IFCAP_POLLING);
-				AWG_UNLOCK(sc);
-			}
-		}
-#endif
-		if (mask & IFCAP_VLAN_MTU)
-			if_togglecapenable(ifp, IFCAP_VLAN_MTU);
-		if (mask & IFCAP_RXCSUM)
-			if_togglecapenable(ifp, IFCAP_RXCSUM);
-		if (mask & IFCAP_TXCSUM)
-			if_togglecapenable(ifp, IFCAP_TXCSUM);
-		if ((if_getcapenable(ifp) & IFCAP_TXCSUM) != 0)
-			if_sethwassistbits(ifp, CSUM_IP | CSUM_UDP | CSUM_TCP, 0);
-		else
-			if_sethwassistbits(ifp, 0, CSUM_IP | CSUM_UDP | CSUM_TCP);
-		break;
-	default:
-		error = ether_ioctl(ifp, cmd, data);
-		break;
-	}
-
-	return (error);
-}
-
+/*
+ * syscon functions
+ */
 static uint32_t
 syscon_read_emac_clk_reg(device_t dev)
 {
@@ -1193,6 +1397,10 @@ syscon_write_emac_clk_reg(device_t dev, uint32_t val)
 		bus_write_4(sc->res[_RES_SYSCON], 0, val);
 }
 
+/*
+ * PHY functions
+ */
+
 static phandle_t
 awg_get_phy_node(device_t dev)
 {
@@ -1532,46 +1740,6 @@ fail:
 	return (error);
 }
 
-static void 
-awg_get_eaddr(device_t dev, uint8_t *eaddr)
-{
-	struct awg_softc *sc;
-	uint32_t maclo, machi, rnd;
-	u_char rootkey[16];
-	uint32_t rootkey_size;
-
-	sc = device_get_softc(dev);
-
-	machi = RD4(sc, EMAC_ADDR_HIGH(0)) & 0xffff;
-	maclo = RD4(sc, EMAC_ADDR_LOW(0));
-
-	rootkey_size = sizeof(rootkey);
-	if (maclo == 0xffffffff && machi == 0xffff) {
-		/* MAC address in hardware is invalid, create one */
-		if (aw_sid_get_fuse(AW_SID_FUSE_ROOTKEY, rootkey,
-		    &rootkey_size) == 0 &&
-		    (rootkey[3] | rootkey[12] | rootkey[13] | rootkey[14] |
-		     rootkey[15]) != 0) {
-			/* MAC address is derived from the root key in SID */
-			maclo = (rootkey[13] << 24) | (rootkey[12] << 16) |
-				(rootkey[3] << 8) | 0x02;
-			machi = (rootkey[15] << 8) | rootkey[14];
-		} else {
-			/* Create one */
-			rnd = arc4random();
-			maclo = 0x00f2 | (rnd & 0xffff0000);
-			machi = rnd & 0xffff;
-		}
-	}
-
-	eaddr[0] = maclo & 0xff;
-	eaddr[1] = (maclo >> 8) & 0xff;
-	eaddr[2] = (maclo >> 16) & 0xff;
-	eaddr[3] = (maclo >> 24) & 0xff;
-	eaddr[4] = machi & 0xff;
-	eaddr[5] = (machi >> 8) & 0xff;
-}
-
 #ifdef AWG_DEBUG
 static void
 awg_dump_regs(device_t dev)
@@ -1696,165 +1864,38 @@ awg_reset(device_t dev)
 	return (0);
 }
 
+/*
+ * Stats
+ */
+
 static void
-awg_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error)
+awg_tick(void *softc)
 {
-	if (error != 0)
-		return;
-	*(bus_addr_t *)arg = segs[0].ds_addr;
-}
-
-static int
-awg_setup_dma(device_t dev)
-{
 	struct awg_softc *sc;
-	int error, i;
+	struct mii_data *mii;
+	if_t ifp;
+	int link;
 
-	sc = device_get_softc(dev);
+	sc = softc;
+	ifp = sc->ifp;
+	mii = device_get_softc(sc->miibus);
 
-	/* Setup TX ring */
-	error = bus_dma_tag_create(
-	    bus_get_dma_tag(dev),	/* Parent tag */
-	    DESC_ALIGN, 0,		/* alignment, boundary */
-	    BUS_SPACE_MAXADDR_32BIT,	/* lowaddr */
-	    BUS_SPACE_MAXADDR,		/* highaddr */
-	    NULL, NULL,			/* filter, filterarg */
-	    TX_DESC_SIZE, 1,		/* maxsize, nsegs */
-	    TX_DESC_SIZE,		/* maxsegsize */
-	    0,				/* flags */
-	    NULL, NULL,			/* lockfunc, lockarg */
-	    &sc->tx.desc_tag);
-	if (error != 0) {
-		device_printf(dev, "cannot create TX descriptor ring tag\n");
-		return (error);
-	}
+	AWG_ASSERT_LOCKED(sc);
 
-	error = bus_dmamem_alloc(sc->tx.desc_tag, (void **)&sc->tx.desc_ring,
-	    BUS_DMA_COHERENT | BUS_DMA_WAITOK | BUS_DMA_ZERO, &sc->tx.desc_map);
-	if (error != 0) {
-		device_printf(dev, "cannot allocate TX descriptor ring\n");
-		return (error);
-	}
+	if ((if_getdrvflags(ifp) & IFF_DRV_RUNNING) == 0)
+		return;
 
-	error = bus_dmamap_load(sc->tx.desc_tag, sc->tx.desc_map,
-	    sc->tx.desc_ring, TX_DESC_SIZE, awg_dmamap_cb,
-	    &sc->tx.desc_ring_paddr, 0);
-	if (error != 0) {
-		device_printf(dev, "cannot load TX descriptor ring\n");
-		return (error);
-	}
+	link = sc->link;
+	mii_tick(mii);
+	if (sc->link && !link)
+		awg_start_locked(sc);
 
-	for (i = 0; i < TX_DESC_COUNT; i++)
-		sc->tx.desc_ring[i].next =
-		    htole32(sc->tx.desc_ring_paddr + DESC_OFF(TX_NEXT(i)));
-
-	error = bus_dma_tag_create(
-	    bus_get_dma_tag(dev),	/* Parent tag */
-	    1, 0,			/* alignment, boundary */
-	    BUS_SPACE_MAXADDR_32BIT,	/* lowaddr */
-	    BUS_SPACE_MAXADDR,		/* highaddr */
-	    NULL, NULL,			/* filter, filterarg */
-	    MCLBYTES, TX_MAX_SEGS,	/* maxsize, nsegs */
-	    MCLBYTES,			/* maxsegsize */
-	    0,				/* flags */
-	    NULL, NULL,			/* lockfunc, lockarg */
-	    &sc->tx.buf_tag);
-	if (error != 0) {
-		device_printf(dev, "cannot create TX buffer tag\n");
-		return (error);
-	}
-
-	sc->tx.queued = 0;
-	for (i = 0; i < TX_DESC_COUNT; i++) {
-		error = bus_dmamap_create(sc->tx.buf_tag, 0,
-		    &sc->tx.buf_map[i].map);
-		if (error != 0) {
-			device_printf(dev, "cannot create TX buffer map\n");
-			return (error);
-		}
-	}
-
-	/* Setup RX ring */
-	error = bus_dma_tag_create(
-	    bus_get_dma_tag(dev),	/* Parent tag */
-	    DESC_ALIGN, 0,		/* alignment, boundary */
-	    BUS_SPACE_MAXADDR_32BIT,	/* lowaddr */
-	    BUS_SPACE_MAXADDR,		/* highaddr */
-	    NULL, NULL,			/* filter, filterarg */
-	    RX_DESC_SIZE, 1,		/* maxsize, nsegs */
-	    RX_DESC_SIZE,		/* maxsegsize */
-	    0,				/* flags */
-	    NULL, NULL,			/* lockfunc, lockarg */
-	    &sc->rx.desc_tag);
-	if (error != 0) {
-		device_printf(dev, "cannot create RX descriptor ring tag\n");
-		return (error);
-	}
-
-	error = bus_dmamem_alloc(sc->rx.desc_tag, (void **)&sc->rx.desc_ring,
-	    BUS_DMA_COHERENT | BUS_DMA_WAITOK | BUS_DMA_ZERO, &sc->rx.desc_map);
-	if (error != 0) {
-		device_printf(dev, "cannot allocate RX descriptor ring\n");
-		return (error);
-	}
-
-	error = bus_dmamap_load(sc->rx.desc_tag, sc->rx.desc_map,
-	    sc->rx.desc_ring, RX_DESC_SIZE, awg_dmamap_cb,
-	    &sc->rx.desc_ring_paddr, 0);
-	if (error != 0) {
-		device_printf(dev, "cannot load RX descriptor ring\n");
-		return (error);
-	}
-
-	error = bus_dma_tag_create(
-	    bus_get_dma_tag(dev),	/* Parent tag */
-	    1, 0,			/* alignment, boundary */
-	    BUS_SPACE_MAXADDR_32BIT,	/* lowaddr */
-	    BUS_SPACE_MAXADDR,		/* highaddr */

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-head mailing list