Sun Jun 12 07:18:52 2016 UTC ()
First pass at making this driver and attachments NET_MPSAFE aware.

I've not tested this yet.


(skrll)
diff -r1.19.2.1 -r1.19.2.2 src/sys/arch/arm/allwinner/awin_gige.c
diff -r1.2.4.2 -r1.2.4.3 src/sys/arch/arm/amlogic/amlogic_gmac.c
diff -r1.28.2.3 -r1.28.2.4 src/sys/dev/ic/dwc_gmac.c
diff -r1.6 -r1.6.2.1 src/sys/dev/ic/dwc_gmac_var.h

cvs diff -r1.19.2.1 -r1.19.2.2 src/sys/arch/arm/allwinner/Attic/awin_gige.c (expand / switch to unified diff)

--- src/sys/arch/arm/allwinner/Attic/awin_gige.c 2015/04/06 15:17:51 1.19.2.1
+++ src/sys/arch/arm/allwinner/Attic/awin_gige.c 2016/06/12 07:18:52 1.19.2.2
@@ -24,27 +24,27 @@ @@ -24,27 +24,27 @@
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE. 27 * POSSIBILITY OF SUCH DAMAGE.
28 */ 28 */
29 29
30#include "locators.h" 30#include "locators.h"
31 31
32#include "axp806pm.h" 32#include "axp806pm.h"
33#include "axp809pm.h" 33#include "axp809pm.h"
34 34
35#include <sys/cdefs.h> 35#include <sys/cdefs.h>
36 36
37__KERNEL_RCSID(1, "$NetBSD: awin_gige.c,v 1.19.2.1 2015/04/06 15:17:51 skrll Exp $"); 37__KERNEL_RCSID(1, "$NetBSD: awin_gige.c,v 1.19.2.2 2016/06/12 07:18:52 skrll Exp $");
38 38
39#include <sys/param.h> 39#include <sys/param.h>
40#include <sys/bus.h> 40#include <sys/bus.h>
41#include <sys/device.h> 41#include <sys/device.h>
42#include <sys/intr.h> 42#include <sys/intr.h>
43#include <sys/systm.h> 43#include <sys/systm.h>
44 44
45#include <arm/allwinner/awin_reg.h> 45#include <arm/allwinner/awin_reg.h>
46#include <arm/allwinner/awin_var.h> 46#include <arm/allwinner/awin_var.h>
47 47
48#if NAXP806PM > 0 48#if NAXP806PM > 0
49#include <dev/i2c/axp806.h> 49#include <dev/i2c/axp806.h>
50#endif 50#endif
@@ -143,27 +143,31 @@ awin_gige_attach(device_t parent, device @@ -143,27 +143,31 @@ awin_gige_attach(device_t parent, device
143 sc->sc_core.sc_bst = aio->aio_core_bst; 143 sc->sc_core.sc_bst = aio->aio_core_bst;
144 sc->sc_core.sc_dmat = aio->aio_dmat; 144 sc->sc_core.sc_dmat = aio->aio_dmat;
145 bus_space_subregion(sc->sc_core.sc_bst, bsh, 145 bus_space_subregion(sc->sc_core.sc_bst, bsh,
146 loc->loc_offset, loc->loc_size, &sc->sc_core.sc_bsh); 146 loc->loc_offset, loc->loc_size, &sc->sc_core.sc_bsh);
147 147
148 aprint_naive("\n"); 148 aprint_naive("\n");
149 aprint_normal(": Gigabit Ethernet Controller\n"); 149 aprint_normal(": Gigabit Ethernet Controller\n");
150 150
151 awin_gige_pmu_init(self); 151 awin_gige_pmu_init(self);
152 152
153 /* 153 /*
154 * Interrupt handler 154 * Interrupt handler
155 */ 155 */
156 sc->sc_ih = intr_establish(loc->loc_intr, IPL_NET, IST_LEVEL, 156 int mpsafe = 0;
 157#ifdef NET_MPSAFE
 158 mpsafe |= IST_MPSAFE;
 159#endif
 160 sc->sc_ih = intr_establish(loc->loc_intr, IPL_NET, IST_LEVEL | mpsafe,
157 awin_gige_intr, sc); 161 awin_gige_intr, sc);
158 if (sc->sc_ih == NULL) { 162 if (sc->sc_ih == NULL) {
159 aprint_error_dev(self, "failed to establish interrupt %d\n", 163 aprint_error_dev(self, "failed to establish interrupt %d\n",
160 loc->loc_intr); 164 loc->loc_intr);
161 return; 165 return;
162 } 166 }
163 aprint_normal_dev(self, "interrupting on irq %d\n", 167 aprint_normal_dev(self, "interrupting on irq %d\n",
164 loc->loc_intr); 168 loc->loc_intr);
165 169
166 if (prop_dictionary_get_cstring_nocopy(cfg, "phy-power", &pin_name)) { 170 if (prop_dictionary_get_cstring_nocopy(cfg, "phy-power", &pin_name)) {
167 if (awin_gpio_pin_reserve(pin_name, &sc->sc_power_pin)) { 171 if (awin_gpio_pin_reserve(pin_name, &sc->sc_power_pin)) {
168 awin_gpio_pindata_write(&sc->sc_power_pin, 1); 172 awin_gpio_pindata_write(&sc->sc_power_pin, 1);
169 } else { 173 } else {

cvs diff -r1.2.4.2 -r1.2.4.3 src/sys/arch/arm/amlogic/Attic/amlogic_gmac.c (expand / switch to unified diff)

--- src/sys/arch/arm/amlogic/Attic/amlogic_gmac.c 2015/04/06 15:17:51 1.2.4.2
+++ src/sys/arch/arm/amlogic/Attic/amlogic_gmac.c 2016/06/12 07:18:52 1.2.4.3
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: amlogic_gmac.c,v 1.2.4.2 2015/04/06 15:17:51 skrll Exp $ */ 1/* $NetBSD: amlogic_gmac.c,v 1.2.4.3 2016/06/12 07:18:52 skrll Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2013, 2014, 2015 The NetBSD Foundation, Inc. 4 * Copyright (c) 2013, 2014, 2015 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Matt Thomas of 3am Software Foundry and Martin Husemann. 8 * by Matt Thomas of 3am Software Foundry and Martin Husemann.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -23,27 +23,27 @@ @@ -23,27 +23,27 @@
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32#include "locators.h" 32#include "locators.h"
33 33
34#include <sys/cdefs.h> 34#include <sys/cdefs.h>
35 35
36__KERNEL_RCSID(1, "$NetBSD: amlogic_gmac.c,v 1.2.4.2 2015/04/06 15:17:51 skrll Exp $"); 36__KERNEL_RCSID(1, "$NetBSD: amlogic_gmac.c,v 1.2.4.3 2016/06/12 07:18:52 skrll Exp $");
37 37
38#include <sys/param.h> 38#include <sys/param.h>
39#include <sys/bus.h> 39#include <sys/bus.h>
40#include <sys/device.h> 40#include <sys/device.h>
41#include <sys/intr.h> 41#include <sys/intr.h>
42#include <sys/systm.h> 42#include <sys/systm.h>
43 43
44#include <arm/amlogic/amlogic_reg.h> 44#include <arm/amlogic/amlogic_reg.h>
45#include <arm/amlogic/amlogic_var.h> 45#include <arm/amlogic/amlogic_var.h>
46 46
47#include <net/if.h> 47#include <net/if.h>
48#include <net/if_ether.h> 48#include <net/if_ether.h>
49#include <net/if_media.h> 49#include <net/if_media.h>
@@ -82,27 +82,31 @@ amlogic_gmac_attach(device_t parent, dev @@ -82,27 +82,31 @@ amlogic_gmac_attach(device_t parent, dev
82 sc->sc_core.sc_bst = aio->aio_core_bst; 82 sc->sc_core.sc_bst = aio->aio_core_bst;
83 sc->sc_core.sc_dmat = aio->aio_dmat; 83 sc->sc_core.sc_dmat = aio->aio_dmat;
84 bus_space_subregion(aio->aio_core_bst, aio->aio_bsh, 84 bus_space_subregion(aio->aio_core_bst, aio->aio_bsh,
85 loc->loc_offset, loc->loc_size, &sc->sc_core.sc_bsh); 85 loc->loc_offset, loc->loc_size, &sc->sc_core.sc_bsh);
86 86
87 aprint_naive("\n"); 87 aprint_naive("\n");
88 aprint_normal(": Gigabit Ethernet Controller\n"); 88 aprint_normal(": Gigabit Ethernet Controller\n");
89 89
90 amlogic_eth_init(); 90 amlogic_eth_init();
91 91
92 /* 92 /*
93 * Interrupt handler 93 * Interrupt handler
94 */ 94 */
95 sc->sc_ih = intr_establish(loc->loc_intr, IPL_NET, IST_EDGE, 95 int mpsafe = 0;
 96#ifdef NET_MPSAFE
 97 mpsafe |= IST_MPSAFE;
 98#endif
 99 sc->sc_ih = intr_establish(loc->loc_intr, IPL_NET, IST_EDGE | mpsafe,
96 amlogic_gmac_intr, sc); 100 amlogic_gmac_intr, sc);
97 if (sc->sc_ih == NULL) { 101 if (sc->sc_ih == NULL) {
98 aprint_error_dev(self, "failed to establish interrupt %d\n", 102 aprint_error_dev(self, "failed to establish interrupt %d\n",
99 loc->loc_intr); 103 loc->loc_intr);
100 return; 104 return;
101 } 105 }
102 aprint_normal_dev(self, "interrupting on irq %d\n", 106 aprint_normal_dev(self, "interrupting on irq %d\n",
103 loc->loc_intr); 107 loc->loc_intr);
104 108
105 dwc_gmac_attach(&sc->sc_core, GMAC_MII_CLK_100_150M_DIV62); 109 dwc_gmac_attach(&sc->sc_core, GMAC_MII_CLK_100_150M_DIV62);
106} 110}
107 111
108static int 112static int

cvs diff -r1.28.2.3 -r1.28.2.4 src/sys/dev/ic/dwc_gmac.c (expand / switch to unified diff)

--- src/sys/dev/ic/dwc_gmac.c 2016/03/19 11:30:09 1.28.2.3
+++ src/sys/dev/ic/dwc_gmac.c 2016/06/12 07:18:52 1.28.2.4
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: dwc_gmac.c,v 1.28.2.3 2016/03/19 11:30:09 skrll Exp $ */ 1/* $NetBSD: dwc_gmac.c,v 1.28.2.4 2016/06/12 07:18:52 skrll Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2013, 2014 The NetBSD Foundation, Inc. 4 * Copyright (c) 2013, 2014 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Matt Thomas of 3am Software Foundry and Martin Husemann. 8 * by Matt Thomas of 3am Software Foundry and Martin Husemann.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -31,31 +31,34 @@ @@ -31,31 +31,34 @@
31 31
32/* 32/*
33 * This driver supports the Synopsis Designware GMAC core, as found 33 * This driver supports the Synopsis Designware GMAC core, as found
34 * on Allwinner A20 cores and others. 34 * on Allwinner A20 cores and others.
35 * 35 *
36 * Real documentation seems to not be available, the marketing product 36 * Real documentation seems to not be available, the marketing product
37 * documents could be found here: 37 * documents could be found here:
38 * 38 *
39 * http://www.synopsys.com/dw/ipdir.php?ds=dwc_ether_mac10_100_1000_unive 39 * http://www.synopsys.com/dw/ipdir.php?ds=dwc_ether_mac10_100_1000_unive
40 */ 40 */
41 41
42#include <sys/cdefs.h> 42#include <sys/cdefs.h>
43 43
44__KERNEL_RCSID(1, "$NetBSD: dwc_gmac.c,v 1.28.2.3 2016/03/19 11:30:09 skrll Exp $"); 44__KERNEL_RCSID(1, "$NetBSD: dwc_gmac.c,v 1.28.2.4 2016/06/12 07:18:52 skrll Exp $");
45 45
46/* #define DWC_GMAC_DEBUG 1 */ 46/* #define DWC_GMAC_DEBUG 1 */
47 47
 48#ifdef _KERNEL_OPT
48#include "opt_inet.h" 49#include "opt_inet.h"
 50#include "opt_net_mpsafe.h"
 51#endif
49 52
50#include <sys/param.h> 53#include <sys/param.h>
51#include <sys/bus.h> 54#include <sys/bus.h>
52#include <sys/device.h> 55#include <sys/device.h>
53#include <sys/intr.h> 56#include <sys/intr.h>
54#include <sys/systm.h> 57#include <sys/systm.h>
55#include <sys/sockio.h> 58#include <sys/sockio.h>
56#include <sys/cprng.h> 59#include <sys/cprng.h>
57 60
58#include <net/if.h> 61#include <net/if.h>
59#include <net/if_ether.h> 62#include <net/if_ether.h>
60#include <net/if_media.h> 63#include <net/if_media.h>
61#include <net/bpf.h> 64#include <net/bpf.h>
@@ -75,28 +78,31 @@ static void dwc_gmac_miibus_statchg(stru @@ -75,28 +78,31 @@ static void dwc_gmac_miibus_statchg(stru
75static int dwc_gmac_reset(struct dwc_gmac_softc *sc); 78static int dwc_gmac_reset(struct dwc_gmac_softc *sc);
76static void dwc_gmac_write_hwaddr(struct dwc_gmac_softc *sc, 79static void dwc_gmac_write_hwaddr(struct dwc_gmac_softc *sc,
77 uint8_t enaddr[ETHER_ADDR_LEN]); 80 uint8_t enaddr[ETHER_ADDR_LEN]);
78static int dwc_gmac_alloc_dma_rings(struct dwc_gmac_softc *sc); 81static int dwc_gmac_alloc_dma_rings(struct dwc_gmac_softc *sc);
79static void dwc_gmac_free_dma_rings(struct dwc_gmac_softc *sc); 82static void dwc_gmac_free_dma_rings(struct dwc_gmac_softc *sc);
80static int dwc_gmac_alloc_rx_ring(struct dwc_gmac_softc *sc, struct dwc_gmac_rx_ring *); 83static int dwc_gmac_alloc_rx_ring(struct dwc_gmac_softc *sc, struct dwc_gmac_rx_ring *);
81static void dwc_gmac_reset_rx_ring(struct dwc_gmac_softc *sc, struct dwc_gmac_rx_ring *); 84static void dwc_gmac_reset_rx_ring(struct dwc_gmac_softc *sc, struct dwc_gmac_rx_ring *);
82static void dwc_gmac_free_rx_ring(struct dwc_gmac_softc *sc, struct dwc_gmac_rx_ring *); 85static void dwc_gmac_free_rx_ring(struct dwc_gmac_softc *sc, struct dwc_gmac_rx_ring *);
83static int dwc_gmac_alloc_tx_ring(struct dwc_gmac_softc *sc, struct dwc_gmac_tx_ring *); 86static int dwc_gmac_alloc_tx_ring(struct dwc_gmac_softc *sc, struct dwc_gmac_tx_ring *);
84static void dwc_gmac_reset_tx_ring(struct dwc_gmac_softc *sc, struct dwc_gmac_tx_ring *); 87static void dwc_gmac_reset_tx_ring(struct dwc_gmac_softc *sc, struct dwc_gmac_tx_ring *);
85static void dwc_gmac_free_tx_ring(struct dwc_gmac_softc *sc, struct dwc_gmac_tx_ring *); 88static void dwc_gmac_free_tx_ring(struct dwc_gmac_softc *sc, struct dwc_gmac_tx_ring *);
86static void dwc_gmac_txdesc_sync(struct dwc_gmac_softc *sc, int start, int end, int ops); 89static void dwc_gmac_txdesc_sync(struct dwc_gmac_softc *sc, int start, int end, int ops);
87static int dwc_gmac_init(struct ifnet *ifp); 90static int dwc_gmac_init(struct ifnet *ifp);
 91static int dwc_gmac_init_locked(struct ifnet *ifp);
88static void dwc_gmac_stop(struct ifnet *ifp, int disable); 92static void dwc_gmac_stop(struct ifnet *ifp, int disable);
 93static void dwc_gmac_stop_locked(struct ifnet *ifp, int disable);
89static void dwc_gmac_start(struct ifnet *ifp); 94static void dwc_gmac_start(struct ifnet *ifp);
 95static void dwc_gmac_start_locked(struct ifnet *ifp);
90static int dwc_gmac_queue(struct dwc_gmac_softc *sc, struct mbuf *m0); 96static int dwc_gmac_queue(struct dwc_gmac_softc *sc, struct mbuf *m0);
91static int dwc_gmac_ioctl(struct ifnet *, u_long, void *); 97static int dwc_gmac_ioctl(struct ifnet *, u_long, void *);
92static void dwc_gmac_tx_intr(struct dwc_gmac_softc *sc); 98static void dwc_gmac_tx_intr(struct dwc_gmac_softc *sc);
93static void dwc_gmac_rx_intr(struct dwc_gmac_softc *sc); 99static void dwc_gmac_rx_intr(struct dwc_gmac_softc *sc);
94static void dwc_gmac_setmulti(struct dwc_gmac_softc *sc); 100static void dwc_gmac_setmulti(struct dwc_gmac_softc *sc);
95static int dwc_gmac_ifflags_cb(struct ethercom *); 101static int dwc_gmac_ifflags_cb(struct ethercom *);
96static uint32_t bitrev32(uint32_t x); 102static uint32_t bitrev32(uint32_t x);
97 103
98#define TX_DESC_OFFSET(N) ((AWGE_RX_RING_COUNT+(N)) \ 104#define TX_DESC_OFFSET(N) ((AWGE_RX_RING_COUNT+(N)) \
99 *sizeof(struct dwc_gmac_dev_dmadesc)) 105 *sizeof(struct dwc_gmac_dev_dmadesc))
100#define TX_NEXT(N) (((N)+1) & (AWGE_TX_RING_COUNT-1)) 106#define TX_NEXT(N) (((N)+1) & (AWGE_TX_RING_COUNT-1))
101 107
102#define RX_DESC_OFFSET(N) ((N)*sizeof(struct dwc_gmac_dev_dmadesc)) 108#define RX_DESC_OFFSET(N) ((N)*sizeof(struct dwc_gmac_dev_dmadesc))
@@ -118,35 +124,38 @@ static uint32_t bitrev32(uint32_t x); @@ -118,35 +124,38 @@ static uint32_t bitrev32(uint32_t x);
118 (AWIN_GMAC_MAC_INT_TSI | AWIN_GMAC_MAC_INT_ANEG | \ 124 (AWIN_GMAC_MAC_INT_TSI | AWIN_GMAC_MAC_INT_ANEG | \
119 AWIN_GMAC_MAC_INT_LINKCHG | AWIN_GMAC_MAC_INT_RGSMII) 125 AWIN_GMAC_MAC_INT_LINKCHG | AWIN_GMAC_MAC_INT_RGSMII)
120 126
121 127
122#ifdef DWC_GMAC_DEBUG 128#ifdef DWC_GMAC_DEBUG
123static void dwc_gmac_dump_dma(struct dwc_gmac_softc *sc); 129static void dwc_gmac_dump_dma(struct dwc_gmac_softc *sc);
124static void dwc_gmac_dump_tx_desc(struct dwc_gmac_softc *sc); 130static void dwc_gmac_dump_tx_desc(struct dwc_gmac_softc *sc);
125static void dwc_gmac_dump_rx_desc(struct dwc_gmac_softc *sc); 131static void dwc_gmac_dump_rx_desc(struct dwc_gmac_softc *sc);
126static void dwc_dump_and_abort(struct dwc_gmac_softc *sc, const char *msg); 132static void dwc_dump_and_abort(struct dwc_gmac_softc *sc, const char *msg);
127static void dwc_dump_status(struct dwc_gmac_softc *sc); 133static void dwc_dump_status(struct dwc_gmac_softc *sc);
128static void dwc_gmac_dump_ffilt(struct dwc_gmac_softc *sc, uint32_t ffilt); 134static void dwc_gmac_dump_ffilt(struct dwc_gmac_softc *sc, uint32_t ffilt);
129#endif 135#endif
130 136
 137#ifdef NET_MPSAFE
 138#define DWCGMAC_MPSAFE 1
 139#endif
 140
131void 141void
132dwc_gmac_attach(struct dwc_gmac_softc *sc, uint32_t mii_clk) 142dwc_gmac_attach(struct dwc_gmac_softc *sc, uint32_t mii_clk)
133{ 143{
134 uint8_t enaddr[ETHER_ADDR_LEN]; 144 uint8_t enaddr[ETHER_ADDR_LEN];
135 uint32_t maclo, machi; 145 uint32_t maclo, machi;
136 struct mii_data * const mii = &sc->sc_mii; 146 struct mii_data * const mii = &sc->sc_mii;
137 struct ifnet * const ifp = &sc->sc_ec.ec_if; 147 struct ifnet * const ifp = &sc->sc_ec.ec_if;
138 prop_dictionary_t dict; 148 prop_dictionary_t dict;
139 int s; 
140 149
141 mutex_init(&sc->sc_mdio_lock, MUTEX_DEFAULT, IPL_NET); 150 mutex_init(&sc->sc_mdio_lock, MUTEX_DEFAULT, IPL_NET);
142 sc->sc_mii_clk = mii_clk & 7; 151 sc->sc_mii_clk = mii_clk & 7;
143 152
144 dict = device_properties(sc->sc_dev); 153 dict = device_properties(sc->sc_dev);
145 prop_data_t ea = dict ? prop_dictionary_get(dict, "mac-address") : NULL; 154 prop_data_t ea = dict ? prop_dictionary_get(dict, "mac-address") : NULL;
146 if (ea != NULL) { 155 if (ea != NULL) {
147 /* 156 /*
148 * If the MAC address is overriden by a device property, 157 * If the MAC address is overriden by a device property,
149 * use that. 158 * use that.
150 */ 159 */
151 KASSERT(prop_object_type(ea) == PROP_TYPE_DATA); 160 KASSERT(prop_object_type(ea) == PROP_TYPE_DATA);
152 KASSERT(prop_data_size(ea) == ETHER_ADDR_LEN); 161 KASSERT(prop_data_size(ea) == ETHER_ADDR_LEN);
@@ -188,32 +197,35 @@ dwc_gmac_attach(struct dwc_gmac_softc *s @@ -188,32 +197,35 @@ dwc_gmac_attach(struct dwc_gmac_softc *s
188 /* 197 /*
189 * Allocate Tx and Rx rings 198 * Allocate Tx and Rx rings
190 */ 199 */
191 if (dwc_gmac_alloc_dma_rings(sc) != 0) { 200 if (dwc_gmac_alloc_dma_rings(sc) != 0) {
192 aprint_error_dev(sc->sc_dev, "could not allocate DMA rings\n"); 201 aprint_error_dev(sc->sc_dev, "could not allocate DMA rings\n");
193 goto fail; 202 goto fail;
194 } 203 }
195 204
196 if (dwc_gmac_alloc_tx_ring(sc, &sc->sc_txq) != 0) { 205 if (dwc_gmac_alloc_tx_ring(sc, &sc->sc_txq) != 0) {
197 aprint_error_dev(sc->sc_dev, "could not allocate Tx ring\n"); 206 aprint_error_dev(sc->sc_dev, "could not allocate Tx ring\n");
198 goto fail; 207 goto fail;
199 } 208 }
200 209
201 mutex_init(&sc->sc_rxq.r_mtx, MUTEX_DEFAULT, IPL_NET); 
202 if (dwc_gmac_alloc_rx_ring(sc, &sc->sc_rxq) != 0) { 210 if (dwc_gmac_alloc_rx_ring(sc, &sc->sc_rxq) != 0) {
203 aprint_error_dev(sc->sc_dev, "could not allocate Rx ring\n"); 211 aprint_error_dev(sc->sc_dev, "could not allocate Rx ring\n");
204 goto fail; 212 goto fail;
205 } 213 }
206 214
 215 sc->sc_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NET);
 216 mutex_init(&sc->sc_txq.t_mtx, MUTEX_DEFAULT, IPL_NET);
 217 mutex_init(&sc->sc_rxq.r_mtx, MUTEX_DEFAULT, IPL_NET);
 218
207 /* 219 /*
208 * Prepare interface data 220 * Prepare interface data
209 */ 221 */
210 ifp->if_softc = sc; 222 ifp->if_softc = sc;
211 strlcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ); 223 strlcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ);
212 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 224 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
213 ifp->if_ioctl = dwc_gmac_ioctl; 225 ifp->if_ioctl = dwc_gmac_ioctl;
214 ifp->if_start = dwc_gmac_start; 226 ifp->if_start = dwc_gmac_start;
215 ifp->if_init = dwc_gmac_init; 227 ifp->if_init = dwc_gmac_init;
216 ifp->if_stop = dwc_gmac_stop; 228 ifp->if_stop = dwc_gmac_stop;
217 IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); 229 IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
218 IFQ_SET_READY(&ifp->if_snd); 230 IFQ_SET_READY(&ifp->if_snd);
219 231
@@ -235,39 +247,42 @@ dwc_gmac_attach(struct dwc_gmac_softc *s @@ -235,39 +247,42 @@ dwc_gmac_attach(struct dwc_gmac_softc *s
235 ifmedia_set(&mii->mii_media, IFM_ETHER|IFM_MANUAL); 247 ifmedia_set(&mii->mii_media, IFM_ETHER|IFM_MANUAL);
236 } else { 248 } else {
237 ifmedia_set(&mii->mii_media, IFM_ETHER|IFM_AUTO); 249 ifmedia_set(&mii->mii_media, IFM_ETHER|IFM_AUTO);
238 } 250 }
239 251
240 /* 252 /*
241 * We can support 802.1Q VLAN-sized frames. 253 * We can support 802.1Q VLAN-sized frames.
242 */ 254 */
243 sc->sc_ec.ec_capabilities |= ETHERCAP_VLAN_MTU; 255 sc->sc_ec.ec_capabilities |= ETHERCAP_VLAN_MTU;
244 256
245 /* 257 /*
246 * Ready, attach interface 258 * Ready, attach interface
247 */ 259 */
248 if_attach(ifp); 260 /* Attach the interface. */
 261 if_initialize(ifp);
 262 sc->sc_ipq = if_percpuq_create(&sc->sc_ec.ec_if);
249 ether_ifattach(ifp, enaddr); 263 ether_ifattach(ifp, enaddr);
250 ether_set_ifflags_cb(&sc->sc_ec, dwc_gmac_ifflags_cb); 264 ether_set_ifflags_cb(&sc->sc_ec, dwc_gmac_ifflags_cb);
 265 if_register(ifp);
251 266
252 /* 267 /*
253 * Enable interrupts 268 * Enable interrupts
254 */ 269 */
255 s = splnet(); 270 mutex_enter(sc->sc_lock);
256 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_INTMASK, 271 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_INTMASK,
257 AWIN_DEF_MAC_INTRMASK); 272 AWIN_DEF_MAC_INTRMASK);
258 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_INTENABLE, 273 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_INTENABLE,
259 GMAC_DEF_DMA_INT_MASK); 274 GMAC_DEF_DMA_INT_MASK);
260 splx(s); 275 mutex_exit(sc->sc_lock);
261 276
262 return; 277 return;
263 278
264fail: 279fail:
265 dwc_gmac_free_rx_ring(sc, &sc->sc_rxq); 280 dwc_gmac_free_rx_ring(sc, &sc->sc_rxq);
266 dwc_gmac_free_tx_ring(sc, &sc->sc_txq); 281 dwc_gmac_free_tx_ring(sc, &sc->sc_txq);
267} 282}
268 283
269 284
270 285
271static int 286static int
272dwc_gmac_reset(struct dwc_gmac_softc *sc) 287dwc_gmac_reset(struct dwc_gmac_softc *sc)
273{ 288{
@@ -429,42 +444,44 @@ dwc_gmac_alloc_rx_ring(struct dwc_gmac_s @@ -429,42 +444,44 @@ dwc_gmac_alloc_rx_ring(struct dwc_gmac_s
429 444
430fail: 445fail:
431 dwc_gmac_free_rx_ring(sc, ring); 446 dwc_gmac_free_rx_ring(sc, ring);
432 return error; 447 return error;
433} 448}
434 449
435static void 450static void
436dwc_gmac_reset_rx_ring(struct dwc_gmac_softc *sc, 451dwc_gmac_reset_rx_ring(struct dwc_gmac_softc *sc,
437 struct dwc_gmac_rx_ring *ring) 452 struct dwc_gmac_rx_ring *ring)
438{ 453{
439 struct dwc_gmac_dev_dmadesc *desc; 454 struct dwc_gmac_dev_dmadesc *desc;
440 int i; 455 int i;
441 456
 457 mutex_enter(&ring->r_mtx);
442 for (i = 0; i < AWGE_RX_RING_COUNT; i++) { 458 for (i = 0; i < AWGE_RX_RING_COUNT; i++) {
443 desc = &sc->sc_rxq.r_desc[i]; 459 desc = &sc->sc_rxq.r_desc[i];
444 desc->ddesc_cntl = htole32( 460 desc->ddesc_cntl = htole32(
445 __SHIFTIN(AWGE_MAX_PACKET,DDESC_CNTL_SIZE1MASK) | 461 __SHIFTIN(AWGE_MAX_PACKET,DDESC_CNTL_SIZE1MASK) |
446 DDESC_CNTL_RXCHAIN); 462 DDESC_CNTL_RXCHAIN);
447 desc->ddesc_status = htole32(DDESC_STATUS_OWNEDBYDEV); 463 desc->ddesc_status = htole32(DDESC_STATUS_OWNEDBYDEV);
448 } 464 }
449 465
450 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 0, 466 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 0,
451 AWGE_RX_RING_COUNT*sizeof(struct dwc_gmac_dev_dmadesc), 467 AWGE_RX_RING_COUNT*sizeof(struct dwc_gmac_dev_dmadesc),
452 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 468 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
453 469
454 ring->r_cur = ring->r_next = 0; 470 ring->r_cur = ring->r_next = 0;
455 /* reset DMA address to start of ring */ 471 /* reset DMA address to start of ring */
456 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_RX_ADDR, 472 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_RX_ADDR,
457 sc->sc_rxq.r_physaddr); 473 sc->sc_rxq.r_physaddr);
 474 mutex_exit(&ring->r_mtx);
458} 475}
459 476
460static int 477static int
461dwc_gmac_alloc_dma_rings(struct dwc_gmac_softc *sc) 478dwc_gmac_alloc_dma_rings(struct dwc_gmac_softc *sc)
462{ 479{
463 const size_t descsize = AWGE_TOTAL_RING_COUNT * 480 const size_t descsize = AWGE_TOTAL_RING_COUNT *
464 sizeof(struct dwc_gmac_dev_dmadesc); 481 sizeof(struct dwc_gmac_dev_dmadesc);
465 int error, nsegs; 482 int error, nsegs;
466 void *rings; 483 void *rings;
467 484
468 error = bus_dmamap_create(sc->sc_dmat, descsize, 1, descsize, 0, 485 error = bus_dmamap_create(sc->sc_dmat, descsize, 1, descsize, 0,
469 BUS_DMA_NOWAIT, &sc->sc_dma_ring_map); 486 BUS_DMA_NOWAIT, &sc->sc_dma_ring_map);
470 if (error != 0) { 487 if (error != 0) {
@@ -608,48 +625,50 @@ dwc_gmac_txdesc_sync(struct dwc_gmac_sof @@ -608,48 +625,50 @@ dwc_gmac_txdesc_sync(struct dwc_gmac_sof
608 /* sync from start of ring to 'end' */ 625 /* sync from start of ring to 'end' */
609 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 626 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map,
610 TX_DESC_OFFSET(0), 627 TX_DESC_OFFSET(0),
611 TX_DESC_OFFSET(end)-TX_DESC_OFFSET(0), 628 TX_DESC_OFFSET(end)-TX_DESC_OFFSET(0),
612 ops); 629 ops);
613} 630}
614 631
615static void 632static void
616dwc_gmac_reset_tx_ring(struct dwc_gmac_softc *sc, 633dwc_gmac_reset_tx_ring(struct dwc_gmac_softc *sc,
617 struct dwc_gmac_tx_ring *ring) 634 struct dwc_gmac_tx_ring *ring)
618{ 635{
619 int i; 636 int i;
620 637
 638 mutex_enter(&ring->t_mtx);
621 for (i = 0; i < AWGE_TX_RING_COUNT; i++) { 639 for (i = 0; i < AWGE_TX_RING_COUNT; i++) {
622 struct dwc_gmac_tx_data *data = &ring->t_data[i]; 640 struct dwc_gmac_tx_data *data = &ring->t_data[i];
623 641
624 if (data->td_m != NULL) { 642 if (data->td_m != NULL) {
625 bus_dmamap_sync(sc->sc_dmat, data->td_active, 643 bus_dmamap_sync(sc->sc_dmat, data->td_active,
626 0, data->td_active->dm_mapsize, 644 0, data->td_active->dm_mapsize,
627 BUS_DMASYNC_POSTWRITE); 645 BUS_DMASYNC_POSTWRITE);
628 bus_dmamap_unload(sc->sc_dmat, data->td_active); 646 bus_dmamap_unload(sc->sc_dmat, data->td_active);
629 m_freem(data->td_m); 647 m_freem(data->td_m);
630 data->td_m = NULL; 648 data->td_m = NULL;
631 } 649 }
632 } 650 }
633 651
634 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 652 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map,
635 TX_DESC_OFFSET(0), 653 TX_DESC_OFFSET(0),
636 AWGE_TX_RING_COUNT*sizeof(struct dwc_gmac_dev_dmadesc), 654 AWGE_TX_RING_COUNT*sizeof(struct dwc_gmac_dev_dmadesc),
637 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 655 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
638 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_TX_ADDR, 656 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_TX_ADDR,
639 sc->sc_txq.t_physaddr); 657 sc->sc_txq.t_physaddr);
640 658
641 ring->t_queued = 0; 659 ring->t_queued = 0;
642 ring->t_cur = ring->t_next = 0; 660 ring->t_cur = ring->t_next = 0;
 661 mutex_exit(&ring->t_mtx);
643} 662}
644 663
645static void 664static void
646dwc_gmac_free_tx_ring(struct dwc_gmac_softc *sc, 665dwc_gmac_free_tx_ring(struct dwc_gmac_softc *sc,
647 struct dwc_gmac_tx_ring *ring) 666 struct dwc_gmac_tx_ring *ring)
648{ 667{
649 int i; 668 int i;
650 669
651 /* unload the maps */ 670 /* unload the maps */
652 for (i = 0; i < AWGE_TX_RING_COUNT; i++) { 671 for (i = 0; i < AWGE_TX_RING_COUNT; i++) {
653 struct dwc_gmac_tx_data *data = &ring->t_data[i]; 672 struct dwc_gmac_tx_data *data = &ring->t_data[i];
654 673
655 if (data->td_m != NULL) { 674 if (data->td_m != NULL) {
@@ -719,26 +738,38 @@ dwc_gmac_miibus_statchg(struct ifnet *if @@ -719,26 +738,38 @@ dwc_gmac_miibus_statchg(struct ifnet *if
719#ifdef DWC_GMAC_DEBUG 738#ifdef DWC_GMAC_DEBUG
720 aprint_normal_dev(sc->sc_dev, 739 aprint_normal_dev(sc->sc_dev,
721 "setting MAC conf register: %08x\n", conf); 740 "setting MAC conf register: %08x\n", conf);
722#endif 741#endif
723 742
724 bus_space_write_4(sc->sc_bst, sc->sc_bsh, 743 bus_space_write_4(sc->sc_bst, sc->sc_bsh,
725 AWIN_GMAC_MAC_CONF, conf); 744 AWIN_GMAC_MAC_CONF, conf);
726} 745}
727 746
728static int 747static int
729dwc_gmac_init(struct ifnet *ifp) 748dwc_gmac_init(struct ifnet *ifp)
730{ 749{
731 struct dwc_gmac_softc *sc = ifp->if_softc; 750 struct dwc_gmac_softc *sc = ifp->if_softc;
 751
 752 mutex_enter(sc->sc_lock);
 753 int ret = dwc_gmac_init_locked(ifp);
 754 mutex_exit(sc->sc_lock);
 755
 756 return ret;
 757}
 758
 759static int
 760dwc_gmac_init_locked(struct ifnet *ifp)
 761{
 762 struct dwc_gmac_softc *sc = ifp->if_softc;
732 uint32_t ffilt; 763 uint32_t ffilt;
733 764
734 if (ifp->if_flags & IFF_RUNNING) 765 if (ifp->if_flags & IFF_RUNNING)
735 return 0; 766 return 0;
736 767
737 dwc_gmac_stop(ifp, 0); 768 dwc_gmac_stop(ifp, 0);
738 769
739 /* 770 /*
740 * Configure DMA burst/transfer mode and RX/TX priorities. 771 * Configure DMA burst/transfer mode and RX/TX priorities.
741 * XXX - the GMAC_BUSMODE_PRIORXTX bits are undocumented. 772 * XXX - the GMAC_BUSMODE_PRIORXTX bits are undocumented.
742 */ 773 */
743 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_BUSMODE, 774 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_BUSMODE,
744 GMAC_BUSMODE_FIXEDBURST | GMAC_BUSMODE_4PBL | 775 GMAC_BUSMODE_FIXEDBURST | GMAC_BUSMODE_4PBL |
@@ -771,36 +802,52 @@ dwc_gmac_init(struct ifnet *ifp) @@ -771,36 +802,52 @@ dwc_gmac_init(struct ifnet *ifp)
771 */ 802 */
772 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_RX_ADDR, 803 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_RX_ADDR,
773 sc->sc_rxq.r_physaddr); 804 sc->sc_rxq.r_physaddr);
774 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_TX_ADDR, 805 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_TX_ADDR,
775 sc->sc_txq.t_physaddr); 806 sc->sc_txq.t_physaddr);
776 807
777 /* 808 /*
778 * Start RX/TX part 809 * Start RX/TX part
779 */ 810 */
780 bus_space_write_4(sc->sc_bst, sc->sc_bsh, 811 bus_space_write_4(sc->sc_bst, sc->sc_bsh,
781 AWIN_GMAC_DMA_OPMODE, GMAC_DMA_OP_RXSTART | GMAC_DMA_OP_TXSTART | 812 AWIN_GMAC_DMA_OPMODE, GMAC_DMA_OP_RXSTART | GMAC_DMA_OP_TXSTART |
782 GMAC_DMA_OP_RXSTOREFORWARD | GMAC_DMA_OP_TXSTOREFORWARD); 813 GMAC_DMA_OP_RXSTOREFORWARD | GMAC_DMA_OP_TXSTOREFORWARD);
783 814
 815 sc->sc_stopping = false;
 816
784 ifp->if_flags |= IFF_RUNNING; 817 ifp->if_flags |= IFF_RUNNING;
785 ifp->if_flags &= ~IFF_OACTIVE; 818 ifp->if_flags &= ~IFF_OACTIVE;
786 819
787 return 0; 820 return 0;
788} 821}
789 822
790static void 823static void
791dwc_gmac_start(struct ifnet *ifp) 824dwc_gmac_start(struct ifnet *ifp)
792{ 825{
793 struct dwc_gmac_softc *sc = ifp->if_softc; 826 struct dwc_gmac_softc *sc = ifp->if_softc;
 827
 828 mutex_enter(sc->sc_lock);
 829 if (!sc->sc_stopping) {
 830 mutex_enter(&sc->sc_txq.t_mtx);
 831 dwc_gmac_start_locked(ifp);
 832 mutex_exit(&sc->sc_txq.t_mtx);
 833 }
 834 mutex_exit(sc->sc_lock);
 835}
 836
 837static void
 838dwc_gmac_start_locked(struct ifnet *ifp)
 839{
 840 struct dwc_gmac_softc *sc = ifp->if_softc;
794 int old = sc->sc_txq.t_queued; 841 int old = sc->sc_txq.t_queued;
795 int start = sc->sc_txq.t_cur; 842 int start = sc->sc_txq.t_cur;
796 struct mbuf *m0; 843 struct mbuf *m0;
797 844
798 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING) 845 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
799 return; 846 return;
800 847
801 for (;;) { 848 for (;;) {
802 IFQ_POLL(&ifp->if_snd, m0); 849 IFQ_POLL(&ifp->if_snd, m0);
803 if (m0 == NULL) 850 if (m0 == NULL)
804 break; 851 break;
805 if (dwc_gmac_queue(sc, m0) != 0) { 852 if (dwc_gmac_queue(sc, m0) != 0) {
806 ifp->if_flags |= IFF_OACTIVE; 853 ifp->if_flags |= IFF_OACTIVE;
@@ -822,26 +869,38 @@ dwc_gmac_start(struct ifnet *ifp) @@ -822,26 +869,38 @@ dwc_gmac_start(struct ifnet *ifp)
822 bus_space_write_4(sc->sc_bst, sc->sc_bsh, 869 bus_space_write_4(sc->sc_bst, sc->sc_bsh,
823 AWIN_GMAC_DMA_TXPOLL, ~0U); 870 AWIN_GMAC_DMA_TXPOLL, ~0U);
824#ifdef DWC_GMAC_DEBUG 871#ifdef DWC_GMAC_DEBUG
825 dwc_dump_status(sc); 872 dwc_dump_status(sc);
826#endif 873#endif
827 } 874 }
828} 875}
829 876
830static void 877static void
831dwc_gmac_stop(struct ifnet *ifp, int disable) 878dwc_gmac_stop(struct ifnet *ifp, int disable)
832{ 879{
833 struct dwc_gmac_softc *sc = ifp->if_softc; 880 struct dwc_gmac_softc *sc = ifp->if_softc;
834 881
 882 mutex_enter(sc->sc_lock);
 883 dwc_gmac_stop_locked(ifp, disable);
 884 mutex_exit(sc->sc_lock);
 885}
 886
 887static void
 888dwc_gmac_stop_locked(struct ifnet *ifp, int disable)
 889{
 890 struct dwc_gmac_softc *sc = ifp->if_softc;
 891
 892 sc->sc_stopping = true;
 893
835 bus_space_write_4(sc->sc_bst, sc->sc_bsh, 894 bus_space_write_4(sc->sc_bst, sc->sc_bsh,
836 AWIN_GMAC_DMA_OPMODE, 895 AWIN_GMAC_DMA_OPMODE,
837 bus_space_read_4(sc->sc_bst, sc->sc_bsh, 896 bus_space_read_4(sc->sc_bst, sc->sc_bsh,
838 AWIN_GMAC_DMA_OPMODE) 897 AWIN_GMAC_DMA_OPMODE)
839 & ~(GMAC_DMA_OP_TXSTART|GMAC_DMA_OP_RXSTART)); 898 & ~(GMAC_DMA_OP_TXSTART|GMAC_DMA_OP_RXSTART));
840 bus_space_write_4(sc->sc_bst, sc->sc_bsh, 899 bus_space_write_4(sc->sc_bst, sc->sc_bsh,
841 AWIN_GMAC_DMA_OPMODE, 900 AWIN_GMAC_DMA_OPMODE,
842 bus_space_read_4(sc->sc_bst, sc->sc_bsh, 901 bus_space_read_4(sc->sc_bst, sc->sc_bsh,
843 AWIN_GMAC_DMA_OPMODE) | GMAC_DMA_OP_FLUSHTX); 902 AWIN_GMAC_DMA_OPMODE) | GMAC_DMA_OP_FLUSHTX);
844 903
845 mii_down(&sc->sc_mii); 904 mii_down(&sc->sc_mii);
846 dwc_gmac_reset_tx_ring(sc, &sc->sc_txq); 905 dwc_gmac_reset_tx_ring(sc, &sc->sc_txq);
847 dwc_gmac_reset_rx_ring(sc, &sc->sc_rxq); 906 dwc_gmac_reset_rx_ring(sc, &sc->sc_rxq);
@@ -930,69 +989,85 @@ dwc_gmac_queue(struct dwc_gmac_softc *sc @@ -930,69 +989,85 @@ dwc_gmac_queue(struct dwc_gmac_softc *sc
930 * If the interface is up and running, only modify the receive 989 * If the interface is up and running, only modify the receive
931 * filter when setting promiscuous or debug mode. Otherwise fall 990 * filter when setting promiscuous or debug mode. Otherwise fall
932 * through to ether_ioctl, which will reset the chip. 991 * through to ether_ioctl, which will reset the chip.
933 */ 992 */
934static int 993static int
935dwc_gmac_ifflags_cb(struct ethercom *ec) 994dwc_gmac_ifflags_cb(struct ethercom *ec)
936{ 995{
937 struct ifnet *ifp = &ec->ec_if; 996 struct ifnet *ifp = &ec->ec_if;
938 struct dwc_gmac_softc *sc = ifp->if_softc; 997 struct dwc_gmac_softc *sc = ifp->if_softc;
939 int change = ifp->if_flags ^ sc->sc_if_flags; 998 int change = ifp->if_flags ^ sc->sc_if_flags;
940 999
941 if ((change & ~(IFF_CANTCHANGE|IFF_DEBUG)) != 0) 1000 if ((change & ~(IFF_CANTCHANGE|IFF_DEBUG)) != 0)
942 return ENETRESET; 1001 return ENETRESET;
943 if ((change & IFF_PROMISC) != 0) 1002 if ((change & IFF_PROMISC) != 0) {
 1003 mutex_enter(sc->sc_lock);
944 dwc_gmac_setmulti(sc); 1004 dwc_gmac_setmulti(sc);
 1005 mutex_exit(sc->sc_lock);
 1006 }
945 return 0; 1007 return 0;
946} 1008}
947 1009
948static int 1010static int
949dwc_gmac_ioctl(struct ifnet *ifp, u_long cmd, void *data) 1011dwc_gmac_ioctl(struct ifnet *ifp, u_long cmd, void *data)
950{ 1012{
951 struct dwc_gmac_softc *sc = ifp->if_softc; 1013 struct dwc_gmac_softc *sc = ifp->if_softc;
952 int s, error = 0; 1014 int error = 0;
953 1015
954 s = splnet(); 1016 int s = splnet();
 1017 error = ether_ioctl(ifp, cmd, data);
955 1018
956 if ((error = ether_ioctl(ifp, cmd, data)) == ENETRESET) { 1019#ifdef DWCGMAC_MPSAFE
 1020 splx(s);
 1021#endif
 1022
 1023 if (error == ENETRESET) {
957 error = 0; 1024 error = 0;
958 if (cmd != SIOCADDMULTI && cmd != SIOCDELMULTI) 1025 if (cmd != SIOCADDMULTI && cmd != SIOCDELMULTI)
959 ; 1026 ;
960 else if (ifp->if_flags & IFF_RUNNING) { 1027 else if (ifp->if_flags & IFF_RUNNING) {
961 /* 1028 /*
962 * Multicast list has changed; set the hardware filter 1029 * Multicast list has changed; set the hardware filter
963 * accordingly. 1030 * accordingly.
964 */ 1031 */
 1032 mutex_enter(sc->sc_lock);
965 dwc_gmac_setmulti(sc); 1033 dwc_gmac_setmulti(sc);
 1034 mutex_exit(sc->sc_lock);
966 } 1035 }
967 } 1036 }
968 1037
969 /* Try to get things going again */ 1038 /* Try to get things going again */
970 if (ifp->if_flags & IFF_UP) 1039 if (ifp->if_flags & IFF_UP)
971 dwc_gmac_start(ifp); 1040 dwc_gmac_start(ifp);
972 sc->sc_if_flags = sc->sc_ec.ec_if.if_flags; 1041 sc->sc_if_flags = sc->sc_ec.ec_if.if_flags;
 1042
 1043#ifndef DWCGMAC_MPSAFE
973 splx(s); 1044 splx(s);
 1045#endif
 1046
974 return error; 1047 return error;
975} 1048}
976 1049
977static void 1050static void
978dwc_gmac_tx_intr(struct dwc_gmac_softc *sc) 1051dwc_gmac_tx_intr(struct dwc_gmac_softc *sc)
979{ 1052{
980 struct ifnet *ifp = &sc->sc_ec.ec_if; 1053 struct ifnet *ifp = &sc->sc_ec.ec_if;
981 struct dwc_gmac_tx_data *data; 1054 struct dwc_gmac_tx_data *data;
982 struct dwc_gmac_dev_dmadesc *desc; 1055 struct dwc_gmac_dev_dmadesc *desc;
983 uint32_t status; 1056 uint32_t status;
984 int i, nsegs; 1057 int i, nsegs;
985 1058
 1059 mutex_enter(&sc->sc_txq.t_mtx);
 1060
986 for (i = sc->sc_txq.t_next; sc->sc_txq.t_queued > 0; i = TX_NEXT(i)) { 1061 for (i = sc->sc_txq.t_next; sc->sc_txq.t_queued > 0; i = TX_NEXT(i)) {
987#ifdef DWC_GMAC_DEBUG 1062#ifdef DWC_GMAC_DEBUG
988 aprint_normal_dev(sc->sc_dev, 1063 aprint_normal_dev(sc->sc_dev,
989 "dwc_gmac_tx_intr: checking desc #%d (t_queued: %d)\n", 1064 "dwc_gmac_tx_intr: checking desc #%d (t_queued: %d)\n",
990 i, sc->sc_txq.t_queued); 1065 i, sc->sc_txq.t_queued);
991#endif 1066#endif
992 1067
993 /* 1068 /*
994 * i+1 does not need to be a valid descriptor, 1069 * i+1 does not need to be a valid descriptor,
995 * this is just a special notion to just sync 1070 * this is just a special notion to just sync
996 * a single tx descriptor (i) 1071 * a single tx descriptor (i)
997 */ 1072 */
998 dwc_gmac_txdesc_sync(sc, i, i+1, 1073 dwc_gmac_txdesc_sync(sc, i, i+1,
@@ -1020,39 +1095,41 @@ dwc_gmac_tx_intr(struct dwc_gmac_softc * @@ -1020,39 +1095,41 @@ dwc_gmac_tx_intr(struct dwc_gmac_softc *
1020#endif 1095#endif
1021 1096
1022 m_freem(data->td_m); 1097 m_freem(data->td_m);
1023 data->td_m = NULL; 1098 data->td_m = NULL;
1024 1099
1025 sc->sc_txq.t_queued -= nsegs; 1100 sc->sc_txq.t_queued -= nsegs;
1026 } 1101 }
1027 1102
1028 sc->sc_txq.t_next = i; 1103 sc->sc_txq.t_next = i;
1029 1104
1030 if (sc->sc_txq.t_queued < AWGE_TX_RING_COUNT) { 1105 if (sc->sc_txq.t_queued < AWGE_TX_RING_COUNT) {
1031 ifp->if_flags &= ~IFF_OACTIVE; 1106 ifp->if_flags &= ~IFF_OACTIVE;
1032 } 1107 }
 1108 mutex_exit(&sc->sc_txq.t_mtx);
1033} 1109}
1034 1110
1035static void 1111static void
1036dwc_gmac_rx_intr(struct dwc_gmac_softc *sc) 1112dwc_gmac_rx_intr(struct dwc_gmac_softc *sc)
1037{ 1113{
1038 struct ifnet *ifp = &sc->sc_ec.ec_if; 1114 struct ifnet *ifp = &sc->sc_ec.ec_if;
1039 struct dwc_gmac_dev_dmadesc *desc; 1115 struct dwc_gmac_dev_dmadesc *desc;
1040 struct dwc_gmac_rx_data *data; 1116 struct dwc_gmac_rx_data *data;
1041 bus_addr_t physaddr; 1117 bus_addr_t physaddr;
1042 uint32_t status; 1118 uint32_t status;
1043 struct mbuf *m, *mnew; 1119 struct mbuf *m, *mnew;
1044 int i, len, error; 1120 int i, len, error;
1045 1121
 1122 mutex_enter(&sc->sc_rxq.r_mtx);
1046 for (i = sc->sc_rxq.r_cur; ; i = RX_NEXT(i)) { 1123 for (i = sc->sc_rxq.r_cur; ; i = RX_NEXT(i)) {
1047 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 1124 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map,
1048 RX_DESC_OFFSET(i), sizeof(*desc), 1125 RX_DESC_OFFSET(i), sizeof(*desc),
1049 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); 1126 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
1050 desc = &sc->sc_rxq.r_desc[i]; 1127 desc = &sc->sc_rxq.r_desc[i];
1051 data = &sc->sc_rxq.r_data[i]; 1128 data = &sc->sc_rxq.r_data[i];
1052 1129
1053 status = le32toh(desc->ddesc_status); 1130 status = le32toh(desc->ddesc_status);
1054 if (status & DDESC_STATUS_OWNEDBYDEV) 1131 if (status & DDESC_STATUS_OWNEDBYDEV)
1055 break; 1132 break;
1056 1133
1057 if (status & (DDESC_STATUS_RXERROR|DDESC_STATUS_RXTRUNCATED)) { 1134 if (status & (DDESC_STATUS_RXERROR|DDESC_STATUS_RXTRUNCATED)) {
1058#ifdef DWC_GMAC_DEBUG 1135#ifdef DWC_GMAC_DEBUG
@@ -1088,99 +1165,105 @@ dwc_gmac_rx_intr(struct dwc_gmac_softc * @@ -1088,99 +1165,105 @@ dwc_gmac_rx_intr(struct dwc_gmac_softc *
1088 ifp->if_ierrors++; 1165 ifp->if_ierrors++;
1089 goto skip; 1166 goto skip;
1090 } 1167 }
1091 1168
1092 /* unload old DMA map */ 1169 /* unload old DMA map */
1093 bus_dmamap_sync(sc->sc_dmat, data->rd_map, 0, 1170 bus_dmamap_sync(sc->sc_dmat, data->rd_map, 0,
1094 data->rd_map->dm_mapsize, BUS_DMASYNC_POSTREAD); 1171 data->rd_map->dm_mapsize, BUS_DMASYNC_POSTREAD);
1095 bus_dmamap_unload(sc->sc_dmat, data->rd_map); 1172 bus_dmamap_unload(sc->sc_dmat, data->rd_map);
1096 1173
1097 /* and reload with new mbuf */ 1174 /* and reload with new mbuf */
1098 error = bus_dmamap_load(sc->sc_dmat, data->rd_map, 1175 error = bus_dmamap_load(sc->sc_dmat, data->rd_map,
1099 mtod(mnew, void*), MCLBYTES, NULL, 1176 mtod(mnew, void*), MCLBYTES, NULL,
1100 BUS_DMA_READ | BUS_DMA_NOWAIT); 1177 BUS_DMA_READ | BUS_DMA_NOWAIT);
1101 if (error != 0) { 1178 if (error != 0) {
1102 m_freem(mnew); 1179 m_freem(mnew);
1103 /* try to reload old mbuf */ 1180 /* try to reload old mbuf */
1104 error = bus_dmamap_load(sc->sc_dmat, data->rd_map, 1181 error = bus_dmamap_load(sc->sc_dmat, data->rd_map,
1105 mtod(data->rd_m, void*), MCLBYTES, NULL, 1182 mtod(data->rd_m, void*), MCLBYTES, NULL,
1106 BUS_DMA_READ | BUS_DMA_NOWAIT); 1183 BUS_DMA_READ | BUS_DMA_NOWAIT);
1107 if (error != 0) { 1184 if (error != 0) {
1108 panic("%s: could not load old rx mbuf", 1185 panic("%s: could not load old rx mbuf",
1109 device_xname(sc->sc_dev)); 1186 device_xname(sc->sc_dev));
1110 } 1187 }
1111 ifp->if_ierrors++; 1188 ifp->if_ierrors++;
1112 goto skip; 1189 goto skip;
1113 } 1190 }
1114 physaddr = data->rd_map->dm_segs[0].ds_addr; 1191 physaddr = data->rd_map->dm_segs[0].ds_addr;
1115 1192
1116 /* 1193 /*
1117 * New mbuf loaded, update RX ring and continue 1194 * New mbuf loaded, update RX ring and continue
1118 */ 1195 */
1119 m = data->rd_m; 1196 m = data->rd_m;
1120 data->rd_m = mnew; 1197 data->rd_m = mnew;
1121 desc->ddesc_data = htole32(physaddr); 1198 desc->ddesc_data = htole32(physaddr);
1122 1199
1123 /* finalize mbuf */ 1200 /* finalize mbuf */
1124 m->m_pkthdr.len = m->m_len = len; 1201 m->m_pkthdr.len = m->m_len = len;
1125 m->m_pkthdr.rcvif = ifp; 1202 m->m_pkthdr.rcvif = ifp;
1126 m->m_flags |= M_HASFCS; 1203 m->m_flags |= M_HASFCS;
1127 1204
1128 bpf_mtap(ifp, m); 
1129 ifp->if_ipackets++; 1205 ifp->if_ipackets++;
 1206
 1207 mutex_exit(&sc->sc_rxq.r_mtx);
 1208
 1209 bpf_mtap(ifp, m);
1130 if_percpuq_enqueue(ifp->if_percpuq, m); 1210 if_percpuq_enqueue(ifp->if_percpuq, m);
1131 1211
 1212 mutex_enter(&sc->sc_rxq.r_mtx);
 1213
1132skip: 1214skip:
1133 bus_dmamap_sync(sc->sc_dmat, data->rd_map, 0, 1215 bus_dmamap_sync(sc->sc_dmat, data->rd_map, 0,
1134 data->rd_map->dm_mapsize, BUS_DMASYNC_PREREAD); 1216 data->rd_map->dm_mapsize, BUS_DMASYNC_PREREAD);
1135 desc->ddesc_cntl = htole32( 1217 desc->ddesc_cntl = htole32(
1136 __SHIFTIN(AWGE_MAX_PACKET,DDESC_CNTL_SIZE1MASK) | 1218 __SHIFTIN(AWGE_MAX_PACKET,DDESC_CNTL_SIZE1MASK) |
1137 DDESC_CNTL_RXCHAIN); 1219 DDESC_CNTL_RXCHAIN);
1138 desc->ddesc_status = htole32(DDESC_STATUS_OWNEDBYDEV); 1220 desc->ddesc_status = htole32(DDESC_STATUS_OWNEDBYDEV);
1139 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 1221 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map,
1140 RX_DESC_OFFSET(i), sizeof(*desc), 1222 RX_DESC_OFFSET(i), sizeof(*desc),
1141 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 1223 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
1142 } 1224 }
1143 1225
1144 /* update RX pointer */ 1226 /* update RX pointer */
1145 sc->sc_rxq.r_cur = i; 1227 sc->sc_rxq.r_cur = i;
1146 1228
 1229 mutex_exit(&sc->sc_rxq.r_mtx);
1147} 1230}
1148 1231
1149/* 1232/*
1150 * Reverse order of bits - http://aggregate.org/MAGIC/#Bit%20Reversal 1233 * Reverse order of bits - http://aggregate.org/MAGIC/#Bit%20Reversal
1151 */ 1234 */
1152static uint32_t 1235static uint32_t
1153bitrev32(uint32_t x) 1236bitrev32(uint32_t x)
1154{ 1237{
1155 x = (((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1)); 1238 x = (((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1));
1156 x = (((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2)); 1239 x = (((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2));
1157 x = (((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4)); 1240 x = (((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4));
1158 x = (((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8)); 1241 x = (((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8));
1159 1242
1160 return (x >> 16) | (x << 16); 1243 return (x >> 16) | (x << 16);
1161} 1244}
1162 1245
1163static void 1246static void
1164dwc_gmac_setmulti(struct dwc_gmac_softc *sc) 1247dwc_gmac_setmulti(struct dwc_gmac_softc *sc)
1165{ 1248{
1166 struct ifnet * const ifp = &sc->sc_ec.ec_if; 1249 struct ifnet * const ifp = &sc->sc_ec.ec_if;
1167 struct ether_multi *enm; 1250 struct ether_multi *enm;
1168 struct ether_multistep step; 1251 struct ether_multistep step;
1169 uint32_t hashes[2] = { 0, 0 }; 1252 uint32_t hashes[2] = { 0, 0 };
1170 uint32_t ffilt, h; 1253 uint32_t ffilt, h;
1171 int mcnt, s; 1254 int mcnt;
1172 1255
1173 s = splnet(); 1256 KASSERT(mutex_owned(sc->sc_lock));
1174 1257
1175 ffilt = bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_FFILT); 1258 ffilt = bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_FFILT);
1176 1259
1177 if (ifp->if_flags & IFF_PROMISC) { 1260 if (ifp->if_flags & IFF_PROMISC) {
1178 ffilt |= AWIN_GMAC_MAC_FFILT_PR; 1261 ffilt |= AWIN_GMAC_MAC_FFILT_PR;
1179 goto special_filter; 1262 goto special_filter;
1180 } 1263 }
1181 1264
1182 ifp->if_flags &= ~IFF_ALLMULTI; 1265 ifp->if_flags &= ~IFF_ALLMULTI;
1183 ffilt &= ~(AWIN_GMAC_MAC_FFILT_PM|AWIN_GMAC_MAC_FFILT_PR); 1266 ffilt &= ~(AWIN_GMAC_MAC_FFILT_PM|AWIN_GMAC_MAC_FFILT_PR);
1184 1267
1185 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTLOW, 0); 1268 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTLOW, 0);
1186 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTHIGH, 0); 1269 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTHIGH, 0);
@@ -1206,54 +1289,54 @@ dwc_gmac_setmulti(struct dwc_gmac_softc  @@ -1206,54 +1289,54 @@ dwc_gmac_setmulti(struct dwc_gmac_softc
1206 1289
1207 if (mcnt) 1290 if (mcnt)
1208 ffilt |= AWIN_GMAC_MAC_FFILT_HMC; 1291 ffilt |= AWIN_GMAC_MAC_FFILT_HMC;
1209 else 1292 else
1210 ffilt &= ~AWIN_GMAC_MAC_FFILT_HMC; 1293 ffilt &= ~AWIN_GMAC_MAC_FFILT_HMC;
1211 1294
1212 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_FFILT, ffilt); 1295 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_FFILT, ffilt);
1213 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTLOW, 1296 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTLOW,
1214 hashes[0]); 1297 hashes[0]);
1215 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTHIGH, 1298 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTHIGH,
1216 hashes[1]); 1299 hashes[1]);
1217 sc->sc_if_flags = sc->sc_ec.ec_if.if_flags; 1300 sc->sc_if_flags = sc->sc_ec.ec_if.if_flags;
1218 1301
1219 splx(s); 
1220 
1221#ifdef DWC_GMAC_DEBUG 1302#ifdef DWC_GMAC_DEBUG
1222 dwc_gmac_dump_ffilt(sc, ffilt); 1303 dwc_gmac_dump_ffilt(sc, ffilt);
1223#endif 1304#endif
1224 return; 1305 return;
1225 1306
1226special_filter: 1307special_filter:
1227#ifdef DWC_GMAC_DEBUG 1308#ifdef DWC_GMAC_DEBUG
1228 dwc_gmac_dump_ffilt(sc, ffilt); 1309 dwc_gmac_dump_ffilt(sc, ffilt);
1229#endif 1310#endif
1230 /* no MAC hashes, ALLMULTI or PROMISC */ 1311 /* no MAC hashes, ALLMULTI or PROMISC */
1231 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_FFILT, 1312 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_FFILT,
1232 ffilt); 1313 ffilt);
1233 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTLOW, 1314 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTLOW,
1234 0xffffffff); 1315 0xffffffff);
1235 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTHIGH, 1316 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTHIGH,
1236 0xffffffff); 1317 0xffffffff);
1237 sc->sc_if_flags = sc->sc_ec.ec_if.if_flags; 1318 sc->sc_if_flags = sc->sc_ec.ec_if.if_flags;
1238 splx(s); 
1239} 1319}
1240 1320
1241int 1321int
1242dwc_gmac_intr(struct dwc_gmac_softc *sc) 1322dwc_gmac_intr(struct dwc_gmac_softc *sc)
1243{ 1323{
1244 uint32_t status, dma_status; 1324 uint32_t status, dma_status;
1245 int rv = 0; 1325 int rv = 0;
1246 1326
 1327 if (sc->sc_stopping)
 1328 return 0;
 1329
1247 status = bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_INTR); 1330 status = bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_INTR);
1248 if (status & AWIN_GMAC_MII_IRQ) { 1331 if (status & AWIN_GMAC_MII_IRQ) {
1249 (void)bus_space_read_4(sc->sc_bst, sc->sc_bsh, 1332 (void)bus_space_read_4(sc->sc_bst, sc->sc_bsh,
1250 AWIN_GMAC_MII_STATUS); 1333 AWIN_GMAC_MII_STATUS);
1251 rv = 1; 1334 rv = 1;
1252 mii_pollstat(&sc->sc_mii); 1335 mii_pollstat(&sc->sc_mii);
1253 } 1336 }
1254 1337
1255 dma_status = bus_space_read_4(sc->sc_bst, sc->sc_bsh, 1338 dma_status = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
1256 AWIN_GMAC_DMA_STATUS); 1339 AWIN_GMAC_DMA_STATUS);
1257 1340
1258 if (dma_status & (GMAC_DMA_INT_NIE|GMAC_DMA_INT_AIE)) 1341 if (dma_status & (GMAC_DMA_INT_NIE|GMAC_DMA_INT_AIE))
1259 rv = 1; 1342 rv = 1;

cvs diff -r1.6 -r1.6.2.1 src/sys/dev/ic/dwc_gmac_var.h (expand / switch to unified diff)

--- src/sys/dev/ic/dwc_gmac_var.h 2014/11/22 18:31:03 1.6
+++ src/sys/dev/ic/dwc_gmac_var.h 2016/06/12 07:18:52 1.6.2.1
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: dwc_gmac_var.h,v 1.6 2014/11/22 18:31:03 jmcneill Exp $ */ 1/* $NetBSD: dwc_gmac_var.h,v 1.6.2.1 2016/06/12 07:18:52 skrll Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2013, 2014 The NetBSD Foundation, Inc. 4 * Copyright (c) 2013, 2014 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Matt Thomas of 3am Software Foundry and Martin Husemann. 8 * by Matt Thomas of 3am Software Foundry and Martin Husemann.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -54,41 +54,47 @@ struct dwc_gmac_rx_data { @@ -54,41 +54,47 @@ struct dwc_gmac_rx_data {
54}; 54};
55 55
56struct dwc_gmac_tx_data { 56struct dwc_gmac_tx_data {
57 bus_dmamap_t td_map; 57 bus_dmamap_t td_map;
58 bus_dmamap_t td_active; 58 bus_dmamap_t td_active;
59 struct mbuf *td_m; 59 struct mbuf *td_m;
60}; 60};
61 61
62struct dwc_gmac_tx_ring { 62struct dwc_gmac_tx_ring {
63 bus_addr_t t_physaddr; /* PA of TX ring start */ 63 bus_addr_t t_physaddr; /* PA of TX ring start */
64 struct dwc_gmac_dev_dmadesc *t_desc; /* VA of TX ring start */ 64 struct dwc_gmac_dev_dmadesc *t_desc; /* VA of TX ring start */
65 struct dwc_gmac_tx_data t_data[AWGE_TX_RING_COUNT]; 65 struct dwc_gmac_tx_data t_data[AWGE_TX_RING_COUNT];
66 int t_cur, t_next, t_queued; 66 int t_cur, t_next, t_queued;
 67 kmutex_t t_mtx;
67}; 68};
68 69
69struct dwc_gmac_rx_ring { 70struct dwc_gmac_rx_ring {
70 bus_addr_t r_physaddr; /* PA of RX ring start */ 71 bus_addr_t r_physaddr; /* PA of RX ring start */
71 struct dwc_gmac_dev_dmadesc *r_desc; /* VA of RX ring start */ 72 struct dwc_gmac_dev_dmadesc *r_desc; /* VA of RX ring start */
72 struct dwc_gmac_rx_data r_data[AWGE_RX_RING_COUNT]; 73 struct dwc_gmac_rx_data r_data[AWGE_RX_RING_COUNT];
73 int r_cur, r_next; 74 int r_cur, r_next;
74 kmutex_t r_mtx; 75 kmutex_t r_mtx;
75}; 76};
76 77
77struct dwc_gmac_softc { 78struct dwc_gmac_softc {
78 device_t sc_dev; 79 device_t sc_dev;
79 bus_space_tag_t sc_bst; 80 bus_space_tag_t sc_bst;
80 bus_space_handle_t sc_bsh; 81 bus_space_handle_t sc_bsh;
81 bus_dma_tag_t sc_dmat; 82 bus_dma_tag_t sc_dmat;
82 struct ethercom sc_ec; 83 struct ethercom sc_ec;
83 struct mii_data sc_mii; 84 struct mii_data sc_mii;
84 kmutex_t sc_mdio_lock; 85 kmutex_t sc_mdio_lock;
85 bus_dmamap_t sc_dma_ring_map; /* common dma memory for RX */ 86 bus_dmamap_t sc_dma_ring_map; /* common dma memory for RX */
86 bus_dma_segment_t sc_dma_ring_seg; /* and TX ring */ 87 bus_dma_segment_t sc_dma_ring_seg; /* and TX ring */
87 struct dwc_gmac_rx_ring sc_rxq; 88 struct dwc_gmac_rx_ring sc_rxq;
88 struct dwc_gmac_tx_ring sc_txq; 89 struct dwc_gmac_tx_ring sc_txq;
89 short sc_if_flags; /* shadow of ether flags */ 90 short sc_if_flags; /* shadow of ether flags */
90 uint16_t sc_mii_clk; 91 uint16_t sc_mii_clk;
 92 bool sc_stopping;
 93
 94 kmutex_t *sc_lock; /* lock for softc operations */
 95
 96 struct if_percpuq *sc_ipq; /* softint-based input queues */
91}; 97};
92 98
93void dwc_gmac_attach(struct dwc_gmac_softc*, uint32_t /*mii_clk*/); 99void dwc_gmac_attach(struct dwc_gmac_softc*, uint32_t /*mii_clk*/);
94int dwc_gmac_intr(struct dwc_gmac_softc*); 100int dwc_gmac_intr(struct dwc_gmac_softc*);