Module Name:    src
Committed By:   knakahara
Date:           Tue Oct 13 08:03:59 UTC 2015

Modified Files:
        src/sys/dev/pci: if_wm.c

Log Message:
refactor: separate busdma initialize processing as functions


To generate a diff of this commit:
cvs rdiff -u -r1.354 -r1.355 src/sys/dev/pci/if_wm.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/pci/if_wm.c
diff -u src/sys/dev/pci/if_wm.c:1.354 src/sys/dev/pci/if_wm.c:1.355
--- src/sys/dev/pci/if_wm.c:1.354	Tue Oct 13 08:00:15 2015
+++ src/sys/dev/pci/if_wm.c	Tue Oct 13 08:03:59 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_wm.c,v 1.354 2015/10/13 08:00:15 knakahara Exp $	*/
+/*	$NetBSD: if_wm.c,v 1.355 2015/10/13 08:03:59 knakahara Exp $	*/
 
 /*
  * Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc.
@@ -83,7 +83,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.354 2015/10/13 08:00:15 knakahara Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.355 2015/10/13 08:03:59 knakahara Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_net_mpsafe.h"
@@ -553,14 +553,21 @@ static int	wm_82547_txfifo_bugchk(struct
 /* DMA related */
 static int	wm_alloc_tx_descs(struct wm_softc *);
 static void	wm_free_tx_descs(struct wm_softc *);
+static void	wm_init_tx_descs(struct wm_softc *);
 static int	wm_alloc_rx_descs(struct wm_softc *);
 static void	wm_free_rx_descs(struct wm_softc *);
+static void	wm_init_rx_descs(struct wm_softc *);
 static int	wm_alloc_tx_buffer(struct wm_softc *);
 static void	wm_free_tx_buffer(struct wm_softc *);
+static void	wm_init_tx_buffer(struct wm_softc *);
 static int	wm_alloc_rx_buffer(struct wm_softc *);
 static void	wm_free_rx_buffer(struct wm_softc *);
+static int	wm_init_rx_buffer(struct wm_softc *);
+static void	wm_init_tx_queue(struct wm_softc *);
+static int	wm_init_rx_queue(struct wm_softc *);
 static int	wm_alloc_txrx_queues(struct wm_softc *);
 static void	wm_free_txrx_queues(struct wm_softc *);
+static int	wm_init_txrx_queues(struct wm_softc *);
 /* Start */
 static void	wm_start(struct ifnet *);
 static void	wm_start_locked(struct ifnet *);
@@ -2285,18 +2292,6 @@ alloc_retry:
 	CSR_WRITE(sc, WMREG_CTRL_EXT, sc->sc_ctrl_ext);
 #endif
 
-	/*
-	 * Set up some register offsets that are different between
-	 * the i82542 and the i82543 and later chips.
-	 */
-	if (sc->sc_type < WM_T_82543) {
-		sc->sc_rdt_reg = WMREG_OLD_RDT0;
-		sc->sc_tdt_reg = WMREG_OLD_TDT;
-	} else {
-		sc->sc_rdt_reg = WMREG_RDT;
-		sc->sc_tdt_reg = WMREG_TDT;
-	}
-
 	if (sc->sc_type == WM_T_PCH) {
 		uint16_t val;
 
@@ -4095,7 +4090,6 @@ static int
 wm_init_locked(struct ifnet *ifp)
 {
 	struct wm_softc *sc = ifp->if_softc;
-	struct wm_rxsoft *rxs;
 	int i, j, trynum, error = 0;
 	uint32_t reg;
 
@@ -4183,124 +4177,9 @@ wm_init_locked(struct ifnet *ifp)
 		sc->sc_itr = 1500;		/* 2604 ints/sec */
 	}
 
-	/* Initialize the transmit descriptor ring. */
-	memset(sc->sc_txdescs, 0, WM_TXDESCSIZE(sc));
-	wm_cdtxsync(sc, 0, WM_NTXDESC(sc),
-	    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
-	sc->sc_txfree = WM_NTXDESC(sc);
-	sc->sc_txnext = 0;
-
-	if (sc->sc_type < WM_T_82543) {
-		CSR_WRITE(sc, WMREG_OLD_TDBAH, WM_CDTXADDR_HI(sc, 0));
-		CSR_WRITE(sc, WMREG_OLD_TDBAL, WM_CDTXADDR_LO(sc, 0));
-		CSR_WRITE(sc, WMREG_OLD_TDLEN, WM_TXDESCSIZE(sc));
-		CSR_WRITE(sc, WMREG_OLD_TDH, 0);
-		CSR_WRITE(sc, WMREG_OLD_TDT, 0);
-		CSR_WRITE(sc, WMREG_OLD_TIDV, 128);
-	} else {
-		CSR_WRITE(sc, WMREG_TDBAH, WM_CDTXADDR_HI(sc, 0));
-		CSR_WRITE(sc, WMREG_TDBAL, WM_CDTXADDR_LO(sc, 0));
-		CSR_WRITE(sc, WMREG_TDLEN, WM_TXDESCSIZE(sc));
-		CSR_WRITE(sc, WMREG_TDH, 0);
-
-		if ((sc->sc_flags & WM_F_NEWQUEUE) != 0)
-			/*
-			 * Don't write TDT before TCTL.EN is set.
-			 * See the document.
-			 */
-			CSR_WRITE(sc, WMREG_TXDCTL(0), TXDCTL_QUEUE_ENABLE
-			    | TXDCTL_PTHRESH(0) | TXDCTL_HTHRESH(0)
-			    | TXDCTL_WTHRESH(0));
-		else {
-			/* ITR / 4 */
-			CSR_WRITE(sc, WMREG_TIDV, sc->sc_itr / 4);
-			if (sc->sc_type >= WM_T_82540) {
-				/* should be same */
-				CSR_WRITE(sc, WMREG_TADV, sc->sc_itr / 4);
-			}
-
-			CSR_WRITE(sc, WMREG_TDT, 0);
-			CSR_WRITE(sc, WMREG_TXDCTL(0), TXDCTL_PTHRESH(0) |
-			    TXDCTL_HTHRESH(0) | TXDCTL_WTHRESH(0));
-			CSR_WRITE(sc, WMREG_RXDCTL, RXDCTL_PTHRESH(0) |
-			    RXDCTL_HTHRESH(0) | RXDCTL_WTHRESH(1));
-		}
-	}
-
-	/* Initialize the transmit job descriptors. */
-	for (i = 0; i < WM_TXQUEUELEN(sc); i++)
-		sc->sc_txsoft[i].txs_mbuf = NULL;
-	sc->sc_txsfree = WM_TXQUEUELEN(sc);
-	sc->sc_txsnext = 0;
-	sc->sc_txsdirty = 0;
-
-	/*
-	 * Initialize the receive descriptor and receive job
-	 * descriptor rings.
-	 */
-	if (sc->sc_type < WM_T_82543) {
-		CSR_WRITE(sc, WMREG_OLD_RDBAH0, WM_CDRXADDR_HI(sc, 0));
-		CSR_WRITE(sc, WMREG_OLD_RDBAL0, WM_CDRXADDR_LO(sc, 0));
-		CSR_WRITE(sc, WMREG_OLD_RDLEN0, sizeof(sc->sc_rxdescs));
-		CSR_WRITE(sc, WMREG_OLD_RDH0, 0);
-		CSR_WRITE(sc, WMREG_OLD_RDT0, 0);
-		CSR_WRITE(sc, WMREG_OLD_RDTR0, 28 | RDTR_FPD);
-
-		CSR_WRITE(sc, WMREG_OLD_RDBA1_HI, 0);
-		CSR_WRITE(sc, WMREG_OLD_RDBA1_LO, 0);
-		CSR_WRITE(sc, WMREG_OLD_RDLEN1, 0);
-		CSR_WRITE(sc, WMREG_OLD_RDH1, 0);
-		CSR_WRITE(sc, WMREG_OLD_RDT1, 0);
-		CSR_WRITE(sc, WMREG_OLD_RDTR1, 0);
-	} else {
-		CSR_WRITE(sc, WMREG_RDBAH, WM_CDRXADDR_HI(sc, 0));
-		CSR_WRITE(sc, WMREG_RDBAL, WM_CDRXADDR_LO(sc, 0));
-		CSR_WRITE(sc, WMREG_RDLEN, sizeof(sc->sc_rxdescs));
-
-		if ((sc->sc_flags & WM_F_NEWQUEUE) != 0) {
-			if (MCLBYTES & ((1 << SRRCTL_BSIZEPKT_SHIFT) - 1))
-				panic("%s: MCLBYTES %d unsupported for i2575 or higher\n", __func__, MCLBYTES);
-			CSR_WRITE(sc, WMREG_SRRCTL, SRRCTL_DESCTYPE_LEGACY
-			    | (MCLBYTES >> SRRCTL_BSIZEPKT_SHIFT));
-			CSR_WRITE(sc, WMREG_RXDCTL, RXDCTL_QUEUE_ENABLE
-			    | RXDCTL_PTHRESH(16) | RXDCTL_HTHRESH(8)
-			    | RXDCTL_WTHRESH(1));
-		} else {
-			CSR_WRITE(sc, WMREG_RDH, 0);
-			CSR_WRITE(sc, WMREG_RDT, 0);
-			/* ITR/4 */
-			CSR_WRITE(sc, WMREG_RDTR, (sc->sc_itr / 4) | RDTR_FPD);
-			/* MUST be same */
-			CSR_WRITE(sc, WMREG_RADV, sc->sc_itr);
-		}
-	}
-	for (i = 0; i < WM_NRXDESC; i++) {
-		rxs = &sc->sc_rxsoft[i];
-		if (rxs->rxs_mbuf == NULL) {
-			if ((error = wm_add_rxbuf(sc, i)) != 0) {
-				log(LOG_ERR, "%s: unable to allocate or map "
-				    "rx buffer %d, error = %d\n",
-				    device_xname(sc->sc_dev), i, error);
-				/*
-				 * XXX Should attempt to run with fewer receive
-				 * XXX buffers instead of just failing.
-				 */
-				wm_rxdrain(sc);
-				goto out;
-			}
-		} else {
-			if ((sc->sc_flags & WM_F_NEWQUEUE) == 0)
-				wm_init_rxdesc(sc, i);
-			/*
-			 * For 82575 and newer device, the RX descriptors
-			 * must be initialized after the setting of RCTL.EN in
-			 * wm_set_filter()
-			 */
-		}
-	}
-	sc->sc_rxptr = 0;
-	sc->sc_rxdiscard = 0;
-	WM_RXCHAIN_RESET(sc);
+	error = wm_init_txrx_queues(sc);
+	if (error)
+		goto out;
 
 	/*
 	 * Clear out the VLAN table -- we don't use it (yet).
@@ -5373,6 +5252,216 @@ wm_free_txrx_queues(struct wm_softc *sc)
 	wm_free_tx_descs(sc);
 }
 
+static void
+wm_init_tx_descs(struct wm_softc *sc)
+{
+
+	KASSERT(WM_TX_LOCKED(sc));
+
+	/* Initialize the transmit descriptor ring. */
+	memset(sc->sc_txdescs, 0, WM_TXDESCSIZE(sc));
+	wm_cdtxsync(sc, 0, WM_NTXDESC(sc),
+	    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
+	sc->sc_txfree = WM_NTXDESC(sc);
+	sc->sc_txnext = 0;
+
+	if (sc->sc_type < WM_T_82543) {
+		CSR_WRITE(sc, WMREG_OLD_TDBAH, WM_CDTXADDR_HI(sc, 0));
+		CSR_WRITE(sc, WMREG_OLD_TDBAL, WM_CDTXADDR_LO(sc, 0));
+		CSR_WRITE(sc, WMREG_OLD_TDLEN, WM_TXDESCSIZE(sc));
+		CSR_WRITE(sc, WMREG_OLD_TDH, 0);
+		CSR_WRITE(sc, WMREG_OLD_TDT, 0);
+		CSR_WRITE(sc, WMREG_OLD_TIDV, 128);
+	} else {
+		CSR_WRITE(sc, WMREG_TDBAH, WM_CDTXADDR_HI(sc, 0));
+		CSR_WRITE(sc, WMREG_TDBAL, WM_CDTXADDR_LO(sc, 0));
+		CSR_WRITE(sc, WMREG_TDLEN, WM_TXDESCSIZE(sc));
+		CSR_WRITE(sc, WMREG_TDH, 0);
+
+		if ((sc->sc_flags & WM_F_NEWQUEUE) != 0)
+			/*
+			 * Don't write TDT before TCTL.EN is set.
+			 * See the document.
+			 */
+			CSR_WRITE(sc, WMREG_TXDCTL(0), TXDCTL_QUEUE_ENABLE
+			    | TXDCTL_PTHRESH(0) | TXDCTL_HTHRESH(0)
+			    | TXDCTL_WTHRESH(0));
+		else {
+			/* ITR / 4 */
+			CSR_WRITE(sc, WMREG_TIDV, sc->sc_itr / 4);
+			if (sc->sc_type >= WM_T_82540) {
+				/* should be same */
+				CSR_WRITE(sc, WMREG_TADV, sc->sc_itr / 4);
+			}
+
+			CSR_WRITE(sc, WMREG_TDT, 0);
+			CSR_WRITE(sc, WMREG_TXDCTL(0), TXDCTL_PTHRESH(0) |
+			    TXDCTL_HTHRESH(0) | TXDCTL_WTHRESH(0));
+			CSR_WRITE(sc, WMREG_RXDCTL, RXDCTL_PTHRESH(0) |
+			    RXDCTL_HTHRESH(0) | RXDCTL_WTHRESH(1));
+		}
+	}
+}
+
+static void
+wm_init_tx_buffer(struct wm_softc *sc)
+{
+	int i;
+
+	KASSERT(WM_TX_LOCKED(sc));
+
+	/* Initialize the transmit job descriptors. */
+	for (i = 0; i < WM_TXQUEUELEN(sc); i++)
+		sc->sc_txsoft[i].txs_mbuf = NULL;
+	sc->sc_txsfree = WM_TXQUEUELEN(sc);
+	sc->sc_txsnext = 0;
+	sc->sc_txsdirty = 0;
+}
+
+static void
+wm_init_tx_queue(struct wm_softc *sc)
+{
+
+	KASSERT(WM_TX_LOCKED(sc));
+
+	/*
+	 * Set up some register offsets that are different between
+	 * the i82542 and the i82543 and later chips.
+	 */
+	if (sc->sc_type < WM_T_82543) {
+		sc->sc_tdt_reg = WMREG_OLD_TDT;
+	} else {
+		sc->sc_tdt_reg = WMREG_TDT;
+	}
+
+	wm_init_tx_descs(sc);
+	wm_init_tx_buffer(sc);
+}
+
+static void
+wm_init_rx_descs(struct wm_softc *sc)
+{
+
+	KASSERT(WM_RX_LOCKED(sc));
+
+	/*
+	 * Initialize the receive descriptor and receive job
+	 * descriptor rings.
+	 */
+	if (sc->sc_type < WM_T_82543) {
+		CSR_WRITE(sc, WMREG_OLD_RDBAH0, WM_CDRXADDR_HI(sc, 0));
+		CSR_WRITE(sc, WMREG_OLD_RDBAL0, WM_CDRXADDR_LO(sc, 0));
+		CSR_WRITE(sc, WMREG_OLD_RDLEN0,
+		    sizeof(wiseman_rxdesc_t) * WM_NRXDESC);
+		CSR_WRITE(sc, WMREG_OLD_RDH0, 0);
+		CSR_WRITE(sc, WMREG_OLD_RDT0, 0);
+		CSR_WRITE(sc, WMREG_OLD_RDTR0, 28 | RDTR_FPD);
+
+		CSR_WRITE(sc, WMREG_OLD_RDBA1_HI, 0);
+		CSR_WRITE(sc, WMREG_OLD_RDBA1_LO, 0);
+		CSR_WRITE(sc, WMREG_OLD_RDLEN1, 0);
+		CSR_WRITE(sc, WMREG_OLD_RDH1, 0);
+		CSR_WRITE(sc, WMREG_OLD_RDT1, 0);
+		CSR_WRITE(sc, WMREG_OLD_RDTR1, 0);
+	} else {
+		CSR_WRITE(sc, WMREG_RDBAH, WM_CDRXADDR_HI(sc, 0));
+		CSR_WRITE(sc, WMREG_RDBAL, WM_CDRXADDR_LO(sc, 0));
+		CSR_WRITE(sc, WMREG_RDLEN,
+		    sizeof(wiseman_rxdesc_t) * WM_NRXDESC);
+
+		if ((sc->sc_flags & WM_F_NEWQUEUE) != 0) {
+			if (MCLBYTES & ((1 << SRRCTL_BSIZEPKT_SHIFT) - 1))
+				panic("%s: MCLBYTES %d unsupported for i2575 or higher\n", __func__, MCLBYTES);
+			CSR_WRITE(sc, WMREG_SRRCTL, SRRCTL_DESCTYPE_LEGACY
+			    | (MCLBYTES >> SRRCTL_BSIZEPKT_SHIFT));
+			CSR_WRITE(sc, WMREG_RXDCTL, RXDCTL_QUEUE_ENABLE
+			    | RXDCTL_PTHRESH(16) | RXDCTL_HTHRESH(8)
+			    | RXDCTL_WTHRESH(1));
+		} else {
+			CSR_WRITE(sc, WMREG_RDH, 0);
+			CSR_WRITE(sc, WMREG_RDT, 0);
+			CSR_WRITE(sc, WMREG_RDTR, 375 | RDTR_FPD); /* ITR/4 */
+			CSR_WRITE(sc, WMREG_RADV, 375);	/* MUST be same */
+		}
+	}
+}
+
+static int
+wm_init_rx_buffer(struct wm_softc *sc)
+{
+	struct wm_rxsoft *rxs;
+	int error, i;
+
+	KASSERT(WM_RX_LOCKED(sc));
+
+	for (i = 0; i < WM_NRXDESC; i++) {
+		rxs = &sc->sc_rxsoft[i];
+		if (rxs->rxs_mbuf == NULL) {
+			if ((error = wm_add_rxbuf(sc, i)) != 0) {
+				log(LOG_ERR, "%s: unable to allocate or map "
+				    "rx buffer %d, error = %d\n",
+				    device_xname(sc->sc_dev), i, error);
+				/*
+				 * XXX Should attempt to run with fewer receive
+				 * XXX buffers instead of just failing.
+				 */
+				wm_rxdrain(sc);
+				return ENOMEM;
+			}
+		} else {
+			if ((sc->sc_flags & WM_F_NEWQUEUE) == 0)
+				wm_init_rxdesc(sc, i);
+			/*
+			 * For 82575 and newer device, the RX descriptors
+			 * must be initialized after the setting of RCTL.EN in
+			 * wm_set_filter()
+			 */
+		}
+	}
+	sc->sc_rxptr = 0;
+	sc->sc_rxdiscard = 0;
+	WM_RXCHAIN_RESET(sc);
+
+	return 0;
+}
+
+static int
+wm_init_rx_queue(struct wm_softc *sc)
+{
+
+	KASSERT(WM_RX_LOCKED(sc));
+
+	/*
+	 * Set up some register offsets that are different between
+	 * the i82542 and the i82543 and later chips.
+	 */
+	if (sc->sc_type < WM_T_82543) {
+		sc->sc_rdt_reg = WMREG_OLD_RDT0;
+	} else {
+		sc->sc_rdt_reg = WMREG_RDT;
+	}
+
+	wm_init_rx_descs(sc);
+	return wm_init_rx_buffer(sc);
+}
+
+/*
+ * wm_init_quques:
+ *	Initialize {tx,rx}descs and {tx,rx} buffers
+ */
+static int
+wm_init_txrx_queues(struct wm_softc *sc)
+{
+	int error;
+
+	KASSERT(WM_BOTH_LOCKED(sc));
+
+	wm_init_tx_queue(sc);
+	error = wm_init_rx_queue(sc);
+
+	return error;
+}
+
 /*
  * wm_start:		[ifnet interface function]
  *

Reply via email to