Wed Jan 29 14:14:56 2020 UTC ()
Adopt <net/if_stats.h>.


(thorpej)
diff -r1.19 -r1.20 src/sys/dev/ic/bwfm.c
diff -r1.36 -r1.37 src/sys/dev/ic/bwi.c
diff -r1.47 -r1.48 src/sys/dev/ic/cs89x0.c
diff -r1.21 -r1.22 src/sys/dev/ic/dm9000.c
diff -r1.95 -r1.96 src/sys/dev/ic/dp8390.c
diff -r1.44 -r1.45 src/sys/dev/ic/dp83932.c
diff -r1.68 -r1.69 src/sys/dev/ic/dwc_gmac.c

cvs diff -r1.19 -r1.20 src/sys/dev/ic/bwfm.c (switch to unified diff)

--- src/sys/dev/ic/bwfm.c 2019/12/27 09:22:20 1.19
+++ src/sys/dev/ic/bwfm.c 2020/01/29 14:14:55 1.20
@@ -1,1513 +1,1513 @@ @@ -1,1513 +1,1513 @@
1/* $NetBSD: bwfm.c,v 1.19 2019/12/27 09:22:20 msaitoh Exp $ */ 1/* $NetBSD: bwfm.c,v 1.20 2020/01/29 14:14:55 thorpej Exp $ */
2/* $OpenBSD: bwfm.c,v 1.5 2017/10/16 22:27:16 patrick Exp $ */ 2/* $OpenBSD: bwfm.c,v 1.5 2017/10/16 22:27:16 patrick Exp $ */
3/* 3/*
4 * Copyright (c) 2010-2016 Broadcom Corporation 4 * Copyright (c) 2010-2016 Broadcom Corporation
5 * Copyright (c) 2016,2017 Patrick Wildt <patrick@blueri.se> 5 * Copyright (c) 2016,2017 Patrick Wildt <patrick@blueri.se>
6 * 6 *
7 * Permission to use, copy, modify, and/or distribute this software for any 7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above 8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies. 9 * copyright notice and this permission notice appear in all copies.
10 * 10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */ 18 */
19 19
20#include <sys/param.h> 20#include <sys/param.h>
21#include <sys/systm.h> 21#include <sys/systm.h>
22#include <sys/buf.h> 22#include <sys/buf.h>
23#include <sys/kernel.h> 23#include <sys/kernel.h>
24#include <sys/device.h> 24#include <sys/device.h>
25#include <sys/queue.h> 25#include <sys/queue.h>
26#include <sys/socket.h> 26#include <sys/socket.h>
27#include <sys/kmem.h> 27#include <sys/kmem.h>
28#include <sys/workqueue.h> 28#include <sys/workqueue.h>
29#include <sys/pcq.h> 29#include <sys/pcq.h>
30 30
31#include <net/bpf.h> 31#include <net/bpf.h>
32#include <net/if.h> 32#include <net/if.h>
33#include <net/if_dl.h> 33#include <net/if_dl.h>
34#include <net/if_media.h> 34#include <net/if_media.h>
35#include <net/if_ether.h> 35#include <net/if_ether.h>
36 36
37#include <netinet/in.h> 37#include <netinet/in.h>
38 38
39#include <net80211/ieee80211_var.h> 39#include <net80211/ieee80211_var.h>
40 40
41#include <dev/ic/bwfmvar.h> 41#include <dev/ic/bwfmvar.h>
42#include <dev/ic/bwfmreg.h> 42#include <dev/ic/bwfmreg.h>
43 43
44/* #define BWFM_DEBUG */ 44/* #define BWFM_DEBUG */
45#ifdef BWFM_DEBUG 45#ifdef BWFM_DEBUG
46#define DPRINTF(x) do { if (bwfm_debug > 0) printf x; } while (0) 46#define DPRINTF(x) do { if (bwfm_debug > 0) printf x; } while (0)
47#define DPRINTFN(n, x) do { if (bwfm_debug >= (n)) printf x; } while (0) 47#define DPRINTFN(n, x) do { if (bwfm_debug >= (n)) printf x; } while (0)
48static int bwfm_debug = 1; 48static int bwfm_debug = 1;
49#else 49#else
50#define DPRINTF(x) do { ; } while (0) 50#define DPRINTF(x) do { ; } while (0)
51#define DPRINTFN(n, x) do { ; } while (0) 51#define DPRINTFN(n, x) do { ; } while (0)
52#endif 52#endif
53 53
54#define DEVNAME(sc) device_xname((sc)->sc_dev) 54#define DEVNAME(sc) device_xname((sc)->sc_dev)
55 55
56void bwfm_start(struct ifnet *); 56void bwfm_start(struct ifnet *);
57int bwfm_init(struct ifnet *); 57int bwfm_init(struct ifnet *);
58void bwfm_stop(struct ifnet *, int); 58void bwfm_stop(struct ifnet *, int);
59void bwfm_watchdog(struct ifnet *); 59void bwfm_watchdog(struct ifnet *);
60int bwfm_ioctl(struct ifnet *, u_long, void *); 60int bwfm_ioctl(struct ifnet *, u_long, void *);
61int bwfm_media_change(struct ifnet *); 61int bwfm_media_change(struct ifnet *);
62 62
63int bwfm_send_mgmt(struct ieee80211com *, struct ieee80211_node *, 63int bwfm_send_mgmt(struct ieee80211com *, struct ieee80211_node *,
64 int, int); 64 int, int);
65void bwfm_recv_mgmt(struct ieee80211com *, struct mbuf *, 65void bwfm_recv_mgmt(struct ieee80211com *, struct mbuf *,
66 struct ieee80211_node *, int, int, uint32_t); 66 struct ieee80211_node *, int, int, uint32_t);
67int bwfm_key_set(struct ieee80211com *, const struct ieee80211_key *, 67int bwfm_key_set(struct ieee80211com *, const struct ieee80211_key *,
68 const uint8_t *); 68 const uint8_t *);
69int bwfm_key_delete(struct ieee80211com *, const struct ieee80211_key *); 69int bwfm_key_delete(struct ieee80211com *, const struct ieee80211_key *);
70int bwfm_newstate(struct ieee80211com *, enum ieee80211_state, int); 70int bwfm_newstate(struct ieee80211com *, enum ieee80211_state, int);
71void bwfm_newstate_cb(struct bwfm_softc *, struct bwfm_cmd_newstate *); 71void bwfm_newstate_cb(struct bwfm_softc *, struct bwfm_cmd_newstate *);
72void bwfm_newassoc(struct ieee80211_node *, int); 72void bwfm_newassoc(struct ieee80211_node *, int);
73void bwfm_task(struct work *, void *); 73void bwfm_task(struct work *, void *);
74 74
75int bwfm_chip_attach(struct bwfm_softc *); 75int bwfm_chip_attach(struct bwfm_softc *);
76int bwfm_chip_detach(struct bwfm_softc *, int); 76int bwfm_chip_detach(struct bwfm_softc *, int);
77struct bwfm_core *bwfm_chip_get_core(struct bwfm_softc *, int); 77struct bwfm_core *bwfm_chip_get_core(struct bwfm_softc *, int);
78struct bwfm_core *bwfm_chip_get_pmu(struct bwfm_softc *); 78struct bwfm_core *bwfm_chip_get_pmu(struct bwfm_softc *);
79int bwfm_chip_ai_isup(struct bwfm_softc *, struct bwfm_core *); 79int bwfm_chip_ai_isup(struct bwfm_softc *, struct bwfm_core *);
80void bwfm_chip_ai_disable(struct bwfm_softc *, struct bwfm_core *, 80void bwfm_chip_ai_disable(struct bwfm_softc *, struct bwfm_core *,
81 uint32_t, uint32_t); 81 uint32_t, uint32_t);
82void bwfm_chip_ai_reset(struct bwfm_softc *, struct bwfm_core *, 82void bwfm_chip_ai_reset(struct bwfm_softc *, struct bwfm_core *,
83 uint32_t, uint32_t, uint32_t); 83 uint32_t, uint32_t, uint32_t);
84void bwfm_chip_dmp_erom_scan(struct bwfm_softc *); 84void bwfm_chip_dmp_erom_scan(struct bwfm_softc *);
85int bwfm_chip_dmp_get_regaddr(struct bwfm_softc *, uint32_t *, 85int bwfm_chip_dmp_get_regaddr(struct bwfm_softc *, uint32_t *,
86 uint32_t *, uint32_t *); 86 uint32_t *, uint32_t *);
87int bwfm_chip_cr4_set_active(struct bwfm_softc *, const uint32_t); 87int bwfm_chip_cr4_set_active(struct bwfm_softc *, const uint32_t);
88void bwfm_chip_cr4_set_passive(struct bwfm_softc *); 88void bwfm_chip_cr4_set_passive(struct bwfm_softc *);
89int bwfm_chip_ca7_set_active(struct bwfm_softc *, const uint32_t); 89int bwfm_chip_ca7_set_active(struct bwfm_softc *, const uint32_t);
90void bwfm_chip_ca7_set_passive(struct bwfm_softc *); 90void bwfm_chip_ca7_set_passive(struct bwfm_softc *);
91int bwfm_chip_cm3_set_active(struct bwfm_softc *); 91int bwfm_chip_cm3_set_active(struct bwfm_softc *);
92void bwfm_chip_cm3_set_passive(struct bwfm_softc *); 92void bwfm_chip_cm3_set_passive(struct bwfm_softc *);
93void bwfm_chip_socram_ramsize(struct bwfm_softc *, struct bwfm_core *); 93void bwfm_chip_socram_ramsize(struct bwfm_softc *, struct bwfm_core *);
94void bwfm_chip_sysmem_ramsize(struct bwfm_softc *, struct bwfm_core *); 94void bwfm_chip_sysmem_ramsize(struct bwfm_softc *, struct bwfm_core *);
95void bwfm_chip_tcm_ramsize(struct bwfm_softc *, struct bwfm_core *); 95void bwfm_chip_tcm_ramsize(struct bwfm_softc *, struct bwfm_core *);
96void bwfm_chip_tcm_rambase(struct bwfm_softc *); 96void bwfm_chip_tcm_rambase(struct bwfm_softc *);
97 97
98int bwfm_proto_bcdc_query_dcmd(struct bwfm_softc *, int, 98int bwfm_proto_bcdc_query_dcmd(struct bwfm_softc *, int,
99 int, char *, size_t *); 99 int, char *, size_t *);
100int bwfm_proto_bcdc_set_dcmd(struct bwfm_softc *, int, 100int bwfm_proto_bcdc_set_dcmd(struct bwfm_softc *, int,
101 int, char *, size_t); 101 int, char *, size_t);
102 102
103int bwfm_fwvar_cmd_get_data(struct bwfm_softc *, int, void *, size_t); 103int bwfm_fwvar_cmd_get_data(struct bwfm_softc *, int, void *, size_t);
104int bwfm_fwvar_cmd_set_data(struct bwfm_softc *, int, void *, size_t); 104int bwfm_fwvar_cmd_set_data(struct bwfm_softc *, int, void *, size_t);
105int bwfm_fwvar_cmd_get_int(struct bwfm_softc *, int, uint32_t *); 105int bwfm_fwvar_cmd_get_int(struct bwfm_softc *, int, uint32_t *);
106int bwfm_fwvar_cmd_set_int(struct bwfm_softc *, int, uint32_t); 106int bwfm_fwvar_cmd_set_int(struct bwfm_softc *, int, uint32_t);
107int bwfm_fwvar_var_get_data(struct bwfm_softc *, const char *, void *, size_t); 107int bwfm_fwvar_var_get_data(struct bwfm_softc *, const char *, void *, size_t);
108int bwfm_fwvar_var_set_data(struct bwfm_softc *, const char *, void *, size_t); 108int bwfm_fwvar_var_set_data(struct bwfm_softc *, const char *, void *, size_t);
109int bwfm_fwvar_var_get_int(struct bwfm_softc *, const char *, uint32_t *); 109int bwfm_fwvar_var_get_int(struct bwfm_softc *, const char *, uint32_t *);
110int bwfm_fwvar_var_set_int(struct bwfm_softc *, const char *, uint32_t); 110int bwfm_fwvar_var_set_int(struct bwfm_softc *, const char *, uint32_t);
111 111
112struct ieee80211_channel *bwfm_bss2chan(struct bwfm_softc *, struct bwfm_bss_info *); 112struct ieee80211_channel *bwfm_bss2chan(struct bwfm_softc *, struct bwfm_bss_info *);
113void bwfm_scan(struct bwfm_softc *); 113void bwfm_scan(struct bwfm_softc *);
114void bwfm_connect(struct bwfm_softc *); 114void bwfm_connect(struct bwfm_softc *);
115void bwfm_get_sta_info(struct bwfm_softc *, struct ifmediareq *); 115void bwfm_get_sta_info(struct bwfm_softc *, struct ifmediareq *);
116 116
117void bwfm_rx(struct bwfm_softc *, struct mbuf *); 117void bwfm_rx(struct bwfm_softc *, struct mbuf *);
118void bwfm_rx_event(struct bwfm_softc *, struct mbuf *); 118void bwfm_rx_event(struct bwfm_softc *, struct mbuf *);
119void bwfm_rx_event_cb(struct bwfm_softc *, struct mbuf *); 119void bwfm_rx_event_cb(struct bwfm_softc *, struct mbuf *);
120void bwfm_scan_node(struct bwfm_softc *, struct bwfm_bss_info *, size_t); 120void bwfm_scan_node(struct bwfm_softc *, struct bwfm_bss_info *, size_t);
121 121
122uint8_t bwfm_2ghz_channels[] = { 122uint8_t bwfm_2ghz_channels[] = {
123 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 123 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
124}; 124};
125uint8_t bwfm_5ghz_channels[] = { 125uint8_t bwfm_5ghz_channels[] = {
126 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64, 100, 104, 108, 112, 126 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64, 100, 104, 108, 112,
127 116, 120, 124, 128, 132, 136, 140, 144, 149, 153, 157, 161, 165, 127 116, 120, 124, 128, 132, 136, 140, 144, 149, 153, 157, 161, 165,
128}; 128};
129 129
130struct bwfm_proto_ops bwfm_proto_bcdc_ops = { 130struct bwfm_proto_ops bwfm_proto_bcdc_ops = {
131 .proto_query_dcmd = bwfm_proto_bcdc_query_dcmd, 131 .proto_query_dcmd = bwfm_proto_bcdc_query_dcmd,
132 .proto_set_dcmd = bwfm_proto_bcdc_set_dcmd, 132 .proto_set_dcmd = bwfm_proto_bcdc_set_dcmd,
133}; 133};
134 134
135void 135void
136bwfm_attach(struct bwfm_softc *sc) 136bwfm_attach(struct bwfm_softc *sc)
137{ 137{
138 struct ieee80211com *ic = &sc->sc_ic; 138 struct ieee80211com *ic = &sc->sc_ic;
139 struct ifnet *ifp = &sc->sc_if; 139 struct ifnet *ifp = &sc->sc_if;
140 struct bwfm_task *t; 140 struct bwfm_task *t;
141 char fw_version[BWFM_DCMD_SMLEN]; 141 char fw_version[BWFM_DCMD_SMLEN];
142 uint32_t bandlist[3]; 142 uint32_t bandlist[3];
143 uint32_t tmp; 143 uint32_t tmp;
144 int i, j, error; 144 int i, j, error;
145 145
146 error = workqueue_create(&sc->sc_taskq, DEVNAME(sc), 146 error = workqueue_create(&sc->sc_taskq, DEVNAME(sc),
147 bwfm_task, sc, PRI_NONE, IPL_NET, 0); 147 bwfm_task, sc, PRI_NONE, IPL_NET, 0);
148 if (error != 0) { 148 if (error != 0) {
149 printf("%s: could not create workqueue\n", DEVNAME(sc)); 149 printf("%s: could not create workqueue\n", DEVNAME(sc));
150 return; 150 return;
151 } 151 }
152 sc->sc_freetask = pcq_create(BWFM_TASK_COUNT, KM_SLEEP); 152 sc->sc_freetask = pcq_create(BWFM_TASK_COUNT, KM_SLEEP);
153 for (i = 0; i < BWFM_TASK_COUNT; i++) { 153 for (i = 0; i < BWFM_TASK_COUNT; i++) {
154 t = &sc->sc_task[i]; 154 t = &sc->sc_task[i];
155 t->t_sc = sc; 155 t->t_sc = sc;
156 pcq_put(sc->sc_freetask, t); 156 pcq_put(sc->sc_freetask, t);
157 } 157 }
158 158
159 /* Stop the device in case it was previously initialized */ 159 /* Stop the device in case it was previously initialized */
160 bwfm_fwvar_cmd_set_int(sc, BWFM_C_DOWN, 1); 160 bwfm_fwvar_cmd_set_int(sc, BWFM_C_DOWN, 1);
161 161
162 if (bwfm_fwvar_cmd_get_int(sc, BWFM_C_GET_VERSION, &tmp)) { 162 if (bwfm_fwvar_cmd_get_int(sc, BWFM_C_GET_VERSION, &tmp)) {
163 printf("%s: could not read io type\n", DEVNAME(sc)); 163 printf("%s: could not read io type\n", DEVNAME(sc));
164 return; 164 return;
165 } else 165 } else
166 sc->sc_io_type = tmp; 166 sc->sc_io_type = tmp;
167 if (bwfm_fwvar_var_get_data(sc, "cur_etheraddr", ic->ic_myaddr, 167 if (bwfm_fwvar_var_get_data(sc, "cur_etheraddr", ic->ic_myaddr,
168 sizeof(ic->ic_myaddr))) { 168 sizeof(ic->ic_myaddr))) {
169 printf("%s: could not read mac address\n", DEVNAME(sc)); 169 printf("%s: could not read mac address\n", DEVNAME(sc));
170 return; 170 return;
171 } 171 }
172 172
173 memset(fw_version, 0, sizeof(fw_version)); 173 memset(fw_version, 0, sizeof(fw_version));
174 if (bwfm_fwvar_var_get_data(sc, "ver", fw_version, sizeof(fw_version)) == 0) 174 if (bwfm_fwvar_var_get_data(sc, "ver", fw_version, sizeof(fw_version)) == 0)
175 printf("%s: %s", DEVNAME(sc), fw_version); 175 printf("%s: %s", DEVNAME(sc), fw_version);
176 printf("%s: address %s\n", DEVNAME(sc), ether_sprintf(ic->ic_myaddr)); 176 printf("%s: address %s\n", DEVNAME(sc), ether_sprintf(ic->ic_myaddr));
177 177
178 ic->ic_ifp = ifp; 178 ic->ic_ifp = ifp;
179 ic->ic_phytype = IEEE80211_T_OFDM; 179 ic->ic_phytype = IEEE80211_T_OFDM;
180 ic->ic_opmode = IEEE80211_M_STA; 180 ic->ic_opmode = IEEE80211_M_STA;
181 ic->ic_state = IEEE80211_S_INIT; 181 ic->ic_state = IEEE80211_S_INIT;
182 182
183 ic->ic_caps = 183 ic->ic_caps =
184 IEEE80211_C_WEP | 184 IEEE80211_C_WEP |
185 IEEE80211_C_TKIP | 185 IEEE80211_C_TKIP |
186 IEEE80211_C_AES | 186 IEEE80211_C_AES |
187 IEEE80211_C_AES_CCM | 187 IEEE80211_C_AES_CCM |
188#if notyet 188#if notyet
189 IEEE80211_C_MONITOR | /* monitor mode supported */ 189 IEEE80211_C_MONITOR | /* monitor mode supported */
190 IEEE80211_C_IBSS | 190 IEEE80211_C_IBSS |
191 IEEE80211_C_TXPMGT | 191 IEEE80211_C_TXPMGT |
192 IEEE80211_C_WME | 192 IEEE80211_C_WME |
193#endif 193#endif
194 IEEE80211_C_SHSLOT | /* short slot time supported */ 194 IEEE80211_C_SHSLOT | /* short slot time supported */
195 IEEE80211_C_SHPREAMBLE | /* short preamble supported */ 195 IEEE80211_C_SHPREAMBLE | /* short preamble supported */
196 IEEE80211_C_WPA | /* 802.11i */ 196 IEEE80211_C_WPA | /* 802.11i */
197 /* IEEE80211_C_WPA_4WAY */0; /* WPA 4-way handshake in hw */ 197 /* IEEE80211_C_WPA_4WAY */0; /* WPA 4-way handshake in hw */
198 198
199 /* IBSS channel undefined for now. */ 199 /* IBSS channel undefined for now. */
200 ic->ic_ibss_chan = &ic->ic_channels[0]; 200 ic->ic_ibss_chan = &ic->ic_channels[0];
201 201
202 if (bwfm_fwvar_cmd_get_data(sc, BWFM_C_GET_BANDLIST, bandlist, 202 if (bwfm_fwvar_cmd_get_data(sc, BWFM_C_GET_BANDLIST, bandlist,
203 sizeof(bandlist))) { 203 sizeof(bandlist))) {
204 printf("%s: couldn't get supported band list\n", DEVNAME(sc)); 204 printf("%s: couldn't get supported band list\n", DEVNAME(sc));
205 return; 205 return;
206 }  206 }
207 const u_int nbands = le32toh(bandlist[0]); 207 const u_int nbands = le32toh(bandlist[0]);
208 for (i = 1; i <= MIN(nbands, __arraycount(bandlist) - 1); i++) { 208 for (i = 1; i <= MIN(nbands, __arraycount(bandlist) - 1); i++) {
209 switch (le32toh(bandlist[i])) { 209 switch (le32toh(bandlist[i])) {
210 case BWFM_BAND_2G: 210 case BWFM_BAND_2G:
211 ic->ic_sup_rates[IEEE80211_MODE_11B] = ieee80211_std_rateset_11b; 211 ic->ic_sup_rates[IEEE80211_MODE_11B] = ieee80211_std_rateset_11b;
212 ic->ic_sup_rates[IEEE80211_MODE_11G] = ieee80211_std_rateset_11g; 212 ic->ic_sup_rates[IEEE80211_MODE_11G] = ieee80211_std_rateset_11g;
213 213
214 for (j = 0; j < __arraycount(bwfm_2ghz_channels); j++) { 214 for (j = 0; j < __arraycount(bwfm_2ghz_channels); j++) {
215 uint8_t chan = bwfm_2ghz_channels[j]; 215 uint8_t chan = bwfm_2ghz_channels[j];
216 ic->ic_channels[chan].ic_freq = 216 ic->ic_channels[chan].ic_freq =
217 ieee80211_ieee2mhz(chan, IEEE80211_CHAN_2GHZ); 217 ieee80211_ieee2mhz(chan, IEEE80211_CHAN_2GHZ);
218 ic->ic_channels[chan].ic_flags = 218 ic->ic_channels[chan].ic_flags =
219 IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM | 219 IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM |
220 IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ; 220 IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ;
221 } 221 }
222 break; 222 break;
223 case BWFM_BAND_5G: 223 case BWFM_BAND_5G:
224 ic->ic_sup_rates[IEEE80211_MODE_11A] = ieee80211_std_rateset_11a; 224 ic->ic_sup_rates[IEEE80211_MODE_11A] = ieee80211_std_rateset_11a;
225 225
226 for (j = 0; j < __arraycount(bwfm_5ghz_channels); j++) { 226 for (j = 0; j < __arraycount(bwfm_5ghz_channels); j++) {
227 uint8_t chan = bwfm_5ghz_channels[j]; 227 uint8_t chan = bwfm_5ghz_channels[j];
228 ic->ic_channels[chan].ic_freq = 228 ic->ic_channels[chan].ic_freq =
229 ieee80211_ieee2mhz(chan, IEEE80211_CHAN_5GHZ); 229 ieee80211_ieee2mhz(chan, IEEE80211_CHAN_5GHZ);
230 ic->ic_channels[chan].ic_flags = 230 ic->ic_channels[chan].ic_flags =
231 IEEE80211_CHAN_A; 231 IEEE80211_CHAN_A;
232 } 232 }
233 break; 233 break;
234 } 234 }
235 } 235 }
236 236
237 ifp->if_softc = sc; 237 ifp->if_softc = sc;
238 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 238 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
239 ifp->if_init = bwfm_init; 239 ifp->if_init = bwfm_init;
240 ifp->if_ioctl = bwfm_ioctl; 240 ifp->if_ioctl = bwfm_ioctl;
241 ifp->if_start = bwfm_start; 241 ifp->if_start = bwfm_start;
242 ifp->if_stop = bwfm_stop; 242 ifp->if_stop = bwfm_stop;
243 ifp->if_watchdog = bwfm_watchdog; 243 ifp->if_watchdog = bwfm_watchdog;
244 IFQ_SET_READY(&ifp->if_snd); 244 IFQ_SET_READY(&ifp->if_snd);
245 memcpy(ifp->if_xname, DEVNAME(sc), IFNAMSIZ); 245 memcpy(ifp->if_xname, DEVNAME(sc), IFNAMSIZ);
246 246
247 error = if_initialize(ifp); 247 error = if_initialize(ifp);
248 if (error != 0) { 248 if (error != 0) {
249 printf("%s: if_initialize failed(%d)\n", DEVNAME(sc), error); 249 printf("%s: if_initialize failed(%d)\n", DEVNAME(sc), error);
250 pcq_destroy(sc->sc_freetask); 250 pcq_destroy(sc->sc_freetask);
251 workqueue_destroy(sc->sc_taskq); 251 workqueue_destroy(sc->sc_taskq);
252 252
253 return; /* Error */ 253 return; /* Error */
254 } 254 }
255  255
256 ieee80211_ifattach(ic); 256 ieee80211_ifattach(ic);
257 ifp->if_percpuq = if_percpuq_create(ifp); 257 ifp->if_percpuq = if_percpuq_create(ifp);
258 if_deferred_start_init(ifp, NULL); 258 if_deferred_start_init(ifp, NULL);
259 if_register(ifp); 259 if_register(ifp);
260 260
261 sc->sc_newstate = ic->ic_newstate; 261 sc->sc_newstate = ic->ic_newstate;
262 ic->ic_newstate = bwfm_newstate; 262 ic->ic_newstate = bwfm_newstate;
263 ic->ic_newassoc = bwfm_newassoc; 263 ic->ic_newassoc = bwfm_newassoc;
264 ic->ic_send_mgmt = bwfm_send_mgmt; 264 ic->ic_send_mgmt = bwfm_send_mgmt;
265 ic->ic_recv_mgmt = bwfm_recv_mgmt; 265 ic->ic_recv_mgmt = bwfm_recv_mgmt;
266 ic->ic_crypto.cs_key_set = bwfm_key_set; 266 ic->ic_crypto.cs_key_set = bwfm_key_set;
267 ic->ic_crypto.cs_key_delete = bwfm_key_delete; 267 ic->ic_crypto.cs_key_delete = bwfm_key_delete;
268 ieee80211_media_init(ic, bwfm_media_change, ieee80211_media_status); 268 ieee80211_media_init(ic, bwfm_media_change, ieee80211_media_status);
269 269
270 ieee80211_announce(ic); 270 ieee80211_announce(ic);
271 271
272 sc->sc_if_attached = true; 272 sc->sc_if_attached = true;
273} 273}
274 274
275int 275int
276bwfm_detach(struct bwfm_softc *sc, int flags) 276bwfm_detach(struct bwfm_softc *sc, int flags)
277{ 277{
278 struct ieee80211com *ic = &sc->sc_ic; 278 struct ieee80211com *ic = &sc->sc_ic;
279 struct ifnet *ifp = ic->ic_ifp; 279 struct ifnet *ifp = ic->ic_ifp;
280 280
281 if (sc->sc_if_attached) { 281 if (sc->sc_if_attached) {
282 bpf_detach(ifp); 282 bpf_detach(ifp);
283 ieee80211_ifdetach(ic); 283 ieee80211_ifdetach(ic);
284 if_detach(ifp); 284 if_detach(ifp);
285 } 285 }
286 286
287 if (sc->sc_taskq) 287 if (sc->sc_taskq)
288 workqueue_destroy(sc->sc_taskq); 288 workqueue_destroy(sc->sc_taskq);
289 if (sc->sc_freetask) 289 if (sc->sc_freetask)
290 pcq_destroy(sc->sc_freetask); 290 pcq_destroy(sc->sc_freetask);
291 291
292 return 0; 292 return 0;
293} 293}
294 294
295void 295void
296bwfm_start(struct ifnet *ifp) 296bwfm_start(struct ifnet *ifp)
297{ 297{
298 struct bwfm_softc *sc = ifp->if_softc; 298 struct bwfm_softc *sc = ifp->if_softc;
299 struct ieee80211com *ic = &sc->sc_ic; 299 struct ieee80211com *ic = &sc->sc_ic;
300 struct mbuf *m; 300 struct mbuf *m;
301 int error; 301 int error;
302 302
303 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING) 303 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
304 return; 304 return;
305 305
306 /* TODO: return if no link? */ 306 /* TODO: return if no link? */
307 307
308 for (;;) { 308 for (;;) {
309 /* Discard management packets (fw handles this for us) */ 309 /* Discard management packets (fw handles this for us) */
310 IF_DEQUEUE(&ic->ic_mgtq, m); 310 IF_DEQUEUE(&ic->ic_mgtq, m);
311 if (m != NULL) { 311 if (m != NULL) {
312 m_freem(m); 312 m_freem(m);
313 continue; 313 continue;
314 } 314 }
315 315
316 if (sc->sc_bus_ops->bs_txcheck(sc)) { 316 if (sc->sc_bus_ops->bs_txcheck(sc)) {
317 ifp->if_flags |= IFF_OACTIVE; 317 ifp->if_flags |= IFF_OACTIVE;
318 break; 318 break;
319 } 319 }
320 320
321 IFQ_DEQUEUE(&ifp->if_snd, m); 321 IFQ_DEQUEUE(&ifp->if_snd, m);
322 if (m == NULL) 322 if (m == NULL)
323 break; 323 break;
324 324
325 error = sc->sc_bus_ops->bs_txdata(sc, &m); 325 error = sc->sc_bus_ops->bs_txdata(sc, &m);
326 if (error == ENOBUFS) { 326 if (error == ENOBUFS) {
327 IF_PREPEND(&ifp->if_snd, m); 327 IF_PREPEND(&ifp->if_snd, m);
328 ifp->if_flags |= IFF_OACTIVE; 328 ifp->if_flags |= IFF_OACTIVE;
329 break; 329 break;
330 } 330 }
331 if (error != 0) { 331 if (error != 0) {
332 ifp->if_oerrors++; 332 if_statinc(ifp, if_oerrors);
333 m_freem(m); 333 m_freem(m);
334 continue; 334 continue;
335 } 335 }
336 336
337 bpf_mtap(ifp, m, BPF_D_OUT); 337 bpf_mtap(ifp, m, BPF_D_OUT);
338 } 338 }
339} 339}
340 340
341int 341int
342bwfm_init(struct ifnet *ifp) 342bwfm_init(struct ifnet *ifp)
343{ 343{
344 struct bwfm_softc *sc = ifp->if_softc; 344 struct bwfm_softc *sc = ifp->if_softc;
345 struct ieee80211com *ic = &sc->sc_ic; 345 struct ieee80211com *ic = &sc->sc_ic;
346 uint8_t evmask[BWFM_EVENT_MASK_LEN]; 346 uint8_t evmask[BWFM_EVENT_MASK_LEN];
347 struct bwfm_join_pref_params join_pref[2]; 347 struct bwfm_join_pref_params join_pref[2];
348 int pm; 348 int pm;
349 349
350 if (bwfm_fwvar_var_set_int(sc, "mpc", 1)) { 350 if (bwfm_fwvar_var_set_int(sc, "mpc", 1)) {
351 printf("%s: could not set mpc\n", DEVNAME(sc)); 351 printf("%s: could not set mpc\n", DEVNAME(sc));
352 return EIO; 352 return EIO;
353 } 353 }
354 354
355 /* Select target by RSSI (boost on 5GHz) */ 355 /* Select target by RSSI (boost on 5GHz) */
356 join_pref[0].type = BWFM_JOIN_PREF_RSSI_DELTA; 356 join_pref[0].type = BWFM_JOIN_PREF_RSSI_DELTA;
357 join_pref[0].len = 2; 357 join_pref[0].len = 2;
358 join_pref[0].rssi_gain = BWFM_JOIN_PREF_RSSI_BOOST; 358 join_pref[0].rssi_gain = BWFM_JOIN_PREF_RSSI_BOOST;
359 join_pref[0].band = BWFM_JOIN_PREF_BAND_5G; 359 join_pref[0].band = BWFM_JOIN_PREF_BAND_5G;
360 join_pref[1].type = BWFM_JOIN_PREF_RSSI; 360 join_pref[1].type = BWFM_JOIN_PREF_RSSI;
361 join_pref[1].len = 2; 361 join_pref[1].len = 2;
362 join_pref[1].rssi_gain = 0; 362 join_pref[1].rssi_gain = 0;
363 join_pref[1].band = 0; 363 join_pref[1].band = 0;
364 if (bwfm_fwvar_var_set_data(sc, "join_pref", join_pref, 364 if (bwfm_fwvar_var_set_data(sc, "join_pref", join_pref,
365 sizeof(join_pref))) { 365 sizeof(join_pref))) {
366 printf("%s: could not set join pref\n", DEVNAME(sc)); 366 printf("%s: could not set join pref\n", DEVNAME(sc));
367 return EIO; 367 return EIO;
368 } 368 }
369 369
370 memset(evmask, 0, sizeof(evmask)); 370 memset(evmask, 0, sizeof(evmask));
371 371
372#define ENABLE_EVENT(e) evmask[(e) / 8] |= 1 << ((e) % 8) 372#define ENABLE_EVENT(e) evmask[(e) / 8] |= 1 << ((e) % 8)
373 /* Events used to drive the state machine */ 373 /* Events used to drive the state machine */
374 switch (ic->ic_opmode) { 374 switch (ic->ic_opmode) {
375 case IEEE80211_M_STA: 375 case IEEE80211_M_STA:
376 ENABLE_EVENT(BWFM_E_IF); 376 ENABLE_EVENT(BWFM_E_IF);
377 ENABLE_EVENT(BWFM_E_LINK); 377 ENABLE_EVENT(BWFM_E_LINK);
378 ENABLE_EVENT(BWFM_E_AUTH); 378 ENABLE_EVENT(BWFM_E_AUTH);
379 ENABLE_EVENT(BWFM_E_ASSOC); 379 ENABLE_EVENT(BWFM_E_ASSOC);
380 ENABLE_EVENT(BWFM_E_DEAUTH); 380 ENABLE_EVENT(BWFM_E_DEAUTH);
381 ENABLE_EVENT(BWFM_E_DISASSOC); 381 ENABLE_EVENT(BWFM_E_DISASSOC);
382 ENABLE_EVENT(BWFM_E_SET_SSID); 382 ENABLE_EVENT(BWFM_E_SET_SSID);
383 ENABLE_EVENT(BWFM_E_ESCAN_RESULT); 383 ENABLE_EVENT(BWFM_E_ESCAN_RESULT);
384 break; 384 break;
385#ifndef IEEE80211_STA_ONLY 385#ifndef IEEE80211_STA_ONLY
386 case IEEE80211_M_HOSTAP: 386 case IEEE80211_M_HOSTAP:
387 ENABLE_EVENT(BWFM_E_AUTH_IND); 387 ENABLE_EVENT(BWFM_E_AUTH_IND);
388 ENABLE_EVENT(BWFM_E_ASSOC_IND); 388 ENABLE_EVENT(BWFM_E_ASSOC_IND);
389 ENABLE_EVENT(BWFM_E_REASSOC_IND); 389 ENABLE_EVENT(BWFM_E_REASSOC_IND);
390 ENABLE_EVENT(BWFM_E_DEAUTH_IND); 390 ENABLE_EVENT(BWFM_E_DEAUTH_IND);
391 ENABLE_EVENT(BWFM_E_DISASSOC_IND); 391 ENABLE_EVENT(BWFM_E_DISASSOC_IND);
392 ENABLE_EVENT(BWFM_E_ESCAN_RESULT); 392 ENABLE_EVENT(BWFM_E_ESCAN_RESULT);
393 ENABLE_EVENT(BWFM_E_ESCAN_RESULT); 393 ENABLE_EVENT(BWFM_E_ESCAN_RESULT);
394 break; 394 break;
395#endif 395#endif
396 default: 396 default:
397 break; 397 break;
398 } 398 }
399#undef ENABLE_EVENT 399#undef ENABLE_EVENT
400 400
401#ifdef BWFM_DEBUG 401#ifdef BWFM_DEBUG
402 memset(evmask, 0xff, sizeof(evmask)); 402 memset(evmask, 0xff, sizeof(evmask));
403#endif 403#endif
404  404
405 if (bwfm_fwvar_var_set_data(sc, "event_msgs", evmask, sizeof(evmask))) { 405 if (bwfm_fwvar_var_set_data(sc, "event_msgs", evmask, sizeof(evmask))) {
406 printf("%s: could not set event mask\n", DEVNAME(sc)); 406 printf("%s: could not set event mask\n", DEVNAME(sc));
407 return EIO; 407 return EIO;
408 } 408 }
409 409
410 if (bwfm_fwvar_cmd_set_int(sc, BWFM_C_SET_SCAN_CHANNEL_TIME, 410 if (bwfm_fwvar_cmd_set_int(sc, BWFM_C_SET_SCAN_CHANNEL_TIME,
411 BWFM_DEFAULT_SCAN_CHANNEL_TIME)) { 411 BWFM_DEFAULT_SCAN_CHANNEL_TIME)) {
412 printf("%s: could not set scan channel time\n", DEVNAME(sc)); 412 printf("%s: could not set scan channel time\n", DEVNAME(sc));
413 return EIO; 413 return EIO;
414 } 414 }
415 if (bwfm_fwvar_cmd_set_int(sc, BWFM_C_SET_SCAN_UNASSOC_TIME, 415 if (bwfm_fwvar_cmd_set_int(sc, BWFM_C_SET_SCAN_UNASSOC_TIME,
416 BWFM_DEFAULT_SCAN_UNASSOC_TIME)) { 416 BWFM_DEFAULT_SCAN_UNASSOC_TIME)) {
417 printf("%s: could not set scan unassoc time\n", DEVNAME(sc)); 417 printf("%s: could not set scan unassoc time\n", DEVNAME(sc));
418 return EIO; 418 return EIO;
419 } 419 }
420 if (bwfm_fwvar_cmd_set_int(sc, BWFM_C_SET_SCAN_PASSIVE_TIME, 420 if (bwfm_fwvar_cmd_set_int(sc, BWFM_C_SET_SCAN_PASSIVE_TIME,
421 BWFM_DEFAULT_SCAN_PASSIVE_TIME)) { 421 BWFM_DEFAULT_SCAN_PASSIVE_TIME)) {
422 printf("%s: could not set scan passive time\n", DEVNAME(sc)); 422 printf("%s: could not set scan passive time\n", DEVNAME(sc));
423 return EIO; 423 return EIO;
424 } 424 }
425 425
426 /* 426 /*
427 * Use CAM (constantly awake) when we are running as AP 427 * Use CAM (constantly awake) when we are running as AP
428 * otherwise use fast power saving. 428 * otherwise use fast power saving.
429 */ 429 */
430 pm = BWFM_PM_FAST_PS; 430 pm = BWFM_PM_FAST_PS;
431#ifndef IEEE80211_STA_ONLY 431#ifndef IEEE80211_STA_ONLY
432 if (ic->ic_opmode == IEEE80211_M_HOSTAP) 432 if (ic->ic_opmode == IEEE80211_M_HOSTAP)
433 pm = BWFM_PM_CAM; 433 pm = BWFM_PM_CAM;
434#endif 434#endif
435 if (bwfm_fwvar_cmd_set_int(sc, BWFM_C_SET_PM, pm)) { 435 if (bwfm_fwvar_cmd_set_int(sc, BWFM_C_SET_PM, pm)) {
436 printf("%s: could not set power\n", DEVNAME(sc)); 436 printf("%s: could not set power\n", DEVNAME(sc));
437 return EIO; 437 return EIO;
438 } 438 }
439 439
440 bwfm_fwvar_var_set_int(sc, "txbf", 1); 440 bwfm_fwvar_var_set_int(sc, "txbf", 1);
441 bwfm_fwvar_cmd_set_int(sc, BWFM_C_UP, 0); 441 bwfm_fwvar_cmd_set_int(sc, BWFM_C_UP, 0);
442 bwfm_fwvar_cmd_set_int(sc, BWFM_C_SET_INFRA, 1); 442 bwfm_fwvar_cmd_set_int(sc, BWFM_C_SET_INFRA, 1);
443 bwfm_fwvar_cmd_set_int(sc, BWFM_C_SET_AP, 0); 443 bwfm_fwvar_cmd_set_int(sc, BWFM_C_SET_AP, 0);
444 444
445 /* Disable all offloading (ARP, NDP, TCP/UDP cksum). */ 445 /* Disable all offloading (ARP, NDP, TCP/UDP cksum). */
446 bwfm_fwvar_var_set_int(sc, "arp_ol", 0); 446 bwfm_fwvar_var_set_int(sc, "arp_ol", 0);
447 bwfm_fwvar_var_set_int(sc, "arpoe", 0); 447 bwfm_fwvar_var_set_int(sc, "arpoe", 0);
448 bwfm_fwvar_var_set_int(sc, "ndoe", 0); 448 bwfm_fwvar_var_set_int(sc, "ndoe", 0);
449 bwfm_fwvar_var_set_int(sc, "toe", 0); 449 bwfm_fwvar_var_set_int(sc, "toe", 0);
450 450
451 /* Accept all multicast frames. */ 451 /* Accept all multicast frames. */
452 bwfm_fwvar_var_set_int(sc, "allmulti", 1); 452 bwfm_fwvar_var_set_int(sc, "allmulti", 1);
453 453
454 /* Setup promiscuous mode */ 454 /* Setup promiscuous mode */
455 bwfm_fwvar_cmd_set_int(sc, BWFM_C_SET_PROMISC, 455 bwfm_fwvar_cmd_set_int(sc, BWFM_C_SET_PROMISC,
456 (ifp->if_flags & IFF_PROMISC) ? 1 : 0); 456 (ifp->if_flags & IFF_PROMISC) ? 1 : 0);
457 457
458 /* 458 /*
459 * Tell the firmware supplicant that we are going to handle the 459 * Tell the firmware supplicant that we are going to handle the
460 * WPA handshake ourselves. 460 * WPA handshake ourselves.
461 */ 461 */
462 bwfm_fwvar_var_set_int(sc, "sup_wpa", 0); 462 bwfm_fwvar_var_set_int(sc, "sup_wpa", 0);
463 463
464 ifp->if_flags |= IFF_RUNNING; 464 ifp->if_flags |= IFF_RUNNING;
465 ifp->if_flags &= ~IFF_OACTIVE; 465 ifp->if_flags &= ~IFF_OACTIVE;
466 466
467 if (ic->ic_opmode != IEEE80211_M_MONITOR) { 467 if (ic->ic_opmode != IEEE80211_M_MONITOR) {
468 if (ic->ic_roaming != IEEE80211_ROAMING_MANUAL) 468 if (ic->ic_roaming != IEEE80211_ROAMING_MANUAL)
469 ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); 469 ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
470 } else { 470 } else {
471 ieee80211_new_state(ic, IEEE80211_S_RUN, -1); 471 ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
472 } 472 }
473 473
474 return 0; 474 return 0;
475} 475}
476 476
477void 477void
478bwfm_stop(struct ifnet *ifp, int disable) 478bwfm_stop(struct ifnet *ifp, int disable)
479{ 479{
480 struct bwfm_softc *sc = ifp->if_softc; 480 struct bwfm_softc *sc = ifp->if_softc;
481 struct ieee80211com *ic = &sc->sc_ic; 481 struct ieee80211com *ic = &sc->sc_ic;
482 struct bwfm_join_params join; 482 struct bwfm_join_params join;
483 483
484 sc->sc_tx_timer = 0; 484 sc->sc_tx_timer = 0;
485 ifp->if_timer = 0; 485 ifp->if_timer = 0;
486 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 486 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
487 487
488 memset(&join, 0, sizeof(join)); 488 memset(&join, 0, sizeof(join));
489 bwfm_fwvar_cmd_set_data(sc, BWFM_C_SET_SSID, &join, sizeof(join)); 489 bwfm_fwvar_cmd_set_data(sc, BWFM_C_SET_SSID, &join, sizeof(join));
490 bwfm_fwvar_cmd_set_int(sc, BWFM_C_DOWN, 1); 490 bwfm_fwvar_cmd_set_int(sc, BWFM_C_DOWN, 1);
491 bwfm_fwvar_cmd_set_int(sc, BWFM_C_SET_PM, 0); 491 bwfm_fwvar_cmd_set_int(sc, BWFM_C_SET_PM, 0);
492 bwfm_fwvar_cmd_set_int(sc, BWFM_C_SET_AP, 0); 492 bwfm_fwvar_cmd_set_int(sc, BWFM_C_SET_AP, 0);
493 bwfm_fwvar_cmd_set_int(sc, BWFM_C_SET_INFRA, 0); 493 bwfm_fwvar_cmd_set_int(sc, BWFM_C_SET_INFRA, 0);
494 bwfm_fwvar_cmd_set_int(sc, BWFM_C_UP, 1); 494 bwfm_fwvar_cmd_set_int(sc, BWFM_C_UP, 1);
495 bwfm_fwvar_cmd_set_int(sc, BWFM_C_SET_PM, BWFM_PM_FAST_PS); 495 bwfm_fwvar_cmd_set_int(sc, BWFM_C_SET_PM, BWFM_PM_FAST_PS);
496 496
497 ieee80211_new_state(ic, IEEE80211_S_INIT, -1); 497 ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
498 498
499 if (sc->sc_bus_ops->bs_stop) 499 if (sc->sc_bus_ops->bs_stop)
500 sc->sc_bus_ops->bs_stop(sc); 500 sc->sc_bus_ops->bs_stop(sc);
501} 501}
502 502
503void 503void
504bwfm_watchdog(struct ifnet *ifp) 504bwfm_watchdog(struct ifnet *ifp)
505{ 505{
506 struct bwfm_softc *sc = ifp->if_softc; 506 struct bwfm_softc *sc = ifp->if_softc;
507 struct ieee80211com *ic = &sc->sc_ic; 507 struct ieee80211com *ic = &sc->sc_ic;
508 508
509 ifp->if_timer = 0; 509 ifp->if_timer = 0;
510 510
511 if (sc->sc_tx_timer > 0) { 511 if (sc->sc_tx_timer > 0) {
512 if (--sc->sc_tx_timer == 0) { 512 if (--sc->sc_tx_timer == 0) {
513 printf("%s: device timeout\n", DEVNAME(sc)); 513 printf("%s: device timeout\n", DEVNAME(sc));
514 ifp->if_oerrors++; 514 if_statinc(ifp, if_oerrors);
515 return; 515 return;
516 } 516 }
517 ifp->if_timer = 1; 517 ifp->if_timer = 1;
518 } 518 }
519 ieee80211_watchdog(ic); 519 ieee80211_watchdog(ic);
520} 520}
521 521
522int 522int
523bwfm_ioctl(struct ifnet *ifp, u_long cmd, void *data) 523bwfm_ioctl(struct ifnet *ifp, u_long cmd, void *data)
524{ 524{
525 struct bwfm_softc *sc = ifp->if_softc; 525 struct bwfm_softc *sc = ifp->if_softc;
526 struct ieee80211com *ic = &sc->sc_ic; 526 struct ieee80211com *ic = &sc->sc_ic;
527 int s, error = 0; 527 int s, error = 0;
528 528
529 s = splnet(); 529 s = splnet();
530 530
531 switch (cmd) { 531 switch (cmd) {
532 case SIOCSIFFLAGS: 532 case SIOCSIFFLAGS:
533 if ((error = ifioctl_common(ifp, cmd, data)) != 0) 533 if ((error = ifioctl_common(ifp, cmd, data)) != 0)
534 break; 534 break;
535 switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) { 535 switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) {
536 case IFF_UP | IFF_RUNNING: 536 case IFF_UP | IFF_RUNNING:
537 break; 537 break;
538 case IFF_UP: 538 case IFF_UP:
539 bwfm_init(ifp); 539 bwfm_init(ifp);
540 break; 540 break;
541 case IFF_RUNNING: 541 case IFF_RUNNING:
542 bwfm_stop(ifp, 1); 542 bwfm_stop(ifp, 1);
543 break; 543 break;
544 case 0: 544 case 0:
545 break; 545 break;
546 } 546 }
547 break; 547 break;
548 548
549 case SIOCADDMULTI: 549 case SIOCADDMULTI:
550 case SIOCDELMULTI: 550 case SIOCDELMULTI:
551 if ((error = ether_ioctl(ifp, cmd, data)) == ENETRESET) { 551 if ((error = ether_ioctl(ifp, cmd, data)) == ENETRESET) {
552 /* setup multicast filter, etc */ 552 /* setup multicast filter, etc */
553 error = 0; 553 error = 0;
554 } 554 }
555 break; 555 break;
556 556
557 case SIOCGIFMEDIA: 557 case SIOCGIFMEDIA:
558 error = ieee80211_ioctl(ic, cmd, data); 558 error = ieee80211_ioctl(ic, cmd, data);
559 if (error == 0 && ic->ic_state == IEEE80211_S_RUN) 559 if (error == 0 && ic->ic_state == IEEE80211_S_RUN)
560 bwfm_get_sta_info(sc, (struct ifmediareq *)data); 560 bwfm_get_sta_info(sc, (struct ifmediareq *)data);
561 break; 561 break;
562 562
563 default: 563 default:
564 error = ieee80211_ioctl(ic, cmd, data); 564 error = ieee80211_ioctl(ic, cmd, data);
565 } 565 }
566 566
567 if (error == ENETRESET) { 567 if (error == ENETRESET) {
568 if ((ifp->if_flags & IFF_UP) != 0 && 568 if ((ifp->if_flags & IFF_UP) != 0 &&
569 (ifp->if_flags & IFF_RUNNING) != 0 && 569 (ifp->if_flags & IFF_RUNNING) != 0 &&
570 ic->ic_roaming != IEEE80211_ROAMING_MANUAL) { 570 ic->ic_roaming != IEEE80211_ROAMING_MANUAL) {
571 bwfm_init(ifp); 571 bwfm_init(ifp);
572 } 572 }
573 error = 0; 573 error = 0;
574 } 574 }
575 575
576 splx(s); 576 splx(s);
577 577
578 return error; 578 return error;
579} 579}
580 580
581int 581int
582bwfm_send_mgmt(struct ieee80211com *ic, struct ieee80211_node *ni, 582bwfm_send_mgmt(struct ieee80211com *ic, struct ieee80211_node *ni,
583 int type, int arg) 583 int type, int arg)
584{ 584{
585 return 0; 585 return 0;
586} 586}
587 587
588void 588void
589bwfm_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0, 589bwfm_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
590 struct ieee80211_node *ni, int subtype, int rssi, uint32_t rstamp) 590 struct ieee80211_node *ni, int subtype, int rssi, uint32_t rstamp)
591{ 591{
592} 592}
593 593
594int 594int
595bwfm_key_set(struct ieee80211com *ic, const struct ieee80211_key *wk, 595bwfm_key_set(struct ieee80211com *ic, const struct ieee80211_key *wk,
596 const uint8_t mac[IEEE80211_ADDR_LEN]) 596 const uint8_t mac[IEEE80211_ADDR_LEN])
597{ 597{
598 struct bwfm_softc *sc = ic->ic_ifp->if_softc; 598 struct bwfm_softc *sc = ic->ic_ifp->if_softc;
599 struct bwfm_task *t; 599 struct bwfm_task *t;
600 600
601 t = pcq_get(sc->sc_freetask); 601 t = pcq_get(sc->sc_freetask);
602 if (t == NULL) { 602 if (t == NULL) {
603 printf("%s: no free tasks\n", DEVNAME(sc)); 603 printf("%s: no free tasks\n", DEVNAME(sc));
604 return 0; 604 return 0;
605 } 605 }
606 606
607 t->t_cmd = BWFM_TASK_KEY_SET; 607 t->t_cmd = BWFM_TASK_KEY_SET;
608 t->t_key.key = wk; 608 t->t_key.key = wk;
609 memcpy(t->t_key.mac, mac, sizeof(t->t_key.mac)); 609 memcpy(t->t_key.mac, mac, sizeof(t->t_key.mac));
610 workqueue_enqueue(sc->sc_taskq, (struct work *)t, NULL); 610 workqueue_enqueue(sc->sc_taskq, (struct work *)t, NULL);
611 return 1; 611 return 1;
612} 612}
613 613
614static void 614static void
615bwfm_key_set_cb(struct bwfm_softc *sc, struct bwfm_cmd_key *ck) 615bwfm_key_set_cb(struct bwfm_softc *sc, struct bwfm_cmd_key *ck)
616{ 616{
617 const struct ieee80211_key *wk = ck->key; 617 const struct ieee80211_key *wk = ck->key;
618 const uint8_t *mac = ck->mac; 618 const uint8_t *mac = ck->mac;
619 struct bwfm_wsec_key wsec_key; 619 struct bwfm_wsec_key wsec_key;
620 uint32_t wsec_enable, wsec; 620 uint32_t wsec_enable, wsec;
621 bool ext_key; 621 bool ext_key;
622 622
623#ifdef BWFM_DEBUG 623#ifdef BWFM_DEBUG
624 printf("key_set: key cipher %s len %d: ", wk->wk_cipher->ic_name, wk->wk_keylen); 624 printf("key_set: key cipher %s len %d: ", wk->wk_cipher->ic_name, wk->wk_keylen);
625 for (int j = 0; j < sizeof(wk->wk_key); j++) 625 for (int j = 0; j < sizeof(wk->wk_key); j++)
626 printf("%02x", wk->wk_key[j]); 626 printf("%02x", wk->wk_key[j]);
627#endif 627#endif
628 628
629 if ((wk->wk_flags & IEEE80211_KEY_GROUP) == 0 && 629 if ((wk->wk_flags & IEEE80211_KEY_GROUP) == 0 &&
630 wk->wk_cipher->ic_cipher != IEEE80211_CIPHER_WEP) { 630 wk->wk_cipher->ic_cipher != IEEE80211_CIPHER_WEP) {
631 ext_key = true; 631 ext_key = true;
632 } else { 632 } else {
633 ext_key = false; 633 ext_key = false;
634 } 634 }
635 635
636#ifdef BWFM_DEBUG 636#ifdef BWFM_DEBUG
637 printf(", ext_key = %d", ext_key); 637 printf(", ext_key = %d", ext_key);
638 printf(", mac = %02x:%02x:%02x:%02x:%02x:%02x", 638 printf(", mac = %02x:%02x:%02x:%02x:%02x:%02x",
639 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); 639 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
640 printf("\n"); 640 printf("\n");
641#endif 641#endif
642 642
643 memset(&wsec_key, 0, sizeof(wsec_key)); 643 memset(&wsec_key, 0, sizeof(wsec_key));
644 if (ext_key && !IEEE80211_IS_MULTICAST(mac)) 644 if (ext_key && !IEEE80211_IS_MULTICAST(mac))
645 memcpy(wsec_key.ea, mac, sizeof(wsec_key.ea)); 645 memcpy(wsec_key.ea, mac, sizeof(wsec_key.ea));
646 wsec_key.index = htole32(wk->wk_keyix); 646 wsec_key.index = htole32(wk->wk_keyix);
647 wsec_key.len = htole32(wk->wk_keylen); 647 wsec_key.len = htole32(wk->wk_keylen);
648 memcpy(wsec_key.data, wk->wk_key, sizeof(wsec_key.data)); 648 memcpy(wsec_key.data, wk->wk_key, sizeof(wsec_key.data));
649 if (!ext_key) 649 if (!ext_key)
650 wsec_key.flags = htole32(BWFM_WSEC_PRIMARY_KEY); 650 wsec_key.flags = htole32(BWFM_WSEC_PRIMARY_KEY);
651 651
652 switch (wk->wk_cipher->ic_cipher) { 652 switch (wk->wk_cipher->ic_cipher) {
653 case IEEE80211_CIPHER_WEP: 653 case IEEE80211_CIPHER_WEP:
654 if (wk->wk_keylen == 5) 654 if (wk->wk_keylen == 5)
655 wsec_key.algo = htole32(BWFM_CRYPTO_ALGO_WEP1); 655 wsec_key.algo = htole32(BWFM_CRYPTO_ALGO_WEP1);
656 else if (wk->wk_keylen == 13) 656 else if (wk->wk_keylen == 13)
657 wsec_key.algo = htole32(BWFM_CRYPTO_ALGO_WEP128); 657 wsec_key.algo = htole32(BWFM_CRYPTO_ALGO_WEP128);
658 else 658 else
659 return; 659 return;
660 wsec_enable = BWFM_WSEC_WEP; 660 wsec_enable = BWFM_WSEC_WEP;
661 break; 661 break;
662 case IEEE80211_CIPHER_TKIP: 662 case IEEE80211_CIPHER_TKIP:
663 wsec_key.algo = htole32(BWFM_CRYPTO_ALGO_TKIP); 663 wsec_key.algo = htole32(BWFM_CRYPTO_ALGO_TKIP);
664 wsec_enable = BWFM_WSEC_TKIP; 664 wsec_enable = BWFM_WSEC_TKIP;
665 break; 665 break;
666 case IEEE80211_CIPHER_AES_CCM: 666 case IEEE80211_CIPHER_AES_CCM:
667 wsec_key.algo = htole32(BWFM_CRYPTO_ALGO_AES_CCM); 667 wsec_key.algo = htole32(BWFM_CRYPTO_ALGO_AES_CCM);
668 wsec_enable = BWFM_WSEC_AES; 668 wsec_enable = BWFM_WSEC_AES;
669 break; 669 break;
670 default: 670 default:
671 printf("%s: %s: cipher %s not supported\n", DEVNAME(sc), 671 printf("%s: %s: cipher %s not supported\n", DEVNAME(sc),
672 __func__, wk->wk_cipher->ic_name); 672 __func__, wk->wk_cipher->ic_name);
673 return; 673 return;
674 } 674 }
675 675
676 if (bwfm_fwvar_var_set_data(sc, "wsec_key", &wsec_key, sizeof(wsec_key))) 676 if (bwfm_fwvar_var_set_data(sc, "wsec_key", &wsec_key, sizeof(wsec_key)))
677 return; 677 return;
678 678
679 bwfm_fwvar_var_set_int(sc, "wpa_auth", BWFM_WPA_AUTH_WPA2_PSK); 679 bwfm_fwvar_var_set_int(sc, "wpa_auth", BWFM_WPA_AUTH_WPA2_PSK);
680 680
681 bwfm_fwvar_var_get_int(sc, "wsec", &wsec); 681 bwfm_fwvar_var_get_int(sc, "wsec", &wsec);
682 wsec |= wsec_enable; 682 wsec |= wsec_enable;
683 bwfm_fwvar_var_set_int(sc, "wsec", wsec); 683 bwfm_fwvar_var_set_int(sc, "wsec", wsec);
684} 684}
685 685
686int 686int
687bwfm_key_delete(struct ieee80211com *ic, const struct ieee80211_key *wk) 687bwfm_key_delete(struct ieee80211com *ic, const struct ieee80211_key *wk)
688{ 688{
689 struct bwfm_softc *sc = ic->ic_ifp->if_softc; 689 struct bwfm_softc *sc = ic->ic_ifp->if_softc;
690 struct bwfm_task *t; 690 struct bwfm_task *t;
691 691
692 t = pcq_get(sc->sc_freetask); 692 t = pcq_get(sc->sc_freetask);
693 if (t == NULL) { 693 if (t == NULL) {
694 printf("%s: no free tasks\n", DEVNAME(sc)); 694 printf("%s: no free tasks\n", DEVNAME(sc));
695 return 0; 695 return 0;
696 } 696 }
697 697
698 t->t_cmd = BWFM_TASK_KEY_DELETE; 698 t->t_cmd = BWFM_TASK_KEY_DELETE;
699 t->t_key.key = wk; 699 t->t_key.key = wk;
700 memset(t->t_key.mac, 0, sizeof(t->t_key.mac)); 700 memset(t->t_key.mac, 0, sizeof(t->t_key.mac));
701 workqueue_enqueue(sc->sc_taskq, (struct work *)t, NULL); 701 workqueue_enqueue(sc->sc_taskq, (struct work *)t, NULL);
702 702
703 return 1; 703 return 1;
704} 704}
705 705
706static void 706static void
707bwfm_key_delete_cb(struct bwfm_softc *sc, struct bwfm_cmd_key *ck) 707bwfm_key_delete_cb(struct bwfm_softc *sc, struct bwfm_cmd_key *ck)
708{ 708{
709 const struct ieee80211_key *wk = ck->key; 709 const struct ieee80211_key *wk = ck->key;
710 struct bwfm_wsec_key wsec_key; 710 struct bwfm_wsec_key wsec_key;
711 711
712 memset(&wsec_key, 0, sizeof(wsec_key)); 712 memset(&wsec_key, 0, sizeof(wsec_key));
713 wsec_key.index = htole32(wk->wk_keyix); 713 wsec_key.index = htole32(wk->wk_keyix);
714 wsec_key.flags = htole32(BWFM_WSEC_PRIMARY_KEY); 714 wsec_key.flags = htole32(BWFM_WSEC_PRIMARY_KEY);
715 715
716 if (bwfm_fwvar_var_set_data(sc, "wsec_key", &wsec_key, sizeof(wsec_key))) 716 if (bwfm_fwvar_var_set_data(sc, "wsec_key", &wsec_key, sizeof(wsec_key)))
717 return; 717 return;
718} 718}
719 719
720int 720int
721bwfm_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) 721bwfm_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
722{ 722{
723 struct bwfm_softc *sc = ic->ic_ifp->if_softc; 723 struct bwfm_softc *sc = ic->ic_ifp->if_softc;
724 struct bwfm_task *t; 724 struct bwfm_task *t;
725 725
726 t = pcq_get(sc->sc_freetask); 726 t = pcq_get(sc->sc_freetask);
727 if (t == NULL) { 727 if (t == NULL) {
728 printf("%s: no free tasks\n", DEVNAME(sc)); 728 printf("%s: no free tasks\n", DEVNAME(sc));
729 return EIO; 729 return EIO;
730 } 730 }
731 731
732 t->t_cmd = BWFM_TASK_NEWSTATE; 732 t->t_cmd = BWFM_TASK_NEWSTATE;
733 t->t_newstate.state = nstate; 733 t->t_newstate.state = nstate;
734 t->t_newstate.arg = arg; 734 t->t_newstate.arg = arg;
735 workqueue_enqueue(sc->sc_taskq, (struct work *)t, NULL); 735 workqueue_enqueue(sc->sc_taskq, (struct work *)t, NULL);
736 736
737 return 0; 737 return 0;
738} 738}
739 739
740void 740void
741bwfm_newstate_cb(struct bwfm_softc *sc, struct bwfm_cmd_newstate *cmd) 741bwfm_newstate_cb(struct bwfm_softc *sc, struct bwfm_cmd_newstate *cmd)
742{ 742{
743 struct ieee80211com *ic = &sc->sc_ic; 743 struct ieee80211com *ic = &sc->sc_ic;
744 enum ieee80211_state ostate = ic->ic_state; 744 enum ieee80211_state ostate = ic->ic_state;
745 enum ieee80211_state nstate = cmd->state; 745 enum ieee80211_state nstate = cmd->state;
746 int s; 746 int s;
747 747
748 DPRINTF(("%s: newstate %d -> %d\n", DEVNAME(sc), ostate, nstate)); 748 DPRINTF(("%s: newstate %d -> %d\n", DEVNAME(sc), ostate, nstate));
749 749
750 s = splnet(); 750 s = splnet();
751 751
752 switch (nstate) { 752 switch (nstate) {
753 case IEEE80211_S_INIT: 753 case IEEE80211_S_INIT:
754 break; 754 break;
755 755
756 case IEEE80211_S_SCAN: 756 case IEEE80211_S_SCAN:
757 if (ostate != IEEE80211_S_SCAN) { 757 if (ostate != IEEE80211_S_SCAN) {
758 /* Start of scanning */ 758 /* Start of scanning */
759 bwfm_scan(sc); 759 bwfm_scan(sc);
760 } 760 }
761 break; 761 break;
762 762
763 case IEEE80211_S_AUTH: 763 case IEEE80211_S_AUTH:
764 bwfm_connect(sc); 764 bwfm_connect(sc);
765 break; 765 break;
766 766
767 case IEEE80211_S_ASSOC: 767 case IEEE80211_S_ASSOC:
768 break; 768 break;
769 769
770 case IEEE80211_S_RUN: 770 case IEEE80211_S_RUN:
771 break; 771 break;
772 } 772 }
773 773
774 sc->sc_newstate(ic, nstate, cmd->arg); 774 sc->sc_newstate(ic, nstate, cmd->arg);
775 775
776 splx(s); 776 splx(s);
777} 777}
778 778
779void 779void
780bwfm_newassoc(struct ieee80211_node *ni, int isnew) 780bwfm_newassoc(struct ieee80211_node *ni, int isnew)
781{ 781{
782 /* Firmware handles rate adaptation for us */ 782 /* Firmware handles rate adaptation for us */
783 ni->ni_txrate = 0; 783 ni->ni_txrate = 0;
784} 784}
785 785
786void 786void
787bwfm_task(struct work *wk, void *arg) 787bwfm_task(struct work *wk, void *arg)
788{ 788{
789 struct bwfm_task *t = (struct bwfm_task *)wk; 789 struct bwfm_task *t = (struct bwfm_task *)wk;
790 struct bwfm_softc *sc = t->t_sc; 790 struct bwfm_softc *sc = t->t_sc;
791 791
792 switch (t->t_cmd) { 792 switch (t->t_cmd) {
793 case BWFM_TASK_NEWSTATE: 793 case BWFM_TASK_NEWSTATE:
794 bwfm_newstate_cb(sc, &t->t_newstate); 794 bwfm_newstate_cb(sc, &t->t_newstate);
795 break; 795 break;
796 case BWFM_TASK_KEY_SET: 796 case BWFM_TASK_KEY_SET:
797 bwfm_key_set_cb(sc, &t->t_key); 797 bwfm_key_set_cb(sc, &t->t_key);
798 break; 798 break;
799 case BWFM_TASK_KEY_DELETE: 799 case BWFM_TASK_KEY_DELETE:
800 bwfm_key_delete_cb(sc, &t->t_key); 800 bwfm_key_delete_cb(sc, &t->t_key);
801 break; 801 break;
802 case BWFM_TASK_RX_EVENT: 802 case BWFM_TASK_RX_EVENT:
803 bwfm_rx_event_cb(sc, t->t_mbuf); 803 bwfm_rx_event_cb(sc, t->t_mbuf);
804 break; 804 break;
805 default: 805 default:
806 panic("bwfm: unknown task command %d", t->t_cmd); 806 panic("bwfm: unknown task command %d", t->t_cmd);
807 } 807 }
808 808
809 pcq_put(sc->sc_freetask, t); 809 pcq_put(sc->sc_freetask, t);
810} 810}
811 811
812int 812int
813bwfm_media_change(struct ifnet *ifp) 813bwfm_media_change(struct ifnet *ifp)
814{ 814{
815 return 0; 815 return 0;
816} 816}
817 817
818/* Chip initialization (SDIO, PCIe) */ 818/* Chip initialization (SDIO, PCIe) */
819int 819int
820bwfm_chip_attach(struct bwfm_softc *sc) 820bwfm_chip_attach(struct bwfm_softc *sc)
821{ 821{
822 struct bwfm_core *core; 822 struct bwfm_core *core;
823 int need_socram = 0; 823 int need_socram = 0;
824 int has_socram = 0; 824 int has_socram = 0;
825 int cpu_found = 0; 825 int cpu_found = 0;
826 uint32_t val; 826 uint32_t val;
827 827
828 LIST_INIT(&sc->sc_chip.ch_list); 828 LIST_INIT(&sc->sc_chip.ch_list);
829 829
830 if (sc->sc_buscore_ops->bc_prepare(sc) != 0) { 830 if (sc->sc_buscore_ops->bc_prepare(sc) != 0) {
831 printf("%s: failed buscore prepare\n", DEVNAME(sc)); 831 printf("%s: failed buscore prepare\n", DEVNAME(sc));
832 return 1; 832 return 1;
833 } 833 }
834 834
835 val = sc->sc_buscore_ops->bc_read(sc, 835 val = sc->sc_buscore_ops->bc_read(sc,
836 BWFM_CHIP_BASE + BWFM_CHIP_REG_CHIPID); 836 BWFM_CHIP_BASE + BWFM_CHIP_REG_CHIPID);
837 sc->sc_chip.ch_chip = BWFM_CHIP_CHIPID_ID(val); 837 sc->sc_chip.ch_chip = BWFM_CHIP_CHIPID_ID(val);
838 sc->sc_chip.ch_chiprev = BWFM_CHIP_CHIPID_REV(val); 838 sc->sc_chip.ch_chiprev = BWFM_CHIP_CHIPID_REV(val);
839 839
840 if ((sc->sc_chip.ch_chip > 0xa000) || (sc->sc_chip.ch_chip < 0x4000)) 840 if ((sc->sc_chip.ch_chip > 0xa000) || (sc->sc_chip.ch_chip < 0x4000))
841 snprintf(sc->sc_chip.ch_name, sizeof(sc->sc_chip.ch_name), 841 snprintf(sc->sc_chip.ch_name, sizeof(sc->sc_chip.ch_name),
842 "%d", sc->sc_chip.ch_chip); 842 "%d", sc->sc_chip.ch_chip);
843 else 843 else
844 snprintf(sc->sc_chip.ch_name, sizeof(sc->sc_chip.ch_name), 844 snprintf(sc->sc_chip.ch_name, sizeof(sc->sc_chip.ch_name),
845 "%x", sc->sc_chip.ch_chip); 845 "%x", sc->sc_chip.ch_chip);
846 846
847 switch (BWFM_CHIP_CHIPID_TYPE(val)) 847 switch (BWFM_CHIP_CHIPID_TYPE(val))
848 { 848 {
849 case BWFM_CHIP_CHIPID_TYPE_SOCI_SB: 849 case BWFM_CHIP_CHIPID_TYPE_SOCI_SB:
850 printf("%s: SoC interconnect SB not implemented\n", 850 printf("%s: SoC interconnect SB not implemented\n",
851 DEVNAME(sc)); 851 DEVNAME(sc));
852 return 1; 852 return 1;
853 case BWFM_CHIP_CHIPID_TYPE_SOCI_AI: 853 case BWFM_CHIP_CHIPID_TYPE_SOCI_AI:
854 sc->sc_chip.ch_core_isup = bwfm_chip_ai_isup; 854 sc->sc_chip.ch_core_isup = bwfm_chip_ai_isup;
855 sc->sc_chip.ch_core_disable = bwfm_chip_ai_disable; 855 sc->sc_chip.ch_core_disable = bwfm_chip_ai_disable;
856 sc->sc_chip.ch_core_reset = bwfm_chip_ai_reset; 856 sc->sc_chip.ch_core_reset = bwfm_chip_ai_reset;
857 bwfm_chip_dmp_erom_scan(sc); 857 bwfm_chip_dmp_erom_scan(sc);
858 break; 858 break;
859 default: 859 default:
860 printf("%s: SoC interconnect %d unknown\n", 860 printf("%s: SoC interconnect %d unknown\n",
861 DEVNAME(sc), BWFM_CHIP_CHIPID_TYPE(val)); 861 DEVNAME(sc), BWFM_CHIP_CHIPID_TYPE(val));
862 return 1; 862 return 1;
863 } 863 }
864 864
865 LIST_FOREACH(core, &sc->sc_chip.ch_list, co_link) { 865 LIST_FOREACH(core, &sc->sc_chip.ch_list, co_link) {
866 DPRINTF(("%s: 0x%x:%-2d base 0x%08x wrap 0x%08x\n", 866 DPRINTF(("%s: 0x%x:%-2d base 0x%08x wrap 0x%08x\n",
867 DEVNAME(sc), core->co_id, core->co_rev, 867 DEVNAME(sc), core->co_id, core->co_rev,
868 core->co_base, core->co_wrapbase)); 868 core->co_base, core->co_wrapbase));
869 869
870 switch (core->co_id) { 870 switch (core->co_id) {
871 case BWFM_AGENT_CORE_ARM_CM3: 871 case BWFM_AGENT_CORE_ARM_CM3:
872 need_socram = true; 872 need_socram = true;
873 /* FALLTHROUGH */ 873 /* FALLTHROUGH */
874 case BWFM_AGENT_CORE_ARM_CR4: 874 case BWFM_AGENT_CORE_ARM_CR4:
875 case BWFM_AGENT_CORE_ARM_CA7: 875 case BWFM_AGENT_CORE_ARM_CA7:
876 cpu_found = true; 876 cpu_found = true;
877 break; 877 break;
878 case BWFM_AGENT_INTERNAL_MEM: 878 case BWFM_AGENT_INTERNAL_MEM:
879 has_socram = true; 879 has_socram = true;
880 break; 880 break;
881 default: 881 default:
882 break; 882 break;
883 } 883 }
884 } 884 }
885 885
886 if (!cpu_found) { 886 if (!cpu_found) {
887 printf("%s: CPU core not detected\n", DEVNAME(sc)); 887 printf("%s: CPU core not detected\n", DEVNAME(sc));
888 return 1; 888 return 1;
889 } 889 }
890 if (need_socram && !has_socram) { 890 if (need_socram && !has_socram) {
891 printf("%s: RAM core not provided\n", DEVNAME(sc)); 891 printf("%s: RAM core not provided\n", DEVNAME(sc));
892 return 1; 892 return 1;
893 } 893 }
894 894
895 bwfm_chip_set_passive(sc); 895 bwfm_chip_set_passive(sc);
896 896
897 if (sc->sc_buscore_ops->bc_reset) { 897 if (sc->sc_buscore_ops->bc_reset) {
898 sc->sc_buscore_ops->bc_reset(sc); 898 sc->sc_buscore_ops->bc_reset(sc);
899 bwfm_chip_set_passive(sc); 899 bwfm_chip_set_passive(sc);
900 } 900 }
901 901
902 if ((core = bwfm_chip_get_core(sc, BWFM_AGENT_CORE_ARM_CR4)) != NULL) { 902 if ((core = bwfm_chip_get_core(sc, BWFM_AGENT_CORE_ARM_CR4)) != NULL) {
903 bwfm_chip_tcm_ramsize(sc, core); 903 bwfm_chip_tcm_ramsize(sc, core);
904 bwfm_chip_tcm_rambase(sc); 904 bwfm_chip_tcm_rambase(sc);
905 } else if ((core = bwfm_chip_get_core(sc, BWFM_AGENT_SYS_MEM)) != NULL) { 905 } else if ((core = bwfm_chip_get_core(sc, BWFM_AGENT_SYS_MEM)) != NULL) {
906 bwfm_chip_sysmem_ramsize(sc, core); 906 bwfm_chip_sysmem_ramsize(sc, core);
907 bwfm_chip_tcm_rambase(sc); 907 bwfm_chip_tcm_rambase(sc);
908 } else if ((core = bwfm_chip_get_core(sc, BWFM_AGENT_INTERNAL_MEM)) != NULL) { 908 } else if ((core = bwfm_chip_get_core(sc, BWFM_AGENT_INTERNAL_MEM)) != NULL) {
909 bwfm_chip_socram_ramsize(sc, core); 909 bwfm_chip_socram_ramsize(sc, core);
910 } 910 }
911 911
912 core = bwfm_chip_get_core(sc, BWFM_AGENT_CORE_CHIPCOMMON); 912 core = bwfm_chip_get_core(sc, BWFM_AGENT_CORE_CHIPCOMMON);
913 sc->sc_chip.ch_cc_caps = sc->sc_buscore_ops->bc_read(sc, 913 sc->sc_chip.ch_cc_caps = sc->sc_buscore_ops->bc_read(sc,
914 core->co_base + BWFM_CHIP_REG_CAPABILITIES); 914 core->co_base + BWFM_CHIP_REG_CAPABILITIES);
915 sc->sc_chip.ch_cc_caps_ext = sc->sc_buscore_ops->bc_read(sc, 915 sc->sc_chip.ch_cc_caps_ext = sc->sc_buscore_ops->bc_read(sc,
916 core->co_base + BWFM_CHIP_REG_CAPABILITIES_EXT); 916 core->co_base + BWFM_CHIP_REG_CAPABILITIES_EXT);
917 917
918 core = bwfm_chip_get_pmu(sc); 918 core = bwfm_chip_get_pmu(sc);
919 if (sc->sc_chip.ch_cc_caps & BWFM_CHIP_REG_CAPABILITIES_PMU) { 919 if (sc->sc_chip.ch_cc_caps & BWFM_CHIP_REG_CAPABILITIES_PMU) {
920 sc->sc_chip.ch_pmucaps = sc->sc_buscore_ops->bc_read(sc, 920 sc->sc_chip.ch_pmucaps = sc->sc_buscore_ops->bc_read(sc,
921 core->co_base + BWFM_CHIP_REG_PMUCAPABILITIES); 921 core->co_base + BWFM_CHIP_REG_PMUCAPABILITIES);
922 sc->sc_chip.ch_pmurev = sc->sc_chip.ch_pmucaps & 922 sc->sc_chip.ch_pmurev = sc->sc_chip.ch_pmucaps &
923 BWFM_CHIP_REG_PMUCAPABILITIES_REV_MASK; 923 BWFM_CHIP_REG_PMUCAPABILITIES_REV_MASK;
924 } 924 }
925 925
926 if (sc->sc_buscore_ops->bc_setup) 926 if (sc->sc_buscore_ops->bc_setup)
927 sc->sc_buscore_ops->bc_setup(sc); 927 sc->sc_buscore_ops->bc_setup(sc);
928 928
929 return 0; 929 return 0;
930} 930}
931 931
932struct bwfm_core * 932struct bwfm_core *
933bwfm_chip_get_core(struct bwfm_softc *sc, int id) 933bwfm_chip_get_core(struct bwfm_softc *sc, int id)
934{ 934{
935 struct bwfm_core *core; 935 struct bwfm_core *core;
936 936
937 LIST_FOREACH(core, &sc->sc_chip.ch_list, co_link) { 937 LIST_FOREACH(core, &sc->sc_chip.ch_list, co_link) {
938 if (core->co_id == id) 938 if (core->co_id == id)
939 return core; 939 return core;
940 } 940 }
941 941
942 return NULL; 942 return NULL;
943} 943}
944 944
945struct bwfm_core * 945struct bwfm_core *
946bwfm_chip_get_pmu(struct bwfm_softc *sc) 946bwfm_chip_get_pmu(struct bwfm_softc *sc)
947{ 947{
948 struct bwfm_core *cc, *pmu; 948 struct bwfm_core *cc, *pmu;
949 949
950 cc = bwfm_chip_get_core(sc, BWFM_AGENT_CORE_CHIPCOMMON); 950 cc = bwfm_chip_get_core(sc, BWFM_AGENT_CORE_CHIPCOMMON);
951 if (cc->co_rev >= 35 && sc->sc_chip.ch_cc_caps_ext & 951 if (cc->co_rev >= 35 && sc->sc_chip.ch_cc_caps_ext &
952 BWFM_CHIP_REG_CAPABILITIES_EXT_AOB_PRESENT) { 952 BWFM_CHIP_REG_CAPABILITIES_EXT_AOB_PRESENT) {
953 pmu = bwfm_chip_get_core(sc, BWFM_AGENT_CORE_PMU); 953 pmu = bwfm_chip_get_core(sc, BWFM_AGENT_CORE_PMU);
954 if (pmu) 954 if (pmu)
955 return pmu; 955 return pmu;
956 } 956 }
957 957
958 return cc; 958 return cc;
959} 959}
960 960
961/* Functions for the AI interconnect */ 961/* Functions for the AI interconnect */
962int 962int
963bwfm_chip_ai_isup(struct bwfm_softc *sc, struct bwfm_core *core) 963bwfm_chip_ai_isup(struct bwfm_softc *sc, struct bwfm_core *core)
964{ 964{
965 uint32_t ioctl, reset; 965 uint32_t ioctl, reset;
966 966
967 ioctl = sc->sc_buscore_ops->bc_read(sc, 967 ioctl = sc->sc_buscore_ops->bc_read(sc,
968 core->co_wrapbase + BWFM_AGENT_IOCTL); 968 core->co_wrapbase + BWFM_AGENT_IOCTL);
969 reset = sc->sc_buscore_ops->bc_read(sc, 969 reset = sc->sc_buscore_ops->bc_read(sc,
970 core->co_wrapbase + BWFM_AGENT_RESET_CTL); 970 core->co_wrapbase + BWFM_AGENT_RESET_CTL);
971 971
972 if (((ioctl & (BWFM_AGENT_IOCTL_FGC | BWFM_AGENT_IOCTL_CLK)) == 972 if (((ioctl & (BWFM_AGENT_IOCTL_FGC | BWFM_AGENT_IOCTL_CLK)) ==
973 BWFM_AGENT_IOCTL_CLK) && 973 BWFM_AGENT_IOCTL_CLK) &&
974 ((reset & BWFM_AGENT_RESET_CTL_RESET) == 0)) 974 ((reset & BWFM_AGENT_RESET_CTL_RESET) == 0))
975 return 1; 975 return 1;
976 976
977 return 0; 977 return 0;
978} 978}
979 979
980void 980void
981bwfm_chip_ai_disable(struct bwfm_softc *sc, struct bwfm_core *core, 981bwfm_chip_ai_disable(struct bwfm_softc *sc, struct bwfm_core *core,
982 uint32_t prereset, uint32_t reset) 982 uint32_t prereset, uint32_t reset)
983{ 983{
984 uint32_t val; 984 uint32_t val;
985 int i; 985 int i;
986 986
987 val = sc->sc_buscore_ops->bc_read(sc, 987 val = sc->sc_buscore_ops->bc_read(sc,
988 core->co_wrapbase + BWFM_AGENT_RESET_CTL); 988 core->co_wrapbase + BWFM_AGENT_RESET_CTL);
989 if ((val & BWFM_AGENT_RESET_CTL_RESET) == 0) { 989 if ((val & BWFM_AGENT_RESET_CTL_RESET) == 0) {
990 990
991 sc->sc_buscore_ops->bc_write(sc, 991 sc->sc_buscore_ops->bc_write(sc,
992 core->co_wrapbase + BWFM_AGENT_IOCTL, 992 core->co_wrapbase + BWFM_AGENT_IOCTL,
993 prereset | BWFM_AGENT_IOCTL_FGC | BWFM_AGENT_IOCTL_CLK); 993 prereset | BWFM_AGENT_IOCTL_FGC | BWFM_AGENT_IOCTL_CLK);
994 sc->sc_buscore_ops->bc_read(sc, 994 sc->sc_buscore_ops->bc_read(sc,
995 core->co_wrapbase + BWFM_AGENT_IOCTL); 995 core->co_wrapbase + BWFM_AGENT_IOCTL);
996 996
997 sc->sc_buscore_ops->bc_write(sc, 997 sc->sc_buscore_ops->bc_write(sc,
998 core->co_wrapbase + BWFM_AGENT_RESET_CTL, 998 core->co_wrapbase + BWFM_AGENT_RESET_CTL,
999 BWFM_AGENT_RESET_CTL_RESET); 999 BWFM_AGENT_RESET_CTL_RESET);
1000 delay(20); 1000 delay(20);
1001 1001
1002 for (i = 300; i > 0; i--) { 1002 for (i = 300; i > 0; i--) {
1003 if (sc->sc_buscore_ops->bc_read(sc, 1003 if (sc->sc_buscore_ops->bc_read(sc,
1004 core->co_wrapbase + BWFM_AGENT_RESET_CTL) == 1004 core->co_wrapbase + BWFM_AGENT_RESET_CTL) ==
1005 BWFM_AGENT_RESET_CTL_RESET) 1005 BWFM_AGENT_RESET_CTL_RESET)
1006 break; 1006 break;
1007 } 1007 }
1008 if (i == 0) 1008 if (i == 0)
1009 printf("%s: timeout on core reset\n", DEVNAME(sc)); 1009 printf("%s: timeout on core reset\n", DEVNAME(sc));
1010 } 1010 }
1011 1011
1012 sc->sc_buscore_ops->bc_write(sc, 1012 sc->sc_buscore_ops->bc_write(sc,
1013 core->co_wrapbase + BWFM_AGENT_IOCTL, 1013 core->co_wrapbase + BWFM_AGENT_IOCTL,
1014 reset | BWFM_AGENT_IOCTL_FGC | BWFM_AGENT_IOCTL_CLK); 1014 reset | BWFM_AGENT_IOCTL_FGC | BWFM_AGENT_IOCTL_CLK);
1015 sc->sc_buscore_ops->bc_read(sc, 1015 sc->sc_buscore_ops->bc_read(sc,
1016 core->co_wrapbase + BWFM_AGENT_IOCTL); 1016 core->co_wrapbase + BWFM_AGENT_IOCTL);
1017} 1017}
1018 1018
1019void 1019void
1020bwfm_chip_ai_reset(struct bwfm_softc *sc, struct bwfm_core *core, 1020bwfm_chip_ai_reset(struct bwfm_softc *sc, struct bwfm_core *core,
1021 uint32_t prereset, uint32_t reset, uint32_t postreset) 1021 uint32_t prereset, uint32_t reset, uint32_t postreset)
1022{ 1022{
1023 int i; 1023 int i;
1024 1024
1025 bwfm_chip_ai_disable(sc, core, prereset, reset); 1025 bwfm_chip_ai_disable(sc, core, prereset, reset);
1026 1026
1027 for (i = 50; i > 0; i--) { 1027 for (i = 50; i > 0; i--) {
1028 if ((sc->sc_buscore_ops->bc_read(sc, 1028 if ((sc->sc_buscore_ops->bc_read(sc,
1029 core->co_wrapbase + BWFM_AGENT_RESET_CTL) & 1029 core->co_wrapbase + BWFM_AGENT_RESET_CTL) &
1030 BWFM_AGENT_RESET_CTL_RESET) == 0) 1030 BWFM_AGENT_RESET_CTL_RESET) == 0)
1031 break; 1031 break;
1032 sc->sc_buscore_ops->bc_write(sc, 1032 sc->sc_buscore_ops->bc_write(sc,
1033 core->co_wrapbase + BWFM_AGENT_RESET_CTL, 0); 1033 core->co_wrapbase + BWFM_AGENT_RESET_CTL, 0);
1034 delay(60); 1034 delay(60);
1035 } 1035 }
1036 if (i == 0) 1036 if (i == 0)
1037 printf("%s: timeout on core reset\n", DEVNAME(sc)); 1037 printf("%s: timeout on core reset\n", DEVNAME(sc));
1038 1038
1039 sc->sc_buscore_ops->bc_write(sc, 1039 sc->sc_buscore_ops->bc_write(sc,
1040 core->co_wrapbase + BWFM_AGENT_IOCTL, 1040 core->co_wrapbase + BWFM_AGENT_IOCTL,
1041 postreset | BWFM_AGENT_IOCTL_CLK); 1041 postreset | BWFM_AGENT_IOCTL_CLK);
1042 sc->sc_buscore_ops->bc_read(sc, 1042 sc->sc_buscore_ops->bc_read(sc,
1043 core->co_wrapbase + BWFM_AGENT_IOCTL); 1043 core->co_wrapbase + BWFM_AGENT_IOCTL);
1044} 1044}
1045 1045
1046void 1046void
1047bwfm_chip_dmp_erom_scan(struct bwfm_softc *sc) 1047bwfm_chip_dmp_erom_scan(struct bwfm_softc *sc)
1048{ 1048{
1049 uint32_t erom, val, base, wrap; 1049 uint32_t erom, val, base, wrap;
1050 uint8_t type = 0; 1050 uint8_t type = 0;
1051 uint16_t id; 1051 uint16_t id;
1052 uint8_t nmw, nsw, rev; 1052 uint8_t nmw, nsw, rev;
1053 struct bwfm_core *core; 1053 struct bwfm_core *core;
1054 1054
1055 erom = sc->sc_buscore_ops->bc_read(sc, 1055 erom = sc->sc_buscore_ops->bc_read(sc,
1056 BWFM_CHIP_BASE + BWFM_CHIP_REG_EROMPTR); 1056 BWFM_CHIP_BASE + BWFM_CHIP_REG_EROMPTR);
1057 while (type != BWFM_DMP_DESC_EOT) { 1057 while (type != BWFM_DMP_DESC_EOT) {
1058 val = sc->sc_buscore_ops->bc_read(sc, erom); 1058 val = sc->sc_buscore_ops->bc_read(sc, erom);
1059 type = val & BWFM_DMP_DESC_MASK; 1059 type = val & BWFM_DMP_DESC_MASK;
1060 erom += 4; 1060 erom += 4;
1061 1061
1062 if (type != BWFM_DMP_DESC_COMPONENT) 1062 if (type != BWFM_DMP_DESC_COMPONENT)
1063 continue; 1063 continue;
1064 1064
1065 id = (val & BWFM_DMP_COMP_PARTNUM) 1065 id = (val & BWFM_DMP_COMP_PARTNUM)
1066 >> BWFM_DMP_COMP_PARTNUM_S; 1066 >> BWFM_DMP_COMP_PARTNUM_S;
1067 1067
1068 val = sc->sc_buscore_ops->bc_read(sc, erom); 1068 val = sc->sc_buscore_ops->bc_read(sc, erom);
1069 type = val & BWFM_DMP_DESC_MASK; 1069 type = val & BWFM_DMP_DESC_MASK;
1070 erom += 4; 1070 erom += 4;
1071 1071
1072 if (type != BWFM_DMP_DESC_COMPONENT) { 1072 if (type != BWFM_DMP_DESC_COMPONENT) {
1073 printf("%s: not component descriptor\n", DEVNAME(sc)); 1073 printf("%s: not component descriptor\n", DEVNAME(sc));
1074 return; 1074 return;
1075 } 1075 }
1076 1076
1077 nmw = (val & BWFM_DMP_COMP_NUM_MWRAP) 1077 nmw = (val & BWFM_DMP_COMP_NUM_MWRAP)
1078 >> BWFM_DMP_COMP_NUM_MWRAP_S; 1078 >> BWFM_DMP_COMP_NUM_MWRAP_S;
1079 nsw = (val & BWFM_DMP_COMP_NUM_SWRAP) 1079 nsw = (val & BWFM_DMP_COMP_NUM_SWRAP)
1080 >> BWFM_DMP_COMP_NUM_SWRAP_S; 1080 >> BWFM_DMP_COMP_NUM_SWRAP_S;
1081 rev = (val & BWFM_DMP_COMP_REVISION) 1081 rev = (val & BWFM_DMP_COMP_REVISION)
1082 >> BWFM_DMP_COMP_REVISION_S; 1082 >> BWFM_DMP_COMP_REVISION_S;
1083 1083
1084 if (nmw + nsw == 0 && id != BWFM_AGENT_CORE_PMU) 1084 if (nmw + nsw == 0 && id != BWFM_AGENT_CORE_PMU)
1085 continue; 1085 continue;
1086 1086
1087 if (bwfm_chip_dmp_get_regaddr(sc, &erom, &base, &wrap)) 1087 if (bwfm_chip_dmp_get_regaddr(sc, &erom, &base, &wrap))
1088 continue; 1088 continue;
1089 1089
1090 core = kmem_alloc(sizeof(*core), KM_SLEEP); 1090 core = kmem_alloc(sizeof(*core), KM_SLEEP);
1091 core->co_id = id; 1091 core->co_id = id;
1092 core->co_base = base; 1092 core->co_base = base;
1093 core->co_wrapbase = wrap; 1093 core->co_wrapbase = wrap;
1094 core->co_rev = rev; 1094 core->co_rev = rev;
1095 LIST_INSERT_HEAD(&sc->sc_chip.ch_list, core, co_link); 1095 LIST_INSERT_HEAD(&sc->sc_chip.ch_list, core, co_link);
1096 } 1096 }
1097} 1097}
1098 1098
1099int 1099int
1100bwfm_chip_dmp_get_regaddr(struct bwfm_softc *sc, uint32_t *erom, 1100bwfm_chip_dmp_get_regaddr(struct bwfm_softc *sc, uint32_t *erom,
1101 uint32_t *base, uint32_t *wrap) 1101 uint32_t *base, uint32_t *wrap)
1102{ 1102{
1103 uint8_t type = 0, mpnum __unused = 0; 1103 uint8_t type = 0, mpnum __unused = 0;
1104 uint8_t stype, sztype, wraptype; 1104 uint8_t stype, sztype, wraptype;
1105 uint32_t val; 1105 uint32_t val;
1106 1106
1107 *base = 0; 1107 *base = 0;
1108 *wrap = 0; 1108 *wrap = 0;
1109 1109
1110 val = sc->sc_buscore_ops->bc_read(sc, *erom); 1110 val = sc->sc_buscore_ops->bc_read(sc, *erom);
1111 type = val & BWFM_DMP_DESC_MASK; 1111 type = val & BWFM_DMP_DESC_MASK;
1112 if (type == BWFM_DMP_DESC_MASTER_PORT) { 1112 if (type == BWFM_DMP_DESC_MASTER_PORT) {
1113 mpnum = (val & BWFM_DMP_MASTER_PORT_NUM) 1113 mpnum = (val & BWFM_DMP_MASTER_PORT_NUM)
1114 >> BWFM_DMP_MASTER_PORT_NUM_S; 1114 >> BWFM_DMP_MASTER_PORT_NUM_S;
1115 wraptype = BWFM_DMP_SLAVE_TYPE_MWRAP; 1115 wraptype = BWFM_DMP_SLAVE_TYPE_MWRAP;
1116 *erom += 4; 1116 *erom += 4;
1117 } else if ((type & ~BWFM_DMP_DESC_ADDRSIZE_GT32) == 1117 } else if ((type & ~BWFM_DMP_DESC_ADDRSIZE_GT32) ==
1118 BWFM_DMP_DESC_ADDRESS) 1118 BWFM_DMP_DESC_ADDRESS)
1119 wraptype = BWFM_DMP_SLAVE_TYPE_SWRAP; 1119 wraptype = BWFM_DMP_SLAVE_TYPE_SWRAP;
1120 else 1120 else
1121 return 1; 1121 return 1;
1122 1122
1123 do { 1123 do {
1124 do { 1124 do {
1125 val = sc->sc_buscore_ops->bc_read(sc, *erom); 1125 val = sc->sc_buscore_ops->bc_read(sc, *erom);
1126 type = val & BWFM_DMP_DESC_MASK; 1126 type = val & BWFM_DMP_DESC_MASK;
1127 if (type == BWFM_DMP_DESC_COMPONENT) 1127 if (type == BWFM_DMP_DESC_COMPONENT)
1128 return 0; 1128 return 0;
1129 if (type == BWFM_DMP_DESC_EOT) 1129 if (type == BWFM_DMP_DESC_EOT)
1130 return 1; 1130 return 1;
1131 *erom += 4; 1131 *erom += 4;
1132 } while ((type & ~BWFM_DMP_DESC_ADDRSIZE_GT32) != 1132 } while ((type & ~BWFM_DMP_DESC_ADDRSIZE_GT32) !=
1133 BWFM_DMP_DESC_ADDRESS); 1133 BWFM_DMP_DESC_ADDRESS);
1134 1134
1135 if (type & BWFM_DMP_DESC_ADDRSIZE_GT32) 1135 if (type & BWFM_DMP_DESC_ADDRSIZE_GT32)
1136 *erom += 4; 1136 *erom += 4;
1137 1137
1138 sztype = (val & BWFM_DMP_SLAVE_SIZE_TYPE) 1138 sztype = (val & BWFM_DMP_SLAVE_SIZE_TYPE)
1139 >> BWFM_DMP_SLAVE_SIZE_TYPE_S; 1139 >> BWFM_DMP_SLAVE_SIZE_TYPE_S;
1140 if (sztype == BWFM_DMP_SLAVE_SIZE_DESC) { 1140 if (sztype == BWFM_DMP_SLAVE_SIZE_DESC) {
1141 val = sc->sc_buscore_ops->bc_read(sc, *erom); 1141 val = sc->sc_buscore_ops->bc_read(sc, *erom);
1142 type = val & BWFM_DMP_DESC_MASK; 1142 type = val & BWFM_DMP_DESC_MASK;
1143 if (type & BWFM_DMP_DESC_ADDRSIZE_GT32) 1143 if (type & BWFM_DMP_DESC_ADDRSIZE_GT32)
1144 *erom += 8; 1144 *erom += 8;
1145 else 1145 else
1146 *erom += 4; 1146 *erom += 4;
1147 } 1147 }
1148 if (sztype != BWFM_DMP_SLAVE_SIZE_4K) 1148 if (sztype != BWFM_DMP_SLAVE_SIZE_4K)
1149 continue; 1149 continue;
1150 1150
1151 stype = (val & BWFM_DMP_SLAVE_TYPE) >> BWFM_DMP_SLAVE_TYPE_S; 1151 stype = (val & BWFM_DMP_SLAVE_TYPE) >> BWFM_DMP_SLAVE_TYPE_S;
1152 if (*base == 0 && stype == BWFM_DMP_SLAVE_TYPE_SLAVE) 1152 if (*base == 0 && stype == BWFM_DMP_SLAVE_TYPE_SLAVE)
1153 *base = val & BWFM_DMP_SLAVE_ADDR_BASE; 1153 *base = val & BWFM_DMP_SLAVE_ADDR_BASE;
1154 if (*wrap == 0 && stype == wraptype) 1154 if (*wrap == 0 && stype == wraptype)
1155 *wrap = val & BWFM_DMP_SLAVE_ADDR_BASE; 1155 *wrap = val & BWFM_DMP_SLAVE_ADDR_BASE;
1156 } while (*base == 0 || *wrap == 0); 1156 } while (*base == 0 || *wrap == 0);
1157 1157
1158 return 0; 1158 return 0;
1159} 1159}
1160 1160
1161/* Core configuration */ 1161/* Core configuration */
1162int 1162int
1163bwfm_chip_set_active(struct bwfm_softc *sc, const uint32_t rstvec) 1163bwfm_chip_set_active(struct bwfm_softc *sc, const uint32_t rstvec)
1164{ 1164{
1165 if (bwfm_chip_get_core(sc, BWFM_AGENT_CORE_ARM_CR4) != NULL) 1165 if (bwfm_chip_get_core(sc, BWFM_AGENT_CORE_ARM_CR4) != NULL)
1166 return bwfm_chip_cr4_set_active(sc, rstvec); 1166 return bwfm_chip_cr4_set_active(sc, rstvec);
1167 if (bwfm_chip_get_core(sc, BWFM_AGENT_CORE_ARM_CA7) != NULL) 1167 if (bwfm_chip_get_core(sc, BWFM_AGENT_CORE_ARM_CA7) != NULL)
1168 return bwfm_chip_ca7_set_active(sc, rstvec); 1168 return bwfm_chip_ca7_set_active(sc, rstvec);
1169 if (bwfm_chip_get_core(sc, BWFM_AGENT_CORE_ARM_CM3) != NULL) 1169 if (bwfm_chip_get_core(sc, BWFM_AGENT_CORE_ARM_CM3) != NULL)
1170 return bwfm_chip_cm3_set_active(sc); 1170 return bwfm_chip_cm3_set_active(sc);
1171 return 1; 1171 return 1;
1172} 1172}
1173 1173
1174void 1174void
1175bwfm_chip_set_passive(struct bwfm_softc *sc) 1175bwfm_chip_set_passive(struct bwfm_softc *sc)
1176{ 1176{
1177 if (bwfm_chip_get_core(sc, BWFM_AGENT_CORE_ARM_CR4) != NULL) { 1177 if (bwfm_chip_get_core(sc, BWFM_AGENT_CORE_ARM_CR4) != NULL) {
1178 bwfm_chip_cr4_set_passive(sc); 1178 bwfm_chip_cr4_set_passive(sc);
1179 return; 1179 return;
1180 } 1180 }
1181 if (bwfm_chip_get_core(sc, BWFM_AGENT_CORE_ARM_CA7) != NULL) { 1181 if (bwfm_chip_get_core(sc, BWFM_AGENT_CORE_ARM_CA7) != NULL) {
1182 bwfm_chip_ca7_set_passive(sc); 1182 bwfm_chip_ca7_set_passive(sc);
1183 return; 1183 return;
1184 } 1184 }
1185 if (bwfm_chip_get_core(sc, BWFM_AGENT_CORE_ARM_CM3) != NULL) { 1185 if (bwfm_chip_get_core(sc, BWFM_AGENT_CORE_ARM_CM3) != NULL) {
1186 bwfm_chip_cm3_set_passive(sc); 1186 bwfm_chip_cm3_set_passive(sc);
1187 return; 1187 return;
1188 } 1188 }
1189} 1189}
1190 1190
1191int 1191int
1192bwfm_chip_cr4_set_active(struct bwfm_softc *sc, const uint32_t rstvec) 1192bwfm_chip_cr4_set_active(struct bwfm_softc *sc, const uint32_t rstvec)
1193{ 1193{
1194 struct bwfm_core *core; 1194 struct bwfm_core *core;
1195 1195
1196 sc->sc_buscore_ops->bc_activate(sc, rstvec); 1196 sc->sc_buscore_ops->bc_activate(sc, rstvec);
1197 core = bwfm_chip_get_core(sc, BWFM_AGENT_CORE_ARM_CR4); 1197 core = bwfm_chip_get_core(sc, BWFM_AGENT_CORE_ARM_CR4);
1198 sc->sc_chip.ch_core_reset(sc, core, 1198 sc->sc_chip.ch_core_reset(sc, core,
1199 BWFM_AGENT_IOCTL_ARMCR4_CPUHALT, 0, 0); 1199 BWFM_AGENT_IOCTL_ARMCR4_CPUHALT, 0, 0);
1200 1200
1201 return 0; 1201 return 0;
1202} 1202}
1203 1203
1204void 1204void
1205bwfm_chip_cr4_set_passive(struct bwfm_softc *sc) 1205bwfm_chip_cr4_set_passive(struct bwfm_softc *sc)
1206{ 1206{
1207 struct bwfm_core *core; 1207 struct bwfm_core *core;
1208 uint32_t val; 1208 uint32_t val;
1209 1209
1210 core = bwfm_chip_get_core(sc, BWFM_AGENT_CORE_ARM_CR4); 1210 core = bwfm_chip_get_core(sc, BWFM_AGENT_CORE_ARM_CR4);
1211 val = sc->sc_buscore_ops->bc_read(sc, 1211 val = sc->sc_buscore_ops->bc_read(sc,
1212 core->co_wrapbase + BWFM_AGENT_IOCTL); 1212 core->co_wrapbase + BWFM_AGENT_IOCTL);
1213 sc->sc_chip.ch_core_reset(sc, core, 1213 sc->sc_chip.ch_core_reset(sc, core,
1214 val & BWFM_AGENT_IOCTL_ARMCR4_CPUHALT, 1214 val & BWFM_AGENT_IOCTL_ARMCR4_CPUHALT,
1215 BWFM_AGENT_IOCTL_ARMCR4_CPUHALT, 1215 BWFM_AGENT_IOCTL_ARMCR4_CPUHALT,
1216 BWFM_AGENT_IOCTL_ARMCR4_CPUHALT); 1216 BWFM_AGENT_IOCTL_ARMCR4_CPUHALT);
1217 1217
1218 core = bwfm_chip_get_core(sc, BWFM_AGENT_CORE_80211); 1218 core = bwfm_chip_get_core(sc, BWFM_AGENT_CORE_80211);
1219 sc->sc_chip.ch_core_reset(sc, core, BWFM_AGENT_D11_IOCTL_PHYRESET | 1219 sc->sc_chip.ch_core_reset(sc, core, BWFM_AGENT_D11_IOCTL_PHYRESET |
1220 BWFM_AGENT_D11_IOCTL_PHYCLOCKEN, BWFM_AGENT_D11_IOCTL_PHYCLOCKEN, 1220 BWFM_AGENT_D11_IOCTL_PHYCLOCKEN, BWFM_AGENT_D11_IOCTL_PHYCLOCKEN,
1221 BWFM_AGENT_D11_IOCTL_PHYCLOCKEN); 1221 BWFM_AGENT_D11_IOCTL_PHYCLOCKEN);
1222} 1222}
1223 1223
1224int 1224int
1225bwfm_chip_ca7_set_active(struct bwfm_softc *sc, const uint32_t rstvec) 1225bwfm_chip_ca7_set_active(struct bwfm_softc *sc, const uint32_t rstvec)
1226{ 1226{
1227 struct bwfm_core *core; 1227 struct bwfm_core *core;
1228 1228
1229 sc->sc_buscore_ops->bc_activate(sc, rstvec); 1229 sc->sc_buscore_ops->bc_activate(sc, rstvec);
1230 core = bwfm_chip_get_core(sc, BWFM_AGENT_CORE_ARM_CA7); 1230 core = bwfm_chip_get_core(sc, BWFM_AGENT_CORE_ARM_CA7);
1231 sc->sc_chip.ch_core_reset(sc, core, 1231 sc->sc_chip.ch_core_reset(sc, core,
1232 BWFM_AGENT_IOCTL_ARMCR4_CPUHALT, 0, 0); 1232 BWFM_AGENT_IOCTL_ARMCR4_CPUHALT, 0, 0);
1233 1233
1234 return 0; 1234 return 0;
1235} 1235}
1236 1236
1237void 1237void
1238bwfm_chip_ca7_set_passive(struct bwfm_softc *sc) 1238bwfm_chip_ca7_set_passive(struct bwfm_softc *sc)
1239{ 1239{
1240 struct bwfm_core *core; 1240 struct bwfm_core *core;
1241 uint32_t val; 1241 uint32_t val;
1242 1242
1243 core = bwfm_chip_get_core(sc, BWFM_AGENT_CORE_ARM_CA7); 1243 core = bwfm_chip_get_core(sc, BWFM_AGENT_CORE_ARM_CA7);
1244 val = sc->sc_buscore_ops->bc_read(sc, 1244 val = sc->sc_buscore_ops->bc_read(sc,
1245 core->co_wrapbase + BWFM_AGENT_IOCTL); 1245 core->co_wrapbase + BWFM_AGENT_IOCTL);
1246 sc->sc_chip.ch_core_reset(sc, core, 1246 sc->sc_chip.ch_core_reset(sc, core,
1247 val & BWFM_AGENT_IOCTL_ARMCR4_CPUHALT, 1247 val & BWFM_AGENT_IOCTL_ARMCR4_CPUHALT,
1248 BWFM_AGENT_IOCTL_ARMCR4_CPUHALT, 1248 BWFM_AGENT_IOCTL_ARMCR4_CPUHALT,
1249 BWFM_AGENT_IOCTL_ARMCR4_CPUHALT); 1249 BWFM_AGENT_IOCTL_ARMCR4_CPUHALT);
1250 1250
1251 core = bwfm_chip_get_core(sc, BWFM_AGENT_CORE_80211); 1251 core = bwfm_chip_get_core(sc, BWFM_AGENT_CORE_80211);
1252 sc->sc_chip.ch_core_reset(sc, core, BWFM_AGENT_D11_IOCTL_PHYRESET | 1252 sc->sc_chip.ch_core_reset(sc, core, BWFM_AGENT_D11_IOCTL_PHYRESET |
1253 BWFM_AGENT_D11_IOCTL_PHYCLOCKEN, BWFM_AGENT_D11_IOCTL_PHYCLOCKEN, 1253 BWFM_AGENT_D11_IOCTL_PHYCLOCKEN, BWFM_AGENT_D11_IOCTL_PHYCLOCKEN,
1254 BWFM_AGENT_D11_IOCTL_PHYCLOCKEN); 1254 BWFM_AGENT_D11_IOCTL_PHYCLOCKEN);
1255} 1255}
1256 1256
1257int 1257int
1258bwfm_chip_cm3_set_active(struct bwfm_softc *sc) 1258bwfm_chip_cm3_set_active(struct bwfm_softc *sc)
1259{ 1259{
1260 struct bwfm_core *core; 1260 struct bwfm_core *core;
1261 1261
1262 core = bwfm_chip_get_core(sc, BWFM_AGENT_INTERNAL_MEM); 1262 core = bwfm_chip_get_core(sc, BWFM_AGENT_INTERNAL_MEM);
1263 if (!sc->sc_chip.ch_core_isup(sc, core)) 1263 if (!sc->sc_chip.ch_core_isup(sc, core))
1264 return 1; 1264 return 1;
1265 1265
1266 sc->sc_buscore_ops->bc_activate(sc, 0); 1266 sc->sc_buscore_ops->bc_activate(sc, 0);
1267 1267
1268 core = bwfm_chip_get_core(sc, BWFM_AGENT_CORE_ARM_CM3); 1268 core = bwfm_chip_get_core(sc, BWFM_AGENT_CORE_ARM_CM3);
1269 sc->sc_chip.ch_core_reset(sc, core, 0, 0, 0); 1269 sc->sc_chip.ch_core_reset(sc, core, 0, 0, 0);
1270 1270
1271 return 0; 1271 return 0;
1272} 1272}
1273 1273
1274void 1274void
1275bwfm_chip_cm3_set_passive(struct bwfm_softc *sc) 1275bwfm_chip_cm3_set_passive(struct bwfm_softc *sc)
1276{ 1276{
1277 struct bwfm_core *core; 1277 struct bwfm_core *core;
1278 1278
1279 core = bwfm_chip_get_core(sc, BWFM_AGENT_CORE_ARM_CM3); 1279 core = bwfm_chip_get_core(sc, BWFM_AGENT_CORE_ARM_CM3);
1280 sc->sc_chip.ch_core_disable(sc, core, 0, 0); 1280 sc->sc_chip.ch_core_disable(sc, core, 0, 0);
1281 core = bwfm_chip_get_core(sc, BWFM_AGENT_CORE_80211); 1281 core = bwfm_chip_get_core(sc, BWFM_AGENT_CORE_80211);
1282 sc->sc_chip.ch_core_reset(sc, core, BWFM_AGENT_D11_IOCTL_PHYRESET | 1282 sc->sc_chip.ch_core_reset(sc, core, BWFM_AGENT_D11_IOCTL_PHYRESET |
1283 BWFM_AGENT_D11_IOCTL_PHYCLOCKEN, BWFM_AGENT_D11_IOCTL_PHYCLOCKEN, 1283 BWFM_AGENT_D11_IOCTL_PHYCLOCKEN, BWFM_AGENT_D11_IOCTL_PHYCLOCKEN,
1284 BWFM_AGENT_D11_IOCTL_PHYCLOCKEN); 1284 BWFM_AGENT_D11_IOCTL_PHYCLOCKEN);
1285 core = bwfm_chip_get_core(sc, BWFM_AGENT_INTERNAL_MEM); 1285 core = bwfm_chip_get_core(sc, BWFM_AGENT_INTERNAL_MEM);
1286 sc->sc_chip.ch_core_reset(sc, core, 0, 0, 0); 1286 sc->sc_chip.ch_core_reset(sc, core, 0, 0, 0);
1287 1287
1288 if (sc->sc_chip.ch_chip == BRCM_CC_43430_CHIP_ID) { 1288 if (sc->sc_chip.ch_chip == BRCM_CC_43430_CHIP_ID) {
1289 sc->sc_buscore_ops->bc_write(sc, 1289 sc->sc_buscore_ops->bc_write(sc,
1290 core->co_base + BWFM_SOCRAM_BANKIDX, 3); 1290 core->co_base + BWFM_SOCRAM_BANKIDX, 3);
1291 sc->sc_buscore_ops->bc_write(sc, 1291 sc->sc_buscore_ops->bc_write(sc,
1292 core->co_base + BWFM_SOCRAM_BANKPDA, 0); 1292 core->co_base + BWFM_SOCRAM_BANKPDA, 0);
1293 } 1293 }
1294} 1294}
1295 1295
1296int 1296int
1297bwfm_chip_sr_capable(struct bwfm_softc *sc) 1297bwfm_chip_sr_capable(struct bwfm_softc *sc)
1298{ 1298{
1299 struct bwfm_core *core; 1299 struct bwfm_core *core;
1300 uint32_t reg; 1300 uint32_t reg;
1301 1301
1302 if (sc->sc_chip.ch_pmurev < 17) 1302 if (sc->sc_chip.ch_pmurev < 17)
1303 return 0; 1303 return 0;
1304 1304
1305 switch (sc->sc_chip.ch_chip) { 1305 switch (sc->sc_chip.ch_chip) {
1306 case BRCM_CC_4345_CHIP_ID: 1306 case BRCM_CC_4345_CHIP_ID:
1307 case BRCM_CC_4354_CHIP_ID: 1307 case BRCM_CC_4354_CHIP_ID:
1308 case BRCM_CC_4356_CHIP_ID: 1308 case BRCM_CC_4356_CHIP_ID:
1309 core = bwfm_chip_get_pmu(sc); 1309 core = bwfm_chip_get_pmu(sc);
1310 sc->sc_buscore_ops->bc_write(sc, core->co_base + 1310 sc->sc_buscore_ops->bc_write(sc, core->co_base +
1311 BWFM_CHIP_REG_CHIPCONTROL_ADDR, 3); 1311 BWFM_CHIP_REG_CHIPCONTROL_ADDR, 3);
1312 reg = sc->sc_buscore_ops->bc_read(sc, core->co_base + 1312 reg = sc->sc_buscore_ops->bc_read(sc, core->co_base +
1313 BWFM_CHIP_REG_CHIPCONTROL_DATA); 1313 BWFM_CHIP_REG_CHIPCONTROL_DATA);
1314 return (reg & (1 << 2)) != 0; 1314 return (reg & (1 << 2)) != 0;
1315 case BRCM_CC_43241_CHIP_ID: 1315 case BRCM_CC_43241_CHIP_ID:
1316 case BRCM_CC_4335_CHIP_ID: 1316 case BRCM_CC_4335_CHIP_ID:
1317 case BRCM_CC_4339_CHIP_ID: 1317 case BRCM_CC_4339_CHIP_ID:
1318 core = bwfm_chip_get_pmu(sc); 1318 core = bwfm_chip_get_pmu(sc);
1319 sc->sc_buscore_ops->bc_write(sc, core->co_base + 1319 sc->sc_buscore_ops->bc_write(sc, core->co_base +
1320 BWFM_CHIP_REG_CHIPCONTROL_ADDR, 3); 1320 BWFM_CHIP_REG_CHIPCONTROL_ADDR, 3);
1321 reg = sc->sc_buscore_ops->bc_read(sc, core->co_base + 1321 reg = sc->sc_buscore_ops->bc_read(sc, core->co_base +
1322 BWFM_CHIP_REG_CHIPCONTROL_DATA); 1322 BWFM_CHIP_REG_CHIPCONTROL_DATA);
1323 return reg != 0; 1323 return reg != 0;
1324 case BRCM_CC_43430_CHIP_ID: 1324 case BRCM_CC_43430_CHIP_ID:
1325 core = bwfm_chip_get_core(sc, BWFM_AGENT_CORE_CHIPCOMMON); 1325 core = bwfm_chip_get_core(sc, BWFM_AGENT_CORE_CHIPCOMMON);
1326 reg = sc->sc_buscore_ops->bc_read(sc, core->co_base + 1326 reg = sc->sc_buscore_ops->bc_read(sc, core->co_base +
1327 BWFM_CHIP_REG_SR_CONTROL1); 1327 BWFM_CHIP_REG_SR_CONTROL1);
1328 return reg != 0; 1328 return reg != 0;
1329 default: 1329 default:
1330 core = bwfm_chip_get_pmu(sc); 1330 core = bwfm_chip_get_pmu(sc);
1331 reg = sc->sc_buscore_ops->bc_read(sc, core->co_base + 1331 reg = sc->sc_buscore_ops->bc_read(sc, core->co_base +
1332 BWFM_CHIP_REG_PMUCAPABILITIES_EXT); 1332 BWFM_CHIP_REG_PMUCAPABILITIES_EXT);
1333 if ((reg & BWFM_CHIP_REG_PMUCAPABILITIES_SR_SUPP) == 0) 1333 if ((reg & BWFM_CHIP_REG_PMUCAPABILITIES_SR_SUPP) == 0)
1334 return 0; 1334 return 0;
1335 reg = sc->sc_buscore_ops->bc_read(sc, core->co_base + 1335 reg = sc->sc_buscore_ops->bc_read(sc, core->co_base +
1336 BWFM_CHIP_REG_RETENTION_CTL); 1336 BWFM_CHIP_REG_RETENTION_CTL);
1337 return (reg & (BWFM_CHIP_REG_RETENTION_CTL_MACPHY_DIS | 1337 return (reg & (BWFM_CHIP_REG_RETENTION_CTL_MACPHY_DIS |
1338 BWFM_CHIP_REG_RETENTION_CTL_LOGIC_DIS)) == 0; 1338 BWFM_CHIP_REG_RETENTION_CTL_LOGIC_DIS)) == 0;
1339 } 1339 }
1340} 1340}
1341 1341
1342/* RAM size helpers */ 1342/* RAM size helpers */
1343void 1343void
1344bwfm_chip_socram_ramsize(struct bwfm_softc *sc, struct bwfm_core *core) 1344bwfm_chip_socram_ramsize(struct bwfm_softc *sc, struct bwfm_core *core)
1345{ 1345{
1346 uint32_t coreinfo, nb, lss, banksize, bankinfo; 1346 uint32_t coreinfo, nb, lss, banksize, bankinfo;
1347 uint32_t ramsize = 0, srsize = 0; 1347 uint32_t ramsize = 0, srsize = 0;
1348 int i; 1348 int i;
1349 1349
1350 if (!sc->sc_chip.ch_core_isup(sc, core)) 1350 if (!sc->sc_chip.ch_core_isup(sc, core))
1351 sc->sc_chip.ch_core_reset(sc, core, 0, 0, 0); 1351 sc->sc_chip.ch_core_reset(sc, core, 0, 0, 0);
1352 1352
1353 coreinfo = sc->sc_buscore_ops->bc_read(sc, 1353 coreinfo = sc->sc_buscore_ops->bc_read(sc,
1354 core->co_base + BWFM_SOCRAM_COREINFO); 1354 core->co_base + BWFM_SOCRAM_COREINFO);
1355 nb = (coreinfo & BWFM_SOCRAM_COREINFO_SRNB_MASK) 1355 nb = (coreinfo & BWFM_SOCRAM_COREINFO_SRNB_MASK)
1356 >> BWFM_SOCRAM_COREINFO_SRNB_SHIFT; 1356 >> BWFM_SOCRAM_COREINFO_SRNB_SHIFT;
1357 1357
1358 if (core->co_rev <= 7 || core->co_rev == 12) { 1358 if (core->co_rev <= 7 || core->co_rev == 12) {
1359 banksize = coreinfo & BWFM_SOCRAM_COREINFO_SRBSZ_MASK; 1359 banksize = coreinfo & BWFM_SOCRAM_COREINFO_SRBSZ_MASK;
1360 lss = (coreinfo & BWFM_SOCRAM_COREINFO_LSS_MASK) 1360 lss = (coreinfo & BWFM_SOCRAM_COREINFO_LSS_MASK)
1361 >> BWFM_SOCRAM_COREINFO_LSS_SHIFT; 1361 >> BWFM_SOCRAM_COREINFO_LSS_SHIFT;
1362 if (lss != 0) 1362 if (lss != 0)
1363 nb--; 1363 nb--;
1364 ramsize = nb * (1 << (banksize + BWFM_SOCRAM_COREINFO_SRBSZ_BASE)); 1364 ramsize = nb * (1 << (banksize + BWFM_SOCRAM_COREINFO_SRBSZ_BASE));
1365 if (lss != 0) 1365 if (lss != 0)
1366 ramsize += (1 << ((lss - 1) + BWFM_SOCRAM_COREINFO_SRBSZ_BASE)); 1366 ramsize += (1 << ((lss - 1) + BWFM_SOCRAM_COREINFO_SRBSZ_BASE));
1367 } else { 1367 } else {
1368 for (i = 0; i < nb; i++) { 1368 for (i = 0; i < nb; i++) {
1369 sc->sc_buscore_ops->bc_write(sc, 1369 sc->sc_buscore_ops->bc_write(sc,
1370 core->co_base + BWFM_SOCRAM_BANKIDX, 1370 core->co_base + BWFM_SOCRAM_BANKIDX,
1371 (BWFM_SOCRAM_BANKIDX_MEMTYPE_RAM << 1371 (BWFM_SOCRAM_BANKIDX_MEMTYPE_RAM <<
1372 BWFM_SOCRAM_BANKIDX_MEMTYPE_SHIFT) | i); 1372 BWFM_SOCRAM_BANKIDX_MEMTYPE_SHIFT) | i);
1373 bankinfo = sc->sc_buscore_ops->bc_read(sc, 1373 bankinfo = sc->sc_buscore_ops->bc_read(sc,
1374 core->co_base + BWFM_SOCRAM_BANKINFO); 1374 core->co_base + BWFM_SOCRAM_BANKINFO);
1375 banksize = ((bankinfo & BWFM_SOCRAM_BANKINFO_SZMASK) + 1) 1375 banksize = ((bankinfo & BWFM_SOCRAM_BANKINFO_SZMASK) + 1)
1376 * BWFM_SOCRAM_BANKINFO_SZBASE; 1376 * BWFM_SOCRAM_BANKINFO_SZBASE;
1377 ramsize += banksize; 1377 ramsize += banksize;
1378 if (bankinfo & BWFM_SOCRAM_BANKINFO_RETNTRAM_MASK) 1378 if (bankinfo & BWFM_SOCRAM_BANKINFO_RETNTRAM_MASK)
1379 srsize += banksize; 1379 srsize += banksize;
1380 } 1380 }
1381 } 1381 }
1382 1382
1383 switch (sc->sc_chip.ch_chip) { 1383 switch (sc->sc_chip.ch_chip) {
1384 case BRCM_CC_4334_CHIP_ID: 1384 case BRCM_CC_4334_CHIP_ID:
1385 if (sc->sc_chip.ch_chiprev < 2) 1385 if (sc->sc_chip.ch_chiprev < 2)
1386 srsize = 32 * 1024; 1386 srsize = 32 * 1024;
1387 break; 1387 break;
1388 case BRCM_CC_43430_CHIP_ID: 1388 case BRCM_CC_43430_CHIP_ID:
1389 srsize = 64 * 1024; 1389 srsize = 64 * 1024;
1390 break; 1390 break;
1391 default: 1391 default:
1392 break; 1392 break;
1393 } 1393 }
1394 1394
1395 sc->sc_chip.ch_ramsize = ramsize; 1395 sc->sc_chip.ch_ramsize = ramsize;
1396 sc->sc_chip.ch_srsize = srsize; 1396 sc->sc_chip.ch_srsize = srsize;
1397} 1397}
1398 1398
1399void 1399void
1400bwfm_chip_sysmem_ramsize(struct bwfm_softc *sc, struct bwfm_core *core) 1400bwfm_chip_sysmem_ramsize(struct bwfm_softc *sc, struct bwfm_core *core)
1401{ 1401{
1402 uint32_t coreinfo, nb, banksize, bankinfo; 1402 uint32_t coreinfo, nb, banksize, bankinfo;
1403 uint32_t ramsize = 0; 1403 uint32_t ramsize = 0;
1404 int i; 1404 int i;
1405 1405
1406 if (!sc->sc_chip.ch_core_isup(sc, core)) 1406 if (!sc->sc_chip.ch_core_isup(sc, core))
1407 sc->sc_chip.ch_core_reset(sc, core, 0, 0, 0); 1407 sc->sc_chip.ch_core_reset(sc, core, 0, 0, 0);
1408 1408
1409 coreinfo = sc->sc_buscore_ops->bc_read(sc, 1409 coreinfo = sc->sc_buscore_ops->bc_read(sc,
1410 core->co_base + BWFM_SOCRAM_COREINFO); 1410 core->co_base + BWFM_SOCRAM_COREINFO);
1411 nb = (coreinfo & BWFM_SOCRAM_COREINFO_SRNB_MASK) 1411 nb = (coreinfo & BWFM_SOCRAM_COREINFO_SRNB_MASK)
1412 >> BWFM_SOCRAM_COREINFO_SRNB_SHIFT; 1412 >> BWFM_SOCRAM_COREINFO_SRNB_SHIFT;
1413 1413
1414 for (i = 0; i < nb; i++) { 1414 for (i = 0; i < nb; i++) {
1415 sc->sc_buscore_ops->bc_write(sc, 1415 sc->sc_buscore_ops->bc_write(sc,
1416 core->co_base + BWFM_SOCRAM_BANKIDX, 1416 core->co_base + BWFM_SOCRAM_BANKIDX,
1417 (BWFM_SOCRAM_BANKIDX_MEMTYPE_RAM << 1417 (BWFM_SOCRAM_BANKIDX_MEMTYPE_RAM <<
1418 BWFM_SOCRAM_BANKIDX_MEMTYPE_SHIFT) | i); 1418 BWFM_SOCRAM_BANKIDX_MEMTYPE_SHIFT) | i);
1419 bankinfo = sc->sc_buscore_ops->bc_read(sc, 1419 bankinfo = sc->sc_buscore_ops->bc_read(sc,
1420 core->co_base + BWFM_SOCRAM_BANKINFO); 1420 core->co_base + BWFM_SOCRAM_BANKINFO);
1421 banksize = ((bankinfo & BWFM_SOCRAM_BANKINFO_SZMASK) + 1) 1421 banksize = ((bankinfo & BWFM_SOCRAM_BANKINFO_SZMASK) + 1)
1422 * BWFM_SOCRAM_BANKINFO_SZBASE; 1422 * BWFM_SOCRAM_BANKINFO_SZBASE;
1423 ramsize += banksize; 1423 ramsize += banksize;
1424 } 1424 }
1425 1425
1426 sc->sc_chip.ch_ramsize = ramsize; 1426 sc->sc_chip.ch_ramsize = ramsize;
1427} 1427}
1428 1428
1429void 1429void
1430bwfm_chip_tcm_ramsize(struct bwfm_softc *sc, struct bwfm_core *core) 1430bwfm_chip_tcm_ramsize(struct bwfm_softc *sc, struct bwfm_core *core)
1431{ 1431{
1432 uint32_t cap, nab, nbb, totb, bxinfo, ramsize = 0; 1432 uint32_t cap, nab, nbb, totb, bxinfo, ramsize = 0;
1433 int i; 1433 int i;
1434 1434
1435 cap = sc->sc_buscore_ops->bc_read(sc, core->co_base + BWFM_ARMCR4_CAP); 1435 cap = sc->sc_buscore_ops->bc_read(sc, core->co_base + BWFM_ARMCR4_CAP);
1436 nab = (cap & BWFM_ARMCR4_CAP_TCBANB_MASK) >> BWFM_ARMCR4_CAP_TCBANB_SHIFT; 1436 nab = (cap & BWFM_ARMCR4_CAP_TCBANB_MASK) >> BWFM_ARMCR4_CAP_TCBANB_SHIFT;
1437 nbb = (cap & BWFM_ARMCR4_CAP_TCBBNB_MASK) >> BWFM_ARMCR4_CAP_TCBBNB_SHIFT; 1437 nbb = (cap & BWFM_ARMCR4_CAP_TCBBNB_MASK) >> BWFM_ARMCR4_CAP_TCBBNB_SHIFT;
1438 totb = nab + nbb; 1438 totb = nab + nbb;
1439 1439
1440 for (i = 0; i < totb; i++) { 1440 for (i = 0; i < totb; i++) {
1441 sc->sc_buscore_ops->bc_write(sc, 1441 sc->sc_buscore_ops->bc_write(sc,
1442 core->co_base + BWFM_ARMCR4_BANKIDX, i); 1442 core->co_base + BWFM_ARMCR4_BANKIDX, i);
1443 bxinfo = sc->sc_buscore_ops->bc_read(sc, 1443 bxinfo = sc->sc_buscore_ops->bc_read(sc,
1444 core->co_base + BWFM_ARMCR4_BANKINFO); 1444 core->co_base + BWFM_ARMCR4_BANKINFO);
1445 ramsize += ((bxinfo & BWFM_ARMCR4_BANKINFO_BSZ_MASK) + 1) * 1445 ramsize += ((bxinfo & BWFM_ARMCR4_BANKINFO_BSZ_MASK) + 1) *
1446 BWFM_ARMCR4_BANKINFO_BSZ_MULT; 1446 BWFM_ARMCR4_BANKINFO_BSZ_MULT;
1447 } 1447 }
1448 1448
1449 sc->sc_chip.ch_ramsize = ramsize; 1449 sc->sc_chip.ch_ramsize = ramsize;
1450} 1450}
1451 1451
1452void 1452void
1453bwfm_chip_tcm_rambase(struct bwfm_softc *sc) 1453bwfm_chip_tcm_rambase(struct bwfm_softc *sc)
1454{ 1454{
1455 switch (sc->sc_chip.ch_chip) { 1455 switch (sc->sc_chip.ch_chip) {
1456 case BRCM_CC_4345_CHIP_ID: 1456 case BRCM_CC_4345_CHIP_ID:
1457 sc->sc_chip.ch_rambase = 0x198000; 1457 sc->sc_chip.ch_rambase = 0x198000;
1458 break; 1458 break;
1459 case BRCM_CC_4335_CHIP_ID: 1459 case BRCM_CC_4335_CHIP_ID:
1460 case BRCM_CC_4339_CHIP_ID: 1460 case BRCM_CC_4339_CHIP_ID:
1461 case BRCM_CC_4350_CHIP_ID: 1461 case BRCM_CC_4350_CHIP_ID:
1462 case BRCM_CC_4354_CHIP_ID: 1462 case BRCM_CC_4354_CHIP_ID:
1463 case BRCM_CC_4356_CHIP_ID: 1463 case BRCM_CC_4356_CHIP_ID:
1464 case BRCM_CC_43567_CHIP_ID: 1464 case BRCM_CC_43567_CHIP_ID:
1465 case BRCM_CC_43569_CHIP_ID: 1465 case BRCM_CC_43569_CHIP_ID:
1466 case BRCM_CC_43570_CHIP_ID: 1466 case BRCM_CC_43570_CHIP_ID:
1467 case BRCM_CC_4358_CHIP_ID: 1467 case BRCM_CC_4358_CHIP_ID:
1468 case BRCM_CC_4359_CHIP_ID: 1468 case BRCM_CC_4359_CHIP_ID:
1469 case BRCM_CC_43602_CHIP_ID: 1469 case BRCM_CC_43602_CHIP_ID:
1470 case BRCM_CC_4371_CHIP_ID: 1470 case BRCM_CC_4371_CHIP_ID:
1471 sc->sc_chip.ch_rambase = 0x180000; 1471 sc->sc_chip.ch_rambase = 0x180000;
1472 break; 1472 break;
1473 case BRCM_CC_43465_CHIP_ID: 1473 case BRCM_CC_43465_CHIP_ID:
1474 case BRCM_CC_43525_CHIP_ID: 1474 case BRCM_CC_43525_CHIP_ID:
1475 case BRCM_CC_4365_CHIP_ID: 1475 case BRCM_CC_4365_CHIP_ID:
1476 case BRCM_CC_4366_CHIP_ID: 1476 case BRCM_CC_4366_CHIP_ID:
1477 sc->sc_chip.ch_rambase = 0x200000; 1477 sc->sc_chip.ch_rambase = 0x200000;
1478 break; 1478 break;
1479 case CY_CC_4373_CHIP_ID: 1479 case CY_CC_4373_CHIP_ID:
1480 sc->sc_chip.ch_rambase = 0x160000; 1480 sc->sc_chip.ch_rambase = 0x160000;
1481 break; 1481 break;
1482 default: 1482 default:
1483 printf("%s: unknown chip: %d\n", DEVNAME(sc), 1483 printf("%s: unknown chip: %d\n", DEVNAME(sc),
1484 sc->sc_chip.ch_chip); 1484 sc->sc_chip.ch_chip);
1485 break; 1485 break;
1486 } 1486 }
1487} 1487}
1488 1488
1489/* BCDC protocol implementation */ 1489/* BCDC protocol implementation */
1490int 1490int
1491bwfm_proto_bcdc_query_dcmd(struct bwfm_softc *sc, int ifidx, 1491bwfm_proto_bcdc_query_dcmd(struct bwfm_softc *sc, int ifidx,
1492 int cmd, char *buf, size_t *len) 1492 int cmd, char *buf, size_t *len)
1493{ 1493{
1494 struct bwfm_proto_bcdc_dcmd *dcmd; 1494 struct bwfm_proto_bcdc_dcmd *dcmd;
1495 size_t size = sizeof(dcmd->hdr) + *len; 1495 size_t size = sizeof(dcmd->hdr) + *len;
1496 int reqid; 1496 int reqid;
1497 int ret = 1; 1497 int ret = 1;
1498 1498
1499 reqid = sc->sc_bcdc_reqid++; 1499 reqid = sc->sc_bcdc_reqid++;
1500 1500
1501 dcmd = kmem_zalloc(sizeof(*dcmd), KM_SLEEP); 1501 dcmd = kmem_zalloc(sizeof(*dcmd), KM_SLEEP);
1502 if (*len > sizeof(dcmd->buf)) 1502 if (*len > sizeof(dcmd->buf))
1503 goto err; 1503 goto err;
1504 1504
1505 dcmd->hdr.cmd = htole32(cmd); 1505 dcmd->hdr.cmd = htole32(cmd);
1506 dcmd->hdr.len = htole32(*len); 1506 dcmd->hdr.len = htole32(*len);
1507 dcmd->hdr.flags |= BWFM_BCDC_DCMD_GET; 1507 dcmd->hdr.flags |= BWFM_BCDC_DCMD_GET;
1508 dcmd->hdr.flags |= BWFM_BCDC_DCMD_ID_SET(reqid); 1508 dcmd->hdr.flags |= BWFM_BCDC_DCMD_ID_SET(reqid);
1509 dcmd->hdr.flags |= BWFM_BCDC_DCMD_IF_SET(ifidx); 1509 dcmd->hdr.flags |= BWFM_BCDC_DCMD_IF_SET(ifidx);
1510 dcmd->hdr.flags = htole32(dcmd->hdr.flags); 1510 dcmd->hdr.flags = htole32(dcmd->hdr.flags);
1511 memcpy(&dcmd->buf, buf, *len); 1511 memcpy(&dcmd->buf, buf, *len);
1512 1512
1513 if (sc->sc_bus_ops->bs_txctl(sc, (void *)dcmd, 1513 if (sc->sc_bus_ops->bs_txctl(sc, (void *)dcmd,

cvs diff -r1.36 -r1.37 src/sys/dev/ic/bwi.c (switch to unified diff)

--- src/sys/dev/ic/bwi.c 2018/12/22 14:07:53 1.36
+++ src/sys/dev/ic/bwi.c 2020/01/29 14:14:55 1.37
@@ -1,1050 +1,1050 @@ @@ -1,1050 +1,1050 @@
1/* $NetBSD: bwi.c,v 1.36 2018/12/22 14:07:53 maxv Exp $ */ 1/* $NetBSD: bwi.c,v 1.37 2020/01/29 14:14:55 thorpej Exp $ */
2/* $OpenBSD: bwi.c,v 1.74 2008/02/25 21:13:30 mglocker Exp $ */ 2/* $OpenBSD: bwi.c,v 1.74 2008/02/25 21:13:30 mglocker Exp $ */
3 3
4/* 4/*
5 * Copyright (c) 2007 The DragonFly Project. All rights reserved. 5 * Copyright (c) 2007 The DragonFly Project. All rights reserved.
6 *  6 *
7 * This code is derived from software contributed to The DragonFly Project 7 * This code is derived from software contributed to The DragonFly Project
8 * by Sepherosa Ziehau <sepherosa@gmail.com> 8 * by Sepherosa Ziehau <sepherosa@gmail.com>
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 *  13 *
14 * 1. Redistributions of source code must retain the above copyright 14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer. 15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright 16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in 17 * notice, this list of conditions and the following disclaimer in
18 * the documentation and/or other materials provided with the 18 * the documentation and/or other materials provided with the
19 * distribution. 19 * distribution.
20 * 3. Neither the name of The DragonFly Project nor the names of its 20 * 3. Neither the name of The DragonFly Project nor the names of its
21 * contributors may be used to endorse or promote products derived 21 * contributors may be used to endorse or promote products derived
22 * from this software without specific, prior written permission. 22 * from this software without specific, prior written permission.
23 *  23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 26 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
27 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 27 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
28 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 28 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
29 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 29 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
30 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 30 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 31 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
32 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 32 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
33 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 33 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
34 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE. 35 * SUCH DAMAGE.
36 *  36 *
37 * $DragonFly: src/sys/dev/netif/bwi/bwimac.c,v 1.1 2007/09/08 06:15:54 sephe Exp $ 37 * $DragonFly: src/sys/dev/netif/bwi/bwimac.c,v 1.1 2007/09/08 06:15:54 sephe Exp $
38 */ 38 */
39 39
40/* 40/*
41 * Broadcom AirForce BCM43xx IEEE 802.11b/g wireless network driver 41 * Broadcom AirForce BCM43xx IEEE 802.11b/g wireless network driver
42 * Generic back end 42 * Generic back end
43 */ 43 */
44 44
45/* [TRC: XXX Names beginning with `bwi_ieee80211_*' are those that I 45/* [TRC: XXX Names beginning with `bwi_ieee80211_*' are those that I
46 think should be in NetBSD's generic 802.11 code, not in this 46 think should be in NetBSD's generic 802.11 code, not in this
47 driver.] */ 47 driver.] */
48 48
49 49
50#include <sys/cdefs.h> 50#include <sys/cdefs.h>
51__KERNEL_RCSID(0, "$NetBSD: bwi.c,v 1.36 2018/12/22 14:07:53 maxv Exp $"); 51__KERNEL_RCSID(0, "$NetBSD: bwi.c,v 1.37 2020/01/29 14:14:55 thorpej Exp $");
52 52
53#include <sys/param.h> 53#include <sys/param.h>
54#include <sys/callout.h> 54#include <sys/callout.h>
55#include <sys/device.h> 55#include <sys/device.h>
56#include <sys/kernel.h> 56#include <sys/kernel.h>
57#include <sys/malloc.h> 57#include <sys/malloc.h>
58#include <sys/mbuf.h> 58#include <sys/mbuf.h>
59#include <sys/socket.h> 59#include <sys/socket.h>
60#include <sys/sockio.h> 60#include <sys/sockio.h>
61#include <sys/sysctl.h> 61#include <sys/sysctl.h>
62#include <sys/systm.h> 62#include <sys/systm.h>
63#include <sys/bus.h> 63#include <sys/bus.h>
64#include <sys/intr.h> 64#include <sys/intr.h>
65 65
66#include <machine/endian.h> 66#include <machine/endian.h>
67 67
68#include <dev/firmload.h> 68#include <dev/firmload.h>
69 69
70#include <net/if.h> 70#include <net/if.h>
71#include <net/if_dl.h> 71#include <net/if_dl.h>
72#include <net/if_ether.h> 72#include <net/if_ether.h>
73#include <net/if_media.h> 73#include <net/if_media.h>
74 74
75#include <net/bpf.h> 75#include <net/bpf.h>
76 76
77#include <net80211/ieee80211_var.h> 77#include <net80211/ieee80211_var.h>
78/* [TRC: XXX amrr] */ 78/* [TRC: XXX amrr] */
79#include <net80211/ieee80211_amrr.h> 79#include <net80211/ieee80211_amrr.h>
80#include <net80211/ieee80211_radiotap.h> 80#include <net80211/ieee80211_radiotap.h>
81 81
82#include <dev/ic/bwireg.h> 82#include <dev/ic/bwireg.h>
83#include <dev/ic/bwivar.h> 83#include <dev/ic/bwivar.h>
84 84
85#ifdef BWI_DEBUG 85#ifdef BWI_DEBUG
86int bwi_debug = 0; 86int bwi_debug = 0;
87 87
88#define DPRINTF(sc, dbg, fmt, ...) \ 88#define DPRINTF(sc, dbg, fmt, ...) \
89do { \ 89do { \
90 if ((sc)->sc_debug & (dbg)) \ 90 if ((sc)->sc_debug & (dbg)) \
91 aprint_debug_dev((sc)->sc_dev, fmt, ##__VA_ARGS__); \ 91 aprint_debug_dev((sc)->sc_dev, fmt, ##__VA_ARGS__); \
92} while (0) 92} while (0)
93 93
94#else /* !BWI_DEBUG */ 94#else /* !BWI_DEBUG */
95 95
96#define DPRINTF(sc, dbg, fmt, ...) ((void)0) 96#define DPRINTF(sc, dbg, fmt, ...) ((void)0)
97 97
98#endif /* BWI_DEBUG */ 98#endif /* BWI_DEBUG */
99 99
100/* XXX temporary porting goop */ 100/* XXX temporary porting goop */
101#include <dev/pci/pcireg.h> 101#include <dev/pci/pcireg.h>
102#include <dev/pci/pcivar.h> 102#include <dev/pci/pcivar.h>
103#include <dev/pci/pcidevs.h> 103#include <dev/pci/pcidevs.h>
104 104
105/* XXX does not belong here */ 105/* XXX does not belong here */
106#define IEEE80211_OFDM_PLCP_RATE_MASK 0x0000000f 106#define IEEE80211_OFDM_PLCP_RATE_MASK 0x0000000f
107#define IEEE80211_OFDM_PLCP_LEN_MASK 0x0001ffe0 107#define IEEE80211_OFDM_PLCP_LEN_MASK 0x0001ffe0
108 108
109/* 109/*
110 * Contention window (slots). [TRC: dfly/net80211/80211.h] 110 * Contention window (slots). [TRC: dfly/net80211/80211.h]
111 */ 111 */
112#define IEEE80211_CW_MAX 1023 /* aCWmax */ 112#define IEEE80211_CW_MAX 1023 /* aCWmax */
113#define IEEE80211_CW_MIN_0 31 /* DS/CCK aCWmin, ERP aCWmin(0) */ 113#define IEEE80211_CW_MIN_0 31 /* DS/CCK aCWmin, ERP aCWmin(0) */
114#define IEEE80211_CW_MIN_1 15 /* OFDM aCWmin, ERP aCWmin(1) */ 114#define IEEE80211_CW_MIN_1 15 /* OFDM aCWmin, ERP aCWmin(1) */
115 115
116/* 116/*
117 * Slot time (microseconds). [TRC: dfly/net80211/80211.h] 117 * Slot time (microseconds). [TRC: dfly/net80211/80211.h]
118 */ 118 */
119#define IEEE80211_DUR_SLOT 20 /* DS/CCK slottime, ERP long slottime */ 119#define IEEE80211_DUR_SLOT 20 /* DS/CCK slottime, ERP long slottime */
120#define IEEE80211_DUR_SHSLOT 9 /* ERP short slottime */ 120#define IEEE80211_DUR_SHSLOT 9 /* ERP short slottime */
121#define IEEE80211_DUR_OFDM_SLOT 9 /* OFDM slottime */ 121#define IEEE80211_DUR_OFDM_SLOT 9 /* OFDM slottime */
122 122
123/* XXX end porting goop */ 123/* XXX end porting goop */
124 124
125/* MAC */ 125/* MAC */
126struct bwi_retry_lim { 126struct bwi_retry_lim {
127 uint16_t shretry; 127 uint16_t shretry;
128 uint16_t shretry_fb; 128 uint16_t shretry_fb;
129 uint16_t lgretry; 129 uint16_t lgretry;
130 uint16_t lgretry_fb; 130 uint16_t lgretry_fb;
131}; 131};
132 132
133struct bwi_clock_freq { 133struct bwi_clock_freq {
134 uint clkfreq_min; 134 uint clkfreq_min;
135 uint clkfreq_max; 135 uint clkfreq_max;
136}; 136};
137 137
138/* XXX does not belong here */ 138/* XXX does not belong here */
139struct ieee80211_ds_plcp_hdr { 139struct ieee80211_ds_plcp_hdr {
140 uint8_t i_signal; 140 uint8_t i_signal;
141 uint8_t i_service; 141 uint8_t i_service;
142 uint16_t i_length; 142 uint16_t i_length;
143 uint16_t i_crc; 143 uint16_t i_crc;
144} __packed; 144} __packed;
145 145
146static void bwi_sysctlattach(struct bwi_softc *); 146static void bwi_sysctlattach(struct bwi_softc *);
147 147
148/* MAC */ 148/* MAC */
149static void bwi_tmplt_write_4(struct bwi_mac *, uint32_t, uint32_t); 149static void bwi_tmplt_write_4(struct bwi_mac *, uint32_t, uint32_t);
150static void bwi_hostflags_write(struct bwi_mac *, uint64_t); 150static void bwi_hostflags_write(struct bwi_mac *, uint64_t);
151static uint64_t bwi_hostflags_read(struct bwi_mac *); 151static uint64_t bwi_hostflags_read(struct bwi_mac *);
152static uint16_t bwi_memobj_read_2(struct bwi_mac *, uint16_t, uint16_t); 152static uint16_t bwi_memobj_read_2(struct bwi_mac *, uint16_t, uint16_t);
153static uint32_t bwi_memobj_read_4(struct bwi_mac *, uint16_t, uint16_t); 153static uint32_t bwi_memobj_read_4(struct bwi_mac *, uint16_t, uint16_t);
154static void bwi_memobj_write_2(struct bwi_mac *, uint16_t, uint16_t, 154static void bwi_memobj_write_2(struct bwi_mac *, uint16_t, uint16_t,
155 uint16_t); 155 uint16_t);
156static void bwi_memobj_write_4(struct bwi_mac *, uint16_t, uint16_t, 156static void bwi_memobj_write_4(struct bwi_mac *, uint16_t, uint16_t,
157 uint32_t); 157 uint32_t);
158static int bwi_mac_lateattach(struct bwi_mac *); 158static int bwi_mac_lateattach(struct bwi_mac *);
159static int bwi_mac_init(struct bwi_mac *); 159static int bwi_mac_init(struct bwi_mac *);
160static void bwi_mac_reset(struct bwi_mac *, int); 160static void bwi_mac_reset(struct bwi_mac *, int);
161static void bwi_mac_set_tpctl_11bg(struct bwi_mac *, 161static void bwi_mac_set_tpctl_11bg(struct bwi_mac *,
162 const struct bwi_tpctl *); 162 const struct bwi_tpctl *);
163static int bwi_mac_test(struct bwi_mac *); 163static int bwi_mac_test(struct bwi_mac *);
164static void bwi_mac_setup_tpctl(struct bwi_mac *); 164static void bwi_mac_setup_tpctl(struct bwi_mac *);
165static void bwi_mac_dummy_xmit(struct bwi_mac *); 165static void bwi_mac_dummy_xmit(struct bwi_mac *);
166static void bwi_mac_init_tpctl_11bg(struct bwi_mac *); 166static void bwi_mac_init_tpctl_11bg(struct bwi_mac *);
167static void bwi_mac_detach(struct bwi_mac *); 167static void bwi_mac_detach(struct bwi_mac *);
168static int bwi_mac_fw_alloc(struct bwi_mac *); 168static int bwi_mac_fw_alloc(struct bwi_mac *);
169static void bwi_mac_fw_free(struct bwi_mac *); 169static void bwi_mac_fw_free(struct bwi_mac *);
170static int bwi_mac_fw_image_alloc(struct bwi_mac *, const char *, 170static int bwi_mac_fw_image_alloc(struct bwi_mac *, const char *,
171 int idx, struct bwi_fw_image *, uint8_t); 171 int idx, struct bwi_fw_image *, uint8_t);
172static void bwi_mac_fw_image_free(struct bwi_mac *, struct bwi_fw_image *); 172static void bwi_mac_fw_image_free(struct bwi_mac *, struct bwi_fw_image *);
173static int bwi_mac_fw_load(struct bwi_mac *); 173static int bwi_mac_fw_load(struct bwi_mac *);
174static int bwi_mac_gpio_init(struct bwi_mac *); 174static int bwi_mac_gpio_init(struct bwi_mac *);
175static int bwi_mac_gpio_fini(struct bwi_mac *); 175static int bwi_mac_gpio_fini(struct bwi_mac *);
176static int bwi_mac_fw_load_iv(struct bwi_mac *, 176static int bwi_mac_fw_load_iv(struct bwi_mac *,
177 const struct bwi_fw_image *); 177 const struct bwi_fw_image *);
178static int bwi_mac_fw_init(struct bwi_mac *); 178static int bwi_mac_fw_init(struct bwi_mac *);
179static void bwi_mac_opmode_init(struct bwi_mac *); 179static void bwi_mac_opmode_init(struct bwi_mac *);
180static void bwi_mac_hostflags_init(struct bwi_mac *); 180static void bwi_mac_hostflags_init(struct bwi_mac *);
181static void bwi_mac_bss_param_init(struct bwi_mac *); 181static void bwi_mac_bss_param_init(struct bwi_mac *);
182static void bwi_mac_set_retry_lim(struct bwi_mac *, 182static void bwi_mac_set_retry_lim(struct bwi_mac *,
183 const struct bwi_retry_lim *); 183 const struct bwi_retry_lim *);
184static void bwi_mac_set_ackrates(struct bwi_mac *, 184static void bwi_mac_set_ackrates(struct bwi_mac *,
185 const struct ieee80211_rateset *); 185 const struct ieee80211_rateset *);
186static int bwi_mac_start(struct bwi_mac *); 186static int bwi_mac_start(struct bwi_mac *);
187static int bwi_mac_stop(struct bwi_mac *); 187static int bwi_mac_stop(struct bwi_mac *);
188static int bwi_mac_config_ps(struct bwi_mac *); 188static int bwi_mac_config_ps(struct bwi_mac *);
189static void bwi_mac_reset_hwkeys(struct bwi_mac *); 189static void bwi_mac_reset_hwkeys(struct bwi_mac *);
190static void bwi_mac_shutdown(struct bwi_mac *); 190static void bwi_mac_shutdown(struct bwi_mac *);
191static int bwi_mac_get_property(struct bwi_mac *); 191static int bwi_mac_get_property(struct bwi_mac *);
192static void bwi_mac_updateslot(struct bwi_mac *, int); 192static void bwi_mac_updateslot(struct bwi_mac *, int);
193static int bwi_mac_attach(struct bwi_softc *, int, uint8_t); 193static int bwi_mac_attach(struct bwi_softc *, int, uint8_t);
194static void bwi_mac_balance_atten(int *, int *); 194static void bwi_mac_balance_atten(int *, int *);
195static void bwi_mac_adjust_tpctl(struct bwi_mac *, int, int); 195static void bwi_mac_adjust_tpctl(struct bwi_mac *, int, int);
196static void bwi_mac_calibrate_txpower(struct bwi_mac *, 196static void bwi_mac_calibrate_txpower(struct bwi_mac *,
197 enum bwi_txpwrcb_type); 197 enum bwi_txpwrcb_type);
198static void bwi_mac_lock(struct bwi_mac *); 198static void bwi_mac_lock(struct bwi_mac *);
199static void bwi_mac_unlock(struct bwi_mac *); 199static void bwi_mac_unlock(struct bwi_mac *);
200static void bwi_mac_set_promisc(struct bwi_mac *, int); 200static void bwi_mac_set_promisc(struct bwi_mac *, int);
201 201
202/* PHY */ 202/* PHY */
203static void bwi_phy_write(struct bwi_mac *, uint16_t, uint16_t); 203static void bwi_phy_write(struct bwi_mac *, uint16_t, uint16_t);
204static uint16_t bwi_phy_read(struct bwi_mac *, uint16_t); 204static uint16_t bwi_phy_read(struct bwi_mac *, uint16_t);
205static int bwi_phy_attach(struct bwi_mac *); 205static int bwi_phy_attach(struct bwi_mac *);
206static void bwi_phy_set_bbp_atten(struct bwi_mac *, uint16_t); 206static void bwi_phy_set_bbp_atten(struct bwi_mac *, uint16_t);
207static int bwi_phy_calibrate(struct bwi_mac *); 207static int bwi_phy_calibrate(struct bwi_mac *);
208static void bwi_tbl_write_2(struct bwi_mac *mac, uint16_t, uint16_t); 208static void bwi_tbl_write_2(struct bwi_mac *mac, uint16_t, uint16_t);
209static void bwi_tbl_write_4(struct bwi_mac *mac, uint16_t, uint32_t); 209static void bwi_tbl_write_4(struct bwi_mac *mac, uint16_t, uint32_t);
210static void bwi_nrssi_write(struct bwi_mac *, uint16_t, int16_t); 210static void bwi_nrssi_write(struct bwi_mac *, uint16_t, int16_t);
211static int16_t bwi_nrssi_read(struct bwi_mac *, uint16_t); 211static int16_t bwi_nrssi_read(struct bwi_mac *, uint16_t);
212static void bwi_phy_init_11a(struct bwi_mac *); 212static void bwi_phy_init_11a(struct bwi_mac *);
213static void bwi_phy_init_11g(struct bwi_mac *); 213static void bwi_phy_init_11g(struct bwi_mac *);
214static void bwi_phy_init_11b_rev2(struct bwi_mac *); 214static void bwi_phy_init_11b_rev2(struct bwi_mac *);
215static void bwi_phy_init_11b_rev4(struct bwi_mac *); 215static void bwi_phy_init_11b_rev4(struct bwi_mac *);
216static void bwi_phy_init_11b_rev5(struct bwi_mac *); 216static void bwi_phy_init_11b_rev5(struct bwi_mac *);
217static void bwi_phy_init_11b_rev6(struct bwi_mac *); 217static void bwi_phy_init_11b_rev6(struct bwi_mac *);
218static void bwi_phy_config_11g(struct bwi_mac *); 218static void bwi_phy_config_11g(struct bwi_mac *);
219static void bwi_phy_config_agc(struct bwi_mac *); 219static void bwi_phy_config_agc(struct bwi_mac *);
220static void bwi_set_gains(struct bwi_mac *, const struct bwi_gains *); 220static void bwi_set_gains(struct bwi_mac *, const struct bwi_gains *);
221static void bwi_phy_clear_state(struct bwi_phy *); 221static void bwi_phy_clear_state(struct bwi_phy *);
222 222
223/* RF */ 223/* RF */
224static int16_t bwi_nrssi_11g(struct bwi_mac *); 224static int16_t bwi_nrssi_11g(struct bwi_mac *);
225static struct bwi_rf_lo 225static struct bwi_rf_lo
226 *bwi_get_rf_lo(struct bwi_mac *, uint16_t, uint16_t); 226 *bwi_get_rf_lo(struct bwi_mac *, uint16_t, uint16_t);
227static int bwi_rf_lo_isused(struct bwi_mac *, const struct bwi_rf_lo *); 227static int bwi_rf_lo_isused(struct bwi_mac *, const struct bwi_rf_lo *);
228static void bwi_rf_write(struct bwi_mac *, uint16_t, uint16_t); 228static void bwi_rf_write(struct bwi_mac *, uint16_t, uint16_t);
229static uint16_t bwi_rf_read(struct bwi_mac *, uint16_t); 229static uint16_t bwi_rf_read(struct bwi_mac *, uint16_t);
230static int bwi_rf_attach(struct bwi_mac *); 230static int bwi_rf_attach(struct bwi_mac *);
231static void bwi_rf_set_chan(struct bwi_mac *, uint, int); 231static void bwi_rf_set_chan(struct bwi_mac *, uint, int);
232static void bwi_rf_get_gains(struct bwi_mac *); 232static void bwi_rf_get_gains(struct bwi_mac *);
233static void bwi_rf_init(struct bwi_mac *); 233static void bwi_rf_init(struct bwi_mac *);
234static void bwi_rf_off_11a(struct bwi_mac *); 234static void bwi_rf_off_11a(struct bwi_mac *);
235static void bwi_rf_off_11bg(struct bwi_mac *); 235static void bwi_rf_off_11bg(struct bwi_mac *);
236static void bwi_rf_off_11g_rev5(struct bwi_mac *); 236static void bwi_rf_off_11g_rev5(struct bwi_mac *);
237static void bwi_rf_workaround(struct bwi_mac *, uint); 237static void bwi_rf_workaround(struct bwi_mac *, uint);
238static struct bwi_rf_lo 238static struct bwi_rf_lo
239 *bwi_rf_lo_find(struct bwi_mac *, const struct bwi_tpctl *); 239 *bwi_rf_lo_find(struct bwi_mac *, const struct bwi_tpctl *);
240static void bwi_rf_lo_adjust(struct bwi_mac *, const struct bwi_tpctl *); 240static void bwi_rf_lo_adjust(struct bwi_mac *, const struct bwi_tpctl *);
241static void bwi_rf_lo_write(struct bwi_mac *, const struct bwi_rf_lo *); 241static void bwi_rf_lo_write(struct bwi_mac *, const struct bwi_rf_lo *);
242static int bwi_rf_gain_max_reached(struct bwi_mac *, int); 242static int bwi_rf_gain_max_reached(struct bwi_mac *, int);
243static uint16_t bwi_bitswap4(uint16_t); 243static uint16_t bwi_bitswap4(uint16_t);
244static uint16_t bwi_phy812_value(struct bwi_mac *, uint16_t); 244static uint16_t bwi_phy812_value(struct bwi_mac *, uint16_t);
245static void bwi_rf_init_bcm2050(struct bwi_mac *); 245static void bwi_rf_init_bcm2050(struct bwi_mac *);
246static uint16_t bwi_rf_calibval(struct bwi_mac *); 246static uint16_t bwi_rf_calibval(struct bwi_mac *);
247static int32_t _bwi_adjust_devide(int32_t, int32_t); 247static int32_t _bwi_adjust_devide(int32_t, int32_t);
248static int bwi_rf_calc_txpower(int8_t *, uint8_t, const int16_t[]); 248static int bwi_rf_calc_txpower(int8_t *, uint8_t, const int16_t[]);
249static int bwi_rf_map_txpower(struct bwi_mac *); 249static int bwi_rf_map_txpower(struct bwi_mac *);
250static void bwi_rf_lo_update_11g(struct bwi_mac *); 250static void bwi_rf_lo_update_11g(struct bwi_mac *);
251static uint32_t bwi_rf_lo_devi_measure(struct bwi_mac *, uint16_t); 251static uint32_t bwi_rf_lo_devi_measure(struct bwi_mac *, uint16_t);
252static uint16_t bwi_rf_get_tp_ctrl2(struct bwi_mac *); 252static uint16_t bwi_rf_get_tp_ctrl2(struct bwi_mac *);
253static uint8_t _bwi_rf_lo_update_11g(struct bwi_mac *, uint16_t); 253static uint8_t _bwi_rf_lo_update_11g(struct bwi_mac *, uint16_t);
254static void bwi_rf_lo_measure_11g(struct bwi_mac *, 254static void bwi_rf_lo_measure_11g(struct bwi_mac *,
255 const struct bwi_rf_lo *, struct bwi_rf_lo *, uint8_t); 255 const struct bwi_rf_lo *, struct bwi_rf_lo *, uint8_t);
256static void bwi_rf_calc_nrssi_slope_11b(struct bwi_mac *); 256static void bwi_rf_calc_nrssi_slope_11b(struct bwi_mac *);
257static void bwi_rf_set_nrssi_ofs_11g(struct bwi_mac *); 257static void bwi_rf_set_nrssi_ofs_11g(struct bwi_mac *);
258static void bwi_rf_calc_nrssi_slope_11g(struct bwi_mac *); 258static void bwi_rf_calc_nrssi_slope_11g(struct bwi_mac *);
259static void bwi_rf_init_sw_nrssi_table(struct bwi_mac *); 259static void bwi_rf_init_sw_nrssi_table(struct bwi_mac *);
260static void bwi_rf_init_hw_nrssi_table(struct bwi_mac *, uint16_t); 260static void bwi_rf_init_hw_nrssi_table(struct bwi_mac *, uint16_t);
261static void bwi_rf_set_nrssi_thr_11b(struct bwi_mac *); 261static void bwi_rf_set_nrssi_thr_11b(struct bwi_mac *);
262static int32_t _nrssi_threshold(const struct bwi_rf *, int32_t); 262static int32_t _nrssi_threshold(const struct bwi_rf *, int32_t);
263static void bwi_rf_set_nrssi_thr_11g(struct bwi_mac *); 263static void bwi_rf_set_nrssi_thr_11g(struct bwi_mac *);
264static void bwi_rf_clear_tssi(struct bwi_mac *); 264static void bwi_rf_clear_tssi(struct bwi_mac *);
265static void bwi_rf_clear_state(struct bwi_rf *); 265static void bwi_rf_clear_state(struct bwi_rf *);
266static void bwi_rf_on_11a(struct bwi_mac *); 266static void bwi_rf_on_11a(struct bwi_mac *);
267static void bwi_rf_on_11bg(struct bwi_mac *); 267static void bwi_rf_on_11bg(struct bwi_mac *);
268static void bwi_rf_set_ant_mode(struct bwi_mac *, int); 268static void bwi_rf_set_ant_mode(struct bwi_mac *, int);
269static int bwi_rf_get_latest_tssi(struct bwi_mac *, int8_t[], uint16_t); 269static int bwi_rf_get_latest_tssi(struct bwi_mac *, int8_t[], uint16_t);
270static int bwi_rf_tssi2dbm(struct bwi_mac *, int8_t, int8_t *); 270static int bwi_rf_tssi2dbm(struct bwi_mac *, int8_t, int8_t *);
271static int bwi_rf_calc_rssi_bcm2050(struct bwi_mac *, 271static int bwi_rf_calc_rssi_bcm2050(struct bwi_mac *,
272 const struct bwi_rxbuf_hdr *); 272 const struct bwi_rxbuf_hdr *);
273static int bwi_rf_calc_rssi_bcm2053(struct bwi_mac *, 273static int bwi_rf_calc_rssi_bcm2053(struct bwi_mac *,
274 const struct bwi_rxbuf_hdr *); 274 const struct bwi_rxbuf_hdr *);
275static int bwi_rf_calc_rssi_bcm2060(struct bwi_mac *, 275static int bwi_rf_calc_rssi_bcm2060(struct bwi_mac *,
276 const struct bwi_rxbuf_hdr *); 276 const struct bwi_rxbuf_hdr *);
277static uint16_t bwi_rf_lo_measure_11b(struct bwi_mac *); 277static uint16_t bwi_rf_lo_measure_11b(struct bwi_mac *);
278static void bwi_rf_lo_update_11b(struct bwi_mac *); 278static void bwi_rf_lo_update_11b(struct bwi_mac *);
279 279
280/* INTERFACE */ 280/* INTERFACE */
281static uint16_t bwi_read_sprom(struct bwi_softc *, uint16_t); 281static uint16_t bwi_read_sprom(struct bwi_softc *, uint16_t);
282static void bwi_setup_desc32(struct bwi_softc *, struct bwi_desc32 *, int, 282static void bwi_setup_desc32(struct bwi_softc *, struct bwi_desc32 *, int,
283 int, bus_addr_t, int, int); 283 int, bus_addr_t, int, int);
284static void bwi_power_on(struct bwi_softc *, int); 284static void bwi_power_on(struct bwi_softc *, int);
285static int bwi_power_off(struct bwi_softc *, int); 285static int bwi_power_off(struct bwi_softc *, int);
286static int bwi_regwin_switch(struct bwi_softc *, struct bwi_regwin *, 286static int bwi_regwin_switch(struct bwi_softc *, struct bwi_regwin *,
287 struct bwi_regwin **); 287 struct bwi_regwin **);
288static int bwi_regwin_select(struct bwi_softc *, int); 288static int bwi_regwin_select(struct bwi_softc *, int);
289static void bwi_regwin_info(struct bwi_softc *, uint16_t *, uint8_t *); 289static void bwi_regwin_info(struct bwi_softc *, uint16_t *, uint8_t *);
290static void bwi_led_attach(struct bwi_softc *); 290static void bwi_led_attach(struct bwi_softc *);
291static void bwi_led_newstate(struct bwi_softc *, enum ieee80211_state); 291static void bwi_led_newstate(struct bwi_softc *, enum ieee80211_state);
292static uint16_t bwi_led_onoff(const struct bwi_led *, uint16_t, int); 292static uint16_t bwi_led_onoff(const struct bwi_led *, uint16_t, int);
293static void bwi_led_event(struct bwi_softc *, int); 293static void bwi_led_event(struct bwi_softc *, int);
294static void bwi_led_blink_start(struct bwi_softc *, int, int); 294static void bwi_led_blink_start(struct bwi_softc *, int, int);
295static void bwi_led_blink_next(void *); 295static void bwi_led_blink_next(void *);
296static void bwi_led_blink_end(void *); 296static void bwi_led_blink_end(void *);
297static int bwi_bbp_attach(struct bwi_softc *); 297static int bwi_bbp_attach(struct bwi_softc *);
298static int bwi_bus_init(struct bwi_softc *, struct bwi_mac *); 298static int bwi_bus_init(struct bwi_softc *, struct bwi_mac *);
299static void bwi_get_card_flags(struct bwi_softc *); 299static void bwi_get_card_flags(struct bwi_softc *);
300static void bwi_get_eaddr(struct bwi_softc *, uint16_t, uint8_t *); 300static void bwi_get_eaddr(struct bwi_softc *, uint16_t, uint8_t *);
301static void bwi_get_clock_freq(struct bwi_softc *, 301static void bwi_get_clock_freq(struct bwi_softc *,
302 struct bwi_clock_freq *); 302 struct bwi_clock_freq *);
303static int bwi_set_clock_mode(struct bwi_softc *, enum bwi_clock_mode); 303static int bwi_set_clock_mode(struct bwi_softc *, enum bwi_clock_mode);
304static int bwi_set_clock_delay(struct bwi_softc *); 304static int bwi_set_clock_delay(struct bwi_softc *);
305static int bwi_init(struct ifnet *); 305static int bwi_init(struct ifnet *);
306static void bwi_init_statechg(struct bwi_softc *, int); 306static void bwi_init_statechg(struct bwi_softc *, int);
307static int bwi_ioctl(struct ifnet *, u_long, void *); 307static int bwi_ioctl(struct ifnet *, u_long, void *);
308static void bwi_start(struct ifnet *); 308static void bwi_start(struct ifnet *);
309static void bwi_watchdog(struct ifnet *); 309static void bwi_watchdog(struct ifnet *);
310static void bwi_stop(struct ifnet *, int); 310static void bwi_stop(struct ifnet *, int);
311static void bwi_newstate_begin(struct bwi_softc *, enum ieee80211_state); 311static void bwi_newstate_begin(struct bwi_softc *, enum ieee80211_state);
312static int bwi_newstate(struct ieee80211com *, enum ieee80211_state, int); 312static int bwi_newstate(struct ieee80211com *, enum ieee80211_state, int);
313static int bwi_media_change(struct ifnet *); 313static int bwi_media_change(struct ifnet *);
314/* [TRC: XXX amrr] */ 314/* [TRC: XXX amrr] */
315static void bwi_iter_func(void *, struct ieee80211_node *); 315static void bwi_iter_func(void *, struct ieee80211_node *);
316static void bwi_amrr_timeout(void *); 316static void bwi_amrr_timeout(void *);
317static void bwi_newassoc(struct ieee80211_node *, int); 317static void bwi_newassoc(struct ieee80211_node *, int);
318static struct ieee80211_node * 318static struct ieee80211_node *
319 bwi_node_alloc(struct ieee80211_node_table *); 319 bwi_node_alloc(struct ieee80211_node_table *);
320static int bwi_dma_alloc(struct bwi_softc *); 320static int bwi_dma_alloc(struct bwi_softc *);
321static void bwi_dma_free(struct bwi_softc *); 321static void bwi_dma_free(struct bwi_softc *);
322static void bwi_ring_data_free(struct bwi_ring_data *, struct bwi_softc *); 322static void bwi_ring_data_free(struct bwi_ring_data *, struct bwi_softc *);
323static int bwi_dma_ring_alloc(struct bwi_softc *, 323static int bwi_dma_ring_alloc(struct bwi_softc *,
324 struct bwi_ring_data *, bus_size_t, uint32_t); 324 struct bwi_ring_data *, bus_size_t, uint32_t);
325static int bwi_dma_txstats_alloc(struct bwi_softc *, uint32_t, 325static int bwi_dma_txstats_alloc(struct bwi_softc *, uint32_t,
326 bus_size_t); 326 bus_size_t);
327static void bwi_dma_txstats_free(struct bwi_softc *); 327static void bwi_dma_txstats_free(struct bwi_softc *);
328static int bwi_dma_mbuf_create(struct bwi_softc *); 328static int bwi_dma_mbuf_create(struct bwi_softc *);
329static void bwi_dma_mbuf_destroy(struct bwi_softc *, int, int); 329static void bwi_dma_mbuf_destroy(struct bwi_softc *, int, int);
330static void bwi_enable_intrs(struct bwi_softc *, uint32_t); 330static void bwi_enable_intrs(struct bwi_softc *, uint32_t);
331static void bwi_disable_intrs(struct bwi_softc *, uint32_t); 331static void bwi_disable_intrs(struct bwi_softc *, uint32_t);
332static int bwi_init_tx_ring32(struct bwi_softc *, int); 332static int bwi_init_tx_ring32(struct bwi_softc *, int);
333static void bwi_init_rxdesc_ring32(struct bwi_softc *, uint32_t, 333static void bwi_init_rxdesc_ring32(struct bwi_softc *, uint32_t,
334 bus_addr_t, int, int); 334 bus_addr_t, int, int);
335static int bwi_init_rx_ring32(struct bwi_softc *); 335static int bwi_init_rx_ring32(struct bwi_softc *);
336static int bwi_init_txstats32(struct bwi_softc *); 336static int bwi_init_txstats32(struct bwi_softc *);
337static void bwi_setup_rx_desc32(struct bwi_softc *, int, bus_addr_t, int); 337static void bwi_setup_rx_desc32(struct bwi_softc *, int, bus_addr_t, int);
338static void bwi_setup_tx_desc32(struct bwi_softc *, struct bwi_ring_data *, 338static void bwi_setup_tx_desc32(struct bwi_softc *, struct bwi_ring_data *,
339 int, bus_addr_t, int); 339 int, bus_addr_t, int);
340static int bwi_init_tx_ring64(struct bwi_softc *, int); 340static int bwi_init_tx_ring64(struct bwi_softc *, int);
341static int bwi_init_rx_ring64(struct bwi_softc *); 341static int bwi_init_rx_ring64(struct bwi_softc *);
342static int bwi_init_txstats64(struct bwi_softc *); 342static int bwi_init_txstats64(struct bwi_softc *);
343static void bwi_setup_rx_desc64(struct bwi_softc *, int, bus_addr_t, int); 343static void bwi_setup_rx_desc64(struct bwi_softc *, int, bus_addr_t, int);
344static void bwi_setup_tx_desc64(struct bwi_softc *, struct bwi_ring_data *, 344static void bwi_setup_tx_desc64(struct bwi_softc *, struct bwi_ring_data *,
345 int, bus_addr_t, int); 345 int, bus_addr_t, int);
346static int bwi_newbuf(struct bwi_softc *, int, int); 346static int bwi_newbuf(struct bwi_softc *, int, int);
347static void bwi_set_addr_filter(struct bwi_softc *, uint16_t, 347static void bwi_set_addr_filter(struct bwi_softc *, uint16_t,
348 const uint8_t *); 348 const uint8_t *);
349static int bwi_set_chan(struct bwi_softc *, struct ieee80211_channel *); 349static int bwi_set_chan(struct bwi_softc *, struct ieee80211_channel *);
350static void bwi_next_scan(void *); 350static void bwi_next_scan(void *);
351static int bwi_rxeof(struct bwi_softc *, int); 351static int bwi_rxeof(struct bwi_softc *, int);
352static int bwi_rxeof32(struct bwi_softc *); 352static int bwi_rxeof32(struct bwi_softc *);
353static int bwi_rxeof64(struct bwi_softc *); 353static int bwi_rxeof64(struct bwi_softc *);
354static void bwi_reset_rx_ring32(struct bwi_softc *, uint32_t); 354static void bwi_reset_rx_ring32(struct bwi_softc *, uint32_t);
355static void bwi_free_txstats32(struct bwi_softc *); 355static void bwi_free_txstats32(struct bwi_softc *);
356static void bwi_free_rx_ring32(struct bwi_softc *); 356static void bwi_free_rx_ring32(struct bwi_softc *);
357static void bwi_free_tx_ring32(struct bwi_softc *, int); 357static void bwi_free_tx_ring32(struct bwi_softc *, int);
358static void bwi_free_txstats64(struct bwi_softc *); 358static void bwi_free_txstats64(struct bwi_softc *);
359static void bwi_free_rx_ring64(struct bwi_softc *); 359static void bwi_free_rx_ring64(struct bwi_softc *);
360static void bwi_free_tx_ring64(struct bwi_softc *, int); 360static void bwi_free_tx_ring64(struct bwi_softc *, int);
361static uint8_t bwi_ieee80211_rate2plcp(uint8_t rate, enum ieee80211_phymode); 361static uint8_t bwi_ieee80211_rate2plcp(uint8_t rate, enum ieee80211_phymode);
362static uint8_t bwi_ieee80211_plcp2rate(uint8_t rate, enum ieee80211_phymode); 362static uint8_t bwi_ieee80211_plcp2rate(uint8_t rate, enum ieee80211_phymode);
363static enum bwi_ieee80211_modtype 363static enum bwi_ieee80211_modtype
364 bwi_ieee80211_rate2modtype(uint8_t rate); 364 bwi_ieee80211_rate2modtype(uint8_t rate);
365static uint8_t bwi_ofdm_plcp2rate(const void *); 365static uint8_t bwi_ofdm_plcp2rate(const void *);
366static uint8_t bwi_ds_plcp2rate(const struct ieee80211_ds_plcp_hdr *); 366static uint8_t bwi_ds_plcp2rate(const struct ieee80211_ds_plcp_hdr *);
367static void bwi_ofdm_plcp_header(uint32_t *, int, uint8_t); 367static void bwi_ofdm_plcp_header(uint32_t *, int, uint8_t);
368static void bwi_ds_plcp_header(struct ieee80211_ds_plcp_hdr *, int, 368static void bwi_ds_plcp_header(struct ieee80211_ds_plcp_hdr *, int,
369 uint8_t); 369 uint8_t);
370static void bwi_plcp_header(void *, int, uint8_t); 370static void bwi_plcp_header(void *, int, uint8_t);
371static int bwi_encap(struct bwi_softc *, int, struct mbuf *, 371static int bwi_encap(struct bwi_softc *, int, struct mbuf *,
372 struct ieee80211_node **, int); 372 struct ieee80211_node **, int);
373static void bwi_start_tx32(struct bwi_softc *, uint32_t, int); 373static void bwi_start_tx32(struct bwi_softc *, uint32_t, int);
374static void bwi_start_tx64(struct bwi_softc *, uint32_t, int); 374static void bwi_start_tx64(struct bwi_softc *, uint32_t, int);
375static void bwi_txeof_status32(struct bwi_softc *); 375static void bwi_txeof_status32(struct bwi_softc *);
376static void bwi_txeof_status64(struct bwi_softc *); 376static void bwi_txeof_status64(struct bwi_softc *);
377static void _bwi_txeof(struct bwi_softc *, uint16_t); 377static void _bwi_txeof(struct bwi_softc *, uint16_t);
378static void bwi_txeof_status(struct bwi_softc *, int); 378static void bwi_txeof_status(struct bwi_softc *, int);
379static void bwi_txeof(struct bwi_softc *); 379static void bwi_txeof(struct bwi_softc *);
380static int bwi_bbp_power_on(struct bwi_softc *, enum bwi_clock_mode); 380static int bwi_bbp_power_on(struct bwi_softc *, enum bwi_clock_mode);
381static void bwi_bbp_power_off(struct bwi_softc *); 381static void bwi_bbp_power_off(struct bwi_softc *);
382static int bwi_get_pwron_delay(struct bwi_softc *sc); 382static int bwi_get_pwron_delay(struct bwi_softc *sc);
383static int bwi_bus_attach(struct bwi_softc *); 383static int bwi_bus_attach(struct bwi_softc *);
384static const char 384static const char
385 *bwi_regwin_name(const struct bwi_regwin *); 385 *bwi_regwin_name(const struct bwi_regwin *);
386static int bwi_regwin_is_enabled(struct bwi_softc *, struct bwi_regwin *); 386static int bwi_regwin_is_enabled(struct bwi_softc *, struct bwi_regwin *);
387static uint32_t bwi_regwin_disable_bits(struct bwi_softc *); 387static uint32_t bwi_regwin_disable_bits(struct bwi_softc *);
388static void bwi_regwin_enable(struct bwi_softc *, struct bwi_regwin *, 388static void bwi_regwin_enable(struct bwi_softc *, struct bwi_regwin *,
389 uint32_t); 389 uint32_t);
390static void bwi_regwin_disable(struct bwi_softc *, struct bwi_regwin *, 390static void bwi_regwin_disable(struct bwi_softc *, struct bwi_regwin *,
391 uint32_t); 391 uint32_t);
392static void bwi_set_bssid(struct bwi_softc *, const uint8_t *); 392static void bwi_set_bssid(struct bwi_softc *, const uint8_t *);
393static void bwi_updateslot(struct ifnet *); 393static void bwi_updateslot(struct ifnet *);
394static void bwi_calibrate(void *); 394static void bwi_calibrate(void *);
395static int bwi_calc_rssi(struct bwi_softc *, 395static int bwi_calc_rssi(struct bwi_softc *,
396 const struct bwi_rxbuf_hdr *); 396 const struct bwi_rxbuf_hdr *);
397static uint8_t bwi_ieee80211_ack_rate(struct ieee80211_node *, uint8_t); 397static uint8_t bwi_ieee80211_ack_rate(struct ieee80211_node *, uint8_t);
398static uint16_t bwi_ieee80211_txtime(struct ieee80211com *, 398static uint16_t bwi_ieee80211_txtime(struct ieee80211com *,
399 struct ieee80211_node *, uint, uint8_t, uint32_t); 399 struct ieee80211_node *, uint, uint8_t, uint32_t);
400 400
401/* MAC */ 401/* MAC */
402static const uint8_t bwi_sup_macrev[] = { 2, 4, 5, 6, 7, 9, 10, 12 }; 402static const uint8_t bwi_sup_macrev[] = { 2, 4, 5, 6, 7, 9, 10, 12 };
403 403
404/* PHY */ 404/* PHY */
405#define SUP_BPHY(num) { .rev = num, .init = bwi_phy_init_11b_rev##num } 405#define SUP_BPHY(num) { .rev = num, .init = bwi_phy_init_11b_rev##num }
406 406
407static const struct { 407static const struct {
408 uint8_t rev; 408 uint8_t rev;
409 void (*init)(struct bwi_mac *); 409 void (*init)(struct bwi_mac *);
410} bwi_sup_bphy[] = { 410} bwi_sup_bphy[] = {
411 SUP_BPHY(2), 411 SUP_BPHY(2),
412 SUP_BPHY(4), 412 SUP_BPHY(4),
413 SUP_BPHY(5), 413 SUP_BPHY(5),
414 SUP_BPHY(6) 414 SUP_BPHY(6)
415}; 415};
416 416
417#undef SUP_BPHY 417#undef SUP_BPHY
418 418
419#define BWI_PHYTBL_WRSSI 0x1000 419#define BWI_PHYTBL_WRSSI 0x1000
420#define BWI_PHYTBL_NOISE_SCALE 0x1400 420#define BWI_PHYTBL_NOISE_SCALE 0x1400
421#define BWI_PHYTBL_NOISE 0x1800 421#define BWI_PHYTBL_NOISE 0x1800
422#define BWI_PHYTBL_ROTOR 0x2000 422#define BWI_PHYTBL_ROTOR 0x2000
423#define BWI_PHYTBL_DELAY 0x2400 423#define BWI_PHYTBL_DELAY 0x2400
424#define BWI_PHYTBL_RSSI 0x4000 424#define BWI_PHYTBL_RSSI 0x4000
425#define BWI_PHYTBL_SIGMA_SQ 0x5000 425#define BWI_PHYTBL_SIGMA_SQ 0x5000
426#define BWI_PHYTBL_WRSSI_REV1 0x5400 426#define BWI_PHYTBL_WRSSI_REV1 0x5400
427#define BWI_PHYTBL_FREQ 0x5800 427#define BWI_PHYTBL_FREQ 0x5800
428 428
429static const uint16_t bwi_phy_freq_11g_rev1[] = 429static const uint16_t bwi_phy_freq_11g_rev1[] =
430 { BWI_PHY_FREQ_11G_REV1 }; 430 { BWI_PHY_FREQ_11G_REV1 };
431static const uint16_t bwi_phy_noise_11g_rev1[] = 431static const uint16_t bwi_phy_noise_11g_rev1[] =
432 { BWI_PHY_NOISE_11G_REV1 }; 432 { BWI_PHY_NOISE_11G_REV1 };
433static const uint16_t bwi_phy_noise_11g[] = 433static const uint16_t bwi_phy_noise_11g[] =
434 { BWI_PHY_NOISE_11G }; 434 { BWI_PHY_NOISE_11G };
435static const uint32_t bwi_phy_rotor_11g_rev1[] = 435static const uint32_t bwi_phy_rotor_11g_rev1[] =
436 { BWI_PHY_ROTOR_11G_REV1 }; 436 { BWI_PHY_ROTOR_11G_REV1 };
437static const uint16_t bwi_phy_noise_scale_11g_rev2[] = 437static const uint16_t bwi_phy_noise_scale_11g_rev2[] =
438 { BWI_PHY_NOISE_SCALE_11G_REV2 }; 438 { BWI_PHY_NOISE_SCALE_11G_REV2 };
439static const uint16_t bwi_phy_noise_scale_11g_rev7[] = 439static const uint16_t bwi_phy_noise_scale_11g_rev7[] =
440 { BWI_PHY_NOISE_SCALE_11G_REV7 }; 440 { BWI_PHY_NOISE_SCALE_11G_REV7 };
441static const uint16_t bwi_phy_noise_scale_11g[] = 441static const uint16_t bwi_phy_noise_scale_11g[] =
442 { BWI_PHY_NOISE_SCALE_11G }; 442 { BWI_PHY_NOISE_SCALE_11G };
443static const uint16_t bwi_phy_sigma_sq_11g_rev2[] = 443static const uint16_t bwi_phy_sigma_sq_11g_rev2[] =
444 { BWI_PHY_SIGMA_SQ_11G_REV2 }; 444 { BWI_PHY_SIGMA_SQ_11G_REV2 };
445static const uint16_t bwi_phy_sigma_sq_11g_rev7[] = 445static const uint16_t bwi_phy_sigma_sq_11g_rev7[] =
446 { BWI_PHY_SIGMA_SQ_11G_REV7 }; 446 { BWI_PHY_SIGMA_SQ_11G_REV7 };
447static const uint32_t bwi_phy_delay_11g_rev1[] = 447static const uint32_t bwi_phy_delay_11g_rev1[] =
448 { BWI_PHY_DELAY_11G_REV1 }; 448 { BWI_PHY_DELAY_11G_REV1 };
449 449
450/* RF */ 450/* RF */
451#define RF_LO_WRITE(mac, lo) bwi_rf_lo_write((mac), (lo)) 451#define RF_LO_WRITE(mac, lo) bwi_rf_lo_write((mac), (lo))
452 452
453#define BWI_RF_2GHZ_CHAN(chan) \ 453#define BWI_RF_2GHZ_CHAN(chan) \
454 (ieee80211_ieee2mhz((chan), IEEE80211_CHAN_2GHZ) - 2400) 454 (ieee80211_ieee2mhz((chan), IEEE80211_CHAN_2GHZ) - 2400)
455 455
456#define BWI_DEFAULT_IDLE_TSSI 52 456#define BWI_DEFAULT_IDLE_TSSI 52
457 457
458struct rf_saveregs { 458struct rf_saveregs {
459 uint16_t phy_01; 459 uint16_t phy_01;
460 uint16_t phy_03; 460 uint16_t phy_03;
461 uint16_t phy_0a; 461 uint16_t phy_0a;
462 uint16_t phy_15; 462 uint16_t phy_15;
463 uint16_t phy_2a; 463 uint16_t phy_2a;
464 uint16_t phy_30; 464 uint16_t phy_30;
465 uint16_t phy_35; 465 uint16_t phy_35;
466 uint16_t phy_60; 466 uint16_t phy_60;
467 uint16_t phy_429; 467 uint16_t phy_429;
468 uint16_t phy_802; 468 uint16_t phy_802;
469 uint16_t phy_811; 469 uint16_t phy_811;
470 uint16_t phy_812; 470 uint16_t phy_812;
471 uint16_t phy_814; 471 uint16_t phy_814;
472 uint16_t phy_815; 472 uint16_t phy_815;
473 473
474 uint16_t rf_43; 474 uint16_t rf_43;
475 uint16_t rf_52; 475 uint16_t rf_52;
476 uint16_t rf_7a; 476 uint16_t rf_7a;
477}; 477};
478 478
479#define SAVE_RF_REG(mac, regs, n) (regs)->rf_##n = RF_READ((mac), 0x##n) 479#define SAVE_RF_REG(mac, regs, n) (regs)->rf_##n = RF_READ((mac), 0x##n)
480#define RESTORE_RF_REG(mac, regs, n) RF_WRITE((mac), 0x##n, (regs)->rf_##n) 480#define RESTORE_RF_REG(mac, regs, n) RF_WRITE((mac), 0x##n, (regs)->rf_##n)
481 481
482#define SAVE_PHY_REG(mac, regs, n) (regs)->phy_##n = PHY_READ((mac), 0x##n) 482#define SAVE_PHY_REG(mac, regs, n) (regs)->phy_##n = PHY_READ((mac), 0x##n)
483#define RESTORE_PHY_REG(mac, regs, n) PHY_WRITE((mac), 0x##n, (regs)->phy_##n) 483#define RESTORE_PHY_REG(mac, regs, n) PHY_WRITE((mac), 0x##n, (regs)->phy_##n)
484 484
485static const int8_t bwi_txpower_map_11b[BWI_TSSI_MAX] = 485static const int8_t bwi_txpower_map_11b[BWI_TSSI_MAX] =
486 { BWI_TXPOWER_MAP_11B }; 486 { BWI_TXPOWER_MAP_11B };
487static const int8_t bwi_txpower_map_11g[BWI_TSSI_MAX] = 487static const int8_t bwi_txpower_map_11g[BWI_TSSI_MAX] =
488 { BWI_TXPOWER_MAP_11G }; 488 { BWI_TXPOWER_MAP_11G };
489 489
490/* INTERFACE */ 490/* INTERFACE */
491 491
492struct bwi_myaddr_bssid { 492struct bwi_myaddr_bssid {
493 uint8_t myaddr[IEEE80211_ADDR_LEN]; 493 uint8_t myaddr[IEEE80211_ADDR_LEN];
494 uint8_t bssid[IEEE80211_ADDR_LEN]; 494 uint8_t bssid[IEEE80211_ADDR_LEN];
495} __packed; 495} __packed;
496 496
497/* [TRC: XXX What are these about?] */ 497/* [TRC: XXX What are these about?] */
498 498
499#define IEEE80211_DS_PLCP_SERVICE_LOCKED 0x04 499#define IEEE80211_DS_PLCP_SERVICE_LOCKED 0x04
500#define IEEE80211_DS_PLCL_SERVICE_PBCC 0x08 500#define IEEE80211_DS_PLCL_SERVICE_PBCC 0x08
501#define IEEE80211_DS_PLCP_SERVICE_LENEXT5 0x20 501#define IEEE80211_DS_PLCP_SERVICE_LENEXT5 0x20
502#define IEEE80211_DS_PLCP_SERVICE_LENEXT6 0x40 502#define IEEE80211_DS_PLCP_SERVICE_LENEXT6 0x40
503#define IEEE80211_DS_PLCP_SERVICE_LENEXT7 0x80 503#define IEEE80211_DS_PLCP_SERVICE_LENEXT7 0x80
504 504
505static const struct { 505static const struct {
506 uint16_t did_min; 506 uint16_t did_min;
507 uint16_t did_max; 507 uint16_t did_max;
508 uint16_t bbp_id; 508 uint16_t bbp_id;
509} bwi_bbpid_map[] = { 509} bwi_bbpid_map[] = {
510 { 0x4301, 0x4301, 0x4301 }, 510 { 0x4301, 0x4301, 0x4301 },
511 { 0x4305, 0x4307, 0x4307 }, 511 { 0x4305, 0x4307, 0x4307 },
512 { 0x4403, 0x4403, 0x4402 }, 512 { 0x4403, 0x4403, 0x4402 },
513 { 0x4610, 0x4615, 0x4610 }, 513 { 0x4610, 0x4615, 0x4610 },
514 { 0x4710, 0x4715, 0x4710 }, 514 { 0x4710, 0x4715, 0x4710 },
515 { 0x4720, 0x4725, 0x4309 } 515 { 0x4720, 0x4725, 0x4309 }
516}; 516};
517 517
518static const struct { 518static const struct {
519 uint16_t bbp_id; 519 uint16_t bbp_id;
520 int nregwin; 520 int nregwin;
521} bwi_regwin_count[] = { 521} bwi_regwin_count[] = {
522 { 0x4301, 5 }, 522 { 0x4301, 5 },
523 { 0x4306, 6 }, 523 { 0x4306, 6 },
524 { 0x4307, 5 }, 524 { 0x4307, 5 },
525 { 0x4310, 8 }, 525 { 0x4310, 8 },
526 { 0x4401, 3 }, 526 { 0x4401, 3 },
527 { 0x4402, 3 }, 527 { 0x4402, 3 },
528 { 0x4610, 9 }, 528 { 0x4610, 9 },
529 { 0x4704, 9 }, 529 { 0x4704, 9 },
530 { 0x4710, 9 }, 530 { 0x4710, 9 },
531 { 0x5365, 7 } 531 { 0x5365, 7 }
532}; 532};
533 533
534#define CLKSRC(src) \ 534#define CLKSRC(src) \
535[BWI_CLKSRC_ ## src] = { \ 535[BWI_CLKSRC_ ## src] = { \
536 .freq_min = BWI_CLKSRC_ ##src## _FMIN, \ 536 .freq_min = BWI_CLKSRC_ ##src## _FMIN, \
537 .freq_max = BWI_CLKSRC_ ##src## _FMAX \ 537 .freq_max = BWI_CLKSRC_ ##src## _FMAX \
538} 538}
539 539
540static const struct { 540static const struct {
541 uint freq_min; 541 uint freq_min;
542 uint freq_max; 542 uint freq_max;
543} bwi_clkfreq[BWI_CLKSRC_MAX] = { 543} bwi_clkfreq[BWI_CLKSRC_MAX] = {
544 CLKSRC(LP_OSC), 544 CLKSRC(LP_OSC),
545 CLKSRC(CS_OSC), 545 CLKSRC(CS_OSC),
546 CLKSRC(PCI) 546 CLKSRC(PCI)
547}; 547};
548 548
549#undef CLKSRC 549#undef CLKSRC
550 550
551#define VENDOR_LED_ACT(vendor) \ 551#define VENDOR_LED_ACT(vendor) \
552{ \ 552{ \
553 .vid = PCI_VENDOR_##vendor, \ 553 .vid = PCI_VENDOR_##vendor, \
554 .led_act = { BWI_VENDOR_LED_ACT_##vendor } \ 554 .led_act = { BWI_VENDOR_LED_ACT_##vendor } \
555} 555}
556 556
557static const struct { 557static const struct {
558 uint16_t vid; 558 uint16_t vid;
559 uint8_t led_act[BWI_LED_MAX]; 559 uint8_t led_act[BWI_LED_MAX];
560} bwi_vendor_led_act[] = { 560} bwi_vendor_led_act[] = {
561 VENDOR_LED_ACT(COMPAQ), 561 VENDOR_LED_ACT(COMPAQ),
562 VENDOR_LED_ACT(LINKSYS) 562 VENDOR_LED_ACT(LINKSYS)
563}; 563};
564 564
565static const uint8_t bwi_default_led_act[BWI_LED_MAX] = 565static const uint8_t bwi_default_led_act[BWI_LED_MAX] =
566 { BWI_VENDOR_LED_ACT_DEFAULT }; 566 { BWI_VENDOR_LED_ACT_DEFAULT };
567 567
568#undef VENDOR_LED_ACT 568#undef VENDOR_LED_ACT
569 569
570static const struct { 570static const struct {
571 int on_dur; 571 int on_dur;
572 int off_dur; 572 int off_dur;
573} bwi_led_duration[109] = { 573} bwi_led_duration[109] = {
574 [0] = { 400, 100 }, 574 [0] = { 400, 100 },
575 [2] = { 150, 75 }, 575 [2] = { 150, 75 },
576 [4] = { 90, 45 }, 576 [4] = { 90, 45 },
577 [11] = { 66, 34 }, 577 [11] = { 66, 34 },
578 [12] = { 53, 26 }, 578 [12] = { 53, 26 },
579 [18] = { 42, 21 }, 579 [18] = { 42, 21 },
580 [22] = { 35, 17 }, 580 [22] = { 35, 17 },
581 [24] = { 32, 16 }, 581 [24] = { 32, 16 },
582 [36] = { 21, 10 }, 582 [36] = { 21, 10 },
583 [48] = { 16, 8 }, 583 [48] = { 16, 8 },
584 [72] = { 11, 5 }, 584 [72] = { 11, 5 },
585 [96] = { 9, 4 }, 585 [96] = { 9, 4 },
586 [108] = { 7, 3 } 586 [108] = { 7, 3 }
587}; 587};
588 588
589/* [TRC: XXX Should this be zeroed?] */ 589/* [TRC: XXX Should this be zeroed?] */
590 590
591static const uint8_t bwi_zero_addr[IEEE80211_ADDR_LEN]; 591static const uint8_t bwi_zero_addr[IEEE80211_ADDR_LEN];
592 592
593/* [TRC: Derived from DragonFly's src/sys/netproto/802_11/_ieee80211.h */ 593/* [TRC: Derived from DragonFly's src/sys/netproto/802_11/_ieee80211.h */
594 594
595enum bwi_ieee80211_modtype { 595enum bwi_ieee80211_modtype {
596 IEEE80211_MODTYPE_DS = 0, /* DS/CCK modulation */ 596 IEEE80211_MODTYPE_DS = 0, /* DS/CCK modulation */
597 IEEE80211_MODTYPE_PBCC = 1, /* PBCC modulation */ 597 IEEE80211_MODTYPE_PBCC = 1, /* PBCC modulation */
598 IEEE80211_MODTYPE_OFDM = 2 /* OFDM modulation */ 598 IEEE80211_MODTYPE_OFDM = 2 /* OFDM modulation */
599}; 599};
600#define IEEE80211_MODTYPE_CCK IEEE80211_MODTYPE_DS 600#define IEEE80211_MODTYPE_CCK IEEE80211_MODTYPE_DS
601 601
602/* 602/*
603 * Setup sysctl(3) MIB, hw.bwi.* and hw.bwiN.* 603 * Setup sysctl(3) MIB, hw.bwi.* and hw.bwiN.*
604 */ 604 */
605 605
606#ifdef BWI_DEBUG 606#ifdef BWI_DEBUG
607SYSCTL_SETUP(sysctl_bwi, "sysctl bwi(4) subtree setup") 607SYSCTL_SETUP(sysctl_bwi, "sysctl bwi(4) subtree setup")
608{ 608{
609 int rc; 609 int rc;
610 const struct sysctlnode *rnode; 610 const struct sysctlnode *rnode;
611 const struct sysctlnode *cnode; 611 const struct sysctlnode *cnode;
612 612
613 if ((rc = sysctl_createv(clog, 0, NULL, &rnode, 613 if ((rc = sysctl_createv(clog, 0, NULL, &rnode,
614 CTLFLAG_PERMANENT, CTLTYPE_NODE, "bwi", 614 CTLFLAG_PERMANENT, CTLTYPE_NODE, "bwi",
615 SYSCTL_DESCR("bwi global controls"), 615 SYSCTL_DESCR("bwi global controls"),
616 NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL)) != 0) 616 NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL)) != 0)
617 goto err; 617 goto err;
618 618
619 if ((rc = sysctl_createv(clog, 0, &rnode, &cnode, 619 if ((rc = sysctl_createv(clog, 0, &rnode, &cnode,
620 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT, 620 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
621 "debug", SYSCTL_DESCR("default debug flags"), 621 "debug", SYSCTL_DESCR("default debug flags"),
622 NULL, 0, &bwi_debug, 0, CTL_CREATE, CTL_EOL)) != 0) 622 NULL, 0, &bwi_debug, 0, CTL_CREATE, CTL_EOL)) != 0)
623 goto err; 623 goto err;
624 624
625 return; 625 return;
626 626
627err: 627err:
628 aprint_error("%s: sysctl_createv failed (rc = %d)\n", __func__, rc); 628 aprint_error("%s: sysctl_createv failed (rc = %d)\n", __func__, rc);
629} 629}
630#endif /* BWI_DEBUG */ 630#endif /* BWI_DEBUG */
631 631
632static void 632static void
633bwi_sysctlattach(struct bwi_softc *sc) 633bwi_sysctlattach(struct bwi_softc *sc)
634{ 634{
635 int rc; 635 int rc;
636 const struct sysctlnode *rnode; 636 const struct sysctlnode *rnode;
637 const struct sysctlnode *cnode; 637 const struct sysctlnode *cnode;
638 638
639 struct sysctllog **clog = &sc->sc_sysctllog; 639 struct sysctllog **clog = &sc->sc_sysctllog;
640 640
641 if ((rc = sysctl_createv(clog, 0, NULL, &rnode, 641 if ((rc = sysctl_createv(clog, 0, NULL, &rnode,
642 CTLFLAG_PERMANENT, CTLTYPE_NODE, device_xname(sc->sc_dev), 642 CTLFLAG_PERMANENT, CTLTYPE_NODE, device_xname(sc->sc_dev),
643 SYSCTL_DESCR("bwi controls and statistics"), 643 SYSCTL_DESCR("bwi controls and statistics"),
644 NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL)) != 0) 644 NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL)) != 0)
645 goto err; 645 goto err;
646 646
647 if ((rc = sysctl_createv(clog, 0, &rnode, &cnode, 647 if ((rc = sysctl_createv(clog, 0, &rnode, &cnode,
648 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT, 648 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
649 "fw_version", SYSCTL_DESCR("firmware version"), 649 "fw_version", SYSCTL_DESCR("firmware version"),
650 NULL, 0, &sc->sc_fw_version, 0, CTL_CREATE, CTL_EOL)) != 0) 650 NULL, 0, &sc->sc_fw_version, 0, CTL_CREATE, CTL_EOL)) != 0)
651 goto err; 651 goto err;
652 652
653 if ((rc = sysctl_createv(clog, 0, &rnode, &cnode, 653 if ((rc = sysctl_createv(clog, 0, &rnode, &cnode,
654 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT, 654 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
655 "dwell_time", SYSCTL_DESCR("channel dwell time during scan (msec)"), 655 "dwell_time", SYSCTL_DESCR("channel dwell time during scan (msec)"),
656 NULL, 0, &sc->sc_dwell_time, 0, CTL_CREATE, CTL_EOL)) != 0) 656 NULL, 0, &sc->sc_dwell_time, 0, CTL_CREATE, CTL_EOL)) != 0)
657 goto err; 657 goto err;
658 658
659 if ((rc = sysctl_createv(clog, 0, &rnode, &cnode, 659 if ((rc = sysctl_createv(clog, 0, &rnode, &cnode,
660 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT, 660 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
661 "led_idle", SYSCTL_DESCR("# ticks before LED enters idle state"), 661 "led_idle", SYSCTL_DESCR("# ticks before LED enters idle state"),
662 NULL, 0, &sc->sc_led_idle, 0, CTL_CREATE, CTL_EOL)) != 0) 662 NULL, 0, &sc->sc_led_idle, 0, CTL_CREATE, CTL_EOL)) != 0)
663 goto err; 663 goto err;
664 664
665 if ((rc = sysctl_createv(clog, 0, &rnode, &cnode, 665 if ((rc = sysctl_createv(clog, 0, &rnode, &cnode,
666 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT, 666 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
667 "led_blink", SYSCTL_DESCR("allow LED to blink"), 667 "led_blink", SYSCTL_DESCR("allow LED to blink"),
668 NULL, 0, &sc->sc_led_blink, 0, CTL_CREATE, CTL_EOL)) != 0) 668 NULL, 0, &sc->sc_led_blink, 0, CTL_CREATE, CTL_EOL)) != 0)
669 goto err; 669 goto err;
670 670
671 if ((rc = sysctl_createv(clog, 0, &rnode, &cnode, 671 if ((rc = sysctl_createv(clog, 0, &rnode, &cnode,
672 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT, 672 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
673 "txpwr_calib", SYSCTL_DESCR("enable software TX power calibration"), 673 "txpwr_calib", SYSCTL_DESCR("enable software TX power calibration"),
674 NULL, 0, &sc->sc_txpwr_calib, 0, CTL_CREATE, CTL_EOL)) != 0) 674 NULL, 0, &sc->sc_txpwr_calib, 0, CTL_CREATE, CTL_EOL)) != 0)
675 goto err; 675 goto err;
676 676
677#ifdef BWI_DEBUG 677#ifdef BWI_DEBUG
678 if ((rc = sysctl_createv(clog, 0, &rnode, &cnode, 678 if ((rc = sysctl_createv(clog, 0, &rnode, &cnode,
679 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT, 679 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
680 "debug", SYSCTL_DESCR("debug flags"), 680 "debug", SYSCTL_DESCR("debug flags"),
681 NULL, 0, &sc->sc_debug, 0, CTL_CREATE, CTL_EOL)) != 0) 681 NULL, 0, &sc->sc_debug, 0, CTL_CREATE, CTL_EOL)) != 0)
682 goto err; 682 goto err;
683#endif 683#endif
684 684
685 return; 685 return;
686 686
687err: 687err:
688 aprint_error("%s: sysctl_createv failed (rc = %d)\n", __func__, rc); 688 aprint_error("%s: sysctl_createv failed (rc = %d)\n", __func__, rc);
689} 689}
690 690
691/* CODE */ 691/* CODE */
692 692
693int 693int
694bwi_intr(void *arg) 694bwi_intr(void *arg)
695{ 695{
696 struct bwi_softc *sc = arg; 696 struct bwi_softc *sc = arg;
697 struct ifnet *ifp = &sc->sc_if; 697 struct ifnet *ifp = &sc->sc_if;
698 698
699 if (!device_is_active(sc->sc_dev) || 699 if (!device_is_active(sc->sc_dev) ||
700 (ifp->if_flags & IFF_RUNNING) == 0) 700 (ifp->if_flags & IFF_RUNNING) == 0)
701 return (0); 701 return (0);
702 702
703 /* Disable all interrupts */ 703 /* Disable all interrupts */
704 bwi_disable_intrs(sc, BWI_ALL_INTRS); 704 bwi_disable_intrs(sc, BWI_ALL_INTRS);
705 705
706 softint_schedule(sc->sc_soft_ih); 706 softint_schedule(sc->sc_soft_ih);
707 return (1); 707 return (1);
708} 708}
709 709
710static void 710static void
711bwi_softintr(void *arg) 711bwi_softintr(void *arg)
712{ 712{
713 struct bwi_softc *sc = arg; 713 struct bwi_softc *sc = arg;
714 struct bwi_mac *mac; 714 struct bwi_mac *mac;
715 struct ifnet *ifp = &sc->sc_if; 715 struct ifnet *ifp = &sc->sc_if;
716 uint32_t intr_status; 716 uint32_t intr_status;
717 uint32_t txrx_intr_status[BWI_TXRX_NRING]; 717 uint32_t txrx_intr_status[BWI_TXRX_NRING];
718 int i, s, txrx_error, tx = 0, rx_data = -1; 718 int i, s, txrx_error, tx = 0, rx_data = -1;
719 719
720 if (!device_is_active(sc->sc_dev) || 720 if (!device_is_active(sc->sc_dev) ||
721 (ifp->if_flags & IFF_RUNNING) == 0) 721 (ifp->if_flags & IFF_RUNNING) == 0)
722 return; 722 return;
723 723
724 for (;;) { 724 for (;;) {
725 /* 725 /*
726 * Get interrupt status 726 * Get interrupt status
727 */ 727 */
728 intr_status = CSR_READ_4(sc, BWI_MAC_INTR_STATUS); 728 intr_status = CSR_READ_4(sc, BWI_MAC_INTR_STATUS);
729 if (intr_status == 0xffffffff) /* Not for us */ 729 if (intr_status == 0xffffffff) /* Not for us */
730 goto out; 730 goto out;
731 731
732 intr_status &= CSR_READ_4(sc, BWI_MAC_INTR_MASK); 732 intr_status &= CSR_READ_4(sc, BWI_MAC_INTR_MASK);
733 if (intr_status == 0) /* Nothing is interesting */ 733 if (intr_status == 0) /* Nothing is interesting */
734 goto out; 734 goto out;
735 735
736 DPRINTF(sc, BWI_DBG_INTR, "intr status 0x%08x\n", intr_status); 736 DPRINTF(sc, BWI_DBG_INTR, "intr status 0x%08x\n", intr_status);
737 737
738 KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC); 738 KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC);
739 mac = (struct bwi_mac *)sc->sc_cur_regwin; 739 mac = (struct bwi_mac *)sc->sc_cur_regwin;
740 740
741 txrx_error = 0; 741 txrx_error = 0;
742 742
743 for (i = 0; i < BWI_TXRX_NRING; ++i) { 743 for (i = 0; i < BWI_TXRX_NRING; ++i) {
744 uint32_t mask; 744 uint32_t mask;
745 745
746 if (BWI_TXRX_IS_RX(i)) 746 if (BWI_TXRX_IS_RX(i))
747 mask = BWI_TXRX_RX_INTRS; 747 mask = BWI_TXRX_RX_INTRS;
748 else 748 else
749 mask = BWI_TXRX_TX_INTRS; 749 mask = BWI_TXRX_TX_INTRS;
750 750
751 txrx_intr_status[i] = 751 txrx_intr_status[i] =
752 CSR_READ_4(sc, BWI_TXRX_INTR_STATUS(i)) & mask; 752 CSR_READ_4(sc, BWI_TXRX_INTR_STATUS(i)) & mask;
753 753
754 if (txrx_intr_status[i] & BWI_TXRX_INTR_ERROR) { 754 if (txrx_intr_status[i] & BWI_TXRX_INTR_ERROR) {
755 aprint_error_dev(sc->sc_dev, 755 aprint_error_dev(sc->sc_dev,
756 "intr fatal TX/RX (%d) error 0x%08x\n", 756 "intr fatal TX/RX (%d) error 0x%08x\n",
757 i, txrx_intr_status[i]); 757 i, txrx_intr_status[i]);
758 txrx_error = 1; 758 txrx_error = 1;
759 } 759 }
760 } 760 }
761 761
762 /* 762 /*
763 * Acknowledge interrupt 763 * Acknowledge interrupt
764 */ 764 */
765 CSR_WRITE_4(sc, BWI_MAC_INTR_STATUS, intr_status); 765 CSR_WRITE_4(sc, BWI_MAC_INTR_STATUS, intr_status);
766 766
767 for (i = 0; i < BWI_TXRX_NRING; ++i) 767 for (i = 0; i < BWI_TXRX_NRING; ++i)
768 CSR_WRITE_4(sc, BWI_TXRX_INTR_STATUS(i), 768 CSR_WRITE_4(sc, BWI_TXRX_INTR_STATUS(i),
769 txrx_intr_status[i]); 769 txrx_intr_status[i]);
770 770
771 if (intr_status & BWI_INTR_PHY_TXERR) { 771 if (intr_status & BWI_INTR_PHY_TXERR) {
772 if (mac->mac_flags & BWI_MAC_F_PHYE_RESET) { 772 if (mac->mac_flags & BWI_MAC_F_PHYE_RESET) {
773 aprint_error_dev(sc->sc_dev, 773 aprint_error_dev(sc->sc_dev,
774 "intr PHY TX error\n"); 774 "intr PHY TX error\n");
775 /* XXX to netisr0? */ 775 /* XXX to netisr0? */
776 s = splnet(); 776 s = splnet();
777 bwi_init_statechg(sc, 0); 777 bwi_init_statechg(sc, 0);
778 splx(s); 778 splx(s);
779 goto out; 779 goto out;
780 } 780 }
781 } 781 }
782 782
783 if (txrx_error) { 783 if (txrx_error) {
784 /* TODO: reset device */ 784 /* TODO: reset device */
785 } 785 }
786 786
787 if (intr_status & BWI_INTR_TBTT) 787 if (intr_status & BWI_INTR_TBTT)
788 bwi_mac_config_ps(mac); 788 bwi_mac_config_ps(mac);
789 789
790 if (intr_status & BWI_INTR_EO_ATIM) 790 if (intr_status & BWI_INTR_EO_ATIM)
791 aprint_normal_dev(sc->sc_dev, "EO_ATIM\n"); 791 aprint_normal_dev(sc->sc_dev, "EO_ATIM\n");
792 792
793 if (intr_status & BWI_INTR_PMQ) { 793 if (intr_status & BWI_INTR_PMQ) {
794 for (;;) { 794 for (;;) {
795 if ((CSR_READ_4(sc, BWI_MAC_PS_STATUS) & 0x8) 795 if ((CSR_READ_4(sc, BWI_MAC_PS_STATUS) & 0x8)
796 == 0) 796 == 0)
797 break; 797 break;
798 } 798 }
799 CSR_WRITE_2(sc, BWI_MAC_PS_STATUS, 0x2); 799 CSR_WRITE_2(sc, BWI_MAC_PS_STATUS, 0x2);
800 } 800 }
801 801
802 if (intr_status & BWI_INTR_NOISE) 802 if (intr_status & BWI_INTR_NOISE)
803 aprint_normal_dev(sc->sc_dev, "intr noise\n"); 803 aprint_normal_dev(sc->sc_dev, "intr noise\n");
804 804
805 if (txrx_intr_status[0] & BWI_TXRX_INTR_RX) 805 if (txrx_intr_status[0] & BWI_TXRX_INTR_RX)
806 rx_data = (sc->sc_rxeof)(sc); 806 rx_data = (sc->sc_rxeof)(sc);
807 807
808 if (txrx_intr_status[3] & BWI_TXRX_INTR_RX) { 808 if (txrx_intr_status[3] & BWI_TXRX_INTR_RX) {
809 (sc->sc_txeof_status)(sc); 809 (sc->sc_txeof_status)(sc);
810 tx = 1; 810 tx = 1;
811 } 811 }
812 812
813 if (intr_status & BWI_INTR_TX_DONE) { 813 if (intr_status & BWI_INTR_TX_DONE) {
814 bwi_txeof(sc); 814 bwi_txeof(sc);
815 tx = 1; 815 tx = 1;
816 } 816 }
817 817
818 if (sc->sc_blink_led != NULL && sc->sc_led_blink) { 818 if (sc->sc_blink_led != NULL && sc->sc_led_blink) {
819 int evt = BWI_LED_EVENT_NONE; 819 int evt = BWI_LED_EVENT_NONE;
820 820
821 if (tx && rx_data > 0) { 821 if (tx && rx_data > 0) {
822 if (sc->sc_rx_rate > sc->sc_tx_rate) 822 if (sc->sc_rx_rate > sc->sc_tx_rate)
823 evt = BWI_LED_EVENT_RX; 823 evt = BWI_LED_EVENT_RX;
824 else 824 else
825 evt = BWI_LED_EVENT_TX; 825 evt = BWI_LED_EVENT_TX;
826 } else if (tx) { 826 } else if (tx) {
827 evt = BWI_LED_EVENT_TX; 827 evt = BWI_LED_EVENT_TX;
828 } else if (rx_data > 0) { 828 } else if (rx_data > 0) {
829 evt = BWI_LED_EVENT_RX; 829 evt = BWI_LED_EVENT_RX;
830 } else if (rx_data == 0) { 830 } else if (rx_data == 0) {
831 evt = BWI_LED_EVENT_POLL; 831 evt = BWI_LED_EVENT_POLL;
832 } 832 }
833 833
834 if (evt != BWI_LED_EVENT_NONE) 834 if (evt != BWI_LED_EVENT_NONE)
835 bwi_led_event(sc, evt); 835 bwi_led_event(sc, evt);
836 } 836 }
837 } 837 }
838 838
839out: 839out:
840 /* Re-enable interrupts */ 840 /* Re-enable interrupts */
841 bwi_enable_intrs(sc, BWI_INIT_INTRS); 841 bwi_enable_intrs(sc, BWI_INIT_INTRS);
842} 842}
843 843
844int 844int
845bwi_attach(struct bwi_softc *sc) 845bwi_attach(struct bwi_softc *sc)
846{ 846{
847 struct ieee80211com *ic = &sc->sc_ic; 847 struct ieee80211com *ic = &sc->sc_ic;
848 struct ifnet *ifp = &sc->sc_if; 848 struct ifnet *ifp = &sc->sc_if;
849 struct bwi_mac *mac; 849 struct bwi_mac *mac;
850 struct bwi_phy *phy; 850 struct bwi_phy *phy;
851 int s, i, error; 851 int s, i, error;
852 852
853 /* [TRC: XXX Is this necessary?] */ 853 /* [TRC: XXX Is this necessary?] */
854 s = splnet(); 854 s = splnet();
855 855
856 sc->sc_soft_ih = softint_establish(SOFTINT_NET, bwi_softintr, sc); 856 sc->sc_soft_ih = softint_establish(SOFTINT_NET, bwi_softintr, sc);
857 if (sc->sc_soft_ih == NULL) { 857 if (sc->sc_soft_ih == NULL) {
858 error = ENXIO; 858 error = ENXIO;
859 goto fail; 859 goto fail;
860 } 860 }
861 861
862 /* 862 /*
863 * Initialize sysctl variables 863 * Initialize sysctl variables
864 */ 864 */
865 sc->sc_fw_version = BWI_FW_VERSION3; 865 sc->sc_fw_version = BWI_FW_VERSION3;
866 sc->sc_dwell_time = 200; 866 sc->sc_dwell_time = 200;
867 sc->sc_led_idle = (2350 * hz) / 1000; 867 sc->sc_led_idle = (2350 * hz) / 1000;
868 sc->sc_led_blink = 1; 868 sc->sc_led_blink = 1;
869 sc->sc_txpwr_calib = 1; 869 sc->sc_txpwr_calib = 1;
870#ifdef BWI_DEBUG 870#ifdef BWI_DEBUG
871 sc->sc_debug = bwi_debug; 871 sc->sc_debug = bwi_debug;
872#endif 872#endif
873 873
874 DPRINTF(sc, BWI_DBG_ATTACH, "%s\n", __func__); 874 DPRINTF(sc, BWI_DBG_ATTACH, "%s\n", __func__);
875 875
876 /* [TRC: XXX amrr] */ 876 /* [TRC: XXX amrr] */
877 /* AMRR rate control */ 877 /* AMRR rate control */
878 sc->sc_amrr.amrr_min_success_threshold = 1; 878 sc->sc_amrr.amrr_min_success_threshold = 1;
879 sc->sc_amrr.amrr_max_success_threshold = 15; 879 sc->sc_amrr.amrr_max_success_threshold = 15;
880 callout_init(&sc->sc_amrr_ch, 0); 880 callout_init(&sc->sc_amrr_ch, 0);
881 callout_setfunc(&sc->sc_amrr_ch, bwi_amrr_timeout, sc); 881 callout_setfunc(&sc->sc_amrr_ch, bwi_amrr_timeout, sc);
882 882
883 callout_init(&sc->sc_scan_ch, 0); 883 callout_init(&sc->sc_scan_ch, 0);
884 callout_setfunc(&sc->sc_scan_ch, bwi_next_scan, sc); 884 callout_setfunc(&sc->sc_scan_ch, bwi_next_scan, sc);
885 callout_init(&sc->sc_calib_ch, 0); 885 callout_init(&sc->sc_calib_ch, 0);
886 callout_setfunc(&sc->sc_calib_ch, bwi_calibrate, sc); 886 callout_setfunc(&sc->sc_calib_ch, bwi_calibrate, sc);
887 887
888 bwi_sysctlattach(sc); 888 bwi_sysctlattach(sc);
889 889
890 bwi_power_on(sc, 1); 890 bwi_power_on(sc, 1);
891 891
892 error = bwi_bbp_attach(sc); 892 error = bwi_bbp_attach(sc);
893 if (error) 893 if (error)
894 goto fail; 894 goto fail;
895 895
896 error = bwi_bbp_power_on(sc, BWI_CLOCK_MODE_FAST); 896 error = bwi_bbp_power_on(sc, BWI_CLOCK_MODE_FAST);
897 if (error) 897 if (error)
898 goto fail; 898 goto fail;
899 899
900 if (BWI_REGWIN_EXIST(&sc->sc_com_regwin)) { 900 if (BWI_REGWIN_EXIST(&sc->sc_com_regwin)) {
901 error = bwi_set_clock_delay(sc); 901 error = bwi_set_clock_delay(sc);
902 if (error) 902 if (error)
903 goto fail; 903 goto fail;
904 904
905 error = bwi_set_clock_mode(sc, BWI_CLOCK_MODE_FAST); 905 error = bwi_set_clock_mode(sc, BWI_CLOCK_MODE_FAST);
906 if (error) 906 if (error)
907 goto fail; 907 goto fail;
908 908
909 error = bwi_get_pwron_delay(sc); 909 error = bwi_get_pwron_delay(sc);
910 if (error) 910 if (error)
911 goto fail; 911 goto fail;
912 } 912 }
913 913
914 error = bwi_bus_attach(sc); 914 error = bwi_bus_attach(sc);
915 if (error) 915 if (error)
916 goto fail; 916 goto fail;
917 917
918 bwi_get_card_flags(sc); 918 bwi_get_card_flags(sc);
919 919
920 bwi_led_attach(sc); 920 bwi_led_attach(sc);
921 921
922 for (i = 0; i < sc->sc_nmac; ++i) { 922 for (i = 0; i < sc->sc_nmac; ++i) {
923 struct bwi_regwin *old; 923 struct bwi_regwin *old;
924 924
925 mac = &sc->sc_mac[i]; 925 mac = &sc->sc_mac[i];
926 error = bwi_regwin_switch(sc, &mac->mac_regwin, &old); 926 error = bwi_regwin_switch(sc, &mac->mac_regwin, &old);
927 if (error) 927 if (error)
928 goto fail; 928 goto fail;
929 929
930 error = bwi_mac_lateattach(mac); 930 error = bwi_mac_lateattach(mac);
931 if (error) 931 if (error)
932 goto fail; 932 goto fail;
933 933
934 error = bwi_regwin_switch(sc, old, NULL); 934 error = bwi_regwin_switch(sc, old, NULL);
935 if (error) 935 if (error)
936 goto fail; 936 goto fail;
937 } 937 }
938 938
939 /* 939 /*
940 * XXX First MAC is known to exist 940 * XXX First MAC is known to exist
941 * TODO2 941 * TODO2
942 */ 942 */
943 mac = &sc->sc_mac[0]; 943 mac = &sc->sc_mac[0];
944 phy = &mac->mac_phy; 944 phy = &mac->mac_phy;
945 945
946 bwi_bbp_power_off(sc); 946 bwi_bbp_power_off(sc);
947 947
948 error = bwi_dma_alloc(sc); 948 error = bwi_dma_alloc(sc);
949 if (error) 949 if (error)
950 goto fail; 950 goto fail;
951 951
952 /* setup interface */ 952 /* setup interface */
953 ifp->if_softc = sc; 953 ifp->if_softc = sc;
954 ifp->if_init = bwi_init; 954 ifp->if_init = bwi_init;
955 ifp->if_ioctl = bwi_ioctl; 955 ifp->if_ioctl = bwi_ioctl;
956 ifp->if_start = bwi_start; 956 ifp->if_start = bwi_start;
957 ifp->if_watchdog = bwi_watchdog; 957 ifp->if_watchdog = bwi_watchdog;
958 ifp->if_stop = bwi_stop; 958 ifp->if_stop = bwi_stop;
959 ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST; 959 ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST;
960 memcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ); 960 memcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ);
961 IFQ_SET_READY(&ifp->if_snd); 961 IFQ_SET_READY(&ifp->if_snd);
962 962
963 /* Get locale */ 963 /* Get locale */
964 sc->sc_locale = __SHIFTOUT(bwi_read_sprom(sc, BWI_SPROM_CARD_INFO), 964 sc->sc_locale = __SHIFTOUT(bwi_read_sprom(sc, BWI_SPROM_CARD_INFO),
965 BWI_SPROM_CARD_INFO_LOCALE); 965 BWI_SPROM_CARD_INFO_LOCALE);
966 DPRINTF(sc, BWI_DBG_ATTACH, "locale: %d\n", sc->sc_locale); 966 DPRINTF(sc, BWI_DBG_ATTACH, "locale: %d\n", sc->sc_locale);
967 967
968 /* 968 /*
969 * Setup ratesets, phytype, channels and get MAC address 969 * Setup ratesets, phytype, channels and get MAC address
970 */ 970 */
971 if (phy->phy_mode == IEEE80211_MODE_11B || 971 if (phy->phy_mode == IEEE80211_MODE_11B ||
972 phy->phy_mode == IEEE80211_MODE_11G) { 972 phy->phy_mode == IEEE80211_MODE_11G) {
973 uint16_t chan_flags; 973 uint16_t chan_flags;
974 974
975 ic->ic_sup_rates[IEEE80211_MODE_11B] = 975 ic->ic_sup_rates[IEEE80211_MODE_11B] =
976 ieee80211_std_rateset_11b; 976 ieee80211_std_rateset_11b;
977 977
978 if (phy->phy_mode == IEEE80211_MODE_11B) { 978 if (phy->phy_mode == IEEE80211_MODE_11B) {
979 chan_flags = IEEE80211_CHAN_B; 979 chan_flags = IEEE80211_CHAN_B;
980 ic->ic_phytype = IEEE80211_T_DS; 980 ic->ic_phytype = IEEE80211_T_DS;
981 } else { 981 } else {
982 chan_flags = IEEE80211_CHAN_CCK | 982 chan_flags = IEEE80211_CHAN_CCK |
983 IEEE80211_CHAN_OFDM | 983 IEEE80211_CHAN_OFDM |
984 IEEE80211_CHAN_DYN | 984 IEEE80211_CHAN_DYN |
985 IEEE80211_CHAN_2GHZ; 985 IEEE80211_CHAN_2GHZ;
986 ic->ic_phytype = IEEE80211_T_OFDM; 986 ic->ic_phytype = IEEE80211_T_OFDM;
987 ic->ic_sup_rates[IEEE80211_MODE_11G] = 987 ic->ic_sup_rates[IEEE80211_MODE_11G] =
988 ieee80211_std_rateset_11g; 988 ieee80211_std_rateset_11g;
989 } 989 }
990 990
991 /* XXX depend on locale */ 991 /* XXX depend on locale */
992 for (i = 1; i <= 14; ++i) { 992 for (i = 1; i <= 14; ++i) {
993 ic->ic_channels[i].ic_freq = 993 ic->ic_channels[i].ic_freq =
994 ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ); 994 ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ);
995 ic->ic_channels[i].ic_flags = chan_flags; 995 ic->ic_channels[i].ic_flags = chan_flags;
996 } 996 }
997 997
998 bwi_get_eaddr(sc, BWI_SPROM_11BG_EADDR, ic->ic_myaddr); 998 bwi_get_eaddr(sc, BWI_SPROM_11BG_EADDR, ic->ic_myaddr);
999 if (IEEE80211_IS_MULTICAST(ic->ic_myaddr)) { 999 if (IEEE80211_IS_MULTICAST(ic->ic_myaddr)) {
1000 bwi_get_eaddr(sc, BWI_SPROM_11A_EADDR, ic->ic_myaddr); 1000 bwi_get_eaddr(sc, BWI_SPROM_11A_EADDR, ic->ic_myaddr);
1001 if (IEEE80211_IS_MULTICAST(ic->ic_myaddr)) 1001 if (IEEE80211_IS_MULTICAST(ic->ic_myaddr))
1002 aprint_error_dev(sc->sc_dev, 1002 aprint_error_dev(sc->sc_dev,
1003 "invalid MAC address: %s\n", 1003 "invalid MAC address: %s\n",
1004 ether_sprintf(ic->ic_myaddr)); 1004 ether_sprintf(ic->ic_myaddr));
1005 } 1005 }
1006 } else if (phy->phy_mode == IEEE80211_MODE_11A) { 1006 } else if (phy->phy_mode == IEEE80211_MODE_11A) {
1007 /* TODO: 11A */ 1007 /* TODO: 11A */
1008 error = ENXIO; 1008 error = ENXIO;
1009 goto fail; 1009 goto fail;
1010 } else 1010 } else
1011 panic("unknown phymode %d\n", phy->phy_mode); 1011 panic("unknown phymode %d\n", phy->phy_mode);
1012 1012
1013 ic->ic_ifp = ifp; 1013 ic->ic_ifp = ifp;
1014 ic->ic_caps = IEEE80211_C_SHSLOT | 1014 ic->ic_caps = IEEE80211_C_SHSLOT |
1015 IEEE80211_C_SHPREAMBLE | 1015 IEEE80211_C_SHPREAMBLE |
1016 IEEE80211_C_IBSS | 1016 IEEE80211_C_IBSS |
1017 IEEE80211_C_HOSTAP | 1017 IEEE80211_C_HOSTAP |
1018 IEEE80211_C_MONITOR; 1018 IEEE80211_C_MONITOR;
1019 ic->ic_state = IEEE80211_S_INIT; 1019 ic->ic_state = IEEE80211_S_INIT;
1020 ic->ic_opmode = IEEE80211_M_STA; 1020 ic->ic_opmode = IEEE80211_M_STA;
1021 1021
1022 ic->ic_updateslot = bwi_updateslot; 1022 ic->ic_updateslot = bwi_updateslot;
1023 1023
1024 error = if_initialize(ifp); 1024 error = if_initialize(ifp);
1025 if (error != 0) { 1025 if (error != 0) {
1026 aprint_error_dev(sc->sc_dev, "if_initialize failed(%d)\n", 1026 aprint_error_dev(sc->sc_dev, "if_initialize failed(%d)\n",
1027 error); 1027 error);
1028 goto fail; 1028 goto fail;
1029 } 1029 }
1030 ieee80211_ifattach(ic); 1030 ieee80211_ifattach(ic);
1031 ifp->if_percpuq = if_percpuq_create(ifp); 1031 ifp->if_percpuq = if_percpuq_create(ifp);
1032 if_register(ifp); 1032 if_register(ifp);
1033 1033
1034 /* [TRC: XXX Not supported on NetBSD?] */ 1034 /* [TRC: XXX Not supported on NetBSD?] */
1035 /* ic->ic_flags_ext |= IEEE80211_FEXT_SWBMISS; */ 1035 /* ic->ic_flags_ext |= IEEE80211_FEXT_SWBMISS; */
1036 1036
1037 sc->sc_newstate = ic->ic_newstate; 1037 sc->sc_newstate = ic->ic_newstate;
1038 ic->ic_newstate = bwi_newstate; 1038 ic->ic_newstate = bwi_newstate;
1039 /* [TRC: XXX amrr] */ 1039 /* [TRC: XXX amrr] */
1040 ic->ic_newassoc = bwi_newassoc; 1040 ic->ic_newassoc = bwi_newassoc;
1041 ic->ic_node_alloc = bwi_node_alloc; 1041 ic->ic_node_alloc = bwi_node_alloc;
1042 1042
1043 ieee80211_media_init(ic, bwi_media_change, ieee80211_media_status); 1043 ieee80211_media_init(ic, bwi_media_change, ieee80211_media_status);
1044 1044
1045 bpf_attach2(ifp, DLT_IEEE802_11_RADIO, 1045 bpf_attach2(ifp, DLT_IEEE802_11_RADIO,
1046 sizeof(struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN, 1046 sizeof(struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN,
1047 &sc->sc_drvbpf); 1047 &sc->sc_drvbpf);
1048 1048
1049 /* [TRC: XXX DragonFlyBSD rounds this up to a multiple of 1049 /* [TRC: XXX DragonFlyBSD rounds this up to a multiple of
1050 sizeof(uint32_t). Should we?] */ 1050 sizeof(uint32_t). Should we?] */
@@ -6424,3337 +6424,3337 @@ bwi_power_on(struct bwi_softc *sc, int w @@ -6424,3337 +6424,3337 @@ bwi_power_on(struct bwi_softc *sc, int w
6424 6424
6425 DPRINTF(sc, BWI_DBG_MISC, "%s\n", __func__); 6425 DPRINTF(sc, BWI_DBG_MISC, "%s\n", __func__);
6426 6426
6427 gpio_in = (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_IN); 6427 gpio_in = (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_IN);
6428 if (gpio_in & BWI_PCIM_GPIO_PWR_ON) 6428 if (gpio_in & BWI_PCIM_GPIO_PWR_ON)
6429 goto back; 6429 goto back;
6430 6430
6431 gpio_out = (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_OUT); 6431 gpio_out = (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_OUT);
6432 gpio_en = (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_ENABLE); 6432 gpio_en = (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_ENABLE);
6433 6433
6434 gpio_out |= BWI_PCIM_GPIO_PWR_ON; 6434 gpio_out |= BWI_PCIM_GPIO_PWR_ON;
6435 gpio_en |= BWI_PCIM_GPIO_PWR_ON; 6435 gpio_en |= BWI_PCIM_GPIO_PWR_ON;
6436 if (with_pll) { 6436 if (with_pll) {
6437 /* Turn off PLL first */ 6437 /* Turn off PLL first */
6438 gpio_out |= BWI_PCIM_GPIO_PLL_PWR_OFF; 6438 gpio_out |= BWI_PCIM_GPIO_PLL_PWR_OFF;
6439 gpio_en |= BWI_PCIM_GPIO_PLL_PWR_OFF; 6439 gpio_en |= BWI_PCIM_GPIO_PLL_PWR_OFF;
6440 } 6440 }
6441 6441
6442 (sc->sc_conf_write)(sc, BWI_PCIR_GPIO_OUT, gpio_out); 6442 (sc->sc_conf_write)(sc, BWI_PCIR_GPIO_OUT, gpio_out);
6443 (sc->sc_conf_write)(sc, BWI_PCIR_GPIO_ENABLE, gpio_en); 6443 (sc->sc_conf_write)(sc, BWI_PCIR_GPIO_ENABLE, gpio_en);
6444 DELAY(1000); 6444 DELAY(1000);
6445 6445
6446 if (with_pll) { 6446 if (with_pll) {
6447 /* Turn on PLL */ 6447 /* Turn on PLL */
6448 gpio_out &= ~BWI_PCIM_GPIO_PLL_PWR_OFF; 6448 gpio_out &= ~BWI_PCIM_GPIO_PLL_PWR_OFF;
6449 (sc->sc_conf_write)(sc, BWI_PCIR_GPIO_OUT, gpio_out); 6449 (sc->sc_conf_write)(sc, BWI_PCIR_GPIO_OUT, gpio_out);
6450 DELAY(5000); 6450 DELAY(5000);
6451 } 6451 }
6452 6452
6453back: 6453back:
6454 /* [TRC: XXX This looks totally wrong -- what's PCI doing in here?] */ 6454 /* [TRC: XXX This looks totally wrong -- what's PCI doing in here?] */
6455 /* Clear "Signaled Target Abort" */ 6455 /* Clear "Signaled Target Abort" */
6456 status = (sc->sc_conf_read)(sc, PCI_COMMAND_STATUS_REG); 6456 status = (sc->sc_conf_read)(sc, PCI_COMMAND_STATUS_REG);
6457 status &= ~PCI_STATUS_TARGET_TARGET_ABORT; 6457 status &= ~PCI_STATUS_TARGET_TARGET_ABORT;
6458 (sc->sc_conf_write)(sc, PCI_COMMAND_STATUS_REG, status); 6458 (sc->sc_conf_write)(sc, PCI_COMMAND_STATUS_REG, status);
6459} 6459}
6460 6460
6461static int 6461static int
6462bwi_power_off(struct bwi_softc *sc, int with_pll) 6462bwi_power_off(struct bwi_softc *sc, int with_pll)
6463{ 6463{
6464 uint32_t gpio_out, gpio_en; 6464 uint32_t gpio_out, gpio_en;
6465 6465
6466 DPRINTF(sc, BWI_DBG_MISC, "%s\n", __func__); 6466 DPRINTF(sc, BWI_DBG_MISC, "%s\n", __func__);
6467 6467
6468 (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_IN); /* dummy read */ 6468 (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_IN); /* dummy read */
6469 gpio_out = (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_OUT); 6469 gpio_out = (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_OUT);
6470 gpio_en = (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_ENABLE); 6470 gpio_en = (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_ENABLE);
6471 6471
6472 gpio_out &= ~BWI_PCIM_GPIO_PWR_ON; 6472 gpio_out &= ~BWI_PCIM_GPIO_PWR_ON;
6473 gpio_en |= BWI_PCIM_GPIO_PWR_ON; 6473 gpio_en |= BWI_PCIM_GPIO_PWR_ON;
6474 if (with_pll) { 6474 if (with_pll) {
6475 gpio_out |= BWI_PCIM_GPIO_PLL_PWR_OFF; 6475 gpio_out |= BWI_PCIM_GPIO_PLL_PWR_OFF;
6476 gpio_en |= BWI_PCIM_GPIO_PLL_PWR_OFF; 6476 gpio_en |= BWI_PCIM_GPIO_PLL_PWR_OFF;
6477 } 6477 }
6478 6478
6479 (sc->sc_conf_write)(sc, BWI_PCIR_GPIO_OUT, gpio_out); 6479 (sc->sc_conf_write)(sc, BWI_PCIR_GPIO_OUT, gpio_out);
6480 (sc->sc_conf_write)(sc, BWI_PCIR_GPIO_ENABLE, gpio_en); 6480 (sc->sc_conf_write)(sc, BWI_PCIR_GPIO_ENABLE, gpio_en);
6481 6481
6482 return (0); 6482 return (0);
6483} 6483}
6484 6484
6485static int 6485static int
6486bwi_regwin_switch(struct bwi_softc *sc, struct bwi_regwin *rw, 6486bwi_regwin_switch(struct bwi_softc *sc, struct bwi_regwin *rw,
6487 struct bwi_regwin **old_rw) 6487 struct bwi_regwin **old_rw)
6488{ 6488{
6489 int error; 6489 int error;
6490 6490
6491 if (old_rw != NULL) 6491 if (old_rw != NULL)
6492 *old_rw = NULL; 6492 *old_rw = NULL;
6493 6493
6494 if (!BWI_REGWIN_EXIST(rw)) 6494 if (!BWI_REGWIN_EXIST(rw))
6495 return (EINVAL); 6495 return (EINVAL);
6496 6496
6497 if (sc->sc_cur_regwin != rw) { 6497 if (sc->sc_cur_regwin != rw) {
6498 error = bwi_regwin_select(sc, rw->rw_id); 6498 error = bwi_regwin_select(sc, rw->rw_id);
6499 if (error) { 6499 if (error) {
6500 aprint_error_dev(sc->sc_dev, 6500 aprint_error_dev(sc->sc_dev,
6501 "can't select regwin %d\n", rw->rw_id); 6501 "can't select regwin %d\n", rw->rw_id);
6502 return (error); 6502 return (error);
6503 } 6503 }
6504 } 6504 }
6505 6505
6506 if (old_rw != NULL) 6506 if (old_rw != NULL)
6507 *old_rw = sc->sc_cur_regwin; 6507 *old_rw = sc->sc_cur_regwin;
6508 sc->sc_cur_regwin = rw; 6508 sc->sc_cur_regwin = rw;
6509 6509
6510 return (0); 6510 return (0);
6511} 6511}
6512 6512
6513static int 6513static int
6514bwi_regwin_select(struct bwi_softc *sc, int id) 6514bwi_regwin_select(struct bwi_softc *sc, int id)
6515{ 6515{
6516 uint32_t win = BWI_PCIM_REGWIN(id); 6516 uint32_t win = BWI_PCIM_REGWIN(id);
6517 int i; 6517 int i;
6518 6518
6519#define RETRY_MAX 50 6519#define RETRY_MAX 50
6520 for (i = 0; i < RETRY_MAX; ++i) { 6520 for (i = 0; i < RETRY_MAX; ++i) {
6521 (sc->sc_conf_write)(sc, BWI_PCIR_SEL_REGWIN, win); 6521 (sc->sc_conf_write)(sc, BWI_PCIR_SEL_REGWIN, win);
6522 if ((sc->sc_conf_read)(sc, BWI_PCIR_SEL_REGWIN) == win) 6522 if ((sc->sc_conf_read)(sc, BWI_PCIR_SEL_REGWIN) == win)
6523 return (0); 6523 return (0);
6524 DELAY(10); 6524 DELAY(10);
6525 } 6525 }
6526#undef RETRY_MAX 6526#undef RETRY_MAX
6527 6527
6528 return (ENXIO); 6528 return (ENXIO);
6529} 6529}
6530 6530
6531static void 6531static void
6532bwi_regwin_info(struct bwi_softc *sc, uint16_t *type, uint8_t *rev) 6532bwi_regwin_info(struct bwi_softc *sc, uint16_t *type, uint8_t *rev)
6533{ 6533{
6534 uint32_t val; 6534 uint32_t val;
6535 6535
6536 val = CSR_READ_4(sc, BWI_ID_HI); 6536 val = CSR_READ_4(sc, BWI_ID_HI);
6537 *type = BWI_ID_HI_REGWIN_TYPE(val); 6537 *type = BWI_ID_HI_REGWIN_TYPE(val);
6538 *rev = BWI_ID_HI_REGWIN_REV(val); 6538 *rev = BWI_ID_HI_REGWIN_REV(val);
6539 6539
6540 DPRINTF(sc, BWI_DBG_ATTACH, "regwin: type 0x%03x, rev %d," 6540 DPRINTF(sc, BWI_DBG_ATTACH, "regwin: type 0x%03x, rev %d,"
6541 " vendor 0x%04x\n", *type, *rev, 6541 " vendor 0x%04x\n", *type, *rev,
6542 __SHIFTOUT(val, BWI_ID_HI_REGWIN_VENDOR_MASK)); 6542 __SHIFTOUT(val, BWI_ID_HI_REGWIN_VENDOR_MASK));
6543} 6543}
6544 6544
6545static void 6545static void
6546bwi_led_attach(struct bwi_softc *sc) 6546bwi_led_attach(struct bwi_softc *sc)
6547{ 6547{
6548 const uint8_t *led_act = NULL; 6548 const uint8_t *led_act = NULL;
6549 uint16_t gpio, val[BWI_LED_MAX]; 6549 uint16_t gpio, val[BWI_LED_MAX];
6550 int i; 6550 int i;
6551 6551
6552 for (i = 0; i < __arraycount(bwi_vendor_led_act); ++i) { 6552 for (i = 0; i < __arraycount(bwi_vendor_led_act); ++i) {
6553 if (sc->sc_pci_subvid == bwi_vendor_led_act[i].vid) { 6553 if (sc->sc_pci_subvid == bwi_vendor_led_act[i].vid) {
6554 led_act = bwi_vendor_led_act[i].led_act; 6554 led_act = bwi_vendor_led_act[i].led_act;
6555 break; 6555 break;
6556 } 6556 }
6557 } 6557 }
6558 if (led_act == NULL) 6558 if (led_act == NULL)
6559 led_act = bwi_default_led_act; 6559 led_act = bwi_default_led_act;
6560 6560
6561 gpio = bwi_read_sprom(sc, BWI_SPROM_GPIO01); 6561 gpio = bwi_read_sprom(sc, BWI_SPROM_GPIO01);
6562 val[0] = __SHIFTOUT(gpio, BWI_SPROM_GPIO_0); 6562 val[0] = __SHIFTOUT(gpio, BWI_SPROM_GPIO_0);
6563 val[1] = __SHIFTOUT(gpio, BWI_SPROM_GPIO_1); 6563 val[1] = __SHIFTOUT(gpio, BWI_SPROM_GPIO_1);
6564 6564
6565 gpio = bwi_read_sprom(sc, BWI_SPROM_GPIO23); 6565 gpio = bwi_read_sprom(sc, BWI_SPROM_GPIO23);
6566 val[2] = __SHIFTOUT(gpio, BWI_SPROM_GPIO_2); 6566 val[2] = __SHIFTOUT(gpio, BWI_SPROM_GPIO_2);
6567 val[3] = __SHIFTOUT(gpio, BWI_SPROM_GPIO_3); 6567 val[3] = __SHIFTOUT(gpio, BWI_SPROM_GPIO_3);
6568 6568
6569 for (i = 0; i < BWI_LED_MAX; ++i) { 6569 for (i = 0; i < BWI_LED_MAX; ++i) {
6570 struct bwi_led *led = &sc->sc_leds[i]; 6570 struct bwi_led *led = &sc->sc_leds[i];
6571 6571
6572 if (val[i] == 0xff) { 6572 if (val[i] == 0xff) {
6573 led->l_act = led_act[i]; 6573 led->l_act = led_act[i];
6574 } else { 6574 } else {
6575 if (val[i] & BWI_LED_ACT_LOW) 6575 if (val[i] & BWI_LED_ACT_LOW)
6576 led->l_flags |= BWI_LED_F_ACTLOW; 6576 led->l_flags |= BWI_LED_F_ACTLOW;
6577 led->l_act = __SHIFTOUT(val[i], BWI_LED_ACT_MASK); 6577 led->l_act = __SHIFTOUT(val[i], BWI_LED_ACT_MASK);
6578 } 6578 }
6579 led->l_mask = (1 << i); 6579 led->l_mask = (1 << i);
6580 6580
6581 if (led->l_act == BWI_LED_ACT_BLINK_SLOW || 6581 if (led->l_act == BWI_LED_ACT_BLINK_SLOW ||
6582 led->l_act == BWI_LED_ACT_BLINK_POLL || 6582 led->l_act == BWI_LED_ACT_BLINK_POLL ||
6583 led->l_act == BWI_LED_ACT_BLINK) { 6583 led->l_act == BWI_LED_ACT_BLINK) {
6584 led->l_flags |= BWI_LED_F_BLINK; 6584 led->l_flags |= BWI_LED_F_BLINK;
6585 if (led->l_act == BWI_LED_ACT_BLINK_POLL) 6585 if (led->l_act == BWI_LED_ACT_BLINK_POLL)
6586 led->l_flags |= BWI_LED_F_POLLABLE; 6586 led->l_flags |= BWI_LED_F_POLLABLE;
6587 else if (led->l_act == BWI_LED_ACT_BLINK_SLOW) 6587 else if (led->l_act == BWI_LED_ACT_BLINK_SLOW)
6588 led->l_flags |= BWI_LED_F_SLOW; 6588 led->l_flags |= BWI_LED_F_SLOW;
6589 6589
6590 if (sc->sc_blink_led == NULL) { 6590 if (sc->sc_blink_led == NULL) {
6591 sc->sc_blink_led = led; 6591 sc->sc_blink_led = led;
6592 if (led->l_flags & BWI_LED_F_SLOW) 6592 if (led->l_flags & BWI_LED_F_SLOW)
6593 BWI_LED_SLOWDOWN(sc->sc_led_idle); 6593 BWI_LED_SLOWDOWN(sc->sc_led_idle);
6594 } 6594 }
6595 } 6595 }
6596 6596
6597 DPRINTF(sc, BWI_DBG_LED | BWI_DBG_ATTACH, 6597 DPRINTF(sc, BWI_DBG_LED | BWI_DBG_ATTACH,
6598 "%dth led, act %d, lowact %d\n", i, led->l_act, 6598 "%dth led, act %d, lowact %d\n", i, led->l_act,
6599 led->l_flags & BWI_LED_F_ACTLOW); 6599 led->l_flags & BWI_LED_F_ACTLOW);
6600 } 6600 }
6601 callout_init(&sc->sc_led_blink_ch, 0); 6601 callout_init(&sc->sc_led_blink_ch, 0);
6602} 6602}
6603 6603
6604static uint16_t 6604static uint16_t
6605bwi_led_onoff(const struct bwi_led *led, uint16_t val, int on) 6605bwi_led_onoff(const struct bwi_led *led, uint16_t val, int on)
6606{ 6606{
6607 if (led->l_flags & BWI_LED_F_ACTLOW) 6607 if (led->l_flags & BWI_LED_F_ACTLOW)
6608 on = !on; 6608 on = !on;
6609 if (on) 6609 if (on)
6610 val |= led->l_mask; 6610 val |= led->l_mask;
6611 else 6611 else
6612 val &= ~led->l_mask; 6612 val &= ~led->l_mask;
6613 6613
6614 return (val); 6614 return (val);
6615} 6615}
6616 6616
6617static void 6617static void
6618bwi_led_newstate(struct bwi_softc *sc, enum ieee80211_state nstate) 6618bwi_led_newstate(struct bwi_softc *sc, enum ieee80211_state nstate)
6619{ 6619{
6620 struct ieee80211com *ic = &sc->sc_ic; 6620 struct ieee80211com *ic = &sc->sc_ic;
6621 struct ifnet *ifp = &sc->sc_if; 6621 struct ifnet *ifp = &sc->sc_if;
6622 uint16_t val; 6622 uint16_t val;
6623 int i; 6623 int i;
6624 6624
6625 if (nstate == IEEE80211_S_INIT) { 6625 if (nstate == IEEE80211_S_INIT) {
6626 callout_stop(&sc->sc_led_blink_ch); 6626 callout_stop(&sc->sc_led_blink_ch);
6627 sc->sc_led_blinking = 0; 6627 sc->sc_led_blinking = 0;
6628 } 6628 }
6629 6629
6630 if ((ifp->if_flags & IFF_RUNNING) == 0) 6630 if ((ifp->if_flags & IFF_RUNNING) == 0)
6631 return; 6631 return;
6632 6632
6633 val = CSR_READ_2(sc, BWI_MAC_GPIO_CTRL); 6633 val = CSR_READ_2(sc, BWI_MAC_GPIO_CTRL);
6634 for (i = 0; i < BWI_LED_MAX; ++i) { 6634 for (i = 0; i < BWI_LED_MAX; ++i) {
6635 struct bwi_led *led = &sc->sc_leds[i]; 6635 struct bwi_led *led = &sc->sc_leds[i];
6636 int on; 6636 int on;
6637 6637
6638 if (led->l_act == BWI_LED_ACT_UNKN || 6638 if (led->l_act == BWI_LED_ACT_UNKN ||
6639 led->l_act == BWI_LED_ACT_NULL) 6639 led->l_act == BWI_LED_ACT_NULL)
6640 continue; 6640 continue;
6641 6641
6642 if ((led->l_flags & BWI_LED_F_BLINK) && 6642 if ((led->l_flags & BWI_LED_F_BLINK) &&
6643 nstate != IEEE80211_S_INIT) 6643 nstate != IEEE80211_S_INIT)
6644 continue; 6644 continue;
6645 6645
6646 switch (led->l_act) { 6646 switch (led->l_act) {
6647 case BWI_LED_ACT_ON: /* Always on */ 6647 case BWI_LED_ACT_ON: /* Always on */
6648 on = 1; 6648 on = 1;
6649 break; 6649 break;
6650 case BWI_LED_ACT_OFF: /* Always off */ 6650 case BWI_LED_ACT_OFF: /* Always off */
6651 case BWI_LED_ACT_5GHZ: /* TODO: 11A */ 6651 case BWI_LED_ACT_5GHZ: /* TODO: 11A */
6652 on = 0; 6652 on = 0;
6653 break; 6653 break;
6654 default: 6654 default:
6655 on = 1; 6655 on = 1;
6656 switch (nstate) { 6656 switch (nstate) {
6657 case IEEE80211_S_INIT: 6657 case IEEE80211_S_INIT:
6658 on = 0; 6658 on = 0;
6659 break; 6659 break;
6660 case IEEE80211_S_RUN: 6660 case IEEE80211_S_RUN:
6661 if (led->l_act == BWI_LED_ACT_11G && 6661 if (led->l_act == BWI_LED_ACT_11G &&
6662 ic->ic_curmode != IEEE80211_MODE_11G) 6662 ic->ic_curmode != IEEE80211_MODE_11G)
6663 on = 0; 6663 on = 0;
6664 break; 6664 break;
6665 default: 6665 default:
6666 if (led->l_act == BWI_LED_ACT_ASSOC) 6666 if (led->l_act == BWI_LED_ACT_ASSOC)
6667 on = 0; 6667 on = 0;
6668 break; 6668 break;
6669 } 6669 }
6670 break; 6670 break;
6671 } 6671 }
6672 6672
6673 val = bwi_led_onoff(led, val, on); 6673 val = bwi_led_onoff(led, val, on);
6674 } 6674 }
6675 CSR_WRITE_2(sc, BWI_MAC_GPIO_CTRL, val); 6675 CSR_WRITE_2(sc, BWI_MAC_GPIO_CTRL, val);
6676} 6676}
6677 6677
6678static void 6678static void
6679bwi_led_event(struct bwi_softc *sc, int event) 6679bwi_led_event(struct bwi_softc *sc, int event)
6680{ 6680{
6681 struct bwi_led *led = sc->sc_blink_led; 6681 struct bwi_led *led = sc->sc_blink_led;
6682 int rate; 6682 int rate;
6683 6683
6684 if (event == BWI_LED_EVENT_POLL) { 6684 if (event == BWI_LED_EVENT_POLL) {
6685 if ((led->l_flags & BWI_LED_F_POLLABLE) == 0) 6685 if ((led->l_flags & BWI_LED_F_POLLABLE) == 0)
6686 return; 6686 return;
6687 if (ticks - sc->sc_led_ticks < sc->sc_led_idle) 6687 if (ticks - sc->sc_led_ticks < sc->sc_led_idle)
6688 return; 6688 return;
6689 } 6689 }
6690 6690
6691 sc->sc_led_ticks = ticks; 6691 sc->sc_led_ticks = ticks;
6692 if (sc->sc_led_blinking) 6692 if (sc->sc_led_blinking)
6693 return; 6693 return;
6694 6694
6695 switch (event) { 6695 switch (event) {
6696 case BWI_LED_EVENT_RX: 6696 case BWI_LED_EVENT_RX:
6697 rate = sc->sc_rx_rate; 6697 rate = sc->sc_rx_rate;
6698 break; 6698 break;
6699 case BWI_LED_EVENT_TX: 6699 case BWI_LED_EVENT_TX:
6700 rate = sc->sc_tx_rate; 6700 rate = sc->sc_tx_rate;
6701 break; 6701 break;
6702 case BWI_LED_EVENT_POLL: 6702 case BWI_LED_EVENT_POLL:
6703 rate = 0; 6703 rate = 0;
6704 break; 6704 break;
6705 default: 6705 default:
6706 panic("unknown LED event %d\n", event); 6706 panic("unknown LED event %d\n", event);
6707 break; 6707 break;
6708 } 6708 }
6709 bwi_led_blink_start(sc, bwi_led_duration[rate].on_dur, 6709 bwi_led_blink_start(sc, bwi_led_duration[rate].on_dur,
6710 bwi_led_duration[rate].off_dur); 6710 bwi_led_duration[rate].off_dur);
6711} 6711}
6712 6712
6713static void 6713static void
6714bwi_led_blink_start(struct bwi_softc *sc, int on_dur, int off_dur) 6714bwi_led_blink_start(struct bwi_softc *sc, int on_dur, int off_dur)
6715{ 6715{
6716 struct bwi_led *led = sc->sc_blink_led; 6716 struct bwi_led *led = sc->sc_blink_led;
6717 uint16_t val; 6717 uint16_t val;
6718 6718
6719 val = CSR_READ_2(sc, BWI_MAC_GPIO_CTRL); 6719 val = CSR_READ_2(sc, BWI_MAC_GPIO_CTRL);
6720 val = bwi_led_onoff(led, val, 1); 6720 val = bwi_led_onoff(led, val, 1);
6721 CSR_WRITE_2(sc, BWI_MAC_GPIO_CTRL, val); 6721 CSR_WRITE_2(sc, BWI_MAC_GPIO_CTRL, val);
6722 6722
6723 if (led->l_flags & BWI_LED_F_SLOW) { 6723 if (led->l_flags & BWI_LED_F_SLOW) {
6724 BWI_LED_SLOWDOWN(on_dur); 6724 BWI_LED_SLOWDOWN(on_dur);
6725 BWI_LED_SLOWDOWN(off_dur); 6725 BWI_LED_SLOWDOWN(off_dur);
6726 } 6726 }
6727 6727
6728 sc->sc_led_blinking = 1; 6728 sc->sc_led_blinking = 1;
6729 sc->sc_led_blink_offdur = off_dur; 6729 sc->sc_led_blink_offdur = off_dur;
6730 6730
6731 callout_reset(&sc->sc_led_blink_ch, on_dur, bwi_led_blink_next, sc); 6731 callout_reset(&sc->sc_led_blink_ch, on_dur, bwi_led_blink_next, sc);
6732} 6732}
6733 6733
6734static void 6734static void
6735bwi_led_blink_next(void *xsc) 6735bwi_led_blink_next(void *xsc)
6736{ 6736{
6737 struct bwi_softc *sc = xsc; 6737 struct bwi_softc *sc = xsc;
6738 uint16_t val; 6738 uint16_t val;
6739 6739
6740 val = CSR_READ_2(sc, BWI_MAC_GPIO_CTRL); 6740 val = CSR_READ_2(sc, BWI_MAC_GPIO_CTRL);
6741 val = bwi_led_onoff(sc->sc_blink_led, val, 0); 6741 val = bwi_led_onoff(sc->sc_blink_led, val, 0);
6742 CSR_WRITE_2(sc, BWI_MAC_GPIO_CTRL, val); 6742 CSR_WRITE_2(sc, BWI_MAC_GPIO_CTRL, val);
6743 6743
6744 callout_reset(&sc->sc_led_blink_ch, sc->sc_led_blink_offdur, 6744 callout_reset(&sc->sc_led_blink_ch, sc->sc_led_blink_offdur,
6745 bwi_led_blink_end, sc); 6745 bwi_led_blink_end, sc);
6746} 6746}
6747 6747
6748static void 6748static void
6749bwi_led_blink_end(void *xsc) 6749bwi_led_blink_end(void *xsc)
6750{ 6750{
6751 struct bwi_softc *sc = xsc; 6751 struct bwi_softc *sc = xsc;
6752 6752
6753 sc->sc_led_blinking = 0; 6753 sc->sc_led_blinking = 0;
6754} 6754}
6755 6755
6756static int 6756static int
6757bwi_bbp_attach(struct bwi_softc *sc) 6757bwi_bbp_attach(struct bwi_softc *sc)
6758{ 6758{
6759 uint16_t bbp_id, rw_type; 6759 uint16_t bbp_id, rw_type;
6760 uint8_t rw_rev; 6760 uint8_t rw_rev;
6761 uint32_t info; 6761 uint32_t info;
6762 int error, nregwin, i; 6762 int error, nregwin, i;
6763 6763
6764 /* 6764 /*
6765 * Get 0th regwin information 6765 * Get 0th regwin information
6766 * NOTE: 0th regwin should exist 6766 * NOTE: 0th regwin should exist
6767 */ 6767 */
6768 error = bwi_regwin_select(sc, 0); 6768 error = bwi_regwin_select(sc, 0);
6769 if (error) { 6769 if (error) {
6770 aprint_error_dev(sc->sc_dev, "can't select regwin 0\n"); 6770 aprint_error_dev(sc->sc_dev, "can't select regwin 0\n");
6771 return (error); 6771 return (error);
6772 } 6772 }
6773 bwi_regwin_info(sc, &rw_type, &rw_rev); 6773 bwi_regwin_info(sc, &rw_type, &rw_rev);
6774 6774
6775 /* 6775 /*
6776 * Find out BBP id 6776 * Find out BBP id
6777 */ 6777 */
6778 bbp_id = 0; 6778 bbp_id = 0;
6779 info = 0; 6779 info = 0;
6780 if (rw_type == BWI_REGWIN_T_COM) { 6780 if (rw_type == BWI_REGWIN_T_COM) {
6781 info = CSR_READ_4(sc, BWI_INFO); 6781 info = CSR_READ_4(sc, BWI_INFO);
6782 bbp_id = __SHIFTOUT(info, BWI_INFO_BBPID_MASK); 6782 bbp_id = __SHIFTOUT(info, BWI_INFO_BBPID_MASK);
6783 6783
6784 BWI_CREATE_REGWIN(&sc->sc_com_regwin, 0, rw_type, rw_rev); 6784 BWI_CREATE_REGWIN(&sc->sc_com_regwin, 0, rw_type, rw_rev);
6785 6785
6786 sc->sc_cap = CSR_READ_4(sc, BWI_CAPABILITY); 6786 sc->sc_cap = CSR_READ_4(sc, BWI_CAPABILITY);
6787 } else { 6787 } else {
6788 uint16_t did = sc->sc_pci_did; 6788 uint16_t did = sc->sc_pci_did;
6789 uint8_t revid = sc->sc_pci_revid; 6789 uint8_t revid = sc->sc_pci_revid;
6790 6790
6791 for (i = 0; i < __arraycount(bwi_bbpid_map); ++i) { 6791 for (i = 0; i < __arraycount(bwi_bbpid_map); ++i) {
6792 if (did >= bwi_bbpid_map[i].did_min && 6792 if (did >= bwi_bbpid_map[i].did_min &&
6793 did <= bwi_bbpid_map[i].did_max) { 6793 did <= bwi_bbpid_map[i].did_max) {
6794 bbp_id = bwi_bbpid_map[i].bbp_id; 6794 bbp_id = bwi_bbpid_map[i].bbp_id;
6795 break; 6795 break;
6796 } 6796 }
6797 } 6797 }
6798 if (bbp_id == 0) { 6798 if (bbp_id == 0) {
6799 aprint_error_dev(sc->sc_dev, "no BBP id for device id" 6799 aprint_error_dev(sc->sc_dev, "no BBP id for device id"
6800 " 0x%04x\n", did); 6800 " 0x%04x\n", did);
6801 return (ENXIO); 6801 return (ENXIO);
6802 } 6802 }
6803 6803
6804 info = __SHIFTIN(revid, BWI_INFO_BBPREV_MASK) | 6804 info = __SHIFTIN(revid, BWI_INFO_BBPREV_MASK) |
6805 __SHIFTIN(0, BWI_INFO_BBPPKG_MASK); 6805 __SHIFTIN(0, BWI_INFO_BBPPKG_MASK);
6806 } 6806 }
6807 6807
6808 /* 6808 /*
6809 * Find out number of regwins 6809 * Find out number of regwins
6810 */ 6810 */
6811 nregwin = 0; 6811 nregwin = 0;
6812 if (rw_type == BWI_REGWIN_T_COM && rw_rev >= 4) { 6812 if (rw_type == BWI_REGWIN_T_COM && rw_rev >= 4) {
6813 nregwin = __SHIFTOUT(info, BWI_INFO_NREGWIN_MASK); 6813 nregwin = __SHIFTOUT(info, BWI_INFO_NREGWIN_MASK);
6814 } else { 6814 } else {
6815 for (i = 0; i < __arraycount(bwi_regwin_count); ++i) { 6815 for (i = 0; i < __arraycount(bwi_regwin_count); ++i) {
6816 if (bwi_regwin_count[i].bbp_id == bbp_id) { 6816 if (bwi_regwin_count[i].bbp_id == bbp_id) {
6817 nregwin = bwi_regwin_count[i].nregwin; 6817 nregwin = bwi_regwin_count[i].nregwin;
6818 break; 6818 break;
6819 } 6819 }
6820 } 6820 }
6821 if (nregwin == 0) { 6821 if (nregwin == 0) {
6822 aprint_error_dev(sc->sc_dev, "no number of win for" 6822 aprint_error_dev(sc->sc_dev, "no number of win for"
6823 " BBP id 0x%04x\n", bbp_id); 6823 " BBP id 0x%04x\n", bbp_id);
6824 return (ENXIO); 6824 return (ENXIO);
6825 } 6825 }
6826 } 6826 }
6827 6827
6828 /* Record BBP id/rev for later using */ 6828 /* Record BBP id/rev for later using */
6829 sc->sc_bbp_id = bbp_id; 6829 sc->sc_bbp_id = bbp_id;
6830 sc->sc_bbp_rev = __SHIFTOUT(info, BWI_INFO_BBPREV_MASK); 6830 sc->sc_bbp_rev = __SHIFTOUT(info, BWI_INFO_BBPREV_MASK);
6831 sc->sc_bbp_pkg = __SHIFTOUT(info, BWI_INFO_BBPPKG_MASK); 6831 sc->sc_bbp_pkg = __SHIFTOUT(info, BWI_INFO_BBPPKG_MASK);
6832 aprint_normal_dev(sc->sc_dev, 6832 aprint_normal_dev(sc->sc_dev,
6833 "BBP id 0x%04x, BBP rev 0x%x, BBP pkg %d\n", 6833 "BBP id 0x%04x, BBP rev 0x%x, BBP pkg %d\n",
6834 sc->sc_bbp_id, sc->sc_bbp_rev, sc->sc_bbp_pkg); 6834 sc->sc_bbp_id, sc->sc_bbp_rev, sc->sc_bbp_pkg);
6835 DPRINTF(sc, BWI_DBG_ATTACH, "nregwin %d, cap 0x%08x\n", 6835 DPRINTF(sc, BWI_DBG_ATTACH, "nregwin %d, cap 0x%08x\n",
6836 nregwin, sc->sc_cap); 6836 nregwin, sc->sc_cap);
6837 6837
6838 /* 6838 /*
6839 * Create rest of the regwins 6839 * Create rest of the regwins
6840 */ 6840 */
6841 6841
6842 /* Don't re-create common regwin, if it is already created */ 6842 /* Don't re-create common regwin, if it is already created */
6843 i = BWI_REGWIN_EXIST(&sc->sc_com_regwin) ? 1 : 0; 6843 i = BWI_REGWIN_EXIST(&sc->sc_com_regwin) ? 1 : 0;
6844 6844
6845 for (; i < nregwin; ++i) { 6845 for (; i < nregwin; ++i) {
6846 /* 6846 /*
6847 * Get regwin information 6847 * Get regwin information
6848 */ 6848 */
6849 error = bwi_regwin_select(sc, i); 6849 error = bwi_regwin_select(sc, i);
6850 if (error) { 6850 if (error) {
6851 aprint_error_dev(sc->sc_dev, "can't select regwin" 6851 aprint_error_dev(sc->sc_dev, "can't select regwin"
6852 " %d\n", i); 6852 " %d\n", i);
6853 return (error); 6853 return (error);
6854 } 6854 }
6855 bwi_regwin_info(sc, &rw_type, &rw_rev); 6855 bwi_regwin_info(sc, &rw_type, &rw_rev);
6856 6856
6857 /* 6857 /*
6858 * Try attach: 6858 * Try attach:
6859 * 1) Bus (PCI/PCIE) regwin 6859 * 1) Bus (PCI/PCIE) regwin
6860 * 2) MAC regwin 6860 * 2) MAC regwin
6861 * Ignore rest types of regwin 6861 * Ignore rest types of regwin
6862 */ 6862 */
6863 if (rw_type == BWI_REGWIN_T_BUSPCI || 6863 if (rw_type == BWI_REGWIN_T_BUSPCI ||
6864 rw_type == BWI_REGWIN_T_BUSPCIE) { 6864 rw_type == BWI_REGWIN_T_BUSPCIE) {
6865 if (BWI_REGWIN_EXIST(&sc->sc_bus_regwin)) { 6865 if (BWI_REGWIN_EXIST(&sc->sc_bus_regwin)) {
6866 aprint_error_dev(sc->sc_dev, 6866 aprint_error_dev(sc->sc_dev,
6867 "bus regwin already exists\n"); 6867 "bus regwin already exists\n");
6868 } else { 6868 } else {
6869 BWI_CREATE_REGWIN(&sc->sc_bus_regwin, i, 6869 BWI_CREATE_REGWIN(&sc->sc_bus_regwin, i,
6870 rw_type, rw_rev); 6870 rw_type, rw_rev);
6871 } 6871 }
6872 } else if (rw_type == BWI_REGWIN_T_MAC) { 6872 } else if (rw_type == BWI_REGWIN_T_MAC) {
6873 /* XXX ignore return value */ 6873 /* XXX ignore return value */
6874 bwi_mac_attach(sc, i, rw_rev); 6874 bwi_mac_attach(sc, i, rw_rev);
6875 } 6875 }
6876 } 6876 }
6877 6877
6878 /* At least one MAC shold exist */ 6878 /* At least one MAC shold exist */
6879 if (!BWI_REGWIN_EXIST(&sc->sc_mac[0].mac_regwin)) { 6879 if (!BWI_REGWIN_EXIST(&sc->sc_mac[0].mac_regwin)) {
6880 aprint_error_dev(sc->sc_dev, "no MAC was found\n"); 6880 aprint_error_dev(sc->sc_dev, "no MAC was found\n");
6881 return (ENXIO); 6881 return (ENXIO);
6882 } 6882 }
6883 KASSERT(sc->sc_nmac > 0); 6883 KASSERT(sc->sc_nmac > 0);
6884 6884
6885 /* Bus regwin must exist */ 6885 /* Bus regwin must exist */
6886 if (!BWI_REGWIN_EXIST(&sc->sc_bus_regwin)) { 6886 if (!BWI_REGWIN_EXIST(&sc->sc_bus_regwin)) {
6887 aprint_error_dev(sc->sc_dev, "no bus regwin was found\n"); 6887 aprint_error_dev(sc->sc_dev, "no bus regwin was found\n");
6888 return (ENXIO); 6888 return (ENXIO);
6889 } 6889 }
6890 6890
6891 /* Start with first MAC */ 6891 /* Start with first MAC */
6892 error = bwi_regwin_switch(sc, &sc->sc_mac[0].mac_regwin, NULL); 6892 error = bwi_regwin_switch(sc, &sc->sc_mac[0].mac_regwin, NULL);
6893 if (error) 6893 if (error)
6894 return (error); 6894 return (error);
6895 6895
6896 return (0); 6896 return (0);
6897} 6897}
6898 6898
6899static int 6899static int
6900bwi_bus_init(struct bwi_softc *sc, struct bwi_mac *mac) 6900bwi_bus_init(struct bwi_softc *sc, struct bwi_mac *mac)
6901{ 6901{
6902 struct bwi_regwin *old, *bus; 6902 struct bwi_regwin *old, *bus;
6903 uint32_t val; 6903 uint32_t val;
6904 int error; 6904 int error;
6905 6905
6906 bus = &sc->sc_bus_regwin; 6906 bus = &sc->sc_bus_regwin;
6907 KASSERT(sc->sc_cur_regwin == &mac->mac_regwin); 6907 KASSERT(sc->sc_cur_regwin == &mac->mac_regwin);
6908 6908
6909 /* 6909 /*
6910 * Tell bus to generate requested interrupts 6910 * Tell bus to generate requested interrupts
6911 */ 6911 */
6912 if (bus->rw_rev < 6 && bus->rw_type == BWI_REGWIN_T_BUSPCI) { 6912 if (bus->rw_rev < 6 && bus->rw_type == BWI_REGWIN_T_BUSPCI) {
6913 /* 6913 /*
6914 * NOTE: Read BWI_FLAGS from MAC regwin 6914 * NOTE: Read BWI_FLAGS from MAC regwin
6915 */ 6915 */
6916 val = CSR_READ_4(sc, BWI_FLAGS); 6916 val = CSR_READ_4(sc, BWI_FLAGS);
6917 6917
6918 error = bwi_regwin_switch(sc, bus, &old); 6918 error = bwi_regwin_switch(sc, bus, &old);
6919 if (error) 6919 if (error)
6920 return (error); 6920 return (error);
6921 6921
6922 CSR_SETBITS_4(sc, BWI_INTRVEC, (val & BWI_FLAGS_INTR_MASK)); 6922 CSR_SETBITS_4(sc, BWI_INTRVEC, (val & BWI_FLAGS_INTR_MASK));
6923 } else { 6923 } else {
6924 uint32_t mac_mask; 6924 uint32_t mac_mask;
6925 6925
6926 mac_mask = 1 << mac->mac_id; 6926 mac_mask = 1 << mac->mac_id;
6927 6927
6928 error = bwi_regwin_switch(sc, bus, &old); 6928 error = bwi_regwin_switch(sc, bus, &old);
6929 if (error) 6929 if (error)
6930 return (error); 6930 return (error);
6931 6931
6932 val = (sc->sc_conf_read)(sc, BWI_PCIR_INTCTL); 6932 val = (sc->sc_conf_read)(sc, BWI_PCIR_INTCTL);
6933 val |= mac_mask << 8; 6933 val |= mac_mask << 8;
6934 (sc->sc_conf_write)(sc, BWI_PCIR_INTCTL, val); 6934 (sc->sc_conf_write)(sc, BWI_PCIR_INTCTL, val);
6935 } 6935 }
6936 6936
6937 if (sc->sc_flags & BWI_F_BUS_INITED) 6937 if (sc->sc_flags & BWI_F_BUS_INITED)
6938 goto back; 6938 goto back;
6939 6939
6940 if (bus->rw_type == BWI_REGWIN_T_BUSPCI) { 6940 if (bus->rw_type == BWI_REGWIN_T_BUSPCI) {
6941 /* 6941 /*
6942 * Enable prefetch and burst 6942 * Enable prefetch and burst
6943 */ 6943 */
6944 CSR_SETBITS_4(sc, BWI_BUS_CONFIG, 6944 CSR_SETBITS_4(sc, BWI_BUS_CONFIG,
6945 BWI_BUS_CONFIG_PREFETCH | BWI_BUS_CONFIG_BURST); 6945 BWI_BUS_CONFIG_PREFETCH | BWI_BUS_CONFIG_BURST);
6946 6946
6947 if (bus->rw_rev < 5) { 6947 if (bus->rw_rev < 5) {
6948 struct bwi_regwin *com = &sc->sc_com_regwin; 6948 struct bwi_regwin *com = &sc->sc_com_regwin;
6949 6949
6950 /* 6950 /*
6951 * Configure timeouts for bus operation 6951 * Configure timeouts for bus operation
6952 */ 6952 */
6953 6953
6954 /* 6954 /*
6955 * Set service timeout and request timeout 6955 * Set service timeout and request timeout
6956 */ 6956 */
6957 CSR_SETBITS_4(sc, BWI_CONF_LO, 6957 CSR_SETBITS_4(sc, BWI_CONF_LO,
6958 __SHIFTIN(BWI_CONF_LO_SERVTO, 6958 __SHIFTIN(BWI_CONF_LO_SERVTO,
6959 BWI_CONF_LO_SERVTO_MASK) | 6959 BWI_CONF_LO_SERVTO_MASK) |
6960 __SHIFTIN(BWI_CONF_LO_REQTO, 6960 __SHIFTIN(BWI_CONF_LO_REQTO,
6961 BWI_CONF_LO_REQTO_MASK)); 6961 BWI_CONF_LO_REQTO_MASK));
6962 6962
6963 /* 6963 /*
6964 * If there is common regwin, we switch to that regwin 6964 * If there is common regwin, we switch to that regwin
6965 * and switch back to bus regwin once we have done. 6965 * and switch back to bus regwin once we have done.
6966 */ 6966 */
6967 if (BWI_REGWIN_EXIST(com)) { 6967 if (BWI_REGWIN_EXIST(com)) {
6968 error = bwi_regwin_switch(sc, com, NULL); 6968 error = bwi_regwin_switch(sc, com, NULL);
6969 if (error) 6969 if (error)
6970 return (error); 6970 return (error);
6971 } 6971 }
6972 6972
6973 /* Let bus know what we have changed */ 6973 /* Let bus know what we have changed */
6974 CSR_WRITE_4(sc, BWI_BUS_ADDR, BWI_BUS_ADDR_MAGIC); 6974 CSR_WRITE_4(sc, BWI_BUS_ADDR, BWI_BUS_ADDR_MAGIC);
6975 CSR_READ_4(sc, BWI_BUS_ADDR); /* Flush */ 6975 CSR_READ_4(sc, BWI_BUS_ADDR); /* Flush */
6976 CSR_WRITE_4(sc, BWI_BUS_DATA, 0); 6976 CSR_WRITE_4(sc, BWI_BUS_DATA, 0);
6977 CSR_READ_4(sc, BWI_BUS_DATA); /* Flush */ 6977 CSR_READ_4(sc, BWI_BUS_DATA); /* Flush */
6978 6978
6979 if (BWI_REGWIN_EXIST(com)) { 6979 if (BWI_REGWIN_EXIST(com)) {
6980 error = bwi_regwin_switch(sc, bus, NULL); 6980 error = bwi_regwin_switch(sc, bus, NULL);
6981 if (error) 6981 if (error)
6982 return (error); 6982 return (error);
6983 } 6983 }
6984 } else if (bus->rw_rev >= 11) { 6984 } else if (bus->rw_rev >= 11) {
6985 /* 6985 /*
6986 * Enable memory read multiple 6986 * Enable memory read multiple
6987 */ 6987 */
6988 CSR_SETBITS_4(sc, BWI_BUS_CONFIG, BWI_BUS_CONFIG_MRM); 6988 CSR_SETBITS_4(sc, BWI_BUS_CONFIG, BWI_BUS_CONFIG_MRM);
6989 } 6989 }
6990 } else { 6990 } else {
6991 /* TODO: PCIE */ 6991 /* TODO: PCIE */
6992 } 6992 }
6993 6993
6994 sc->sc_flags |= BWI_F_BUS_INITED; 6994 sc->sc_flags |= BWI_F_BUS_INITED;
6995back: 6995back:
6996 return (bwi_regwin_switch(sc, old, NULL)); 6996 return (bwi_regwin_switch(sc, old, NULL));
6997} 6997}
6998 6998
6999static void 6999static void
7000bwi_get_card_flags(struct bwi_softc *sc) 7000bwi_get_card_flags(struct bwi_softc *sc)
7001{ 7001{
7002 sc->sc_card_flags = bwi_read_sprom(sc, BWI_SPROM_CARD_FLAGS); 7002 sc->sc_card_flags = bwi_read_sprom(sc, BWI_SPROM_CARD_FLAGS);
7003 if (sc->sc_card_flags == 0xffff) 7003 if (sc->sc_card_flags == 0xffff)
7004 sc->sc_card_flags = 0; 7004 sc->sc_card_flags = 0;
7005 7005
7006 if (sc->sc_pci_subvid == PCI_VENDOR_APPLE && 7006 if (sc->sc_pci_subvid == PCI_VENDOR_APPLE &&
7007 sc->sc_pci_subdid == 0x4e && /* XXX */ 7007 sc->sc_pci_subdid == 0x4e && /* XXX */
7008 sc->sc_pci_revid > 0x40) 7008 sc->sc_pci_revid > 0x40)
7009 sc->sc_card_flags |= BWI_CARD_F_PA_GPIO9; 7009 sc->sc_card_flags |= BWI_CARD_F_PA_GPIO9;
7010 7010
7011 DPRINTF(sc, BWI_DBG_ATTACH, "card flags 0x%04x\n", sc->sc_card_flags); 7011 DPRINTF(sc, BWI_DBG_ATTACH, "card flags 0x%04x\n", sc->sc_card_flags);
7012} 7012}
7013 7013
7014static void 7014static void
7015bwi_get_eaddr(struct bwi_softc *sc, uint16_t eaddr_ofs, uint8_t *eaddr) 7015bwi_get_eaddr(struct bwi_softc *sc, uint16_t eaddr_ofs, uint8_t *eaddr)
7016{ 7016{
7017 int i; 7017 int i;
7018 7018
7019 for (i = 0; i < 3; ++i) { 7019 for (i = 0; i < 3; ++i) {
7020 *((uint16_t *)eaddr + i) = 7020 *((uint16_t *)eaddr + i) =
7021 htobe16(bwi_read_sprom(sc, eaddr_ofs + 2 * i)); 7021 htobe16(bwi_read_sprom(sc, eaddr_ofs + 2 * i));
7022 } 7022 }
7023} 7023}
7024 7024
7025static void 7025static void
7026bwi_get_clock_freq(struct bwi_softc *sc, struct bwi_clock_freq *freq) 7026bwi_get_clock_freq(struct bwi_softc *sc, struct bwi_clock_freq *freq)
7027{ 7027{
7028 struct bwi_regwin *com; 7028 struct bwi_regwin *com;
7029 uint32_t val; 7029 uint32_t val;
7030 uint div; 7030 uint div;
7031 int src; 7031 int src;
7032 7032
7033 memset(freq, 0, sizeof(*freq)); 7033 memset(freq, 0, sizeof(*freq));
7034 com = &sc->sc_com_regwin; 7034 com = &sc->sc_com_regwin;
7035 7035
7036 KASSERT(BWI_REGWIN_EXIST(com)); 7036 KASSERT(BWI_REGWIN_EXIST(com));
7037 KASSERT(sc->sc_cur_regwin == com); 7037 KASSERT(sc->sc_cur_regwin == com);
7038 KASSERT(sc->sc_cap & BWI_CAP_CLKMODE); 7038 KASSERT(sc->sc_cap & BWI_CAP_CLKMODE);
7039 7039
7040 /* 7040 /*
7041 * Calculate clock frequency 7041 * Calculate clock frequency
7042 */ 7042 */
7043 src = -1; 7043 src = -1;
7044 div = 0; 7044 div = 0;
7045 if (com->rw_rev < 6) { 7045 if (com->rw_rev < 6) {
7046 val = (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_OUT); 7046 val = (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_OUT);
7047 if (val & BWI_PCIM_GPIO_OUT_CLKSRC) { 7047 if (val & BWI_PCIM_GPIO_OUT_CLKSRC) {
7048 src = BWI_CLKSRC_PCI; 7048 src = BWI_CLKSRC_PCI;
7049 div = 64; 7049 div = 64;
7050 } else { 7050 } else {
7051 src = BWI_CLKSRC_CS_OSC; 7051 src = BWI_CLKSRC_CS_OSC;
7052 div = 32; 7052 div = 32;
7053 } 7053 }
7054 } else if (com->rw_rev < 10) { 7054 } else if (com->rw_rev < 10) {
7055 val = CSR_READ_4(sc, BWI_CLOCK_CTRL); 7055 val = CSR_READ_4(sc, BWI_CLOCK_CTRL);
7056 7056
7057 src = __SHIFTOUT(val, BWI_CLOCK_CTRL_CLKSRC); 7057 src = __SHIFTOUT(val, BWI_CLOCK_CTRL_CLKSRC);
7058 if (src == BWI_CLKSRC_LP_OSC) 7058 if (src == BWI_CLKSRC_LP_OSC)
7059 div = 1; 7059 div = 1;
7060 else { 7060 else {
7061 div = (__SHIFTOUT(val, BWI_CLOCK_CTRL_FDIV) + 1) << 2; 7061 div = (__SHIFTOUT(val, BWI_CLOCK_CTRL_FDIV) + 1) << 2;
7062 7062
7063 /* Unknown source */ 7063 /* Unknown source */
7064 if (src >= BWI_CLKSRC_MAX) 7064 if (src >= BWI_CLKSRC_MAX)
7065 src = BWI_CLKSRC_CS_OSC; 7065 src = BWI_CLKSRC_CS_OSC;
7066 } 7066 }
7067 } else { 7067 } else {
7068 val = CSR_READ_4(sc, BWI_CLOCK_INFO); 7068 val = CSR_READ_4(sc, BWI_CLOCK_INFO);
7069 7069
7070 src = BWI_CLKSRC_CS_OSC; 7070 src = BWI_CLKSRC_CS_OSC;
7071 div = (__SHIFTOUT(val, BWI_CLOCK_INFO_FDIV) + 1) << 2; 7071 div = (__SHIFTOUT(val, BWI_CLOCK_INFO_FDIV) + 1) << 2;
7072 } 7072 }
7073 7073
7074 KASSERT(src >= 0 && src < BWI_CLKSRC_MAX); 7074 KASSERT(src >= 0 && src < BWI_CLKSRC_MAX);
7075 KASSERT(div != 0); 7075 KASSERT(div != 0);
7076 7076
7077 DPRINTF(sc, BWI_DBG_ATTACH, "clksrc %s\n", 7077 DPRINTF(sc, BWI_DBG_ATTACH, "clksrc %s\n",
7078 src == BWI_CLKSRC_PCI ? "PCI" : 7078 src == BWI_CLKSRC_PCI ? "PCI" :
7079 (src == BWI_CLKSRC_LP_OSC ? "LP_OSC" : "CS_OSC")); 7079 (src == BWI_CLKSRC_LP_OSC ? "LP_OSC" : "CS_OSC"));
7080 7080
7081 freq->clkfreq_min = bwi_clkfreq[src].freq_min / div; 7081 freq->clkfreq_min = bwi_clkfreq[src].freq_min / div;
7082 freq->clkfreq_max = bwi_clkfreq[src].freq_max / div; 7082 freq->clkfreq_max = bwi_clkfreq[src].freq_max / div;
7083 7083
7084 DPRINTF(sc, BWI_DBG_ATTACH, "clkfreq min %u, max %u\n", 7084 DPRINTF(sc, BWI_DBG_ATTACH, "clkfreq min %u, max %u\n",
7085 freq->clkfreq_min, freq->clkfreq_max); 7085 freq->clkfreq_min, freq->clkfreq_max);
7086} 7086}
7087 7087
7088static int 7088static int
7089bwi_set_clock_mode(struct bwi_softc *sc, enum bwi_clock_mode clk_mode) 7089bwi_set_clock_mode(struct bwi_softc *sc, enum bwi_clock_mode clk_mode)
7090{ 7090{
7091 struct bwi_regwin *old, *com; 7091 struct bwi_regwin *old, *com;
7092 uint32_t clk_ctrl, clk_src; 7092 uint32_t clk_ctrl, clk_src;
7093 int error, pwr_off = 0; 7093 int error, pwr_off = 0;
7094 7094
7095 com = &sc->sc_com_regwin; 7095 com = &sc->sc_com_regwin;
7096 if (!BWI_REGWIN_EXIST(com)) 7096 if (!BWI_REGWIN_EXIST(com))
7097 return (0); 7097 return (0);
7098 7098
7099 if (com->rw_rev >= 10 || com->rw_rev < 6) 7099 if (com->rw_rev >= 10 || com->rw_rev < 6)
7100 return (0); 7100 return (0);
7101 7101
7102 /* 7102 /*
7103 * For common regwin whose rev is [6, 10), the chip 7103 * For common regwin whose rev is [6, 10), the chip
7104 * must be capable to change clock mode. 7104 * must be capable to change clock mode.
7105 */ 7105 */
7106 if ((sc->sc_cap & BWI_CAP_CLKMODE) == 0) 7106 if ((sc->sc_cap & BWI_CAP_CLKMODE) == 0)
7107 return (0); 7107 return (0);
7108 7108
7109 error = bwi_regwin_switch(sc, com, &old); 7109 error = bwi_regwin_switch(sc, com, &old);
7110 if (error) 7110 if (error)
7111 return (error); 7111 return (error);
7112 7112
7113 if (clk_mode == BWI_CLOCK_MODE_FAST) 7113 if (clk_mode == BWI_CLOCK_MODE_FAST)
7114 bwi_power_on(sc, 0); /* Don't turn on PLL */ 7114 bwi_power_on(sc, 0); /* Don't turn on PLL */
7115 7115
7116 clk_ctrl = CSR_READ_4(sc, BWI_CLOCK_CTRL); 7116 clk_ctrl = CSR_READ_4(sc, BWI_CLOCK_CTRL);
7117 clk_src = __SHIFTOUT(clk_ctrl, BWI_CLOCK_CTRL_CLKSRC); 7117 clk_src = __SHIFTOUT(clk_ctrl, BWI_CLOCK_CTRL_CLKSRC);
7118 7118
7119 switch (clk_mode) { 7119 switch (clk_mode) {
7120 case BWI_CLOCK_MODE_FAST: 7120 case BWI_CLOCK_MODE_FAST:
7121 clk_ctrl &= ~BWI_CLOCK_CTRL_SLOW; 7121 clk_ctrl &= ~BWI_CLOCK_CTRL_SLOW;
7122 clk_ctrl |= BWI_CLOCK_CTRL_IGNPLL; 7122 clk_ctrl |= BWI_CLOCK_CTRL_IGNPLL;
7123 break; 7123 break;
7124 case BWI_CLOCK_MODE_SLOW: 7124 case BWI_CLOCK_MODE_SLOW:
7125 clk_ctrl |= BWI_CLOCK_CTRL_SLOW; 7125 clk_ctrl |= BWI_CLOCK_CTRL_SLOW;
7126 break; 7126 break;
7127 case BWI_CLOCK_MODE_DYN: 7127 case BWI_CLOCK_MODE_DYN:
7128 clk_ctrl &= ~(BWI_CLOCK_CTRL_SLOW | 7128 clk_ctrl &= ~(BWI_CLOCK_CTRL_SLOW |
7129 BWI_CLOCK_CTRL_IGNPLL | 7129 BWI_CLOCK_CTRL_IGNPLL |
7130 BWI_CLOCK_CTRL_NODYN); 7130 BWI_CLOCK_CTRL_NODYN);
7131 if (clk_src != BWI_CLKSRC_CS_OSC) { 7131 if (clk_src != BWI_CLKSRC_CS_OSC) {
7132 clk_ctrl |= BWI_CLOCK_CTRL_NODYN; 7132 clk_ctrl |= BWI_CLOCK_CTRL_NODYN;
7133 pwr_off = 1; 7133 pwr_off = 1;
7134 } 7134 }
7135 break; 7135 break;
7136 } 7136 }
7137 CSR_WRITE_4(sc, BWI_CLOCK_CTRL, clk_ctrl); 7137 CSR_WRITE_4(sc, BWI_CLOCK_CTRL, clk_ctrl);
7138 7138
7139 if (pwr_off) 7139 if (pwr_off)
7140 bwi_power_off(sc, 0); /* Leave PLL as it is */ 7140 bwi_power_off(sc, 0); /* Leave PLL as it is */
7141 7141
7142 return (bwi_regwin_switch(sc, old, NULL)); 7142 return (bwi_regwin_switch(sc, old, NULL));
7143} 7143}
7144 7144
7145static int 7145static int
7146bwi_set_clock_delay(struct bwi_softc *sc) 7146bwi_set_clock_delay(struct bwi_softc *sc)
7147{ 7147{
7148 struct bwi_regwin *old, *com; 7148 struct bwi_regwin *old, *com;
7149 int error; 7149 int error;
7150 7150
7151 com = &sc->sc_com_regwin; 7151 com = &sc->sc_com_regwin;
7152 if (!BWI_REGWIN_EXIST(com)) 7152 if (!BWI_REGWIN_EXIST(com))
7153 return (0); 7153 return (0);
7154 7154
7155 error = bwi_regwin_switch(sc, com, &old); 7155 error = bwi_regwin_switch(sc, com, &old);
7156 if (error) 7156 if (error)
7157 return (error); 7157 return (error);
7158 7158
7159 if (sc->sc_bbp_id == BWI_BBPID_BCM4321) { 7159 if (sc->sc_bbp_id == BWI_BBPID_BCM4321) {
7160 if (sc->sc_bbp_rev == 0) 7160 if (sc->sc_bbp_rev == 0)
7161 CSR_WRITE_4(sc, BWI_CONTROL, BWI_CONTROL_MAGIC0); 7161 CSR_WRITE_4(sc, BWI_CONTROL, BWI_CONTROL_MAGIC0);
7162 else if (sc->sc_bbp_rev == 1) 7162 else if (sc->sc_bbp_rev == 1)
7163 CSR_WRITE_4(sc, BWI_CONTROL, BWI_CONTROL_MAGIC1); 7163 CSR_WRITE_4(sc, BWI_CONTROL, BWI_CONTROL_MAGIC1);
7164 } 7164 }
7165 7165
7166 if (sc->sc_cap & BWI_CAP_CLKMODE) { 7166 if (sc->sc_cap & BWI_CAP_CLKMODE) {
7167 if (com->rw_rev >= 10) 7167 if (com->rw_rev >= 10)
7168 CSR_FILT_SETBITS_4(sc, BWI_CLOCK_INFO, 0xffff, 0x40000); 7168 CSR_FILT_SETBITS_4(sc, BWI_CLOCK_INFO, 0xffff, 0x40000);
7169 else { 7169 else {
7170 struct bwi_clock_freq freq; 7170 struct bwi_clock_freq freq;
7171 7171
7172 bwi_get_clock_freq(sc, &freq); 7172 bwi_get_clock_freq(sc, &freq);
7173 CSR_WRITE_4(sc, BWI_PLL_ON_DELAY, 7173 CSR_WRITE_4(sc, BWI_PLL_ON_DELAY,
7174 howmany(freq.clkfreq_max * 150, 1000000)); 7174 howmany(freq.clkfreq_max * 150, 1000000));
7175 CSR_WRITE_4(sc, BWI_FREQ_SEL_DELAY, 7175 CSR_WRITE_4(sc, BWI_FREQ_SEL_DELAY,
7176 howmany(freq.clkfreq_max * 15, 1000000)); 7176 howmany(freq.clkfreq_max * 15, 1000000));
7177 } 7177 }
7178 } 7178 }
7179 7179
7180 return (bwi_regwin_switch(sc, old, NULL)); 7180 return (bwi_regwin_switch(sc, old, NULL));
7181} 7181}
7182 7182
7183static int 7183static int
7184bwi_init(struct ifnet *ifp) 7184bwi_init(struct ifnet *ifp)
7185{ 7185{
7186 struct bwi_softc *sc = ifp->if_softc; 7186 struct bwi_softc *sc = ifp->if_softc;
7187 7187
7188 bwi_init_statechg(sc, 1); 7188 bwi_init_statechg(sc, 1);
7189 7189
7190 return (0); 7190 return (0);
7191} 7191}
7192 7192
7193static void 7193static void
7194bwi_init_statechg(struct bwi_softc *sc, int statechg) 7194bwi_init_statechg(struct bwi_softc *sc, int statechg)
7195{ 7195{
7196 struct ieee80211com *ic = &sc->sc_ic; 7196 struct ieee80211com *ic = &sc->sc_ic;
7197 struct ifnet *ifp = &sc->sc_if; 7197 struct ifnet *ifp = &sc->sc_if;
7198 struct bwi_mac *mac; 7198 struct bwi_mac *mac;
7199 int error; 7199 int error;
7200 7200
7201 DPRINTF(sc, BWI_DBG_MISC, "%s\n", __func__); 7201 DPRINTF(sc, BWI_DBG_MISC, "%s\n", __func__);
7202 7202
7203 bwi_stop(ifp, statechg); 7203 bwi_stop(ifp, statechg);
7204 7204
7205 /* power on cardbus socket */ 7205 /* power on cardbus socket */
7206 if (sc->sc_enable != NULL) 7206 if (sc->sc_enable != NULL)
7207 (sc->sc_enable)(sc, 0); 7207 (sc->sc_enable)(sc, 0);
7208 7208
7209 bwi_bbp_power_on(sc, BWI_CLOCK_MODE_FAST); 7209 bwi_bbp_power_on(sc, BWI_CLOCK_MODE_FAST);
7210 7210
7211 /* TODO: 2 MAC */ 7211 /* TODO: 2 MAC */
7212 7212
7213 mac = &sc->sc_mac[0]; 7213 mac = &sc->sc_mac[0];
7214 error = bwi_regwin_switch(sc, &mac->mac_regwin, NULL); 7214 error = bwi_regwin_switch(sc, &mac->mac_regwin, NULL);
7215 if (error) 7215 if (error)
7216 goto back; 7216 goto back;
7217 7217
7218 error = bwi_mac_init(mac); 7218 error = bwi_mac_init(mac);
7219 if (error) 7219 if (error)
7220 goto back; 7220 goto back;
7221 7221
7222 bwi_bbp_power_on(sc, BWI_CLOCK_MODE_DYN); 7222 bwi_bbp_power_on(sc, BWI_CLOCK_MODE_DYN);
7223  7223
7224 IEEE80211_ADDR_COPY(ic->ic_myaddr, CLLADDR(ifp->if_sadl)); 7224 IEEE80211_ADDR_COPY(ic->ic_myaddr, CLLADDR(ifp->if_sadl));
7225 7225
7226 bwi_set_bssid(sc, bwi_zero_addr); /* Clear BSSID */ 7226 bwi_set_bssid(sc, bwi_zero_addr); /* Clear BSSID */
7227 bwi_set_addr_filter(sc, BWI_ADDR_FILTER_MYADDR, ic->ic_myaddr); 7227 bwi_set_addr_filter(sc, BWI_ADDR_FILTER_MYADDR, ic->ic_myaddr);
7228 7228
7229 bwi_mac_reset_hwkeys(mac); 7229 bwi_mac_reset_hwkeys(mac);
7230 7230
7231 if ((mac->mac_flags & BWI_MAC_F_HAS_TXSTATS) == 0) { 7231 if ((mac->mac_flags & BWI_MAC_F_HAS_TXSTATS) == 0) {
7232 int i; 7232 int i;
7233 7233
7234#define NRETRY 1000 7234#define NRETRY 1000
7235 /* 7235 /*
7236 * Drain any possible pending TX status 7236 * Drain any possible pending TX status
7237 */ 7237 */
7238 for (i = 0; i < NRETRY; ++i) { 7238 for (i = 0; i < NRETRY; ++i) {
7239 if ((CSR_READ_4(sc, BWI_TXSTATUS_0) & 7239 if ((CSR_READ_4(sc, BWI_TXSTATUS_0) &
7240 BWI_TXSTATUS_0_MORE) == 0) 7240 BWI_TXSTATUS_0_MORE) == 0)
7241 break; 7241 break;
7242 CSR_READ_4(sc, BWI_TXSTATUS_1); 7242 CSR_READ_4(sc, BWI_TXSTATUS_1);
7243 } 7243 }
7244 if (i == NRETRY) 7244 if (i == NRETRY)
7245 aprint_error_dev(sc->sc_dev, 7245 aprint_error_dev(sc->sc_dev,
7246 "can't drain TX status\n"); 7246 "can't drain TX status\n");
7247#undef NRETRY 7247#undef NRETRY
7248 } 7248 }
7249 7249
7250 if (mac->mac_phy.phy_mode == IEEE80211_MODE_11G) 7250 if (mac->mac_phy.phy_mode == IEEE80211_MODE_11G)
7251 bwi_mac_updateslot(mac, 1); 7251 bwi_mac_updateslot(mac, 1);
7252 7252
7253 /* Start MAC */ 7253 /* Start MAC */
7254 error = bwi_mac_start(mac); 7254 error = bwi_mac_start(mac);
7255 if (error) 7255 if (error)
7256 goto back; 7256 goto back;
7257 7257
7258 /* Enable intrs */ 7258 /* Enable intrs */
7259 bwi_enable_intrs(sc, BWI_INIT_INTRS); 7259 bwi_enable_intrs(sc, BWI_INIT_INTRS);
7260 7260
7261 ifp->if_flags |= IFF_RUNNING; 7261 ifp->if_flags |= IFF_RUNNING;
7262 ifp->if_flags &= ~IFF_OACTIVE; 7262 ifp->if_flags &= ~IFF_OACTIVE;
7263 7263
7264 if (statechg) { 7264 if (statechg) {
7265 if (ic->ic_opmode != IEEE80211_M_MONITOR) { 7265 if (ic->ic_opmode != IEEE80211_M_MONITOR) {
7266 /* [TRC: XXX OpenBSD omits this conditional.] */ 7266 /* [TRC: XXX OpenBSD omits this conditional.] */
7267 if (ic->ic_roaming != IEEE80211_ROAMING_MANUAL) 7267 if (ic->ic_roaming != IEEE80211_ROAMING_MANUAL)
7268 ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); 7268 ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
7269 } else { 7269 } else {
7270 ieee80211_new_state(ic, IEEE80211_S_RUN, -1); 7270 ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
7271 } 7271 }
7272 } else { 7272 } else {
7273 ieee80211_new_state(ic, ic->ic_state, -1); 7273 ieee80211_new_state(ic, ic->ic_state, -1);
7274 } 7274 }
7275 7275
7276back: 7276back:
7277 if (error) 7277 if (error)
7278 bwi_stop(ifp, 1); 7278 bwi_stop(ifp, 1);
7279 else 7279 else
7280 /* [TRC: XXX DragonFlyBD uses ifp->if_start(ifp).] */ 7280 /* [TRC: XXX DragonFlyBD uses ifp->if_start(ifp).] */
7281 bwi_start(ifp); 7281 bwi_start(ifp);
7282} 7282}
7283 7283
7284static int 7284static int
7285bwi_ioctl(struct ifnet *ifp, u_long cmd, void *data) 7285bwi_ioctl(struct ifnet *ifp, u_long cmd, void *data)
7286{ 7286{
7287 struct bwi_softc *sc = ifp->if_softc; 7287 struct bwi_softc *sc = ifp->if_softc;
7288 struct ieee80211com *ic = &sc->sc_ic; 7288 struct ieee80211com *ic = &sc->sc_ic;
7289 int s, error = 0; 7289 int s, error = 0;
7290 7290
7291 /* [TRC: XXX Superstitiously cargo-culted from wi(4).] */ 7291 /* [TRC: XXX Superstitiously cargo-culted from wi(4).] */
7292 if (!device_is_active(sc->sc_dev)) 7292 if (!device_is_active(sc->sc_dev))
7293 return (ENXIO); 7293 return (ENXIO);
7294 7294
7295 s = splnet(); 7295 s = splnet();
7296 7296
7297 switch (cmd) { 7297 switch (cmd) {
7298 case SIOCSIFFLAGS: 7298 case SIOCSIFFLAGS:
7299 if ((error = ifioctl_common(ifp, cmd, data)) != 0) 7299 if ((error = ifioctl_common(ifp, cmd, data)) != 0)
7300 break; 7300 break;
7301 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == 7301 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
7302 (IFF_UP | IFF_RUNNING)) { 7302 (IFF_UP | IFF_RUNNING)) {
7303 struct bwi_mac *mac; 7303 struct bwi_mac *mac;
7304 int promisc = -1; 7304 int promisc = -1;
7305 7305
7306 KASSERT(sc->sc_cur_regwin->rw_type == 7306 KASSERT(sc->sc_cur_regwin->rw_type ==
7307 BWI_REGWIN_T_MAC); 7307 BWI_REGWIN_T_MAC);
7308 mac = (struct bwi_mac *)sc->sc_cur_regwin; 7308 mac = (struct bwi_mac *)sc->sc_cur_regwin;
7309 7309
7310 if ((ifp->if_flags & IFF_PROMISC) && 7310 if ((ifp->if_flags & IFF_PROMISC) &&
7311 (sc->sc_flags & BWI_F_PROMISC) == 0) { 7311 (sc->sc_flags & BWI_F_PROMISC) == 0) {
7312 promisc = 1; 7312 promisc = 1;
7313 sc->sc_flags |= BWI_F_PROMISC; 7313 sc->sc_flags |= BWI_F_PROMISC;
7314 } else if ((ifp->if_flags & IFF_PROMISC) == 0 && 7314 } else if ((ifp->if_flags & IFF_PROMISC) == 0 &&
7315 (sc->sc_flags & BWI_F_PROMISC)) { 7315 (sc->sc_flags & BWI_F_PROMISC)) {
7316 promisc = 0; 7316 promisc = 0;
7317 sc->sc_flags &= ~BWI_F_PROMISC; 7317 sc->sc_flags &= ~BWI_F_PROMISC;
7318 } 7318 }
7319 7319
7320 if (promisc >= 0) 7320 if (promisc >= 0)
7321 bwi_mac_set_promisc(mac, promisc); 7321 bwi_mac_set_promisc(mac, promisc);
7322 } 7322 }
7323 7323
7324 if (ifp->if_flags & IFF_UP) { 7324 if (ifp->if_flags & IFF_UP) {
7325 if (!(ifp->if_flags & IFF_RUNNING)) 7325 if (!(ifp->if_flags & IFF_RUNNING))
7326 bwi_init(ifp); 7326 bwi_init(ifp);
7327 } else { 7327 } else {
7328 if (ifp->if_flags & IFF_RUNNING) 7328 if (ifp->if_flags & IFF_RUNNING)
7329 bwi_stop(ifp, 1); 7329 bwi_stop(ifp, 1);
7330 } 7330 }
7331 break; 7331 break;
7332 7332
7333 case SIOCADDMULTI: 7333 case SIOCADDMULTI:
7334 case SIOCDELMULTI: 7334 case SIOCDELMULTI:
7335 /* [TRC: Several other drivers appear to have this 7335 /* [TRC: Several other drivers appear to have this
7336 copied & pasted, so I'm following suit.] */ 7336 copied & pasted, so I'm following suit.] */
7337 /* XXX no h/w multicast filter? --dyoung */ 7337 /* XXX no h/w multicast filter? --dyoung */
7338 if ((error = ether_ioctl(ifp, cmd, data)) == ENETRESET) { 7338 if ((error = ether_ioctl(ifp, cmd, data)) == ENETRESET) {
7339 /* setup multicast filter, etc */ 7339 /* setup multicast filter, etc */
7340 error = 0; 7340 error = 0;
7341 } 7341 }
7342 break; 7342 break;
7343 7343
7344 case SIOCS80211CHANNEL: 7344 case SIOCS80211CHANNEL:
7345 /* [TRC: Pilfered from OpenBSD. No clue whether it works.] */ 7345 /* [TRC: Pilfered from OpenBSD. No clue whether it works.] */
7346 /* allow fast channel switching in monitor mode */ 7346 /* allow fast channel switching in monitor mode */
7347 error = ieee80211_ioctl(ic, cmd, data); 7347 error = ieee80211_ioctl(ic, cmd, data);
7348 if (error == ENETRESET && 7348 if (error == ENETRESET &&
7349 ic->ic_opmode == IEEE80211_M_MONITOR) { 7349 ic->ic_opmode == IEEE80211_M_MONITOR) {
7350 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == 7350 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
7351 (IFF_UP | IFF_RUNNING)) { 7351 (IFF_UP | IFF_RUNNING)) {
7352 /* [TRC: XXX ????] */ 7352 /* [TRC: XXX ????] */
7353 ic->ic_bss->ni_chan = ic->ic_ibss_chan; 7353 ic->ic_bss->ni_chan = ic->ic_ibss_chan;
7354 ic->ic_curchan = ic->ic_ibss_chan; 7354 ic->ic_curchan = ic->ic_ibss_chan;
7355 bwi_set_chan(sc, ic->ic_bss->ni_chan); 7355 bwi_set_chan(sc, ic->ic_bss->ni_chan);
7356 } 7356 }
7357 error = 0; 7357 error = 0;
7358 } 7358 }
7359 break; 7359 break;
7360 7360
7361 default: 7361 default:
7362 error = ieee80211_ioctl(ic, cmd, data); 7362 error = ieee80211_ioctl(ic, cmd, data);
7363 break; 7363 break;
7364 } 7364 }
7365 7365
7366 if (error == ENETRESET) { 7366 if (error == ENETRESET) {
7367 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == 7367 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
7368 (IFF_UP | IFF_RUNNING) && 7368 (IFF_UP | IFF_RUNNING) &&
7369 /* [TRC: XXX Superstitiously cargo-culted from iwi(4). */ 7369 /* [TRC: XXX Superstitiously cargo-culted from iwi(4). */
7370 (ic->ic_roaming != IEEE80211_ROAMING_MANUAL)) 7370 (ic->ic_roaming != IEEE80211_ROAMING_MANUAL))
7371 bwi_init(ifp); 7371 bwi_init(ifp);
7372 error = 0; 7372 error = 0;
7373 } 7373 }
7374 7374
7375 splx(s); 7375 splx(s);
7376 7376
7377 return (error); 7377 return (error);
7378} 7378}
7379 7379
7380static void 7380static void
7381bwi_start(struct ifnet *ifp) 7381bwi_start(struct ifnet *ifp)
7382{ 7382{
7383 struct bwi_softc *sc = ifp->if_softc; 7383 struct bwi_softc *sc = ifp->if_softc;
7384 struct ieee80211com *ic = &sc->sc_ic; 7384 struct ieee80211com *ic = &sc->sc_ic;
7385 struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[BWI_TX_DATA_RING]; 7385 struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[BWI_TX_DATA_RING];
7386 int trans, idx; 7386 int trans, idx;
7387 7387
7388 /* [TRC: XXX I'm not sure under which conditions we're actually 7388 /* [TRC: XXX I'm not sure under which conditions we're actually
7389 supposed to refuse to start, so I'm copying what OpenBSD and 7389 supposed to refuse to start, so I'm copying what OpenBSD and
7390 DragonFlyBSD do, even if no one else on NetBSD does it. */ 7390 DragonFlyBSD do, even if no one else on NetBSD does it. */
7391 if ((ifp->if_flags & IFF_OACTIVE) || 7391 if ((ifp->if_flags & IFF_OACTIVE) ||
7392 (ifp->if_flags & IFF_RUNNING) == 0) 7392 (ifp->if_flags & IFF_RUNNING) == 0)
7393 return; 7393 return;
7394 7394
7395 trans = 0; 7395 trans = 0;
7396 idx = tbd->tbd_idx; 7396 idx = tbd->tbd_idx;
7397 7397
7398 while (tbd->tbd_buf[idx].tb_mbuf == NULL) { 7398 while (tbd->tbd_buf[idx].tb_mbuf == NULL) {
7399 struct ieee80211_frame *wh; 7399 struct ieee80211_frame *wh;
7400 struct ieee80211_node *ni; 7400 struct ieee80211_node *ni;
7401 struct mbuf *m; 7401 struct mbuf *m;
7402 int mgt_pkt = 0; 7402 int mgt_pkt = 0;
7403 7403
7404 IF_DEQUEUE(&ic->ic_mgtq, m); 7404 IF_DEQUEUE(&ic->ic_mgtq, m);
7405 if (m != NULL) { 7405 if (m != NULL) {
7406 ni = M_GETCTX(m, struct ieee80211_node *); 7406 ni = M_GETCTX(m, struct ieee80211_node *);
7407 M_CLEARCTX(m); 7407 M_CLEARCTX(m);
7408 7408
7409 mgt_pkt = 1; 7409 mgt_pkt = 1;
7410 } else { 7410 } else {
7411 struct ether_header *eh; 7411 struct ether_header *eh;
7412 7412
7413 if (ic->ic_state != IEEE80211_S_RUN) 7413 if (ic->ic_state != IEEE80211_S_RUN)
7414 break; 7414 break;
7415 7415
7416 IFQ_DEQUEUE(&ifp->if_snd, m); 7416 IFQ_DEQUEUE(&ifp->if_snd, m);
7417 if (m == NULL) 7417 if (m == NULL)
7418 break; 7418 break;
7419 7419
7420 if (m->m_len < sizeof(*eh)) { 7420 if (m->m_len < sizeof(*eh)) {
7421 m = m_pullup(m, sizeof(*eh)); 7421 m = m_pullup(m, sizeof(*eh));
7422 if (m == NULL) { 7422 if (m == NULL) {
7423 ifp->if_oerrors++; 7423 if_statinc(ifp, if_oerrors);
7424 continue; 7424 continue;
7425 } 7425 }
7426 } 7426 }
7427 eh = mtod(m, struct ether_header *); 7427 eh = mtod(m, struct ether_header *);
7428 7428
7429 ni = ieee80211_find_txnode(ic, eh->ether_dhost); 7429 ni = ieee80211_find_txnode(ic, eh->ether_dhost);
7430 if (ni == NULL) { 7430 if (ni == NULL) {
7431 ifp->if_oerrors++; 7431 if_statinc(ifp, if_oerrors);
7432 m_freem(m); 7432 m_freem(m);
7433 continue; 7433 continue;
7434 } 7434 }
7435 7435
7436 /* [TRC: XXX Superstitiously cargo-culted from 7436 /* [TRC: XXX Superstitiously cargo-culted from
7437 ath(4) and wi(4).] */ 7437 ath(4) and wi(4).] */
7438 if ((ni->ni_flags & IEEE80211_NODE_PWR_MGT) && 7438 if ((ni->ni_flags & IEEE80211_NODE_PWR_MGT) &&
7439 (m->m_flags & M_PWR_SAV) == 0) { 7439 (m->m_flags & M_PWR_SAV) == 0) {
7440 ieee80211_pwrsave(ic, ni, m); 7440 ieee80211_pwrsave(ic, ni, m);
7441 ieee80211_free_node(ni); 7441 ieee80211_free_node(ni);
7442 continue; 7442 continue;
7443 } 7443 }
7444 7444
7445 /* [TRC: XXX I *think* we're supposed to do 7445 /* [TRC: XXX I *think* we're supposed to do
7446 this, but honestly I have no clue. We don't 7446 this, but honestly I have no clue. We don't
7447 use M_WME_GETAC, so...] */ 7447 use M_WME_GETAC, so...] */
7448 if (ieee80211_classify(ic, m, ni)) { 7448 if (ieee80211_classify(ic, m, ni)) {
7449 /* [TRC: XXX What debug flag?] */ 7449 /* [TRC: XXX What debug flag?] */
7450 DPRINTF(sc, BWI_DBG_MISC, 7450 DPRINTF(sc, BWI_DBG_MISC,
7451 "%s: discard, classification failure\n", 7451 "%s: discard, classification failure\n",
7452 __func__); 7452 __func__);
7453 ifp->if_oerrors++; 7453 if_statinc(ifp, if_oerrors);
7454 m_freem(m); 7454 m_freem(m);
7455 ieee80211_free_node(ni); 7455 ieee80211_free_node(ni);
7456 continue; 7456 continue;
7457 } 7457 }
7458 7458
7459 /* [TRC: XXX wi(4) and awi(4) do this; iwi(4) 7459 /* [TRC: XXX wi(4) and awi(4) do this; iwi(4)
7460 doesn't.] */ 7460 doesn't.] */
7461 ifp->if_opackets++; 7461 if_statinc(ifp, if_opackets);
7462 7462
7463 /* [TRC: XXX When should the packet be 7463 /* [TRC: XXX When should the packet be
7464 filtered? Different drivers appear to do it 7464 filtered? Different drivers appear to do it
7465 at different times.] */ 7465 at different times.] */
7466 /* TODO: PS */ 7466 /* TODO: PS */
7467 bpf_mtap(ifp, m, BPF_D_OUT); 7467 bpf_mtap(ifp, m, BPF_D_OUT);
7468 m = ieee80211_encap(ic, m, ni); 7468 m = ieee80211_encap(ic, m, ni);
7469 if (m == NULL) { 7469 if (m == NULL) {
7470 ifp->if_oerrors++; 7470 if_statinc(ifp, if_oerrors);
7471 ieee80211_free_node(ni); 7471 ieee80211_free_node(ni);
7472 continue; 7472 continue;
7473 } 7473 }
7474 } 7474 }
7475 bpf_mtap3(ic->ic_rawbpf, m, BPF_D_OUT); 7475 bpf_mtap3(ic->ic_rawbpf, m, BPF_D_OUT);
7476 7476
7477 wh = mtod(m, struct ieee80211_frame *); 7477 wh = mtod(m, struct ieee80211_frame *);
7478 /* [TRC: XXX What about ic->ic_flags & IEEE80211_F_PRIVACY?] */ 7478 /* [TRC: XXX What about ic->ic_flags & IEEE80211_F_PRIVACY?] */
7479 if (wh->i_fc[1] & IEEE80211_FC1_WEP) { 7479 if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
7480 if (ieee80211_crypto_encap(ic, ni, m) == NULL) { 7480 if (ieee80211_crypto_encap(ic, ni, m) == NULL) {
7481 ifp->if_oerrors++; 7481 if_statinc(ifp, if_oerrors);
7482 m_freem(m); 7482 m_freem(m);
7483 ieee80211_free_node(ni); 7483 ieee80211_free_node(ni);
7484 continue; 7484 continue;
7485 } 7485 }
7486 } 7486 }
7487 wh = NULL; /* [TRC: XXX Huh?] */ 7487 wh = NULL; /* [TRC: XXX Huh?] */
7488 7488
7489 if (bwi_encap(sc, idx, m, &ni, mgt_pkt) != 0) { 7489 if (bwi_encap(sc, idx, m, &ni, mgt_pkt) != 0) {
7490 /* 'm' is freed in bwi_encap() if we reach here */ 7490 /* 'm' is freed in bwi_encap() if we reach here */
7491 ifp->if_oerrors++; 7491 if_statinc(ifp, if_oerrors);
7492 if (ni != NULL) 7492 if (ni != NULL)
7493 ieee80211_free_node(ni); 7493 ieee80211_free_node(ni);
7494 continue; 7494 continue;
7495 } 7495 }
7496 7496
7497 trans = 1; 7497 trans = 1;
7498 tbd->tbd_used++; 7498 tbd->tbd_used++;
7499 idx = (idx + 1) % BWI_TX_NDESC; 7499 idx = (idx + 1) % BWI_TX_NDESC;
7500 7500
7501 if (tbd->tbd_used + BWI_TX_NSPRDESC >= BWI_TX_NDESC) { 7501 if (tbd->tbd_used + BWI_TX_NSPRDESC >= BWI_TX_NDESC) {
7502 ifp->if_flags |= IFF_OACTIVE; 7502 ifp->if_flags |= IFF_OACTIVE;
7503 break; 7503 break;
7504 } 7504 }
7505 } 7505 }
7506 tbd->tbd_idx = idx; 7506 tbd->tbd_idx = idx;
7507 7507
7508 if (trans) 7508 if (trans)
7509 sc->sc_tx_timer = 5; 7509 sc->sc_tx_timer = 5;
7510 ifp->if_timer = 1; 7510 ifp->if_timer = 1;
7511} 7511}
7512 7512
7513static void 7513static void
7514bwi_watchdog(struct ifnet *ifp) 7514bwi_watchdog(struct ifnet *ifp)
7515{ 7515{
7516 struct bwi_softc *sc = ifp->if_softc; 7516 struct bwi_softc *sc = ifp->if_softc;
7517 7517
7518 ifp->if_timer = 0; 7518 ifp->if_timer = 0;
7519 7519
7520 if ((ifp->if_flags & IFF_RUNNING) == 0 || 7520 if ((ifp->if_flags & IFF_RUNNING) == 0 ||
7521 !device_is_active(sc->sc_dev)) 7521 !device_is_active(sc->sc_dev))
7522 return; 7522 return;
7523 7523
7524 if (sc->sc_tx_timer) { 7524 if (sc->sc_tx_timer) {
7525 if (--sc->sc_tx_timer == 0) { 7525 if (--sc->sc_tx_timer == 0) {
7526 aprint_error_dev(sc->sc_dev, "device timeout\n"); 7526 aprint_error_dev(sc->sc_dev, "device timeout\n");
7527 ifp->if_oerrors++; 7527 if_statinc(ifp, if_oerrors);
7528 /* TODO */ 7528 /* TODO */
7529 /* [TRC: XXX TODO what? Stop the device? 7529 /* [TRC: XXX TODO what? Stop the device?
7530 Bring it down? iwi(4) does this.] */ 7530 Bring it down? iwi(4) does this.] */
7531 } else 7531 } else
7532 ifp->if_timer = 1; 7532 ifp->if_timer = 1;
7533 } 7533 }
7534 7534
7535 ieee80211_watchdog(&sc->sc_ic); 7535 ieee80211_watchdog(&sc->sc_ic);
7536} 7536}
7537 7537
7538static void 7538static void
7539bwi_stop(struct ifnet *ifp, int state_chg) 7539bwi_stop(struct ifnet *ifp, int state_chg)
7540{ 7540{
7541 struct bwi_softc *sc = ifp->if_softc; 7541 struct bwi_softc *sc = ifp->if_softc;
7542 struct ieee80211com *ic = &sc->sc_ic; 7542 struct ieee80211com *ic = &sc->sc_ic;
7543 struct bwi_mac *mac; 7543 struct bwi_mac *mac;
7544 int i, error, pwr_off = 0; 7544 int i, error, pwr_off = 0;
7545 7545
7546 DPRINTF(sc, BWI_DBG_MISC, "%s\n", __func__); 7546 DPRINTF(sc, BWI_DBG_MISC, "%s\n", __func__);
7547 7547
7548 if (state_chg) 7548 if (state_chg)
7549 ieee80211_new_state(ic, IEEE80211_S_INIT, -1); 7549 ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
7550 else 7550 else
7551 bwi_newstate_begin(sc, IEEE80211_S_INIT); 7551 bwi_newstate_begin(sc, IEEE80211_S_INIT);
7552 7552
7553 if (ifp->if_flags & IFF_RUNNING) { 7553 if (ifp->if_flags & IFF_RUNNING) {
7554 KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC); 7554 KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC);
7555 mac = (struct bwi_mac *)sc->sc_cur_regwin; 7555 mac = (struct bwi_mac *)sc->sc_cur_regwin;
7556 7556
7557 bwi_disable_intrs(sc, BWI_ALL_INTRS); 7557 bwi_disable_intrs(sc, BWI_ALL_INTRS);
7558 CSR_READ_4(sc, BWI_MAC_INTR_MASK); 7558 CSR_READ_4(sc, BWI_MAC_INTR_MASK);
7559 bwi_mac_stop(mac); 7559 bwi_mac_stop(mac);
7560 } 7560 }
7561 7561
7562 for (i = 0; i < sc->sc_nmac; ++i) { 7562 for (i = 0; i < sc->sc_nmac; ++i) {
7563 struct bwi_regwin *old_rw; 7563 struct bwi_regwin *old_rw;
7564 7564
7565 mac = &sc->sc_mac[i]; 7565 mac = &sc->sc_mac[i];
7566 if ((mac->mac_flags & BWI_MAC_F_INITED) == 0) 7566 if ((mac->mac_flags & BWI_MAC_F_INITED) == 0)
7567 continue; 7567 continue;
7568 7568
7569 error = bwi_regwin_switch(sc, &mac->mac_regwin, &old_rw); 7569 error = bwi_regwin_switch(sc, &mac->mac_regwin, &old_rw);
7570 if (error) 7570 if (error)
7571 continue; 7571 continue;
7572 7572
7573 bwi_mac_shutdown(mac); 7573 bwi_mac_shutdown(mac);
7574 pwr_off = 1; 7574 pwr_off = 1;
7575 7575
7576 bwi_regwin_switch(sc, old_rw, NULL); 7576 bwi_regwin_switch(sc, old_rw, NULL);
7577 } 7577 }
7578 7578
7579 if (pwr_off) 7579 if (pwr_off)
7580 bwi_bbp_power_off(sc); 7580 bwi_bbp_power_off(sc);
7581 7581
7582 sc->sc_tx_timer = 0; 7582 sc->sc_tx_timer = 0;
7583 ifp->if_timer = 0; 7583 ifp->if_timer = 0;
7584 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 7584 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
7585 7585
7586 /* power off cardbus socket */ 7586 /* power off cardbus socket */
7587 if (sc->sc_disable != NULL) 7587 if (sc->sc_disable != NULL)
7588 (sc->sc_disable)(sc, 0); 7588 (sc->sc_disable)(sc, 0);
7589 7589
7590 return; 7590 return;
7591} 7591}
7592 7592
7593static void 7593static void
7594bwi_newstate_begin(struct bwi_softc *sc, enum ieee80211_state nstate) 7594bwi_newstate_begin(struct bwi_softc *sc, enum ieee80211_state nstate)
7595{ 7595{
7596 callout_stop(&sc->sc_scan_ch); 7596 callout_stop(&sc->sc_scan_ch);
7597 callout_stop(&sc->sc_calib_ch); 7597 callout_stop(&sc->sc_calib_ch);
7598 7598
7599 bwi_led_newstate(sc, nstate); 7599 bwi_led_newstate(sc, nstate);
7600 7600
7601 if (nstate == IEEE80211_S_INIT) 7601 if (nstate == IEEE80211_S_INIT)
7602 sc->sc_txpwrcb_type = BWI_TXPWR_INIT; 7602 sc->sc_txpwrcb_type = BWI_TXPWR_INIT;
7603} 7603}
7604 7604
7605static int 7605static int
7606bwi_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) 7606bwi_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
7607{ 7607{
7608 struct bwi_softc *sc = ic->ic_ifp->if_softc; 7608 struct bwi_softc *sc = ic->ic_ifp->if_softc;
7609 struct ieee80211_node *ni; 7609 struct ieee80211_node *ni;
7610 int error; 7610 int error;
7611 7611
7612 /* [TRC: XXX amrr] */ 7612 /* [TRC: XXX amrr] */
7613 callout_stop(&sc->sc_amrr_ch); 7613 callout_stop(&sc->sc_amrr_ch);
7614 7614
7615 bwi_newstate_begin(sc, nstate); 7615 bwi_newstate_begin(sc, nstate);
7616 7616
7617 if (nstate == IEEE80211_S_INIT) 7617 if (nstate == IEEE80211_S_INIT)
7618 goto back; 7618 goto back;
7619 7619
7620 /* [TRC: XXX What channel do we set this to? */ 7620 /* [TRC: XXX What channel do we set this to? */
7621 error = bwi_set_chan(sc, ic->ic_curchan); 7621 error = bwi_set_chan(sc, ic->ic_curchan);
7622 if (error) { 7622 if (error) {
7623 aprint_error_dev(sc->sc_dev, "can't set channel to %u\n", 7623 aprint_error_dev(sc->sc_dev, "can't set channel to %u\n",
7624 ieee80211_chan2ieee(ic, ic->ic_curchan)); 7624 ieee80211_chan2ieee(ic, ic->ic_curchan));
7625 return (error); 7625 return (error);
7626 } 7626 }
7627 7627
7628 if (ic->ic_opmode == IEEE80211_M_MONITOR) { 7628 if (ic->ic_opmode == IEEE80211_M_MONITOR) {
7629 /* Nothing to do */ 7629 /* Nothing to do */
7630 } else if (nstate == IEEE80211_S_RUN) { 7630 } else if (nstate == IEEE80211_S_RUN) {
7631 struct bwi_mac *mac; 7631 struct bwi_mac *mac;
7632 7632
7633 ni = ic->ic_bss; 7633 ni = ic->ic_bss;
7634 7634
7635 bwi_set_bssid(sc, ic->ic_bss->ni_bssid); 7635 bwi_set_bssid(sc, ic->ic_bss->ni_bssid);
7636 7636
7637 KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC); 7637 KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC);
7638 mac = (struct bwi_mac *)sc->sc_cur_regwin; 7638 mac = (struct bwi_mac *)sc->sc_cur_regwin;
7639 7639
7640 /* Initial TX power calibration */ 7640 /* Initial TX power calibration */
7641 bwi_mac_calibrate_txpower(mac, BWI_TXPWR_INIT); 7641 bwi_mac_calibrate_txpower(mac, BWI_TXPWR_INIT);
7642#ifdef notyet 7642#ifdef notyet
7643 sc->sc_txpwrcb_type = BWI_TXPWR_FORCE; 7643 sc->sc_txpwrcb_type = BWI_TXPWR_FORCE;
7644#else 7644#else
7645 sc->sc_txpwrcb_type = BWI_TXPWR_CALIB; 7645 sc->sc_txpwrcb_type = BWI_TXPWR_CALIB;
7646#endif 7646#endif
7647 /* [TRC: XXX amrr] */ 7647 /* [TRC: XXX amrr] */
7648 if (ic->ic_opmode == IEEE80211_M_STA) { 7648 if (ic->ic_opmode == IEEE80211_M_STA) {
7649 /* fake a join to init the tx rate */ 7649 /* fake a join to init the tx rate */
7650 bwi_newassoc(ni, 1); 7650 bwi_newassoc(ni, 1);
7651 } 7651 }
7652 7652
7653 if (ic->ic_opmode != IEEE80211_M_MONITOR) { 7653 if (ic->ic_opmode != IEEE80211_M_MONITOR) {
7654 /* start automatic rate control timer */ 7654 /* start automatic rate control timer */
7655 if (ic->ic_fixed_rate == -1) 7655 if (ic->ic_fixed_rate == -1)
7656 callout_schedule(&sc->sc_amrr_ch, hz / 2); 7656 callout_schedule(&sc->sc_amrr_ch, hz / 2);
7657 } 7657 }
7658 } else 7658 } else
7659 bwi_set_bssid(sc, bwi_zero_addr); 7659 bwi_set_bssid(sc, bwi_zero_addr);
7660 7660
7661back: 7661back:
7662 error = (sc->sc_newstate)(ic, nstate, arg); 7662 error = (sc->sc_newstate)(ic, nstate, arg);
7663 7663
7664 if (nstate == IEEE80211_S_SCAN) { 7664 if (nstate == IEEE80211_S_SCAN) {
7665 callout_schedule(&sc->sc_scan_ch, 7665 callout_schedule(&sc->sc_scan_ch,
7666 (sc->sc_dwell_time * hz) / 1000); 7666 (sc->sc_dwell_time * hz) / 1000);
7667 } else if (nstate == IEEE80211_S_RUN) { 7667 } else if (nstate == IEEE80211_S_RUN) {
7668 /* XXX 15 seconds */ 7668 /* XXX 15 seconds */
7669 callout_schedule(&sc->sc_calib_ch, hz); 7669 callout_schedule(&sc->sc_calib_ch, hz);
7670 } 7670 }
7671 7671
7672 return (error); 7672 return (error);
7673} 7673}
7674 7674
7675static int 7675static int
7676bwi_media_change(struct ifnet *ifp) 7676bwi_media_change(struct ifnet *ifp)
7677{ 7677{
7678 int error; 7678 int error;
7679 7679
7680 error = ieee80211_media_change(ifp); 7680 error = ieee80211_media_change(ifp);
7681 if (error != ENETRESET) 7681 if (error != ENETRESET)
7682 return (error); 7682 return (error);
7683 7683
7684 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING)) 7684 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING))
7685 bwi_init(ifp); 7685 bwi_init(ifp);
7686 7686
7687 return (0); 7687 return (0);
7688} 7688}
7689 7689
7690/* [TRC: XXX amrr] */ 7690/* [TRC: XXX amrr] */
7691static void 7691static void
7692bwi_iter_func(void *arg, struct ieee80211_node *ni) 7692bwi_iter_func(void *arg, struct ieee80211_node *ni)
7693{ 7693{
7694 struct bwi_softc *sc = arg; 7694 struct bwi_softc *sc = arg;
7695 struct bwi_node *bn = (struct bwi_node *)ni; 7695 struct bwi_node *bn = (struct bwi_node *)ni;
7696 7696
7697 ieee80211_amrr_choose(&sc->sc_amrr, ni, &bn->amn); 7697 ieee80211_amrr_choose(&sc->sc_amrr, ni, &bn->amn);
7698} 7698}
7699 7699
7700static void 7700static void
7701bwi_amrr_timeout(void *arg) 7701bwi_amrr_timeout(void *arg)
7702{ 7702{
7703 struct bwi_softc *sc = arg; 7703 struct bwi_softc *sc = arg;
7704 struct ieee80211com *ic = &sc->sc_ic; 7704 struct ieee80211com *ic = &sc->sc_ic;
7705 int s; 7705 int s;
7706 7706
7707 s = splnet(); 7707 s = splnet();
7708 if (ic->ic_opmode == IEEE80211_M_STA) 7708 if (ic->ic_opmode == IEEE80211_M_STA)
7709 bwi_iter_func(sc, ic->ic_bss); 7709 bwi_iter_func(sc, ic->ic_bss);
7710 else 7710 else
7711 /* [TRC: XXX I'm making a wild guess about what to 7711 /* [TRC: XXX I'm making a wild guess about what to
7712 supply for the node table.] */ 7712 supply for the node table.] */
7713 ieee80211_iterate_nodes(&ic->ic_sta, bwi_iter_func, sc); 7713 ieee80211_iterate_nodes(&ic->ic_sta, bwi_iter_func, sc);
7714 7714
7715 callout_schedule(&sc->sc_amrr_ch, hz / 2); 7715 callout_schedule(&sc->sc_amrr_ch, hz / 2);
7716 splx(s); 7716 splx(s);
7717} 7717}
7718 7718
7719static void 7719static void
7720bwi_newassoc(struct ieee80211_node *ni, int isnew) 7720bwi_newassoc(struct ieee80211_node *ni, int isnew)
7721{ 7721{
7722 struct ieee80211com *ic = ni->ni_ic; 7722 struct ieee80211com *ic = ni->ni_ic;
7723 struct bwi_softc *sc = ic->ic_ifp->if_softc; 7723 struct bwi_softc *sc = ic->ic_ifp->if_softc;
7724 int i; 7724 int i;
7725 7725
7726 DPRINTF(sc, BWI_DBG_STATION, "%s\n", __func__); 7726 DPRINTF(sc, BWI_DBG_STATION, "%s\n", __func__);
7727 7727
7728 ieee80211_amrr_node_init(&sc->sc_amrr, &((struct bwi_node *)ni)->amn); 7728 ieee80211_amrr_node_init(&sc->sc_amrr, &((struct bwi_node *)ni)->amn);
7729 7729
7730 /* set rate to some reasonable initial value */ 7730 /* set rate to some reasonable initial value */
7731 for (i = ni->ni_rates.rs_nrates - 1; 7731 for (i = ni->ni_rates.rs_nrates - 1;
7732 i > 0 && (ni->ni_rates.rs_rates[i] & IEEE80211_RATE_VAL) > 72; 7732 i > 0 && (ni->ni_rates.rs_rates[i] & IEEE80211_RATE_VAL) > 72;
7733 i--); 7733 i--);
7734 7734
7735 ni->ni_txrate = i; 7735 ni->ni_txrate = i;
7736} 7736}
7737 7737
7738static struct ieee80211_node * 7738static struct ieee80211_node *
7739bwi_node_alloc(struct ieee80211_node_table *nt) 7739bwi_node_alloc(struct ieee80211_node_table *nt)
7740{ 7740{
7741 struct bwi_node *bn; 7741 struct bwi_node *bn;
7742 7742
7743 bn = malloc(sizeof(struct bwi_node), M_80211_NODE, M_NOWAIT | M_ZERO); 7743 bn = malloc(sizeof(struct bwi_node), M_80211_NODE, M_NOWAIT | M_ZERO);
7744 7744
7745 return ((struct ieee80211_node *)bn); 7745 return ((struct ieee80211_node *)bn);
7746} 7746}
7747/* [TRC: XXX amrr end] */ 7747/* [TRC: XXX amrr end] */
7748 7748
7749static int 7749static int
7750bwi_dma_alloc(struct bwi_softc *sc) 7750bwi_dma_alloc(struct bwi_softc *sc)
7751{ 7751{
7752 int error, i, has_txstats; 7752 int error, i, has_txstats;
7753 /* [TRC: XXX DragonFlyBSD adjusts the low address for different 7753 /* [TRC: XXX DragonFlyBSD adjusts the low address for different
7754 bus spaces. Should we?] */ 7754 bus spaces. Should we?] */
7755 bus_size_t tx_ring_sz, rx_ring_sz, desc_sz = 0; 7755 bus_size_t tx_ring_sz, rx_ring_sz, desc_sz = 0;
7756 uint32_t txrx_ctrl_step = 0; 7756 uint32_t txrx_ctrl_step = 0;
7757 7757
7758 has_txstats = 0; 7758 has_txstats = 0;
7759 for (i = 0; i < sc->sc_nmac; ++i) { 7759 for (i = 0; i < sc->sc_nmac; ++i) {
7760 if (sc->sc_mac[i].mac_flags & BWI_MAC_F_HAS_TXSTATS) { 7760 if (sc->sc_mac[i].mac_flags & BWI_MAC_F_HAS_TXSTATS) {
7761 has_txstats = 1; 7761 has_txstats = 1;
7762 break; 7762 break;
7763 } 7763 }
7764 } 7764 }
7765 7765
7766 switch (sc->sc_bus_space) { 7766 switch (sc->sc_bus_space) {
7767 case BWI_BUS_SPACE_30BIT: 7767 case BWI_BUS_SPACE_30BIT:
7768 case BWI_BUS_SPACE_32BIT: 7768 case BWI_BUS_SPACE_32BIT:
7769 desc_sz = sizeof(struct bwi_desc32); 7769 desc_sz = sizeof(struct bwi_desc32);
7770 txrx_ctrl_step = 0x20; 7770 txrx_ctrl_step = 0x20;
7771 7771
7772 sc->sc_init_tx_ring = bwi_init_tx_ring32; 7772 sc->sc_init_tx_ring = bwi_init_tx_ring32;
7773 sc->sc_free_tx_ring = bwi_free_tx_ring32; 7773 sc->sc_free_tx_ring = bwi_free_tx_ring32;
7774 sc->sc_init_rx_ring = bwi_init_rx_ring32; 7774 sc->sc_init_rx_ring = bwi_init_rx_ring32;
7775 sc->sc_free_rx_ring = bwi_free_rx_ring32; 7775 sc->sc_free_rx_ring = bwi_free_rx_ring32;
7776 sc->sc_setup_rxdesc = bwi_setup_rx_desc32; 7776 sc->sc_setup_rxdesc = bwi_setup_rx_desc32;
7777 sc->sc_setup_txdesc = bwi_setup_tx_desc32; 7777 sc->sc_setup_txdesc = bwi_setup_tx_desc32;
7778 sc->sc_rxeof = bwi_rxeof32; 7778 sc->sc_rxeof = bwi_rxeof32;
7779 sc->sc_start_tx = bwi_start_tx32; 7779 sc->sc_start_tx = bwi_start_tx32;
7780 if (has_txstats) { 7780 if (has_txstats) {
7781 sc->sc_init_txstats = bwi_init_txstats32; 7781 sc->sc_init_txstats = bwi_init_txstats32;
7782 sc->sc_free_txstats = bwi_free_txstats32; 7782 sc->sc_free_txstats = bwi_free_txstats32;
7783 sc->sc_txeof_status = bwi_txeof_status32; 7783 sc->sc_txeof_status = bwi_txeof_status32;
7784 } 7784 }
7785 break; 7785 break;
7786 7786
7787 case BWI_BUS_SPACE_64BIT: 7787 case BWI_BUS_SPACE_64BIT:
7788 desc_sz = sizeof(struct bwi_desc64); 7788 desc_sz = sizeof(struct bwi_desc64);
7789 txrx_ctrl_step = 0x40; 7789 txrx_ctrl_step = 0x40;
7790 7790
7791 sc->sc_init_tx_ring = bwi_init_tx_ring64; 7791 sc->sc_init_tx_ring = bwi_init_tx_ring64;
7792 sc->sc_free_tx_ring = bwi_free_tx_ring64; 7792 sc->sc_free_tx_ring = bwi_free_tx_ring64;
7793 sc->sc_init_rx_ring = bwi_init_rx_ring64; 7793 sc->sc_init_rx_ring = bwi_init_rx_ring64;
7794 sc->sc_free_rx_ring = bwi_free_rx_ring64; 7794 sc->sc_free_rx_ring = bwi_free_rx_ring64;
7795 sc->sc_setup_rxdesc = bwi_setup_rx_desc64; 7795 sc->sc_setup_rxdesc = bwi_setup_rx_desc64;
7796 sc->sc_setup_txdesc = bwi_setup_tx_desc64; 7796 sc->sc_setup_txdesc = bwi_setup_tx_desc64;
7797 sc->sc_rxeof = bwi_rxeof64; 7797 sc->sc_rxeof = bwi_rxeof64;
7798 sc->sc_start_tx = bwi_start_tx64; 7798 sc->sc_start_tx = bwi_start_tx64;
7799 if (has_txstats) { 7799 if (has_txstats) {
7800 sc->sc_init_txstats = bwi_init_txstats64; 7800 sc->sc_init_txstats = bwi_init_txstats64;
7801 sc->sc_free_txstats = bwi_free_txstats64; 7801 sc->sc_free_txstats = bwi_free_txstats64;
7802 sc->sc_txeof_status = bwi_txeof_status64; 7802 sc->sc_txeof_status = bwi_txeof_status64;
7803 } 7803 }
7804 break; 7804 break;
7805 } 7805 }
7806 7806
7807 KASSERT(desc_sz != 0); 7807 KASSERT(desc_sz != 0);
7808 KASSERT(txrx_ctrl_step != 0); 7808 KASSERT(txrx_ctrl_step != 0);
7809 7809
7810 tx_ring_sz = roundup(desc_sz * BWI_TX_NDESC, BWI_RING_ALIGN); 7810 tx_ring_sz = roundup(desc_sz * BWI_TX_NDESC, BWI_RING_ALIGN);
7811 rx_ring_sz = roundup(desc_sz * BWI_RX_NDESC, BWI_RING_ALIGN); 7811 rx_ring_sz = roundup(desc_sz * BWI_RX_NDESC, BWI_RING_ALIGN);
7812 7812
7813 /* [TRC: XXX Using OpenBSD's code, which is rather different 7813 /* [TRC: XXX Using OpenBSD's code, which is rather different
7814 from DragonFlyBSD's.] */ 7814 from DragonFlyBSD's.] */
7815#define TXRX_CTRL(idx) (BWI_TXRX_CTRL_BASE + (idx) * txrx_ctrl_step) 7815#define TXRX_CTRL(idx) (BWI_TXRX_CTRL_BASE + (idx) * txrx_ctrl_step)
7816 /* 7816 /*
7817 * Create TX ring DMA stuffs 7817 * Create TX ring DMA stuffs
7818 */ 7818 */
7819 for (i = 0; i < BWI_TX_NRING; ++i) { 7819 for (i = 0; i < BWI_TX_NRING; ++i) {
7820 error = bus_dmamap_create(sc->sc_dmat, tx_ring_sz, 1, 7820 error = bus_dmamap_create(sc->sc_dmat, tx_ring_sz, 1,
7821 tx_ring_sz, 0, BUS_DMA_NOWAIT, 7821 tx_ring_sz, 0, BUS_DMA_NOWAIT,
7822 &sc->sc_tx_rdata[i].rdata_dmap); 7822 &sc->sc_tx_rdata[i].rdata_dmap);
7823 if (error) { 7823 if (error) {
7824 aprint_error_dev(sc->sc_dev, 7824 aprint_error_dev(sc->sc_dev,
7825 "%dth TX ring DMA create failed\n", i); 7825 "%dth TX ring DMA create failed\n", i);
7826 return (error); 7826 return (error);
7827 } 7827 }
7828 error = bwi_dma_ring_alloc(sc, 7828 error = bwi_dma_ring_alloc(sc,
7829 &sc->sc_tx_rdata[i], tx_ring_sz, TXRX_CTRL(i)); 7829 &sc->sc_tx_rdata[i], tx_ring_sz, TXRX_CTRL(i));
7830 if (error) { 7830 if (error) {
7831 aprint_error_dev(sc->sc_dev, 7831 aprint_error_dev(sc->sc_dev,
7832 "%dth TX ring DMA alloc failed\n", i); 7832 "%dth TX ring DMA alloc failed\n", i);
7833 return (error); 7833 return (error);
7834 } 7834 }
7835 } 7835 }
7836 7836
7837 /* 7837 /*
7838 * Create RX ring DMA stuffs 7838 * Create RX ring DMA stuffs
7839 */ 7839 */
7840 error = bus_dmamap_create(sc->sc_dmat, rx_ring_sz, 1, 7840 error = bus_dmamap_create(sc->sc_dmat, rx_ring_sz, 1,
7841 rx_ring_sz, 0, BUS_DMA_NOWAIT, 7841 rx_ring_sz, 0, BUS_DMA_NOWAIT,
7842 &sc->sc_rx_rdata.rdata_dmap); 7842 &sc->sc_rx_rdata.rdata_dmap);
7843 if (error) { 7843 if (error) {
7844 aprint_error_dev(sc->sc_dev, "RX ring DMA create failed\n"); 7844 aprint_error_dev(sc->sc_dev, "RX ring DMA create failed\n");
7845 return (error); 7845 return (error);
7846 } 7846 }
7847 7847
7848 error = bwi_dma_ring_alloc(sc, &sc->sc_rx_rdata, 7848 error = bwi_dma_ring_alloc(sc, &sc->sc_rx_rdata,
7849 rx_ring_sz, TXRX_CTRL(0)); 7849 rx_ring_sz, TXRX_CTRL(0));
7850 if (error) { 7850 if (error) {
7851 aprint_error_dev(sc->sc_dev, "RX ring DMA alloc failed\n"); 7851 aprint_error_dev(sc->sc_dev, "RX ring DMA alloc failed\n");
7852 return (error); 7852 return (error);
7853 } 7853 }
7854 7854
7855 if (has_txstats) { 7855 if (has_txstats) {
7856 error = bwi_dma_txstats_alloc(sc, TXRX_CTRL(3), desc_sz); 7856 error = bwi_dma_txstats_alloc(sc, TXRX_CTRL(3), desc_sz);
7857 if (error) { 7857 if (error) {
7858 aprint_error_dev(sc->sc_dev, 7858 aprint_error_dev(sc->sc_dev,
7859 "TX stats DMA alloc failed\n"); 7859 "TX stats DMA alloc failed\n");
7860 return (error); 7860 return (error);
7861 } 7861 }
7862 } 7862 }
7863#undef TXRX_CTRL 7863#undef TXRX_CTRL
7864 7864
7865 return (bwi_dma_mbuf_create(sc)); 7865 return (bwi_dma_mbuf_create(sc));
7866} 7866}
7867 7867
7868static void 7868static void
7869bwi_dma_free(struct bwi_softc *sc) 7869bwi_dma_free(struct bwi_softc *sc)
7870{ 7870{
7871 int i; 7871 int i;
7872 7872
7873 for (i = 0; i < BWI_TX_NRING; ++i) 7873 for (i = 0; i < BWI_TX_NRING; ++i)
7874 bwi_ring_data_free(&sc->sc_tx_rdata[i], sc); 7874 bwi_ring_data_free(&sc->sc_tx_rdata[i], sc);
7875 7875
7876 bwi_ring_data_free(&sc->sc_rx_rdata, sc); 7876 bwi_ring_data_free(&sc->sc_rx_rdata, sc);
7877 bwi_dma_txstats_free(sc); 7877 bwi_dma_txstats_free(sc);
7878 bwi_dma_mbuf_destroy(sc, BWI_TX_NRING, 1); 7878 bwi_dma_mbuf_destroy(sc, BWI_TX_NRING, 1);
7879} 7879}
7880 7880
7881static void 7881static void
7882bwi_ring_data_free(struct bwi_ring_data *rd, struct bwi_softc *sc) 7882bwi_ring_data_free(struct bwi_ring_data *rd, struct bwi_softc *sc)
7883{ 7883{
7884 if (rd->rdata_desc != NULL) { 7884 if (rd->rdata_desc != NULL) {
7885 bus_dmamap_unload(sc->sc_dmat, rd->rdata_dmap); 7885 bus_dmamap_unload(sc->sc_dmat, rd->rdata_dmap);
7886 bus_dmamem_free(sc->sc_dmat, &rd->rdata_seg, 1); 7886 bus_dmamem_free(sc->sc_dmat, &rd->rdata_seg, 1);
7887 } 7887 }
7888} 7888}
7889 7889
7890static int 7890static int
7891bwi_dma_ring_alloc(struct bwi_softc *sc, 7891bwi_dma_ring_alloc(struct bwi_softc *sc,
7892 struct bwi_ring_data *rd, bus_size_t size, uint32_t txrx_ctrl) 7892 struct bwi_ring_data *rd, bus_size_t size, uint32_t txrx_ctrl)
7893{ 7893{
7894 int error, nsegs; 7894 int error, nsegs;
7895 7895
7896 error = bus_dmamem_alloc(sc->sc_dmat, size, BWI_ALIGN, 0, 7896 error = bus_dmamem_alloc(sc->sc_dmat, size, BWI_ALIGN, 0,
7897 &rd->rdata_seg, 1, &nsegs, BUS_DMA_NOWAIT); 7897 &rd->rdata_seg, 1, &nsegs, BUS_DMA_NOWAIT);
7898 if (error) { 7898 if (error) {
7899 aprint_error_dev(sc->sc_dev, "can't allocate DMA mem\n"); 7899 aprint_error_dev(sc->sc_dev, "can't allocate DMA mem\n");
7900 return (error); 7900 return (error);
7901 } 7901 }
7902 7902
7903 error = bus_dmamem_map(sc->sc_dmat, &rd->rdata_seg, nsegs, 7903 error = bus_dmamem_map(sc->sc_dmat, &rd->rdata_seg, nsegs,
7904 size, (void **)&rd->rdata_desc, BUS_DMA_NOWAIT); 7904 size, (void **)&rd->rdata_desc, BUS_DMA_NOWAIT);
7905 if (error) { 7905 if (error) {
7906 aprint_error_dev(sc->sc_dev, "can't map DMA mem\n"); 7906 aprint_error_dev(sc->sc_dev, "can't map DMA mem\n");
7907 return (error); 7907 return (error);
7908 } 7908 }
7909 7909
7910 error = bus_dmamap_load(sc->sc_dmat, rd->rdata_dmap, rd->rdata_desc, 7910 error = bus_dmamap_load(sc->sc_dmat, rd->rdata_dmap, rd->rdata_desc,
7911 size, NULL, BUS_DMA_WAITOK); 7911 size, NULL, BUS_DMA_WAITOK);
7912 if (error) { 7912 if (error) {
7913 aprint_error_dev(sc->sc_dev, "can't load DMA mem\n"); 7913 aprint_error_dev(sc->sc_dev, "can't load DMA mem\n");
7914 bus_dmamem_free(sc->sc_dmat, &rd->rdata_seg, nsegs); 7914 bus_dmamem_free(sc->sc_dmat, &rd->rdata_seg, nsegs);
7915 rd->rdata_desc = NULL; 7915 rd->rdata_desc = NULL;
7916 return (error); 7916 return (error);
7917 } 7917 }
7918 7918
7919 rd->rdata_paddr = rd->rdata_dmap->dm_segs[0].ds_addr; 7919 rd->rdata_paddr = rd->rdata_dmap->dm_segs[0].ds_addr;
7920 rd->rdata_txrx_ctrl = txrx_ctrl; 7920 rd->rdata_txrx_ctrl = txrx_ctrl;
7921 7921
7922 return (0); 7922 return (0);
7923} 7923}
7924 7924
7925static int 7925static int
7926bwi_dma_txstats_alloc(struct bwi_softc *sc, uint32_t ctrl_base, 7926bwi_dma_txstats_alloc(struct bwi_softc *sc, uint32_t ctrl_base,
7927 bus_size_t desc_sz) 7927 bus_size_t desc_sz)
7928{ 7928{
7929 struct bwi_txstats_data *st; 7929 struct bwi_txstats_data *st;
7930 bus_size_t dma_size; 7930 bus_size_t dma_size;
7931 int error, nsegs; 7931 int error, nsegs;
7932 7932
7933 st = malloc(sizeof(*st), M_DEVBUF, M_WAITOK | M_ZERO); 7933 st = malloc(sizeof(*st), M_DEVBUF, M_WAITOK | M_ZERO);
7934 sc->sc_txstats = st; 7934 sc->sc_txstats = st;
7935 7935
7936 /* 7936 /*
7937 * Create TX stats descriptor DMA stuffs 7937 * Create TX stats descriptor DMA stuffs
7938 */ 7938 */
7939 dma_size = roundup(desc_sz * BWI_TXSTATS_NDESC, BWI_RING_ALIGN); 7939 dma_size = roundup(desc_sz * BWI_TXSTATS_NDESC, BWI_RING_ALIGN);
7940 7940
7941 error = bus_dmamap_create(sc->sc_dmat, dma_size, 1, dma_size, 0, 7941 error = bus_dmamap_create(sc->sc_dmat, dma_size, 1, dma_size, 0,
7942 BUS_DMA_NOWAIT, &st->stats_ring_dmap); 7942 BUS_DMA_NOWAIT, &st->stats_ring_dmap);
7943 if (error) { 7943 if (error) {
7944 aprint_error_dev(sc->sc_dev, 7944 aprint_error_dev(sc->sc_dev,
7945 "can't create txstats ring DMA mem\n"); 7945 "can't create txstats ring DMA mem\n");
7946 return (error); 7946 return (error);
7947 } 7947 }
7948 7948
7949 error = bus_dmamem_alloc(sc->sc_dmat, dma_size, BWI_RING_ALIGN, 0, 7949 error = bus_dmamem_alloc(sc->sc_dmat, dma_size, BWI_RING_ALIGN, 0,
7950 &st->stats_ring_seg, 1, &nsegs, BUS_DMA_NOWAIT); 7950 &st->stats_ring_seg, 1, &nsegs, BUS_DMA_NOWAIT);
7951 if (error) { 7951 if (error) {
7952 aprint_error_dev(sc->sc_dev, 7952 aprint_error_dev(sc->sc_dev,
7953 "can't allocate txstats ring DMA mem\n"); 7953 "can't allocate txstats ring DMA mem\n");
7954 return (error); 7954 return (error);
7955 } 7955 }
7956 7956
7957 error = bus_dmamem_map(sc->sc_dmat, &st->stats_ring_seg, nsegs, 7957 error = bus_dmamem_map(sc->sc_dmat, &st->stats_ring_seg, nsegs,
7958 dma_size, (void **)&st->stats_ring, BUS_DMA_NOWAIT); 7958 dma_size, (void **)&st->stats_ring, BUS_DMA_NOWAIT);
7959 if (error) { 7959 if (error) {
7960 aprint_error_dev(sc->sc_dev, 7960 aprint_error_dev(sc->sc_dev,
7961 "can't map txstats ring DMA mem\n"); 7961 "can't map txstats ring DMA mem\n");
7962 return (error); 7962 return (error);
7963 } 7963 }
7964 7964
7965 error = bus_dmamap_load(sc->sc_dmat, st->stats_ring_dmap, 7965 error = bus_dmamap_load(sc->sc_dmat, st->stats_ring_dmap,
7966 st->stats_ring, dma_size, NULL, BUS_DMA_WAITOK); 7966 st->stats_ring, dma_size, NULL, BUS_DMA_WAITOK);
7967 if (error) { 7967 if (error) {
7968 aprint_error_dev(sc->sc_dev, 7968 aprint_error_dev(sc->sc_dev,
7969 "can't load txstats ring DMA mem\n"); 7969 "can't load txstats ring DMA mem\n");
7970 bus_dmamem_free(sc->sc_dmat, &st->stats_ring_seg, nsegs); 7970 bus_dmamem_free(sc->sc_dmat, &st->stats_ring_seg, nsegs);
7971 return (error); 7971 return (error);
7972 } 7972 }
7973 7973
7974 memset(st->stats_ring, 0, dma_size); 7974 memset(st->stats_ring, 0, dma_size);
7975 st->stats_ring_paddr = st->stats_ring_dmap->dm_segs[0].ds_addr; 7975 st->stats_ring_paddr = st->stats_ring_dmap->dm_segs[0].ds_addr;
7976 7976
7977 /* 7977 /*
7978 * Create TX stats DMA stuffs 7978 * Create TX stats DMA stuffs
7979 */ 7979 */
7980 dma_size = roundup(sizeof(struct bwi_txstats) * BWI_TXSTATS_NDESC, 7980 dma_size = roundup(sizeof(struct bwi_txstats) * BWI_TXSTATS_NDESC,
7981 BWI_ALIGN); 7981 BWI_ALIGN);
7982 7982
7983 error = bus_dmamap_create(sc->sc_dmat, dma_size, 1, dma_size, 0, 7983 error = bus_dmamap_create(sc->sc_dmat, dma_size, 1, dma_size, 0,
7984 BUS_DMA_NOWAIT, &st->stats_dmap); 7984 BUS_DMA_NOWAIT, &st->stats_dmap);
7985 if (error) { 7985 if (error) {
7986 aprint_error_dev(sc->sc_dev, 7986 aprint_error_dev(sc->sc_dev,
7987 "can't create txstats ring DMA mem\n"); 7987 "can't create txstats ring DMA mem\n");
7988 return (error); 7988 return (error);
7989 } 7989 }
7990 7990
7991 error = bus_dmamem_alloc(sc->sc_dmat, dma_size, BWI_ALIGN, 0, 7991 error = bus_dmamem_alloc(sc->sc_dmat, dma_size, BWI_ALIGN, 0,
7992 &st->stats_seg, 1, &nsegs, BUS_DMA_NOWAIT); 7992 &st->stats_seg, 1, &nsegs, BUS_DMA_NOWAIT);
7993 if (error) { 7993 if (error) {
7994 aprint_error_dev(sc->sc_dev, 7994 aprint_error_dev(sc->sc_dev,
7995 "can't allocate txstats DMA mem\n"); 7995 "can't allocate txstats DMA mem\n");
7996 return (error); 7996 return (error);
7997 } 7997 }
7998 7998
7999 error = bus_dmamem_map(sc->sc_dmat, &st->stats_seg, nsegs, 7999 error = bus_dmamem_map(sc->sc_dmat, &st->stats_seg, nsegs,
8000 dma_size, (void **)&st->stats, BUS_DMA_NOWAIT); 8000 dma_size, (void **)&st->stats, BUS_DMA_NOWAIT);
8001 if (error) { 8001 if (error) {
8002 aprint_error_dev(sc->sc_dev, "can't map txstats DMA mem\n"); 8002 aprint_error_dev(sc->sc_dev, "can't map txstats DMA mem\n");
8003 return (error); 8003 return (error);
8004 } 8004 }
8005 8005
8006 error = bus_dmamap_load(sc->sc_dmat, st->stats_dmap, st->stats, 8006 error = bus_dmamap_load(sc->sc_dmat, st->stats_dmap, st->stats,
8007 dma_size, NULL, BUS_DMA_WAITOK); 8007 dma_size, NULL, BUS_DMA_WAITOK);
8008 if (error) { 8008 if (error) {
8009 aprint_error_dev(sc->sc_dev, "can't load txstats DMA mem\n"); 8009 aprint_error_dev(sc->sc_dev, "can't load txstats DMA mem\n");
8010 bus_dmamem_free(sc->sc_dmat, &st->stats_seg, nsegs); 8010 bus_dmamem_free(sc->sc_dmat, &st->stats_seg, nsegs);
8011 return (error); 8011 return (error);
8012 } 8012 }
8013 8013
8014 memset(st->stats, 0, dma_size); 8014 memset(st->stats, 0, dma_size);
8015 st->stats_paddr = st->stats_dmap->dm_segs[0].ds_addr; 8015 st->stats_paddr = st->stats_dmap->dm_segs[0].ds_addr;
8016 st->stats_ctrl_base = ctrl_base; 8016 st->stats_ctrl_base = ctrl_base;
8017 8017
8018 return (0); 8018 return (0);
8019} 8019}
8020 8020
8021static void 8021static void
8022bwi_dma_txstats_free(struct bwi_softc *sc) 8022bwi_dma_txstats_free(struct bwi_softc *sc)
8023{ 8023{
8024 struct bwi_txstats_data *st; 8024 struct bwi_txstats_data *st;
8025 8025
8026 if (sc->sc_txstats == NULL) 8026 if (sc->sc_txstats == NULL)
8027 return; 8027 return;
8028 st = sc->sc_txstats; 8028 st = sc->sc_txstats;
8029 8029
8030 bus_dmamap_unload(sc->sc_dmat, st->stats_ring_dmap); 8030 bus_dmamap_unload(sc->sc_dmat, st->stats_ring_dmap);
8031 bus_dmamem_free(sc->sc_dmat, &st->stats_ring_seg, 1); 8031 bus_dmamem_free(sc->sc_dmat, &st->stats_ring_seg, 1);
8032 8032
8033 bus_dmamap_unload(sc->sc_dmat, st->stats_dmap); 8033 bus_dmamap_unload(sc->sc_dmat, st->stats_dmap);
8034 bus_dmamem_free(sc->sc_dmat, &st->stats_seg, 1); 8034 bus_dmamem_free(sc->sc_dmat, &st->stats_seg, 1);
8035 8035
8036 free(st, M_DEVBUF); 8036 free(st, M_DEVBUF);
8037} 8037}
8038 8038
8039static int 8039static int
8040bwi_dma_mbuf_create(struct bwi_softc *sc) 8040bwi_dma_mbuf_create(struct bwi_softc *sc)
8041{ 8041{
8042 struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata; 8042 struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata;
8043 int i, j, k, ntx, error; 8043 int i, j, k, ntx, error;
8044 8044
8045 ntx = 0; 8045 ntx = 0;
8046 8046
8047 /* 8047 /*
8048 * Create TX mbuf DMA map 8048 * Create TX mbuf DMA map
8049 */ 8049 */
8050 for (i = 0; i < BWI_TX_NRING; ++i) { 8050 for (i = 0; i < BWI_TX_NRING; ++i) {
8051 struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[i]; 8051 struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[i];
8052 8052
8053 for (j = 0; j < BWI_TX_NDESC; ++j) { 8053 for (j = 0; j < BWI_TX_NDESC; ++j) {
8054 error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES, 8054 error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES,
8055 0, BUS_DMA_NOWAIT, &tbd->tbd_buf[j].tb_dmap); 8055 0, BUS_DMA_NOWAIT, &tbd->tbd_buf[j].tb_dmap);
8056 if (error) { 8056 if (error) {
8057 aprint_error_dev(sc->sc_dev, 8057 aprint_error_dev(sc->sc_dev,
8058 "can't create %dth tbd, %dth DMA map\n", 8058 "can't create %dth tbd, %dth DMA map\n",
8059 i, j); 8059 i, j);
8060 ntx = i; 8060 ntx = i;
8061 for (k = 0; k < j; ++k) { 8061 for (k = 0; k < j; ++k) {
8062 bus_dmamap_destroy(sc->sc_dmat, 8062 bus_dmamap_destroy(sc->sc_dmat,
8063 tbd->tbd_buf[k].tb_dmap); 8063 tbd->tbd_buf[k].tb_dmap);
8064 } 8064 }
8065 goto fail; 8065 goto fail;
8066 } 8066 }
8067 } 8067 }
8068 } 8068 }
8069 ntx = BWI_TX_NRING; 8069 ntx = BWI_TX_NRING;
8070 8070
8071 /* 8071 /*
8072 * Create RX mbuf DMA map and a spare DMA map 8072 * Create RX mbuf DMA map and a spare DMA map
8073 */ 8073 */
8074 error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES, 0, 8074 error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES, 0,
8075 BUS_DMA_NOWAIT, &rbd->rbd_tmp_dmap); 8075 BUS_DMA_NOWAIT, &rbd->rbd_tmp_dmap);
8076 if (error) { 8076 if (error) {
8077 aprint_error_dev(sc->sc_dev, 8077 aprint_error_dev(sc->sc_dev,
8078 "can't create spare RX buf DMA map\n"); 8078 "can't create spare RX buf DMA map\n");
8079 goto fail; 8079 goto fail;
8080 } 8080 }
8081 8081
8082 for (j = 0; j < BWI_RX_NDESC; ++j) { 8082 for (j = 0; j < BWI_RX_NDESC; ++j) {
8083 error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES, 0, 8083 error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES, 0,
8084 BUS_DMA_NOWAIT, &rbd->rbd_buf[j].rb_dmap); 8084 BUS_DMA_NOWAIT, &rbd->rbd_buf[j].rb_dmap);
8085 if (error) { 8085 if (error) {
8086 aprint_error_dev(sc->sc_dev, 8086 aprint_error_dev(sc->sc_dev,
8087 "can't create %dth RX buf DMA map\n", j); 8087 "can't create %dth RX buf DMA map\n", j);
8088 8088
8089 for (k = 0; k < j; ++k) { 8089 for (k = 0; k < j; ++k) {
8090 bus_dmamap_destroy(sc->sc_dmat, 8090 bus_dmamap_destroy(sc->sc_dmat,
8091 rbd->rbd_buf[j].rb_dmap); 8091 rbd->rbd_buf[j].rb_dmap);
8092 } 8092 }
8093 bus_dmamap_destroy(sc->sc_dmat, 8093 bus_dmamap_destroy(sc->sc_dmat,
8094 rbd->rbd_tmp_dmap); 8094 rbd->rbd_tmp_dmap);
8095 goto fail; 8095 goto fail;
8096 } 8096 }
8097 } 8097 }
8098 8098
8099 return (0); 8099 return (0);
8100fail: 8100fail:
8101 bwi_dma_mbuf_destroy(sc, ntx, 0); 8101 bwi_dma_mbuf_destroy(sc, ntx, 0);
8102 8102
8103 return (error); 8103 return (error);
8104} 8104}
8105 8105
8106static void 8106static void
8107bwi_dma_mbuf_destroy(struct bwi_softc *sc, int ntx, int nrx) 8107bwi_dma_mbuf_destroy(struct bwi_softc *sc, int ntx, int nrx)
8108{ 8108{
8109 int i, j; 8109 int i, j;
8110 8110
8111 for (i = 0; i < ntx; ++i) { 8111 for (i = 0; i < ntx; ++i) {
8112 struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[i]; 8112 struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[i];
8113 8113
8114 for (j = 0; j < BWI_TX_NDESC; ++j) { 8114 for (j = 0; j < BWI_TX_NDESC; ++j) {
8115 struct bwi_txbuf *tb = &tbd->tbd_buf[j]; 8115 struct bwi_txbuf *tb = &tbd->tbd_buf[j];
8116 8116
8117 if (tb->tb_mbuf != NULL) { 8117 if (tb->tb_mbuf != NULL) {
8118 bus_dmamap_unload(sc->sc_dmat, 8118 bus_dmamap_unload(sc->sc_dmat,
8119 tb->tb_dmap); 8119 tb->tb_dmap);
8120 m_freem(tb->tb_mbuf); 8120 m_freem(tb->tb_mbuf);
8121 } 8121 }
8122 if (tb->tb_ni != NULL) 8122 if (tb->tb_ni != NULL)
8123 ieee80211_free_node(tb->tb_ni); 8123 ieee80211_free_node(tb->tb_ni);
8124 bus_dmamap_destroy(sc->sc_dmat, tb->tb_dmap); 8124 bus_dmamap_destroy(sc->sc_dmat, tb->tb_dmap);
8125 } 8125 }
8126 } 8126 }
8127 8127
8128 if (nrx) { 8128 if (nrx) {
8129 struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata; 8129 struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata;
8130 8130
8131 bus_dmamap_destroy(sc->sc_dmat, rbd->rbd_tmp_dmap); 8131 bus_dmamap_destroy(sc->sc_dmat, rbd->rbd_tmp_dmap);
8132 for (j = 0; j < BWI_RX_NDESC; ++j) { 8132 for (j = 0; j < BWI_RX_NDESC; ++j) {
8133 struct bwi_rxbuf *rb = &rbd->rbd_buf[j]; 8133 struct bwi_rxbuf *rb = &rbd->rbd_buf[j];
8134 8134
8135 if (rb->rb_mbuf != NULL) { 8135 if (rb->rb_mbuf != NULL) {
8136 bus_dmamap_unload(sc->sc_dmat, 8136 bus_dmamap_unload(sc->sc_dmat,
8137 rb->rb_dmap); 8137 rb->rb_dmap);
8138 m_freem(rb->rb_mbuf); 8138 m_freem(rb->rb_mbuf);
8139 } 8139 }
8140 bus_dmamap_destroy(sc->sc_dmat, rb->rb_dmap); 8140 bus_dmamap_destroy(sc->sc_dmat, rb->rb_dmap);
8141 } 8141 }
8142 } 8142 }
8143} 8143}
8144 8144
8145static void 8145static void
8146bwi_enable_intrs(struct bwi_softc *sc, uint32_t enable_intrs) 8146bwi_enable_intrs(struct bwi_softc *sc, uint32_t enable_intrs)
8147{ 8147{
8148 CSR_SETBITS_4(sc, BWI_MAC_INTR_MASK, enable_intrs); 8148 CSR_SETBITS_4(sc, BWI_MAC_INTR_MASK, enable_intrs);
8149} 8149}
8150 8150
8151static void 8151static void
8152bwi_disable_intrs(struct bwi_softc *sc, uint32_t disable_intrs) 8152bwi_disable_intrs(struct bwi_softc *sc, uint32_t disable_intrs)
8153{ 8153{
8154 CSR_CLRBITS_4(sc, BWI_MAC_INTR_MASK, disable_intrs); 8154 CSR_CLRBITS_4(sc, BWI_MAC_INTR_MASK, disable_intrs);
8155} 8155}
8156 8156
8157static int 8157static int
8158bwi_init_tx_ring32(struct bwi_softc *sc, int ring_idx) 8158bwi_init_tx_ring32(struct bwi_softc *sc, int ring_idx)
8159{ 8159{
8160 struct bwi_ring_data *rd; 8160 struct bwi_ring_data *rd;
8161 struct bwi_txbuf_data *tbd; 8161 struct bwi_txbuf_data *tbd;
8162 uint32_t val, addr_hi, addr_lo; 8162 uint32_t val, addr_hi, addr_lo;
8163 8163
8164 KASSERT(ring_idx < BWI_TX_NRING); 8164 KASSERT(ring_idx < BWI_TX_NRING);
8165 rd = &sc->sc_tx_rdata[ring_idx]; 8165 rd = &sc->sc_tx_rdata[ring_idx];
8166 tbd = &sc->sc_tx_bdata[ring_idx]; 8166 tbd = &sc->sc_tx_bdata[ring_idx];
8167 8167
8168 tbd->tbd_idx = 0; 8168 tbd->tbd_idx = 0;
8169 tbd->tbd_used = 0; 8169 tbd->tbd_used = 0;
8170 8170
8171 memset(rd->rdata_desc, 0, sizeof(struct bwi_desc32) * BWI_TX_NDESC); 8171 memset(rd->rdata_desc, 0, sizeof(struct bwi_desc32) * BWI_TX_NDESC);
8172 bus_dmamap_sync(sc->sc_dmat, rd->rdata_dmap, 0, 8172 bus_dmamap_sync(sc->sc_dmat, rd->rdata_dmap, 0,
8173 rd->rdata_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE); 8173 rd->rdata_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE);
8174 8174
8175 addr_lo = __SHIFTOUT(rd->rdata_paddr, BWI_TXRX32_RINGINFO_ADDR_MASK); 8175 addr_lo = __SHIFTOUT(rd->rdata_paddr, BWI_TXRX32_RINGINFO_ADDR_MASK);
8176 addr_hi = __SHIFTOUT(rd->rdata_paddr, BWI_TXRX32_RINGINFO_FUNC_MASK); 8176 addr_hi = __SHIFTOUT(rd->rdata_paddr, BWI_TXRX32_RINGINFO_FUNC_MASK);
8177 8177
8178 val = __SHIFTIN(addr_lo, BWI_TXRX32_RINGINFO_ADDR_MASK) | 8178 val = __SHIFTIN(addr_lo, BWI_TXRX32_RINGINFO_ADDR_MASK) |
8179 __SHIFTIN(BWI_TXRX32_RINGINFO_FUNC_TXRX, 8179 __SHIFTIN(BWI_TXRX32_RINGINFO_FUNC_TXRX,
8180 BWI_TXRX32_RINGINFO_FUNC_MASK); 8180 BWI_TXRX32_RINGINFO_FUNC_MASK);
8181 CSR_WRITE_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_RINGINFO, val); 8181 CSR_WRITE_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_RINGINFO, val);
8182 8182
8183 val = __SHIFTIN(addr_hi, BWI_TXRX32_CTRL_ADDRHI_MASK) | 8183 val = __SHIFTIN(addr_hi, BWI_TXRX32_CTRL_ADDRHI_MASK) |
8184 BWI_TXRX32_CTRL_ENABLE; 8184 BWI_TXRX32_CTRL_ENABLE;
8185 CSR_WRITE_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_CTRL, val); 8185 CSR_WRITE_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_CTRL, val);
8186 8186
8187 return (0); 8187 return (0);
8188} 8188}
8189 8189
8190static void 8190static void
8191bwi_init_rxdesc_ring32(struct bwi_softc *sc, uint32_t ctrl_base, 8191bwi_init_rxdesc_ring32(struct bwi_softc *sc, uint32_t ctrl_base,
8192 bus_addr_t paddr, int hdr_size, int ndesc) 8192 bus_addr_t paddr, int hdr_size, int ndesc)
8193{ 8193{
8194 uint32_t val, addr_hi, addr_lo; 8194 uint32_t val, addr_hi, addr_lo;
8195 8195
8196 addr_lo = __SHIFTOUT(paddr, BWI_TXRX32_RINGINFO_ADDR_MASK); 8196 addr_lo = __SHIFTOUT(paddr, BWI_TXRX32_RINGINFO_ADDR_MASK);
8197 addr_hi = __SHIFTOUT(paddr, BWI_TXRX32_RINGINFO_FUNC_MASK); 8197 addr_hi = __SHIFTOUT(paddr, BWI_TXRX32_RINGINFO_FUNC_MASK);
8198 8198
8199 val = __SHIFTIN(addr_lo, BWI_TXRX32_RINGINFO_ADDR_MASK) | 8199 val = __SHIFTIN(addr_lo, BWI_TXRX32_RINGINFO_ADDR_MASK) |
8200 __SHIFTIN(BWI_TXRX32_RINGINFO_FUNC_TXRX, 8200 __SHIFTIN(BWI_TXRX32_RINGINFO_FUNC_TXRX,
8201 BWI_TXRX32_RINGINFO_FUNC_MASK); 8201 BWI_TXRX32_RINGINFO_FUNC_MASK);
8202 CSR_WRITE_4(sc, ctrl_base + BWI_RX32_RINGINFO, val); 8202 CSR_WRITE_4(sc, ctrl_base + BWI_RX32_RINGINFO, val);
8203 8203
8204 val = __SHIFTIN(hdr_size, BWI_RX32_CTRL_HDRSZ_MASK) | 8204 val = __SHIFTIN(hdr_size, BWI_RX32_CTRL_HDRSZ_MASK) |
8205 __SHIFTIN(addr_hi, BWI_TXRX32_CTRL_ADDRHI_MASK) | 8205 __SHIFTIN(addr_hi, BWI_TXRX32_CTRL_ADDRHI_MASK) |
8206 BWI_TXRX32_CTRL_ENABLE; 8206 BWI_TXRX32_CTRL_ENABLE;
8207 CSR_WRITE_4(sc, ctrl_base + BWI_RX32_CTRL, val); 8207 CSR_WRITE_4(sc, ctrl_base + BWI_RX32_CTRL, val);
8208 8208
8209 CSR_WRITE_4(sc, ctrl_base + BWI_RX32_INDEX, 8209 CSR_WRITE_4(sc, ctrl_base + BWI_RX32_INDEX,
8210 (ndesc - 1) * sizeof(struct bwi_desc32)); 8210 (ndesc - 1) * sizeof(struct bwi_desc32));
8211} 8211}
8212 8212
8213static int 8213static int
8214bwi_init_rx_ring32(struct bwi_softc *sc) 8214bwi_init_rx_ring32(struct bwi_softc *sc)
8215{ 8215{
8216 struct bwi_ring_data *rd = &sc->sc_rx_rdata; 8216 struct bwi_ring_data *rd = &sc->sc_rx_rdata;
8217 int i, error; 8217 int i, error;
8218 8218
8219 sc->sc_rx_bdata.rbd_idx = 0; 8219 sc->sc_rx_bdata.rbd_idx = 0;
8220 8220
8221 for (i = 0; i < BWI_RX_NDESC; ++i) { 8221 for (i = 0; i < BWI_RX_NDESC; ++i) {
8222 error = bwi_newbuf(sc, i, 1); 8222 error = bwi_newbuf(sc, i, 1);
8223 if (error) { 8223 if (error) {
8224 aprint_error_dev(sc->sc_dev, 8224 aprint_error_dev(sc->sc_dev,
8225 "can't allocate %dth RX buffer\n", i); 8225 "can't allocate %dth RX buffer\n", i);
8226 return (error); 8226 return (error);
8227 } 8227 }
8228 } 8228 }
8229 bus_dmamap_sync(sc->sc_dmat, rd->rdata_dmap, 0, 8229 bus_dmamap_sync(sc->sc_dmat, rd->rdata_dmap, 0,
8230 rd->rdata_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE); 8230 rd->rdata_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE);
8231 8231
8232 bwi_init_rxdesc_ring32(sc, rd->rdata_txrx_ctrl, rd->rdata_paddr, 8232 bwi_init_rxdesc_ring32(sc, rd->rdata_txrx_ctrl, rd->rdata_paddr,
8233 sizeof(struct bwi_rxbuf_hdr), BWI_RX_NDESC); 8233 sizeof(struct bwi_rxbuf_hdr), BWI_RX_NDESC);
8234 return (0); 8234 return (0);
8235} 8235}
8236 8236
8237static int 8237static int
8238bwi_init_txstats32(struct bwi_softc *sc) 8238bwi_init_txstats32(struct bwi_softc *sc)
8239{ 8239{
8240 struct bwi_txstats_data *st = sc->sc_txstats; 8240 struct bwi_txstats_data *st = sc->sc_txstats;
8241 bus_addr_t stats_paddr; 8241 bus_addr_t stats_paddr;
8242 int i; 8242 int i;
8243 8243
8244 memset(st->stats, 0, BWI_TXSTATS_NDESC * sizeof(struct bwi_txstats)); 8244 memset(st->stats, 0, BWI_TXSTATS_NDESC * sizeof(struct bwi_txstats));
8245 bus_dmamap_sync(sc->sc_dmat, st->stats_dmap, 0, 8245 bus_dmamap_sync(sc->sc_dmat, st->stats_dmap, 0,
8246 st->stats_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE); 8246 st->stats_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE);
8247 8247
8248 st->stats_idx = 0; 8248 st->stats_idx = 0;
8249 8249
8250 stats_paddr = st->stats_paddr; 8250 stats_paddr = st->stats_paddr;
8251 for (i = 0; i < BWI_TXSTATS_NDESC; ++i) { 8251 for (i = 0; i < BWI_TXSTATS_NDESC; ++i) {
8252 bwi_setup_desc32(sc, st->stats_ring, BWI_TXSTATS_NDESC, i, 8252 bwi_setup_desc32(sc, st->stats_ring, BWI_TXSTATS_NDESC, i,
8253 stats_paddr, sizeof(struct bwi_txstats), 0); 8253 stats_paddr, sizeof(struct bwi_txstats), 0);
8254 stats_paddr += sizeof(struct bwi_txstats); 8254 stats_paddr += sizeof(struct bwi_txstats);
8255 } 8255 }
8256 bus_dmamap_sync(sc->sc_dmat, st->stats_ring_dmap, 0, 8256 bus_dmamap_sync(sc->sc_dmat, st->stats_ring_dmap, 0,
8257 st->stats_ring_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE); 8257 st->stats_ring_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE);
8258 8258
8259 bwi_init_rxdesc_ring32(sc, st->stats_ctrl_base, 8259 bwi_init_rxdesc_ring32(sc, st->stats_ctrl_base,
8260 st->stats_ring_paddr, 0, BWI_TXSTATS_NDESC); 8260 st->stats_ring_paddr, 0, BWI_TXSTATS_NDESC);
8261 8261
8262 return (0); 8262 return (0);
8263} 8263}
8264 8264
8265static void 8265static void
8266bwi_setup_rx_desc32(struct bwi_softc *sc, int buf_idx, bus_addr_t paddr, 8266bwi_setup_rx_desc32(struct bwi_softc *sc, int buf_idx, bus_addr_t paddr,
8267 int buf_len) 8267 int buf_len)
8268{ 8268{
8269 struct bwi_ring_data *rd = &sc->sc_rx_rdata; 8269 struct bwi_ring_data *rd = &sc->sc_rx_rdata;
8270 8270
8271 KASSERT(buf_idx < BWI_RX_NDESC); 8271 KASSERT(buf_idx < BWI_RX_NDESC);
8272 bwi_setup_desc32(sc, rd->rdata_desc, BWI_RX_NDESC, buf_idx, 8272 bwi_setup_desc32(sc, rd->rdata_desc, BWI_RX_NDESC, buf_idx,
8273 paddr, buf_len, 0); 8273 paddr, buf_len, 0);
8274} 8274}
8275 8275
8276static void 8276static void
8277bwi_setup_tx_desc32(struct bwi_softc *sc, struct bwi_ring_data *rd, 8277bwi_setup_tx_desc32(struct bwi_softc *sc, struct bwi_ring_data *rd,
8278 int buf_idx, bus_addr_t paddr, int buf_len) 8278 int buf_idx, bus_addr_t paddr, int buf_len)
8279{ 8279{
8280 KASSERT(buf_idx < BWI_TX_NDESC); 8280 KASSERT(buf_idx < BWI_TX_NDESC);
8281 bwi_setup_desc32(sc, rd->rdata_desc, BWI_TX_NDESC, buf_idx, 8281 bwi_setup_desc32(sc, rd->rdata_desc, BWI_TX_NDESC, buf_idx,
8282 paddr, buf_len, 1); 8282 paddr, buf_len, 1);
8283} 8283}
8284static int 8284static int
8285bwi_init_tx_ring64(struct bwi_softc *sc, int ring_idx) 8285bwi_init_tx_ring64(struct bwi_softc *sc, int ring_idx)
8286{ 8286{
8287 /* TODO: 64 */ 8287 /* TODO: 64 */
8288 return (EOPNOTSUPP); 8288 return (EOPNOTSUPP);
8289} 8289}
8290 8290
8291static int 8291static int
8292bwi_init_rx_ring64(struct bwi_softc *sc) 8292bwi_init_rx_ring64(struct bwi_softc *sc)
8293{ 8293{
8294 /* TODO: 64 */ 8294 /* TODO: 64 */
8295 return (EOPNOTSUPP); 8295 return (EOPNOTSUPP);
8296} 8296}
8297 8297
8298static int 8298static int
8299bwi_init_txstats64(struct bwi_softc *sc) 8299bwi_init_txstats64(struct bwi_softc *sc)
8300{ 8300{
8301 /* TODO: 64 */ 8301 /* TODO: 64 */
8302 return (EOPNOTSUPP); 8302 return (EOPNOTSUPP);
8303} 8303}
8304 8304
8305static void 8305static void
8306bwi_setup_rx_desc64(struct bwi_softc *sc, int buf_idx, bus_addr_t paddr, 8306bwi_setup_rx_desc64(struct bwi_softc *sc, int buf_idx, bus_addr_t paddr,
8307 int buf_len) 8307 int buf_len)
8308{ 8308{
8309 /* TODO: 64 */ 8309 /* TODO: 64 */
8310} 8310}
8311 8311
8312static void 8312static void
8313bwi_setup_tx_desc64(struct bwi_softc *sc, struct bwi_ring_data *rd, 8313bwi_setup_tx_desc64(struct bwi_softc *sc, struct bwi_ring_data *rd,
8314 int buf_idx, bus_addr_t paddr, int buf_len) 8314 int buf_idx, bus_addr_t paddr, int buf_len)
8315{ 8315{
8316 /* TODO: 64 */ 8316 /* TODO: 64 */
8317} 8317}
8318 8318
8319static int 8319static int
8320bwi_newbuf(struct bwi_softc *sc, int buf_idx, int init) 8320bwi_newbuf(struct bwi_softc *sc, int buf_idx, int init)
8321{ 8321{
8322 struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata; 8322 struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata;
8323 struct bwi_rxbuf *rxbuf = &rbd->rbd_buf[buf_idx]; 8323 struct bwi_rxbuf *rxbuf = &rbd->rbd_buf[buf_idx];
8324 struct bwi_rxbuf_hdr *hdr; 8324 struct bwi_rxbuf_hdr *hdr;
8325 bus_dmamap_t map; 8325 bus_dmamap_t map;
8326 bus_addr_t paddr; 8326 bus_addr_t paddr;
8327 struct mbuf *m; 8327 struct mbuf *m;
8328 int error; 8328 int error;
8329 8329
8330 KASSERT(buf_idx < BWI_RX_NDESC); 8330 KASSERT(buf_idx < BWI_RX_NDESC);
8331 8331
8332 MGETHDR(m, init ? M_WAITOK : M_DONTWAIT, MT_DATA); 8332 MGETHDR(m, init ? M_WAITOK : M_DONTWAIT, MT_DATA);
8333 if (m == NULL) 8333 if (m == NULL)
8334 return (ENOBUFS); 8334 return (ENOBUFS);
8335 MCLGET(m, init ? M_WAITOK : M_DONTWAIT); 8335 MCLGET(m, init ? M_WAITOK : M_DONTWAIT);
8336 if ((m->m_flags & M_EXT) == 0) { 8336 if ((m->m_flags & M_EXT) == 0) {
8337 error = ENOBUFS; 8337 error = ENOBUFS;
8338 8338
8339 /* 8339 /*
8340 * If the NIC is up and running, we need to: 8340 * If the NIC is up and running, we need to:
8341 * - Clear RX buffer's header. 8341 * - Clear RX buffer's header.
8342 * - Restore RX descriptor settings. 8342 * - Restore RX descriptor settings.
8343 */ 8343 */
8344 if (init) 8344 if (init)
8345 return error; 8345 return error;
8346 else 8346 else
8347 goto back; 8347 goto back;
8348 } 8348 }
8349 m->m_len = m->m_pkthdr.len = MCLBYTES; 8349 m->m_len = m->m_pkthdr.len = MCLBYTES;
8350 8350
8351 /* 8351 /*
8352 * Try to load RX buf into temporary DMA map 8352 * Try to load RX buf into temporary DMA map
8353 */ 8353 */
8354 error = bus_dmamap_load_mbuf(sc->sc_dmat, rbd->rbd_tmp_dmap, m, 8354 error = bus_dmamap_load_mbuf(sc->sc_dmat, rbd->rbd_tmp_dmap, m,
8355 init ? BUS_DMA_WAITOK : BUS_DMA_NOWAIT); 8355 init ? BUS_DMA_WAITOK : BUS_DMA_NOWAIT);
8356 if (error) { 8356 if (error) {
8357 m_freem(m); 8357 m_freem(m);
8358 8358
8359 /* 8359 /*
8360 * See the comment above 8360 * See the comment above
8361 */ 8361 */
8362 if (init) 8362 if (init)
8363 return error; 8363 return error;
8364 else 8364 else
8365 goto back; 8365 goto back;
8366 } 8366 }
8367 8367
8368 if (!init) 8368 if (!init)
8369 bus_dmamap_unload(sc->sc_dmat, rxbuf->rb_dmap); 8369 bus_dmamap_unload(sc->sc_dmat, rxbuf->rb_dmap);
8370 rxbuf->rb_mbuf = m; 8370 rxbuf->rb_mbuf = m;
8371 8371
8372 /* 8372 /*
8373 * Swap RX buf's DMA map with the loaded temporary one 8373 * Swap RX buf's DMA map with the loaded temporary one
8374 */ 8374 */
8375 map = rxbuf->rb_dmap; 8375 map = rxbuf->rb_dmap;
8376 rxbuf->rb_dmap = rbd->rbd_tmp_dmap; 8376 rxbuf->rb_dmap = rbd->rbd_tmp_dmap;
8377 rbd->rbd_tmp_dmap = map; 8377 rbd->rbd_tmp_dmap = map;
8378 paddr = rxbuf->rb_dmap->dm_segs[0].ds_addr; 8378 paddr = rxbuf->rb_dmap->dm_segs[0].ds_addr;
8379 rxbuf->rb_paddr = paddr; 8379 rxbuf->rb_paddr = paddr;
8380 8380
8381back: 8381back:
8382 /* 8382 /*
8383 * Clear RX buf header 8383 * Clear RX buf header
8384 */ 8384 */
8385 hdr = mtod(rxbuf->rb_mbuf, struct bwi_rxbuf_hdr *); 8385 hdr = mtod(rxbuf->rb_mbuf, struct bwi_rxbuf_hdr *);
8386 memset(hdr, 0, sizeof(*hdr)); 8386 memset(hdr, 0, sizeof(*hdr));
8387 bus_dmamap_sync(sc->sc_dmat, rxbuf->rb_dmap, 0, 8387 bus_dmamap_sync(sc->sc_dmat, rxbuf->rb_dmap, 0,
8388 rxbuf->rb_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE); 8388 rxbuf->rb_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE);
8389 8389
8390 /* 8390 /*
8391 * Setup RX buf descriptor 8391 * Setup RX buf descriptor
8392 */ 8392 */
8393 (sc->sc_setup_rxdesc)(sc, buf_idx, rxbuf->rb_paddr, 8393 (sc->sc_setup_rxdesc)(sc, buf_idx, rxbuf->rb_paddr,
8394 rxbuf->rb_mbuf->m_len - sizeof(*hdr)); 8394 rxbuf->rb_mbuf->m_len - sizeof(*hdr));
8395 return error; 8395 return error;
8396} 8396}
8397 8397
8398static void 8398static void
8399bwi_set_addr_filter(struct bwi_softc *sc, uint16_t addr_ofs, 8399bwi_set_addr_filter(struct bwi_softc *sc, uint16_t addr_ofs,
8400 const uint8_t *addr) 8400 const uint8_t *addr)
8401{ 8401{
8402 int i; 8402 int i;
8403 8403
8404 CSR_WRITE_2(sc, BWI_ADDR_FILTER_CTRL, 8404 CSR_WRITE_2(sc, BWI_ADDR_FILTER_CTRL,
8405 BWI_ADDR_FILTER_CTRL_SET | addr_ofs); 8405 BWI_ADDR_FILTER_CTRL_SET | addr_ofs);
8406 8406
8407 for (i = 0; i < (IEEE80211_ADDR_LEN / 2); ++i) { 8407 for (i = 0; i < (IEEE80211_ADDR_LEN / 2); ++i) {
8408 uint16_t addr_val; 8408 uint16_t addr_val;
8409 8409
8410 addr_val = (uint16_t)addr[i * 2] | 8410 addr_val = (uint16_t)addr[i * 2] |
8411 (((uint16_t)addr[(i * 2) + 1]) << 8); 8411 (((uint16_t)addr[(i * 2) + 1]) << 8);
8412 CSR_WRITE_2(sc, BWI_ADDR_FILTER_DATA, addr_val); 8412 CSR_WRITE_2(sc, BWI_ADDR_FILTER_DATA, addr_val);
8413 } 8413 }
8414} 8414}
8415 8415
8416static int 8416static int
8417bwi_set_chan(struct bwi_softc *sc, struct ieee80211_channel *c) 8417bwi_set_chan(struct bwi_softc *sc, struct ieee80211_channel *c)
8418{ 8418{
8419 struct ieee80211com *ic = &sc->sc_ic; 8419 struct ieee80211com *ic = &sc->sc_ic;
8420 struct bwi_mac *mac; 8420 struct bwi_mac *mac;
8421 /* uint16_t flags; */ /* [TRC: XXX See below.] */ 8421 /* uint16_t flags; */ /* [TRC: XXX See below.] */
8422 uint chan; 8422 uint chan;
8423 8423
8424 KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC); 8424 KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC);
8425 mac = (struct bwi_mac *)sc->sc_cur_regwin; 8425 mac = (struct bwi_mac *)sc->sc_cur_regwin;
8426 8426
8427 chan = ieee80211_chan2ieee(ic, c); 8427 chan = ieee80211_chan2ieee(ic, c);
8428 8428
8429 bwi_rf_set_chan(mac, chan, 0); 8429 bwi_rf_set_chan(mac, chan, 0);
8430 8430
8431 /* [TRC: XXX DragonFlyBSD sets up radio tap channel frequency 8431 /* [TRC: XXX DragonFlyBSD sets up radio tap channel frequency
8432 and flags here. OpenBSD does not, and appears to do so 8432 and flags here. OpenBSD does not, and appears to do so
8433 later (in bwi_rxeof and bwi_encap).] */ 8433 later (in bwi_rxeof and bwi_encap).] */
8434 8434
8435 return (0); 8435 return (0);
8436} 8436}
8437 8437
8438static void 8438static void
8439bwi_next_scan(void *xsc) 8439bwi_next_scan(void *xsc)
8440{ 8440{
8441 struct bwi_softc *sc = xsc; 8441 struct bwi_softc *sc = xsc;
8442 struct ieee80211com *ic = &sc->sc_ic; 8442 struct ieee80211com *ic = &sc->sc_ic;
8443 int s; 8443 int s;
8444 8444
8445 s = splnet(); 8445 s = splnet();
8446 8446
8447 if (ic->ic_state == IEEE80211_S_SCAN) 8447 if (ic->ic_state == IEEE80211_S_SCAN)
8448 ieee80211_next_scan(ic); 8448 ieee80211_next_scan(ic);
8449 8449
8450 splx(s); 8450 splx(s);
8451} 8451}
8452 8452
8453static int 8453static int
8454bwi_rxeof(struct bwi_softc *sc, int end_idx) 8454bwi_rxeof(struct bwi_softc *sc, int end_idx)
8455{ 8455{
8456 struct bwi_ring_data *rd = &sc->sc_rx_rdata; 8456 struct bwi_ring_data *rd = &sc->sc_rx_rdata;
8457 struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata; 8457 struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata;
8458 struct ieee80211com *ic = &sc->sc_ic; 8458 struct ieee80211com *ic = &sc->sc_ic;
8459 struct ifnet *ifp = &sc->sc_if; 8459 struct ifnet *ifp = &sc->sc_if;
8460 int s, idx, rx_data = 0; 8460 int s, idx, rx_data = 0;
8461 8461
8462 idx = rbd->rbd_idx; 8462 idx = rbd->rbd_idx;
8463 while (idx != end_idx) { 8463 while (idx != end_idx) {
8464 struct bwi_rxbuf *rb = &rbd->rbd_buf[idx]; 8464 struct bwi_rxbuf *rb = &rbd->rbd_buf[idx];
8465 struct bwi_rxbuf_hdr *hdr; 8465 struct bwi_rxbuf_hdr *hdr;
8466 struct ieee80211_frame_min *wh; 8466 struct ieee80211_frame_min *wh;
8467 struct ieee80211_node *ni; 8467 struct ieee80211_node *ni;
8468 struct mbuf *m; 8468 struct mbuf *m;
8469 const void *plcp; 8469 const void *plcp;
8470 uint16_t flags2; 8470 uint16_t flags2;
8471 int buflen, wh_ofs, hdr_extra, rssi, type, rate; 8471 int buflen, wh_ofs, hdr_extra, rssi, type, rate;
8472 8472
8473 m = rb->rb_mbuf; 8473 m = rb->rb_mbuf;
8474 bus_dmamap_sync(sc->sc_dmat, rb->rb_dmap, 0, 8474 bus_dmamap_sync(sc->sc_dmat, rb->rb_dmap, 0,
8475 rb->rb_dmap->dm_mapsize, BUS_DMASYNC_POSTREAD); 8475 rb->rb_dmap->dm_mapsize, BUS_DMASYNC_POSTREAD);
8476 8476
8477 if (bwi_newbuf(sc, idx, 0)) { 8477 if (bwi_newbuf(sc, idx, 0)) {
8478 ifp->if_ierrors++; 8478 if_statinc(ifp, if_ierrors);
8479 goto next; 8479 goto next;
8480 } 8480 }
8481 8481
8482 hdr = mtod(m, struct bwi_rxbuf_hdr *); 8482 hdr = mtod(m, struct bwi_rxbuf_hdr *);
8483 flags2 = le16toh(hdr->rxh_flags2); 8483 flags2 = le16toh(hdr->rxh_flags2);
8484 8484
8485 hdr_extra = 0; 8485 hdr_extra = 0;
8486 if (flags2 & BWI_RXH_F2_TYPE2FRAME) 8486 if (flags2 & BWI_RXH_F2_TYPE2FRAME)
8487 hdr_extra = 2; 8487 hdr_extra = 2;
8488 wh_ofs = hdr_extra + 6; /* XXX magic number */ 8488 wh_ofs = hdr_extra + 6; /* XXX magic number */
8489 8489
8490 buflen = le16toh(hdr->rxh_buflen); 8490 buflen = le16toh(hdr->rxh_buflen);
8491 if (buflen < BWI_FRAME_MIN_LEN(wh_ofs)) { 8491 if (buflen < BWI_FRAME_MIN_LEN(wh_ofs)) {
8492 aprint_error_dev(sc->sc_dev, "short frame %d," 8492 aprint_error_dev(sc->sc_dev, "short frame %d,"
8493 " hdr_extra %d\n", buflen, hdr_extra); 8493 " hdr_extra %d\n", buflen, hdr_extra);
8494 ifp->if_ierrors++; 8494 if_statinc(ifp, if_ierrors);
8495 m_freem(m); 8495 m_freem(m);
8496 goto next; 8496 goto next;
8497 } 8497 }
8498 8498
8499 plcp = ((const uint8_t *)(hdr + 1) + hdr_extra); 8499 plcp = ((const uint8_t *)(hdr + 1) + hdr_extra);
8500 rssi = bwi_calc_rssi(sc, hdr); 8500 rssi = bwi_calc_rssi(sc, hdr);
8501 8501
8502 m_set_rcvif(m, ifp); 8502 m_set_rcvif(m, ifp);
8503 m->m_len = m->m_pkthdr.len = buflen + sizeof(*hdr); 8503 m->m_len = m->m_pkthdr.len = buflen + sizeof(*hdr);
8504 m_adj(m, sizeof(*hdr) + wh_ofs); 8504 m_adj(m, sizeof(*hdr) + wh_ofs);
8505 8505
8506 if (htole16(hdr->rxh_flags1) & BWI_RXH_F1_OFDM) 8506 if (htole16(hdr->rxh_flags1) & BWI_RXH_F1_OFDM)
8507 rate = bwi_ofdm_plcp2rate(plcp); 8507 rate = bwi_ofdm_plcp2rate(plcp);
8508 else 8508 else
8509 rate = bwi_ds_plcp2rate(plcp); 8509 rate = bwi_ds_plcp2rate(plcp);
8510 8510
8511 s = splnet(); 8511 s = splnet();
8512 8512
8513 /* RX radio tap */ 8513 /* RX radio tap */
8514 if (sc->sc_drvbpf != NULL) { 8514 if (sc->sc_drvbpf != NULL) {
8515 struct mbuf mb; 8515 struct mbuf mb;
8516 struct bwi_rx_radiotap_hdr *tap = &sc->sc_rxtap; 8516 struct bwi_rx_radiotap_hdr *tap = &sc->sc_rxtap;
8517 8517
8518 tap->wr_tsf = hdr->rxh_tsf; 8518 tap->wr_tsf = hdr->rxh_tsf;
8519 tap->wr_flags = 0; 8519 tap->wr_flags = 0;
8520 tap->wr_rate = rate; 8520 tap->wr_rate = rate;
8521 tap->wr_chan_freq = 8521 tap->wr_chan_freq =
8522 htole16(ic->ic_bss->ni_chan->ic_freq); 8522 htole16(ic->ic_bss->ni_chan->ic_freq);
8523 tap->wr_chan_flags = 8523 tap->wr_chan_flags =
8524 htole16(ic->ic_bss->ni_chan->ic_flags); 8524 htole16(ic->ic_bss->ni_chan->ic_flags);
8525 tap->wr_antsignal = rssi; 8525 tap->wr_antsignal = rssi;
8526 tap->wr_antnoise = BWI_NOISE_FLOOR; 8526 tap->wr_antnoise = BWI_NOISE_FLOOR;
8527 8527
8528 mb.m_data = (void *)tap; 8528 mb.m_data = (void *)tap;
8529 mb.m_len = sc->sc_rxtap_len; 8529 mb.m_len = sc->sc_rxtap_len;
8530 mb.m_next = m; 8530 mb.m_next = m;
8531 mb.m_nextpkt = NULL; 8531 mb.m_nextpkt = NULL;
8532 mb.m_owner = NULL; 8532 mb.m_owner = NULL;
8533 mb.m_type = 0; 8533 mb.m_type = 0;
8534 mb.m_flags = 0; 8534 mb.m_flags = 0;
8535 bpf_mtap3(sc->sc_drvbpf, &mb, BPF_D_IN); 8535 bpf_mtap3(sc->sc_drvbpf, &mb, BPF_D_IN);
8536 } 8536 }
8537 8537
8538 m_adj(m, -IEEE80211_CRC_LEN); 8538 m_adj(m, -IEEE80211_CRC_LEN);
8539 8539
8540 wh = mtod(m, struct ieee80211_frame_min *); 8540 wh = mtod(m, struct ieee80211_frame_min *);
8541 ni = ieee80211_find_rxnode(ic, wh); 8541 ni = ieee80211_find_rxnode(ic, wh);
8542 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; 8542 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
8543 8543
8544 ieee80211_input(ic, m, ni, hdr->rxh_rssi, 8544 ieee80211_input(ic, m, ni, hdr->rxh_rssi,
8545 le16toh(hdr->rxh_tsf)); 8545 le16toh(hdr->rxh_tsf));
8546 8546
8547 ieee80211_free_node(ni); 8547 ieee80211_free_node(ni);
8548 8548
8549 if (type == IEEE80211_FC0_TYPE_DATA) { 8549 if (type == IEEE80211_FC0_TYPE_DATA) {
8550 rx_data = 1; 8550 rx_data = 1;
8551 sc->sc_rx_rate = rate; 8551 sc->sc_rx_rate = rate;
8552 } 8552 }
8553 8553
8554 splx(s); 8554 splx(s);
8555next: 8555next:
8556 idx = (idx + 1) % BWI_RX_NDESC; 8556 idx = (idx + 1) % BWI_RX_NDESC;
8557 } 8557 }
8558 8558
8559 rbd->rbd_idx = idx; 8559 rbd->rbd_idx = idx;
8560 bus_dmamap_sync(sc->sc_dmat, rd->rdata_dmap, 0, 8560 bus_dmamap_sync(sc->sc_dmat, rd->rdata_dmap, 0,
8561 rd->rdata_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE); 8561 rd->rdata_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE);
8562 8562
8563 return (rx_data); 8563 return (rx_data);
8564} 8564}
8565 8565
8566static int 8566static int
8567bwi_rxeof32(struct bwi_softc *sc) 8567bwi_rxeof32(struct bwi_softc *sc)
8568{ 8568{
8569 uint32_t val, rx_ctrl; 8569 uint32_t val, rx_ctrl;
8570 int end_idx, rx_data; 8570 int end_idx, rx_data;
8571 8571
8572 rx_ctrl = sc->sc_rx_rdata.rdata_txrx_ctrl; 8572 rx_ctrl = sc->sc_rx_rdata.rdata_txrx_ctrl;
8573 8573
8574 val = CSR_READ_4(sc, rx_ctrl + BWI_RX32_STATUS); 8574 val = CSR_READ_4(sc, rx_ctrl + BWI_RX32_STATUS);
8575 end_idx = __SHIFTOUT(val, BWI_RX32_STATUS_INDEX_MASK) / 8575 end_idx = __SHIFTOUT(val, BWI_RX32_STATUS_INDEX_MASK) /
8576 sizeof(struct bwi_desc32); 8576 sizeof(struct bwi_desc32);
8577 8577
8578 rx_data = bwi_rxeof(sc, end_idx); 8578 rx_data = bwi_rxeof(sc, end_idx);
8579 8579
8580 CSR_WRITE_4(sc, rx_ctrl + BWI_RX32_INDEX, 8580 CSR_WRITE_4(sc, rx_ctrl + BWI_RX32_INDEX,
8581 end_idx * sizeof(struct bwi_desc32)); 8581 end_idx * sizeof(struct bwi_desc32));
8582 8582
8583 return (rx_data); 8583 return (rx_data);
8584} 8584}
8585 8585
8586static int 8586static int
8587bwi_rxeof64(struct bwi_softc *sc) 8587bwi_rxeof64(struct bwi_softc *sc)
8588{ 8588{
8589 /* TODO: 64 */ 8589 /* TODO: 64 */
8590 return (0); 8590 return (0);
8591} 8591}
8592 8592
8593static void 8593static void
8594bwi_reset_rx_ring32(struct bwi_softc *sc, uint32_t rx_ctrl) 8594bwi_reset_rx_ring32(struct bwi_softc *sc, uint32_t rx_ctrl)
8595{ 8595{
8596 int i; 8596 int i;
8597 8597
8598 CSR_WRITE_4(sc, rx_ctrl + BWI_RX32_CTRL, 0); 8598 CSR_WRITE_4(sc, rx_ctrl + BWI_RX32_CTRL, 0);
8599 8599
8600#define NRETRY 10 8600#define NRETRY 10
8601 for (i = 0; i < NRETRY; ++i) { 8601 for (i = 0; i < NRETRY; ++i) {
8602 uint32_t status; 8602 uint32_t status;
8603 8603
8604 status = CSR_READ_4(sc, rx_ctrl + BWI_RX32_STATUS); 8604 status = CSR_READ_4(sc, rx_ctrl + BWI_RX32_STATUS);
8605 if (__SHIFTOUT(status, BWI_RX32_STATUS_STATE_MASK) == 8605 if (__SHIFTOUT(status, BWI_RX32_STATUS_STATE_MASK) ==
8606 BWI_RX32_STATUS_STATE_DISABLED) 8606 BWI_RX32_STATUS_STATE_DISABLED)
8607 break; 8607 break;
8608 8608
8609 DELAY(1000); 8609 DELAY(1000);
8610 } 8610 }
8611 if (i == NRETRY) 8611 if (i == NRETRY)
8612 aprint_error_dev(sc->sc_dev, "reset rx ring timedout\n"); 8612 aprint_error_dev(sc->sc_dev, "reset rx ring timedout\n");
8613#undef NRETRY 8613#undef NRETRY
8614 8614
8615 CSR_WRITE_4(sc, rx_ctrl + BWI_RX32_RINGINFO, 0); 8615 CSR_WRITE_4(sc, rx_ctrl + BWI_RX32_RINGINFO, 0);
8616} 8616}
8617 8617
8618static void 8618static void
8619bwi_free_txstats32(struct bwi_softc *sc) 8619bwi_free_txstats32(struct bwi_softc *sc)
8620{ 8620{
8621 bwi_reset_rx_ring32(sc, sc->sc_txstats->stats_ctrl_base); 8621 bwi_reset_rx_ring32(sc, sc->sc_txstats->stats_ctrl_base);
8622} 8622}
8623 8623
8624static void 8624static void
8625bwi_free_rx_ring32(struct bwi_softc *sc) 8625bwi_free_rx_ring32(struct bwi_softc *sc)
8626{ 8626{
8627 struct bwi_ring_data *rd = &sc->sc_rx_rdata; 8627 struct bwi_ring_data *rd = &sc->sc_rx_rdata;
8628 struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata; 8628 struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata;
8629 int i; 8629 int i;
8630 8630
8631 bwi_reset_rx_ring32(sc, rd->rdata_txrx_ctrl); 8631 bwi_reset_rx_ring32(sc, rd->rdata_txrx_ctrl);
8632 8632
8633 for (i = 0; i < BWI_RX_NDESC; ++i) { 8633 for (i = 0; i < BWI_RX_NDESC; ++i) {
8634 struct bwi_rxbuf *rb = &rbd->rbd_buf[i]; 8634 struct bwi_rxbuf *rb = &rbd->rbd_buf[i];
8635 8635
8636 if (rb->rb_mbuf != NULL) { 8636 if (rb->rb_mbuf != NULL) {
8637 bus_dmamap_unload(sc->sc_dmat, rb->rb_dmap); 8637 bus_dmamap_unload(sc->sc_dmat, rb->rb_dmap);
8638 m_freem(rb->rb_mbuf); 8638 m_freem(rb->rb_mbuf);
8639 rb->rb_mbuf = NULL; 8639 rb->rb_mbuf = NULL;
8640 } 8640 }
8641 } 8641 }
8642} 8642}
8643 8643
8644static void 8644static void
8645bwi_free_tx_ring32(struct bwi_softc *sc, int ring_idx) 8645bwi_free_tx_ring32(struct bwi_softc *sc, int ring_idx)
8646{ 8646{
8647 struct bwi_ring_data *rd; 8647 struct bwi_ring_data *rd;
8648 struct bwi_txbuf_data *tbd; 8648 struct bwi_txbuf_data *tbd;
8649 uint32_t state, val; 8649 uint32_t state, val;
8650 int i; 8650 int i;
8651 8651
8652 KASSERT(ring_idx < BWI_TX_NRING); 8652 KASSERT(ring_idx < BWI_TX_NRING);
8653 rd = &sc->sc_tx_rdata[ring_idx]; 8653 rd = &sc->sc_tx_rdata[ring_idx];
8654 tbd = &sc->sc_tx_bdata[ring_idx]; 8654 tbd = &sc->sc_tx_bdata[ring_idx];
8655 8655
8656#define NRETRY 10 8656#define NRETRY 10
8657 for (i = 0; i < NRETRY; ++i) { 8657 for (i = 0; i < NRETRY; ++i) {
8658 val = CSR_READ_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_STATUS); 8658 val = CSR_READ_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_STATUS);
8659 state = __SHIFTOUT(val, BWI_TX32_STATUS_STATE_MASK); 8659 state = __SHIFTOUT(val, BWI_TX32_STATUS_STATE_MASK);
8660 if (state == BWI_TX32_STATUS_STATE_DISABLED || 8660 if (state == BWI_TX32_STATUS_STATE_DISABLED ||
8661 state == BWI_TX32_STATUS_STATE_IDLE || 8661 state == BWI_TX32_STATUS_STATE_IDLE ||
8662 state == BWI_TX32_STATUS_STATE_STOPPED) 8662 state == BWI_TX32_STATUS_STATE_STOPPED)
8663 break; 8663 break;
8664 8664
8665 DELAY(1000); 8665 DELAY(1000);
8666 } 8666 }
8667 if (i == NRETRY) 8667 if (i == NRETRY)
8668 aprint_error_dev(sc->sc_dev, 8668 aprint_error_dev(sc->sc_dev,
8669 "wait for TX ring(%d) stable timed out\n", ring_idx); 8669 "wait for TX ring(%d) stable timed out\n", ring_idx);
8670 8670
8671 CSR_WRITE_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_CTRL, 0); 8671 CSR_WRITE_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_CTRL, 0);
8672 for (i = 0; i < NRETRY; ++i) { 8672 for (i = 0; i < NRETRY; ++i) {
8673 val = CSR_READ_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_STATUS); 8673 val = CSR_READ_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_STATUS);
8674 state = __SHIFTOUT(val, BWI_TX32_STATUS_STATE_MASK); 8674 state = __SHIFTOUT(val, BWI_TX32_STATUS_STATE_MASK);
8675 if (state == BWI_TX32_STATUS_STATE_DISABLED) 8675 if (state == BWI_TX32_STATUS_STATE_DISABLED)
8676 break; 8676 break;
8677 8677
8678 DELAY(1000); 8678 DELAY(1000);
8679 } 8679 }
8680 if (i == NRETRY) 8680 if (i == NRETRY)
8681 aprint_error_dev(sc->sc_dev, "reset TX ring (%d) timed out\n", 8681 aprint_error_dev(sc->sc_dev, "reset TX ring (%d) timed out\n",
8682 ring_idx); 8682 ring_idx);
8683#undef NRETRY 8683#undef NRETRY
8684 8684
8685 DELAY(1000); 8685 DELAY(1000);
8686 8686
8687 CSR_WRITE_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_RINGINFO, 0); 8687 CSR_WRITE_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_RINGINFO, 0);
8688 8688
8689 for (i = 0; i < BWI_TX_NDESC; ++i) { 8689 for (i = 0; i < BWI_TX_NDESC; ++i) {
8690 struct bwi_txbuf *tb = &tbd->tbd_buf[i]; 8690 struct bwi_txbuf *tb = &tbd->tbd_buf[i];
8691 8691
8692 if (tb->tb_mbuf != NULL) { 8692 if (tb->tb_mbuf != NULL) {
8693 bus_dmamap_unload(sc->sc_dmat, tb->tb_dmap); 8693 bus_dmamap_unload(sc->sc_dmat, tb->tb_dmap);
8694 m_freem(tb->tb_mbuf); 8694 m_freem(tb->tb_mbuf);
8695 tb->tb_mbuf = NULL; 8695 tb->tb_mbuf = NULL;
8696 } 8696 }
8697 if (tb->tb_ni != NULL) { 8697 if (tb->tb_ni != NULL) {
8698 ieee80211_free_node(tb->tb_ni); 8698 ieee80211_free_node(tb->tb_ni);
8699 tb->tb_ni = NULL; 8699 tb->tb_ni = NULL;
8700 } 8700 }
8701 } 8701 }
8702} 8702}
8703 8703
8704static void 8704static void
8705bwi_free_txstats64(struct bwi_softc *sc) 8705bwi_free_txstats64(struct bwi_softc *sc)
8706{ 8706{
8707 /* TODO: 64 */ 8707 /* TODO: 64 */
8708} 8708}
8709 8709
8710static void 8710static void
8711bwi_free_rx_ring64(struct bwi_softc *sc) 8711bwi_free_rx_ring64(struct bwi_softc *sc)
8712{ 8712{
8713 /* TODO: 64 */ 8713 /* TODO: 64 */
8714} 8714}
8715 8715
8716static void 8716static void
8717bwi_free_tx_ring64(struct bwi_softc *sc, int ring_idx) 8717bwi_free_tx_ring64(struct bwi_softc *sc, int ring_idx)
8718{ 8718{
8719 /* TODO: 64 */ 8719 /* TODO: 64 */
8720} 8720}
8721 8721
8722/* XXX does not belong here */ 8722/* XXX does not belong here */
8723/* [TRC: Begin pilferage from OpenBSD.] */ 8723/* [TRC: Begin pilferage from OpenBSD.] */
8724 8724
8725/* 8725/*
8726 * Convert bit rate (in 0.5Mbps units) to PLCP signal (R4-R1) and vice versa. 8726 * Convert bit rate (in 0.5Mbps units) to PLCP signal (R4-R1) and vice versa.
8727 */ 8727 */
8728uint8_t 8728uint8_t
8729bwi_ieee80211_rate2plcp(u_int8_t rate, enum ieee80211_phymode mode) 8729bwi_ieee80211_rate2plcp(u_int8_t rate, enum ieee80211_phymode mode)
8730{ 8730{
8731 rate &= IEEE80211_RATE_VAL; 8731 rate &= IEEE80211_RATE_VAL;
8732 8732
8733 if (mode == IEEE80211_MODE_11B) { 8733 if (mode == IEEE80211_MODE_11B) {
8734 /* IEEE Std 802.11b-1999 page 15, subclause 18.2.3.3 */ 8734 /* IEEE Std 802.11b-1999 page 15, subclause 18.2.3.3 */
8735 switch (rate) { 8735 switch (rate) {
8736 case 2: return 10; 8736 case 2: return 10;
8737 case 4: return 20; 8737 case 4: return 20;
8738 case 11: return 55; 8738 case 11: return 55;
8739 case 22: return 110; 8739 case 22: return 110;
8740 /* IEEE Std 802.11g-2003 page 19, subclause 19.3.2.1 */ 8740 /* IEEE Std 802.11g-2003 page 19, subclause 19.3.2.1 */
8741 case 44: return 220; 8741 case 44: return 220;
8742 } 8742 }
8743 } else if (mode == IEEE80211_MODE_11G || mode == IEEE80211_MODE_11A) { 8743 } else if (mode == IEEE80211_MODE_11G || mode == IEEE80211_MODE_11A) {
8744 /* IEEE Std 802.11a-1999 page 14, subclause 17.3.4.1 */ 8744 /* IEEE Std 802.11a-1999 page 14, subclause 17.3.4.1 */
8745 switch (rate) { 8745 switch (rate) {
8746 case 12: return 0x0b; 8746 case 12: return 0x0b;
8747 case 18: return 0x0f; 8747 case 18: return 0x0f;
8748 case 24: return 0x0a; 8748 case 24: return 0x0a;
8749 case 36: return 0x0e; 8749 case 36: return 0x0e;
8750 case 48: return 0x09; 8750 case 48: return 0x09;
8751 case 72: return 0x0d; 8751 case 72: return 0x0d;
8752 case 96: return 0x08; 8752 case 96: return 0x08;
8753 case 108: return 0x0c; 8753 case 108: return 0x0c;
8754 } 8754 }
8755 } else 8755 } else
8756 panic("Unexpected mode %u", mode); 8756 panic("Unexpected mode %u", mode);
8757 8757
8758 return 0; 8758 return 0;
8759} 8759}
8760 8760
8761static uint8_t 8761static uint8_t
8762bwi_ieee80211_plcp2rate(uint8_t plcp, enum ieee80211_phymode mode) 8762bwi_ieee80211_plcp2rate(uint8_t plcp, enum ieee80211_phymode mode)
8763{ 8763{
8764 if (mode == IEEE80211_MODE_11B) { 8764 if (mode == IEEE80211_MODE_11B) {
8765 /* IEEE Std 802.11g-2003 page 19, subclause 19.3.2.1 */ 8765 /* IEEE Std 802.11g-2003 page 19, subclause 19.3.2.1 */
8766 switch (plcp) { 8766 switch (plcp) {
8767 case 10: return 2; 8767 case 10: return 2;
8768 case 20: return 4; 8768 case 20: return 4;
8769 case 55: return 11; 8769 case 55: return 11;
8770 case 110: return 22; 8770 case 110: return 22;
8771 /* IEEE Std 802.11g-2003 page 19, subclause 19.3.2.1 */ 8771 /* IEEE Std 802.11g-2003 page 19, subclause 19.3.2.1 */
8772 case 220: return 44; 8772 case 220: return 44;
8773 } 8773 }
8774 } else if (mode == IEEE80211_MODE_11G || mode == IEEE80211_MODE_11A) { 8774 } else if (mode == IEEE80211_MODE_11G || mode == IEEE80211_MODE_11A) {
8775 /* IEEE Std 802.11a-1999 page 14, subclause 17.3.4.1 */ 8775 /* IEEE Std 802.11a-1999 page 14, subclause 17.3.4.1 */
8776 switch (plcp) { 8776 switch (plcp) {
8777 case 0x0b: return 12; 8777 case 0x0b: return 12;
8778 case 0x0f: return 18; 8778 case 0x0f: return 18;
8779 case 0x0a: return 24; 8779 case 0x0a: return 24;
8780 case 0x0e: return 36; 8780 case 0x0e: return 36;
8781 case 0x09: return 48; 8781 case 0x09: return 48;
8782 case 0x0d: return 72; 8782 case 0x0d: return 72;
8783 case 0x08: return 96; 8783 case 0x08: return 96;
8784 case 0x0c: return 108; 8784 case 0x0c: return 108;
8785 } 8785 }
8786 } else 8786 } else
8787 panic("Unexpected mode %u", mode); 8787 panic("Unexpected mode %u", mode);
8788 8788
8789 return 0; 8789 return 0;
8790} 8790}
8791/* [TRC: End pilferage from OpenBSD.] */ 8791/* [TRC: End pilferage from OpenBSD.] */
8792 8792
8793static enum bwi_ieee80211_modtype 8793static enum bwi_ieee80211_modtype
8794bwi_ieee80211_rate2modtype(uint8_t rate) 8794bwi_ieee80211_rate2modtype(uint8_t rate)
8795{ 8795{
8796 rate &= IEEE80211_RATE_VAL; 8796 rate &= IEEE80211_RATE_VAL;
8797 8797
8798 if (rate == 44) 8798 if (rate == 44)
8799 return (IEEE80211_MODTYPE_PBCC); 8799 return (IEEE80211_MODTYPE_PBCC);
8800 else if (rate == 22 || rate < 12) 8800 else if (rate == 22 || rate < 12)
8801 return (IEEE80211_MODTYPE_DS); 8801 return (IEEE80211_MODTYPE_DS);
8802 else 8802 else
8803 return (IEEE80211_MODTYPE_OFDM); 8803 return (IEEE80211_MODTYPE_OFDM);
8804} 8804}
8805 8805
8806static uint8_t 8806static uint8_t
8807bwi_ofdm_plcp2rate(const void *plcp0) 8807bwi_ofdm_plcp2rate(const void *plcp0)
8808{ 8808{
8809 uint32_t plcp; 8809 uint32_t plcp;
8810 uint8_t plcp_rate; 8810 uint8_t plcp_rate;
8811 8811
8812 /* plcp0 may not be 32-bit aligned. */ 8812 /* plcp0 may not be 32-bit aligned. */
8813 plcp = le32dec(plcp0); 8813 plcp = le32dec(plcp0);
8814 plcp_rate = __SHIFTOUT(plcp, IEEE80211_OFDM_PLCP_RATE_MASK); 8814 plcp_rate = __SHIFTOUT(plcp, IEEE80211_OFDM_PLCP_RATE_MASK);
8815 8815
8816 return (bwi_ieee80211_plcp2rate(plcp_rate, IEEE80211_MODE_11G)); 8816 return (bwi_ieee80211_plcp2rate(plcp_rate, IEEE80211_MODE_11G));
8817} 8817}
8818 8818
8819static uint8_t 8819static uint8_t
8820bwi_ds_plcp2rate(const struct ieee80211_ds_plcp_hdr *hdr) 8820bwi_ds_plcp2rate(const struct ieee80211_ds_plcp_hdr *hdr)
8821{ 8821{
8822 return (bwi_ieee80211_plcp2rate(hdr->i_signal, IEEE80211_MODE_11B)); 8822 return (bwi_ieee80211_plcp2rate(hdr->i_signal, IEEE80211_MODE_11B));
8823} 8823}
8824 8824
8825static void 8825static void
8826bwi_ofdm_plcp_header(uint32_t *plcp0, int pkt_len, uint8_t rate) 8826bwi_ofdm_plcp_header(uint32_t *plcp0, int pkt_len, uint8_t rate)
8827{ 8827{
8828 uint32_t plcp; 8828 uint32_t plcp;
8829 8829
8830 plcp = __SHIFTIN(bwi_ieee80211_rate2plcp(rate, IEEE80211_MODE_11G), 8830 plcp = __SHIFTIN(bwi_ieee80211_rate2plcp(rate, IEEE80211_MODE_11G),
8831 IEEE80211_OFDM_PLCP_RATE_MASK) | 8831 IEEE80211_OFDM_PLCP_RATE_MASK) |
8832 __SHIFTIN(pkt_len, IEEE80211_OFDM_PLCP_LEN_MASK); 8832 __SHIFTIN(pkt_len, IEEE80211_OFDM_PLCP_LEN_MASK);
8833 *plcp0 = htole32(plcp); 8833 *plcp0 = htole32(plcp);
8834} 8834}
8835 8835
8836static void 8836static void
8837bwi_ds_plcp_header(struct ieee80211_ds_plcp_hdr *plcp, int pkt_len, 8837bwi_ds_plcp_header(struct ieee80211_ds_plcp_hdr *plcp, int pkt_len,
8838 uint8_t rate) 8838 uint8_t rate)
8839{ 8839{
8840 int len, service, pkt_bitlen; 8840 int len, service, pkt_bitlen;
8841 8841
8842 pkt_bitlen = pkt_len * NBBY; 8842 pkt_bitlen = pkt_len * NBBY;
8843 len = howmany(pkt_bitlen * 2, rate); 8843 len = howmany(pkt_bitlen * 2, rate);
8844 8844
8845 service = IEEE80211_DS_PLCP_SERVICE_LOCKED; 8845 service = IEEE80211_DS_PLCP_SERVICE_LOCKED;
8846 if (rate == (11 * 2)) { 8846 if (rate == (11 * 2)) {
8847 int pkt_bitlen1; 8847 int pkt_bitlen1;
8848 8848
8849 /* 8849 /*
8850 * PLCP service field needs to be adjusted, 8850 * PLCP service field needs to be adjusted,
8851 * if TX rate is 11Mbytes/s 8851 * if TX rate is 11Mbytes/s
8852 */ 8852 */
8853 pkt_bitlen1 = len * 11; 8853 pkt_bitlen1 = len * 11;
8854 if (pkt_bitlen1 - pkt_bitlen >= NBBY) 8854 if (pkt_bitlen1 - pkt_bitlen >= NBBY)
8855 service |= IEEE80211_DS_PLCP_SERVICE_LENEXT7; 8855 service |= IEEE80211_DS_PLCP_SERVICE_LENEXT7;
8856 } 8856 }
8857 8857
8858 plcp->i_signal = bwi_ieee80211_rate2plcp(rate, IEEE80211_MODE_11B); 8858 plcp->i_signal = bwi_ieee80211_rate2plcp(rate, IEEE80211_MODE_11B);
8859 plcp->i_service = service; 8859 plcp->i_service = service;
8860 plcp->i_length = htole16(len); 8860 plcp->i_length = htole16(len);
8861 /* NOTE: do NOT touch i_crc */ 8861 /* NOTE: do NOT touch i_crc */
8862} 8862}
8863 8863
8864static void 8864static void
8865bwi_plcp_header(void *plcp, int pkt_len, uint8_t rate) 8865bwi_plcp_header(void *plcp, int pkt_len, uint8_t rate)
8866{ 8866{
8867 enum bwi_ieee80211_modtype modtype; 8867 enum bwi_ieee80211_modtype modtype;
8868 8868
8869 /* 8869 /*
8870 * Assume caller has zeroed 'plcp' 8870 * Assume caller has zeroed 'plcp'
8871 */ 8871 */
8872 8872
8873 modtype = bwi_ieee80211_rate2modtype(rate); 8873 modtype = bwi_ieee80211_rate2modtype(rate);
8874 if (modtype == IEEE80211_MODTYPE_OFDM) 8874 if (modtype == IEEE80211_MODTYPE_OFDM)
8875 bwi_ofdm_plcp_header(plcp, pkt_len, rate); 8875 bwi_ofdm_plcp_header(plcp, pkt_len, rate);
8876 else if (modtype == IEEE80211_MODTYPE_DS) 8876 else if (modtype == IEEE80211_MODTYPE_DS)
8877 bwi_ds_plcp_header(plcp, pkt_len, rate); 8877 bwi_ds_plcp_header(plcp, pkt_len, rate);
8878 else 8878 else
8879 panic("unsupport modulation type %u\n", modtype); 8879 panic("unsupport modulation type %u\n", modtype);
8880} 8880}
8881 8881
8882static uint8_t 8882static uint8_t
8883bwi_ieee80211_ack_rate(struct ieee80211_node *ni, uint8_t rate) 8883bwi_ieee80211_ack_rate(struct ieee80211_node *ni, uint8_t rate)
8884{ 8884{
8885 const struct ieee80211_rateset *rs = &ni->ni_rates; 8885 const struct ieee80211_rateset *rs = &ni->ni_rates;
8886 uint8_t ack_rate = 0; 8886 uint8_t ack_rate = 0;
8887 enum bwi_ieee80211_modtype modtype; 8887 enum bwi_ieee80211_modtype modtype;
8888 int i; 8888 int i;
8889 8889
8890 rate &= IEEE80211_RATE_VAL; 8890 rate &= IEEE80211_RATE_VAL;
8891 8891
8892 modtype = bwi_ieee80211_rate2modtype(rate); 8892 modtype = bwi_ieee80211_rate2modtype(rate);
8893 8893
8894 for (i = 0; i < rs->rs_nrates; ++i) { 8894 for (i = 0; i < rs->rs_nrates; ++i) {
8895 uint8_t rate1 = rs->rs_rates[i] & IEEE80211_RATE_VAL; 8895 uint8_t rate1 = rs->rs_rates[i] & IEEE80211_RATE_VAL;
8896  8896
8897 if (rate1 > rate) { 8897 if (rate1 > rate) {
8898 if (ack_rate != 0) 8898 if (ack_rate != 0)
8899 return (ack_rate); 8899 return (ack_rate);
8900 else 8900 else
8901 break; 8901 break;
8902 } 8902 }
8903 8903
8904 if ((rs->rs_rates[i] & IEEE80211_RATE_BASIC) && 8904 if ((rs->rs_rates[i] & IEEE80211_RATE_BASIC) &&
8905 bwi_ieee80211_rate2modtype(rate1) == modtype) 8905 bwi_ieee80211_rate2modtype(rate1) == modtype)
8906 ack_rate = rate1; 8906 ack_rate = rate1;
8907 } 8907 }
8908 8908
8909 switch (rate) { 8909 switch (rate) {
8910 /* CCK */ 8910 /* CCK */
8911 case 2: 8911 case 2:
8912 case 4: 8912 case 4:
8913 case 11: 8913 case 11:
8914 case 22: 8914 case 22:
8915 ack_rate = rate; 8915 ack_rate = rate;
8916 break; 8916 break;
8917 /* PBCC */ 8917 /* PBCC */
8918 case 44: 8918 case 44:
8919 ack_rate = 22; 8919 ack_rate = 22;
8920 break; 8920 break;
8921 8921
8922 /* OFDM */ 8922 /* OFDM */
8923 case 12: 8923 case 12:
8924 case 18: 8924 case 18:
8925 ack_rate = 12; 8925 ack_rate = 12;
8926 break; 8926 break;
8927 case 24: 8927 case 24:
8928 case 36: 8928 case 36:
8929 ack_rate = 24; 8929 ack_rate = 24;
8930 break; 8930 break;
8931 case 48: 8931 case 48:
8932 case 72: 8932 case 72:
8933 case 96: 8933 case 96:
8934 case 108: 8934 case 108:
8935 ack_rate = 48; 8935 ack_rate = 48;
8936 break; 8936 break;
8937 default: 8937 default:
8938 panic("unsupported rate %d\n", rate); 8938 panic("unsupported rate %d\n", rate);
8939 } 8939 }
8940 return (ack_rate); 8940 return (ack_rate);
8941} 8941}
8942 8942
8943/* [TRC: XXX does not belong here] */ 8943/* [TRC: XXX does not belong here] */
8944 8944
8945#define IEEE80211_OFDM_TXTIME(kbps, frmlen) \ 8945#define IEEE80211_OFDM_TXTIME(kbps, frmlen) \
8946 (IEEE80211_OFDM_PREAMBLE_TIME + \ 8946 (IEEE80211_OFDM_PREAMBLE_TIME + \
8947 IEEE80211_OFDM_SIGNAL_TIME + \ 8947 IEEE80211_OFDM_SIGNAL_TIME + \
8948 (IEEE80211_OFDM_NSYMS((kbps), (frmlen)) * IEEE80211_OFDM_SYM_TIME)) 8948 (IEEE80211_OFDM_NSYMS((kbps), (frmlen)) * IEEE80211_OFDM_SYM_TIME))
8949 8949
8950#define IEEE80211_OFDM_SYM_TIME 4 8950#define IEEE80211_OFDM_SYM_TIME 4
8951#define IEEE80211_OFDM_PREAMBLE_TIME 16 8951#define IEEE80211_OFDM_PREAMBLE_TIME 16
8952#define IEEE80211_OFDM_SIGNAL_EXT_TIME 6 8952#define IEEE80211_OFDM_SIGNAL_EXT_TIME 6
8953#define IEEE80211_OFDM_SIGNAL_TIME 4 8953#define IEEE80211_OFDM_SIGNAL_TIME 4
8954 8954
8955#define IEEE80211_OFDM_PLCP_SERVICE_NBITS 16 8955#define IEEE80211_OFDM_PLCP_SERVICE_NBITS 16
8956#define IEEE80211_OFDM_TAIL_NBITS 6  8956#define IEEE80211_OFDM_TAIL_NBITS 6
8957 8957
8958#define IEEE80211_OFDM_NBITS(frmlen) \ 8958#define IEEE80211_OFDM_NBITS(frmlen) \
8959 (IEEE80211_OFDM_PLCP_SERVICE_NBITS + \ 8959 (IEEE80211_OFDM_PLCP_SERVICE_NBITS + \
8960 ((frmlen) * NBBY) + \ 8960 ((frmlen) * NBBY) + \
8961 IEEE80211_OFDM_TAIL_NBITS) 8961 IEEE80211_OFDM_TAIL_NBITS)
8962 8962
8963#define IEEE80211_OFDM_NBITS_PER_SYM(kbps) \ 8963#define IEEE80211_OFDM_NBITS_PER_SYM(kbps) \
8964 (((kbps) * IEEE80211_OFDM_SYM_TIME) / 1000) 8964 (((kbps) * IEEE80211_OFDM_SYM_TIME) / 1000)
8965 8965
8966#define IEEE80211_OFDM_NSYMS(kbps, frmlen) \ 8966#define IEEE80211_OFDM_NSYMS(kbps, frmlen) \
8967 howmany(IEEE80211_OFDM_NBITS((frmlen)), \ 8967 howmany(IEEE80211_OFDM_NBITS((frmlen)), \
8968 IEEE80211_OFDM_NBITS_PER_SYM((kbps))) 8968 IEEE80211_OFDM_NBITS_PER_SYM((kbps)))
8969 8969
8970#define IEEE80211_CCK_TXTIME(kbps, frmlen) \ 8970#define IEEE80211_CCK_TXTIME(kbps, frmlen) \
8971 (((IEEE80211_CCK_NBITS((frmlen)) * 1000) + (kbps) - 1) / (kbps)) 8971 (((IEEE80211_CCK_NBITS((frmlen)) * 1000) + (kbps) - 1) / (kbps))
8972 8972
8973#define IEEE80211_CCK_PREAMBLE_LEN 144 8973#define IEEE80211_CCK_PREAMBLE_LEN 144
8974#define IEEE80211_CCK_PLCP_HDR_TIME 48 8974#define IEEE80211_CCK_PLCP_HDR_TIME 48
8975#define IEEE80211_CCK_SHPREAMBLE_LEN 72 8975#define IEEE80211_CCK_SHPREAMBLE_LEN 72
8976#define IEEE80211_CCK_SHPLCP_HDR_TIME 24 8976#define IEEE80211_CCK_SHPLCP_HDR_TIME 24
8977 8977
8978#define IEEE80211_CCK_NBITS(frmlen) ((frmlen) * NBBY) 8978#define IEEE80211_CCK_NBITS(frmlen) ((frmlen) * NBBY)
8979 8979
8980static uint16_t 8980static uint16_t
8981bwi_ieee80211_txtime(struct ieee80211com *ic, struct ieee80211_node *ni, 8981bwi_ieee80211_txtime(struct ieee80211com *ic, struct ieee80211_node *ni,
8982 uint len, uint8_t rs_rate, uint32_t flags) 8982 uint len, uint8_t rs_rate, uint32_t flags)
8983{ 8983{
8984 enum bwi_ieee80211_modtype modtype; 8984 enum bwi_ieee80211_modtype modtype;
8985 uint16_t txtime; 8985 uint16_t txtime;
8986 int rate; 8986 int rate;
8987 8987
8988 rs_rate &= IEEE80211_RATE_VAL; 8988 rs_rate &= IEEE80211_RATE_VAL;
8989 8989
8990 rate = rs_rate * 500; /* ieee80211 rate -> kbps */ 8990 rate = rs_rate * 500; /* ieee80211 rate -> kbps */
8991 8991
8992 modtype = bwi_ieee80211_rate2modtype(rs_rate); 8992 modtype = bwi_ieee80211_rate2modtype(rs_rate);
8993 if (modtype == IEEE80211_MODTYPE_OFDM) { 8993 if (modtype == IEEE80211_MODTYPE_OFDM) {
8994 /* 8994 /*
8995 * IEEE Std 802.11a-1999, page 37, equation (29) 8995 * IEEE Std 802.11a-1999, page 37, equation (29)
8996 * IEEE Std 802.11g-2003, page 44, equation (42) 8996 * IEEE Std 802.11g-2003, page 44, equation (42)
8997 */ 8997 */
8998 txtime = IEEE80211_OFDM_TXTIME(rate, len); 8998 txtime = IEEE80211_OFDM_TXTIME(rate, len);
8999 if (ic->ic_curmode == IEEE80211_MODE_11G) 8999 if (ic->ic_curmode == IEEE80211_MODE_11G)
9000 txtime += IEEE80211_OFDM_SIGNAL_EXT_TIME; 9000 txtime += IEEE80211_OFDM_SIGNAL_EXT_TIME;
9001 } else { 9001 } else {
9002 /* 9002 /*
9003 * IEEE Std 802.11b-1999, page 28, subclause 18.3.4 9003 * IEEE Std 802.11b-1999, page 28, subclause 18.3.4
9004 * IEEE Std 802.11g-2003, page 45, equation (43) 9004 * IEEE Std 802.11g-2003, page 45, equation (43)
9005 */ 9005 */
9006 if (modtype == IEEE80211_MODTYPE_PBCC) 9006 if (modtype == IEEE80211_MODTYPE_PBCC)
9007 ++len; 9007 ++len;
9008 txtime = IEEE80211_CCK_TXTIME(rate, len); 9008 txtime = IEEE80211_CCK_TXTIME(rate, len);
9009 9009
9010 /* 9010 /*
9011 * Short preamble is not applicable for DS 1Mbits/s 9011 * Short preamble is not applicable for DS 1Mbits/s
9012 */ 9012 */
9013 if (rs_rate != 2 && (flags & IEEE80211_F_SHPREAMBLE)) { 9013 if (rs_rate != 2 && (flags & IEEE80211_F_SHPREAMBLE)) {
9014 txtime += IEEE80211_CCK_SHPREAMBLE_LEN + 9014 txtime += IEEE80211_CCK_SHPREAMBLE_LEN +
9015 IEEE80211_CCK_SHPLCP_HDR_TIME; 9015 IEEE80211_CCK_SHPLCP_HDR_TIME;
9016 } else { 9016 } else {
9017 txtime += IEEE80211_CCK_PREAMBLE_LEN + 9017 txtime += IEEE80211_CCK_PREAMBLE_LEN +
9018 IEEE80211_CCK_PLCP_HDR_TIME; 9018 IEEE80211_CCK_PLCP_HDR_TIME;
9019 } 9019 }
9020 } 9020 }
9021 return (txtime); 9021 return (txtime);
9022} 9022}
9023 9023
9024static int 9024static int
9025bwi_encap(struct bwi_softc *sc, int idx, struct mbuf *m, 9025bwi_encap(struct bwi_softc *sc, int idx, struct mbuf *m,
9026 struct ieee80211_node **nip, int mgt_pkt) 9026 struct ieee80211_node **nip, int mgt_pkt)
9027{ 9027{
9028 struct ieee80211com *ic = &sc->sc_ic; 9028 struct ieee80211com *ic = &sc->sc_ic;
9029 struct ieee80211_node *ni = *nip; 9029 struct ieee80211_node *ni = *nip;
9030 struct bwi_ring_data *rd = &sc->sc_tx_rdata[BWI_TX_DATA_RING]; 9030 struct bwi_ring_data *rd = &sc->sc_tx_rdata[BWI_TX_DATA_RING];
9031 struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[BWI_TX_DATA_RING]; 9031 struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[BWI_TX_DATA_RING];
9032 struct bwi_txbuf *tb = &tbd->tbd_buf[idx]; 9032 struct bwi_txbuf *tb = &tbd->tbd_buf[idx];
9033 struct bwi_mac *mac; 9033 struct bwi_mac *mac;
9034 struct bwi_txbuf_hdr *hdr; 9034 struct bwi_txbuf_hdr *hdr;
9035 struct ieee80211_frame *wh; 9035 struct ieee80211_frame *wh;
9036 uint8_t rate; /* [TRC: XXX Use a fallback rate?] */ 9036 uint8_t rate; /* [TRC: XXX Use a fallback rate?] */
9037 uint32_t mac_ctrl; 9037 uint32_t mac_ctrl;
9038 uint16_t phy_ctrl; 9038 uint16_t phy_ctrl;
9039 bus_addr_t paddr; 9039 bus_addr_t paddr;
9040 int pkt_len, error, mcast_pkt = 0; 9040 int pkt_len, error, mcast_pkt = 0;
9041#if 0 9041#if 0
9042 const uint8_t *p; 9042 const uint8_t *p;
9043 int i; 9043 int i;
9044#endif 9044#endif
9045 9045
9046 KASSERT(ni != NULL); 9046 KASSERT(ni != NULL);
9047 KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC); 9047 KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC);
9048 mac = (struct bwi_mac *)sc->sc_cur_regwin; 9048 mac = (struct bwi_mac *)sc->sc_cur_regwin;
9049 9049
9050 wh = mtod(m, struct ieee80211_frame *); 9050 wh = mtod(m, struct ieee80211_frame *);
9051 9051
9052 /* Get 802.11 frame len before prepending TX header */ 9052 /* Get 802.11 frame len before prepending TX header */
9053 pkt_len = m->m_pkthdr.len + IEEE80211_CRC_LEN; 9053 pkt_len = m->m_pkthdr.len + IEEE80211_CRC_LEN;
9054 9054
9055 /* 9055 /*
9056 * Find TX rate 9056 * Find TX rate
9057 */ 9057 */
9058 memset(tb->tb_rate_idx, 0, sizeof(tb->tb_rate_idx)); 9058 memset(tb->tb_rate_idx, 0, sizeof(tb->tb_rate_idx));
9059 if (!mgt_pkt) { 9059 if (!mgt_pkt) {
9060 if (ic->ic_fixed_rate != -1) { 9060 if (ic->ic_fixed_rate != -1) {
9061 rate = ic->ic_sup_rates[ic->ic_curmode]. 9061 rate = ic->ic_sup_rates[ic->ic_curmode].
9062 rs_rates[ic->ic_fixed_rate]; 9062 rs_rates[ic->ic_fixed_rate];
9063 /* [TRC: XXX Set fallback rate.] */ 9063 /* [TRC: XXX Set fallback rate.] */
9064 } else { 9064 } else {
9065 /* AMRR rate control */ 9065 /* AMRR rate control */
9066 /* [TRC: XXX amrr] */ 9066 /* [TRC: XXX amrr] */
9067 /* rate = ni->ni_rates.rs_rates[ni->ni_txrate]; */ 9067 /* rate = ni->ni_rates.rs_rates[ni->ni_txrate]; */
9068 rate = (1 * 2); 9068 rate = (1 * 2);
9069 /* [TRC: XXX Set fallback rate.] */ 9069 /* [TRC: XXX Set fallback rate.] */
9070 } 9070 }
9071 } else { 9071 } else {
9072 /* Fixed at 1Mbits/s for mgt frames */ 9072 /* Fixed at 1Mbits/s for mgt frames */
9073 /* [TRC: XXX Set fallback rate.] */ 9073 /* [TRC: XXX Set fallback rate.] */
9074 rate = (1 * 2); 9074 rate = (1 * 2);
9075 } 9075 }
9076 9076
9077 rate &= IEEE80211_RATE_VAL; 9077 rate &= IEEE80211_RATE_VAL;
9078 9078
9079 if (IEEE80211_IS_MULTICAST(wh->i_addr1)) { 9079 if (IEEE80211_IS_MULTICAST(wh->i_addr1)) {
9080 /* [TRC: XXX Set fallback rate.] */ 9080 /* [TRC: XXX Set fallback rate.] */
9081 rate = ic->ic_mcast_rate; 9081 rate = ic->ic_mcast_rate;
9082 mcast_pkt = 1; 9082 mcast_pkt = 1;
9083 } 9083 }
9084 9084
9085 /* [TRC: XXX Check fallback rate.] */ 9085 /* [TRC: XXX Check fallback rate.] */
9086 if (rate == 0) { 9086 if (rate == 0) {
9087 aprint_error_dev(sc->sc_dev, "invalid rate %u", rate); 9087 aprint_error_dev(sc->sc_dev, "invalid rate %u", rate);
9088 /* [TRC: In the margin of the following line, 9088 /* [TRC: In the margin of the following line,
9089 DragonFlyBSD writes `Force 1Mbits/s', whereas 9089 DragonFlyBSD writes `Force 1Mbits/s', whereas
9090 OpenBSD writes `Force 1Mbytes/s'.] */ 9090 OpenBSD writes `Force 1Mbytes/s'.] */
9091 rate = (1 * 2); 9091 rate = (1 * 2);
9092 /* [TRC: XXX Set fallback rate.] */ 9092 /* [TRC: XXX Set fallback rate.] */
9093 } 9093 }
9094 sc->sc_tx_rate = rate; 9094 sc->sc_tx_rate = rate;
9095 9095
9096 /* TX radio tap */ 9096 /* TX radio tap */
9097 if (sc->sc_drvbpf != NULL) { 9097 if (sc->sc_drvbpf != NULL) {
9098 struct mbuf mb; 9098 struct mbuf mb;
9099 struct bwi_tx_radiotap_hdr *tap = &sc->sc_txtap; 9099 struct bwi_tx_radiotap_hdr *tap = &sc->sc_txtap;
9100 9100
9101 tap->wt_flags = 0; 9101 tap->wt_flags = 0;
9102 tap->wt_rate = rate; 9102 tap->wt_rate = rate;
9103 tap->wt_chan_freq = 9103 tap->wt_chan_freq =
9104 htole16(ic->ic_bss->ni_chan->ic_freq); 9104 htole16(ic->ic_bss->ni_chan->ic_freq);
9105 tap->wt_chan_flags = 9105 tap->wt_chan_flags =
9106 htole16(ic->ic_bss->ni_chan->ic_flags); 9106 htole16(ic->ic_bss->ni_chan->ic_flags);
9107 9107
9108 mb.m_data = (void *)tap; 9108 mb.m_data = (void *)tap;
9109 mb.m_len = sc->sc_txtap_len; 9109 mb.m_len = sc->sc_txtap_len;
9110 mb.m_next = m; 9110 mb.m_next = m;
9111 mb.m_nextpkt = NULL; 9111 mb.m_nextpkt = NULL;
9112 mb.m_type = 0; 9112 mb.m_type = 0;
9113 mb.m_flags = 0; 9113 mb.m_flags = 0;
9114 bpf_mtap3(sc->sc_drvbpf, &mb, BPF_D_OUT); 9114 bpf_mtap3(sc->sc_drvbpf, &mb, BPF_D_OUT);
9115 } 9115 }
9116 9116
9117 /* 9117 /*
9118 * Setup the embedded TX header 9118 * Setup the embedded TX header
9119 */ 9119 */
9120 M_PREPEND(m, sizeof(*hdr), M_DONTWAIT); 9120 M_PREPEND(m, sizeof(*hdr), M_DONTWAIT);
9121 if (m == NULL) { 9121 if (m == NULL) {
9122 aprint_error_dev(sc->sc_dev, "prepend TX header failed\n"); 9122 aprint_error_dev(sc->sc_dev, "prepend TX header failed\n");
9123 return (ENOBUFS); 9123 return (ENOBUFS);
9124 } 9124 }
9125 hdr = mtod(m, struct bwi_txbuf_hdr *); 9125 hdr = mtod(m, struct bwi_txbuf_hdr *);
9126 9126
9127 memset(hdr, 0, sizeof(*hdr)); 9127 memset(hdr, 0, sizeof(*hdr));
9128 9128
9129 memcpy(hdr->txh_fc, wh->i_fc, sizeof(hdr->txh_fc)); 9129 memcpy(hdr->txh_fc, wh->i_fc, sizeof(hdr->txh_fc));
9130 memcpy(hdr->txh_addr1, wh->i_addr1, sizeof(hdr->txh_addr1)); 9130 memcpy(hdr->txh_addr1, wh->i_addr1, sizeof(hdr->txh_addr1));
9131 9131
9132 if (!mcast_pkt) { 9132 if (!mcast_pkt) {
9133 uint16_t dur; 9133 uint16_t dur;
9134 uint8_t ack_rate; 9134 uint8_t ack_rate;
9135 9135
9136 /* [TRC: XXX Set fallback rate.] */ 9136 /* [TRC: XXX Set fallback rate.] */
9137 ack_rate = bwi_ieee80211_ack_rate(ni, rate); 9137 ack_rate = bwi_ieee80211_ack_rate(ni, rate);
9138 dur = bwi_ieee80211_txtime(ic, ni, 9138 dur = bwi_ieee80211_txtime(ic, ni,
9139 sizeof(struct ieee80211_frame_ack) + IEEE80211_CRC_LEN, 9139 sizeof(struct ieee80211_frame_ack) + IEEE80211_CRC_LEN,
9140 ack_rate, ic->ic_flags & IEEE80211_F_SHPREAMBLE); 9140 ack_rate, ic->ic_flags & IEEE80211_F_SHPREAMBLE);
9141 9141
9142 hdr->txh_fb_duration = htole16(dur); 9142 hdr->txh_fb_duration = htole16(dur);
9143 } 9143 }
9144 9144
9145 hdr->txh_id = htole16( 9145 hdr->txh_id = htole16(
9146 __SHIFTIN(BWI_TX_DATA_RING, BWI_TXH_ID_RING_MASK) | 9146 __SHIFTIN(BWI_TX_DATA_RING, BWI_TXH_ID_RING_MASK) |
9147 __SHIFTIN(idx, BWI_TXH_ID_IDX_MASK)); 9147 __SHIFTIN(idx, BWI_TXH_ID_IDX_MASK));
9148 9148
9149 bwi_plcp_header(hdr->txh_plcp, pkt_len, rate); 9149 bwi_plcp_header(hdr->txh_plcp, pkt_len, rate);
9150 /* [TRC: XXX Use fallback rate.] */ 9150 /* [TRC: XXX Use fallback rate.] */
9151 bwi_plcp_header(hdr->txh_fb_plcp, pkt_len, rate); 9151 bwi_plcp_header(hdr->txh_fb_plcp, pkt_len, rate);
9152 9152
9153 phy_ctrl = __SHIFTIN(mac->mac_rf.rf_ant_mode, 9153 phy_ctrl = __SHIFTIN(mac->mac_rf.rf_ant_mode,
9154 BWI_TXH_PHY_C_ANTMODE_MASK); 9154 BWI_TXH_PHY_C_ANTMODE_MASK);
9155 if (bwi_ieee80211_rate2modtype(rate) == IEEE80211_MODTYPE_OFDM) 9155 if (bwi_ieee80211_rate2modtype(rate) == IEEE80211_MODTYPE_OFDM)
9156 phy_ctrl |= BWI_TXH_PHY_C_OFDM; 9156 phy_ctrl |= BWI_TXH_PHY_C_OFDM;
9157 else if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) && rate != (2 * 1)) 9157 else if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) && rate != (2 * 1))
9158 phy_ctrl |= BWI_TXH_PHY_C_SHPREAMBLE; 9158 phy_ctrl |= BWI_TXH_PHY_C_SHPREAMBLE;
9159 9159
9160 mac_ctrl = BWI_TXH_MAC_C_HWSEQ | BWI_TXH_MAC_C_FIRST_FRAG; 9160 mac_ctrl = BWI_TXH_MAC_C_HWSEQ | BWI_TXH_MAC_C_FIRST_FRAG;
9161 if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) 9161 if (!IEEE80211_IS_MULTICAST(wh->i_addr1))
9162 mac_ctrl |= BWI_TXH_MAC_C_ACK; 9162 mac_ctrl |= BWI_TXH_MAC_C_ACK;
9163 if (bwi_ieee80211_rate2modtype(rate) == IEEE80211_MODTYPE_OFDM) 9163 if (bwi_ieee80211_rate2modtype(rate) == IEEE80211_MODTYPE_OFDM)
9164 mac_ctrl |= BWI_TXH_MAC_C_FB_OFDM; 9164 mac_ctrl |= BWI_TXH_MAC_C_FB_OFDM;
9165 9165
9166 hdr->txh_mac_ctrl = htole32(mac_ctrl); 9166 hdr->txh_mac_ctrl = htole32(mac_ctrl);
9167 hdr->txh_phy_ctrl = htole16(phy_ctrl); 9167 hdr->txh_phy_ctrl = htole16(phy_ctrl);
9168 9168
9169 /* Catch any further usage */ 9169 /* Catch any further usage */
9170 hdr = NULL; 9170 hdr = NULL;
9171 wh = NULL; 9171 wh = NULL;
9172 9172
9173 /* DMA load */ 9173 /* DMA load */
9174 error = bus_dmamap_load_mbuf(sc->sc_dmat, tb->tb_dmap, m, 9174 error = bus_dmamap_load_mbuf(sc->sc_dmat, tb->tb_dmap, m,
9175 BUS_DMA_NOWAIT); 9175 BUS_DMA_NOWAIT);
9176 if (error && error != EFBIG) { 9176 if (error && error != EFBIG) {
9177 aprint_error_dev(sc->sc_dev, "can't load TX buffer (1) %d\n", 9177 aprint_error_dev(sc->sc_dev, "can't load TX buffer (1) %d\n",
9178 error); 9178 error);
9179 goto back; 9179 goto back;
9180 } 9180 }
9181 9181
9182 if (error) { /* error == EFBIG */ 9182 if (error) { /* error == EFBIG */
9183 struct mbuf *m_new; 9183 struct mbuf *m_new;
9184 9184
9185 error = 0; 9185 error = 0;
9186 9186
9187 MGETHDR(m_new, M_DONTWAIT, MT_DATA); 9187 MGETHDR(m_new, M_DONTWAIT, MT_DATA);
9188 if (m_new == NULL) { 9188 if (m_new == NULL) {
9189 error = ENOBUFS; 9189 error = ENOBUFS;
9190 aprint_error_dev(sc->sc_dev, 9190 aprint_error_dev(sc->sc_dev,
9191 "can't defrag TX buffer (1)\n"); 9191 "can't defrag TX buffer (1)\n");
9192 goto back; 9192 goto back;
9193 } 9193 }
9194 9194
9195 m_copy_pkthdr(m_new, m); 9195 m_copy_pkthdr(m_new, m);
9196 if (m->m_pkthdr.len > MHLEN) { 9196 if (m->m_pkthdr.len > MHLEN) {
9197 MCLGET(m_new, M_DONTWAIT); 9197 MCLGET(m_new, M_DONTWAIT);
9198 if (!(m_new->m_flags & M_EXT)) { 9198 if (!(m_new->m_flags & M_EXT)) {
9199 m_freem(m_new); 9199 m_freem(m_new);
9200 error = ENOBUFS; 9200 error = ENOBUFS;
9201 } 9201 }
9202 } 9202 }
9203  9203
9204 if (error) { 9204 if (error) {
9205 aprint_error_dev(sc->sc_dev, 9205 aprint_error_dev(sc->sc_dev,
9206 "can't defrag TX buffer (2)\n"); 9206 "can't defrag TX buffer (2)\n");
9207 goto back; 9207 goto back;
9208 } 9208 }
9209 9209
9210 m_copydata(m, 0, m->m_pkthdr.len, mtod(m_new, void *)); 9210 m_copydata(m, 0, m->m_pkthdr.len, mtod(m_new, void *));
9211 m_freem(m); 9211 m_freem(m);
9212 m_new->m_len = m_new->m_pkthdr.len; 9212 m_new->m_len = m_new->m_pkthdr.len;
9213 m = m_new; 9213 m = m_new;
9214  9214
9215 error = bus_dmamap_load_mbuf(sc->sc_dmat, tb->tb_dmap, m, 9215 error = bus_dmamap_load_mbuf(sc->sc_dmat, tb->tb_dmap, m,
9216 BUS_DMA_NOWAIT); 9216 BUS_DMA_NOWAIT);
9217 if (error) { 9217 if (error) {
9218 aprint_error_dev(sc->sc_dev, 9218 aprint_error_dev(sc->sc_dev,
9219 "can't load TX buffer (2) %d\n", error); 9219 "can't load TX buffer (2) %d\n", error);
9220 goto back; 9220 goto back;
9221 } 9221 }
9222 } 9222 }
9223 error = 0; 9223 error = 0;
9224 9224
9225 bus_dmamap_sync(sc->sc_dmat, tb->tb_dmap, 0, 9225 bus_dmamap_sync(sc->sc_dmat, tb->tb_dmap, 0,
9226 tb->tb_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE); 9226 tb->tb_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE);
9227 9227
9228 if (mgt_pkt || mcast_pkt) { 9228 if (mgt_pkt || mcast_pkt) {
9229 /* Don't involve mcast/mgt packets into TX rate control */ 9229 /* Don't involve mcast/mgt packets into TX rate control */
9230 ieee80211_free_node(ni); 9230 ieee80211_free_node(ni);
9231 *nip = ni = NULL; 9231 *nip = ni = NULL;
9232 } 9232 }
9233 9233
9234 tb->tb_mbuf = m; 9234 tb->tb_mbuf = m;
9235 tb->tb_ni = ni; 9235 tb->tb_ni = ni;
9236 9236
9237#if 0 9237#if 0
9238 p = mtod(m, const uint8_t *); 9238 p = mtod(m, const uint8_t *);
9239 for (i = 0; i < m->m_pkthdr.len; ++i) { 9239 for (i = 0; i < m->m_pkthdr.len; ++i) {
9240 if (i % 8 == 0) { 9240 if (i % 8 == 0) {
9241 if (i != 0) 9241 if (i != 0)
9242 aprint_debug("\n"); 9242 aprint_debug("\n");
9243 aprint_debug_dev(sc->sc_dev, ""); 9243 aprint_debug_dev(sc->sc_dev, "");
9244 } 9244 }
9245 aprint_debug(" %02x", p[i]); 9245 aprint_debug(" %02x", p[i]);
9246 } 9246 }
9247 aprint_debug("\n"); 9247 aprint_debug("\n");
9248#endif 9248#endif
9249 9249
9250 DPRINTF(sc, BWI_DBG_TX, "idx %d, pkt_len %d, buflen %d\n", 9250 DPRINTF(sc, BWI_DBG_TX, "idx %d, pkt_len %d, buflen %d\n",
9251 idx, pkt_len, m->m_pkthdr.len); 9251 idx, pkt_len, m->m_pkthdr.len);
9252 9252
9253 /* Setup TX descriptor */ 9253 /* Setup TX descriptor */
9254 paddr = tb->tb_dmap->dm_segs[0].ds_addr; 9254 paddr = tb->tb_dmap->dm_segs[0].ds_addr;
9255 (sc->sc_setup_txdesc)(sc, rd, idx, paddr, m->m_pkthdr.len); 9255 (sc->sc_setup_txdesc)(sc, rd, idx, paddr, m->m_pkthdr.len);
9256 bus_dmamap_sync(sc->sc_dmat, rd->rdata_dmap, 0, 9256 bus_dmamap_sync(sc->sc_dmat, rd->rdata_dmap, 0,
9257 rd->rdata_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE); 9257 rd->rdata_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE);
9258 9258
9259 /* Kick start */ 9259 /* Kick start */
9260 (sc->sc_start_tx)(sc, rd->rdata_txrx_ctrl, idx); 9260 (sc->sc_start_tx)(sc, rd->rdata_txrx_ctrl, idx);
9261 9261
9262back: 9262back:
9263 if (error) 9263 if (error)
9264 m_freem(m); 9264 m_freem(m);
9265 return (error); 9265 return (error);
9266} 9266}
9267 9267
9268static void 9268static void
9269bwi_start_tx32(struct bwi_softc *sc, uint32_t tx_ctrl, int idx) 9269bwi_start_tx32(struct bwi_softc *sc, uint32_t tx_ctrl, int idx)
9270{ 9270{
9271 idx = (idx + 1) % BWI_TX_NDESC; 9271 idx = (idx + 1) % BWI_TX_NDESC;
9272 CSR_WRITE_4(sc, tx_ctrl + BWI_TX32_INDEX, 9272 CSR_WRITE_4(sc, tx_ctrl + BWI_TX32_INDEX,
9273 idx * sizeof(struct bwi_desc32)); 9273 idx * sizeof(struct bwi_desc32));
9274} 9274}
9275 9275
9276static void 9276static void
9277bwi_start_tx64(struct bwi_softc *sc, uint32_t tx_ctrl, int idx) 9277bwi_start_tx64(struct bwi_softc *sc, uint32_t tx_ctrl, int idx)
9278{ 9278{
9279 /* TODO: 64 */ 9279 /* TODO: 64 */
9280} 9280}
9281 9281
9282static void 9282static void
9283bwi_txeof_status32(struct bwi_softc *sc) 9283bwi_txeof_status32(struct bwi_softc *sc)
9284{ 9284{
9285 struct ifnet *ifp = &sc->sc_if; 9285 struct ifnet *ifp = &sc->sc_if;
9286 uint32_t val, ctrl_base; 9286 uint32_t val, ctrl_base;
9287 int end_idx, s; 9287 int end_idx, s;
9288 9288
9289 s = splnet(); 9289 s = splnet();
9290 9290
9291 ctrl_base = sc->sc_txstats->stats_ctrl_base; 9291 ctrl_base = sc->sc_txstats->stats_ctrl_base;
9292 9292
9293 val = CSR_READ_4(sc, ctrl_base + BWI_RX32_STATUS); 9293 val = CSR_READ_4(sc, ctrl_base + BWI_RX32_STATUS);
9294 end_idx = __SHIFTOUT(val, BWI_RX32_STATUS_INDEX_MASK) / 9294 end_idx = __SHIFTOUT(val, BWI_RX32_STATUS_INDEX_MASK) /
9295 sizeof(struct bwi_desc32); 9295 sizeof(struct bwi_desc32);
9296 9296
9297 bwi_txeof_status(sc, end_idx); 9297 bwi_txeof_status(sc, end_idx);
9298 9298
9299 CSR_WRITE_4(sc, ctrl_base + BWI_RX32_INDEX, 9299 CSR_WRITE_4(sc, ctrl_base + BWI_RX32_INDEX,
9300 end_idx * sizeof(struct bwi_desc32)); 9300 end_idx * sizeof(struct bwi_desc32));
9301 9301
9302 if ((ifp->if_flags & IFF_OACTIVE) == 0) 9302 if ((ifp->if_flags & IFF_OACTIVE) == 0)
9303 ifp->if_start(ifp); /* [TRC: XXX Why not bwi_start?] */ 9303 ifp->if_start(ifp); /* [TRC: XXX Why not bwi_start?] */
9304 9304
9305 splx(s); 9305 splx(s);
9306} 9306}
9307 9307
9308static void 9308static void
9309bwi_txeof_status64(struct bwi_softc *sc) 9309bwi_txeof_status64(struct bwi_softc *sc)
9310{ 9310{
9311 /* TODO: 64 */ 9311 /* TODO: 64 */
9312} 9312}
9313 9313
9314static void 9314static void
9315_bwi_txeof(struct bwi_softc *sc, uint16_t tx_id) 9315_bwi_txeof(struct bwi_softc *sc, uint16_t tx_id)
9316{ 9316{
9317 struct ifnet *ifp = &sc->sc_if; 9317 struct ifnet *ifp = &sc->sc_if;
9318 struct bwi_txbuf_data *tbd; 9318 struct bwi_txbuf_data *tbd;
9319 struct bwi_txbuf *tb; 9319 struct bwi_txbuf *tb;
9320 int ring_idx, buf_idx; 9320 int ring_idx, buf_idx;
9321 9321
9322 if (tx_id == 0) { 9322 if (tx_id == 0) {
9323 /* [TRC: XXX What is the severity of this message?] */ 9323 /* [TRC: XXX What is the severity of this message?] */
9324 aprint_normal_dev(sc->sc_dev, "zero tx id\n"); 9324 aprint_normal_dev(sc->sc_dev, "zero tx id\n");
9325 return; 9325 return;
9326 } 9326 }
9327 9327
9328 ring_idx = __SHIFTOUT(tx_id, BWI_TXH_ID_RING_MASK); 9328 ring_idx = __SHIFTOUT(tx_id, BWI_TXH_ID_RING_MASK);
9329 buf_idx = __SHIFTOUT(tx_id, BWI_TXH_ID_IDX_MASK); 9329 buf_idx = __SHIFTOUT(tx_id, BWI_TXH_ID_IDX_MASK);
9330 9330
9331 KASSERT(ring_idx == BWI_TX_DATA_RING); 9331 KASSERT(ring_idx == BWI_TX_DATA_RING);
9332 KASSERT(buf_idx < BWI_TX_NDESC); 9332 KASSERT(buf_idx < BWI_TX_NDESC);
9333 tbd = &sc->sc_tx_bdata[ring_idx]; 9333 tbd = &sc->sc_tx_bdata[ring_idx];
9334 KASSERT(tbd->tbd_used > 0); 9334 KASSERT(tbd->tbd_used > 0);
9335 tbd->tbd_used--; 9335 tbd->tbd_used--;
9336 9336
9337 tb = &tbd->tbd_buf[buf_idx]; 9337 tb = &tbd->tbd_buf[buf_idx];
9338 9338
9339 bus_dmamap_unload(sc->sc_dmat, tb->tb_dmap); 9339 bus_dmamap_unload(sc->sc_dmat, tb->tb_dmap);
9340 m_freem(tb->tb_mbuf); 9340 m_freem(tb->tb_mbuf);
9341 tb->tb_mbuf = NULL; 9341 tb->tb_mbuf = NULL;
9342 9342
9343 if (tb->tb_ni != NULL) { 9343 if (tb->tb_ni != NULL) {
9344 ieee80211_free_node(tb->tb_ni); 9344 ieee80211_free_node(tb->tb_ni);
9345 tb->tb_ni = NULL; 9345 tb->tb_ni = NULL;
9346 } 9346 }
9347 9347
9348 if (tbd->tbd_used == 0) 9348 if (tbd->tbd_used == 0)
9349 sc->sc_tx_timer = 0; 9349 sc->sc_tx_timer = 0;
9350 9350
9351 ifp->if_flags &= ~IFF_OACTIVE; 9351 ifp->if_flags &= ~IFF_OACTIVE;
9352} 9352}
9353 9353
9354static void 9354static void
9355bwi_txeof_status(struct bwi_softc *sc, int end_idx) 9355bwi_txeof_status(struct bwi_softc *sc, int end_idx)
9356{ 9356{
9357 struct bwi_txstats_data *st = sc->sc_txstats; 9357 struct bwi_txstats_data *st = sc->sc_txstats;
9358 int idx; 9358 int idx;
9359 9359
9360 bus_dmamap_sync(sc->sc_dmat, st->stats_dmap, 0, 9360 bus_dmamap_sync(sc->sc_dmat, st->stats_dmap, 0,
9361 st->stats_dmap->dm_mapsize, BUS_DMASYNC_POSTREAD); 9361 st->stats_dmap->dm_mapsize, BUS_DMASYNC_POSTREAD);
9362 9362
9363 idx = st->stats_idx; 9363 idx = st->stats_idx;
9364 while (idx != end_idx) { 9364 while (idx != end_idx) {
9365 /* [TRC: XXX Filter this out if it is not pending; see 9365 /* [TRC: XXX Filter this out if it is not pending; see
9366 DragonFlyBSD's revision 1.5. */ 9366 DragonFlyBSD's revision 1.5. */
9367 _bwi_txeof(sc, le16toh(st->stats[idx].txs_id)); 9367 _bwi_txeof(sc, le16toh(st->stats[idx].txs_id));
9368 idx = (idx + 1) % BWI_TXSTATS_NDESC; 9368 idx = (idx + 1) % BWI_TXSTATS_NDESC;
9369 } 9369 }
9370 st->stats_idx = idx; 9370 st->stats_idx = idx;
9371} 9371}
9372 9372
9373static void 9373static void
9374bwi_txeof(struct bwi_softc *sc) 9374bwi_txeof(struct bwi_softc *sc)
9375{ 9375{
9376 struct ifnet *ifp = &sc->sc_if; 9376 struct ifnet *ifp = &sc->sc_if;
9377 int s; 9377 int s;
9378 9378
9379 s = splnet(); 9379 s = splnet();
9380 9380
9381 for (;;) { 9381 for (;;) {
9382 uint32_t tx_status0; 9382 uint32_t tx_status0;
9383 uint16_t tx_id, tx_info; 9383 uint16_t tx_id, tx_info;
9384 9384
9385 tx_status0 = CSR_READ_4(sc, BWI_TXSTATUS_0); 9385 tx_status0 = CSR_READ_4(sc, BWI_TXSTATUS_0);
9386 if ((tx_status0 & BWI_TXSTATUS_0_MORE) == 0) 9386 if ((tx_status0 & BWI_TXSTATUS_0_MORE) == 0)
9387 break; 9387 break;
9388 (void)CSR_READ_4(sc, BWI_TXSTATUS_1); 9388 (void)CSR_READ_4(sc, BWI_TXSTATUS_1);
9389 9389
9390 tx_id = __SHIFTOUT(tx_status0, BWI_TXSTATUS_0_TXID_MASK); 9390 tx_id = __SHIFTOUT(tx_status0, BWI_TXSTATUS_0_TXID_MASK);
9391 tx_info = BWI_TXSTATUS_0_INFO(tx_status0); 9391 tx_info = BWI_TXSTATUS_0_INFO(tx_status0);
9392 9392
9393 if (tx_info & 0x30) /* XXX */ 9393 if (tx_info & 0x30) /* XXX */
9394 continue; 9394 continue;
9395 9395
9396 _bwi_txeof(sc, tx_id); 9396 _bwi_txeof(sc, tx_id);
9397 9397
9398 ifp->if_opackets++; 9398 if_statinc(ifp, if_opackets);
9399 } 9399 }
9400 9400
9401 if ((ifp->if_flags & IFF_OACTIVE) == 0) 9401 if ((ifp->if_flags & IFF_OACTIVE) == 0)
9402 ifp->if_start(ifp); 9402 ifp->if_start(ifp);
9403 9403
9404 splx(s); 9404 splx(s);
9405} 9405}
9406 9406
9407static int 9407static int
9408bwi_bbp_power_on(struct bwi_softc *sc, enum bwi_clock_mode clk_mode) 9408bwi_bbp_power_on(struct bwi_softc *sc, enum bwi_clock_mode clk_mode)
9409{ 9409{
9410 bwi_power_on(sc, 1); 9410 bwi_power_on(sc, 1);
9411 9411
9412 return (bwi_set_clock_mode(sc, clk_mode)); 9412 return (bwi_set_clock_mode(sc, clk_mode));
9413} 9413}
9414 9414
9415static void 9415static void
9416bwi_bbp_power_off(struct bwi_softc *sc) 9416bwi_bbp_power_off(struct bwi_softc *sc)
9417{ 9417{
9418 bwi_set_clock_mode(sc, BWI_CLOCK_MODE_SLOW); 9418 bwi_set_clock_mode(sc, BWI_CLOCK_MODE_SLOW);
9419 bwi_power_off(sc, 1); 9419 bwi_power_off(sc, 1);
9420} 9420}
9421 9421
9422static int 9422static int
9423bwi_get_pwron_delay(struct bwi_softc *sc) 9423bwi_get_pwron_delay(struct bwi_softc *sc)
9424{ 9424{
9425 struct bwi_regwin *com, *old; 9425 struct bwi_regwin *com, *old;
9426 struct bwi_clock_freq freq; 9426 struct bwi_clock_freq freq;
9427 uint32_t val; 9427 uint32_t val;
9428 int error; 9428 int error;
9429 9429
9430 com = &sc->sc_com_regwin; 9430 com = &sc->sc_com_regwin;
9431 KASSERT(BWI_REGWIN_EXIST(com)); 9431 KASSERT(BWI_REGWIN_EXIST(com));
9432 9432
9433 if ((sc->sc_cap & BWI_CAP_CLKMODE) == 0) 9433 if ((sc->sc_cap & BWI_CAP_CLKMODE) == 0)
9434 return (0); 9434 return (0);
9435 9435
9436 error = bwi_regwin_switch(sc, com, &old); 9436 error = bwi_regwin_switch(sc, com, &old);
9437 if (error) 9437 if (error)
9438 return (error); 9438 return (error);
9439 9439
9440 bwi_get_clock_freq(sc, &freq); 9440 bwi_get_clock_freq(sc, &freq);
9441 9441
9442 val = CSR_READ_4(sc, BWI_PLL_ON_DELAY); 9442 val = CSR_READ_4(sc, BWI_PLL_ON_DELAY);
9443 sc->sc_pwron_delay = howmany((val + 2) * 1000000, freq.clkfreq_min); 9443 sc->sc_pwron_delay = howmany((val + 2) * 1000000, freq.clkfreq_min);
9444 DPRINTF(sc, BWI_DBG_ATTACH, "power on delay %u\n", sc->sc_pwron_delay); 9444 DPRINTF(sc, BWI_DBG_ATTACH, "power on delay %u\n", sc->sc_pwron_delay);
9445 9445
9446 return (bwi_regwin_switch(sc, old, NULL)); 9446 return (bwi_regwin_switch(sc, old, NULL));
9447} 9447}
9448 9448
9449static int 9449static int
9450bwi_bus_attach(struct bwi_softc *sc) 9450bwi_bus_attach(struct bwi_softc *sc)
9451{ 9451{
9452 struct bwi_regwin *bus, *old; 9452 struct bwi_regwin *bus, *old;
9453 int error; 9453 int error;
9454 9454
9455 bus = &sc->sc_bus_regwin; 9455 bus = &sc->sc_bus_regwin;
9456 9456
9457 error = bwi_regwin_switch(sc, bus, &old); 9457 error = bwi_regwin_switch(sc, bus, &old);
9458 if (error) 9458 if (error)
9459 return (error); 9459 return (error);
9460 9460
9461 if (!bwi_regwin_is_enabled(sc, bus)) 9461 if (!bwi_regwin_is_enabled(sc, bus))
9462 bwi_regwin_enable(sc, bus, 0); 9462 bwi_regwin_enable(sc, bus, 0);
9463 9463
9464 /* Disable interripts */ 9464 /* Disable interripts */
9465 CSR_WRITE_4(sc, BWI_INTRVEC, 0); 9465 CSR_WRITE_4(sc, BWI_INTRVEC, 0);
9466 9466
9467 return (bwi_regwin_switch(sc, old, NULL)); 9467 return (bwi_regwin_switch(sc, old, NULL));
9468} 9468}
9469 9469
9470static const char * 9470static const char *
9471bwi_regwin_name(const struct bwi_regwin *rw) 9471bwi_regwin_name(const struct bwi_regwin *rw)
9472{ 9472{
9473 switch (rw->rw_type) { 9473 switch (rw->rw_type) {
9474 case BWI_REGWIN_T_COM: 9474 case BWI_REGWIN_T_COM:
9475 return ("COM"); 9475 return ("COM");
9476 case BWI_REGWIN_T_BUSPCI: 9476 case BWI_REGWIN_T_BUSPCI:
9477 return ("PCI"); 9477 return ("PCI");
9478 case BWI_REGWIN_T_MAC: 9478 case BWI_REGWIN_T_MAC:
9479 return ("MAC"); 9479 return ("MAC");
9480 case BWI_REGWIN_T_BUSPCIE: 9480 case BWI_REGWIN_T_BUSPCIE:
9481 return ("PCIE"); 9481 return ("PCIE");
9482 } 9482 }
9483 panic("unknown regwin type 0x%04x\n", rw->rw_type); 9483 panic("unknown regwin type 0x%04x\n", rw->rw_type);
9484 9484
9485 return (NULL); 9485 return (NULL);
9486} 9486}
9487 9487
9488static uint32_t 9488static uint32_t
9489bwi_regwin_disable_bits(struct bwi_softc *sc) 9489bwi_regwin_disable_bits(struct bwi_softc *sc)
9490{ 9490{
9491 uint32_t busrev; 9491 uint32_t busrev;
9492 9492
9493 /* XXX cache this */ 9493 /* XXX cache this */
9494 busrev = __SHIFTOUT(CSR_READ_4(sc, BWI_ID_LO), BWI_ID_LO_BUSREV_MASK); 9494 busrev = __SHIFTOUT(CSR_READ_4(sc, BWI_ID_LO), BWI_ID_LO_BUSREV_MASK);
9495 DPRINTF(sc, BWI_DBG_ATTACH | BWI_DBG_INIT | BWI_DBG_MISC, 9495 DPRINTF(sc, BWI_DBG_ATTACH | BWI_DBG_INIT | BWI_DBG_MISC,
9496 "bus rev %u\n", busrev); 9496 "bus rev %u\n", busrev);
9497 9497
9498 if (busrev == BWI_BUSREV_0) 9498 if (busrev == BWI_BUSREV_0)
9499 return (BWI_STATE_LO_DISABLE1); 9499 return (BWI_STATE_LO_DISABLE1);
9500 else if (busrev == BWI_BUSREV_1) 9500 else if (busrev == BWI_BUSREV_1)
9501 return (BWI_STATE_LO_DISABLE2); 9501 return (BWI_STATE_LO_DISABLE2);
9502 else 9502 else
9503 return (BWI_STATE_LO_DISABLE1 | BWI_STATE_LO_DISABLE2); 9503 return (BWI_STATE_LO_DISABLE1 | BWI_STATE_LO_DISABLE2);
9504} 9504}
9505 9505
9506static int 9506static int
9507bwi_regwin_is_enabled(struct bwi_softc *sc, struct bwi_regwin *rw) 9507bwi_regwin_is_enabled(struct bwi_softc *sc, struct bwi_regwin *rw)
9508{ 9508{
9509 uint32_t val, disable_bits; 9509 uint32_t val, disable_bits;
9510 9510
9511 disable_bits = bwi_regwin_disable_bits(sc); 9511 disable_bits = bwi_regwin_disable_bits(sc);
9512 val = CSR_READ_4(sc, BWI_STATE_LO); 9512 val = CSR_READ_4(sc, BWI_STATE_LO);
9513 9513
9514 if ((val & (BWI_STATE_LO_CLOCK | 9514 if ((val & (BWI_STATE_LO_CLOCK |
9515 BWI_STATE_LO_RESET | 9515 BWI_STATE_LO_RESET |
9516 disable_bits)) == BWI_STATE_LO_CLOCK) { 9516 disable_bits)) == BWI_STATE_LO_CLOCK) {
9517 DPRINTF(sc, BWI_DBG_ATTACH | BWI_DBG_INIT, "%s is enabled\n", 9517 DPRINTF(sc, BWI_DBG_ATTACH | BWI_DBG_INIT, "%s is enabled\n",
9518 bwi_regwin_name(rw)); 9518 bwi_regwin_name(rw));
9519 return (1); 9519 return (1);
9520 } else { 9520 } else {
9521 DPRINTF(sc, BWI_DBG_ATTACH | BWI_DBG_INIT, "%s is disabled\n", 9521 DPRINTF(sc, BWI_DBG_ATTACH | BWI_DBG_INIT, "%s is disabled\n",
9522 bwi_regwin_name(rw)); 9522 bwi_regwin_name(rw));
9523 return (0); 9523 return (0);
9524 } 9524 }
9525} 9525}
9526 9526
9527static void 9527static void
9528bwi_regwin_disable(struct bwi_softc *sc, struct bwi_regwin *rw, uint32_t flags) 9528bwi_regwin_disable(struct bwi_softc *sc, struct bwi_regwin *rw, uint32_t flags)
9529{ 9529{
9530 uint32_t state_lo, disable_bits; 9530 uint32_t state_lo, disable_bits;
9531 int i; 9531 int i;
9532 9532
9533 state_lo = CSR_READ_4(sc, BWI_STATE_LO); 9533 state_lo = CSR_READ_4(sc, BWI_STATE_LO);
9534 9534
9535 /* 9535 /*
9536 * If current regwin is in 'reset' state, it was already disabled. 9536 * If current regwin is in 'reset' state, it was already disabled.
9537 */ 9537 */
9538 if (state_lo & BWI_STATE_LO_RESET) { 9538 if (state_lo & BWI_STATE_LO_RESET) {
9539 DPRINTF(sc, BWI_DBG_ATTACH | BWI_DBG_INIT, 9539 DPRINTF(sc, BWI_DBG_ATTACH | BWI_DBG_INIT,
9540 "%s was already disabled\n", bwi_regwin_name(rw)); 9540 "%s was already disabled\n", bwi_regwin_name(rw));
9541 return; 9541 return;
9542 } 9542 }
9543 9543
9544 disable_bits = bwi_regwin_disable_bits(sc); 9544 disable_bits = bwi_regwin_disable_bits(sc);
9545 9545
9546 /* 9546 /*
9547 * Disable normal clock 9547 * Disable normal clock
9548 */ 9548 */
9549 state_lo = BWI_STATE_LO_CLOCK | disable_bits; 9549 state_lo = BWI_STATE_LO_CLOCK | disable_bits;
9550 CSR_WRITE_4(sc, BWI_STATE_LO, state_lo); 9550 CSR_WRITE_4(sc, BWI_STATE_LO, state_lo);
9551 9551
9552 /* 9552 /*
9553 * Wait until normal clock is disabled 9553 * Wait until normal clock is disabled
9554 */ 9554 */
9555#define NRETRY 1000 9555#define NRETRY 1000
9556 for (i = 0; i < NRETRY; ++i) { 9556 for (i = 0; i < NRETRY; ++i) {
9557 state_lo = CSR_READ_4(sc, BWI_STATE_LO); 9557 state_lo = CSR_READ_4(sc, BWI_STATE_LO);
9558 if (state_lo & disable_bits) 9558 if (state_lo & disable_bits)
9559 break; 9559 break;
9560 DELAY(10); 9560 DELAY(10);
9561 } 9561 }
9562 if (i == NRETRY) { 9562 if (i == NRETRY) {
9563 aprint_error_dev(sc->sc_dev, "%s disable clock timeout\n", 9563 aprint_error_dev(sc->sc_dev, "%s disable clock timeout\n",
9564 bwi_regwin_name(rw)); 9564 bwi_regwin_name(rw));
9565 } 9565 }
9566 9566
9567 for (i = 0; i < NRETRY; ++i) { 9567 for (i = 0; i < NRETRY; ++i) {
9568 uint32_t state_hi; 9568 uint32_t state_hi;
9569 9569
9570 state_hi = CSR_READ_4(sc, BWI_STATE_HI); 9570 state_hi = CSR_READ_4(sc, BWI_STATE_HI);
9571 if ((state_hi & BWI_STATE_HI_BUSY) == 0) 9571 if ((state_hi & BWI_STATE_HI_BUSY) == 0)
9572 break; 9572 break;
9573 DELAY(10); 9573 DELAY(10);
9574 } 9574 }
9575 if (i == NRETRY) { 9575 if (i == NRETRY) {
9576 aprint_error_dev(sc->sc_dev, "%s wait BUSY unset timeout\n", 9576 aprint_error_dev(sc->sc_dev, "%s wait BUSY unset timeout\n",
9577 bwi_regwin_name(rw)); 9577 bwi_regwin_name(rw));
9578 } 9578 }
9579#undef NRETRY 9579#undef NRETRY
9580 9580
9581 /* 9581 /*
9582 * Reset and disable regwin with gated clock 9582 * Reset and disable regwin with gated clock
9583 */ 9583 */
9584 state_lo = BWI_STATE_LO_RESET | disable_bits | 9584 state_lo = BWI_STATE_LO_RESET | disable_bits |
9585 BWI_STATE_LO_CLOCK | BWI_STATE_LO_GATED_CLOCK | 9585 BWI_STATE_LO_CLOCK | BWI_STATE_LO_GATED_CLOCK |
9586 __SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK); 9586 __SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK);
9587 CSR_WRITE_4(sc, BWI_STATE_LO, state_lo); 9587 CSR_WRITE_4(sc, BWI_STATE_LO, state_lo);
9588 9588
9589 /* Flush pending bus write */ 9589 /* Flush pending bus write */
9590 CSR_READ_4(sc, BWI_STATE_LO); 9590 CSR_READ_4(sc, BWI_STATE_LO);
9591 DELAY(1); 9591 DELAY(1);
9592 9592
9593 /* Reset and disable regwin */ 9593 /* Reset and disable regwin */
9594 state_lo = BWI_STATE_LO_RESET | disable_bits | 9594 state_lo = BWI_STATE_LO_RESET | disable_bits |
9595 __SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK); 9595 __SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK);
9596 CSR_WRITE_4(sc, BWI_STATE_LO, state_lo); 9596 CSR_WRITE_4(sc, BWI_STATE_LO, state_lo);
9597 9597
9598 /* Flush pending bus write */ 9598 /* Flush pending bus write */
9599 CSR_READ_4(sc, BWI_STATE_LO); 9599 CSR_READ_4(sc, BWI_STATE_LO);
9600 DELAY(1); 9600 DELAY(1);
9601} 9601}
9602 9602
9603static void 9603static void
9604bwi_regwin_enable(struct bwi_softc *sc, struct bwi_regwin *rw, uint32_t flags) 9604bwi_regwin_enable(struct bwi_softc *sc, struct bwi_regwin *rw, uint32_t flags)
9605{ 9605{
9606 uint32_t state_lo, state_hi, imstate; 9606 uint32_t state_lo, state_hi, imstate;
9607 9607
9608 bwi_regwin_disable(sc, rw, flags); 9608 bwi_regwin_disable(sc, rw, flags);
9609 9609
9610 /* Reset regwin with gated clock */ 9610 /* Reset regwin with gated clock */
9611 state_lo = BWI_STATE_LO_RESET | 9611 state_lo = BWI_STATE_LO_RESET |
9612 BWI_STATE_LO_CLOCK | 9612 BWI_STATE_LO_CLOCK |
9613 BWI_STATE_LO_GATED_CLOCK | 9613 BWI_STATE_LO_GATED_CLOCK |
9614 __SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK); 9614 __SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK);
9615 CSR_WRITE_4(sc, BWI_STATE_LO, state_lo); 9615 CSR_WRITE_4(sc, BWI_STATE_LO, state_lo);
9616 9616
9617 /* Flush pending bus write */ 9617 /* Flush pending bus write */
9618 CSR_READ_4(sc, BWI_STATE_LO); 9618 CSR_READ_4(sc, BWI_STATE_LO);
9619 DELAY(1); 9619 DELAY(1);
9620 9620
9621 state_hi = CSR_READ_4(sc, BWI_STATE_HI); 9621 state_hi = CSR_READ_4(sc, BWI_STATE_HI);
9622 if (state_hi & BWI_STATE_HI_SERROR) 9622 if (state_hi & BWI_STATE_HI_SERROR)
9623 CSR_WRITE_4(sc, BWI_STATE_HI, 0); 9623 CSR_WRITE_4(sc, BWI_STATE_HI, 0);
9624 9624
9625 imstate = CSR_READ_4(sc, BWI_IMSTATE); 9625 imstate = CSR_READ_4(sc, BWI_IMSTATE);
9626 if (imstate & (BWI_IMSTATE_INBAND_ERR | BWI_IMSTATE_TIMEOUT)) { 9626 if (imstate & (BWI_IMSTATE_INBAND_ERR | BWI_IMSTATE_TIMEOUT)) {
9627 imstate &= ~(BWI_IMSTATE_INBAND_ERR | BWI_IMSTATE_TIMEOUT); 9627 imstate &= ~(BWI_IMSTATE_INBAND_ERR | BWI_IMSTATE_TIMEOUT);
9628 CSR_WRITE_4(sc, BWI_IMSTATE, imstate); 9628 CSR_WRITE_4(sc, BWI_IMSTATE, imstate);
9629 } 9629 }
9630 9630
9631 /* Enable regwin with gated clock */ 9631 /* Enable regwin with gated clock */
9632 state_lo = BWI_STATE_LO_CLOCK | 9632 state_lo = BWI_STATE_LO_CLOCK |
9633 BWI_STATE_LO_GATED_CLOCK | 9633 BWI_STATE_LO_GATED_CLOCK |
9634 __SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK); 9634 __SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK);
9635 CSR_WRITE_4(sc, BWI_STATE_LO, state_lo); 9635 CSR_WRITE_4(sc, BWI_STATE_LO, state_lo);
9636 9636
9637 /* Flush pending bus write */ 9637 /* Flush pending bus write */
9638 CSR_READ_4(sc, BWI_STATE_LO); 9638 CSR_READ_4(sc, BWI_STATE_LO);
9639 DELAY(1); 9639 DELAY(1);
9640 9640
9641 /* Enable regwin with normal clock */ 9641 /* Enable regwin with normal clock */
9642 state_lo = BWI_STATE_LO_CLOCK | 9642 state_lo = BWI_STATE_LO_CLOCK |
9643 __SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK); 9643 __SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK);
9644 CSR_WRITE_4(sc, BWI_STATE_LO, state_lo); 9644 CSR_WRITE_4(sc, BWI_STATE_LO, state_lo);
9645 9645
9646 /* Flush pending bus write */ 9646 /* Flush pending bus write */
9647 CSR_READ_4(sc, BWI_STATE_LO); 9647 CSR_READ_4(sc, BWI_STATE_LO);
9648 DELAY(1); 9648 DELAY(1);
9649} 9649}
9650 9650
9651static void 9651static void
9652bwi_set_bssid(struct bwi_softc *sc, const uint8_t *bssid) 9652bwi_set_bssid(struct bwi_softc *sc, const uint8_t *bssid)
9653{ 9653{
9654 struct ieee80211com *ic = &sc->sc_ic; 9654 struct ieee80211com *ic = &sc->sc_ic;
9655 struct bwi_mac *mac; 9655 struct bwi_mac *mac;
9656 struct bwi_myaddr_bssid buf; 9656 struct bwi_myaddr_bssid buf;
9657 const uint8_t *p; 9657 const uint8_t *p;
9658 uint32_t val; 9658 uint32_t val;
9659 int n, i; 9659 int n, i;
9660 9660
9661 KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC); 9661 KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC);
9662 mac = (struct bwi_mac *)sc->sc_cur_regwin; 9662 mac = (struct bwi_mac *)sc->sc_cur_regwin;
9663 9663
9664 bwi_set_addr_filter(sc, BWI_ADDR_FILTER_BSSID, bssid); 9664 bwi_set_addr_filter(sc, BWI_ADDR_FILTER_BSSID, bssid);
9665 9665
9666 memcpy(buf.myaddr, ic->ic_myaddr, sizeof(buf.myaddr)); 9666 memcpy(buf.myaddr, ic->ic_myaddr, sizeof(buf.myaddr));
9667 memcpy(buf.bssid, bssid, sizeof(buf.bssid)); 9667 memcpy(buf.bssid, bssid, sizeof(buf.bssid));
9668 9668
9669 n = sizeof(buf) / sizeof(val); 9669 n = sizeof(buf) / sizeof(val);
9670 p = (const uint8_t *)&buf; 9670 p = (const uint8_t *)&buf;
9671 for (i = 0; i < n; ++i) { 9671 for (i = 0; i < n; ++i) {
9672 int j; 9672 int j;
9673 9673
9674 val = 0; 9674 val = 0;
9675 for (j = 0; j < sizeof(val); ++j) 9675 for (j = 0; j < sizeof(val); ++j)
9676 val |= ((uint32_t)(*p++)) << (j * 8); 9676 val |= ((uint32_t)(*p++)) << (j * 8);
9677 9677
9678 TMPLT_WRITE_4(mac, 0x20 + (i * sizeof(val)), val); 9678 TMPLT_WRITE_4(mac, 0x20 + (i * sizeof(val)), val);
9679 } 9679 }
9680} 9680}
9681 9681
9682static void 9682static void
9683bwi_updateslot(struct ifnet *ifp) 9683bwi_updateslot(struct ifnet *ifp)
9684{ 9684{
9685 struct bwi_softc *sc = ifp->if_softc; 9685 struct bwi_softc *sc = ifp->if_softc;
9686 struct ieee80211com *ic = &sc->sc_ic; 9686 struct ieee80211com *ic = &sc->sc_ic;
9687 struct bwi_mac *mac; 9687 struct bwi_mac *mac;
9688 9688
9689 if ((ifp->if_flags & IFF_RUNNING) == 0) 9689 if ((ifp->if_flags & IFF_RUNNING) == 0)
9690 return; 9690 return;
9691 9691
9692 DPRINTF(sc, BWI_DBG_80211, "%s\n", __func__); 9692 DPRINTF(sc, BWI_DBG_80211, "%s\n", __func__);
9693 9693
9694 KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC); 9694 KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC);
9695 mac = (struct bwi_mac *)sc->sc_cur_regwin; 9695 mac = (struct bwi_mac *)sc->sc_cur_regwin;
9696 9696
9697 bwi_mac_updateslot(mac, (ic->ic_flags & IEEE80211_F_SHSLOT)); 9697 bwi_mac_updateslot(mac, (ic->ic_flags & IEEE80211_F_SHSLOT));
9698} 9698}
9699 9699
9700static void 9700static void
9701bwi_calibrate(void *xsc) 9701bwi_calibrate(void *xsc)
9702{ 9702{
9703 struct bwi_softc *sc = xsc; 9703 struct bwi_softc *sc = xsc;
9704 struct ieee80211com *ic = &sc->sc_ic; 9704 struct ieee80211com *ic = &sc->sc_ic;
9705 int s; 9705 int s;
9706 9706
9707 s = splnet(); 9707 s = splnet();
9708 9708
9709 if (ic->ic_state == IEEE80211_S_RUN) { 9709 if (ic->ic_state == IEEE80211_S_RUN) {
9710 struct bwi_mac *mac; 9710 struct bwi_mac *mac;
9711 9711
9712 KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC); 9712 KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC);
9713 mac = (struct bwi_mac *)sc->sc_cur_regwin; 9713 mac = (struct bwi_mac *)sc->sc_cur_regwin;
9714 9714
9715 if (ic->ic_opmode != IEEE80211_M_MONITOR) { 9715 if (ic->ic_opmode != IEEE80211_M_MONITOR) {
9716 bwi_mac_calibrate_txpower(mac, sc->sc_txpwrcb_type); 9716 bwi_mac_calibrate_txpower(mac, sc->sc_txpwrcb_type);
9717 sc->sc_txpwrcb_type = BWI_TXPWR_CALIB; 9717 sc->sc_txpwrcb_type = BWI_TXPWR_CALIB;
9718 } 9718 }
9719 9719
9720 /* XXX 15 seconds */ 9720 /* XXX 15 seconds */
9721 callout_schedule(&sc->sc_calib_ch, hz * 15); 9721 callout_schedule(&sc->sc_calib_ch, hz * 15);
9722 } 9722 }
9723 9723
9724 splx(s); 9724 splx(s);
9725} 9725}
9726 9726
9727static int 9727static int
9728bwi_calc_rssi(struct bwi_softc *sc, const struct bwi_rxbuf_hdr *hdr) 9728bwi_calc_rssi(struct bwi_softc *sc, const struct bwi_rxbuf_hdr *hdr)
9729{ 9729{
9730 struct bwi_mac *mac; 9730 struct bwi_mac *mac;
9731 9731
9732 KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC); 9732 KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC);
9733 mac = (struct bwi_mac *)sc->sc_cur_regwin; 9733 mac = (struct bwi_mac *)sc->sc_cur_regwin;
9734 9734
9735 return (bwi_rf_calc_rssi(mac, hdr)); 9735 return (bwi_rf_calc_rssi(mac, hdr));
9736} 9736}
9737 9737
9738bool 9738bool
9739bwi_suspend(device_t dv, const pmf_qual_t *qual) 9739bwi_suspend(device_t dv, const pmf_qual_t *qual)
9740{ 9740{
9741 struct bwi_softc *sc = device_private(dv); 9741 struct bwi_softc *sc = device_private(dv);
9742 9742
9743 bwi_power_off(sc, 0); 9743 bwi_power_off(sc, 0);
9744 if (sc->sc_disable != NULL) 9744 if (sc->sc_disable != NULL)
9745 (sc->sc_disable)(sc, 1); 9745 (sc->sc_disable)(sc, 1);
9746 9746
9747 return true; 9747 return true;
9748} 9748}
9749 9749
9750bool 9750bool
9751bwi_resume(device_t dv, const pmf_qual_t *qual) 9751bwi_resume(device_t dv, const pmf_qual_t *qual)
9752{ 9752{
9753 struct bwi_softc *sc = device_private(dv); 9753 struct bwi_softc *sc = device_private(dv);
9754 9754
9755 if (sc->sc_enable != NULL) 9755 if (sc->sc_enable != NULL)
9756 (sc->sc_enable)(sc, 1); 9756 (sc->sc_enable)(sc, 1);
9757 bwi_power_on(sc, 1); 9757 bwi_power_on(sc, 1);
9758 9758
9759 return true; 9759 return true;
9760} 9760}

cvs diff -r1.47 -r1.48 src/sys/dev/ic/cs89x0.c (switch to unified diff)

--- src/sys/dev/ic/cs89x0.c 2019/05/29 10:07:29 1.47
+++ src/sys/dev/ic/cs89x0.c 2020/01/29 14:14:55 1.48
@@ -1,2145 +1,2148 @@ @@ -1,2145 +1,2148 @@
1/* $NetBSD: cs89x0.c,v 1.47 2019/05/29 10:07:29 msaitoh Exp $ */ 1/* $NetBSD: cs89x0.c,v 1.48 2020/01/29 14:14:55 thorpej Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2004 Christopher Gilbert 4 * Copyright (c) 2004 Christopher Gilbert
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution. 11 * documentation and/or other materials provided with the distribution.
12 * 3. The name of the company nor the name of the author may be used to 12 * 3. The name of the company nor the name of the author may be used to
13 * endorse or promote products derived from this software without specific 13 * endorse or promote products derived from this software without specific
14 * prior written permission. 14 * prior written permission.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 19 * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
20 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE. 26 * SUCH DAMAGE.
27 */ 27 */
28 28
29/* 29/*
30 * Copyright 1997 30 * Copyright 1997
31 * Digital Equipment Corporation. All rights reserved. 31 * Digital Equipment Corporation. All rights reserved.
32 * 32 *
33 * This software is furnished under license and may be used and 33 * This software is furnished under license and may be used and
34 * copied only in accordance with the following terms and conditions. 34 * copied only in accordance with the following terms and conditions.
35 * Subject to these conditions, you may download, copy, install, 35 * Subject to these conditions, you may download, copy, install,
36 * use, modify and distribute this software in source and/or binary 36 * use, modify and distribute this software in source and/or binary
37 * form. No title or ownership is transferred hereby. 37 * form. No title or ownership is transferred hereby.
38 * 38 *
39 * 1) Any source code used, modified or distributed must reproduce 39 * 1) Any source code used, modified or distributed must reproduce
40 * and retain this copyright notice and list of conditions as 40 * and retain this copyright notice and list of conditions as
41 * they appear in the source file. 41 * they appear in the source file.
42 * 42 *
43 * 2) No right is granted to use any trade name, trademark, or logo of 43 * 2) No right is granted to use any trade name, trademark, or logo of
44 * Digital Equipment Corporation. Neither the "Digital Equipment 44 * Digital Equipment Corporation. Neither the "Digital Equipment
45 * Corporation" name nor any trademark or logo of Digital Equipment 45 * Corporation" name nor any trademark or logo of Digital Equipment
46 * Corporation may be used to endorse or promote products derived 46 * Corporation may be used to endorse or promote products derived
47 * from this software without the prior written permission of 47 * from this software without the prior written permission of
48 * Digital Equipment Corporation. 48 * Digital Equipment Corporation.
49 * 49 *
50 * 3) This software is provided "AS-IS" and any express or implied 50 * 3) This software is provided "AS-IS" and any express or implied
51 * warranties, including but not limited to, any implied warranties 51 * warranties, including but not limited to, any implied warranties
52 * of merchantability, fitness for a particular purpose, or 52 * of merchantability, fitness for a particular purpose, or
53 * non-infringement are disclaimed. In no event shall DIGITAL be 53 * non-infringement are disclaimed. In no event shall DIGITAL be
54 * liable for any damages whatsoever, and in particular, DIGITAL 54 * liable for any damages whatsoever, and in particular, DIGITAL
55 * shall not be liable for special, indirect, consequential, or 55 * shall not be liable for special, indirect, consequential, or
56 * incidental damages or damages for lost profits, loss of 56 * incidental damages or damages for lost profits, loss of
57 * revenue or loss of use, whether such damages arise in contract, 57 * revenue or loss of use, whether such damages arise in contract,
58 * negligence, tort, under statute, in equity, at law or otherwise, 58 * negligence, tort, under statute, in equity, at law or otherwise,
59 * even if advised of the possibility of such damage. 59 * even if advised of the possibility of such damage.
60 */ 60 */
61 61
62/* 62/*
63**++ 63**++
64** FACILITY 64** FACILITY
65** 65**
66** Device Driver for the Crystal CS8900 ISA Ethernet Controller. 66** Device Driver for the Crystal CS8900 ISA Ethernet Controller.
67** 67**
68** ABSTRACT 68** ABSTRACT
69** 69**
70** This module provides standard ethernet access for INET protocols 70** This module provides standard ethernet access for INET protocols
71** only. 71** only.
72** 72**
73** AUTHORS 73** AUTHORS
74** 74**
75** Peter Dettori SEA - Software Engineering. 75** Peter Dettori SEA - Software Engineering.
76** 76**
77** CREATION DATE: 77** CREATION DATE:
78** 78**
79** 13-Feb-1997. 79** 13-Feb-1997.
80** 80**
81** MODIFICATION HISTORY (Digital): 81** MODIFICATION HISTORY (Digital):
82** 82**
83** Revision 1.27 1998/01/20 17:59:40 cgd 83** Revision 1.27 1998/01/20 17:59:40 cgd
84** update for moved headers 84** update for moved headers
85** 85**
86** Revision 1.26 1998/01/12 19:29:36 cgd 86** Revision 1.26 1998/01/12 19:29:36 cgd
87** use arm32/isa versions of isadma code. 87** use arm32/isa versions of isadma code.
88** 88**
89** Revision 1.25 1997/12/12 01:35:27 cgd 89** Revision 1.25 1997/12/12 01:35:27 cgd
90** convert to use new arp code (from Brini) 90** convert to use new arp code (from Brini)
91** 91**
92** Revision 1.24 1997/12/10 22:31:56 cgd 92** Revision 1.24 1997/12/10 22:31:56 cgd
93** trim some fat (get rid of ability to explicitly supply enet addr, since 93** trim some fat (get rid of ability to explicitly supply enet addr, since
94** it was never used and added a bunch of code which really doesn't belong in 94** it was never used and added a bunch of code which really doesn't belong in
95** an enet driver), and clean up slightly. 95** an enet driver), and clean up slightly.
96** 96**
97** Revision 1.23 1997/10/06 16:42:12 cgd 97** Revision 1.23 1997/10/06 16:42:12 cgd
98** copyright notices 98** copyright notices
99** 99**
100** Revision 1.22 1997/06/20 19:38:01 chaiken 100** Revision 1.22 1997/06/20 19:38:01 chaiken
101** fixes some smartcard problems 101** fixes some smartcard problems
102** 102**
103** Revision 1.21 1997/06/10 02:56:20 grohn 103** Revision 1.21 1997/06/10 02:56:20 grohn
104** Added call to ledNetActive 104** Added call to ledNetActive
105** 105**
106** Revision 1.20 1997/06/05 00:47:06 dettori 106** Revision 1.20 1997/06/05 00:47:06 dettori
107** Changed cs_process_rx_dma to reset and re-initialise the 107** Changed cs_process_rx_dma to reset and re-initialise the
108** ethernet chip when DMA gets out of sync, or mbufs 108** ethernet chip when DMA gets out of sync, or mbufs
109** can't be allocated. 109** can't be allocated.
110** 110**
111** Revision 1.19 1997/06/03 03:09:58 dettori 111** Revision 1.19 1997/06/03 03:09:58 dettori
112** Turn off sc_txbusy flag when a transmit underrun 112** Turn off sc_txbusy flag when a transmit underrun
113** occurs. 113** occurs.
114** 114**
115** Revision 1.18 1997/06/02 00:04:35 dettori 115** Revision 1.18 1997/06/02 00:04:35 dettori
116** redefined the transmit table to get around the nfs_timer bug while we are 116** redefined the transmit table to get around the nfs_timer bug while we are
117** looking into it further. 117** looking into it further.
118** 118**
119** Also changed interrupts from EDGE to LEVEL. 119** Also changed interrupts from EDGE to LEVEL.
120** 120**
121** Revision 1.17 1997/05/27 23:31:01 dettori 121** Revision 1.17 1997/05/27 23:31:01 dettori
122** Pulled out changes to DMAMODE defines. 122** Pulled out changes to DMAMODE defines.
123** 123**
124** Revision 1.16 1997/05/23 04:25:16 cgd 124** Revision 1.16 1997/05/23 04:25:16 cgd
125** reformat log so it fits in 80cols 125** reformat log so it fits in 80cols
126** 126**
127** Revision 1.15 1997/05/23 04:22:18 cgd 127** Revision 1.15 1997/05/23 04:22:18 cgd
128** remove the existing copyright notice (which Peter Dettori indicated 128** remove the existing copyright notice (which Peter Dettori indicated
129** was incorrect, copied from an existing NetBSD file only so that the 129** was incorrect, copied from an existing NetBSD file only so that the
130** file would have a copyright notice on it, and which he'd intended to 130** file would have a copyright notice on it, and which he'd intended to
131** replace). Replace it with a Digital copyright notice, cloned from 131** replace). Replace it with a Digital copyright notice, cloned from
132** ess.c. It's not really correct either (it indicates that the source 132** ess.c. It's not really correct either (it indicates that the source
133** is Digital confidential!), but is better than nothing and more 133** is Digital confidential!), but is better than nothing and more
134** correct than what was there before. 134** correct than what was there before.
135** 135**
136** Revision 1.14 1997/05/23 04:12:50 cgd 136** Revision 1.14 1997/05/23 04:12:50 cgd
137** use an adaptive transmit start algorithm: start by telling the chip 137** use an adaptive transmit start algorithm: start by telling the chip
138** to start transmitting after 381 bytes have been fed to it. if that 138** to start transmitting after 381 bytes have been fed to it. if that
139** gets transmit underruns, ramp down to 1021 bytes then "whole 139** gets transmit underruns, ramp down to 1021 bytes then "whole
140** packet." If successful at a given level for a while, try the next 140** packet." If successful at a given level for a while, try the next
141** more agressive level. This code doesn't ever try to start 141** more agressive level. This code doesn't ever try to start
142** transmitting after 5 bytes have been sent to the NIC, because 142** transmitting after 5 bytes have been sent to the NIC, because
143** that underruns rather regularly. The back-off and ramp-up mechanism 143** that underruns rather regularly. The back-off and ramp-up mechanism
144** could probably be tuned a little bit, but this works well enough to 144** could probably be tuned a little bit, but this works well enough to
145** support > 1MB/s transmit rates on a clear ethernet (which is about 145** support > 1MB/s transmit rates on a clear ethernet (which is about
146** 20-25% better than the driver had previously been getting). 146** 20-25% better than the driver had previously been getting).
147** 147**
148** Revision 1.13 1997/05/22 21:06:54 cgd 148** Revision 1.13 1997/05/22 21:06:54 cgd
149** redo cs_copy_tx_frame() from scratch. It had a fatal flaw: it was blindly 149** redo cs_copy_tx_frame() from scratch. It had a fatal flaw: it was blindly
150** casting from uint8_t * to uint16_t * without worrying about alignment 150** casting from uint8_t * to uint16_t * without worrying about alignment
151** issues. This would cause bogus data to be spit out for mbufs with 151** issues. This would cause bogus data to be spit out for mbufs with
152** misaligned data. For instance, it caused the following bits to appear 152** misaligned data. For instance, it caused the following bits to appear
153** on the wire: 153** on the wire:
154** ... etBND 1S2C .SHA(K) R ... 154** ... etBND 1S2C .SHA(K) R ...
155** 11112222333344445555 155** 11112222333344445555
156** which should have appeared as: 156** which should have appeared as:
157** ... NetBSD 1.2C (SHARK) ... 157** ... NetBSD 1.2C (SHARK) ...
158** 11112222333344445555 158** 11112222333344445555
159** Note the apparent 'rotate' of the bytes in the word, which was due to 159** Note the apparent 'rotate' of the bytes in the word, which was due to
160** incorrect unaligned accesses. This data corruption was the cause of 160** incorrect unaligned accesses. This data corruption was the cause of
161** incoming telnet/rlogin hangs. 161** incoming telnet/rlogin hangs.
162** 162**
163** Revision 1.12 1997/05/22 01:55:32 cgd 163** Revision 1.12 1997/05/22 01:55:32 cgd
164** reformat log so it fits in 80cols 164** reformat log so it fits in 80cols
165** 165**
166** Revision 1.11 1997/05/22 01:50:27 cgd 166** Revision 1.11 1997/05/22 01:50:27 cgd
167** * enable input packet address checking in the BPF+IFF_PROMISCUOUS case, 167** * enable input packet address checking in the BPF+IFF_PROMISCUOUS case,
168** so packets aimed at other hosts don't get sent to ether_input(). 168** so packets aimed at other hosts don't get sent to ether_input().
169** * Add a static const char *rcsid initialized with an RCS Id tag, so that 169** * Add a static const char *rcsid initialized with an RCS Id tag, so that
170** you can easily tell (`strings`) what version of the driver is in your 170** you can easily tell (`strings`) what version of the driver is in your
171** kernel binary. 171** kernel binary.
172** * get rid of ether_cmp(). It was inconsistently used, not necessarily 172** * get rid of ether_cmp(). It was inconsistently used, not necessarily
173** safe, and not really a performance win anyway. (It was only used when 173** safe, and not really a performance win anyway. (It was only used when
174** setting up the multicast logical address filter, which is an 174** setting up the multicast logical address filter, which is an
175** infrequent event. It could have been used in the IFF_PROMISCUOUS 175** infrequent event. It could have been used in the IFF_PROMISCUOUS
176** address check above, but the benefit of it vs. memcmp would be 176** address check above, but the benefit of it vs. memcmp would be
177** inconsequential, there.) Use memcmp() instead. 177** inconsequential, there.) Use memcmp() instead.
178** * restructure csStartOuput to avoid the following bugs in the case where 178** * restructure csStartOuput to avoid the following bugs in the case where
179** txWait was being set: 179** txWait was being set:
180** * it would accidentally drop the outgoing packet if told to wait 180** * it would accidentally drop the outgoing packet if told to wait
181** but the outgoing packet queue was empty. 181** but the outgoing packet queue was empty.
182** * it would bpf_mtap() the outgoing packet multiple times (once for 182** * it would bpf_mtap() the outgoing packet multiple times (once for
183** each time it was told to wait), and would also recalculate 183** each time it was told to wait), and would also recalculate
184** the length of the outgoing packet each time it was told to 184** the length of the outgoing packet each time it was told to
185** wait. 185** wait.
186** While there, rename txWait to txLoop, since with the new structure of 186** While there, rename txWait to txLoop, since with the new structure of
187** the code, the latter name makes more sense. 187** the code, the latter name makes more sense.
188** 188**
189** Revision 1.10 1997/05/19 02:03:20 cgd 189** Revision 1.10 1997/05/19 02:03:20 cgd
190** Set RX_CTL in cs_set_ladr_filt(), rather than cs_initChip(). cs_initChip() 190** Set RX_CTL in cs_set_ladr_filt(), rather than cs_initChip(). cs_initChip()
191** is the only caller of cs_set_ladr_filt(), and always calls it, so this 191** is the only caller of cs_set_ladr_filt(), and always calls it, so this
192** ends up being logically the same. In cs_set_ladr_filt(), if IFF_PROMISC 192** ends up being logically the same. In cs_set_ladr_filt(), if IFF_PROMISC
193** is set, enable promiscuous mode (and set IFF_ALLMULTI), otherwise behave 193** is set, enable promiscuous mode (and set IFF_ALLMULTI), otherwise behave
194** as before. 194** as before.
195** 195**
196** Revision 1.9 1997/05/19 01:45:37 cgd 196** Revision 1.9 1997/05/19 01:45:37 cgd
197** create a new function, cs_ether_input(), which does received-packet 197** create a new function, cs_ether_input(), which does received-packet
198** BPF and ether_input processing. This code used to be in three places, 198** BPF and ether_input processing. This code used to be in three places,
199** and centralizing it will make adding IFF_PROMISC support much easier. 199** and centralizing it will make adding IFF_PROMISC support much easier.
200** Also, in cs_copy_tx_frame(), put it some (currently disabled) code to 200** Also, in cs_copy_tx_frame(), put it some (currently disabled) code to
201** do copies with bus_space_write_region_2(). It's more correct, and 201** do copies with bus_space_write_region_2(). It's more correct, and
202** potentially more efficient. That function needs to be gutted (to 202** potentially more efficient. That function needs to be gutted (to
203** deal properly with alignment issues, which it currently does wrong), 203** deal properly with alignment issues, which it currently does wrong),
204** however, and the change doesn't gain much, so there's no point in 204** however, and the change doesn't gain much, so there's no point in
205** enabling it now. 205** enabling it now.
206** 206**
207** Revision 1.8 1997/05/19 01:17:10 cgd 207** Revision 1.8 1997/05/19 01:17:10 cgd
208** fix a comment re: the setting of the TxConfig register. Clean up 208** fix a comment re: the setting of the TxConfig register. Clean up
209** interface counter maintenance (make it use standard idiom). 209** interface counter maintenance (make it use standard idiom).
210** 210**
211**-- 211**--
212*/ 212*/
213 213
214#include <sys/cdefs.h> 214#include <sys/cdefs.h>
215__KERNEL_RCSID(0, "$NetBSD: cs89x0.c,v 1.47 2019/05/29 10:07:29 msaitoh Exp $"); 215__KERNEL_RCSID(0, "$NetBSD: cs89x0.c,v 1.48 2020/01/29 14:14:55 thorpej Exp $");
216 216
217#include "opt_inet.h" 217#include "opt_inet.h"
218 218
219#include <sys/param.h> 219#include <sys/param.h>
220#include <sys/systm.h> 220#include <sys/systm.h>
221#include <sys/mbuf.h> 221#include <sys/mbuf.h>
222#include <sys/syslog.h> 222#include <sys/syslog.h>
223#include <sys/socket.h> 223#include <sys/socket.h>
224#include <sys/device.h> 224#include <sys/device.h>
225#include <sys/malloc.h> 225#include <sys/malloc.h>
226#include <sys/ioctl.h> 226#include <sys/ioctl.h>
227#include <sys/errno.h> 227#include <sys/errno.h>
228#include <sys/bus.h> 228#include <sys/bus.h>
229#include <sys/intr.h> 229#include <sys/intr.h>
230#include <sys/rndsource.h> 230#include <sys/rndsource.h>
231 231
232#include <net/if.h> 232#include <net/if.h>
233#include <net/if_ether.h> 233#include <net/if_ether.h>
234#include <net/if_media.h> 234#include <net/if_media.h>
235#include <net/bpf.h> 235#include <net/bpf.h>
236 236
237#ifdef INET 237#ifdef INET
238#include <netinet/in.h> 238#include <netinet/in.h>
239#include <netinet/if_inarp.h> 239#include <netinet/if_inarp.h>
240#endif 240#endif
241 241
242#include <dev/ic/cs89x0reg.h> 242#include <dev/ic/cs89x0reg.h>
243#include <dev/ic/cs89x0var.h> 243#include <dev/ic/cs89x0var.h>
244 244
245#ifdef SHARK 245#ifdef SHARK
246#include <shark/shark/sequoia.h> 246#include <shark/shark/sequoia.h>
247#endif 247#endif
248 248
249/* 249/*
250 * MACRO DEFINITIONS 250 * MACRO DEFINITIONS
251 */ 251 */
252#define CS_OUTPUT_LOOP_MAX 100 /* max times round notorious tx loop */ 252#define CS_OUTPUT_LOOP_MAX 100 /* max times round notorious tx loop */
253 253
254/* 254/*
255 * FUNCTION PROTOTYPES 255 * FUNCTION PROTOTYPES
256 */ 256 */
257static void cs_get_default_media(struct cs_softc *); 257static void cs_get_default_media(struct cs_softc *);
258static int cs_get_params(struct cs_softc *); 258static int cs_get_params(struct cs_softc *);
259static int cs_get_enaddr(struct cs_softc *); 259static int cs_get_enaddr(struct cs_softc *);
260static int cs_reset_chip(struct cs_softc *); 260static int cs_reset_chip(struct cs_softc *);
261static void cs_reset(struct cs_softc *); 261static void cs_reset(struct cs_softc *);
262static int cs_ioctl(struct ifnet *, u_long, void *); 262static int cs_ioctl(struct ifnet *, u_long, void *);
263static void cs_initChip(struct cs_softc *); 263static void cs_initChip(struct cs_softc *);
264static void cs_buffer_event(struct cs_softc *, uint16_t); 264static void cs_buffer_event(struct cs_softc *, uint16_t);
265static void cs_transmit_event(struct cs_softc *, uint16_t); 265static void cs_transmit_event(struct cs_softc *, uint16_t);
266static void cs_receive_event(struct cs_softc *, uint16_t); 266static void cs_receive_event(struct cs_softc *, uint16_t);
267static void cs_process_receive(struct cs_softc *); 267static void cs_process_receive(struct cs_softc *);
268static void cs_process_rx_early(struct cs_softc *); 268static void cs_process_rx_early(struct cs_softc *);
269static void cs_start_output(struct ifnet *); 269static void cs_start_output(struct ifnet *);
270static void cs_copy_tx_frame(struct cs_softc *, struct mbuf *); 270static void cs_copy_tx_frame(struct cs_softc *, struct mbuf *);
271static void cs_set_ladr_filt(struct cs_softc *, struct ethercom *); 271static void cs_set_ladr_filt(struct cs_softc *, struct ethercom *);
272static uint16_t cs_hash_index(char *); 272static uint16_t cs_hash_index(char *);
273static void cs_counter_event(struct cs_softc *, uint16_t); 273static void cs_counter_event(struct cs_softc *, uint16_t);
274 274
275static int cs_mediachange(struct ifnet *); 275static int cs_mediachange(struct ifnet *);
276static void cs_mediastatus(struct ifnet *, struct ifmediareq *); 276static void cs_mediastatus(struct ifnet *, struct ifmediareq *);
277 277
278static bool cs_shutdown(device_t, int); 278static bool cs_shutdown(device_t, int);
279static int cs_enable(struct cs_softc *); 279static int cs_enable(struct cs_softc *);
280static void cs_disable(struct cs_softc *); 280static void cs_disable(struct cs_softc *);
281static void cs_stop(struct ifnet *, int); 281static void cs_stop(struct ifnet *, int);
282static int cs_scan_eeprom(struct cs_softc *); 282static int cs_scan_eeprom(struct cs_softc *);
283static int cs_read_pktpg_from_eeprom(struct cs_softc *, int, uint16_t *); 283static int cs_read_pktpg_from_eeprom(struct cs_softc *, int, uint16_t *);
284 284
285 285
286/* 286/*
287 * GLOBAL DECLARATIONS 287 * GLOBAL DECLARATIONS
288 */ 288 */
289 289
290/* 290/*
291 * Xmit-early table. 291 * Xmit-early table.
292 * 292 *
293 * To get better performance, we tell the chip to start packet 293 * To get better performance, we tell the chip to start packet
294 * transmission before the whole packet is copied to the chip. 294 * transmission before the whole packet is copied to the chip.
295 * However, this can fail under load. When it fails, we back off 295 * However, this can fail under load. When it fails, we back off
296 * to a safer setting for a little while. 296 * to a safer setting for a little while.
297 * 297 *
298 * txcmd is the value of txcmd used to indicate when to start transmission. 298 * txcmd is the value of txcmd used to indicate when to start transmission.
299 * better is the next 'better' state in the table. 299 * better is the next 'better' state in the table.
300 * better_count is the number of output packets before transition to the 300 * better_count is the number of output packets before transition to the
301 * better state. 301 * better state.
302 * worse is the next 'worse' state in the table. 302 * worse is the next 'worse' state in the table.
303 * 303 *
304 * Transition to the next worse state happens automatically when a 304 * Transition to the next worse state happens automatically when a
305 * transmittion underrun occurs. 305 * transmittion underrun occurs.
306 */ 306 */
307struct cs_xmit_early { 307struct cs_xmit_early {
308 uint16_t txcmd; 308 uint16_t txcmd;
309 int better; 309 int better;
310 int better_count; 310 int better_count;
311 int worse; 311 int worse;
312} cs_xmit_early_table[3] = { 312} cs_xmit_early_table[3] = {
313 { TX_CMD_START_381, 0, INT_MAX, 1, }, 313 { TX_CMD_START_381, 0, INT_MAX, 1, },
314 { TX_CMD_START_1021, 0, 50000, 2, }, 314 { TX_CMD_START_1021, 0, 50000, 2, },
315 { TX_CMD_START_ALL, 1, 5000, 2, }, 315 { TX_CMD_START_ALL, 1, 5000, 2, },
316}; 316};
317 317
318int cs_default_media[] = { 318int cs_default_media[] = {
319 IFM_ETHER | IFM_10_2, 319 IFM_ETHER | IFM_10_2,
320 IFM_ETHER | IFM_10_5, 320 IFM_ETHER | IFM_10_5,
321 IFM_ETHER | IFM_10_T, 321 IFM_ETHER | IFM_10_T,
322 IFM_ETHER | IFM_10_T | IFM_FDX, 322 IFM_ETHER | IFM_10_T | IFM_FDX,
323}; 323};
324int cs_default_nmedia = __arraycount(cs_default_media); 324int cs_default_nmedia = __arraycount(cs_default_media);
325 325
326int 326int
327cs_attach(struct cs_softc *sc, uint8_t *enaddr, int *media, 327cs_attach(struct cs_softc *sc, uint8_t *enaddr, int *media,
328 int nmedia, int defmedia) 328 int nmedia, int defmedia)
329{ 329{
330 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 330 struct ifnet *ifp = &sc->sc_ethercom.ec_if;
331 const char *chipname, *medname; 331 const char *chipname, *medname;
332 uint16_t reg; 332 uint16_t reg;
333 int i; 333 int i;
334 334
335 /* Start out in IO mode */ 335 /* Start out in IO mode */
336 sc->sc_memorymode = FALSE; 336 sc->sc_memorymode = FALSE;
337 337
338 /* Make sure we're right */ 338 /* Make sure we're right */
339 for (i = 0; i < 10000; i++) { 339 for (i = 0; i < 10000; i++) {
340 reg = CS_READ_PACKET_PAGE(sc, PKTPG_EISA_NUM); 340 reg = CS_READ_PACKET_PAGE(sc, PKTPG_EISA_NUM);
341 if (reg == EISA_NUM_CRYSTAL) 341 if (reg == EISA_NUM_CRYSTAL)
342 break; 342 break;
343 } 343 }
344 if (i == 10000) { 344 if (i == 10000) {
345 aprint_error_dev(sc->sc_dev, "wrong id(0x%x)\n", reg); 345 aprint_error_dev(sc->sc_dev, "wrong id(0x%x)\n", reg);
346 return 1; /* XXX should panic? */ 346 return 1; /* XXX should panic? */
347 } 347 }
348 348
349 reg = CS_READ_PACKET_PAGE(sc, PKTPG_PRODUCT_ID); 349 reg = CS_READ_PACKET_PAGE(sc, PKTPG_PRODUCT_ID);
350 sc->sc_prodid = reg & PROD_ID_MASK; 350 sc->sc_prodid = reg & PROD_ID_MASK;
351 sc->sc_prodrev = (reg & PROD_REV_MASK) >> 8; 351 sc->sc_prodrev = (reg & PROD_REV_MASK) >> 8;
352 352
353 switch (sc->sc_prodid) { 353 switch (sc->sc_prodid) {
354 case PROD_ID_CS8900: 354 case PROD_ID_CS8900:
355 chipname = "CS8900"; 355 chipname = "CS8900";
356 break; 356 break;
357 case PROD_ID_CS8920: 357 case PROD_ID_CS8920:
358 chipname = "CS8920"; 358 chipname = "CS8920";
359 break; 359 break;
360 case PROD_ID_CS8920M: 360 case PROD_ID_CS8920M:
361 chipname = "CS8920M"; 361 chipname = "CS8920M";
362 break; 362 break;
363 default: 363 default:
364 panic("cs_attach: impossible"); 364 panic("cs_attach: impossible");
365 } 365 }
366 366
367 /* 367 /*
368 * The first thing to do is check that the mbuf cluster size is 368 * The first thing to do is check that the mbuf cluster size is
369 * greater than the MTU for an ethernet frame. The code depends on 369 * greater than the MTU for an ethernet frame. The code depends on
370 * this and to port this to a OS where this was not the case would 370 * this and to port this to a OS where this was not the case would
371 * not be straightforward. 371 * not be straightforward.
372 * 372 *
373 * We need 1 byte spare because our packet read loop can overrun. 373 * We need 1 byte spare because our packet read loop can overrun.
374 * and we may need pad bytes to align ip header. 374 * and we may need pad bytes to align ip header.
375 */ 375 */
376 if (MCLBYTES < ETHER_MAX_LEN + 1 + ALIGN(sizeof(struct ether_header)) 376 if (MCLBYTES < ETHER_MAX_LEN + 1 + ALIGN(sizeof(struct ether_header))
377 - sizeof(struct ether_header)) { 377 - sizeof(struct ether_header)) {
378 printf("%s: MCLBYTES too small for Ethernet frame\n", 378 printf("%s: MCLBYTES too small for Ethernet frame\n",
379 device_xname(sc->sc_dev)); 379 device_xname(sc->sc_dev));
380 return 1; 380 return 1;
381 } 381 }
382 382
383 /* Start out not transmitting */ 383 /* Start out not transmitting */
384 sc->sc_txbusy = FALSE; 384 sc->sc_txbusy = FALSE;
385 385
386 /* Set up early transmit threshhold */ 386 /* Set up early transmit threshhold */
387 sc->sc_xe_ent = 0; 387 sc->sc_xe_ent = 0;
388 sc->sc_xe_togo = cs_xmit_early_table[sc->sc_xe_ent].better_count; 388 sc->sc_xe_togo = cs_xmit_early_table[sc->sc_xe_ent].better_count;
389 389
390 /* Initialize ifnet structure. */ 390 /* Initialize ifnet structure. */
391 strlcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ); 391 strlcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ);
392 ifp->if_softc = sc; 392 ifp->if_softc = sc;
393 ifp->if_start = cs_start_output; 393 ifp->if_start = cs_start_output;
394 ifp->if_init = cs_init; 394 ifp->if_init = cs_init;
395 ifp->if_ioctl = cs_ioctl; 395 ifp->if_ioctl = cs_ioctl;
396 ifp->if_stop = cs_stop; 396 ifp->if_stop = cs_stop;
397 ifp->if_watchdog = NULL; /* No watchdog at this stage */ 397 ifp->if_watchdog = NULL; /* No watchdog at this stage */
398 ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST; 398 ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST;
399 IFQ_SET_READY(&ifp->if_snd); 399 IFQ_SET_READY(&ifp->if_snd);
400 400
401 /* Initialize ifmedia structures. */ 401 /* Initialize ifmedia structures. */
402 sc->sc_ethercom.ec_ifmedia = &sc->sc_media; 402 sc->sc_ethercom.ec_ifmedia = &sc->sc_media;
403 ifmedia_init(&sc->sc_media, 0, cs_mediachange, cs_mediastatus); 403 ifmedia_init(&sc->sc_media, 0, cs_mediachange, cs_mediastatus);
404 404
405 if (media != NULL) { 405 if (media != NULL) {
406 for (i = 0; i < nmedia; i++) 406 for (i = 0; i < nmedia; i++)
407 ifmedia_add(&sc->sc_media, media[i], 0, NULL); 407 ifmedia_add(&sc->sc_media, media[i], 0, NULL);
408 ifmedia_set(&sc->sc_media, defmedia); 408 ifmedia_set(&sc->sc_media, defmedia);
409 } else { 409 } else {
410 for (i = 0; i < cs_default_nmedia; i++) 410 for (i = 0; i < cs_default_nmedia; i++)
411 ifmedia_add(&sc->sc_media, cs_default_media[i], 411 ifmedia_add(&sc->sc_media, cs_default_media[i],
412 0, NULL); 412 0, NULL);
413 cs_get_default_media(sc); 413 cs_get_default_media(sc);
414 } 414 }
415 415
416 if (sc->sc_cfgflags & CFGFLG_PARSE_EEPROM) { 416 if (sc->sc_cfgflags & CFGFLG_PARSE_EEPROM) {
417 if (cs_scan_eeprom(sc) == CS_ERROR) { 417 if (cs_scan_eeprom(sc) == CS_ERROR) {
418 /* 418 /*
419 * Failed to scan the eeprom, pretend there isn't an 419 * Failed to scan the eeprom, pretend there isn't an
420 * eeprom 420 * eeprom
421 */ 421 */
422 aprint_error_dev(sc->sc_dev, 422 aprint_error_dev(sc->sc_dev,
423 "unable to scan EEPROM\n"); 423 "unable to scan EEPROM\n");
424 sc->sc_cfgflags |= CFGFLG_NOT_EEPROM; 424 sc->sc_cfgflags |= CFGFLG_NOT_EEPROM;
425 } 425 }
426 } 426 }
427 427
428 if ((sc->sc_cfgflags & CFGFLG_NOT_EEPROM) == 0) { 428 if ((sc->sc_cfgflags & CFGFLG_NOT_EEPROM) == 0) {
429 /* Get parameters from the EEPROM */ 429 /* Get parameters from the EEPROM */
430 if (cs_get_params(sc) == CS_ERROR) { 430 if (cs_get_params(sc) == CS_ERROR) {
431 aprint_error_dev(sc->sc_dev, 431 aprint_error_dev(sc->sc_dev,
432 "unable to get settings from EEPROM\n"); 432 "unable to get settings from EEPROM\n");
433 return 1; 433 return 1;
434 } 434 }
435 } 435 }
436 436
437 if (enaddr != NULL) 437 if (enaddr != NULL)
438 memcpy(sc->sc_enaddr, enaddr, sizeof(sc->sc_enaddr)); 438 memcpy(sc->sc_enaddr, enaddr, sizeof(sc->sc_enaddr));
439 else if ((sc->sc_cfgflags & CFGFLG_NOT_EEPROM) == 0) { 439 else if ((sc->sc_cfgflags & CFGFLG_NOT_EEPROM) == 0) {
440 /* Get and store the Ethernet address */ 440 /* Get and store the Ethernet address */
441 if (cs_get_enaddr(sc) == CS_ERROR) { 441 if (cs_get_enaddr(sc) == CS_ERROR) {
442 aprint_error_dev(sc->sc_dev, 442 aprint_error_dev(sc->sc_dev,
443 "unable to read Ethernet address\n"); 443 "unable to read Ethernet address\n");
444 return 1; 444 return 1;
445 } 445 }
446 } else { 446 } else {
447#if 1 447#if 1
448 int j; 448 int j;
449 uint v; 449 uint v;
450 450
451 for (j = 0; j < 6; j += 2) { 451 for (j = 0; j < 6; j += 2) {
452 v = CS_READ_PACKET_PAGE(sc, PKTPG_IND_ADDR + j); 452 v = CS_READ_PACKET_PAGE(sc, PKTPG_IND_ADDR + j);
453 sc->sc_enaddr[j + 0] = v; 453 sc->sc_enaddr[j + 0] = v;
454 sc->sc_enaddr[j + 1] = v >> 8; 454 sc->sc_enaddr[j + 1] = v >> 8;
455 } 455 }
456#else 456#else
457 printf("%s: no Ethernet address!\n", device_xname(sc->sc_dev)); 457 printf("%s: no Ethernet address!\n", device_xname(sc->sc_dev));
458 return 1; 458 return 1;
459#endif 459#endif
460 } 460 }
461 461
462 switch (IFM_SUBTYPE(sc->sc_media.ifm_cur->ifm_media)) { 462 switch (IFM_SUBTYPE(sc->sc_media.ifm_cur->ifm_media)) {
463 case IFM_10_2: 463 case IFM_10_2:
464 medname = "BNC"; 464 medname = "BNC";
465 break; 465 break;
466 case IFM_10_5: 466 case IFM_10_5:
467 medname = "AUI"; 467 medname = "AUI";
468 break; 468 break;
469 case IFM_10_T: 469 case IFM_10_T:
470 if (sc->sc_media.ifm_cur->ifm_media & IFM_FDX) 470 if (sc->sc_media.ifm_cur->ifm_media & IFM_FDX)
471 medname = "UTP <full-duplex>"; 471 medname = "UTP <full-duplex>";
472 else 472 else
473 medname = "UTP"; 473 medname = "UTP";
474 break; 474 break;
475 default: 475 default:
476 panic("cs_attach: impossible"); 476 panic("cs_attach: impossible");
477 } 477 }
478 printf("%s: %s rev. %c, address %s, media %s\n", 478 printf("%s: %s rev. %c, address %s, media %s\n",
479 device_xname(sc->sc_dev), 479 device_xname(sc->sc_dev),
480 chipname, sc->sc_prodrev + 'A', ether_sprintf(sc->sc_enaddr), 480 chipname, sc->sc_prodrev + 'A', ether_sprintf(sc->sc_enaddr),
481 medname); 481 medname);
482 482
483 if (sc->sc_dma_attach) 483 if (sc->sc_dma_attach)
484 (*sc->sc_dma_attach)(sc); 484 (*sc->sc_dma_attach)(sc);
485 485
486 /* Attach the interface. */ 486 /* Attach the interface. */
487 if_attach(ifp); 487 if_attach(ifp);
488 if_deferred_start_init(ifp, NULL); 488 if_deferred_start_init(ifp, NULL);
489 ether_ifattach(ifp, sc->sc_enaddr); 489 ether_ifattach(ifp, sc->sc_enaddr);
490 490
491 rnd_attach_source(&sc->rnd_source, device_xname(sc->sc_dev), 491 rnd_attach_source(&sc->rnd_source, device_xname(sc->sc_dev),
492 RND_TYPE_NET, RND_FLAG_DEFAULT); 492 RND_TYPE_NET, RND_FLAG_DEFAULT);
493 sc->sc_cfgflags |= CFGFLG_ATTACHED; 493 sc->sc_cfgflags |= CFGFLG_ATTACHED;
494 494
495 if (pmf_device_register1(sc->sc_dev, NULL, NULL, cs_shutdown)) 495 if (pmf_device_register1(sc->sc_dev, NULL, NULL, cs_shutdown))
496 pmf_class_network_register(sc->sc_dev, ifp); 496 pmf_class_network_register(sc->sc_dev, ifp);
497 else 497 else
498 aprint_error_dev(sc->sc_dev, 498 aprint_error_dev(sc->sc_dev,
499 "couldn't establish power handler\n"); 499 "couldn't establish power handler\n");
500 500
501 /* Reset the chip */ 501 /* Reset the chip */
502 if (cs_reset_chip(sc) == CS_ERROR) { 502 if (cs_reset_chip(sc) == CS_ERROR) {
503 aprint_error_dev(sc->sc_dev, "reset failed\n"); 503 aprint_error_dev(sc->sc_dev, "reset failed\n");
504 cs_detach(sc); 504 cs_detach(sc);
505 return 1; 505 return 1;
506 } 506 }
507 507
508 return 0; 508 return 0;
509} 509}
510 510
511int 511int
512cs_detach(struct cs_softc *sc) 512cs_detach(struct cs_softc *sc)
513{ 513{
514 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 514 struct ifnet *ifp = &sc->sc_ethercom.ec_if;
515 515
516 if (sc->sc_cfgflags & CFGFLG_ATTACHED) { 516 if (sc->sc_cfgflags & CFGFLG_ATTACHED) {
517 rnd_detach_source(&sc->rnd_source); 517 rnd_detach_source(&sc->rnd_source);
518 ether_ifdetach(ifp); 518 ether_ifdetach(ifp);
519 if_detach(ifp); 519 if_detach(ifp);
520 sc->sc_cfgflags &= ~CFGFLG_ATTACHED; 520 sc->sc_cfgflags &= ~CFGFLG_ATTACHED;
521 } 521 }
522 522
523#if 0 523#if 0
524 /* XXX not necessary */ 524 /* XXX not necessary */
525 if (sc->sc_cfgflags & CFGFLG_DMA_MODE) { 525 if (sc->sc_cfgflags & CFGFLG_DMA_MODE) {
526 isa_dmamem_unmap(sc->sc_ic, sc->sc_drq, sc->sc_dmabase, 526 isa_dmamem_unmap(sc->sc_ic, sc->sc_drq, sc->sc_dmabase,
527 sc->sc_dmasize); 527 sc->sc_dmasize);
528 isa_dmamem_free(sc->sc_ic, sc->sc_drq, sc->sc_dmaaddr, 528 isa_dmamem_free(sc->sc_ic, sc->sc_drq, sc->sc_dmaaddr,
529 sc->sc_dmasize); 529 sc->sc_dmasize);
530 isa_dmamap_destroy(sc->sc_ic, sc->sc_drq); 530 isa_dmamap_destroy(sc->sc_ic, sc->sc_drq);
531 sc->sc_cfgflags &= ~CFGFLG_DMA_MODE; 531 sc->sc_cfgflags &= ~CFGFLG_DMA_MODE;
532 } 532 }
533#endif 533#endif
534 534
535 pmf_device_deregister(sc->sc_dev); 535 pmf_device_deregister(sc->sc_dev);
536 536
537 return 0; 537 return 0;
538} 538}
539 539
540bool 540bool
541cs_shutdown(device_t self, int howto) 541cs_shutdown(device_t self, int howto)
542{ 542{
543 struct cs_softc *sc; 543 struct cs_softc *sc;
544 544
545 sc = device_private(self); 545 sc = device_private(self);
546 cs_reset(sc); 546 cs_reset(sc);
547 547
548 return true; 548 return true;
549} 549}
550 550
551void 551void
552cs_get_default_media(struct cs_softc *sc) 552cs_get_default_media(struct cs_softc *sc)
553{ 553{
554 uint16_t adp_cfg, xmit_ctl; 554 uint16_t adp_cfg, xmit_ctl;
555 555
556 if (cs_verify_eeprom(sc) == CS_ERROR) { 556 if (cs_verify_eeprom(sc) == CS_ERROR) {
557 aprint_error_dev(sc->sc_dev, 557 aprint_error_dev(sc->sc_dev,
558 "cs_get_default_media: EEPROM missing or bad\n"); 558 "cs_get_default_media: EEPROM missing or bad\n");
559 goto fakeit; 559 goto fakeit;
560 } 560 }
561 561
562 if (cs_read_eeprom(sc, EEPROM_ADPTR_CFG, &adp_cfg) == CS_ERROR) { 562 if (cs_read_eeprom(sc, EEPROM_ADPTR_CFG, &adp_cfg) == CS_ERROR) {
563 aprint_error_dev(sc->sc_dev, 563 aprint_error_dev(sc->sc_dev,
564 "unable to read adapter config from EEPROM\n"); 564 "unable to read adapter config from EEPROM\n");
565 goto fakeit; 565 goto fakeit;
566 } 566 }
567 567
568 if (cs_read_eeprom(sc, EEPROM_XMIT_CTL, &xmit_ctl) == CS_ERROR) { 568 if (cs_read_eeprom(sc, EEPROM_XMIT_CTL, &xmit_ctl) == CS_ERROR) {
569 aprint_error_dev(sc->sc_dev, 569 aprint_error_dev(sc->sc_dev,
570 "unable to read transmit control from EEPROM\n"); 570 "unable to read transmit control from EEPROM\n");
571 goto fakeit; 571 goto fakeit;
572 } 572 }
573 573
574 switch (adp_cfg & ADPTR_CFG_MEDIA) { 574 switch (adp_cfg & ADPTR_CFG_MEDIA) {
575 case ADPTR_CFG_AUI: 575 case ADPTR_CFG_AUI:
576 ifmedia_set(&sc->sc_media, IFM_ETHER | IFM_10_5); 576 ifmedia_set(&sc->sc_media, IFM_ETHER | IFM_10_5);
577 break; 577 break;
578 case ADPTR_CFG_10BASE2: 578 case ADPTR_CFG_10BASE2:
579 ifmedia_set(&sc->sc_media, IFM_ETHER | IFM_10_2); 579 ifmedia_set(&sc->sc_media, IFM_ETHER | IFM_10_2);
580 break; 580 break;
581 case ADPTR_CFG_10BASET: 581 case ADPTR_CFG_10BASET:
582 default: 582 default:
583 if (xmit_ctl & XMIT_CTL_FDX) 583 if (xmit_ctl & XMIT_CTL_FDX)
584 ifmedia_set(&sc->sc_media, IFM_ETHER | IFM_10_T 584 ifmedia_set(&sc->sc_media, IFM_ETHER | IFM_10_T
585 | IFM_FDX); 585 | IFM_FDX);
586 else 586 else
587 ifmedia_set(&sc->sc_media, IFM_ETHER | IFM_10_T); 587 ifmedia_set(&sc->sc_media, IFM_ETHER | IFM_10_T);
588 break; 588 break;
589 } 589 }
590 return; 590 return;
591 591
592 fakeit: 592 fakeit:
593 aprint_error_dev(sc->sc_dev, 593 aprint_error_dev(sc->sc_dev,
594 "WARNING: default media setting may be inaccurate\n"); 594 "WARNING: default media setting may be inaccurate\n");
595 /* XXX Arbitrary... */ 595 /* XXX Arbitrary... */
596 ifmedia_set(&sc->sc_media, IFM_ETHER | IFM_10_T); 596 ifmedia_set(&sc->sc_media, IFM_ETHER | IFM_10_T);
597} 597}
598 598
599/* 599/*
600 * cs_scan_eeprom 600 * cs_scan_eeprom
601 * 601 *
602 * Attempt to take a complete copy of the eeprom into main memory. 602 * Attempt to take a complete copy of the eeprom into main memory.
603 * this will allow faster parsing of the eeprom data. 603 * this will allow faster parsing of the eeprom data.
604 * 604 *
605 * Only tested against a 8920M's eeprom, but the data sheet for the 605 * Only tested against a 8920M's eeprom, but the data sheet for the
606 * 8920A indicates that is uses the same layout. 606 * 8920A indicates that is uses the same layout.
607 */ 607 */
608int 608int
609cs_scan_eeprom(struct cs_softc *sc) 609cs_scan_eeprom(struct cs_softc *sc)
610{ 610{
611 uint16_t result; 611 uint16_t result;
612 int i; 612 int i;
613 int eeprom_size; 613 int eeprom_size;
614 uint8_t checksum = 0; 614 uint8_t checksum = 0;
615 615
616 if (cs_verify_eeprom(sc) == CS_ERROR) { 616 if (cs_verify_eeprom(sc) == CS_ERROR) {
617 aprint_error_dev(sc->sc_dev, 617 aprint_error_dev(sc->sc_dev,
618 "cs_scan_params: EEPROM missing or bad\n"); 618 "cs_scan_params: EEPROM missing or bad\n");
619 return CS_ERROR; 619 return CS_ERROR;
620 } 620 }
621 621
622 /* 622 /*
623 * Read the 0th word from the eeprom, it will tell us the length 623 * Read the 0th word from the eeprom, it will tell us the length
624 * and if the eeprom is valid 624 * and if the eeprom is valid
625 */ 625 */
626 cs_read_eeprom(sc, 0, &result); 626 cs_read_eeprom(sc, 0, &result);
627 627
628 /* Check the eeprom signature */ 628 /* Check the eeprom signature */
629 if ((result & 0xE000) != 0xA000) { 629 if ((result & 0xE000) != 0xA000) {
630 /* Empty eeprom */ 630 /* Empty eeprom */
631 return CS_ERROR; 631 return CS_ERROR;
632 } 632 }
633 633
634 /* 634 /*
635 * Take the eeprom size (note the read value doesn't include the header 635 * Take the eeprom size (note the read value doesn't include the header
636 * word) 636 * word)
637 */ 637 */
638 eeprom_size = (result & 0xff) + 2; 638 eeprom_size = (result & 0xff) + 2;
639 639
640 sc->eeprom_data = malloc(eeprom_size, M_DEVBUF, M_WAITOK); 640 sc->eeprom_data = malloc(eeprom_size, M_DEVBUF, M_WAITOK);
641 if (sc->eeprom_data == NULL) { 641 if (sc->eeprom_data == NULL) {
642 /* No memory, treat this as if there's no eeprom */ 642 /* No memory, treat this as if there's no eeprom */
643 return CS_ERROR; 643 return CS_ERROR;
644 } 644 }
645 645
646 sc->eeprom_size = eeprom_size; 646 sc->eeprom_size = eeprom_size;
647 647
648 /* Read the eeprom into the buffer, also calculate the checksum */ 648 /* Read the eeprom into the buffer, also calculate the checksum */
649 for (i = 0; i < (eeprom_size >> 1); i++) { 649 for (i = 0; i < (eeprom_size >> 1); i++) {
650 cs_read_eeprom(sc, i, &(sc->eeprom_data[i])); 650 cs_read_eeprom(sc, i, &(sc->eeprom_data[i]));
651 checksum += (sc->eeprom_data[i] & 0xff00) >> 8; 651 checksum += (sc->eeprom_data[i] & 0xff00) >> 8;
652 checksum += (sc->eeprom_data[i] & 0x00ff); 652 checksum += (sc->eeprom_data[i] & 0x00ff);
653 } 653 }
654 654
655 /* 655 /*
656 * Validate checksum calculation, the sum of all the bytes should be 0, 656 * Validate checksum calculation, the sum of all the bytes should be 0,
657 * as the high byte of the last word is the 2's complement of the 657 * as the high byte of the last word is the 2's complement of the
658 * sum to that point. 658 * sum to that point.
659 */ 659 */
660 if (checksum != 0) { 660 if (checksum != 0) {
661 aprint_error_dev(sc->sc_dev, "eeprom checksum failure\n"); 661 aprint_error_dev(sc->sc_dev, "eeprom checksum failure\n");
662 return CS_ERROR; 662 return CS_ERROR;
663 } 663 }
664 664
665 return CS_OK; 665 return CS_OK;
666} 666}
667 667
668static int 668static int
669cs_read_pktpg_from_eeprom(struct cs_softc *sc, int pktpg, uint16_t *pValue) 669cs_read_pktpg_from_eeprom(struct cs_softc *sc, int pktpg, uint16_t *pValue)
670{ 670{
671 int x, maxword; 671 int x, maxword;
672 672
673 /* Check that we have eeprom data */ 673 /* Check that we have eeprom data */
674 if ((sc->eeprom_data == NULL) || (sc->eeprom_size < 2)) 674 if ((sc->eeprom_data == NULL) || (sc->eeprom_size < 2))
675 return CS_ERROR; 675 return CS_ERROR;
676 676
677 /* 677 /*
678 * We only want to read the data words, the last word contains the 678 * We only want to read the data words, the last word contains the
679 * checksum 679 * checksum
680 */ 680 */
681 maxword = (sc->eeprom_size - 2) >> 1; 681 maxword = (sc->eeprom_size - 2) >> 1;
682 682
683 /* Start 1 word in, as the first word is the length and signature */ 683 /* Start 1 word in, as the first word is the length and signature */
684 x = 1; 684 x = 1;
685 685
686 while ( x < (maxword)) { 686 while ( x < (maxword)) {
687 uint16_t header; 687 uint16_t header;
688 int group_size; 688 int group_size;
689 int offset; 689 int offset;
690 int offset_max; 690 int offset_max;
691 691
692 /* Read in the group header word */ 692 /* Read in the group header word */
693 header = sc->eeprom_data[x]; 693 header = sc->eeprom_data[x];
694 x++; /* Skip group header */ 694 x++; /* Skip group header */
695 695
696 /* 696 /*
697 * Size of group in words is in the top 4 bits, note that it 697 * Size of group in words is in the top 4 bits, note that it
698 * is one less than the number of words 698 * is one less than the number of words
699 */ 699 */
700 group_size = header & 0xF000; 700 group_size = header & 0xF000;
701 701
702 /* 702 /*
703 * CS8900 Data sheet says this should be 0x01ff, 703 * CS8900 Data sheet says this should be 0x01ff,
704 * but my cs8920 eeprom has higher offsets, 704 * but my cs8920 eeprom has higher offsets,
705 * perhaps the 8920 allows higher offsets, otherwise 705 * perhaps the 8920 allows higher offsets, otherwise
706 * it's writing to places that it shouldn't 706 * it's writing to places that it shouldn't
707 */ 707 */
708 /* Work out the offsets this group covers */ 708 /* Work out the offsets this group covers */
709 offset = header & 0x0FFF; 709 offset = header & 0x0FFF;
710 offset_max = offset + (group_size << 1); 710 offset_max = offset + (group_size << 1);
711 711
712 /* Check if the pkgpg we're after is in this group */ 712 /* Check if the pkgpg we're after is in this group */
713 if ((offset <= pktpg) && (pktpg <= offset_max)) { 713 if ((offset <= pktpg) && (pktpg <= offset_max)) {
714 /* The pkgpg value we want is in here */ 714 /* The pkgpg value we want is in here */
715 int eeprom_location; 715 int eeprom_location;
716 716
717 eeprom_location = ((pktpg - offset) >> 1) ; 717 eeprom_location = ((pktpg - offset) >> 1) ;
718 718
719 *pValue = sc->eeprom_data[x + eeprom_location]; 719 *pValue = sc->eeprom_data[x + eeprom_location];
720 return CS_OK; 720 return CS_OK;
721 } else { 721 } else {
722 /* Skip this group (+ 1 for first entry) */ 722 /* Skip this group (+ 1 for first entry) */
723 x += group_size + 1; 723 x += group_size + 1;
724 } 724 }
725 } 725 }
726 726
727 /* 727 /*
728 * If we've fallen out here then we don't have a value in the EEPROM 728 * If we've fallen out here then we don't have a value in the EEPROM
729 * for this pktpg so return an error 729 * for this pktpg so return an error
730 */ 730 */
731 return CS_ERROR; 731 return CS_ERROR;
732} 732}
733 733
734int 734int
735cs_get_params(struct cs_softc *sc) 735cs_get_params(struct cs_softc *sc)
736{ 736{
737 uint16_t isaConfig; 737 uint16_t isaConfig;
738 uint16_t adapterConfig; 738 uint16_t adapterConfig;
739 739
740 if (cs_verify_eeprom(sc) == CS_ERROR) { 740 if (cs_verify_eeprom(sc) == CS_ERROR) {
741 aprint_error_dev(sc->sc_dev, 741 aprint_error_dev(sc->sc_dev,
742 "cs_get_params: EEPROM missing or bad\n"); 742 "cs_get_params: EEPROM missing or bad\n");
743 return CS_ERROR; 743 return CS_ERROR;
744 } 744 }
745 745
746 if (sc->sc_cfgflags & CFGFLG_PARSE_EEPROM) { 746 if (sc->sc_cfgflags & CFGFLG_PARSE_EEPROM) {
747 /* Get ISA configuration from the EEPROM */ 747 /* Get ISA configuration from the EEPROM */
748 if (cs_read_pktpg_from_eeprom(sc, PKTPG_BUS_CTL, &isaConfig) 748 if (cs_read_pktpg_from_eeprom(sc, PKTPG_BUS_CTL, &isaConfig)
749 == CS_ERROR) { 749 == CS_ERROR) {
750 /* 750 /*
751 * Eeprom doesn't have this value, use data sheet 751 * Eeprom doesn't have this value, use data sheet
752 * default 752 * default
753 */ 753 */
754 isaConfig = 0x0017; 754 isaConfig = 0x0017;
755 } 755 }
756 756
757 /* Get adapter configuration from the EEPROM */ 757 /* Get adapter configuration from the EEPROM */
758 if (cs_read_pktpg_from_eeprom(sc, PKTPG_SELF_CTL, 758 if (cs_read_pktpg_from_eeprom(sc, PKTPG_SELF_CTL,
759 &adapterConfig) == CS_ERROR) { 759 &adapterConfig) == CS_ERROR) {
760 /* 760 /*
761 * Eeprom doesn't have this value, use data sheet 761 * Eeprom doesn't have this value, use data sheet
762 * default 762 * default
763 */ 763 */
764 adapterConfig = 0x0015; 764 adapterConfig = 0x0015;
765 } 765 }
766 766
767 /* Copy the USE_SA flag */ 767 /* Copy the USE_SA flag */
768 if (isaConfig & BUS_CTL_USE_SA) 768 if (isaConfig & BUS_CTL_USE_SA)
769 sc->sc_cfgflags |= CFGFLG_USE_SA; 769 sc->sc_cfgflags |= CFGFLG_USE_SA;
770 770
771 /* Copy the IO Channel Ready flag */ 771 /* Copy the IO Channel Ready flag */
772 if (isaConfig & BUS_CTL_IOCHRDY) 772 if (isaConfig & BUS_CTL_IOCHRDY)
773 sc->sc_cfgflags |= CFGFLG_IOCHRDY; 773 sc->sc_cfgflags |= CFGFLG_IOCHRDY;
774 774
775 /* Copy the DC/DC Polarity flag */ 775 /* Copy the DC/DC Polarity flag */
776 if (adapterConfig & SELF_CTL_HCB1) 776 if (adapterConfig & SELF_CTL_HCB1)
777 sc->sc_cfgflags |= CFGFLG_DCDC_POL; 777 sc->sc_cfgflags |= CFGFLG_DCDC_POL;
778 } else { 778 } else {
779 /* Get ISA configuration from the EEPROM */ 779 /* Get ISA configuration from the EEPROM */
780 if (cs_read_eeprom(sc, EEPROM_ISA_CFG, &isaConfig) == CS_ERROR) 780 if (cs_read_eeprom(sc, EEPROM_ISA_CFG, &isaConfig) == CS_ERROR)
781 goto eeprom_bad; 781 goto eeprom_bad;
782 782
783 /* Get adapter configuration from the EEPROM */ 783 /* Get adapter configuration from the EEPROM */
784 if (cs_read_eeprom(sc, EEPROM_ADPTR_CFG, &adapterConfig) 784 if (cs_read_eeprom(sc, EEPROM_ADPTR_CFG, &adapterConfig)
785 == CS_ERROR) 785 == CS_ERROR)
786 goto eeprom_bad; 786 goto eeprom_bad;
787 787
788 /* Copy the USE_SA flag */ 788 /* Copy the USE_SA flag */
789 if (isaConfig & ISA_CFG_USE_SA) 789 if (isaConfig & ISA_CFG_USE_SA)
790 sc->sc_cfgflags |= CFGFLG_USE_SA; 790 sc->sc_cfgflags |= CFGFLG_USE_SA;
791 791
792 /* Copy the IO Channel Ready flag */ 792 /* Copy the IO Channel Ready flag */
793 if (isaConfig & ISA_CFG_IOCHRDY) 793 if (isaConfig & ISA_CFG_IOCHRDY)
794 sc->sc_cfgflags |= CFGFLG_IOCHRDY; 794 sc->sc_cfgflags |= CFGFLG_IOCHRDY;
795 795
796 /* Copy the DC/DC Polarity flag */ 796 /* Copy the DC/DC Polarity flag */
797 if (adapterConfig & ADPTR_CFG_DCDC_POL) 797 if (adapterConfig & ADPTR_CFG_DCDC_POL)
798 sc->sc_cfgflags |= CFGFLG_DCDC_POL; 798 sc->sc_cfgflags |= CFGFLG_DCDC_POL;
799 } 799 }
800 800
801 return CS_OK; 801 return CS_OK;
802eeprom_bad: 802eeprom_bad:
803 aprint_error_dev(sc->sc_dev, 803 aprint_error_dev(sc->sc_dev,
804 "cs_get_params: unable to read from EEPROM\n"); 804 "cs_get_params: unable to read from EEPROM\n");
805 return CS_ERROR; 805 return CS_ERROR;
806} 806}
807 807
808int 808int
809cs_get_enaddr(struct cs_softc *sc) 809cs_get_enaddr(struct cs_softc *sc)
810{ 810{
811 uint16_t myea[ETHER_ADDR_LEN / sizeof(uint16_t)]; 811 uint16_t myea[ETHER_ADDR_LEN / sizeof(uint16_t)];
812 int i; 812 int i;
813 813
814 if (cs_verify_eeprom(sc) == CS_ERROR) { 814 if (cs_verify_eeprom(sc) == CS_ERROR) {
815 aprint_error_dev(sc->sc_dev, 815 aprint_error_dev(sc->sc_dev,
816 "cs_get_enaddr: EEPROM missing or bad\n"); 816 "cs_get_enaddr: EEPROM missing or bad\n");
817 return CS_ERROR; 817 return CS_ERROR;
818 } 818 }
819 819
820 /* Get Ethernet address from the EEPROM */ 820 /* Get Ethernet address from the EEPROM */
821 if (sc->sc_cfgflags & CFGFLG_PARSE_EEPROM) { 821 if (sc->sc_cfgflags & CFGFLG_PARSE_EEPROM) {
822 if (cs_read_pktpg_from_eeprom(sc, PKTPG_IND_ADDR, &myea[0]) 822 if (cs_read_pktpg_from_eeprom(sc, PKTPG_IND_ADDR, &myea[0])
823 == CS_ERROR) 823 == CS_ERROR)
824 goto eeprom_bad; 824 goto eeprom_bad;
825 if (cs_read_pktpg_from_eeprom(sc, PKTPG_IND_ADDR + 2, &myea[1]) 825 if (cs_read_pktpg_from_eeprom(sc, PKTPG_IND_ADDR + 2, &myea[1])
826 == CS_ERROR) 826 == CS_ERROR)
827 goto eeprom_bad; 827 goto eeprom_bad;
828 if (cs_read_pktpg_from_eeprom(sc, PKTPG_IND_ADDR + 4, &myea[2]) 828 if (cs_read_pktpg_from_eeprom(sc, PKTPG_IND_ADDR + 4, &myea[2])
829 == CS_ERROR) 829 == CS_ERROR)
830 goto eeprom_bad; 830 goto eeprom_bad;
831 } else { 831 } else {
832 if (cs_read_eeprom(sc, EEPROM_IND_ADDR_H, &myea[0]) == CS_ERROR) 832 if (cs_read_eeprom(sc, EEPROM_IND_ADDR_H, &myea[0]) == CS_ERROR)
833 goto eeprom_bad; 833 goto eeprom_bad;
834 if (cs_read_eeprom(sc, EEPROM_IND_ADDR_M, &myea[1]) == CS_ERROR) 834 if (cs_read_eeprom(sc, EEPROM_IND_ADDR_M, &myea[1]) == CS_ERROR)
835 goto eeprom_bad; 835 goto eeprom_bad;
836 if (cs_read_eeprom(sc, EEPROM_IND_ADDR_L, &myea[2]) == CS_ERROR) 836 if (cs_read_eeprom(sc, EEPROM_IND_ADDR_L, &myea[2]) == CS_ERROR)
837 goto eeprom_bad; 837 goto eeprom_bad;
838 } 838 }
839 839
840 for (i = 0; i < __arraycount(myea); i++) { 840 for (i = 0; i < __arraycount(myea); i++) {
841 sc->sc_enaddr[i * 2 + 0] = myea[i]; 841 sc->sc_enaddr[i * 2 + 0] = myea[i];
842 sc->sc_enaddr[i * 2 + 1] = myea[i] >> 8; 842 sc->sc_enaddr[i * 2 + 1] = myea[i] >> 8;
843 } 843 }
844 844
845 return CS_OK; 845 return CS_OK;
846 846
847 eeprom_bad: 847 eeprom_bad:
848 aprint_error_dev(sc->sc_dev, 848 aprint_error_dev(sc->sc_dev,
849 "cs_get_enaddr: unable to read from EEPROM\n"); 849 "cs_get_enaddr: unable to read from EEPROM\n");
850 return CS_ERROR; 850 return CS_ERROR;
851} 851}
852 852
853int 853int
854cs_reset_chip(struct cs_softc *sc) 854cs_reset_chip(struct cs_softc *sc)
855{ 855{
856 int intState; 856 int intState;
857 int x; 857 int x;
858 858
859 /* Disable interrupts at the CPU so reset command is atomic */ 859 /* Disable interrupts at the CPU so reset command is atomic */
860 intState = splnet(); 860 intState = splnet();
861 861
862 /* 862 /*
863 * We are now resetting the chip 863 * We are now resetting the chip
864 * 864 *
865 * A spurious interrupt is generated by the chip when it is reset. This 865 * A spurious interrupt is generated by the chip when it is reset. This
866 * variable informs the interrupt handler to ignore this interrupt. 866 * variable informs the interrupt handler to ignore this interrupt.
867 */ 867 */
868 sc->sc_resetting = TRUE; 868 sc->sc_resetting = TRUE;
869 869
870 /* Issue a reset command to the chip */ 870 /* Issue a reset command to the chip */
871 CS_WRITE_PACKET_PAGE(sc, PKTPG_SELF_CTL, SELF_CTL_RESET); 871 CS_WRITE_PACKET_PAGE(sc, PKTPG_SELF_CTL, SELF_CTL_RESET);
872 872
873 /* Re-enable interrupts at the CPU */ 873 /* Re-enable interrupts at the CPU */
874 splx(intState); 874 splx(intState);
875 875
876 /* The chip is always in IO mode after a reset */ 876 /* The chip is always in IO mode after a reset */
877 sc->sc_memorymode = FALSE; 877 sc->sc_memorymode = FALSE;
878 878
879 /* If transmission was in progress, it is not now */ 879 /* If transmission was in progress, it is not now */
880 sc->sc_txbusy = FALSE; 880 sc->sc_txbusy = FALSE;
881 881
882 /* 882 /*
883 * There was a delay(125); here, but it seems uneccesary 125 usec is 883 * There was a delay(125); here, but it seems uneccesary 125 usec is
884 * 1/8000 of a second, not 1/8 of a second. the data sheet advises 884 * 1/8000 of a second, not 1/8 of a second. the data sheet advises
885 * 1/10 of a second here, but the SI_BUSY and INIT_DONE loops below 885 * 1/10 of a second here, but the SI_BUSY and INIT_DONE loops below
886 * should be sufficient. 886 * should be sufficient.
887 */ 887 */
888 888
889 /* Transition SBHE to switch chip from 8-bit to 16-bit */ 889 /* Transition SBHE to switch chip from 8-bit to 16-bit */
890 IO_READ_1(sc, PORT_PKTPG_PTR + 0); 890 IO_READ_1(sc, PORT_PKTPG_PTR + 0);
891 IO_READ_1(sc, PORT_PKTPG_PTR + 1); 891 IO_READ_1(sc, PORT_PKTPG_PTR + 1);
892 IO_READ_1(sc, PORT_PKTPG_PTR + 0); 892 IO_READ_1(sc, PORT_PKTPG_PTR + 0);
893 IO_READ_1(sc, PORT_PKTPG_PTR + 1); 893 IO_READ_1(sc, PORT_PKTPG_PTR + 1);
894 894
895 /* Wait until the EEPROM is not busy */ 895 /* Wait until the EEPROM is not busy */
896 for (x = 0; x < MAXLOOP; x++) { 896 for (x = 0; x < MAXLOOP; x++) {
897 if (!(CS_READ_PACKET_PAGE(sc, PKTPG_SELF_ST) & SELF_ST_SI_BUSY)) 897 if (!(CS_READ_PACKET_PAGE(sc, PKTPG_SELF_ST) & SELF_ST_SI_BUSY))
898 break; 898 break;
899 } 899 }
900 900
901 if (x == MAXLOOP) 901 if (x == MAXLOOP)
902 return CS_ERROR; 902 return CS_ERROR;
903 903
904 /* Wait until initialization is done */ 904 /* Wait until initialization is done */
905 for (x = 0; x < MAXLOOP; x++) { 905 for (x = 0; x < MAXLOOP; x++) {
906 if (CS_READ_PACKET_PAGE(sc, PKTPG_SELF_ST) & SELF_ST_INIT_DONE) 906 if (CS_READ_PACKET_PAGE(sc, PKTPG_SELF_ST) & SELF_ST_INIT_DONE)
907 break; 907 break;
908 } 908 }
909 909
910 if (x == MAXLOOP) 910 if (x == MAXLOOP)
911 return CS_ERROR; 911 return CS_ERROR;
912 912
913 /* Reset is no longer in progress */ 913 /* Reset is no longer in progress */
914 sc->sc_resetting = FALSE; 914 sc->sc_resetting = FALSE;
915 915
916 return CS_OK; 916 return CS_OK;
917} 917}
918 918
919int 919int
920cs_verify_eeprom(struct cs_softc *sc) 920cs_verify_eeprom(struct cs_softc *sc)
921{ 921{
922 uint16_t self_status; 922 uint16_t self_status;
923 923
924 /* Verify that the EEPROM is present and OK */ 924 /* Verify that the EEPROM is present and OK */
925 self_status = CS_READ_PACKET_PAGE_IO(sc, PKTPG_SELF_ST); 925 self_status = CS_READ_PACKET_PAGE_IO(sc, PKTPG_SELF_ST);
926 if (((self_status & SELF_ST_EEP_PRES) && 926 if (((self_status & SELF_ST_EEP_PRES) &&
927 (self_status & SELF_ST_EEP_OK)) == 0) 927 (self_status & SELF_ST_EEP_OK)) == 0)
928 return CS_ERROR; 928 return CS_ERROR;
929 929
930 return CS_OK; 930 return CS_OK;
931} 931}
932 932
933int 933int
934cs_read_eeprom(struct cs_softc *sc, int offset, uint16_t *pValue) 934cs_read_eeprom(struct cs_softc *sc, int offset, uint16_t *pValue)
935{ 935{
936 int x; 936 int x;
937 937
938 /* Ensure that the EEPROM is not busy */ 938 /* Ensure that the EEPROM is not busy */
939 for (x = 0; x < MAXLOOP; x++) { 939 for (x = 0; x < MAXLOOP; x++) {
940 if (!(CS_READ_PACKET_PAGE_IO(sc, PKTPG_SELF_ST) & 940 if (!(CS_READ_PACKET_PAGE_IO(sc, PKTPG_SELF_ST) &
941 SELF_ST_SI_BUSY)) 941 SELF_ST_SI_BUSY))
942 break; 942 break;
943 } 943 }
944 944
945 if (x == MAXLOOP) 945 if (x == MAXLOOP)
946 return CS_ERROR; 946 return CS_ERROR;
947 947
948 /* Issue the command to read the offset within the EEPROM */ 948 /* Issue the command to read the offset within the EEPROM */
949 CS_WRITE_PACKET_PAGE_IO(sc, PKTPG_EEPROM_CMD, 949 CS_WRITE_PACKET_PAGE_IO(sc, PKTPG_EEPROM_CMD,
950 offset | EEPROM_CMD_READ); 950 offset | EEPROM_CMD_READ);
951 951
952 /* Wait until the command is completed */ 952 /* Wait until the command is completed */
953 for (x = 0; x < MAXLOOP; x++) { 953 for (x = 0; x < MAXLOOP; x++) {
954 if (!(CS_READ_PACKET_PAGE_IO(sc, PKTPG_SELF_ST) & 954 if (!(CS_READ_PACKET_PAGE_IO(sc, PKTPG_SELF_ST) &
955 SELF_ST_SI_BUSY)) 955 SELF_ST_SI_BUSY))
956 break; 956 break;
957 } 957 }
958 958
959 if (x == MAXLOOP) 959 if (x == MAXLOOP)
960 return CS_ERROR; 960 return CS_ERROR;
961 961
962 /* Get the EEPROM data from the EEPROM Data register */ 962 /* Get the EEPROM data from the EEPROM Data register */
963 *pValue = CS_READ_PACKET_PAGE_IO(sc, PKTPG_EEPROM_DATA); 963 *pValue = CS_READ_PACKET_PAGE_IO(sc, PKTPG_EEPROM_DATA);
964 964
965 return CS_OK; 965 return CS_OK;
966} 966}
967 967
968void 968void
969cs_initChip(struct cs_softc *sc) 969cs_initChip(struct cs_softc *sc)
970{ 970{
971 uint16_t busCtl; 971 uint16_t busCtl;
972 uint16_t selfCtl; 972 uint16_t selfCtl;
973 uint16_t v; 973 uint16_t v;
974 uint16_t isaId; 974 uint16_t isaId;
975 int i; 975 int i;
976 int media = IFM_SUBTYPE(sc->sc_media.ifm_cur->ifm_media); 976 int media = IFM_SUBTYPE(sc->sc_media.ifm_cur->ifm_media);
977 977
978 /* Disable reception and transmission of frames */ 978 /* Disable reception and transmission of frames */
979 CS_WRITE_PACKET_PAGE(sc, PKTPG_LINE_CTL, 979 CS_WRITE_PACKET_PAGE(sc, PKTPG_LINE_CTL,
980 CS_READ_PACKET_PAGE(sc, PKTPG_LINE_CTL) & 980 CS_READ_PACKET_PAGE(sc, PKTPG_LINE_CTL) &
981 ~LINE_CTL_RX_ON & ~LINE_CTL_TX_ON); 981 ~LINE_CTL_RX_ON & ~LINE_CTL_TX_ON);
982 982
983 /* Disable interrupt at the chip */ 983 /* Disable interrupt at the chip */
984 CS_WRITE_PACKET_PAGE(sc, PKTPG_BUS_CTL, 984 CS_WRITE_PACKET_PAGE(sc, PKTPG_BUS_CTL,
985 CS_READ_PACKET_PAGE(sc, PKTPG_BUS_CTL) & ~BUS_CTL_INT_ENBL); 985 CS_READ_PACKET_PAGE(sc, PKTPG_BUS_CTL) & ~BUS_CTL_INT_ENBL);
986 986
987 /* If IOCHRDY is enabled then clear the bit in the busCtl register */ 987 /* If IOCHRDY is enabled then clear the bit in the busCtl register */
988 busCtl = CS_READ_PACKET_PAGE(sc, PKTPG_BUS_CTL); 988 busCtl = CS_READ_PACKET_PAGE(sc, PKTPG_BUS_CTL);
989 if (sc->sc_cfgflags & CFGFLG_IOCHRDY) { 989 if (sc->sc_cfgflags & CFGFLG_IOCHRDY) {
990 CS_WRITE_PACKET_PAGE(sc, PKTPG_BUS_CTL, 990 CS_WRITE_PACKET_PAGE(sc, PKTPG_BUS_CTL,
991 busCtl & ~BUS_CTL_IOCHRDY); 991 busCtl & ~BUS_CTL_IOCHRDY);
992 } else { 992 } else {
993 CS_WRITE_PACKET_PAGE(sc, PKTPG_BUS_CTL, 993 CS_WRITE_PACKET_PAGE(sc, PKTPG_BUS_CTL,
994 busCtl | BUS_CTL_IOCHRDY); 994 busCtl | BUS_CTL_IOCHRDY);
995 } 995 }
996 996
997 /* Set the Line Control register to match the media type */ 997 /* Set the Line Control register to match the media type */
998 if (media == IFM_10_T) 998 if (media == IFM_10_T)
999 CS_WRITE_PACKET_PAGE(sc, PKTPG_LINE_CTL, LINE_CTL_10BASET); 999 CS_WRITE_PACKET_PAGE(sc, PKTPG_LINE_CTL, LINE_CTL_10BASET);
1000 else 1000 else
1001 CS_WRITE_PACKET_PAGE(sc, PKTPG_LINE_CTL, LINE_CTL_AUI_ONLY); 1001 CS_WRITE_PACKET_PAGE(sc, PKTPG_LINE_CTL, LINE_CTL_AUI_ONLY);
1002 1002
1003 /* 1003 /*
1004 * Set the BSTATUS/HC1 pin to be used as HC1. HC1 is used to 1004 * Set the BSTATUS/HC1 pin to be used as HC1. HC1 is used to
1005 * enable the DC/DC converter 1005 * enable the DC/DC converter
1006 */ 1006 */
1007 selfCtl = SELF_CTL_HC1E; 1007 selfCtl = SELF_CTL_HC1E;
1008 1008
1009 /* If the media type is 10Base2 */ 1009 /* If the media type is 10Base2 */
1010 if (media == IFM_10_2) { 1010 if (media == IFM_10_2) {
1011 /* Enable the DC/DC converter if it has a low enable. */ 1011 /* Enable the DC/DC converter if it has a low enable. */
1012 if ((sc->sc_cfgflags & CFGFLG_DCDC_POL) == 0) 1012 if ((sc->sc_cfgflags & CFGFLG_DCDC_POL) == 0)
1013 /* 1013 /*
1014 * Set the HCB1 bit, which causes the HC1 pin to go 1014 * Set the HCB1 bit, which causes the HC1 pin to go
1015 * low. 1015 * low.
1016 */ 1016 */
1017 selfCtl |= SELF_CTL_HCB1; 1017 selfCtl |= SELF_CTL_HCB1;
1018 } else { /* Media type is 10BaseT or AUI */ 1018 } else { /* Media type is 10BaseT or AUI */
1019 /* Disable the DC/DC converter if it has a high enable. */ 1019 /* Disable the DC/DC converter if it has a high enable. */
1020 if ((sc->sc_cfgflags & CFGFLG_DCDC_POL) != 0) { 1020 if ((sc->sc_cfgflags & CFGFLG_DCDC_POL) != 0) {
1021 /* 1021 /*
1022 * Set the HCB1 bit, which causes the HC1 pin to go 1022 * Set the HCB1 bit, which causes the HC1 pin to go
1023 * low. 1023 * low.
1024 */ 1024 */
1025 selfCtl |= SELF_CTL_HCB1; 1025 selfCtl |= SELF_CTL_HCB1;
1026 } 1026 }
1027 } 1027 }
1028 CS_WRITE_PACKET_PAGE(sc, PKTPG_SELF_CTL, selfCtl); 1028 CS_WRITE_PACKET_PAGE(sc, PKTPG_SELF_CTL, selfCtl);
1029 1029
1030 /* Enable normal link pulse */ 1030 /* Enable normal link pulse */
1031 if (sc->sc_prodid == PROD_ID_CS8920 || sc->sc_prodid == PROD_ID_CS8920M) 1031 if (sc->sc_prodid == PROD_ID_CS8920 || sc->sc_prodid == PROD_ID_CS8920M)
1032 CS_WRITE_PACKET_PAGE(sc, PKTPG_AUTONEG_CTL, AUTOCTL_NLP_ENABLE); 1032 CS_WRITE_PACKET_PAGE(sc, PKTPG_AUTONEG_CTL, AUTOCTL_NLP_ENABLE);
1033 1033
1034 /* Enable full-duplex, if appropriate */ 1034 /* Enable full-duplex, if appropriate */
1035 if (sc->sc_media.ifm_cur->ifm_media & IFM_FDX) 1035 if (sc->sc_media.ifm_cur->ifm_media & IFM_FDX)
1036 CS_WRITE_PACKET_PAGE(sc, PKTPG_TEST_CTL, TEST_CTL_FDX); 1036 CS_WRITE_PACKET_PAGE(sc, PKTPG_TEST_CTL, TEST_CTL_FDX);
1037 1037
1038 /* RX_CTL set in cs_set_ladr_filt(), below */ 1038 /* RX_CTL set in cs_set_ladr_filt(), below */
1039 1039
1040 /* Enable all transmission interrupts */ 1040 /* Enable all transmission interrupts */
1041 CS_WRITE_PACKET_PAGE(sc, PKTPG_TX_CFG, TX_CFG_ALL_IE); 1041 CS_WRITE_PACKET_PAGE(sc, PKTPG_TX_CFG, TX_CFG_ALL_IE);
1042 1042
1043 /* Accept all receive interrupts */ 1043 /* Accept all receive interrupts */
1044 CS_WRITE_PACKET_PAGE(sc, PKTPG_RX_CFG, RX_CFG_ALL_IE); 1044 CS_WRITE_PACKET_PAGE(sc, PKTPG_RX_CFG, RX_CFG_ALL_IE);
1045 1045
1046 /* 1046 /*
1047 * Configure Operational Modes 1047 * Configure Operational Modes
1048 * 1048 *
1049 * I have turned off the BUF_CFG_RX_MISS_IE, to speed things up, this 1049 * I have turned off the BUF_CFG_RX_MISS_IE, to speed things up, this
1050 * is a better way to do it because the card has a counter which can be 1050 * is a better way to do it because the card has a counter which can be
1051 * read to update the RX_MISS counter. This saves many interrupts. 1051 * read to update the RX_MISS counter. This saves many interrupts.
1052 * 1052 *
1053 * I have turned on the tx and rx overflow interrupts to counter using 1053 * I have turned on the tx and rx overflow interrupts to counter using
1054 * the receive miss interrupt. This is a better estimate of errors 1054 * the receive miss interrupt. This is a better estimate of errors
1055 * and requires lower system overhead. 1055 * and requires lower system overhead.
1056 */ 1056 */
1057 CS_WRITE_PACKET_PAGE(sc, PKTPG_BUF_CFG, BUF_CFG_TX_UNDR_IE | 1057 CS_WRITE_PACKET_PAGE(sc, PKTPG_BUF_CFG, BUF_CFG_TX_UNDR_IE |
1058 BUF_CFG_RX_DMA_IE); 1058 BUF_CFG_RX_DMA_IE);
1059 1059
1060 if (sc->sc_dma_chipinit) 1060 if (sc->sc_dma_chipinit)
1061 (*sc->sc_dma_chipinit)(sc); 1061 (*sc->sc_dma_chipinit)(sc);
1062 1062
1063 /* If memory mode is enabled */ 1063 /* If memory mode is enabled */
1064 if (sc->sc_cfgflags & CFGFLG_MEM_MODE) { 1064 if (sc->sc_cfgflags & CFGFLG_MEM_MODE) {
1065 /* If external logic is present for address decoding */ 1065 /* If external logic is present for address decoding */
1066 if (CS_READ_PACKET_PAGE(sc, PKTPG_SELF_ST) & SELF_ST_EL_PRES) { 1066 if (CS_READ_PACKET_PAGE(sc, PKTPG_SELF_ST) & SELF_ST_EL_PRES) {
1067 /* 1067 /*
1068 * Program the external logic to decode address bits 1068 * Program the external logic to decode address bits
1069 * SA20-SA23 1069 * SA20-SA23
1070 */ 1070 */
1071 CS_WRITE_PACKET_PAGE(sc, PKTPG_EEPROM_CMD, 1071 CS_WRITE_PACKET_PAGE(sc, PKTPG_EEPROM_CMD,
1072 ((sc->sc_pktpgaddr & 0xffffff) >> 20) | 1072 ((sc->sc_pktpgaddr & 0xffffff) >> 20) |
1073 EEPROM_CMD_ELSEL); 1073 EEPROM_CMD_ELSEL);
1074 } 1074 }
1075 1075
1076 /* 1076 /*
1077 * Write the packet page base physical address to the memory 1077 * Write the packet page base physical address to the memory
1078 * base register. 1078 * base register.
1079 */ 1079 */
1080 CS_WRITE_PACKET_PAGE(sc, PKTPG_MEM_BASE + 0, 1080 CS_WRITE_PACKET_PAGE(sc, PKTPG_MEM_BASE + 0,
1081 sc->sc_pktpgaddr & 0xFFFF); 1081 sc->sc_pktpgaddr & 0xFFFF);
1082 CS_WRITE_PACKET_PAGE(sc, PKTPG_MEM_BASE + 2, 1082 CS_WRITE_PACKET_PAGE(sc, PKTPG_MEM_BASE + 2,
1083 sc->sc_pktpgaddr >> 16); 1083 sc->sc_pktpgaddr >> 16);
1084 busCtl = BUS_CTL_MEM_MODE; 1084 busCtl = BUS_CTL_MEM_MODE;
1085 1085
1086 /* Tell the chip to read the addresses off the SA pins */ 1086 /* Tell the chip to read the addresses off the SA pins */
1087 if (sc->sc_cfgflags & CFGFLG_USE_SA) { 1087 if (sc->sc_cfgflags & CFGFLG_USE_SA) {
1088 busCtl |= BUS_CTL_USE_SA; 1088 busCtl |= BUS_CTL_USE_SA;
1089 } 1089 }
1090 CS_WRITE_PACKET_PAGE(sc, PKTPG_BUS_CTL, 1090 CS_WRITE_PACKET_PAGE(sc, PKTPG_BUS_CTL,
1091 CS_READ_PACKET_PAGE(sc, PKTPG_BUS_CTL) | busCtl); 1091 CS_READ_PACKET_PAGE(sc, PKTPG_BUS_CTL) | busCtl);
1092 1092
1093 /* We are in memory mode now! */ 1093 /* We are in memory mode now! */
1094 sc->sc_memorymode = TRUE; 1094 sc->sc_memorymode = TRUE;
1095 1095
1096 /* 1096 /*
1097 * Wait here (10ms) for the chip to swap over. this is the 1097 * Wait here (10ms) for the chip to swap over. this is the
1098 * maximum time that this could take. 1098 * maximum time that this could take.
1099 */ 1099 */
1100 delay(10000); 1100 delay(10000);
1101 1101
1102 /* Verify that we can read from the chip */ 1102 /* Verify that we can read from the chip */
1103 isaId = CS_READ_PACKET_PAGE(sc, PKTPG_EISA_NUM); 1103 isaId = CS_READ_PACKET_PAGE(sc, PKTPG_EISA_NUM);
1104 1104
1105 /* 1105 /*
1106 * As a last minute sanity check before actually using mapped 1106 * As a last minute sanity check before actually using mapped
1107 * memory we verify that we can read the isa number from the 1107 * memory we verify that we can read the isa number from the
1108 * chip in memory mode. 1108 * chip in memory mode.
1109 */ 1109 */
1110 if (isaId != EISA_NUM_CRYSTAL) { 1110 if (isaId != EISA_NUM_CRYSTAL) {
1111 aprint_error_dev(sc->sc_dev, 1111 aprint_error_dev(sc->sc_dev,
1112 "failed to enable memory mode\n"); 1112 "failed to enable memory mode\n");
1113 sc->sc_memorymode = FALSE; 1113 sc->sc_memorymode = FALSE;
1114 } else { 1114 } else {
1115 /* 1115 /*
1116 * We are in memory mode so if we aren't using DMA, 1116 * We are in memory mode so if we aren't using DMA,
1117 * then program the chip to interrupt early. 1117 * then program the chip to interrupt early.
1118 */ 1118 */
1119 if ((sc->sc_cfgflags & CFGFLG_DMA_MODE) == 0) { 1119 if ((sc->sc_cfgflags & CFGFLG_DMA_MODE) == 0) {
1120 CS_WRITE_PACKET_PAGE(sc, PKTPG_BUF_CFG, 1120 CS_WRITE_PACKET_PAGE(sc, PKTPG_BUF_CFG,
1121 BUF_CFG_RX_DEST_IE | 1121 BUF_CFG_RX_DEST_IE |
1122 BUF_CFG_RX_MISS_OVER_IE | 1122 BUF_CFG_RX_MISS_OVER_IE |
1123 BUF_CFG_TX_COL_OVER_IE); 1123 BUF_CFG_TX_COL_OVER_IE);
1124 } 1124 }
1125 } 1125 }
1126 1126
1127 } 1127 }
1128 1128
1129 /* Put Ethernet address into the Individual Address register */ 1129 /* Put Ethernet address into the Individual Address register */
1130 for (i = 0; i < 6; i += 2) { 1130 for (i = 0; i < 6; i += 2) {
1131 v = sc->sc_enaddr[i + 0] | (sc->sc_enaddr[i + 1]) << 8; 1131 v = sc->sc_enaddr[i + 0] | (sc->sc_enaddr[i + 1]) << 8;
1132 CS_WRITE_PACKET_PAGE(sc, PKTPG_IND_ADDR + i, v); 1132 CS_WRITE_PACKET_PAGE(sc, PKTPG_IND_ADDR + i, v);
1133 } 1133 }
1134 1134
1135 if (sc->sc_irq != -1) { 1135 if (sc->sc_irq != -1) {
1136 /* Set the interrupt level in the chip */ 1136 /* Set the interrupt level in the chip */
1137 if (sc->sc_prodid == PROD_ID_CS8900) { 1137 if (sc->sc_prodid == PROD_ID_CS8900) {
1138 if (sc->sc_irq == 5) 1138 if (sc->sc_irq == 5)
1139 CS_WRITE_PACKET_PAGE(sc, PKTPG_INT_NUM, 3); 1139 CS_WRITE_PACKET_PAGE(sc, PKTPG_INT_NUM, 3);
1140 else 1140 else
1141 CS_WRITE_PACKET_PAGE(sc, PKTPG_INT_NUM, 1141 CS_WRITE_PACKET_PAGE(sc, PKTPG_INT_NUM,
1142 (sc->sc_irq) - 10); 1142 (sc->sc_irq) - 10);
1143 } else { /* CS8920 */ 1143 } else { /* CS8920 */
1144 CS_WRITE_PACKET_PAGE(sc, PKTPG_8920_INT_NUM, 1144 CS_WRITE_PACKET_PAGE(sc, PKTPG_8920_INT_NUM,
1145 sc->sc_irq); 1145 sc->sc_irq);
1146 } 1146 }
1147 } 1147 }
1148 1148
1149 /* Write the multicast mask to the address filter register */ 1149 /* Write the multicast mask to the address filter register */
1150 cs_set_ladr_filt(sc, &sc->sc_ethercom); 1150 cs_set_ladr_filt(sc, &sc->sc_ethercom);
1151 1151
1152 /* Enable reception and transmission of frames */ 1152 /* Enable reception and transmission of frames */
1153 CS_WRITE_PACKET_PAGE(sc, PKTPG_LINE_CTL, 1153 CS_WRITE_PACKET_PAGE(sc, PKTPG_LINE_CTL,
1154 CS_READ_PACKET_PAGE(sc, PKTPG_LINE_CTL) | 1154 CS_READ_PACKET_PAGE(sc, PKTPG_LINE_CTL) |
1155 LINE_CTL_RX_ON | LINE_CTL_TX_ON); 1155 LINE_CTL_RX_ON | LINE_CTL_TX_ON);
1156 1156
1157 /* Enable interrupt at the chip */ 1157 /* Enable interrupt at the chip */
1158 CS_WRITE_PACKET_PAGE(sc, PKTPG_BUS_CTL, 1158 CS_WRITE_PACKET_PAGE(sc, PKTPG_BUS_CTL,
1159 CS_READ_PACKET_PAGE(sc, PKTPG_BUS_CTL) | BUS_CTL_INT_ENBL); 1159 CS_READ_PACKET_PAGE(sc, PKTPG_BUS_CTL) | BUS_CTL_INT_ENBL);
1160} 1160}
1161 1161
1162int 1162int
1163cs_init(struct ifnet *ifp) 1163cs_init(struct ifnet *ifp)
1164{ 1164{
1165 int intState; 1165 int intState;
1166 int error = CS_OK; 1166 int error = CS_OK;
1167 struct cs_softc *sc = ifp->if_softc; 1167 struct cs_softc *sc = ifp->if_softc;
1168 1168
1169 if (cs_enable(sc)) 1169 if (cs_enable(sc))
1170 goto out; 1170 goto out;
1171 1171
1172 cs_stop(ifp, 0); 1172 cs_stop(ifp, 0);
1173 1173
1174 intState = splnet(); 1174 intState = splnet();
1175 1175
1176#if 0 1176#if 0
1177 /* Mark the interface as down */ 1177 /* Mark the interface as down */
1178 sc->sc_ethercom.ec_if.if_flags &= ~(IFF_UP | IFF_RUNNING); 1178 sc->sc_ethercom.ec_if.if_flags &= ~(IFF_UP | IFF_RUNNING);
1179#endif 1179#endif
1180 1180
1181#ifdef CS_DEBUG 1181#ifdef CS_DEBUG
1182 /* Enable debugging */ 1182 /* Enable debugging */
1183 sc->sc_ethercom.ec_if.if_flags |= IFF_DEBUG; 1183 sc->sc_ethercom.ec_if.if_flags |= IFF_DEBUG;
1184#endif 1184#endif
1185 1185
1186 /* Reset the chip */ 1186 /* Reset the chip */
1187 if ((error = cs_reset_chip(sc)) == CS_OK) { 1187 if ((error = cs_reset_chip(sc)) == CS_OK) {
1188 /* Initialize the chip */ 1188 /* Initialize the chip */
1189 cs_initChip(sc); 1189 cs_initChip(sc);
1190 1190
1191 /* Mark the interface as running */ 1191 /* Mark the interface as running */
1192 sc->sc_ethercom.ec_if.if_flags |= IFF_RUNNING; 1192 sc->sc_ethercom.ec_if.if_flags |= IFF_RUNNING;
1193 sc->sc_ethercom.ec_if.if_flags &= ~IFF_OACTIVE; 1193 sc->sc_ethercom.ec_if.if_flags &= ~IFF_OACTIVE;
1194 sc->sc_ethercom.ec_if.if_timer = 0; 1194 sc->sc_ethercom.ec_if.if_timer = 0;
1195 1195
1196 /* Assume we have carrier until we are told otherwise. */ 1196 /* Assume we have carrier until we are told otherwise. */
1197 sc->sc_carrier = 1; 1197 sc->sc_carrier = 1;
1198 } else 1198 } else
1199 aprint_error_dev(sc->sc_dev, "unable to reset chip\n"); 1199 aprint_error_dev(sc->sc_dev, "unable to reset chip\n");
1200 1200
1201 splx(intState); 1201 splx(intState);
1202out: 1202out:
1203 if (error == CS_OK) 1203 if (error == CS_OK)
1204 return 0; 1204 return 0;
1205 return EIO; 1205 return EIO;
1206} 1206}
1207 1207
1208void 1208void
1209cs_set_ladr_filt(struct cs_softc *sc, struct ethercom *ec) 1209cs_set_ladr_filt(struct cs_softc *sc, struct ethercom *ec)
1210{ 1210{
1211 struct ifnet *ifp = &ec->ec_if; 1211 struct ifnet *ifp = &ec->ec_if;
1212 struct ether_multi *enm; 1212 struct ether_multi *enm;
1213 struct ether_multistep step; 1213 struct ether_multistep step;
1214 uint16_t af[4]; 1214 uint16_t af[4];
1215 uint16_t port, mask, index; 1215 uint16_t port, mask, index;
1216 1216
1217 /* 1217 /*
1218 * Set up multicast address filter by passing all multicast addresses 1218 * Set up multicast address filter by passing all multicast addresses
1219 * through a crc generator, and then using the high order 6 bits as an 1219 * through a crc generator, and then using the high order 6 bits as an
1220 * index into the 64 bit logical address filter. The high order bit 1220 * index into the 64 bit logical address filter. The high order bit
1221 * selects the word, while the rest of the bits select the bit within 1221 * selects the word, while the rest of the bits select the bit within
1222 * the word. 1222 * the word.
1223 */ 1223 */
1224 if (ifp->if_flags & IFF_PROMISC) { 1224 if (ifp->if_flags & IFF_PROMISC) {
1225 /* Accept all valid frames. */ 1225 /* Accept all valid frames. */
1226 CS_WRITE_PACKET_PAGE(sc, PKTPG_RX_CTL, 1226 CS_WRITE_PACKET_PAGE(sc, PKTPG_RX_CTL,
1227 RX_CTL_PROMISC_A | RX_CTL_RX_OK_A | 1227 RX_CTL_PROMISC_A | RX_CTL_RX_OK_A |
1228 RX_CTL_IND_A | RX_CTL_BCAST_A | RX_CTL_MCAST_A); 1228 RX_CTL_IND_A | RX_CTL_BCAST_A | RX_CTL_MCAST_A);
1229 ifp->if_flags |= IFF_ALLMULTI; 1229 ifp->if_flags |= IFF_ALLMULTI;
1230 return; 1230 return;
1231 } 1231 }
1232 1232
1233 /* 1233 /*
1234 * Accept frames if a. crc valid, b. individual address match c. 1234 * Accept frames if a. crc valid, b. individual address match c.
1235 * broadcast address,and d. multicast addresses matched in the hash 1235 * broadcast address,and d. multicast addresses matched in the hash
1236 * filter 1236 * filter
1237 */ 1237 */
1238 CS_WRITE_PACKET_PAGE(sc, PKTPG_RX_CTL, 1238 CS_WRITE_PACKET_PAGE(sc, PKTPG_RX_CTL,
1239 RX_CTL_RX_OK_A | RX_CTL_IND_A | RX_CTL_BCAST_A | RX_CTL_MCAST_A); 1239 RX_CTL_RX_OK_A | RX_CTL_IND_A | RX_CTL_BCAST_A | RX_CTL_MCAST_A);
1240 1240
1241 1241
1242 /* 1242 /*
1243 * Start off with all multicast flag clear, set it if we need to 1243 * Start off with all multicast flag clear, set it if we need to
1244 * later, otherwise we will leave it. 1244 * later, otherwise we will leave it.
1245 */ 1245 */
1246 ifp->if_flags &= ~IFF_ALLMULTI; 1246 ifp->if_flags &= ~IFF_ALLMULTI;
1247 af[0] = af[1] = af[2] = af[3] = 0x0000; 1247 af[0] = af[1] = af[2] = af[3] = 0x0000;
1248 1248
1249 /* 1249 /*
1250 * Loop through all the multicast addresses unless we get a range of 1250 * Loop through all the multicast addresses unless we get a range of
1251 * addresses, in which case we will just accept all packets. 1251 * addresses, in which case we will just accept all packets.
1252 * Justification for this is given in the next comment. 1252 * Justification for this is given in the next comment.
1253 */ 1253 */
1254 ETHER_LOCK(ec); 1254 ETHER_LOCK(ec);
1255 ETHER_FIRST_MULTI(step, ec, enm); 1255 ETHER_FIRST_MULTI(step, ec, enm);
1256 while (enm != NULL) { 1256 while (enm != NULL) {
1257 if (memcmp(enm->enm_addrlo, enm->enm_addrhi, 1257 if (memcmp(enm->enm_addrlo, enm->enm_addrhi,
1258 sizeof enm->enm_addrlo)) { 1258 sizeof enm->enm_addrlo)) {
1259 /* 1259 /*
1260 * We must listen to a range of multicast addresses. 1260 * We must listen to a range of multicast addresses.
1261 * For now, just accept all multicasts, rather than 1261 * For now, just accept all multicasts, rather than
1262 * trying to set only those filter bits needed to match 1262 * trying to set only those filter bits needed to match
1263 * the range. (At this time, the only use of address 1263 * the range. (At this time, the only use of address
1264 * ranges is for IP multicast routing, for which the 1264 * ranges is for IP multicast routing, for which the
1265 * range is big enough to require all bits set.) 1265 * range is big enough to require all bits set.)
1266 */ 1266 */
1267 ifp->if_flags |= IFF_ALLMULTI; 1267 ifp->if_flags |= IFF_ALLMULTI;
1268 af[0] = af[1] = af[2] = af[3] = 0xffff; 1268 af[0] = af[1] = af[2] = af[3] = 0xffff;
1269 break; 1269 break;
1270 } else { 1270 } else {
1271 /* 1271 /*
1272 * We have got an individual address so just set that 1272 * We have got an individual address so just set that
1273 * bit. 1273 * bit.
1274 */ 1274 */
1275 index = cs_hash_index(enm->enm_addrlo); 1275 index = cs_hash_index(enm->enm_addrlo);
1276 1276
1277 /* Set the bit the Logical address filter. */ 1277 /* Set the bit the Logical address filter. */
1278 port = (uint16_t) (index >> 4); 1278 port = (uint16_t) (index >> 4);
1279 mask = (uint16_t) (1 << (index & 0xf)); 1279 mask = (uint16_t) (1 << (index & 0xf));
1280 af[port] |= mask; 1280 af[port] |= mask;
1281 1281
1282 ETHER_NEXT_MULTI(step, enm); 1282 ETHER_NEXT_MULTI(step, enm);
1283 } 1283 }
1284 } 1284 }
1285 ETHER_UNLOCK(ec); 1285 ETHER_UNLOCK(ec);
1286 1286
1287 /* Now program the chip with the addresses */ 1287 /* Now program the chip with the addresses */
1288 CS_WRITE_PACKET_PAGE(sc, PKTPG_LOG_ADDR + 0, af[0]); 1288 CS_WRITE_PACKET_PAGE(sc, PKTPG_LOG_ADDR + 0, af[0]);
1289 CS_WRITE_PACKET_PAGE(sc, PKTPG_LOG_ADDR + 2, af[1]); 1289 CS_WRITE_PACKET_PAGE(sc, PKTPG_LOG_ADDR + 2, af[1]);
1290 CS_WRITE_PACKET_PAGE(sc, PKTPG_LOG_ADDR + 4, af[2]); 1290 CS_WRITE_PACKET_PAGE(sc, PKTPG_LOG_ADDR + 4, af[2]);
1291 CS_WRITE_PACKET_PAGE(sc, PKTPG_LOG_ADDR + 6, af[3]); 1291 CS_WRITE_PACKET_PAGE(sc, PKTPG_LOG_ADDR + 6, af[3]);
1292 return; 1292 return;
1293} 1293}
1294 1294
1295uint16_t 1295uint16_t
1296cs_hash_index(char *addr) 1296cs_hash_index(char *addr)
1297{ 1297{
1298 uint32_t crc; 1298 uint32_t crc;
1299 uint16_t hash_code; 1299 uint16_t hash_code;
1300 1300
1301 crc = ether_crc32_le(addr, ETHER_ADDR_LEN); 1301 crc = ether_crc32_le(addr, ETHER_ADDR_LEN);
1302 1302
1303 hash_code = crc >> 26; 1303 hash_code = crc >> 26;
1304 return hash_code; 1304 return hash_code;
1305} 1305}
1306 1306
1307void 1307void
1308cs_reset(struct cs_softc *sc) 1308cs_reset(struct cs_softc *sc)
1309{ 1309{
1310 1310
1311 /* Mark the interface as down */ 1311 /* Mark the interface as down */
1312 sc->sc_ethercom.ec_if.if_flags &= ~IFF_RUNNING; 1312 sc->sc_ethercom.ec_if.if_flags &= ~IFF_RUNNING;
1313 1313
1314 /* Reset the chip */ 1314 /* Reset the chip */
1315 cs_reset_chip(sc); 1315 cs_reset_chip(sc);
1316} 1316}
1317 1317
1318int 1318int
1319cs_ioctl(struct ifnet *ifp, u_long cmd, void *data) 1319cs_ioctl(struct ifnet *ifp, u_long cmd, void *data)
1320{ 1320{
1321 struct cs_softc *sc = ifp->if_softc; 1321 struct cs_softc *sc = ifp->if_softc;
1322 int state; 1322 int state;
1323 int result; 1323 int result;
1324 1324
1325 state = splnet(); 1325 state = splnet();
1326 1326
1327 result = 0; /* Only set if something goes wrong */ 1327 result = 0; /* Only set if something goes wrong */
1328 1328
1329 switch (cmd) { 1329 switch (cmd) {
1330 default: 1330 default:
1331 result = ether_ioctl(ifp, cmd, data); 1331 result = ether_ioctl(ifp, cmd, data);
1332 if (result == ENETRESET) { 1332 if (result == ENETRESET) {
1333 if (ifp->if_flags & IFF_RUNNING) { 1333 if (ifp->if_flags & IFF_RUNNING) {
1334 /* 1334 /*
1335 * Multicast list has changed. Set the 1335 * Multicast list has changed. Set the
1336 * hardware filter accordingly. 1336 * hardware filter accordingly.
1337 */ 1337 */
1338 cs_set_ladr_filt(sc, &sc->sc_ethercom); 1338 cs_set_ladr_filt(sc, &sc->sc_ethercom);
1339 } 1339 }
1340 result = 0; 1340 result = 0;
1341 } 1341 }
1342 break; 1342 break;
1343 } 1343 }
1344 1344
1345 splx(state); 1345 splx(state);
1346 1346
1347 return result; 1347 return result;
1348} 1348}
1349 1349
1350int 1350int
1351cs_mediachange(struct ifnet *ifp) 1351cs_mediachange(struct ifnet *ifp)
1352{ 1352{
1353 1353
1354 /* 1354 /*
1355 * Current media is already set up. Just reset the interface 1355 * Current media is already set up. Just reset the interface
1356 * to let the new value take hold. 1356 * to let the new value take hold.
1357 */ 1357 */
1358 cs_init(ifp); 1358 cs_init(ifp);
1359 return 0; 1359 return 0;
1360} 1360}
1361 1361
1362void 1362void
1363cs_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr) 1363cs_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr)
1364{ 1364{
1365 struct cs_softc *sc = ifp->if_softc; 1365 struct cs_softc *sc = ifp->if_softc;
1366 1366
1367 /* The currently selected media is always the active media. */ 1367 /* The currently selected media is always the active media. */
1368 ifmr->ifm_active = sc->sc_media.ifm_cur->ifm_media; 1368 ifmr->ifm_active = sc->sc_media.ifm_cur->ifm_media;
1369 1369
1370 if (ifp->if_flags & IFF_UP) { 1370 if (ifp->if_flags & IFF_UP) {
1371 /* Interface up, status is valid. */ 1371 /* Interface up, status is valid. */
1372 ifmr->ifm_status = IFM_AVALID | 1372 ifmr->ifm_status = IFM_AVALID |
1373 (sc->sc_carrier ? IFM_ACTIVE : 0); 1373 (sc->sc_carrier ? IFM_ACTIVE : 0);
1374 } 1374 }
1375 else ifmr->ifm_status = 0; 1375 else ifmr->ifm_status = 0;
1376} 1376}
1377 1377
1378int 1378int
1379cs_intr(void *arg) 1379cs_intr(void *arg)
1380{ 1380{
1381 struct cs_softc *sc = arg; 1381 struct cs_softc *sc = arg;
1382 uint16_t Event; 1382 uint16_t Event;
1383 uint16_t rndEvent; 1383 uint16_t rndEvent;
1384 1384
1385/*printf("cs_intr %p\n", sc);*/ 1385/*printf("cs_intr %p\n", sc);*/
1386 /* Ignore any interrupts that happen while the chip is being reset */ 1386 /* Ignore any interrupts that happen while the chip is being reset */
1387 if (sc->sc_resetting) { 1387 if (sc->sc_resetting) {
1388 printf("%s: cs_intr: reset in progress\n", 1388 printf("%s: cs_intr: reset in progress\n",
1389 device_xname(sc->sc_dev)); 1389 device_xname(sc->sc_dev));
1390 return 1; 1390 return 1;
1391 } 1391 }
1392 1392
1393 /* Read an event from the Interrupt Status Queue */ 1393 /* Read an event from the Interrupt Status Queue */
1394 if (sc->sc_memorymode) 1394 if (sc->sc_memorymode)
1395 Event = CS_READ_PACKET_PAGE(sc, PKTPG_ISQ); 1395 Event = CS_READ_PACKET_PAGE(sc, PKTPG_ISQ);
1396 else 1396 else
1397 Event = CS_READ_PORT(sc, PORT_ISQ); 1397 Event = CS_READ_PORT(sc, PORT_ISQ);
1398 1398
1399 if ((Event & REG_NUM_MASK) == 0 || Event == 0xffff) 1399 if ((Event & REG_NUM_MASK) == 0 || Event == 0xffff)
1400 return 0; /* Not ours */ 1400 return 0; /* Not ours */
1401 1401
1402 rndEvent = Event; 1402 rndEvent = Event;
1403 1403
1404 /* Process all the events in the Interrupt Status Queue */ 1404 /* Process all the events in the Interrupt Status Queue */
1405 while ((Event & REG_NUM_MASK) != 0 && Event != 0xffff) { 1405 while ((Event & REG_NUM_MASK) != 0 && Event != 0xffff) {
1406 /* Dispatch to an event handler based on the register number */ 1406 /* Dispatch to an event handler based on the register number */
1407 switch (Event & REG_NUM_MASK) { 1407 switch (Event & REG_NUM_MASK) {
1408 case REG_NUM_RX_EVENT: 1408 case REG_NUM_RX_EVENT:
1409 cs_receive_event(sc, Event); 1409 cs_receive_event(sc, Event);
1410 break; 1410 break;
1411 case REG_NUM_TX_EVENT: 1411 case REG_NUM_TX_EVENT:
1412 cs_transmit_event(sc, Event); 1412 cs_transmit_event(sc, Event);
1413 break; 1413 break;
1414 case REG_NUM_BUF_EVENT: 1414 case REG_NUM_BUF_EVENT:
1415 cs_buffer_event(sc, Event); 1415 cs_buffer_event(sc, Event);
1416 break; 1416 break;
1417 case REG_NUM_TX_COL: 1417 case REG_NUM_TX_COL:
1418 case REG_NUM_RX_MISS: 1418 case REG_NUM_RX_MISS:
1419 cs_counter_event(sc, Event); 1419 cs_counter_event(sc, Event);
1420 break; 1420 break;
1421 default: 1421 default:
1422 printf("%s: unknown interrupt event 0x%x\n", 1422 printf("%s: unknown interrupt event 0x%x\n",
1423 device_xname(sc->sc_dev), Event); 1423 device_xname(sc->sc_dev), Event);
1424 break; 1424 break;
1425 } 1425 }
1426 1426
1427 /* Read another event from the Interrupt Status Queue */ 1427 /* Read another event from the Interrupt Status Queue */
1428 if (sc->sc_memorymode) 1428 if (sc->sc_memorymode)
1429 Event = CS_READ_PACKET_PAGE(sc, PKTPG_ISQ); 1429 Event = CS_READ_PACKET_PAGE(sc, PKTPG_ISQ);
1430 else 1430 else
1431 Event = CS_READ_PORT(sc, PORT_ISQ); 1431 Event = CS_READ_PORT(sc, PORT_ISQ);
1432 } 1432 }
1433 1433
1434 /* have handled the interrupt */ 1434 /* have handled the interrupt */
1435 rnd_add_uint32(&sc->rnd_source, rndEvent); 1435 rnd_add_uint32(&sc->rnd_source, rndEvent);
1436 return 1; 1436 return 1;
1437} 1437}
1438 1438
1439void 1439void
1440cs_counter_event(struct cs_softc *sc, uint16_t cntEvent) 1440cs_counter_event(struct cs_softc *sc, uint16_t cntEvent)
1441{ 1441{
1442 struct ifnet *ifp; 1442 struct ifnet *ifp;
1443 uint16_t errorCount; 1443 uint16_t errorCount;
1444 1444
1445 ifp = &sc->sc_ethercom.ec_if; 1445 ifp = &sc->sc_ethercom.ec_if;
1446 1446
1447 switch (cntEvent & REG_NUM_MASK) { 1447 switch (cntEvent & REG_NUM_MASK) {
1448 case REG_NUM_TX_COL: 1448 case REG_NUM_TX_COL:
1449 /* The count should be read before an overflow occurs. */ 1449 /* The count should be read before an overflow occurs. */
1450 errorCount = CS_READ_PACKET_PAGE(sc, PKTPG_TX_COL); 1450 errorCount = CS_READ_PACKET_PAGE(sc, PKTPG_TX_COL);
1451 /* 1451 /*
1452 * The tramsit event routine always checks the number of 1452 * The tramsit event routine always checks the number of
1453 * collisions for any packet so we don't increment any 1453 * collisions for any packet so we don't increment any
1454 * counters here, as they should already have been 1454 * counters here, as they should already have been
1455 * considered. 1455 * considered.
1456 */ 1456 */
1457 break; 1457 break;
1458 case REG_NUM_RX_MISS: 1458 case REG_NUM_RX_MISS:
1459 /* The count should be read before an overflow occurs. */ 1459 /* The count should be read before an overflow occurs. */
1460 errorCount = CS_READ_PACKET_PAGE(sc, PKTPG_RX_MISS); 1460 errorCount = CS_READ_PACKET_PAGE(sc, PKTPG_RX_MISS);
1461 /* 1461 /*
1462 * Increment the input error count, the first 6bits are the 1462 * Increment the input error count, the first 6bits are the
1463 * register id. 1463 * register id.
1464 */ 1464 */
1465 ifp->if_ierrors += ((errorCount & 0xffC0) >> 6); 1465 if_statadd(ifp, if_ierrors, (errorCount & 0xffC0) >> 6);
1466 break; 1466 break;
1467 default: 1467 default:
1468 /* Do nothing */ 1468 /* Do nothing */
1469 break; 1469 break;
1470 } 1470 }
1471} 1471}
1472 1472
1473void 1473void
1474cs_buffer_event(struct cs_softc *sc, uint16_t bufEvent) 1474cs_buffer_event(struct cs_softc *sc, uint16_t bufEvent)
1475{ 1475{
1476 1476
1477 /* 1477 /*
1478 * Multiple events can be in the buffer event register at one time so 1478 * Multiple events can be in the buffer event register at one time so
1479 * a standard switch statement will not suffice, here every event 1479 * a standard switch statement will not suffice, here every event
1480 * must be checked. 1480 * must be checked.
1481 */ 1481 */
1482 1482
1483 /* 1483 /*
1484 * If 128 bits have been rxed by the time we get here, the dest event 1484 * If 128 bits have been rxed by the time we get here, the dest event
1485 * will be cleared and 128 event will be set. 1485 * will be cleared and 128 event will be set.
1486 */ 1486 */
1487 if ((bufEvent & (BUF_EVENT_RX_DEST | BUF_EVENT_RX_128)) != 0) 1487 if ((bufEvent & (BUF_EVENT_RX_DEST | BUF_EVENT_RX_128)) != 0)
1488 cs_process_rx_early(sc); 1488 cs_process_rx_early(sc);
1489 1489
1490 if (bufEvent & BUF_EVENT_RX_DMA) { 1490 if (bufEvent & BUF_EVENT_RX_DMA) {
1491 /* Process the receive data */ 1491 /* Process the receive data */
1492 if (sc->sc_dma_process_rx) 1492 if (sc->sc_dma_process_rx)
1493 (*sc->sc_dma_process_rx)(sc); 1493 (*sc->sc_dma_process_rx)(sc);
1494 else 1494 else
1495 /* Should panic? */ 1495 /* Should panic? */
1496 aprint_error_dev(sc->sc_dev, "unexpected DMA event\n"); 1496 aprint_error_dev(sc->sc_dev, "unexpected DMA event\n");
1497 } 1497 }
1498 1498
1499 if (bufEvent & BUF_EVENT_TX_UNDR) { 1499 if (bufEvent & BUF_EVENT_TX_UNDR) {
1500#if 0 1500#if 0
1501 /* 1501 /*
1502 * This can happen occasionally, and it's not worth worrying 1502 * This can happen occasionally, and it's not worth worrying
1503 * about. 1503 * about.
1504 */ 1504 */
1505 printf("%s: transmit underrun (%d -> %d)\n", 1505 printf("%s: transmit underrun (%d -> %d)\n",
1506 device_xname(sc->sc_dev), sc->sc_xe_ent, 1506 device_xname(sc->sc_dev), sc->sc_xe_ent,
1507 cs_xmit_early_table[sc->sc_xe_ent].worse); 1507 cs_xmit_early_table[sc->sc_xe_ent].worse);
1508#endif 1508#endif
1509 sc->sc_xe_ent = cs_xmit_early_table[sc->sc_xe_ent].worse; 1509 sc->sc_xe_ent = cs_xmit_early_table[sc->sc_xe_ent].worse;
1510 sc->sc_xe_togo = 1510 sc->sc_xe_togo =
1511 cs_xmit_early_table[sc->sc_xe_ent].better_count; 1511 cs_xmit_early_table[sc->sc_xe_ent].better_count;
1512 1512
1513 /* had an underrun, transmit is finished */ 1513 /* had an underrun, transmit is finished */
1514 sc->sc_txbusy = FALSE; 1514 sc->sc_txbusy = FALSE;
1515 } 1515 }
1516 1516
1517 if (bufEvent & BUF_EVENT_SW_INT) 1517 if (bufEvent & BUF_EVENT_SW_INT)
1518 printf("%s: software initiated interrupt\n", 1518 printf("%s: software initiated interrupt\n",
1519 device_xname(sc->sc_dev)); 1519 device_xname(sc->sc_dev));
1520} 1520}
1521 1521
1522void 1522void
1523cs_transmit_event(struct cs_softc *sc, uint16_t txEvent) 1523cs_transmit_event(struct cs_softc *sc, uint16_t txEvent)
1524{ 1524{
1525 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 1525 struct ifnet *ifp = &sc->sc_ethercom.ec_if;
1526 1526
1527 /* If there were any errors transmitting this frame */ 1527 /* If there were any errors transmitting this frame */
1528 if (txEvent & (TX_EVENT_LOSS_CRS | TX_EVENT_SQE_ERR | 1528 if (txEvent & (TX_EVENT_LOSS_CRS | TX_EVENT_SQE_ERR |
1529 TX_EVENT_OUT_WIN | TX_EVENT_JABBER | TX_EVENT_16_COLL)) { 1529 TX_EVENT_OUT_WIN | TX_EVENT_JABBER | TX_EVENT_16_COLL)) {
1530 /* Increment the output error count */ 1530 /* Increment the output error count */
1531 ifp->if_oerrors++; 1531 if_statinc(ifp, if_oerrors);
1532 1532
1533 /* Note carrier loss. */ 1533 /* Note carrier loss. */
1534 if (txEvent & TX_EVENT_LOSS_CRS) 1534 if (txEvent & TX_EVENT_LOSS_CRS)
1535 sc->sc_carrier = 0; 1535 sc->sc_carrier = 0;
1536 1536
1537 /* If debugging is enabled then log error messages */ 1537 /* If debugging is enabled then log error messages */
1538 if (ifp->if_flags & IFF_DEBUG) { 1538 if (ifp->if_flags & IFF_DEBUG) {
1539 if (txEvent & TX_EVENT_LOSS_CRS) 1539 if (txEvent & TX_EVENT_LOSS_CRS)
1540 aprint_error_dev(sc->sc_dev, "lost carrier\n"); 1540 aprint_error_dev(sc->sc_dev, "lost carrier\n");
1541 1541
1542 if (txEvent & TX_EVENT_SQE_ERR) 1542 if (txEvent & TX_EVENT_SQE_ERR)
1543 aprint_error_dev(sc->sc_dev, "SQE error\n"); 1543 aprint_error_dev(sc->sc_dev, "SQE error\n");
1544 1544
1545 if (txEvent & TX_EVENT_OUT_WIN) 1545 if (txEvent & TX_EVENT_OUT_WIN)
1546 aprint_error_dev(sc->sc_dev, 1546 aprint_error_dev(sc->sc_dev,
1547 "out-of-window collision\n"); 1547 "out-of-window collision\n");
1548 1548
1549 if (txEvent & TX_EVENT_JABBER) 1549 if (txEvent & TX_EVENT_JABBER)
1550 aprint_error_dev(sc->sc_dev, "jabber\n"); 1550 aprint_error_dev(sc->sc_dev, "jabber\n");
1551 1551
1552 if (txEvent & TX_EVENT_16_COLL) 1552 if (txEvent & TX_EVENT_16_COLL)
1553 aprint_error_dev(sc->sc_dev, 1553 aprint_error_dev(sc->sc_dev,
1554 "16 collisions\n"); 1554 "16 collisions\n");
1555 } 1555 }
1556 } else { 1556 } else {
1557 /* Transmission successful, carrier is up. */ 1557 /* Transmission successful, carrier is up. */
1558 sc->sc_carrier = 1; 1558 sc->sc_carrier = 1;
1559#ifdef SHARK 1559#ifdef SHARK
1560 ledNetActive(); 1560 ledNetActive();
1561#endif 1561#endif
1562 } 1562 }
1563 1563
1564 /* Add the number of collisions for this frame */ 1564 /* Add the number of collisions for this frame */
 1565 net_stat_ref_t nsr = IF_STAT_GETREF(ifp);
1565 if (txEvent & TX_EVENT_16_COLL) 1566 if (txEvent & TX_EVENT_16_COLL)
1566 ifp->if_collisions += 16; 1567 if_statadd_ref(nsr, if_collisions, 16);
1567 else 1568 else
1568 ifp->if_collisions += ((txEvent & TX_EVENT_COLL_MASK) >> 11); 1569 if_statadd_ref(nsr, if_collisions,
 1570 ((txEvent & TX_EVENT_COLL_MASK) >> 11));
1569 1571
1570 ifp->if_opackets++; 1572 if_statinc_ref(nsr, if_opackets);
 1573 IF_STAT_PUTREF(ifp);
1571 1574
1572 /* Transmission is no longer in progress */ 1575 /* Transmission is no longer in progress */
1573 sc->sc_txbusy = FALSE; 1576 sc->sc_txbusy = FALSE;
1574 1577
1575 /* If there is more to transmit, start the next transmission */ 1578 /* If there is more to transmit, start the next transmission */
1576 if_schedule_deferred_start(ifp); 1579 if_schedule_deferred_start(ifp);
1577} 1580}
1578 1581
1579void 1582void
1580cs_print_rx_errors(struct cs_softc *sc, uint16_t rxEvent) 1583cs_print_rx_errors(struct cs_softc *sc, uint16_t rxEvent)
1581{ 1584{
1582 1585
1583 if (rxEvent & RX_EVENT_RUNT) 1586 if (rxEvent & RX_EVENT_RUNT)
1584 aprint_error_dev(sc->sc_dev, "runt\n"); 1587 aprint_error_dev(sc->sc_dev, "runt\n");
1585 1588
1586 if (rxEvent & RX_EVENT_X_DATA) 1589 if (rxEvent & RX_EVENT_X_DATA)
1587 aprint_error_dev(sc->sc_dev, "extra data\n"); 1590 aprint_error_dev(sc->sc_dev, "extra data\n");
1588 1591
1589 if (rxEvent & RX_EVENT_CRC_ERR) { 1592 if (rxEvent & RX_EVENT_CRC_ERR) {
1590 if (rxEvent & RX_EVENT_DRIBBLE) 1593 if (rxEvent & RX_EVENT_DRIBBLE)
1591 aprint_error_dev(sc->sc_dev, "alignment error\n"); 1594 aprint_error_dev(sc->sc_dev, "alignment error\n");
1592 else 1595 else
1593 aprint_error_dev(sc->sc_dev, "CRC error\n"); 1596 aprint_error_dev(sc->sc_dev, "CRC error\n");
1594 } else { 1597 } else {
1595 if (rxEvent & RX_EVENT_DRIBBLE) 1598 if (rxEvent & RX_EVENT_DRIBBLE)
1596 aprint_error_dev(sc->sc_dev, "dribble bits\n"); 1599 aprint_error_dev(sc->sc_dev, "dribble bits\n");
1597 } 1600 }
1598} 1601}
1599 1602
1600void 1603void
1601cs_receive_event(struct cs_softc *sc, uint16_t rxEvent) 1604cs_receive_event(struct cs_softc *sc, uint16_t rxEvent)
1602{ 1605{
1603 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 1606 struct ifnet *ifp = &sc->sc_ethercom.ec_if;
1604 1607
1605 /* If the frame was not received OK */ 1608 /* If the frame was not received OK */
1606 if (!(rxEvent & RX_EVENT_RX_OK)) { 1609 if (!(rxEvent & RX_EVENT_RX_OK)) {
1607 /* Increment the input error count */ 1610 /* Increment the input error count */
1608 ifp->if_ierrors++; 1611 if_statinc(ifp, if_ierrors);
1609 1612
1610 /* If debugging is enabled then log error messages. */ 1613 /* If debugging is enabled then log error messages. */
1611 if (ifp->if_flags & IFF_DEBUG) { 1614 if (ifp->if_flags & IFF_DEBUG) {
1612 if (rxEvent != REG_NUM_RX_EVENT) { 1615 if (rxEvent != REG_NUM_RX_EVENT) {
1613 cs_print_rx_errors(sc, rxEvent); 1616 cs_print_rx_errors(sc, rxEvent);
1614 1617
1615 /* 1618 /*
1616 * Must read the length of all received 1619 * Must read the length of all received
1617 * frames 1620 * frames
1618 */ 1621 */
1619 CS_READ_PACKET_PAGE(sc, PKTPG_RX_LENGTH); 1622 CS_READ_PACKET_PAGE(sc, PKTPG_RX_LENGTH);
1620 1623
1621 /* Skip the received frame */ 1624 /* Skip the received frame */
1622 CS_WRITE_PACKET_PAGE(sc, PKTPG_RX_CFG, 1625 CS_WRITE_PACKET_PAGE(sc, PKTPG_RX_CFG,
1623 CS_READ_PACKET_PAGE(sc, PKTPG_RX_CFG) | 1626 CS_READ_PACKET_PAGE(sc, PKTPG_RX_CFG) |
1624 RX_CFG_SKIP); 1627 RX_CFG_SKIP);
1625 } else 1628 } else
1626 aprint_error_dev(sc->sc_dev, "implied skip\n"); 1629 aprint_error_dev(sc->sc_dev, "implied skip\n");
1627 } 1630 }
1628 } else { 1631 } else {
1629 /* 1632 /*
1630 * Process the received frame and pass it up to the upper 1633 * Process the received frame and pass it up to the upper
1631 * layers. 1634 * layers.
1632 */ 1635 */
1633 cs_process_receive(sc); 1636 cs_process_receive(sc);
1634 } 1637 }
1635} 1638}
1636 1639
1637void 1640void
1638cs_ether_input(struct cs_softc *sc, struct mbuf *m) 1641cs_ether_input(struct cs_softc *sc, struct mbuf *m)
1639{ 1642{
1640 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 1643 struct ifnet *ifp = &sc->sc_ethercom.ec_if;
1641 1644
1642 /* Pass the packet up. */ 1645 /* Pass the packet up. */
1643 if_percpuq_enqueue(ifp->if_percpuq, m); 1646 if_percpuq_enqueue(ifp->if_percpuq, m);
1644} 1647}
1645 1648
1646void 1649void
1647cs_process_receive(struct cs_softc *sc) 1650cs_process_receive(struct cs_softc *sc)
1648{ 1651{
1649 struct ifnet *ifp; 1652 struct ifnet *ifp;
1650 struct mbuf *m; 1653 struct mbuf *m;
1651 int totlen; 1654 int totlen;
1652 uint16_t *pBuff, *pBuffLimit; 1655 uint16_t *pBuff, *pBuffLimit;
1653 int pad; 1656 int pad;
1654 unsigned int frameOffset = 0; /* XXX: gcc */ 1657 unsigned int frameOffset = 0; /* XXX: gcc */
1655 1658
1656#ifdef SHARK 1659#ifdef SHARK
1657 ledNetActive(); 1660 ledNetActive();
1658#endif 1661#endif
1659 1662
1660 ifp = &sc->sc_ethercom.ec_if; 1663 ifp = &sc->sc_ethercom.ec_if;
1661 1664
1662 /* Received a packet; carrier is up. */ 1665 /* Received a packet; carrier is up. */
1663 sc->sc_carrier = 1; 1666 sc->sc_carrier = 1;
1664 1667
1665 if (sc->sc_memorymode) { 1668 if (sc->sc_memorymode) {
1666 /* Initialize the frame offset */ 1669 /* Initialize the frame offset */
1667 frameOffset = PKTPG_RX_LENGTH; 1670 frameOffset = PKTPG_RX_LENGTH;
1668 1671
1669 /* Get the length of the received frame */ 1672 /* Get the length of the received frame */
1670 totlen = CS_READ_PACKET_PAGE(sc, frameOffset); 1673 totlen = CS_READ_PACKET_PAGE(sc, frameOffset);
1671 frameOffset += 2; 1674 frameOffset += 2;
1672 } else { 1675 } else {
1673 /* Drop status */ 1676 /* Drop status */
1674 CS_READ_PORT(sc, PORT_RXTX_DATA); 1677 CS_READ_PORT(sc, PORT_RXTX_DATA);
1675 1678
1676 /* Get the length of the received frame */ 1679 /* Get the length of the received frame */
1677 totlen = CS_READ_PORT(sc, PORT_RXTX_DATA); 1680 totlen = CS_READ_PORT(sc, PORT_RXTX_DATA);
1678 } 1681 }
1679 1682
1680 if (totlen > ETHER_MAX_LEN) { 1683 if (totlen > ETHER_MAX_LEN) {
1681 aprint_error_dev(sc->sc_dev, "invalid packet length %d\n", 1684 aprint_error_dev(sc->sc_dev, "invalid packet length %d\n",
1682 totlen); 1685 totlen);
1683 1686
1684 /* Skip the received frame */ 1687 /* Skip the received frame */
1685 CS_WRITE_PACKET_PAGE(sc, PKTPG_RX_CFG, 1688 CS_WRITE_PACKET_PAGE(sc, PKTPG_RX_CFG,
1686 CS_READ_PACKET_PAGE(sc, PKTPG_RX_CFG) | RX_CFG_SKIP); 1689 CS_READ_PACKET_PAGE(sc, PKTPG_RX_CFG) | RX_CFG_SKIP);
1687 return; 1690 return;
1688 } 1691 }
1689 1692
1690 MGETHDR(m, M_DONTWAIT, MT_DATA); 1693 MGETHDR(m, M_DONTWAIT, MT_DATA);
1691 if (m == 0) { 1694 if (m == 0) {
1692 aprint_error_dev(sc->sc_dev, 1695 aprint_error_dev(sc->sc_dev,
1693 "cs_process_receive: unable to allocate mbuf\n"); 1696 "cs_process_receive: unable to allocate mbuf\n");
1694 ifp->if_ierrors++; 1697 if_statinc(ifp, if_ierrors);
1695 /* 1698 /*
1696 * Couldn't allocate an mbuf so things are not good, may as 1699 * Couldn't allocate an mbuf so things are not good, may as
1697 * well drop the packet I think. 1700 * well drop the packet I think.
1698 * 1701 *
1699 * have already read the length so we should be right to skip 1702 * have already read the length so we should be right to skip
1700 * the packet. 1703 * the packet.
1701 */ 1704 */
1702 CS_WRITE_PACKET_PAGE(sc, PKTPG_RX_CFG, 1705 CS_WRITE_PACKET_PAGE(sc, PKTPG_RX_CFG,
1703 CS_READ_PACKET_PAGE(sc, PKTPG_RX_CFG) | RX_CFG_SKIP); 1706 CS_READ_PACKET_PAGE(sc, PKTPG_RX_CFG) | RX_CFG_SKIP);
1704 return; 1707 return;
1705 } 1708 }
1706 m_set_rcvif(m, ifp); 1709 m_set_rcvif(m, ifp);
1707 m->m_pkthdr.len = totlen; 1710 m->m_pkthdr.len = totlen;
1708 1711
1709 /* Number of bytes to align ip header on word boundary for ipintr */ 1712 /* Number of bytes to align ip header on word boundary for ipintr */
1710 pad = ALIGN(sizeof(struct ether_header)) - sizeof(struct ether_header); 1713 pad = ALIGN(sizeof(struct ether_header)) - sizeof(struct ether_header);
1711 1714
1712 /* 1715 /*
1713 * Alloc mbuf cluster if we need. 1716 * Alloc mbuf cluster if we need.
1714 * We need 1 byte spare because following packet read loop can overrun. 1717 * We need 1 byte spare because following packet read loop can overrun.
1715 */ 1718 */
1716 if (totlen + pad + 1 > MHLEN) { 1719 if (totlen + pad + 1 > MHLEN) {
1717 MCLGET(m, M_DONTWAIT); 1720 MCLGET(m, M_DONTWAIT);
1718 if ((m->m_flags & M_EXT) == 0) { 1721 if ((m->m_flags & M_EXT) == 0) {
1719 /* Couldn't allocate an mbuf cluster */ 1722 /* Couldn't allocate an mbuf cluster */
1720 aprint_error_dev(sc->sc_dev, 1723 aprint_error_dev(sc->sc_dev,
1721 "cs_process_receive: " 1724 "cs_process_receive: "
1722 "unable to allocate a cluster\n"); 1725 "unable to allocate a cluster\n");
1723 m_freem(m); 1726 m_freem(m);
1724 1727
1725 /* Skip the received frame */ 1728 /* Skip the received frame */
1726 CS_WRITE_PACKET_PAGE(sc, PKTPG_RX_CFG, 1729 CS_WRITE_PACKET_PAGE(sc, PKTPG_RX_CFG,
1727 CS_READ_PACKET_PAGE(sc, PKTPG_RX_CFG) 1730 CS_READ_PACKET_PAGE(sc, PKTPG_RX_CFG)
1728 | RX_CFG_SKIP); 1731 | RX_CFG_SKIP);
1729 return; 1732 return;
1730 } 1733 }
1731 } 1734 }
1732 1735
1733 /* Align ip header on word boundary for ipintr */ 1736 /* Align ip header on word boundary for ipintr */
1734 m->m_data += pad; 1737 m->m_data += pad;
1735 1738
1736 m->m_len = totlen; 1739 m->m_len = totlen;
1737 pBuff = mtod(m, uint16_t *); 1740 pBuff = mtod(m, uint16_t *);
1738 1741
1739 /* Now read the data from the chip */ 1742 /* Now read the data from the chip */
1740 if (sc->sc_memorymode) { 1743 if (sc->sc_memorymode) {
1741 /* Don't want to go over */ 1744 /* Don't want to go over */
1742 pBuffLimit = pBuff + (totlen + 1) / 2; 1745 pBuffLimit = pBuff + (totlen + 1) / 2;
1743 1746
1744 while (pBuff < pBuffLimit) { 1747 while (pBuff < pBuffLimit) {
1745 *pBuff++ = CS_READ_PACKET_PAGE(sc, frameOffset); 1748 *pBuff++ = CS_READ_PACKET_PAGE(sc, frameOffset);
1746 frameOffset += 2; 1749 frameOffset += 2;
1747 } 1750 }
1748 } else 1751 } else
1749 IO_READ_MULTI_2(sc, PORT_RXTX_DATA, pBuff, (totlen + 1)>>1); 1752 IO_READ_MULTI_2(sc, PORT_RXTX_DATA, pBuff, (totlen + 1)>>1);
1750 1753
1751 cs_ether_input(sc, m); 1754 cs_ether_input(sc, m);
1752} 1755}
1753 1756
1754void 1757void
1755cs_process_rx_early(struct cs_softc *sc) 1758cs_process_rx_early(struct cs_softc *sc)
1756{ 1759{
1757 struct ifnet *ifp; 1760 struct ifnet *ifp;
1758 struct mbuf *m; 1761 struct mbuf *m;
1759 uint16_t frameCount, oldFrameCount; 1762 uint16_t frameCount, oldFrameCount;
1760 uint16_t rxEvent; 1763 uint16_t rxEvent;
1761 uint16_t *pBuff; 1764 uint16_t *pBuff;
1762 int pad; 1765 int pad;
1763 unsigned int frameOffset; 1766 unsigned int frameOffset;
1764 1767
1765 1768
1766 ifp = &sc->sc_ethercom.ec_if; 1769 ifp = &sc->sc_ethercom.ec_if;
1767 1770
1768 /* Initialize the frame offset */ 1771 /* Initialize the frame offset */
1769 frameOffset = PKTPG_RX_FRAME; 1772 frameOffset = PKTPG_RX_FRAME;
1770 frameCount = 0; 1773 frameCount = 0;
1771 1774
1772 MGETHDR(m, M_DONTWAIT, MT_DATA); 1775 MGETHDR(m, M_DONTWAIT, MT_DATA);
1773 if (m == 0) { 1776 if (m == 0) {
1774 aprint_error_dev(sc->sc_dev, 1777 aprint_error_dev(sc->sc_dev,
1775 "cs_process_rx_early: unable to allocate mbuf\n"); 1778 "cs_process_rx_early: unable to allocate mbuf\n");
1776 ifp->if_ierrors++; 1779 if_statinc(ifp, if_ierrors);
1777 /* 1780 /*
1778 * Couldn't allocate an mbuf so things are not good, may as 1781 * Couldn't allocate an mbuf so things are not good, may as
1779 * well drop the packet I think. 1782 * well drop the packet I think.
1780 * 1783 *
1781 * have already read the length so we should be right to skip 1784 * have already read the length so we should be right to skip
1782 * the packet. 1785 * the packet.
1783 */ 1786 */
1784 CS_WRITE_PACKET_PAGE(sc, PKTPG_RX_CFG, 1787 CS_WRITE_PACKET_PAGE(sc, PKTPG_RX_CFG,
1785 CS_READ_PACKET_PAGE(sc, PKTPG_RX_CFG) | RX_CFG_SKIP); 1788 CS_READ_PACKET_PAGE(sc, PKTPG_RX_CFG) | RX_CFG_SKIP);
1786 return; 1789 return;
1787 } 1790 }
1788 m_set_rcvif(m, ifp); 1791 m_set_rcvif(m, ifp);
1789 /* 1792 /*
1790 * Save processing by always using a mbuf cluster, guaranteed to fit 1793 * Save processing by always using a mbuf cluster, guaranteed to fit
1791 * packet 1794 * packet
1792 */ 1795 */
1793 MCLGET(m, M_DONTWAIT); 1796 MCLGET(m, M_DONTWAIT);
1794 if ((m->m_flags & M_EXT) == 0) { 1797 if ((m->m_flags & M_EXT) == 0) {
1795 /* Couldn't allocate an mbuf cluster */ 1798 /* Couldn't allocate an mbuf cluster */
1796 aprint_error_dev(sc->sc_dev, 1799 aprint_error_dev(sc->sc_dev,
1797 "cs_process_rx_early: unable to allocate a cluster\n"); 1800 "cs_process_rx_early: unable to allocate a cluster\n");
1798 m_freem(m); 1801 m_freem(m);
1799 /* Skip the frame */ 1802 /* Skip the frame */
1800 CS_WRITE_PACKET_PAGE(sc, PKTPG_RX_CFG, 1803 CS_WRITE_PACKET_PAGE(sc, PKTPG_RX_CFG,
1801 CS_READ_PACKET_PAGE(sc, PKTPG_RX_CFG) | RX_CFG_SKIP); 1804 CS_READ_PACKET_PAGE(sc, PKTPG_RX_CFG) | RX_CFG_SKIP);
1802 return; 1805 return;
1803 } 1806 }
1804 1807
1805 /* Align ip header on word boundary for ipintr */ 1808 /* Align ip header on word boundary for ipintr */
1806 pad = ALIGN(sizeof(struct ether_header)) - sizeof(struct ether_header); 1809 pad = ALIGN(sizeof(struct ether_header)) - sizeof(struct ether_header);
1807 m->m_data += pad; 1810 m->m_data += pad;
1808 1811
1809 /* Set up the buffer pointer to point to the data area */ 1812 /* Set up the buffer pointer to point to the data area */
1810 pBuff = mtod(m, uint16_t *); 1813 pBuff = mtod(m, uint16_t *);
1811 1814
1812 /* 1815 /*
1813 * Now read the frame byte counter until we have finished reading the 1816 * Now read the frame byte counter until we have finished reading the
1814 * frame 1817 * frame
1815 */ 1818 */
1816 oldFrameCount = 0; 1819 oldFrameCount = 0;
1817 frameCount = CS_READ_PACKET_PAGE(sc, PKTPG_FRAME_BYTE_COUNT); 1820 frameCount = CS_READ_PACKET_PAGE(sc, PKTPG_FRAME_BYTE_COUNT);
1818 while ((frameCount != 0) && (frameCount < MCLBYTES)) { 1821 while ((frameCount != 0) && (frameCount < MCLBYTES)) {
1819 for (; oldFrameCount < frameCount; oldFrameCount += 2) { 1822 for (; oldFrameCount < frameCount; oldFrameCount += 2) {
1820 *pBuff++ = CS_READ_PACKET_PAGE(sc, frameOffset); 1823 *pBuff++ = CS_READ_PACKET_PAGE(sc, frameOffset);
1821 frameOffset += 2; 1824 frameOffset += 2;
1822 } 1825 }
1823 1826
1824 /* Read the new count from the chip */ 1827 /* Read the new count from the chip */
1825 frameCount = CS_READ_PACKET_PAGE(sc, PKTPG_FRAME_BYTE_COUNT); 1828 frameCount = CS_READ_PACKET_PAGE(sc, PKTPG_FRAME_BYTE_COUNT);
1826 } 1829 }
1827 1830
1828 /* Update the mbuf counts */ 1831 /* Update the mbuf counts */
1829 m->m_len = oldFrameCount; 1832 m->m_len = oldFrameCount;
1830 m->m_pkthdr.len = oldFrameCount; 1833 m->m_pkthdr.len = oldFrameCount;
1831 1834
1832 /* Now check the Rx Event register */ 1835 /* Now check the Rx Event register */
1833 rxEvent = CS_READ_PACKET_PAGE(sc, PKTPG_RX_EVENT); 1836 rxEvent = CS_READ_PACKET_PAGE(sc, PKTPG_RX_EVENT);
1834 1837
1835 if ((rxEvent & RX_EVENT_RX_OK) != 0) { 1838 if ((rxEvent & RX_EVENT_RX_OK) != 0) {
1836 /* 1839 /*
1837 * Do an implied skip, it seems to be more reliable than a 1840 * Do an implied skip, it seems to be more reliable than a
1838 * forced skip. 1841 * forced skip.
1839 */ 1842 */
1840 rxEvent = CS_READ_PACKET_PAGE(sc, PKTPG_RX_STATUS); 1843 rxEvent = CS_READ_PACKET_PAGE(sc, PKTPG_RX_STATUS);
1841 rxEvent = CS_READ_PACKET_PAGE(sc, PKTPG_RX_LENGTH); 1844 rxEvent = CS_READ_PACKET_PAGE(sc, PKTPG_RX_LENGTH);
1842 1845
1843 /* 1846 /*
1844 * Now read the RX_EVENT register to perform an implied skip. 1847 * Now read the RX_EVENT register to perform an implied skip.
1845 */ 1848 */
1846 rxEvent = CS_READ_PACKET_PAGE(sc, PKTPG_RX_EVENT); 1849 rxEvent = CS_READ_PACKET_PAGE(sc, PKTPG_RX_EVENT);
1847 1850
1848 cs_ether_input(sc, m); 1851 cs_ether_input(sc, m);
1849 } else { 1852 } else {
1850 m_freem(m); 1853 m_freem(m);
1851 ifp->if_ierrors++; 1854 if_statinc(ifp, if_ierrors);
1852 } 1855 }
1853} 1856}
1854 1857
1855void 1858void
1856cs_start_output(struct ifnet *ifp) 1859cs_start_output(struct ifnet *ifp)
1857{ 1860{
1858 struct cs_softc *sc; 1861 struct cs_softc *sc;
1859 struct mbuf *pMbuf; 1862 struct mbuf *pMbuf;
1860 struct mbuf *pMbufChain; 1863 struct mbuf *pMbufChain;
1861 uint16_t BusStatus; 1864 uint16_t BusStatus;
1862 uint16_t Length; 1865 uint16_t Length;
1863 int txLoop = 0; 1866 int txLoop = 0;
1864 int dropout = 0; 1867 int dropout = 0;
1865 1868
1866 sc = ifp->if_softc; 1869 sc = ifp->if_softc;
1867 1870
1868 /* Check that the interface is up and running */ 1871 /* Check that the interface is up and running */
1869 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING) 1872 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
1870 return; 1873 return;
1871 1874
1872 /* Don't interrupt a transmission in progress */ 1875 /* Don't interrupt a transmission in progress */
1873 if (sc->sc_txbusy) 1876 if (sc->sc_txbusy)
1874 return; 1877 return;
1875 1878
1876 /* This loop will only run through once if transmission is successful */ 1879 /* This loop will only run through once if transmission is successful */
1877 /* 1880 /*
1878 * While there are packets to transmit and a transmit is not in 1881 * While there are packets to transmit and a transmit is not in
1879 * progress 1882 * progress
1880 */ 1883 */
1881 while (sc->sc_txbusy == 0 && dropout == 0) { 1884 while (sc->sc_txbusy == 0 && dropout == 0) {
1882 IFQ_DEQUEUE(&ifp->if_snd, pMbufChain); 1885 IFQ_DEQUEUE(&ifp->if_snd, pMbufChain);
1883 if (pMbufChain == NULL) 1886 if (pMbufChain == NULL)
1884 break; 1887 break;
1885 1888
1886 /* 1889 /*
1887 * If BPF is listening on this interface, let it see the packet 1890 * If BPF is listening on this interface, let it see the packet
1888 * before we commit it to the wire. 1891 * before we commit it to the wire.
1889 */ 1892 */
1890 bpf_mtap(ifp, pMbufChain, BPF_D_OUT); 1893 bpf_mtap(ifp, pMbufChain, BPF_D_OUT);
1891 1894
1892 /* Find the total length of the data to transmit */ 1895 /* Find the total length of the data to transmit */
1893 Length = 0; 1896 Length = 0;
1894 for (pMbuf = pMbufChain; pMbuf != NULL; pMbuf = pMbuf->m_next) 1897 for (pMbuf = pMbufChain; pMbuf != NULL; pMbuf = pMbuf->m_next)
1895 Length += pMbuf->m_len; 1898 Length += pMbuf->m_len;
1896 1899
1897 do { 1900 do {
1898 /* 1901 /*
1899 * Request that the transmit be started after all 1902 * Request that the transmit be started after all
1900 * data has been copied 1903 * data has been copied
1901 * 1904 *
1902 * In IO mode must write to the IO port not the packet 1905 * In IO mode must write to the IO port not the packet
1903 * page address 1906 * page address
1904 * 1907 *
1905 * If this is changed to start transmission after a 1908 * If this is changed to start transmission after a
1906 * small amount of data has been copied you tend to 1909 * small amount of data has been copied you tend to
1907 * get packet missed errors i think because the ISA 1910 * get packet missed errors i think because the ISA
1908 * bus is too slow. Or possibly the copy routine is 1911 * bus is too slow. Or possibly the copy routine is
1909 * not streamlined enough. 1912 * not streamlined enough.
1910 */ 1913 */
1911 if (sc->sc_memorymode) { 1914 if (sc->sc_memorymode) {
1912 CS_WRITE_PACKET_PAGE(sc, PKTPG_TX_CMD, 1915 CS_WRITE_PACKET_PAGE(sc, PKTPG_TX_CMD,
1913 cs_xmit_early_table[sc->sc_xe_ent].txcmd); 1916 cs_xmit_early_table[sc->sc_xe_ent].txcmd);
1914 CS_WRITE_PACKET_PAGE(sc, PKTPG_TX_LENGTH, Length); 1917 CS_WRITE_PACKET_PAGE(sc, PKTPG_TX_LENGTH, Length);
1915 } else { 1918 } else {
1916 CS_WRITE_PORT(sc, PORT_TX_CMD, 1919 CS_WRITE_PORT(sc, PORT_TX_CMD,
1917 cs_xmit_early_table[sc->sc_xe_ent].txcmd); 1920 cs_xmit_early_table[sc->sc_xe_ent].txcmd);
1918 CS_WRITE_PORT(sc, PORT_TX_LENGTH, Length); 1921 CS_WRITE_PORT(sc, PORT_TX_LENGTH, Length);
1919 } 1922 }
1920 1923
1921 /* Adjust early-transmit machinery. */ 1924 /* Adjust early-transmit machinery. */
1922 if (--sc->sc_xe_togo == 0) { 1925 if (--sc->sc_xe_togo == 0) {
1923 sc->sc_xe_ent = 1926 sc->sc_xe_ent =
1924 cs_xmit_early_table[sc->sc_xe_ent].better; 1927 cs_xmit_early_table[sc->sc_xe_ent].better;
1925 sc->sc_xe_togo = 1928 sc->sc_xe_togo =
1926 cs_xmit_early_table[sc->sc_xe_ent].better_count; 1929 cs_xmit_early_table[sc->sc_xe_ent].better_count;
1927 } 1930 }
1928 /* 1931 /*
1929 * Read the BusStatus register which indicates 1932 * Read the BusStatus register which indicates
1930 * success of the request 1933 * success of the request
1931 */ 1934 */
1932 BusStatus = CS_READ_PACKET_PAGE(sc, PKTPG_BUS_ST); 1935 BusStatus = CS_READ_PACKET_PAGE(sc, PKTPG_BUS_ST);
1933 1936
1934 /* 1937 /*
1935 * If there was an error in the transmit bid free the 1938 * If there was an error in the transmit bid free the
1936 * mbuf and go on. This is presuming that mbuf is 1939 * mbuf and go on. This is presuming that mbuf is
1937 * corrupt. 1940 * corrupt.
1938 */ 1941 */
1939 if (BusStatus & BUS_ST_TX_BID_ERR) { 1942 if (BusStatus & BUS_ST_TX_BID_ERR) {
1940 aprint_error_dev(sc->sc_dev, 1943 aprint_error_dev(sc->sc_dev,
1941 "transmit bid error (too big)"); 1944 "transmit bid error (too big)");
1942 1945
1943 /* Discard the bad mbuf chain */ 1946 /* Discard the bad mbuf chain */
1944 m_freem(pMbufChain); 1947 m_freem(pMbufChain);
1945 sc->sc_ethercom.ec_if.if_oerrors++; 1948 if_statinc(&sc->sc_ethercom.ec_if, if_oerrors);
1946 1949
1947 /* Loop up to transmit the next chain */ 1950 /* Loop up to transmit the next chain */
1948 txLoop = 0; 1951 txLoop = 0;
1949 } else { 1952 } else {
1950 if (BusStatus & BUS_ST_RDY4TXNOW) { 1953 if (BusStatus & BUS_ST_RDY4TXNOW) {
1951 /* 1954 /*
1952 * The chip is ready for transmission 1955 * The chip is ready for transmission
1953 * now 1956 * now
1954 */ 1957 */
1955 /* 1958 /*
1956 * Copy the frame to the chip to 1959 * Copy the frame to the chip to
1957 * start transmission 1960 * start transmission
1958 */ 1961 */
1959 cs_copy_tx_frame(sc, pMbufChain); 1962 cs_copy_tx_frame(sc, pMbufChain);
1960 1963
1961 /* Free the mbuf chain */ 1964 /* Free the mbuf chain */
1962 m_freem(pMbufChain); 1965 m_freem(pMbufChain);
1963 1966
1964 /* Transmission is now in progress */ 1967 /* Transmission is now in progress */
1965 sc->sc_txbusy = TRUE; 1968 sc->sc_txbusy = TRUE;
1966 txLoop = 0; 1969 txLoop = 0;
1967 } else { 1970 } else {
1968 /* 1971 /*
1969 * If we get here we want to try 1972 * If we get here we want to try
1970 * again with the same mbuf, until 1973 * again with the same mbuf, until
1971 * the chip lets us transmit. 1974 * the chip lets us transmit.
1972 */ 1975 */
1973 txLoop++; 1976 txLoop++;
1974 if (txLoop > CS_OUTPUT_LOOP_MAX) { 1977 if (txLoop > CS_OUTPUT_LOOP_MAX) {
1975 /* Free the mbuf chain */ 1978 /* Free the mbuf chain */
1976 m_freem(pMbufChain); 1979 m_freem(pMbufChain);
1977 /* 1980 /*
1978 * Transmission is not in 1981 * Transmission is not in
1979 * progress 1982 * progress
1980 */ 1983 */
1981 sc->sc_txbusy = FALSE; 1984 sc->sc_txbusy = FALSE;
1982 /* 1985 /*
1983 * Increment the output error 1986 * Increment the output error
1984 * count 1987 * count
1985 */ 1988 */
1986 ifp->if_oerrors++; 1989 if_statinc(ifp, if_oerrors);
1987 /* 1990 /*
1988 * exit the routine and drop 1991 * exit the routine and drop
1989 * the packet. 1992 * the packet.
1990 */ 1993 */
1991 txLoop = 0; 1994 txLoop = 0;
1992 dropout = 1; 1995 dropout = 1;
1993 } 1996 }
1994 } 1997 }
1995 } 1998 }
1996 } while (txLoop); 1999 } while (txLoop);
1997 } 2000 }
1998} 2001}
1999 2002
2000void 2003void
2001cs_copy_tx_frame(struct cs_softc *sc, struct mbuf *m0) 2004cs_copy_tx_frame(struct cs_softc *sc, struct mbuf *m0)
2002{ 2005{
2003 struct mbuf *m; 2006 struct mbuf *m;
2004 int len, leftover, frameoff; 2007 int len, leftover, frameoff;
2005 uint16_t dbuf; 2008 uint16_t dbuf;
2006 uint8_t *p; 2009 uint8_t *p;
2007#ifdef DIAGNOSTIC 2010#ifdef DIAGNOSTIC
2008 uint8_t *lim; 2011 uint8_t *lim;
2009#endif 2012#endif
2010 2013
2011 /* Initialize frame pointer and data port address */ 2014 /* Initialize frame pointer and data port address */
2012 frameoff = PKTPG_TX_FRAME; 2015 frameoff = PKTPG_TX_FRAME;
2013 2016
2014 /* Start out with no leftover data */ 2017 /* Start out with no leftover data */
2015 leftover = 0; 2018 leftover = 0;
2016 dbuf = 0; 2019 dbuf = 0;
2017 2020
2018 /* Process the chain of mbufs */ 2021 /* Process the chain of mbufs */
2019 for (m = m0; m != NULL; m = m->m_next) { 2022 for (m = m0; m != NULL; m = m->m_next) {
2020 /* Process all of the data in a single mbuf. */ 2023 /* Process all of the data in a single mbuf. */
2021 p = mtod(m, uint8_t *); 2024 p = mtod(m, uint8_t *);
2022 len = m->m_len; 2025 len = m->m_len;
2023#ifdef DIAGNOSTIC 2026#ifdef DIAGNOSTIC
2024 lim = p + len; 2027 lim = p + len;
2025#endif 2028#endif
2026 2029
2027 while (len > 0) { 2030 while (len > 0) {
2028 if (leftover) { 2031 if (leftover) {
2029 /* 2032 /*
2030 * Data left over (from mbuf or realignment). 2033 * Data left over (from mbuf or realignment).
2031 * Buffer the next byte, and write it and 2034 * Buffer the next byte, and write it and
2032 * the leftover data out. 2035 * the leftover data out.
2033 */ 2036 */
2034 dbuf |= *p++ << 8; 2037 dbuf |= *p++ << 8;
2035 len--; 2038 len--;
2036 if (sc->sc_memorymode) { 2039 if (sc->sc_memorymode) {
2037 CS_WRITE_PACKET_PAGE(sc, frameoff, dbuf); 2040 CS_WRITE_PACKET_PAGE(sc, frameoff, dbuf);
2038 frameoff += 2; 2041 frameoff += 2;
2039 } 2042 }
2040 else { 2043 else {
2041 CS_WRITE_PORT(sc, PORT_RXTX_DATA, dbuf); 2044 CS_WRITE_PORT(sc, PORT_RXTX_DATA, dbuf);
2042 } 2045 }
2043 leftover = 0; 2046 leftover = 0;
2044 } else if ((long) p & 1) { 2047 } else if ((long) p & 1) {
2045 /* Misaligned data. Buffer the next byte. */ 2048 /* Misaligned data. Buffer the next byte. */
2046 dbuf = *p++; 2049 dbuf = *p++;
2047 len--; 2050 len--;
2048 leftover = 1; 2051 leftover = 1;
2049 } else { 2052 } else {
2050 /* 2053 /*
2051 * Aligned data. This is the case we like. 2054 * Aligned data. This is the case we like.
2052 * 2055 *
2053 * Write-region out as much as we can, then 2056 * Write-region out as much as we can, then
2054 * buffer the remaining byte (if any). 2057 * buffer the remaining byte (if any).
2055 */ 2058 */
2056 leftover = len & 1; 2059 leftover = len & 1;
2057 len &= ~1; 2060 len &= ~1;
2058 if (sc->sc_memorymode) { 2061 if (sc->sc_memorymode) {
2059 MEM_WRITE_REGION_2(sc, frameoff, 2062 MEM_WRITE_REGION_2(sc, frameoff,
2060 (uint16_t *) p, len >> 1); 2063 (uint16_t *) p, len >> 1);
2061 frameoff += len; 2064 frameoff += len;
2062 } else 2065 } else
2063 IO_WRITE_MULTI_2(sc, PORT_RXTX_DATA, 2066 IO_WRITE_MULTI_2(sc, PORT_RXTX_DATA,
2064 (uint16_t *)p, len >> 1); 2067 (uint16_t *)p, len >> 1);
2065 p += len; 2068 p += len;
2066 2069
2067 if (leftover) 2070 if (leftover)
2068 dbuf = *p++; 2071 dbuf = *p++;
2069 len = 0; 2072 len = 0;
2070 } 2073 }
2071 } 2074 }
2072 if (len < 0) 2075 if (len < 0)
2073 panic("cs_copy_tx_frame: negative len"); 2076 panic("cs_copy_tx_frame: negative len");
2074#ifdef DIAGNOSTIC 2077#ifdef DIAGNOSTIC
2075 if (p != lim) 2078 if (p != lim)
2076 panic("cs_copy_tx_frame: p != lim"); 2079 panic("cs_copy_tx_frame: p != lim");
2077#endif 2080#endif
2078 } 2081 }
2079 if (leftover) { 2082 if (leftover) {
2080 if (sc->sc_memorymode) 2083 if (sc->sc_memorymode)
2081 CS_WRITE_PACKET_PAGE(sc, frameoff, dbuf); 2084 CS_WRITE_PACKET_PAGE(sc, frameoff, dbuf);
2082 else 2085 else
2083 CS_WRITE_PORT(sc, PORT_RXTX_DATA, dbuf); 2086 CS_WRITE_PORT(sc, PORT_RXTX_DATA, dbuf);
2084 } 2087 }
2085} 2088}
2086 2089
2087static int 2090static int
2088cs_enable(struct cs_softc *sc) 2091cs_enable(struct cs_softc *sc)
2089{ 2092{
2090 2093
2091 if (CS_IS_ENABLED(sc) == 0) { 2094 if (CS_IS_ENABLED(sc) == 0) {
2092 if (sc->sc_enable != NULL) { 2095 if (sc->sc_enable != NULL) {
2093 int error; 2096 int error;
2094 2097
2095 error = (*sc->sc_enable)(sc); 2098 error = (*sc->sc_enable)(sc);
2096 if (error) 2099 if (error)
2097 return error; 2100 return error;
2098 } 2101 }
2099 sc->sc_cfgflags |= CFGFLG_ENABLED; 2102 sc->sc_cfgflags |= CFGFLG_ENABLED;
2100 } 2103 }
2101 2104
2102 return 0; 2105 return 0;
2103} 2106}
2104 2107
2105static void 2108static void
2106cs_disable(struct cs_softc *sc) 2109cs_disable(struct cs_softc *sc)
2107{ 2110{
2108 2111
2109 if (CS_IS_ENABLED(sc)) { 2112 if (CS_IS_ENABLED(sc)) {
2110 if (sc->sc_disable != NULL) 2113 if (sc->sc_disable != NULL)
2111 (*sc->sc_disable)(sc); 2114 (*sc->sc_disable)(sc);
2112 2115
2113 sc->sc_cfgflags &= ~CFGFLG_ENABLED; 2116 sc->sc_cfgflags &= ~CFGFLG_ENABLED;
2114 } 2117 }
2115} 2118}
2116 2119
2117static void 2120static void
2118cs_stop(struct ifnet *ifp, int disable) 2121cs_stop(struct ifnet *ifp, int disable)
2119{ 2122{
2120 struct cs_softc *sc = ifp->if_softc; 2123 struct cs_softc *sc = ifp->if_softc;
2121 2124
2122 CS_WRITE_PACKET_PAGE(sc, PKTPG_RX_CFG, 0); 2125 CS_WRITE_PACKET_PAGE(sc, PKTPG_RX_CFG, 0);
2123 CS_WRITE_PACKET_PAGE(sc, PKTPG_TX_CFG, 0); 2126 CS_WRITE_PACKET_PAGE(sc, PKTPG_TX_CFG, 0);
2124 CS_WRITE_PACKET_PAGE(sc, PKTPG_BUF_CFG, 0); 2127 CS_WRITE_PACKET_PAGE(sc, PKTPG_BUF_CFG, 0);
2125 CS_WRITE_PACKET_PAGE(sc, PKTPG_BUS_CTL, 0); 2128 CS_WRITE_PACKET_PAGE(sc, PKTPG_BUS_CTL, 0);
2126 2129
2127 if (disable) 2130 if (disable)
2128 cs_disable(sc); 2131 cs_disable(sc);
2129 2132
2130 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 2133 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
2131} 2134}
2132 2135
2133int 2136int
2134cs_activate(device_t self, enum devact act) 2137cs_activate(device_t self, enum devact act)
2135{ 2138{
2136 struct cs_softc *sc = device_private(self); 2139 struct cs_softc *sc = device_private(self);
2137 2140
2138 switch (act) { 2141 switch (act) {
2139 case DVACT_DEACTIVATE: 2142 case DVACT_DEACTIVATE:
2140 if_deactivate(&sc->sc_ethercom.ec_if); 2143 if_deactivate(&sc->sc_ethercom.ec_if);
2141 return 0; 2144 return 0;
2142 default: 2145 default:
2143 return EOPNOTSUPP; 2146 return EOPNOTSUPP;
2144 } 2147 }
2145} 2148}

cvs diff -r1.21 -r1.22 src/sys/dev/ic/dm9000.c (switch to unified diff)

--- src/sys/dev/ic/dm9000.c 2019/05/29 10:07:29 1.21
+++ src/sys/dev/ic/dm9000.c 2020/01/29 14:14:55 1.22
@@ -1,1229 +1,1229 @@ @@ -1,1229 +1,1229 @@
1/* $NetBSD: dm9000.c,v 1.21 2019/05/29 10:07:29 msaitoh Exp $ */ 1/* $NetBSD: dm9000.c,v 1.22 2020/01/29 14:14:55 thorpej Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2009 Paul Fleischer 4 * Copyright (c) 2009 Paul Fleischer
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution. 11 * documentation and/or other materials provided with the distribution.
12 * 3. The name of the company nor the name of the author may be used to 12 * 3. The name of the company nor the name of the author may be used to
13 * endorse or promote products derived from this software without specific 13 * endorse or promote products derived from this software without specific
14 * prior written permission. 14 * prior written permission.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 19 * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
20 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE. 26 * SUCH DAMAGE.
27 */ 27 */
28 28
29/* based on sys/dev/ic/cs89x0.c */ 29/* based on sys/dev/ic/cs89x0.c */
30/* 30/*
31 * Copyright (c) 2004 Christopher Gilbert 31 * Copyright (c) 2004 Christopher Gilbert
32 * All rights reserved. 32 * All rights reserved.
33 * 33 *
34 * 1. Redistributions of source code must retain the above copyright 34 * 1. Redistributions of source code must retain the above copyright
35 * notice, this list of conditions and the following disclaimer. 35 * notice, this list of conditions and the following disclaimer.
36 * 2. Redistributions in binary form must reproduce the above copyright 36 * 2. Redistributions in binary form must reproduce the above copyright
37 * notice, this list of conditions and the following disclaimer in the 37 * notice, this list of conditions and the following disclaimer in the
38 * documentation and/or other materials provided with the distribution. 38 * documentation and/or other materials provided with the distribution.
39 * 3. The name of the company nor the name of the author may be used to 39 * 3. The name of the company nor the name of the author may be used to
40 * endorse or promote products derived from this software without specific 40 * endorse or promote products derived from this software without specific
41 * prior written permission. 41 * prior written permission.
42 * 42 *
43 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 43 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
44 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 44 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
45 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 45 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
46 * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 46 * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
47 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 47 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
48 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 48 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
49 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 49 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
50 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 50 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
51 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 51 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
52 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 52 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
53 * SUCH DAMAGE. 53 * SUCH DAMAGE.
54 */ 54 */
55 55
56/* 56/*
57 * Copyright 1997 57 * Copyright 1997
58 * Digital Equipment Corporation. All rights reserved. 58 * Digital Equipment Corporation. All rights reserved.
59 * 59 *
60 * This software is furnished under license and may be used and 60 * This software is furnished under license and may be used and
61 * copied only in accordance with the following terms and conditions. 61 * copied only in accordance with the following terms and conditions.
62 * Subject to these conditions, you may download, copy, install, 62 * Subject to these conditions, you may download, copy, install,
63 * use, modify and distribute this software in source and/or binary 63 * use, modify and distribute this software in source and/or binary
64 * form. No title or ownership is transferred hereby. 64 * form. No title or ownership is transferred hereby.
65 * 65 *
66 * 1) Any source code used, modified or distributed must reproduce 66 * 1) Any source code used, modified or distributed must reproduce
67 * and retain this copyright notice and list of conditions as 67 * and retain this copyright notice and list of conditions as
68 * they appear in the source file. 68 * they appear in the source file.
69 * 69 *
70 * 2) No right is granted to use any trade name, trademark, or logo of 70 * 2) No right is granted to use any trade name, trademark, or logo of
71 * Digital Equipment Corporation. Neither the "Digital Equipment 71 * Digital Equipment Corporation. Neither the "Digital Equipment
72 * Corporation" name nor any trademark or logo of Digital Equipment 72 * Corporation" name nor any trademark or logo of Digital Equipment
73 * Corporation may be used to endorse or promote products derived 73 * Corporation may be used to endorse or promote products derived
74 * from this software without the prior written permission of 74 * from this software without the prior written permission of
75 * Digital Equipment Corporation. 75 * Digital Equipment Corporation.
76 * 76 *
77 * 3) This software is provided "AS-IS" and any express or implied 77 * 3) This software is provided "AS-IS" and any express or implied
78 * warranties, including but not limited to, any implied warranties 78 * warranties, including but not limited to, any implied warranties
79 * of merchantability, fitness for a particular purpose, or 79 * of merchantability, fitness for a particular purpose, or
80 * non-infringement are disclaimed. In no event shall DIGITAL be 80 * non-infringement are disclaimed. In no event shall DIGITAL be
81 * liable for any damages whatsoever, and in particular, DIGITAL 81 * liable for any damages whatsoever, and in particular, DIGITAL
82 * shall not be liable for special, indirect, consequential, or 82 * shall not be liable for special, indirect, consequential, or
83 * incidental damages or damages for lost profits, loss of 83 * incidental damages or damages for lost profits, loss of
84 * revenue or loss of use, whether such damages arise in contract, 84 * revenue or loss of use, whether such damages arise in contract,
85 * negligence, tort, under statute, in equity, at law or otherwise, 85 * negligence, tort, under statute, in equity, at law or otherwise,
86 * even if advised of the possibility of such damage. 86 * even if advised of the possibility of such damage.
87 */ 87 */
88 88
89#include <sys/cdefs.h> 89#include <sys/cdefs.h>
90 90
91#include <sys/param.h> 91#include <sys/param.h>
92#include <sys/kernel.h> 92#include <sys/kernel.h>
93#include <sys/systm.h> 93#include <sys/systm.h>
94#include <sys/mbuf.h> 94#include <sys/mbuf.h>
95#include <sys/syslog.h> 95#include <sys/syslog.h>
96#include <sys/socket.h> 96#include <sys/socket.h>
97#include <sys/device.h> 97#include <sys/device.h>
98#include <sys/malloc.h> 98#include <sys/malloc.h>
99#include <sys/ioctl.h> 99#include <sys/ioctl.h>
100#include <sys/errno.h> 100#include <sys/errno.h>
101 101
102#include <net/if.h> 102#include <net/if.h>
103#include <net/if_ether.h> 103#include <net/if_ether.h>
104#include <net/if_media.h> 104#include <net/if_media.h>
105#include <net/bpf.h> 105#include <net/bpf.h>
106 106
107#ifdef INET 107#ifdef INET
108#include <netinet/in.h> 108#include <netinet/in.h>
109#include <netinet/if_inarp.h> 109#include <netinet/if_inarp.h>
110#endif 110#endif
111 111
112#include <sys/bus.h> 112#include <sys/bus.h>
113#include <sys/intr.h> 113#include <sys/intr.h>
114 114
115#include <dev/ic/dm9000var.h> 115#include <dev/ic/dm9000var.h>
116#include <dev/ic/dm9000reg.h> 116#include <dev/ic/dm9000reg.h>
117 117
118#if 1 118#if 1
119#undef DM9000_DEBUG 119#undef DM9000_DEBUG
120#undef DM9000_TX_DEBUG 120#undef DM9000_TX_DEBUG
121#undef DM9000_TX_DATA_DEBUG 121#undef DM9000_TX_DATA_DEBUG
122#undef DM9000_RX_DEBUG 122#undef DM9000_RX_DEBUG
123#undef DM9000_RX_DATA_DEBUG 123#undef DM9000_RX_DATA_DEBUG
124#else 124#else
125#define DM9000_DEBUG 125#define DM9000_DEBUG
126#define DM9000_TX_DEBUG 126#define DM9000_TX_DEBUG
127#define DM9000_TX_DATA_DEBUG 127#define DM9000_TX_DATA_DEBUG
128#define DM9000_RX_DEBUG 128#define DM9000_RX_DEBUG
129#define DM9000_RX_DATA_DEBUG 129#define DM9000_RX_DATA_DEBUG
130#endif 130#endif
131 131
132#ifdef DM9000_DEBUG 132#ifdef DM9000_DEBUG
133#define DPRINTF(s) do {printf s; } while (/*CONSTCOND*/0) 133#define DPRINTF(s) do {printf s; } while (/*CONSTCOND*/0)
134#else 134#else
135#define DPRINTF(s) do {} while (/*CONSTCOND*/0) 135#define DPRINTF(s) do {} while (/*CONSTCOND*/0)
136#endif 136#endif
137 137
138#ifdef DM9000_TX_DEBUG 138#ifdef DM9000_TX_DEBUG
139#define TX_DPRINTF(s) do {printf s; } while (/*CONSTCOND*/0) 139#define TX_DPRINTF(s) do {printf s; } while (/*CONSTCOND*/0)
140#else 140#else
141#define TX_DPRINTF(s) do {} while (/*CONSTCOND*/0) 141#define TX_DPRINTF(s) do {} while (/*CONSTCOND*/0)
142#endif 142#endif
143 143
144#ifdef DM9000_RX_DEBUG 144#ifdef DM9000_RX_DEBUG
145#define RX_DPRINTF(s) do {printf s; } while (/*CONSTCOND*/0) 145#define RX_DPRINTF(s) do {printf s; } while (/*CONSTCOND*/0)
146#else 146#else
147#define RX_DPRINTF(s) do {} while (/*CONSTCOND*/0) 147#define RX_DPRINTF(s) do {} while (/*CONSTCOND*/0)
148#endif 148#endif
149 149
150#ifdef DM9000_RX_DATA_DEBUG 150#ifdef DM9000_RX_DATA_DEBUG
151#define RX_DATA_DPRINTF(s) do {printf s; } while (/*CONSTCOND*/0) 151#define RX_DATA_DPRINTF(s) do {printf s; } while (/*CONSTCOND*/0)
152#else 152#else
153#define RX_DATA_DPRINTF(s) do {} while (/*CONSTCOND*/0) 153#define RX_DATA_DPRINTF(s) do {} while (/*CONSTCOND*/0)
154#endif 154#endif
155 155
156#ifdef DM9000_TX_DATA_DEBUG 156#ifdef DM9000_TX_DATA_DEBUG
157#define TX_DATA_DPRINTF(s) do {printf s; } while (/*CONSTCOND*/0) 157#define TX_DATA_DPRINTF(s) do {printf s; } while (/*CONSTCOND*/0)
158#else 158#else
159#define TX_DATA_DPRINTF(s) do {} while (/*CONSTCOND*/0) 159#define TX_DATA_DPRINTF(s) do {} while (/*CONSTCOND*/0)
160#endif 160#endif
161 161
162/*** Internal PHY functions ***/ 162/*** Internal PHY functions ***/
163uint16_t dme_phy_read(struct dme_softc *, int ); 163uint16_t dme_phy_read(struct dme_softc *, int );
164void dme_phy_write(struct dme_softc *, int, uint16_t); 164void dme_phy_write(struct dme_softc *, int, uint16_t);
165void dme_phy_init(struct dme_softc *); 165void dme_phy_init(struct dme_softc *);
166void dme_phy_reset(struct dme_softc *); 166void dme_phy_reset(struct dme_softc *);
167void dme_phy_update_media(struct dme_softc *); 167void dme_phy_update_media(struct dme_softc *);
168void dme_phy_check_link(void *); 168void dme_phy_check_link(void *);
169 169
170/*** Methods registered in struct ifnet ***/ 170/*** Methods registered in struct ifnet ***/
171void dme_start_output(struct ifnet *); 171void dme_start_output(struct ifnet *);
172int dme_init(struct ifnet *); 172int dme_init(struct ifnet *);
173int dme_ioctl(struct ifnet *, u_long, void *); 173int dme_ioctl(struct ifnet *, u_long, void *);
174void dme_stop(struct ifnet *, int); 174void dme_stop(struct ifnet *, int);
175 175
176int dme_mediachange(struct ifnet *); 176int dme_mediachange(struct ifnet *);
177void dme_mediastatus(struct ifnet *, struct ifmediareq *); 177void dme_mediastatus(struct ifnet *, struct ifmediareq *);
178 178
179/*** Internal methods ***/ 179/*** Internal methods ***/
180 180
181/* Prepare data to be transmitted (i.e. dequeue and load it into the DM9000) */ 181/* Prepare data to be transmitted (i.e. dequeue and load it into the DM9000) */
182void dme_prepare(struct dme_softc *, struct ifnet *); 182void dme_prepare(struct dme_softc *, struct ifnet *);
183 183
184/* Transmit prepared data */ 184/* Transmit prepared data */
185void dme_transmit(struct dme_softc *); 185void dme_transmit(struct dme_softc *);
186 186
187/* Receive data */ 187/* Receive data */
188void dme_receive(struct dme_softc *, struct ifnet *); 188void dme_receive(struct dme_softc *, struct ifnet *);
189 189
190/* Software Initialize/Reset of the DM9000 */ 190/* Software Initialize/Reset of the DM9000 */
191void dme_reset(struct dme_softc *); 191void dme_reset(struct dme_softc *);
192 192
193/* Configure multicast filter */ 193/* Configure multicast filter */
194void dme_set_addr_filter(struct dme_softc *); 194void dme_set_addr_filter(struct dme_softc *);
195 195
196/* Set media */ 196/* Set media */
197int dme_set_media(struct dme_softc *, int ); 197int dme_set_media(struct dme_softc *, int );
198 198
199/* Read/write packet data from/to DM9000 IC in various transfer sizes */ 199/* Read/write packet data from/to DM9000 IC in various transfer sizes */
200int dme_pkt_read_2(struct dme_softc *, struct ifnet *, struct mbuf **); 200int dme_pkt_read_2(struct dme_softc *, struct ifnet *, struct mbuf **);
201int dme_pkt_write_2(struct dme_softc *, struct mbuf *); 201int dme_pkt_write_2(struct dme_softc *, struct mbuf *);
202int dme_pkt_read_1(struct dme_softc *, struct ifnet *, struct mbuf **); 202int dme_pkt_read_1(struct dme_softc *, struct ifnet *, struct mbuf **);
203int dme_pkt_write_1(struct dme_softc *, struct mbuf *); 203int dme_pkt_write_1(struct dme_softc *, struct mbuf *);
204/* TODO: Implement 32 bit read/write functions */ 204/* TODO: Implement 32 bit read/write functions */
205 205
206uint16_t 206uint16_t
207dme_phy_read(struct dme_softc *sc, int reg) 207dme_phy_read(struct dme_softc *sc, int reg)
208{ 208{
209 uint16_t val; 209 uint16_t val;
210 /* Select Register to read*/ 210 /* Select Register to read*/
211 dme_write(sc, DM9000_EPAR, DM9000_EPAR_INT_PHY + 211 dme_write(sc, DM9000_EPAR, DM9000_EPAR_INT_PHY +
212 (reg & DM9000_EPAR_EROA_MASK)); 212 (reg & DM9000_EPAR_EROA_MASK));
213 /* Select read operation (DM9000_EPCR_ERPRR) from the PHY */ 213 /* Select read operation (DM9000_EPCR_ERPRR) from the PHY */
214 dme_write(sc, DM9000_EPCR, DM9000_EPCR_ERPRR + DM9000_EPCR_EPOS_PHY); 214 dme_write(sc, DM9000_EPCR, DM9000_EPCR_ERPRR + DM9000_EPCR_EPOS_PHY);
215 215
216 /* Wait until access to PHY has completed */ 216 /* Wait until access to PHY has completed */
217 while (dme_read(sc, DM9000_EPCR) & DM9000_EPCR_ERRE) 217 while (dme_read(sc, DM9000_EPCR) & DM9000_EPCR_ERRE)
218 ; 218 ;
219 219
220 /* Reset ERPRR-bit */ 220 /* Reset ERPRR-bit */
221 dme_write(sc, DM9000_EPCR, DM9000_EPCR_EPOS_PHY); 221 dme_write(sc, DM9000_EPCR, DM9000_EPCR_EPOS_PHY);
222 222
223 val = dme_read(sc, DM9000_EPDRL); 223 val = dme_read(sc, DM9000_EPDRL);
224 val += dme_read(sc, DM9000_EPDRH) << 8; 224 val += dme_read(sc, DM9000_EPDRH) << 8;
225 225
226 return val; 226 return val;
227} 227}
228 228
229void 229void
230dme_phy_write(struct dme_softc *sc, int reg, uint16_t value) 230dme_phy_write(struct dme_softc *sc, int reg, uint16_t value)
231{ 231{
232 /* Select Register to write*/ 232 /* Select Register to write*/
233 dme_write(sc, DM9000_EPAR, DM9000_EPAR_INT_PHY + 233 dme_write(sc, DM9000_EPAR, DM9000_EPAR_INT_PHY +
234 (reg & DM9000_EPAR_EROA_MASK)); 234 (reg & DM9000_EPAR_EROA_MASK));
235 235
236 /* Write data to the two data registers */ 236 /* Write data to the two data registers */
237 dme_write(sc, DM9000_EPDRL, value & 0xFF); 237 dme_write(sc, DM9000_EPDRL, value & 0xFF);
238 dme_write(sc, DM9000_EPDRH, (value >> 8) & 0xFF); 238 dme_write(sc, DM9000_EPDRH, (value >> 8) & 0xFF);
239 239
240 /* Select write operation (DM9000_EPCR_ERPRW) from the PHY */ 240 /* Select write operation (DM9000_EPCR_ERPRW) from the PHY */
241 dme_write(sc, DM9000_EPCR, DM9000_EPCR_ERPRW + DM9000_EPCR_EPOS_PHY); 241 dme_write(sc, DM9000_EPCR, DM9000_EPCR_ERPRW + DM9000_EPCR_EPOS_PHY);
242 242
243 /* Wait until access to PHY has completed */ 243 /* Wait until access to PHY has completed */
244 while (dme_read(sc, DM9000_EPCR) & DM9000_EPCR_ERRE) 244 while (dme_read(sc, DM9000_EPCR) & DM9000_EPCR_ERRE)
245 ; 245 ;
246 246
247 /* Reset ERPRR-bit */ 247 /* Reset ERPRR-bit */
248 dme_write(sc, DM9000_EPCR, DM9000_EPCR_EPOS_PHY); 248 dme_write(sc, DM9000_EPCR, DM9000_EPCR_EPOS_PHY);
249} 249}
250 250
251void 251void
252dme_phy_init(struct dme_softc *sc) 252dme_phy_init(struct dme_softc *sc)
253{ 253{
254 u_int ifm_media = sc->sc_media.ifm_media; 254 u_int ifm_media = sc->sc_media.ifm_media;
255 uint32_t bmcr, anar; 255 uint32_t bmcr, anar;
256 256
257 bmcr = dme_phy_read(sc, DM9000_PHY_BMCR); 257 bmcr = dme_phy_read(sc, DM9000_PHY_BMCR);
258 anar = dme_phy_read(sc, DM9000_PHY_ANAR); 258 anar = dme_phy_read(sc, DM9000_PHY_ANAR);
259 259
260 anar = anar & ~DM9000_PHY_ANAR_10_HDX 260 anar = anar & ~DM9000_PHY_ANAR_10_HDX
261 & ~DM9000_PHY_ANAR_10_FDX 261 & ~DM9000_PHY_ANAR_10_FDX
262 & ~DM9000_PHY_ANAR_TX_HDX 262 & ~DM9000_PHY_ANAR_TX_HDX
263 & ~DM9000_PHY_ANAR_TX_FDX; 263 & ~DM9000_PHY_ANAR_TX_FDX;
264 264
265 switch (IFM_SUBTYPE(ifm_media)) { 265 switch (IFM_SUBTYPE(ifm_media)) {
266 case IFM_AUTO: 266 case IFM_AUTO:
267 bmcr |= DM9000_PHY_BMCR_AUTO_NEG_EN; 267 bmcr |= DM9000_PHY_BMCR_AUTO_NEG_EN;
268 anar |= DM9000_PHY_ANAR_10_HDX | 268 anar |= DM9000_PHY_ANAR_10_HDX |
269 DM9000_PHY_ANAR_10_FDX | 269 DM9000_PHY_ANAR_10_FDX |
270 DM9000_PHY_ANAR_TX_HDX | 270 DM9000_PHY_ANAR_TX_HDX |
271 DM9000_PHY_ANAR_TX_FDX; 271 DM9000_PHY_ANAR_TX_FDX;
272 break; 272 break;
273 case IFM_10_T: 273 case IFM_10_T:
274 //bmcr &= ~DM9000_PHY_BMCR_AUTO_NEG_EN; 274 //bmcr &= ~DM9000_PHY_BMCR_AUTO_NEG_EN;
275 bmcr &= ~DM9000_PHY_BMCR_SPEED_SELECT; 275 bmcr &= ~DM9000_PHY_BMCR_SPEED_SELECT;
276 if (ifm_media & IFM_FDX) 276 if (ifm_media & IFM_FDX)
277 anar |= DM9000_PHY_ANAR_10_FDX; 277 anar |= DM9000_PHY_ANAR_10_FDX;
278 else 278 else
279 anar |= DM9000_PHY_ANAR_10_HDX; 279 anar |= DM9000_PHY_ANAR_10_HDX;
280 break; 280 break;
281 case IFM_100_TX: 281 case IFM_100_TX:
282 //bmcr &= ~DM9000_PHY_BMCR_AUTO_NEG_EN; 282 //bmcr &= ~DM9000_PHY_BMCR_AUTO_NEG_EN;
283 bmcr |= DM9000_PHY_BMCR_SPEED_SELECT; 283 bmcr |= DM9000_PHY_BMCR_SPEED_SELECT;
284 if (ifm_media & IFM_FDX) 284 if (ifm_media & IFM_FDX)
285 anar |= DM9000_PHY_ANAR_TX_FDX; 285 anar |= DM9000_PHY_ANAR_TX_FDX;
286 else 286 else
287 anar |= DM9000_PHY_ANAR_TX_HDX; 287 anar |= DM9000_PHY_ANAR_TX_HDX;
288 288
289 break; 289 break;
290 } 290 }
291 291
292 if (ifm_media & IFM_FDX) 292 if (ifm_media & IFM_FDX)
293 bmcr |= DM9000_PHY_BMCR_DUPLEX_MODE; 293 bmcr |= DM9000_PHY_BMCR_DUPLEX_MODE;
294 else 294 else
295 bmcr &= ~DM9000_PHY_BMCR_DUPLEX_MODE; 295 bmcr &= ~DM9000_PHY_BMCR_DUPLEX_MODE;
296 296
297 dme_phy_write(sc, DM9000_PHY_BMCR, bmcr); 297 dme_phy_write(sc, DM9000_PHY_BMCR, bmcr);
298 dme_phy_write(sc, DM9000_PHY_ANAR, anar); 298 dme_phy_write(sc, DM9000_PHY_ANAR, anar);
299} 299}
300 300
301void 301void
302dme_phy_reset(struct dme_softc *sc) 302dme_phy_reset(struct dme_softc *sc)
303{ 303{
304 uint32_t reg; 304 uint32_t reg;
305 305
306 /* PHY Reset */ 306 /* PHY Reset */
307 dme_phy_write(sc, DM9000_PHY_BMCR, DM9000_PHY_BMCR_RESET); 307 dme_phy_write(sc, DM9000_PHY_BMCR, DM9000_PHY_BMCR_RESET);
308 308
309 reg = dme_read(sc, DM9000_GPCR); 309 reg = dme_read(sc, DM9000_GPCR);
310 dme_write(sc, DM9000_GPCR, reg & ~DM9000_GPCR_GPIO0_OUT); 310 dme_write(sc, DM9000_GPCR, reg & ~DM9000_GPCR_GPIO0_OUT);
311 reg = dme_read(sc, DM9000_GPR); 311 reg = dme_read(sc, DM9000_GPR);
312 dme_write(sc, DM9000_GPR, reg | DM9000_GPR_PHY_PWROFF); 312 dme_write(sc, DM9000_GPR, reg | DM9000_GPR_PHY_PWROFF);
313 313
314 dme_phy_init(sc); 314 dme_phy_init(sc);
315 315
316 reg = dme_read(sc, DM9000_GPR); 316 reg = dme_read(sc, DM9000_GPR);
317 dme_write(sc, DM9000_GPR, reg & ~DM9000_GPR_PHY_PWROFF); 317 dme_write(sc, DM9000_GPR, reg & ~DM9000_GPR_PHY_PWROFF);
318 reg = dme_read(sc, DM9000_GPCR); 318 reg = dme_read(sc, DM9000_GPCR);
319 dme_write(sc, DM9000_GPCR, reg | DM9000_GPCR_GPIO0_OUT); 319 dme_write(sc, DM9000_GPCR, reg | DM9000_GPCR_GPIO0_OUT);
320 320
321 dme_phy_update_media(sc); 321 dme_phy_update_media(sc);
322} 322}
323 323
324void 324void
325dme_phy_update_media(struct dme_softc *sc) 325dme_phy_update_media(struct dme_softc *sc)
326{ 326{
327 u_int ifm_media = sc->sc_media.ifm_media; 327 u_int ifm_media = sc->sc_media.ifm_media;
328 uint32_t reg; 328 uint32_t reg;
329 329
330 if (IFM_SUBTYPE(ifm_media) == IFM_AUTO) { 330 if (IFM_SUBTYPE(ifm_media) == IFM_AUTO) {
331 /* If auto-negotiation is used, ensures that it is completed 331 /* If auto-negotiation is used, ensures that it is completed
332 before trying to extract any media information. */ 332 before trying to extract any media information. */
333 reg = dme_phy_read(sc, DM9000_PHY_BMSR); 333 reg = dme_phy_read(sc, DM9000_PHY_BMSR);
334 if ((reg & DM9000_PHY_BMSR_AUTO_NEG_AB) == 0) { 334 if ((reg & DM9000_PHY_BMSR_AUTO_NEG_AB) == 0) {
335 /* Auto-negotation not possible, therefore there is no 335 /* Auto-negotation not possible, therefore there is no
336 reason to try obtain any media information. */ 336 reason to try obtain any media information. */
337 return; 337 return;
338 } 338 }
339 339
340 /* Then loop until the negotiation is completed. */ 340 /* Then loop until the negotiation is completed. */
341 while ((reg & DM9000_PHY_BMSR_AUTO_NEG_COM) == 0) { 341 while ((reg & DM9000_PHY_BMSR_AUTO_NEG_COM) == 0) {
342 /* TODO: Bail out after a finite number of attempts 342 /* TODO: Bail out after a finite number of attempts
343 in case something goes wrong. */ 343 in case something goes wrong. */
344 preempt(); 344 preempt();
345 reg = dme_phy_read(sc, DM9000_PHY_BMSR); 345 reg = dme_phy_read(sc, DM9000_PHY_BMSR);
346 } 346 }
347 } 347 }
348 348
349 349
350 sc->sc_media_active = IFM_ETHER; 350 sc->sc_media_active = IFM_ETHER;
351 reg = dme_phy_read(sc, DM9000_PHY_BMCR); 351 reg = dme_phy_read(sc, DM9000_PHY_BMCR);
352 352
353 if (reg & DM9000_PHY_BMCR_SPEED_SELECT) 353 if (reg & DM9000_PHY_BMCR_SPEED_SELECT)
354 sc->sc_media_active |= IFM_100_TX; 354 sc->sc_media_active |= IFM_100_TX;
355 else 355 else
356 sc->sc_media_active |= IFM_10_T; 356 sc->sc_media_active |= IFM_10_T;
357 357
358 if (reg & DM9000_PHY_BMCR_DUPLEX_MODE) 358 if (reg & DM9000_PHY_BMCR_DUPLEX_MODE)
359 sc->sc_media_active |= IFM_FDX; 359 sc->sc_media_active |= IFM_FDX;
360} 360}
361 361
362void 362void
363dme_phy_check_link(void *arg) 363dme_phy_check_link(void *arg)
364{ 364{
365 struct dme_softc *sc = arg; 365 struct dme_softc *sc = arg;
366 uint32_t reg; 366 uint32_t reg;
367 int s; 367 int s;
368 368
369 s = splnet(); 369 s = splnet();
370 370
371 reg = dme_read(sc, DM9000_NSR) & DM9000_NSR_LINKST; 371 reg = dme_read(sc, DM9000_NSR) & DM9000_NSR_LINKST;
372 372
373 if (reg) 373 if (reg)
374 reg = IFM_ETHER | IFM_AVALID | IFM_ACTIVE; 374 reg = IFM_ETHER | IFM_AVALID | IFM_ACTIVE;
375 else { 375 else {
376 reg = IFM_ETHER | IFM_AVALID; 376 reg = IFM_ETHER | IFM_AVALID;
377 sc->sc_media_active = IFM_NONE; 377 sc->sc_media_active = IFM_NONE;
378 } 378 }
379 379
380 if ((sc->sc_media_status != reg) && (reg & IFM_ACTIVE)) 380 if ((sc->sc_media_status != reg) && (reg & IFM_ACTIVE))
381 dme_phy_reset(sc); 381 dme_phy_reset(sc);
382 382
383 sc->sc_media_status = reg; 383 sc->sc_media_status = reg;
384 384
385 callout_schedule(&sc->sc_link_callout, mstohz(2000)); 385 callout_schedule(&sc->sc_link_callout, mstohz(2000));
386 splx(s); 386 splx(s);
387} 387}
388 388
389int 389int
390dme_set_media(struct dme_softc *sc, int media) 390dme_set_media(struct dme_softc *sc, int media)
391{ 391{
392 int s; 392 int s;
393 393
394 s = splnet(); 394 s = splnet();
395 sc->sc_media.ifm_media = media; 395 sc->sc_media.ifm_media = media;
396 dme_phy_reset(sc); 396 dme_phy_reset(sc);
397 397
398 splx(s); 398 splx(s);
399 399
400 return 0; 400 return 0;
401} 401}
402 402
403int 403int
404dme_attach(struct dme_softc *sc, const uint8_t *enaddr) 404dme_attach(struct dme_softc *sc, const uint8_t *enaddr)
405{ 405{
406 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 406 struct ifnet *ifp = &sc->sc_ethercom.ec_if;
407 uint8_t b[2]; 407 uint8_t b[2];
408 uint16_t io_mode; 408 uint16_t io_mode;
409 409
410 dme_read_c(sc, DM9000_VID0, b, 2); 410 dme_read_c(sc, DM9000_VID0, b, 2);
411#if BYTE_ORDER == BIG_ENDIAN 411#if BYTE_ORDER == BIG_ENDIAN
412 sc->sc_vendor_id = (b[0] << 8) | b[1]; 412 sc->sc_vendor_id = (b[0] << 8) | b[1];
413#else 413#else
414 sc->sc_vendor_id = b[0] | (b[1] << 8); 414 sc->sc_vendor_id = b[0] | (b[1] << 8);
415#endif 415#endif
416 dme_read_c(sc, DM9000_PID0, b, 2); 416 dme_read_c(sc, DM9000_PID0, b, 2);
417#if BYTE_ORDER == BIG_ENDIAN 417#if BYTE_ORDER == BIG_ENDIAN
418 sc->sc_product_id = (b[0] << 8) | b[1]; 418 sc->sc_product_id = (b[0] << 8) | b[1];
419#else 419#else
420 sc->sc_product_id = b[0] | (b[1] << 8); 420 sc->sc_product_id = b[0] | (b[1] << 8);
421#endif 421#endif
422 /* TODO: Check the vendor ID as well */ 422 /* TODO: Check the vendor ID as well */
423 if (sc->sc_product_id != 0x9000) { 423 if (sc->sc_product_id != 0x9000) {
424 panic("dme_attach: product id mismatch (0x%hx != 0x9000)", 424 panic("dme_attach: product id mismatch (0x%hx != 0x9000)",
425 sc->sc_product_id); 425 sc->sc_product_id);
426 } 426 }
427 427
428 /* Initialize ifnet structure. */ 428 /* Initialize ifnet structure. */
429 strlcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ); 429 strlcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ);
430 ifp->if_softc = sc; 430 ifp->if_softc = sc;
431 ifp->if_start = dme_start_output; 431 ifp->if_start = dme_start_output;
432 ifp->if_init = dme_init; 432 ifp->if_init = dme_init;
433 ifp->if_ioctl = dme_ioctl; 433 ifp->if_ioctl = dme_ioctl;
434 ifp->if_stop = dme_stop; 434 ifp->if_stop = dme_stop;
435 ifp->if_watchdog = NULL; /* no watchdog at this stage */ 435 ifp->if_watchdog = NULL; /* no watchdog at this stage */
436 ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST; 436 ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST;
437 IFQ_SET_READY(&ifp->if_snd); 437 IFQ_SET_READY(&ifp->if_snd);
438 438
439 /* Initialize ifmedia structures. */ 439 /* Initialize ifmedia structures. */
440 sc->sc_ethercom.ec_ifmedia = &sc->sc_media; 440 sc->sc_ethercom.ec_ifmedia = &sc->sc_media;
441 ifmedia_init(&sc->sc_media, 0, dme_mediachange, dme_mediastatus); 441 ifmedia_init(&sc->sc_media, 0, dme_mediachange, dme_mediastatus);
442 ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_AUTO, 0, NULL); 442 ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_AUTO, 0, NULL);
443 ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_10_T | IFM_FDX, 0, NULL); 443 ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_10_T | IFM_FDX, 0, NULL);
444 ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_10_T, 0, NULL); 444 ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_10_T, 0, NULL);
445 ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_100_TX | IFM_FDX, 0, NULL); 445 ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_100_TX | IFM_FDX, 0, NULL);
446 ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_100_TX, 0, NULL); 446 ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_100_TX, 0, NULL);
447 447
448 ifmedia_set(&sc->sc_media, IFM_ETHER | IFM_AUTO); 448 ifmedia_set(&sc->sc_media, IFM_ETHER | IFM_AUTO);
449 449
450 if (enaddr != NULL) 450 if (enaddr != NULL)
451 memcpy(sc->sc_enaddr, enaddr, sizeof(sc->sc_enaddr)); 451 memcpy(sc->sc_enaddr, enaddr, sizeof(sc->sc_enaddr));
452 /* TODO: Support an EEPROM attached to the DM9000 chip */ 452 /* TODO: Support an EEPROM attached to the DM9000 chip */
453 453
454 callout_init(&sc->sc_link_callout, 0); 454 callout_init(&sc->sc_link_callout, 0);
455 callout_setfunc(&sc->sc_link_callout, dme_phy_check_link, sc); 455 callout_setfunc(&sc->sc_link_callout, dme_phy_check_link, sc);
456 456
457 sc->sc_media_status = 0; 457 sc->sc_media_status = 0;
458 458
459 /* Configure DM9000 with the MAC address */ 459 /* Configure DM9000 with the MAC address */
460 dme_write_c(sc, DM9000_PAB0, sc->sc_enaddr, 6); 460 dme_write_c(sc, DM9000_PAB0, sc->sc_enaddr, 6);
461 461
462#ifdef DM9000_DEBUG 462#ifdef DM9000_DEBUG
463 { 463 {
464 uint8_t macAddr[6]; 464 uint8_t macAddr[6];
465 dme_read_c(sc, DM9000_PAB0, macAddr, 6); 465 dme_read_c(sc, DM9000_PAB0, macAddr, 6);
466 printf("DM9000 configured with MAC address: "); 466 printf("DM9000 configured with MAC address: ");
467 for (int i = 0; i < 6; i++) 467 for (int i = 0; i < 6; i++)
468 printf("%02X:", macAddr[i]); 468 printf("%02X:", macAddr[i]);
469 printf("\n"); 469 printf("\n");
470 } 470 }
471#endif 471#endif
472 472
473 if_attach(ifp); 473 if_attach(ifp);
474 ether_ifattach(ifp, sc->sc_enaddr); 474 ether_ifattach(ifp, sc->sc_enaddr);
475 475
476#ifdef DM9000_DEBUG 476#ifdef DM9000_DEBUG
477 { 477 {
478 uint8_t network_state; 478 uint8_t network_state;
479 network_state = dme_read(sc, DM9000_NSR); 479 network_state = dme_read(sc, DM9000_NSR);
480 printf("DM9000 Link status: "); 480 printf("DM9000 Link status: ");
481 if (network_state & DM9000_NSR_LINKST) { 481 if (network_state & DM9000_NSR_LINKST) {
482 if (network_state & DM9000_NSR_SPEED) 482 if (network_state & DM9000_NSR_SPEED)
483 printf("10Mbps"); 483 printf("10Mbps");
484 else 484 else
485 printf("100Mbps"); 485 printf("100Mbps");
486 } else 486 } else
487 printf("Down"); 487 printf("Down");
488 printf("\n"); 488 printf("\n");
489 } 489 }
490#endif 490#endif
491 491
492 io_mode = (dme_read(sc, DM9000_ISR) & 492 io_mode = (dme_read(sc, DM9000_ISR) &
493 DM9000_IOMODE_MASK) >> DM9000_IOMODE_SHIFT; 493 DM9000_IOMODE_MASK) >> DM9000_IOMODE_SHIFT;
494 494
495 DPRINTF(("DM9000 Operation Mode: ")); 495 DPRINTF(("DM9000 Operation Mode: "));
496 switch (io_mode) { 496 switch (io_mode) {
497 case DM9000_MODE_16BIT: 497 case DM9000_MODE_16BIT:
498 DPRINTF(("16-bit mode")); 498 DPRINTF(("16-bit mode"));
499 sc->sc_data_width = 2; 499 sc->sc_data_width = 2;
500 sc->sc_pkt_write = dme_pkt_write_2; 500 sc->sc_pkt_write = dme_pkt_write_2;
501 sc->sc_pkt_read = dme_pkt_read_2; 501 sc->sc_pkt_read = dme_pkt_read_2;
502 break; 502 break;
503 case DM9000_MODE_32BIT: 503 case DM9000_MODE_32BIT:
504 DPRINTF(("32-bit mode")); 504 DPRINTF(("32-bit mode"));
505 sc->sc_data_width = 4; 505 sc->sc_data_width = 4;
506 panic("32bit mode is unsupported\n"); 506 panic("32bit mode is unsupported\n");
507 break; 507 break;
508 case DM9000_MODE_8BIT: 508 case DM9000_MODE_8BIT:
509 DPRINTF(("8-bit mode")); 509 DPRINTF(("8-bit mode"));
510 sc->sc_data_width = 1; 510 sc->sc_data_width = 1;
511 sc->sc_pkt_write = dme_pkt_write_1; 511 sc->sc_pkt_write = dme_pkt_write_1;
512 sc->sc_pkt_read = dme_pkt_read_1; 512 sc->sc_pkt_read = dme_pkt_read_1;
513 break; 513 break;
514 default: 514 default:
515 DPRINTF(("Invalid mode")); 515 DPRINTF(("Invalid mode"));
516 break; 516 break;
517 } 517 }
518 DPRINTF(("\n")); 518 DPRINTF(("\n"));
519 519
520 callout_schedule(&sc->sc_link_callout, mstohz(2000)); 520 callout_schedule(&sc->sc_link_callout, mstohz(2000));
521 521
522 return 0; 522 return 0;
523} 523}
524 524
525int dme_intr(void *arg) 525int dme_intr(void *arg)
526{ 526{
527 struct dme_softc *sc = arg; 527 struct dme_softc *sc = arg;
528 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 528 struct ifnet *ifp = &sc->sc_ethercom.ec_if;
529 uint8_t status; 529 uint8_t status;
530 530
531 531
532 DPRINTF(("dme_intr: Begin\n")); 532 DPRINTF(("dme_intr: Begin\n"));
533 533
534 /* Disable interrupts */ 534 /* Disable interrupts */
535 dme_write(sc, DM9000_IMR, DM9000_IMR_PAR ); 535 dme_write(sc, DM9000_IMR, DM9000_IMR_PAR );
536 536
537 status = dme_read(sc, DM9000_ISR); 537 status = dme_read(sc, DM9000_ISR);
538 dme_write(sc, DM9000_ISR, status); 538 dme_write(sc, DM9000_ISR, status);
539 539
540 if (status & DM9000_ISR_PRS) { 540 if (status & DM9000_ISR_PRS) {
541 if (ifp->if_flags & IFF_RUNNING ) 541 if (ifp->if_flags & IFF_RUNNING )
542 dme_receive(sc, ifp); 542 dme_receive(sc, ifp);
543 } 543 }
544 if (status & DM9000_ISR_PTS) { 544 if (status & DM9000_ISR_PTS) {
545 uint8_t nsr; 545 uint8_t nsr;
546 uint8_t tx_status = 0x01; /* Initialize to an error value */ 546 uint8_t tx_status = 0x01; /* Initialize to an error value */
547 547
548 /* A packet has been transmitted */ 548 /* A packet has been transmitted */
549 sc->txbusy = 0; 549 sc->txbusy = 0;
550 550
551 nsr = dme_read(sc, DM9000_NSR); 551 nsr = dme_read(sc, DM9000_NSR);
552 552
553 if (nsr & DM9000_NSR_TX1END) { 553 if (nsr & DM9000_NSR_TX1END) {
554 tx_status = dme_read(sc, DM9000_TSR1); 554 tx_status = dme_read(sc, DM9000_TSR1);
555 TX_DPRINTF(("dme_intr: Sent using channel 0\n")); 555 TX_DPRINTF(("dme_intr: Sent using channel 0\n"));
556 } else if (nsr & DM9000_NSR_TX2END) { 556 } else if (nsr & DM9000_NSR_TX2END) {
557 tx_status = dme_read(sc, DM9000_TSR2); 557 tx_status = dme_read(sc, DM9000_TSR2);
558 TX_DPRINTF(("dme_intr: Sent using channel 1\n")); 558 TX_DPRINTF(("dme_intr: Sent using channel 1\n"));
559 } 559 }
560 560
561 if (tx_status == 0x0) { 561 if (tx_status == 0x0) {
562 /* Frame successfully sent */ 562 /* Frame successfully sent */
563 ifp->if_opackets++; 563 if_statinc(ifp, if_opackets);
564 } else { 564 } else {
565 ifp->if_oerrors++; 565 if_statinc(ifp, if_oerrors);
566 } 566 }
567 567
568 /* If we have nothing ready to transmit, prepare something */ 568 /* If we have nothing ready to transmit, prepare something */
569 if (!sc->txready) 569 if (!sc->txready)
570 dme_prepare(sc, ifp); 570 dme_prepare(sc, ifp);
571 571
572 if (sc->txready) 572 if (sc->txready)
573 dme_transmit(sc); 573 dme_transmit(sc);
574 574
575 /* Prepare the next frame */ 575 /* Prepare the next frame */
576 dme_prepare(sc, ifp); 576 dme_prepare(sc, ifp);
577 577
578 } 578 }
579#ifdef notyet 579#ifdef notyet
580 if (status & DM9000_ISR_LNKCHNG) { 580 if (status & DM9000_ISR_LNKCHNG) {
581 } 581 }
582#endif 582#endif
583 583
584 /* Enable interrupts again */ 584 /* Enable interrupts again */
585 dme_write(sc, DM9000_IMR, 585 dme_write(sc, DM9000_IMR,
586 DM9000_IMR_PAR | DM9000_IMR_PRM | DM9000_IMR_PTM); 586 DM9000_IMR_PAR | DM9000_IMR_PRM | DM9000_IMR_PTM);
587 587
588 DPRINTF(("dme_intr: End\n")); 588 DPRINTF(("dme_intr: End\n"));
589 589
590 return 1; 590 return 1;
591} 591}
592 592
593void 593void
594dme_start_output(struct ifnet *ifp) 594dme_start_output(struct ifnet *ifp)
595{ 595{
596 struct dme_softc *sc; 596 struct dme_softc *sc;
597 597
598 sc = ifp->if_softc; 598 sc = ifp->if_softc;
599 599
600 DPRINTF(("dme_start_output: Begin\n")); 600 DPRINTF(("dme_start_output: Begin\n"));
601 601
602 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING) { 602 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING) {
603 printf("No output\n"); 603 printf("No output\n");
604 return; 604 return;
605 } 605 }
606 606
607 if (sc->txbusy && sc->txready) 607 if (sc->txbusy && sc->txready)
608 panic("DM9000: Internal error, trying to send without" 608 panic("DM9000: Internal error, trying to send without"
609 " any empty queue\n"); 609 " any empty queue\n");
610 610
611 dme_prepare(sc, ifp); 611 dme_prepare(sc, ifp);
612 612
613 if (sc->txbusy == 0) { 613 if (sc->txbusy == 0) {
614 /* We are ready to transmit right away */ 614 /* We are ready to transmit right away */
615 dme_transmit(sc); 615 dme_transmit(sc);
616 dme_prepare(sc, ifp); /* Prepare next one */ 616 dme_prepare(sc, ifp); /* Prepare next one */
617 } else { 617 } else {
618 /* We need to wait until the current packet has 618 /* We need to wait until the current packet has
619 * been transmitted. 619 * been transmitted.
620 */ 620 */
621 ifp->if_flags |= IFF_OACTIVE; 621 ifp->if_flags |= IFF_OACTIVE;
622 } 622 }
623 623
624 DPRINTF(("dme_start_output: End\n")); 624 DPRINTF(("dme_start_output: End\n"));
625} 625}
626 626
627void 627void
628dme_prepare(struct dme_softc *sc, struct ifnet *ifp) 628dme_prepare(struct dme_softc *sc, struct ifnet *ifp)
629{ 629{
630 struct mbuf *bufChain; 630 struct mbuf *bufChain;
631 uint16_t length; 631 uint16_t length;
632 632
633 TX_DPRINTF(("dme_prepare: Entering\n")); 633 TX_DPRINTF(("dme_prepare: Entering\n"));
634 634
635 if (sc->txready) 635 if (sc->txready)
636 panic("dme_prepare: Someone called us with txready set\n"); 636 panic("dme_prepare: Someone called us with txready set\n");
637 637
638 IFQ_DEQUEUE(&ifp->if_snd, bufChain); 638 IFQ_DEQUEUE(&ifp->if_snd, bufChain);
639 if (bufChain == NULL) { 639 if (bufChain == NULL) {
640 TX_DPRINTF(("dme_prepare: Nothing to transmit\n")); 640 TX_DPRINTF(("dme_prepare: Nothing to transmit\n"));
641 ifp->if_flags &= ~IFF_OACTIVE; /* Clear OACTIVE bit */ 641 ifp->if_flags &= ~IFF_OACTIVE; /* Clear OACTIVE bit */
642 return; /* Nothing to transmit */ 642 return; /* Nothing to transmit */
643 } 643 }
644 644
645 /* Element has now been removed from the queue, so we better send it */ 645 /* Element has now been removed from the queue, so we better send it */
646 646
647 bpf_mtap(ifp, bufChain, BPF_D_OUT); 647 bpf_mtap(ifp, bufChain, BPF_D_OUT);
648 648
649 /* Setup the DM9000 to accept the writes, and then write each buf in 649 /* Setup the DM9000 to accept the writes, and then write each buf in
650 the chain. */ 650 the chain. */
651 651
652 TX_DATA_DPRINTF(("dme_prepare: Writing data: ")); 652 TX_DATA_DPRINTF(("dme_prepare: Writing data: "));
653 bus_space_write_1(sc->sc_iot, sc->sc_ioh, sc->dme_io, DM9000_MWCMD); 653 bus_space_write_1(sc->sc_iot, sc->sc_ioh, sc->dme_io, DM9000_MWCMD);
654 length = sc->sc_pkt_write(sc, bufChain); 654 length = sc->sc_pkt_write(sc, bufChain);
655 TX_DATA_DPRINTF(("\n")); 655 TX_DATA_DPRINTF(("\n"));
656 656
657 if (length % sc->sc_data_width != 0) 657 if (length % sc->sc_data_width != 0)
658 panic("dme_prepare: length is not compatible with IO_MODE"); 658 panic("dme_prepare: length is not compatible with IO_MODE");
659 659
660 sc->txready_length = length; 660 sc->txready_length = length;
661 sc->txready = 1; 661 sc->txready = 1;
662 662
663 TX_DPRINTF(("dme_prepare: txbusy: %d\ndme_prepare: " 663 TX_DPRINTF(("dme_prepare: txbusy: %d\ndme_prepare: "
664 "txready: %d, txready_length: %d\n", 664 "txready: %d, txready_length: %d\n",
665 sc->txbusy, sc->txready, sc->txready_length)); 665 sc->txbusy, sc->txready, sc->txready_length));
666 666
667 m_freem(bufChain); 667 m_freem(bufChain);
668 668
669 TX_DPRINTF(("dme_prepare: Leaving\n")); 669 TX_DPRINTF(("dme_prepare: Leaving\n"));
670} 670}
671 671
672int 672int
673dme_init(struct ifnet *ifp) 673dme_init(struct ifnet *ifp)
674{ 674{
675 int s; 675 int s;
676 struct dme_softc *sc = ifp->if_softc; 676 struct dme_softc *sc = ifp->if_softc;
677 677
678 dme_stop(ifp, 0); 678 dme_stop(ifp, 0);
679 679
680 s = splnet(); 680 s = splnet();
681 681
682 dme_reset(sc); 682 dme_reset(sc);
683 683
684 sc->sc_ethercom.ec_if.if_flags |= IFF_RUNNING; 684 sc->sc_ethercom.ec_if.if_flags |= IFF_RUNNING;
685 sc->sc_ethercom.ec_if.if_flags &= ~IFF_OACTIVE; 685 sc->sc_ethercom.ec_if.if_flags &= ~IFF_OACTIVE;
686 sc->sc_ethercom.ec_if.if_timer = 0; 686 sc->sc_ethercom.ec_if.if_timer = 0;
687 687
688 splx(s); 688 splx(s);
689 689
690 return 0; 690 return 0;
691} 691}
692 692
693int 693int
694dme_ioctl(struct ifnet *ifp, u_long cmd, void *data) 694dme_ioctl(struct ifnet *ifp, u_long cmd, void *data)
695{ 695{
696 struct dme_softc *sc = ifp->if_softc; 696 struct dme_softc *sc = ifp->if_softc;
697 int s, error = 0; 697 int s, error = 0;
698 698
699 s = splnet(); 699 s = splnet();
700 700
701 switch (cmd) { 701 switch (cmd) {
702 default: 702 default:
703 error = ether_ioctl(ifp, cmd, data); 703 error = ether_ioctl(ifp, cmd, data);
704 if (error == ENETRESET) { 704 if (error == ENETRESET) {
705 if (ifp->if_flags && IFF_RUNNING) { 705 if (ifp->if_flags && IFF_RUNNING) {
706 /* Address list has changed, reconfigure 706 /* Address list has changed, reconfigure
707 filter */ 707 filter */
708 dme_set_addr_filter(sc); 708 dme_set_addr_filter(sc);
709 } 709 }
710 error = 0; 710 error = 0;
711 } 711 }
712 break; 712 break;
713 } 713 }
714 714
715 splx(s); 715 splx(s);
716 return error; 716 return error;
717} 717}
718 718
719void 719void
720dme_stop(struct ifnet *ifp, int disable) 720dme_stop(struct ifnet *ifp, int disable)
721{ 721{
722 struct dme_softc *sc = ifp->if_softc; 722 struct dme_softc *sc = ifp->if_softc;
723 723
724 /* Not quite sure what to do when called with disable == 0 */ 724 /* Not quite sure what to do when called with disable == 0 */
725 if (disable) { 725 if (disable) {
726 /* Disable RX */ 726 /* Disable RX */
727 dme_write(sc, DM9000_RCR, 0x0); 727 dme_write(sc, DM9000_RCR, 0x0);
728 } 728 }
729 729
730 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 730 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
731 ifp->if_timer = 0; 731 ifp->if_timer = 0;
732} 732}
733 733
734int 734int
735dme_mediachange(struct ifnet *ifp) 735dme_mediachange(struct ifnet *ifp)
736{ 736{
737 struct dme_softc *sc = ifp->if_softc; 737 struct dme_softc *sc = ifp->if_softc;
738 738
739 return dme_set_media(sc, sc->sc_media.ifm_cur->ifm_media); 739 return dme_set_media(sc, sc->sc_media.ifm_cur->ifm_media);
740} 740}
741 741
742void 742void
743dme_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr) 743dme_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr)
744{ 744{
745 struct dme_softc *sc = ifp->if_softc; 745 struct dme_softc *sc = ifp->if_softc;
746 746
747 ifmr->ifm_active = sc->sc_media_active; 747 ifmr->ifm_active = sc->sc_media_active;
748 ifmr->ifm_status = sc->sc_media_status; 748 ifmr->ifm_status = sc->sc_media_status;
749} 749}
750 750
751void 751void
752dme_transmit(struct dme_softc *sc) 752dme_transmit(struct dme_softc *sc)
753{ 753{
754 754
755 TX_DPRINTF(("dme_transmit: PRE: txready: %d, txbusy: %d\n", 755 TX_DPRINTF(("dme_transmit: PRE: txready: %d, txbusy: %d\n",
756 sc->txready, sc->txbusy)); 756 sc->txready, sc->txbusy));
757 757
758 dme_write(sc, DM9000_TXPLL, sc->txready_length & 0xff); 758 dme_write(sc, DM9000_TXPLL, sc->txready_length & 0xff);
759 dme_write(sc, DM9000_TXPLH, (sc->txready_length >> 8) & 0xff ); 759 dme_write(sc, DM9000_TXPLH, (sc->txready_length >> 8) & 0xff );
760 760
761 /* Request to send the packet */ 761 /* Request to send the packet */
762 dme_read(sc, DM9000_ISR); 762 dme_read(sc, DM9000_ISR);
763 763
764 dme_write(sc, DM9000_TCR, DM9000_TCR_TXREQ); 764 dme_write(sc, DM9000_TCR, DM9000_TCR_TXREQ);
765 765
766 sc->txready = 0; 766 sc->txready = 0;
767 sc->txbusy = 1; 767 sc->txbusy = 1;
768 sc->txready_length = 0; 768 sc->txready_length = 0;
769} 769}
770 770
771void 771void
772dme_receive(struct dme_softc *sc, struct ifnet *ifp) 772dme_receive(struct dme_softc *sc, struct ifnet *ifp)
773{ 773{
774 uint8_t ready = 0x01; 774 uint8_t ready = 0x01;
775 775
776 DPRINTF(("inside dme_receive\n")); 776 DPRINTF(("inside dme_receive\n"));
777 777
778 while (ready == 0x01) { 778 while (ready == 0x01) {
779 /* Packet received, retrieve it */ 779 /* Packet received, retrieve it */
780 780
781 /* Read without address increment to get the ready byte without 781 /* Read without address increment to get the ready byte without
782 moving past it. */ 782 moving past it. */
783 bus_space_write_1(sc->sc_iot, sc->sc_ioh, 783 bus_space_write_1(sc->sc_iot, sc->sc_ioh,
784 sc->dme_io, DM9000_MRCMDX); 784 sc->dme_io, DM9000_MRCMDX);
785 /* Dummy ready */ 785 /* Dummy ready */
786 ready = bus_space_read_1(sc->sc_iot, sc->sc_ioh, sc->dme_data); 786 ready = bus_space_read_1(sc->sc_iot, sc->sc_ioh, sc->dme_data);
787 ready = bus_space_read_1(sc->sc_iot, sc->sc_ioh, sc->dme_data); 787 ready = bus_space_read_1(sc->sc_iot, sc->sc_ioh, sc->dme_data);
788 ready &= 0x03; /* we only want bits 1:0 */ 788 ready &= 0x03; /* we only want bits 1:0 */
789 if (ready == 0x01) { 789 if (ready == 0x01) {
790 uint8_t rx_status; 790 uint8_t rx_status;
791 struct mbuf *m; 791 struct mbuf *m;
792 792
793 /* Read with address increment. */ 793 /* Read with address increment. */
794 bus_space_write_1(sc->sc_iot, sc->sc_ioh, 794 bus_space_write_1(sc->sc_iot, sc->sc_ioh,
795 sc->dme_io, DM9000_MRCMD); 795 sc->dme_io, DM9000_MRCMD);
796 796
797 rx_status = sc->sc_pkt_read(sc, ifp, &m); 797 rx_status = sc->sc_pkt_read(sc, ifp, &m);
798 if (m == NULL) { 798 if (m == NULL) {
799 /* failed to allocate a receive buffer */ 799 /* failed to allocate a receive buffer */
800 ifp->if_ierrors++; 800 if_statinc(ifp, if_ierrors);
801 RX_DPRINTF(("dme_receive: " 801 RX_DPRINTF(("dme_receive: "
802 "Error allocating buffer\n")); 802 "Error allocating buffer\n"));
803 } else if (rx_status & (DM9000_RSR_CE | DM9000_RSR_PLE)) { 803 } else if (rx_status & (DM9000_RSR_CE | DM9000_RSR_PLE)) {
804 /* Error while receiving the packet, 804 /* Error while receiving the packet,
805 * discard it and keep track of counters 805 * discard it and keep track of counters
806 */ 806 */
807 ifp->if_ierrors++; 807 if_statinc(ifp, if_ierrors);
808 RX_DPRINTF(("dme_receive: " 808 RX_DPRINTF(("dme_receive: "
809 "Error reciving packet\n")); 809 "Error reciving packet\n"));
810 } else if (rx_status & DM9000_RSR_LCS) { 810 } else if (rx_status & DM9000_RSR_LCS) {
811 ifp->if_collisions++; 811 if_statinc(ifp, if_collisions);
812 } else { 812 } else {
813 if_percpuq_enqueue(ifp->if_percpuq, m); 813 if_percpuq_enqueue(ifp->if_percpuq, m);
814 } 814 }
815 815
816 } else if (ready != 0x00) { 816 } else if (ready != 0x00) {
817 /* Should this be logged somehow? */ 817 /* Should this be logged somehow? */
818 printf("%s: Resetting chip\n", 818 printf("%s: Resetting chip\n",
819 device_xname(sc->sc_dev)); 819 device_xname(sc->sc_dev));
820 dme_reset(sc); 820 dme_reset(sc);
821 } 821 }
822 } 822 }
823} 823}
824 824
825void 825void
826dme_reset(struct dme_softc *sc) 826dme_reset(struct dme_softc *sc)
827{ 827{
828 uint8_t var; 828 uint8_t var;
829 829
830 /* We only re-initialized the PHY in this function the first time it is 830 /* We only re-initialized the PHY in this function the first time it is
831 called. */ 831 called. */
832 if (!sc->sc_phy_initialized) { 832 if (!sc->sc_phy_initialized) {
833 /* PHY Reset */ 833 /* PHY Reset */
834 dme_phy_write(sc, DM9000_PHY_BMCR, DM9000_PHY_BMCR_RESET); 834 dme_phy_write(sc, DM9000_PHY_BMCR, DM9000_PHY_BMCR_RESET);
835 835
836 /* PHY Power Down */ 836 /* PHY Power Down */
837 var = dme_read(sc, DM9000_GPR); 837 var = dme_read(sc, DM9000_GPR);
838 dme_write(sc, DM9000_GPR, var | DM9000_GPR_PHY_PWROFF); 838 dme_write(sc, DM9000_GPR, var | DM9000_GPR_PHY_PWROFF);
839 } 839 }
840 840
841 /* Reset the DM9000 twice, as described in section 2 of the Programming 841 /* Reset the DM9000 twice, as described in section 2 of the Programming
842 Guide. 842 Guide.
843 The PHY is initialized and enabled between those two resets. 843 The PHY is initialized and enabled between those two resets.
844 */ 844 */
845 845
846 /* Software Reset*/ 846 /* Software Reset*/
847 dme_write(sc, DM9000_NCR, 847 dme_write(sc, DM9000_NCR,
848 DM9000_NCR_RST | DM9000_NCR_LBK_MAC_INTERNAL); 848 DM9000_NCR_RST | DM9000_NCR_LBK_MAC_INTERNAL);
849 delay(20); 849 delay(20);
850 dme_write(sc, DM9000_NCR, 0x0); 850 dme_write(sc, DM9000_NCR, 0x0);
851 851
852 if (!sc->sc_phy_initialized) { 852 if (!sc->sc_phy_initialized) {
853 /* PHY Initialization */ 853 /* PHY Initialization */
854 dme_phy_init(sc); 854 dme_phy_init(sc);
855 855
856 /* PHY Enable */ 856 /* PHY Enable */
857 var = dme_read(sc, DM9000_GPR); 857 var = dme_read(sc, DM9000_GPR);
858 dme_write(sc, DM9000_GPR, var & ~DM9000_GPR_PHY_PWROFF); 858 dme_write(sc, DM9000_GPR, var & ~DM9000_GPR_PHY_PWROFF);
859 var = dme_read(sc, DM9000_GPCR); 859 var = dme_read(sc, DM9000_GPCR);
860 dme_write(sc, DM9000_GPCR, var | DM9000_GPCR_GPIO0_OUT); 860 dme_write(sc, DM9000_GPCR, var | DM9000_GPCR_GPIO0_OUT);
861 861
862 dme_write(sc, DM9000_NCR, 862 dme_write(sc, DM9000_NCR,
863 DM9000_NCR_RST | DM9000_NCR_LBK_MAC_INTERNAL); 863 DM9000_NCR_RST | DM9000_NCR_LBK_MAC_INTERNAL);
864 delay(20); 864 delay(20);
865 dme_write(sc, DM9000_NCR, 0x0); 865 dme_write(sc, DM9000_NCR, 0x0);
866 } 866 }
867 867
868 /* Select internal PHY, no wakeup event, no collosion mode, 868 /* Select internal PHY, no wakeup event, no collosion mode,
869 * normal loopback mode. 869 * normal loopback mode.
870 */ 870 */
871 dme_write(sc, DM9000_NCR, DM9000_NCR_LBK_NORMAL ); 871 dme_write(sc, DM9000_NCR, DM9000_NCR_LBK_NORMAL );
872 872
873 /* Will clear TX1END, TX2END, and WAKEST fields by reading DM9000_NSR*/ 873 /* Will clear TX1END, TX2END, and WAKEST fields by reading DM9000_NSR*/
874 dme_read(sc, DM9000_NSR); 874 dme_read(sc, DM9000_NSR);
875 875
876 /* Enable wraparound of read/write pointer, packet received latch, 876 /* Enable wraparound of read/write pointer, packet received latch,
877 * and packet transmitted latch. 877 * and packet transmitted latch.
878 */ 878 */
879 dme_write(sc, DM9000_IMR, 879 dme_write(sc, DM9000_IMR,
880 DM9000_IMR_PAR | DM9000_IMR_PRM | DM9000_IMR_PTM); 880 DM9000_IMR_PAR | DM9000_IMR_PRM | DM9000_IMR_PTM);
881 881
882 /* Setup multicast address filter, and enable RX. */ 882 /* Setup multicast address filter, and enable RX. */
883 dme_set_addr_filter(sc); 883 dme_set_addr_filter(sc);
884 884
885 /* Obtain media information from PHY */ 885 /* Obtain media information from PHY */
886 dme_phy_update_media(sc); 886 dme_phy_update_media(sc);
887 887
888 sc->txbusy = 0; 888 sc->txbusy = 0;
889 sc->txready = 0; 889 sc->txready = 0;
890 sc->sc_phy_initialized = 1; 890 sc->sc_phy_initialized = 1;
891} 891}
892 892
893void 893void
894dme_set_addr_filter(struct dme_softc *sc) 894dme_set_addr_filter(struct dme_softc *sc)
895{ 895{
896 struct ether_multi *enm; 896 struct ether_multi *enm;
897 struct ether_multistep step; 897 struct ether_multistep step;
898 struct ethercom *ec; 898 struct ethercom *ec;
899 struct ifnet *ifp; 899 struct ifnet *ifp;
900 uint16_t af[4]; 900 uint16_t af[4];
901 int i; 901 int i;
902 902
903 ec = &sc->sc_ethercom; 903 ec = &sc->sc_ethercom;
904 ifp = &ec->ec_if; 904 ifp = &ec->ec_if;
905 905
906 if (ifp->if_flags & IFF_PROMISC) { 906 if (ifp->if_flags & IFF_PROMISC) {
907 dme_write(sc, DM9000_RCR, DM9000_RCR_RXEN | 907 dme_write(sc, DM9000_RCR, DM9000_RCR_RXEN |
908 DM9000_RCR_WTDIS | 908 DM9000_RCR_WTDIS |
909 DM9000_RCR_PRMSC); 909 DM9000_RCR_PRMSC);
910 ifp->if_flags |= IFF_ALLMULTI; 910 ifp->if_flags |= IFF_ALLMULTI;
911 return; 911 return;
912 } 912 }
913 913
914 af[0] = af[1] = af[2] = af[3] = 0x0000; 914 af[0] = af[1] = af[2] = af[3] = 0x0000;
915 ifp->if_flags &= ~IFF_ALLMULTI; 915 ifp->if_flags &= ~IFF_ALLMULTI;
916 916
917 ETHER_LOCK(ec); 917 ETHER_LOCK(ec);
918 ETHER_FIRST_MULTI(step, ec, enm); 918 ETHER_FIRST_MULTI(step, ec, enm);
919 while (enm != NULL) { 919 while (enm != NULL) {
920 uint16_t hash; 920 uint16_t hash;
921 if (memcpy(enm->enm_addrlo, enm->enm_addrhi, 921 if (memcpy(enm->enm_addrlo, enm->enm_addrhi,
922 sizeof(enm->enm_addrlo))) { 922 sizeof(enm->enm_addrlo))) {
923 /* 923 /*
924 * We must listen to a range of multicast addresses. 924 * We must listen to a range of multicast addresses.
925 * For now, just accept all multicasts, rather than 925 * For now, just accept all multicasts, rather than
926 * trying to set only those filter bits needed to match 926 * trying to set only those filter bits needed to match
927 * the range. (At this time, the only use of address 927 * the range. (At this time, the only use of address
928 * ranges is for IP multicast routing, for which the 928 * ranges is for IP multicast routing, for which the
929 * range is big enough to require all bits set.) 929 * range is big enough to require all bits set.)
930 */ 930 */
931 ifp->if_flags |= IFF_ALLMULTI; 931 ifp->if_flags |= IFF_ALLMULTI;
932 af[0] = af[1] = af[2] = af[3] = 0xffff; 932 af[0] = af[1] = af[2] = af[3] = 0xffff;
933 break; 933 break;
934 } else { 934 } else {
935 hash = ether_crc32_le(enm->enm_addrlo, ETHER_ADDR_LEN) & 0x3F; 935 hash = ether_crc32_le(enm->enm_addrlo, ETHER_ADDR_LEN) & 0x3F;
936 af[(uint16_t)(hash>>4)] |= (uint16_t)(1 << (hash % 16)); 936 af[(uint16_t)(hash>>4)] |= (uint16_t)(1 << (hash % 16));
937 ETHER_NEXT_MULTI(step, enm); 937 ETHER_NEXT_MULTI(step, enm);
938 } 938 }
939 } 939 }
940 ETHER_UNLOCK(ec); 940 ETHER_UNLOCK(ec);
941 941
942 /* Write the multicast address filter */ 942 /* Write the multicast address filter */
943 for (i = 0; i < 4; i++) { 943 for (i = 0; i < 4; i++) {
944 dme_write(sc, DM9000_MAB0+i*2, af[i] & 0xFF); 944 dme_write(sc, DM9000_MAB0+i*2, af[i] & 0xFF);
945 dme_write(sc, DM9000_MAB0+i*2+1, (af[i] >> 8) & 0xFF); 945 dme_write(sc, DM9000_MAB0+i*2+1, (af[i] >> 8) & 0xFF);
946 } 946 }
947 947
948 /* Setup RX controls */ 948 /* Setup RX controls */
949 dme_write(sc, DM9000_RCR, DM9000_RCR_RXEN | DM9000_RCR_WTDIS); 949 dme_write(sc, DM9000_RCR, DM9000_RCR_RXEN | DM9000_RCR_WTDIS);
950} 950}
951 951
952int 952int
953dme_pkt_write_2(struct dme_softc *sc, struct mbuf *bufChain) 953dme_pkt_write_2(struct dme_softc *sc, struct mbuf *bufChain)
954{ 954{
955 int left_over_count = 0; /* Number of bytes from previous mbuf, which 955 int left_over_count = 0; /* Number of bytes from previous mbuf, which
956 need to be written with the next.*/ 956 need to be written with the next.*/
957 uint16_t left_over_buf = 0; 957 uint16_t left_over_buf = 0;
958 int length = 0; 958 int length = 0;
959 struct mbuf *buf; 959 struct mbuf *buf;
960 uint8_t *write_ptr; 960 uint8_t *write_ptr;
961 961
962 /* We expect that the DM9000 has been setup to accept writes before 962 /* We expect that the DM9000 has been setup to accept writes before
963 this function is called. */ 963 this function is called. */
964 964
965 for (buf = bufChain; buf != NULL; buf = buf->m_next) { 965 for (buf = bufChain; buf != NULL; buf = buf->m_next) {
966 int to_write = buf->m_len; 966 int to_write = buf->m_len;
967 967
968 length += to_write; 968 length += to_write;
969 969
970 write_ptr = buf->m_data; 970 write_ptr = buf->m_data;
971 while (to_write > 0 || 971 while (to_write > 0 ||
972 (buf->m_next == NULL && left_over_count > 0)) { 972 (buf->m_next == NULL && left_over_count > 0)) {
973 if (left_over_count > 0) { 973 if (left_over_count > 0) {
974 uint8_t b = 0; 974 uint8_t b = 0;
975 DPRINTF(("dme_pkt_write_16: " 975 DPRINTF(("dme_pkt_write_16: "
976 "Writing left over byte\n")); 976 "Writing left over byte\n"));
977 977
978 if (to_write > 0) { 978 if (to_write > 0) {
979 b = *write_ptr; 979 b = *write_ptr;
980 to_write--; 980 to_write--;
981 write_ptr++; 981 write_ptr++;
982 982
983 DPRINTF(("Took single byte\n")); 983 DPRINTF(("Took single byte\n"));
984 } else { 984 } else {
985 DPRINTF(("Leftover in last run\n")); 985 DPRINTF(("Leftover in last run\n"));
986 length++; 986 length++;
987 } 987 }
988 988
989 /* Does shift direction depend on endianess? */ 989 /* Does shift direction depend on endianess? */
990 left_over_buf = left_over_buf | (b << 8); 990 left_over_buf = left_over_buf | (b << 8);
991 991
992 bus_space_write_2(sc->sc_iot, sc->sc_ioh, 992 bus_space_write_2(sc->sc_iot, sc->sc_ioh,
993 sc->dme_data, left_over_buf); 993 sc->dme_data, left_over_buf);
994 TX_DATA_DPRINTF(("%02X ", left_over_buf)); 994 TX_DATA_DPRINTF(("%02X ", left_over_buf));
995 left_over_count = 0; 995 left_over_count = 0;
996 } else if ((long)write_ptr % 2 != 0) { 996 } else if ((long)write_ptr % 2 != 0) {
997 /* Misaligned data */ 997 /* Misaligned data */
998 DPRINTF(("dme_pkt_write_16: " 998 DPRINTF(("dme_pkt_write_16: "
999 "Detected misaligned data\n")); 999 "Detected misaligned data\n"));
1000 left_over_buf = *write_ptr; 1000 left_over_buf = *write_ptr;
1001 left_over_count = 1; 1001 left_over_count = 1;
1002 write_ptr++; 1002 write_ptr++;
1003 to_write--; 1003 to_write--;
1004 } else { 1004 } else {
1005 int i; 1005 int i;
1006 uint16_t *dptr = (uint16_t *)write_ptr; 1006 uint16_t *dptr = (uint16_t *)write_ptr;
1007 1007
1008 /* A block of aligned data. */ 1008 /* A block of aligned data. */
1009 for (i = 0; i < to_write / 2; i++) { 1009 for (i = 0; i < to_write / 2; i++) {
1010 /* buf will be half-word aligned 1010 /* buf will be half-word aligned
1011 * all the time 1011 * all the time
1012 */ 1012 */
1013 bus_space_write_2(sc->sc_iot, 1013 bus_space_write_2(sc->sc_iot,
1014 sc->sc_ioh, sc->dme_data, *dptr); 1014 sc->sc_ioh, sc->dme_data, *dptr);
1015 TX_DATA_DPRINTF(("%02X %02X ", 1015 TX_DATA_DPRINTF(("%02X %02X ",
1016 *dptr & 0xFF, (*dptr >> 8) & 0xFF)); 1016 *dptr & 0xFF, (*dptr >> 8) & 0xFF));
1017 dptr++; 1017 dptr++;
1018 } 1018 }
1019 1019
1020 write_ptr += i * 2; 1020 write_ptr += i * 2;
1021 if (to_write % 2 != 0) { 1021 if (to_write % 2 != 0) {
1022 DPRINTF(("dme_pkt_write_16: " 1022 DPRINTF(("dme_pkt_write_16: "
1023 "to_write %% 2: %d\n", 1023 "to_write %% 2: %d\n",
1024 to_write % 2)); 1024 to_write % 2));
1025 left_over_count = 1; 1025 left_over_count = 1;
1026 /* XXX: Does this depend on 1026 /* XXX: Does this depend on
1027 * the endianess? 1027 * the endianess?
1028 */ 1028 */
1029 left_over_buf = *write_ptr; 1029 left_over_buf = *write_ptr;
1030 1030
1031 write_ptr++; 1031 write_ptr++;
1032 to_write--; 1032 to_write--;
1033 DPRINTF(("dme_pkt_write_16: " 1033 DPRINTF(("dme_pkt_write_16: "
1034 "to_write (after): %d\n", 1034 "to_write (after): %d\n",
1035 to_write)); 1035 to_write));
1036 DPRINTF(("dme_pkt_write_16: i * 2: %d\n", 1036 DPRINTF(("dme_pkt_write_16: i * 2: %d\n",
1037 i*2)); 1037 i*2));
1038 } 1038 }
1039 to_write -= i * 2; 1039 to_write -= i * 2;
1040 } 1040 }
1041 } /* while (...) */ 1041 } /* while (...) */
1042 } /* for (...) */ 1042 } /* for (...) */
1043 1043
1044 return length; 1044 return length;
1045} 1045}
1046 1046
1047int 1047int
1048dme_pkt_read_2(struct dme_softc *sc, struct ifnet *ifp, struct mbuf **outBuf) 1048dme_pkt_read_2(struct dme_softc *sc, struct ifnet *ifp, struct mbuf **outBuf)
1049{ 1049{
1050 uint8_t rx_status; 1050 uint8_t rx_status;
1051 struct mbuf *m; 1051 struct mbuf *m;
1052 uint16_t data; 1052 uint16_t data;
1053 uint16_t frame_length; 1053 uint16_t frame_length;
1054 uint16_t i; 1054 uint16_t i;
1055 uint16_t *buf; 1055 uint16_t *buf;
1056 1056
1057 data = bus_space_read_2(sc->sc_iot, sc->sc_ioh, sc->dme_data); 1057 data = bus_space_read_2(sc->sc_iot, sc->sc_ioh, sc->dme_data);
1058 1058
1059 rx_status = data & 0xFF; 1059 rx_status = data & 0xFF;
1060 frame_length = bus_space_read_2(sc->sc_iot, 1060 frame_length = bus_space_read_2(sc->sc_iot,
1061 sc->sc_ioh, sc->dme_data); 1061 sc->sc_ioh, sc->dme_data);
1062 if (frame_length > ETHER_MAX_LEN) { 1062 if (frame_length > ETHER_MAX_LEN) {
1063 printf("Got frame of length: %d\n", frame_length); 1063 printf("Got frame of length: %d\n", frame_length);
1064 printf("ETHER_MAX_LEN is: %d\n", ETHER_MAX_LEN); 1064 printf("ETHER_MAX_LEN is: %d\n", ETHER_MAX_LEN);
1065 panic("Something is rotten"); 1065 panic("Something is rotten");
1066 } 1066 }
1067 RX_DPRINTF(("dme_receive: rx_statux: 0x%x, frame_length: %d\n", 1067 RX_DPRINTF(("dme_receive: rx_statux: 0x%x, frame_length: %d\n",
1068 rx_status, frame_length)); 1068 rx_status, frame_length));
1069 1069
1070 1070
1071 m = dme_alloc_receive_buffer(ifp, frame_length); 1071 m = dme_alloc_receive_buffer(ifp, frame_length);
1072 if (m == NULL) { 1072 if (m == NULL) {
1073 /* 1073 /*
1074 * didn't get a receive buffer, so we read the rest of the 1074 * didn't get a receive buffer, so we read the rest of the
1075 * packet, throw it away and return an error 1075 * packet, throw it away and return an error
1076 */ 1076 */
1077 for (i = 0; i < frame_length; i += 2 ) { 1077 for (i = 0; i < frame_length; i += 2 ) {
1078 data = bus_space_read_2(sc->sc_iot, 1078 data = bus_space_read_2(sc->sc_iot,
1079 sc->sc_ioh, sc->dme_data); 1079 sc->sc_ioh, sc->dme_data);
1080 } 1080 }
1081 *outBuf = NULL; 1081 *outBuf = NULL;
1082 return 0; 1082 return 0;
1083 } 1083 }
1084 1084
1085 buf = mtod(m, uint16_t*); 1085 buf = mtod(m, uint16_t*);
1086 1086
1087 RX_DPRINTF(("dme_receive: ")); 1087 RX_DPRINTF(("dme_receive: "));
1088 1088
1089 for (i = 0; i < frame_length; i += 2 ) { 1089 for (i = 0; i < frame_length; i += 2 ) {
1090 data = bus_space_read_2(sc->sc_iot, 1090 data = bus_space_read_2(sc->sc_iot,
1091 sc->sc_ioh, sc->dme_data); 1091 sc->sc_ioh, sc->dme_data);
1092 if ( (frame_length % 2 != 0) && 1092 if ( (frame_length % 2 != 0) &&
1093 (i == frame_length - 1) ) { 1093 (i == frame_length - 1) ) {
1094 data = data & 0xff; 1094 data = data & 0xff;
1095 RX_DPRINTF((" L ")); 1095 RX_DPRINTF((" L "));
1096 } 1096 }
1097 *buf = data; 1097 *buf = data;
1098 buf++; 1098 buf++;
1099 RX_DATA_DPRINTF(("%02X %02X ", data & 0xff, 1099 RX_DATA_DPRINTF(("%02X %02X ", data & 0xff,
1100 (data >> 8) & 0xff)); 1100 (data >> 8) & 0xff));
1101 } 1101 }
1102 1102
1103 RX_DATA_DPRINTF(("\n")); 1103 RX_DATA_DPRINTF(("\n"));
1104 RX_DPRINTF(("Read %d bytes\n", i)); 1104 RX_DPRINTF(("Read %d bytes\n", i));
1105 1105
1106 *outBuf = m; 1106 *outBuf = m;
1107 return rx_status; 1107 return rx_status;
1108} 1108}
1109 1109
1110int 1110int
1111dme_pkt_write_1(struct dme_softc *sc, struct mbuf *bufChain) 1111dme_pkt_write_1(struct dme_softc *sc, struct mbuf *bufChain)
1112{ 1112{
1113 int length = 0, i; 1113 int length = 0, i;
1114 struct mbuf *buf; 1114 struct mbuf *buf;
1115 uint8_t *write_ptr; 1115 uint8_t *write_ptr;
1116 1116
1117 /* 1117 /*
1118 * We expect that the DM9000 has been setup to accept writes before 1118 * We expect that the DM9000 has been setup to accept writes before
1119 * this function is called. 1119 * this function is called.
1120 */ 1120 */
1121 1121
1122 for (buf = bufChain; buf != NULL; buf = buf->m_next) { 1122 for (buf = bufChain; buf != NULL; buf = buf->m_next) {
1123 int to_write = buf->m_len; 1123 int to_write = buf->m_len;
1124 1124
1125 length += to_write; 1125 length += to_write;
1126 1126
1127 write_ptr = buf->m_data; 1127 write_ptr = buf->m_data;
1128 for (i = 0; i < to_write; i++) { 1128 for (i = 0; i < to_write; i++) {
1129 bus_space_write_1(sc->sc_iot, sc->sc_ioh, 1129 bus_space_write_1(sc->sc_iot, sc->sc_ioh,
1130 sc->dme_data, *write_ptr); 1130 sc->dme_data, *write_ptr);
1131 write_ptr++; 1131 write_ptr++;
1132 } 1132 }
1133 } /* for (...) */ 1133 } /* for (...) */
1134 1134
1135 return length; 1135 return length;
1136} 1136}
1137 1137
1138int 1138int
1139dme_pkt_read_1(struct dme_softc *sc, struct ifnet *ifp, struct mbuf **outBuf) 1139dme_pkt_read_1(struct dme_softc *sc, struct ifnet *ifp, struct mbuf **outBuf)
1140{ 1140{
1141 uint8_t rx_status; 1141 uint8_t rx_status;
1142 struct mbuf *m; 1142 struct mbuf *m;
1143 uint8_t *buf; 1143 uint8_t *buf;
1144 uint16_t frame_length; 1144 uint16_t frame_length;
1145 uint16_t i, reg; 1145 uint16_t i, reg;
1146 uint8_t data; 1146 uint8_t data;
1147 1147
1148 reg = bus_space_read_1(sc->sc_iot, sc->sc_ioh, sc->dme_data); 1148 reg = bus_space_read_1(sc->sc_iot, sc->sc_ioh, sc->dme_data);
1149 reg |= bus_space_read_1(sc->sc_iot, sc->sc_ioh, sc->dme_data) << 8; 1149 reg |= bus_space_read_1(sc->sc_iot, sc->sc_ioh, sc->dme_data) << 8;
1150 rx_status = reg & 0xFF; 1150 rx_status = reg & 0xFF;
1151 1151
1152 reg = bus_space_read_1(sc->sc_iot, sc->sc_ioh, sc->dme_data); 1152 reg = bus_space_read_1(sc->sc_iot, sc->sc_ioh, sc->dme_data);
1153 reg |= bus_space_read_1(sc->sc_iot, sc->sc_ioh, sc->dme_data) << 8; 1153 reg |= bus_space_read_1(sc->sc_iot, sc->sc_ioh, sc->dme_data) << 8;
1154 frame_length = reg; 1154 frame_length = reg;
1155 1155
1156 if (frame_length > ETHER_MAX_LEN) { 1156 if (frame_length > ETHER_MAX_LEN) {
1157 printf("Got frame of length: %d\n", frame_length); 1157 printf("Got frame of length: %d\n", frame_length);
1158 printf("ETHER_MAX_LEN is: %d\n", ETHER_MAX_LEN); 1158 printf("ETHER_MAX_LEN is: %d\n", ETHER_MAX_LEN);
1159 panic("Something is rotten"); 1159 panic("Something is rotten");
1160 } 1160 }
1161 RX_DPRINTF(("dme_receive: " 1161 RX_DPRINTF(("dme_receive: "
1162 "rx_statux: 0x%x, frame_length: %d\n", 1162 "rx_statux: 0x%x, frame_length: %d\n",
1163 rx_status, frame_length)); 1163 rx_status, frame_length));
1164 1164
1165 1165
1166 m = dme_alloc_receive_buffer(ifp, frame_length); 1166 m = dme_alloc_receive_buffer(ifp, frame_length);
1167 if (m == NULL) { 1167 if (m == NULL) {
1168 /* 1168 /*
1169 * didn't get a receive buffer, so we read the rest of the 1169 * didn't get a receive buffer, so we read the rest of the
1170 * packet, throw it away and return an error 1170 * packet, throw it away and return an error
1171 */ 1171 */
1172 for (i = 0; i < frame_length; i++ ) { 1172 for (i = 0; i < frame_length; i++ ) {
1173 data = bus_space_read_2(sc->sc_iot, 1173 data = bus_space_read_2(sc->sc_iot,
1174 sc->sc_ioh, sc->dme_data); 1174 sc->sc_ioh, sc->dme_data);
1175 } 1175 }
1176 *outBuf = NULL; 1176 *outBuf = NULL;
1177 return 0; 1177 return 0;
1178 } 1178 }
1179 1179
1180 buf = mtod(m, uint8_t *); 1180 buf = mtod(m, uint8_t *);
1181 1181
1182 RX_DPRINTF(("dme_receive: ")); 1182 RX_DPRINTF(("dme_receive: "));
1183 1183
1184 for (i = 0; i< frame_length; i += 1 ) { 1184 for (i = 0; i< frame_length; i += 1 ) {
1185 data = bus_space_read_1(sc->sc_iot, sc->sc_ioh, sc->dme_data); 1185 data = bus_space_read_1(sc->sc_iot, sc->sc_ioh, sc->dme_data);
1186 *buf = data; 1186 *buf = data;
1187 buf++; 1187 buf++;
1188 RX_DATA_DPRINTF(("%02X ", data)); 1188 RX_DATA_DPRINTF(("%02X ", data));
1189 } 1189 }
1190 1190
1191 RX_DATA_DPRINTF(("\n")); 1191 RX_DATA_DPRINTF(("\n"));
1192 RX_DPRINTF(("Read %d bytes\n", i)); 1192 RX_DPRINTF(("Read %d bytes\n", i));
1193 1193
1194 *outBuf = m; 1194 *outBuf = m;
1195 return rx_status; 1195 return rx_status;
1196} 1196}
1197 1197
1198struct mbuf* 1198struct mbuf*
1199dme_alloc_receive_buffer(struct ifnet *ifp, unsigned int frame_length) 1199dme_alloc_receive_buffer(struct ifnet *ifp, unsigned int frame_length)
1200{ 1200{
1201 struct dme_softc *sc = ifp->if_softc; 1201 struct dme_softc *sc = ifp->if_softc;
1202 struct mbuf *m; 1202 struct mbuf *m;
1203 int pad; 1203 int pad;
1204 1204
1205 MGETHDR(m, M_DONTWAIT, MT_DATA); 1205 MGETHDR(m, M_DONTWAIT, MT_DATA);
1206 if (m == NULL) return NULL; 1206 if (m == NULL) return NULL;
1207 1207
1208 m_set_rcvif(m, ifp); 1208 m_set_rcvif(m, ifp);
1209 /* Ensure that we always allocate an even number of 1209 /* Ensure that we always allocate an even number of
1210 * bytes in order to avoid writing beyond the buffer 1210 * bytes in order to avoid writing beyond the buffer
1211 */ 1211 */
1212 m->m_pkthdr.len = frame_length + (frame_length % sc->sc_data_width); 1212 m->m_pkthdr.len = frame_length + (frame_length % sc->sc_data_width);
1213 pad = ALIGN(sizeof(struct ether_header)) - 1213 pad = ALIGN(sizeof(struct ether_header)) -
1214 sizeof(struct ether_header); 1214 sizeof(struct ether_header);
1215 /* All our frames have the CRC attached */ 1215 /* All our frames have the CRC attached */
1216 m->m_flags |= M_HASFCS; 1216 m->m_flags |= M_HASFCS;
1217 if (m->m_pkthdr.len + pad > MHLEN) { 1217 if (m->m_pkthdr.len + pad > MHLEN) {
1218 MCLGET(m, M_DONTWAIT); 1218 MCLGET(m, M_DONTWAIT);
1219 if ((m->m_flags & M_EXT) == 0) { 1219 if ((m->m_flags & M_EXT) == 0) {
1220 m_freem(m); 1220 m_freem(m);
1221 return NULL; 1221 return NULL;
1222 } 1222 }
1223 } 1223 }
1224 1224
1225 m->m_data += pad; 1225 m->m_data += pad;
1226 m->m_len = frame_length + (frame_length % sc->sc_data_width); 1226 m->m_len = frame_length + (frame_length % sc->sc_data_width);
1227 1227
1228 return m; 1228 return m;
1229} 1229}

cvs diff -r1.95 -r1.96 src/sys/dev/ic/dp8390.c (switch to unified diff)

--- src/sys/dev/ic/dp8390.c 2019/05/29 10:07:29 1.95
+++ src/sys/dev/ic/dp8390.c 2020/01/29 14:14:55 1.96
@@ -1,1227 +1,1231 @@ @@ -1,1227 +1,1231 @@
1/* $NetBSD: dp8390.c,v 1.95 2019/05/29 10:07:29 msaitoh Exp $ */ 1/* $NetBSD: dp8390.c,v 1.96 2020/01/29 14:14:55 thorpej Exp $ */
2 2
3/* 3/*
4 * Device driver for National Semiconductor DS8390/WD83C690 based ethernet 4 * Device driver for National Semiconductor DS8390/WD83C690 based ethernet
5 * adapters. 5 * adapters.
6 * 6 *
7 * Copyright (c) 1994, 1995 Charles M. Hannum. All rights reserved. 7 * Copyright (c) 1994, 1995 Charles M. Hannum. All rights reserved.
8 * 8 *
9 * Copyright (C) 1993, David Greenman. This software may be used, modified, 9 * Copyright (C) 1993, David Greenman. This software may be used, modified,
10 * copied, distributed, and sold, in both source and binary form provided that 10 * copied, distributed, and sold, in both source and binary form provided that
11 * the above copyright and these terms are retained. Under no circumstances is 11 * the above copyright and these terms are retained. Under no circumstances is
12 * the author responsible for the proper functioning of this software, nor does 12 * the author responsible for the proper functioning of this software, nor does
13 * the author assume any responsibility for damages incurred with its use. 13 * the author assume any responsibility for damages incurred with its use.
14 */ 14 */
15 15
16#include <sys/cdefs.h> 16#include <sys/cdefs.h>
17__KERNEL_RCSID(0, "$NetBSD: dp8390.c,v 1.95 2019/05/29 10:07:29 msaitoh Exp $"); 17__KERNEL_RCSID(0, "$NetBSD: dp8390.c,v 1.96 2020/01/29 14:14:55 thorpej Exp $");
18 18
19#include "opt_inet.h" 19#include "opt_inet.h"
20 20
21#include <sys/param.h> 21#include <sys/param.h>
22#include <sys/systm.h> 22#include <sys/systm.h>
23#include <sys/device.h> 23#include <sys/device.h>
24#include <sys/errno.h> 24#include <sys/errno.h>
25#include <sys/ioctl.h> 25#include <sys/ioctl.h>
26#include <sys/mbuf.h> 26#include <sys/mbuf.h>
27#include <sys/socket.h> 27#include <sys/socket.h>
28#include <sys/syslog.h> 28#include <sys/syslog.h>
29#include <sys/rndsource.h> 29#include <sys/rndsource.h>
30#include <sys/bus.h> 30#include <sys/bus.h>
31 31
32#include <net/if.h> 32#include <net/if.h>
33#include <net/if_dl.h> 33#include <net/if_dl.h>
34#include <net/if_types.h> 34#include <net/if_types.h>
35#include <net/if_media.h> 35#include <net/if_media.h>
36#include <net/if_ether.h> 36#include <net/if_ether.h>
37#include <net/bpf.h> 37#include <net/bpf.h>
38 38
39#ifdef INET 39#ifdef INET
40#include <netinet/in.h> 40#include <netinet/in.h>
41#include <netinet/in_systm.h> 41#include <netinet/in_systm.h>
42#include <netinet/in_var.h> 42#include <netinet/in_var.h>
43#include <netinet/ip.h> 43#include <netinet/ip.h>
44#include <netinet/if_inarp.h> 44#include <netinet/if_inarp.h>
45#endif 45#endif
46 46
47#include <dev/ic/dp8390reg.h> 47#include <dev/ic/dp8390reg.h>
48#include <dev/ic/dp8390var.h> 48#include <dev/ic/dp8390var.h>
49 49
50#ifdef DEBUG 50#ifdef DEBUG
51int dp8390_debug = 0; 51int dp8390_debug = 0;
52#endif 52#endif
53 53
54static void dp8390_xmit(struct dp8390_softc *); 54static void dp8390_xmit(struct dp8390_softc *);
55 55
56static void dp8390_read_hdr(struct dp8390_softc *, int, struct dp8390_ring *); 56static void dp8390_read_hdr(struct dp8390_softc *, int, struct dp8390_ring *);
57static int dp8390_ring_copy(struct dp8390_softc *, int, void *, u_short); 57static int dp8390_ring_copy(struct dp8390_softc *, int, void *, u_short);
58static int dp8390_write_mbuf(struct dp8390_softc *, struct mbuf *, int); 58static int dp8390_write_mbuf(struct dp8390_softc *, struct mbuf *, int);
59 59
60static int dp8390_test_mem(struct dp8390_softc *); 60static int dp8390_test_mem(struct dp8390_softc *);
61 61
62/* 62/*
63 * Standard media init routine for the dp8390. 63 * Standard media init routine for the dp8390.
64 */ 64 */
65void 65void
66dp8390_media_init(struct dp8390_softc *sc) 66dp8390_media_init(struct dp8390_softc *sc)
67{ 67{
68 68
69 sc->sc_ec.ec_ifmedia = &sc->sc_media; 69 sc->sc_ec.ec_ifmedia = &sc->sc_media;
70 ifmedia_init(&sc->sc_media, 0, dp8390_mediachange, dp8390_mediastatus); 70 ifmedia_init(&sc->sc_media, 0, dp8390_mediachange, dp8390_mediastatus);
71 ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_MANUAL, 0, NULL); 71 ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_MANUAL, 0, NULL);
72 ifmedia_set(&sc->sc_media, IFM_ETHER | IFM_MANUAL); 72 ifmedia_set(&sc->sc_media, IFM_ETHER | IFM_MANUAL);
73} 73}
74 74
75/* 75/*
76 * Do bus-independent setup. 76 * Do bus-independent setup.
77 */ 77 */
78int 78int
79dp8390_config(struct dp8390_softc *sc) 79dp8390_config(struct dp8390_softc *sc)
80{ 80{
81 struct ifnet *ifp = &sc->sc_ec.ec_if; 81 struct ifnet *ifp = &sc->sc_ec.ec_if;
82 int rv; 82 int rv;
83 83
84 rv = 1; 84 rv = 1;
85 85
86 if (sc->test_mem == NULL) 86 if (sc->test_mem == NULL)
87 sc->test_mem = dp8390_test_mem; 87 sc->test_mem = dp8390_test_mem;
88 if (sc->read_hdr == NULL) 88 if (sc->read_hdr == NULL)
89 sc->read_hdr = dp8390_read_hdr; 89 sc->read_hdr = dp8390_read_hdr;
90 if (sc->recv_int == NULL) 90 if (sc->recv_int == NULL)
91 sc->recv_int = dp8390_rint; 91 sc->recv_int = dp8390_rint;
92 if (sc->ring_copy == NULL) 92 if (sc->ring_copy == NULL)
93 sc->ring_copy = dp8390_ring_copy; 93 sc->ring_copy = dp8390_ring_copy;
94 if (sc->write_mbuf == NULL) 94 if (sc->write_mbuf == NULL)
95 sc->write_mbuf = dp8390_write_mbuf; 95 sc->write_mbuf = dp8390_write_mbuf;
96 96
97 /* Allocate one xmit buffer if < 16k, two buffers otherwise. */ 97 /* Allocate one xmit buffer if < 16k, two buffers otherwise. */
98 if ((sc->mem_size < 16384) || 98 if ((sc->mem_size < 16384) ||
99 (sc->sc_flags & DP8390_NO_MULTI_BUFFERING)) 99 (sc->sc_flags & DP8390_NO_MULTI_BUFFERING))
100 sc->txb_cnt = 1; 100 sc->txb_cnt = 1;
101 else if (sc->mem_size < 8192 * 3) 101 else if (sc->mem_size < 8192 * 3)
102 sc->txb_cnt = 2; 102 sc->txb_cnt = 2;
103 else 103 else
104 sc->txb_cnt = 3; 104 sc->txb_cnt = 3;
105 105
106 sc->tx_page_start = sc->mem_start >> ED_PAGE_SHIFT; 106 sc->tx_page_start = sc->mem_start >> ED_PAGE_SHIFT;
107 sc->rec_page_start = sc->tx_page_start + sc->txb_cnt * ED_TXBUF_SIZE; 107 sc->rec_page_start = sc->tx_page_start + sc->txb_cnt * ED_TXBUF_SIZE;
108 sc->rec_page_stop = sc->tx_page_start + (sc->mem_size >> ED_PAGE_SHIFT); 108 sc->rec_page_stop = sc->tx_page_start + (sc->mem_size >> ED_PAGE_SHIFT);
109 sc->mem_ring = sc->mem_start + 109 sc->mem_ring = sc->mem_start +
110 ((sc->txb_cnt * ED_TXBUF_SIZE) << ED_PAGE_SHIFT); 110 ((sc->txb_cnt * ED_TXBUF_SIZE) << ED_PAGE_SHIFT);
111 sc->mem_end = sc->mem_start + sc->mem_size; 111 sc->mem_end = sc->mem_start + sc->mem_size;
112 112
113 /* Now zero memory and verify that it is clear. */ 113 /* Now zero memory and verify that it is clear. */
114 if ((*sc->test_mem)(sc)) 114 if ((*sc->test_mem)(sc))
115 goto out; 115 goto out;
116 116
117 /* Set interface to stopped condition (reset). */ 117 /* Set interface to stopped condition (reset). */
118 dp8390_stop(sc); 118 dp8390_stop(sc);
119 119
120 /* Initialize ifnet structure. */ 120 /* Initialize ifnet structure. */
121 strcpy(ifp->if_xname, device_xname(sc->sc_dev)); 121 strcpy(ifp->if_xname, device_xname(sc->sc_dev));
122 ifp->if_softc = sc; 122 ifp->if_softc = sc;
123 ifp->if_start = dp8390_start; 123 ifp->if_start = dp8390_start;
124 ifp->if_ioctl = dp8390_ioctl; 124 ifp->if_ioctl = dp8390_ioctl;
125 if (ifp->if_watchdog == NULL) 125 if (ifp->if_watchdog == NULL)
126 ifp->if_watchdog = dp8390_watchdog; 126 ifp->if_watchdog = dp8390_watchdog;
127 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 127 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
128 IFQ_SET_READY(&ifp->if_snd); 128 IFQ_SET_READY(&ifp->if_snd);
129 129
130 /* Print additional info when attached. */ 130 /* Print additional info when attached. */
131 aprint_normal_dev(sc->sc_dev, "Ethernet address %s\n", 131 aprint_normal_dev(sc->sc_dev, "Ethernet address %s\n",
132 ether_sprintf(sc->sc_enaddr)); 132 ether_sprintf(sc->sc_enaddr));
133 133
134 /* Initialize media goo. */ 134 /* Initialize media goo. */
135 (*sc->sc_media_init)(sc); 135 (*sc->sc_media_init)(sc);
136 136
137 /* We can support 802.1Q VLAN-sized frames. */ 137 /* We can support 802.1Q VLAN-sized frames. */
138 sc->sc_ec.ec_capabilities |= ETHERCAP_VLAN_MTU; 138 sc->sc_ec.ec_capabilities |= ETHERCAP_VLAN_MTU;
139 139
140 /* Attach the interface. */ 140 /* Attach the interface. */
141 if_attach(ifp); 141 if_attach(ifp);
142 if_deferred_start_init(ifp, NULL); 142 if_deferred_start_init(ifp, NULL);
143 ether_ifattach(ifp, sc->sc_enaddr); 143 ether_ifattach(ifp, sc->sc_enaddr);
144 144
145 rnd_attach_source(&sc->rnd_source, device_xname(sc->sc_dev), 145 rnd_attach_source(&sc->rnd_source, device_xname(sc->sc_dev),
146 RND_TYPE_NET, RND_FLAG_DEFAULT); 146 RND_TYPE_NET, RND_FLAG_DEFAULT);
147 147
148 /* The attach is successful. */ 148 /* The attach is successful. */
149 sc->sc_flags |= DP8390_ATTACHED; 149 sc->sc_flags |= DP8390_ATTACHED;
150 150
151 rv = 0; 151 rv = 0;
152 out: 152 out:
153 return rv; 153 return rv;
154} 154}
155 155
156/* 156/*
157 * Media change callback. 157 * Media change callback.
158 */ 158 */
159int 159int
160dp8390_mediachange(struct ifnet *ifp) 160dp8390_mediachange(struct ifnet *ifp)
161{ 161{
162 struct dp8390_softc *sc = ifp->if_softc; 162 struct dp8390_softc *sc = ifp->if_softc;
163 163
164 if (sc->sc_mediachange) 164 if (sc->sc_mediachange)
165 return (*sc->sc_mediachange)(sc); 165 return (*sc->sc_mediachange)(sc);
166 return 0; 166 return 0;
167} 167}
168 168
169/* 169/*
170 * Media status callback. 170 * Media status callback.
171 */ 171 */
172void 172void
173dp8390_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr) 173dp8390_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr)
174{ 174{
175 struct dp8390_softc *sc = ifp->if_softc; 175 struct dp8390_softc *sc = ifp->if_softc;
176 176
177 if (sc->sc_enabled == 0) { 177 if (sc->sc_enabled == 0) {
178 ifmr->ifm_active = IFM_ETHER | IFM_NONE; 178 ifmr->ifm_active = IFM_ETHER | IFM_NONE;
179 ifmr->ifm_status = 0; 179 ifmr->ifm_status = 0;
180 return; 180 return;
181 } 181 }
182 182
183 if (sc->sc_mediastatus) 183 if (sc->sc_mediastatus)
184 (*sc->sc_mediastatus)(sc, ifmr); 184 (*sc->sc_mediastatus)(sc, ifmr);
185} 185}
186 186
187/* 187/*
188 * Reset interface. 188 * Reset interface.
189 */ 189 */
190void 190void
191dp8390_reset(struct dp8390_softc *sc) 191dp8390_reset(struct dp8390_softc *sc)
192{ 192{
193 int s; 193 int s;
194 194
195 s = splnet(); 195 s = splnet();
196 dp8390_stop(sc); 196 dp8390_stop(sc);
197 dp8390_init(sc); 197 dp8390_init(sc);
198 splx(s); 198 splx(s);
199} 199}
200 200
201/* 201/*
202 * Take interface offline. 202 * Take interface offline.
203 */ 203 */
204void 204void
205dp8390_stop(struct dp8390_softc *sc) 205dp8390_stop(struct dp8390_softc *sc)
206{ 206{
207 bus_space_tag_t regt = sc->sc_regt; 207 bus_space_tag_t regt = sc->sc_regt;
208 bus_space_handle_t regh = sc->sc_regh; 208 bus_space_handle_t regh = sc->sc_regh;
209 int n = 5000; 209 int n = 5000;
210 210
211 /* Stop everything on the interface, and select page 0 registers. */ 211 /* Stop everything on the interface, and select page 0 registers. */
212 NIC_BARRIER(regt, regh); 212 NIC_BARRIER(regt, regh);
213 NIC_PUT(regt, regh, ED_P0_CR, 213 NIC_PUT(regt, regh, ED_P0_CR,
214 sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STP); 214 sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STP);
215 NIC_BARRIER(regt, regh); 215 NIC_BARRIER(regt, regh);
216 216
217 /* 217 /*
218 * Wait for interface to enter stopped state, but limit # of checks to 218 * Wait for interface to enter stopped state, but limit # of checks to
219 * 'n' (about 5ms). It shouldn't even take 5us on modern DS8390's, but 219 * 'n' (about 5ms). It shouldn't even take 5us on modern DS8390's, but
220 * just in case it's an old one. 220 * just in case it's an old one.
221 */ 221 */
222 while (((NIC_GET(regt, regh, ED_P0_ISR) & ED_ISR_RST) == 0) && --n) 222 while (((NIC_GET(regt, regh, ED_P0_ISR) & ED_ISR_RST) == 0) && --n)
223 DELAY(1); 223 DELAY(1);
224 224
225 if (sc->stop_card != NULL) 225 if (sc->stop_card != NULL)
226 (*sc->stop_card)(sc); 226 (*sc->stop_card)(sc);
227} 227}
228 228
229/* 229/*
230 * Device timeout/watchdog routine. Entered if the device neglects to generate 230 * Device timeout/watchdog routine. Entered if the device neglects to generate
231 * an interrupt after a transmit has been started on it. 231 * an interrupt after a transmit has been started on it.
232 */ 232 */
233 233
234void 234void
235dp8390_watchdog(struct ifnet *ifp) 235dp8390_watchdog(struct ifnet *ifp)
236{ 236{
237 struct dp8390_softc *sc = ifp->if_softc; 237 struct dp8390_softc *sc = ifp->if_softc;
238 238
239 log(LOG_ERR, "%s: device timeout\n", device_xname(sc->sc_dev)); 239 log(LOG_ERR, "%s: device timeout\n", device_xname(sc->sc_dev));
240 ++sc->sc_ec.ec_if.if_oerrors; 240 if_statinc(ifp, if_oerrors);
241 241
242 dp8390_reset(sc); 242 dp8390_reset(sc);
243} 243}
244 244
245/* 245/*
246 * Initialize device. 246 * Initialize device.
247 */ 247 */
248void 248void
249dp8390_init(struct dp8390_softc *sc) 249dp8390_init(struct dp8390_softc *sc)
250{ 250{
251 bus_space_tag_t regt = sc->sc_regt; 251 bus_space_tag_t regt = sc->sc_regt;
252 bus_space_handle_t regh = sc->sc_regh; 252 bus_space_handle_t regh = sc->sc_regh;
253 struct ifnet *ifp = &sc->sc_ec.ec_if; 253 struct ifnet *ifp = &sc->sc_ec.ec_if;
254 uint8_t mcaf[8]; 254 uint8_t mcaf[8];
255 int i; 255 int i;
256 256
257 /* 257 /*
258 * Initialize the NIC in the exact order outlined in the NS manual. 258 * Initialize the NIC in the exact order outlined in the NS manual.
259 * This init procedure is "mandatory"...don't change what or when 259 * This init procedure is "mandatory"...don't change what or when
260 * things happen. 260 * things happen.
261 */ 261 */
262 262
263 /* Reset transmitter flags. */ 263 /* Reset transmitter flags. */
264 ifp->if_timer = 0; 264 ifp->if_timer = 0;
265 265
266 sc->txb_inuse = 0; 266 sc->txb_inuse = 0;
267 sc->txb_new = 0; 267 sc->txb_new = 0;
268 sc->txb_next_tx = 0; 268 sc->txb_next_tx = 0;
269 269
270 /* Set interface for page 0, remote DMA complete, stopped. */ 270 /* Set interface for page 0, remote DMA complete, stopped. */
271 NIC_BARRIER(regt, regh); 271 NIC_BARRIER(regt, regh);
272 NIC_PUT(regt, regh, ED_P0_CR, 272 NIC_PUT(regt, regh, ED_P0_CR,
273 sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STP); 273 sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STP);
274 NIC_BARRIER(regt, regh); 274 NIC_BARRIER(regt, regh);
275 275
276 if (sc->dcr_reg & ED_DCR_LS) { 276 if (sc->dcr_reg & ED_DCR_LS) {
277 NIC_PUT(regt, regh, ED_P0_DCR, sc->dcr_reg); 277 NIC_PUT(regt, regh, ED_P0_DCR, sc->dcr_reg);
278 } else { 278 } else {
279 /* 279 /*
280 * Set FIFO threshold to 8, No auto-init Remote DMA, byte 280 * Set FIFO threshold to 8, No auto-init Remote DMA, byte
281 * order=80x86, byte-wide DMA xfers, 281 * order=80x86, byte-wide DMA xfers,
282 */ 282 */
283 NIC_PUT(regt, regh, ED_P0_DCR, ED_DCR_FT1 | ED_DCR_LS); 283 NIC_PUT(regt, regh, ED_P0_DCR, ED_DCR_FT1 | ED_DCR_LS);
284 } 284 }
285 285
286 /* Clear remote byte count registers. */ 286 /* Clear remote byte count registers. */
287 NIC_PUT(regt, regh, ED_P0_RBCR0, 0); 287 NIC_PUT(regt, regh, ED_P0_RBCR0, 0);
288 NIC_PUT(regt, regh, ED_P0_RBCR1, 0); 288 NIC_PUT(regt, regh, ED_P0_RBCR1, 0);
289 289
290 /* Tell RCR to do nothing for now. */ 290 /* Tell RCR to do nothing for now. */
291 NIC_PUT(regt, regh, ED_P0_RCR, ED_RCR_MON | sc->rcr_proto); 291 NIC_PUT(regt, regh, ED_P0_RCR, ED_RCR_MON | sc->rcr_proto);
292 292
293 /* Place NIC in internal loopback mode. */ 293 /* Place NIC in internal loopback mode. */
294 NIC_PUT(regt, regh, ED_P0_TCR, ED_TCR_LB0); 294 NIC_PUT(regt, regh, ED_P0_TCR, ED_TCR_LB0);
295 295
296 /* Set lower bits of byte addressable framing to 0. */ 296 /* Set lower bits of byte addressable framing to 0. */
297 if (sc->is790) 297 if (sc->is790)
298 NIC_PUT(regt, regh, 0x09, 0); 298 NIC_PUT(regt, regh, 0x09, 0);
299 299
300 /* Initialize receive buffer ring. */ 300 /* Initialize receive buffer ring. */
301 NIC_PUT(regt, regh, ED_P0_BNRY, sc->rec_page_start); 301 NIC_PUT(regt, regh, ED_P0_BNRY, sc->rec_page_start);
302 NIC_PUT(regt, regh, ED_P0_PSTART, sc->rec_page_start); 302 NIC_PUT(regt, regh, ED_P0_PSTART, sc->rec_page_start);
303 NIC_PUT(regt, regh, ED_P0_PSTOP, sc->rec_page_stop); 303 NIC_PUT(regt, regh, ED_P0_PSTOP, sc->rec_page_stop);
304 304
305 /* 305 /*
306 * Enable the following interrupts: receive/transmit complete, 306 * Enable the following interrupts: receive/transmit complete,
307 * receive/transmit error, and Receiver OverWrite. 307 * receive/transmit error, and Receiver OverWrite.
308 * 308 *
309 * Counter overflow and Remote DMA complete are *not* enabled. 309 * Counter overflow and Remote DMA complete are *not* enabled.
310 */ 310 */
311 NIC_PUT(regt, regh, ED_P0_IMR, 311 NIC_PUT(regt, regh, ED_P0_IMR,
312 ED_IMR_PRXE | ED_IMR_PTXE | ED_IMR_RXEE | ED_IMR_TXEE | 312 ED_IMR_PRXE | ED_IMR_PTXE | ED_IMR_RXEE | ED_IMR_TXEE |
313 ED_IMR_OVWE); 313 ED_IMR_OVWE);
314 314
315 /* 315 /*
316 * Clear all interrupts. A '1' in each bit position clears the 316 * Clear all interrupts. A '1' in each bit position clears the
317 * corresponding flag. 317 * corresponding flag.
318 */ 318 */
319 NIC_PUT(regt, regh, ED_P0_ISR, 0xff); 319 NIC_PUT(regt, regh, ED_P0_ISR, 0xff);
320 320
321 /* Program command register for page 1. */ 321 /* Program command register for page 1. */
322 NIC_BARRIER(regt, regh); 322 NIC_BARRIER(regt, regh);
323 NIC_PUT(regt, regh, ED_P0_CR, 323 NIC_PUT(regt, regh, ED_P0_CR,
324 sc->cr_proto | ED_CR_PAGE_1 | ED_CR_STP); 324 sc->cr_proto | ED_CR_PAGE_1 | ED_CR_STP);
325 NIC_BARRIER(regt, regh); 325 NIC_BARRIER(regt, regh);
326 326
327 /* Copy out our station address. */ 327 /* Copy out our station address. */
328 for (i = 0; i < ETHER_ADDR_LEN; i++) 328 for (i = 0; i < ETHER_ADDR_LEN; i++)
329 NIC_PUT(regt, regh, ED_P1_PAR0 + i, CLLADDR(ifp->if_sadl)[i]); 329 NIC_PUT(regt, regh, ED_P1_PAR0 + i, CLLADDR(ifp->if_sadl)[i]);
330 330
331 /* Set multicast filter on chip. */ 331 /* Set multicast filter on chip. */
332 dp8390_getmcaf(&sc->sc_ec, mcaf); 332 dp8390_getmcaf(&sc->sc_ec, mcaf);
333 for (i = 0; i < 8; i++) 333 for (i = 0; i < 8; i++)
334 NIC_PUT(regt, regh, ED_P1_MAR0 + i, mcaf[i]); 334 NIC_PUT(regt, regh, ED_P1_MAR0 + i, mcaf[i]);
335 335
336 /* 336 /*
337 * Set current page pointer to one page after the boundary pointer, as 337 * Set current page pointer to one page after the boundary pointer, as
338 * recommended in the National manual. 338 * recommended in the National manual.
339 */ 339 */
340 sc->next_packet = sc->rec_page_start + 1; 340 sc->next_packet = sc->rec_page_start + 1;
341 NIC_PUT(regt, regh, ED_P1_CURR, sc->next_packet); 341 NIC_PUT(regt, regh, ED_P1_CURR, sc->next_packet);
342 342
343 /* Program command register for page 0. */ 343 /* Program command register for page 0. */
344 NIC_BARRIER(regt, regh); 344 NIC_BARRIER(regt, regh);
345 NIC_PUT(regt, regh, ED_P1_CR, 345 NIC_PUT(regt, regh, ED_P1_CR,
346 sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STP); 346 sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STP);
347 NIC_BARRIER(regt, regh); 347 NIC_BARRIER(regt, regh);
348 348
349 /* Accept broadcast and multicast packets by default. */ 349 /* Accept broadcast and multicast packets by default. */
350 i = ED_RCR_AB | ED_RCR_AM | sc->rcr_proto; 350 i = ED_RCR_AB | ED_RCR_AM | sc->rcr_proto;
351 if (ifp->if_flags & IFF_PROMISC) { 351 if (ifp->if_flags & IFF_PROMISC) {
352 /* 352 /*
353 * Set promiscuous mode. Multicast filter was set earlier so 353 * Set promiscuous mode. Multicast filter was set earlier so
354 * that we should receive all multicast packets. 354 * that we should receive all multicast packets.
355 */ 355 */
356 i |= ED_RCR_PRO | ED_RCR_AR | ED_RCR_SEP; 356 i |= ED_RCR_PRO | ED_RCR_AR | ED_RCR_SEP;
357 } 357 }
358 NIC_PUT(regt, regh, ED_P0_RCR, i); 358 NIC_PUT(regt, regh, ED_P0_RCR, i);
359 359
360 /* Take interface out of loopback. */ 360 /* Take interface out of loopback. */
361 NIC_PUT(regt, regh, ED_P0_TCR, 0); 361 NIC_PUT(regt, regh, ED_P0_TCR, 0);
362 362
363 /* Do any card-specific initialization, if applicable. */ 363 /* Do any card-specific initialization, if applicable. */
364 if (sc->init_card != NULL) 364 if (sc->init_card != NULL)
365 (*sc->init_card)(sc); 365 (*sc->init_card)(sc);
366 366
367 /* Fire up the interface. */ 367 /* Fire up the interface. */
368 NIC_BARRIER(regt, regh); 368 NIC_BARRIER(regt, regh);
369 NIC_PUT(regt, regh, ED_P0_CR, 369 NIC_PUT(regt, regh, ED_P0_CR,
370 sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STA); 370 sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STA);
371 371
372 /* Set 'running' flag, and clear output active flag. */ 372 /* Set 'running' flag, and clear output active flag. */
373 ifp->if_flags |= IFF_RUNNING; 373 ifp->if_flags |= IFF_RUNNING;
374 ifp->if_flags &= ~IFF_OACTIVE; 374 ifp->if_flags &= ~IFF_OACTIVE;
375 375
376 /* ...and attempt to start output. */ 376 /* ...and attempt to start output. */
377 dp8390_start(ifp); 377 dp8390_start(ifp);
378} 378}
379 379
380/* 380/*
381 * This routine actually starts the transmission on the interface. 381 * This routine actually starts the transmission on the interface.
382 */ 382 */
383static void 383static void
384dp8390_xmit(struct dp8390_softc *sc) 384dp8390_xmit(struct dp8390_softc *sc)
385{ 385{
386 bus_space_tag_t regt = sc->sc_regt; 386 bus_space_tag_t regt = sc->sc_regt;
387 bus_space_handle_t regh = sc->sc_regh; 387 bus_space_handle_t regh = sc->sc_regh;
388 struct ifnet *ifp = &sc->sc_ec.ec_if; 388 struct ifnet *ifp = &sc->sc_ec.ec_if;
389 u_short len; 389 u_short len;
390 390
391#ifdef DIAGNOSTIC 391#ifdef DIAGNOSTIC
392 if ((sc->txb_next_tx + sc->txb_inuse) % sc->txb_cnt != sc->txb_new) 392 if ((sc->txb_next_tx + sc->txb_inuse) % sc->txb_cnt != sc->txb_new)
393 panic("dp8390_xmit: desync, next_tx=%d inuse=%d cnt=%d new=%d", 393 panic("dp8390_xmit: desync, next_tx=%d inuse=%d cnt=%d new=%d",
394 sc->txb_next_tx, sc->txb_inuse, sc->txb_cnt, sc->txb_new); 394 sc->txb_next_tx, sc->txb_inuse, sc->txb_cnt, sc->txb_new);
395 395
396 if (sc->txb_inuse == 0) 396 if (sc->txb_inuse == 0)
397 panic("dp8390_xmit: no packets to xmit"); 397 panic("dp8390_xmit: no packets to xmit");
398#endif 398#endif
399 399
400 len = sc->txb_len[sc->txb_next_tx]; 400 len = sc->txb_len[sc->txb_next_tx];
401 401
402 /* Set NIC for page 0 register access. */ 402 /* Set NIC for page 0 register access. */
403 NIC_BARRIER(regt, regh); 403 NIC_BARRIER(regt, regh);
404 NIC_PUT(regt, regh, ED_P0_CR, 404 NIC_PUT(regt, regh, ED_P0_CR,
405 sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STA); 405 sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STA);
406 NIC_BARRIER(regt, regh); 406 NIC_BARRIER(regt, regh);
407 407
408 /* Set TX buffer start page. */ 408 /* Set TX buffer start page. */
409 NIC_PUT(regt, regh, ED_P0_TPSR, 409 NIC_PUT(regt, regh, ED_P0_TPSR,
410 sc->tx_page_start + sc->txb_next_tx * ED_TXBUF_SIZE); 410 sc->tx_page_start + sc->txb_next_tx * ED_TXBUF_SIZE);
411 411
412 /* Set TX length. */ 412 /* Set TX length. */
413 NIC_PUT(regt, regh, ED_P0_TBCR0, len); 413 NIC_PUT(regt, regh, ED_P0_TBCR0, len);
414 NIC_PUT(regt, regh, ED_P0_TBCR1, len >> 8); 414 NIC_PUT(regt, regh, ED_P0_TBCR1, len >> 8);
415 415
416 /* Set page 0, remote DMA complete, transmit packet, and *start*. */ 416 /* Set page 0, remote DMA complete, transmit packet, and *start*. */
417 NIC_BARRIER(regt, regh); 417 NIC_BARRIER(regt, regh);
418 NIC_PUT(regt, regh, ED_P0_CR, 418 NIC_PUT(regt, regh, ED_P0_CR,
419 sc->cr_proto | ED_CR_PAGE_0 | ED_CR_TXP | ED_CR_STA); 419 sc->cr_proto | ED_CR_PAGE_0 | ED_CR_TXP | ED_CR_STA);
420 420
421 /* Point to next transmit buffer slot and wrap if necessary. */ 421 /* Point to next transmit buffer slot and wrap if necessary. */
422 if (++sc->txb_next_tx == sc->txb_cnt) 422 if (++sc->txb_next_tx == sc->txb_cnt)
423 sc->txb_next_tx = 0; 423 sc->txb_next_tx = 0;
424 424
425 /* Set a timer just in case we never hear from the board again. */ 425 /* Set a timer just in case we never hear from the board again. */
426 ifp->if_timer = 2; 426 ifp->if_timer = 2;
427} 427}
428 428
429/* 429/*
430 * Start output on interface. 430 * Start output on interface.
431 * We make two assumptions here: 431 * We make two assumptions here:
432 * 1) that the current priority is set to splnet _before_ this code 432 * 1) that the current priority is set to splnet _before_ this code
433 * is called *and* is returned to the appropriate priority after 433 * is called *and* is returned to the appropriate priority after
434 * return 434 * return
435 * 2) that the IFF_OACTIVE flag is checked before this code is called 435 * 2) that the IFF_OACTIVE flag is checked before this code is called
436 * (i.e. that the output part of the interface is idle) 436 * (i.e. that the output part of the interface is idle)
437 */ 437 */
438void 438void
439dp8390_start(struct ifnet *ifp) 439dp8390_start(struct ifnet *ifp)
440{ 440{
441 struct dp8390_softc *sc = ifp->if_softc; 441 struct dp8390_softc *sc = ifp->if_softc;
442 struct mbuf *m0; 442 struct mbuf *m0;
443 int buffer; 443 int buffer;
444 int len; 444 int len;
445 445
446 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING) 446 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
447 return; 447 return;
448 448
449 outloop: 449 outloop:
450 /* See if there is room to put another packet in the buffer. */ 450 /* See if there is room to put another packet in the buffer. */
451 if (sc->txb_inuse == sc->txb_cnt) { 451 if (sc->txb_inuse == sc->txb_cnt) {
452 /* No room. Indicate this to the outside world and exit. */ 452 /* No room. Indicate this to the outside world and exit. */
453 ifp->if_flags |= IFF_OACTIVE; 453 ifp->if_flags |= IFF_OACTIVE;
454 return; 454 return;
455 } 455 }
456 IFQ_DEQUEUE(&ifp->if_snd, m0); 456 IFQ_DEQUEUE(&ifp->if_snd, m0);
457 if (m0 == NULL) 457 if (m0 == NULL)
458 return; 458 return;
459 459
460 /* We need to use m->m_pkthdr.len, so require the header */ 460 /* We need to use m->m_pkthdr.len, so require the header */
461 if ((m0->m_flags & M_PKTHDR) == 0) 461 if ((m0->m_flags & M_PKTHDR) == 0)
462 panic("dp8390_start: no header mbuf"); 462 panic("dp8390_start: no header mbuf");
463 463
464 /* Tap off here if there is a BPF listener. */ 464 /* Tap off here if there is a BPF listener. */
465 bpf_mtap(ifp, m0, BPF_D_OUT); 465 bpf_mtap(ifp, m0, BPF_D_OUT);
466 466
467 /* txb_new points to next open buffer slot. */ 467 /* txb_new points to next open buffer slot. */
468 buffer = sc->mem_start + 468 buffer = sc->mem_start +
469 ((sc->txb_new * ED_TXBUF_SIZE) << ED_PAGE_SHIFT); 469 ((sc->txb_new * ED_TXBUF_SIZE) << ED_PAGE_SHIFT);
470 470
471 len = (*sc->write_mbuf)(sc, m0, buffer); 471 len = (*sc->write_mbuf)(sc, m0, buffer);
472 472
473 m_freem(m0); 473 m_freem(m0);
474 sc->txb_len[sc->txb_new] = len; 474 sc->txb_len[sc->txb_new] = len;
475 475
476 /* Point to next buffer slot and wrap if necessary. */ 476 /* Point to next buffer slot and wrap if necessary. */
477 if (++sc->txb_new == sc->txb_cnt) 477 if (++sc->txb_new == sc->txb_cnt)
478 sc->txb_new = 0; 478 sc->txb_new = 0;
479 479
480 /* Start the first packet transmitting. */ 480 /* Start the first packet transmitting. */
481 if (sc->txb_inuse++ == 0) 481 if (sc->txb_inuse++ == 0)
482 dp8390_xmit(sc); 482 dp8390_xmit(sc);
483 483
484 /* Loop back to the top to possibly buffer more packets. */ 484 /* Loop back to the top to possibly buffer more packets. */
485 goto outloop; 485 goto outloop;
486} 486}
487 487
488/* 488/*
489 * Ethernet interface receiver interrupt. 489 * Ethernet interface receiver interrupt.
490 */ 490 */
491void 491void
492dp8390_rint(struct dp8390_softc *sc) 492dp8390_rint(struct dp8390_softc *sc)
493{ 493{
494 bus_space_tag_t regt = sc->sc_regt; 494 bus_space_tag_t regt = sc->sc_regt;
495 bus_space_handle_t regh = sc->sc_regh; 495 bus_space_handle_t regh = sc->sc_regh;
496 struct dp8390_ring packet_hdr; 496 struct dp8390_ring packet_hdr;
497 int packet_ptr; 497 int packet_ptr;
498 uint16_t len; 498 uint16_t len;
499 uint8_t boundary, current; 499 uint8_t boundary, current;
500 uint8_t nlen; 500 uint8_t nlen;
501 501
502 loop: 502 loop:
503 /* Set NIC to page 1 registers to get 'current' pointer. */ 503 /* Set NIC to page 1 registers to get 'current' pointer. */
504 NIC_BARRIER(regt, regh); 504 NIC_BARRIER(regt, regh);
505 NIC_PUT(regt, regh, ED_P0_CR, 505 NIC_PUT(regt, regh, ED_P0_CR,
506 sc->cr_proto | ED_CR_PAGE_1 | ED_CR_STA); 506 sc->cr_proto | ED_CR_PAGE_1 | ED_CR_STA);
507 NIC_BARRIER(regt, regh); 507 NIC_BARRIER(regt, regh);
508 508
509 /* 509 /*
510 * 'sc->next_packet' is the logical beginning of the ring-buffer - i.e. 510 * 'sc->next_packet' is the logical beginning of the ring-buffer - i.e.
511 * it points to where new data has been buffered. The 'CURR' (current) 511 * it points to where new data has been buffered. The 'CURR' (current)
512 * register points to the logical end of the ring-buffer - i.e. it 512 * register points to the logical end of the ring-buffer - i.e. it
513 * points to where additional new data will be added. We loop here 513 * points to where additional new data will be added. We loop here
514 * until the logical beginning equals the logical end (or in other 514 * until the logical beginning equals the logical end (or in other
515 * words, until the ring-buffer is empty). 515 * words, until the ring-buffer is empty).
516 */ 516 */
517 current = NIC_GET(regt, regh, ED_P1_CURR); 517 current = NIC_GET(regt, regh, ED_P1_CURR);
518 if (sc->next_packet == current) 518 if (sc->next_packet == current)
519 return; 519 return;
520 520
521 /* Set NIC to page 0 registers to update boundary register. */ 521 /* Set NIC to page 0 registers to update boundary register. */
522 NIC_BARRIER(regt, regh); 522 NIC_BARRIER(regt, regh);
523 NIC_PUT(regt, regh, ED_P1_CR, 523 NIC_PUT(regt, regh, ED_P1_CR,
524 sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STA); 524 sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STA);
525 NIC_BARRIER(regt, regh); 525 NIC_BARRIER(regt, regh);
526 526
527 do { 527 do {
528 /* Get pointer to this buffer's header structure. */ 528 /* Get pointer to this buffer's header structure. */
529 packet_ptr = sc->mem_ring + 529 packet_ptr = sc->mem_ring +
530 ((sc->next_packet - sc->rec_page_start) << ED_PAGE_SHIFT); 530 ((sc->next_packet - sc->rec_page_start) << ED_PAGE_SHIFT);
531 531
532 (*sc->read_hdr)(sc, packet_ptr, &packet_hdr); 532 (*sc->read_hdr)(sc, packet_ptr, &packet_hdr);
533 len = packet_hdr.count; 533 len = packet_hdr.count;
534 534
535 /* 535 /*
536 * Try do deal with old, buggy chips that sometimes duplicate 536 * Try do deal with old, buggy chips that sometimes duplicate
537 * the low byte of the length into the high byte. We do this 537 * the low byte of the length into the high byte. We do this
538 * by simply ignoring the high byte of the length and always 538 * by simply ignoring the high byte of the length and always
539 * recalculating it. 539 * recalculating it.
540 * 540 *
541 * NOTE: sc->next_packet is pointing at the current packet. 541 * NOTE: sc->next_packet is pointing at the current packet.
542 */ 542 */
543 if (packet_hdr.next_packet >= sc->next_packet) 543 if (packet_hdr.next_packet >= sc->next_packet)
544 nlen = (packet_hdr.next_packet - sc->next_packet); 544 nlen = (packet_hdr.next_packet - sc->next_packet);
545 else 545 else
546 nlen = ((packet_hdr.next_packet - sc->rec_page_start) + 546 nlen = ((packet_hdr.next_packet - sc->rec_page_start) +
547 (sc->rec_page_stop - sc->next_packet)); 547 (sc->rec_page_stop - sc->next_packet));
548 --nlen; 548 --nlen;
549 if ((len & ED_PAGE_MASK) + sizeof(packet_hdr) > ED_PAGE_SIZE) 549 if ((len & ED_PAGE_MASK) + sizeof(packet_hdr) > ED_PAGE_SIZE)
550 --nlen; 550 --nlen;
551 len = (len & ED_PAGE_MASK) | (nlen << ED_PAGE_SHIFT); 551 len = (len & ED_PAGE_MASK) | (nlen << ED_PAGE_SHIFT);
552#ifdef DIAGNOSTIC 552#ifdef DIAGNOSTIC
553 if (len != packet_hdr.count) { 553 if (len != packet_hdr.count) {
554 aprint_verbose_dev(sc->sc_dev, "length does not match " 554 aprint_verbose_dev(sc->sc_dev, "length does not match "
555 "next packet pointer\n"); 555 "next packet pointer\n");
556 aprint_verbose_dev(sc->sc_dev, "len %04x nlen %04x " 556 aprint_verbose_dev(sc->sc_dev, "len %04x nlen %04x "
557 "start %02x first %02x curr %02x next %02x " 557 "start %02x first %02x curr %02x next %02x "
558 "stop %02x\n", packet_hdr.count, len, 558 "stop %02x\n", packet_hdr.count, len,
559 sc->rec_page_start, sc->next_packet, current, 559 sc->rec_page_start, sc->next_packet, current,
560 packet_hdr.next_packet, sc->rec_page_stop); 560 packet_hdr.next_packet, sc->rec_page_stop);
561 } 561 }
562#endif 562#endif
563 563
564 /* 564 /*
565 * Be fairly liberal about what we allow as a "reasonable" 565 * Be fairly liberal about what we allow as a "reasonable"
566 * length so that a [crufty] packet will make it to BPF (and 566 * length so that a [crufty] packet will make it to BPF (and
567 * can thus be analyzed). Note that all that is really 567 * can thus be analyzed). Note that all that is really
568 * important is that we have a length that will fit into one 568 * important is that we have a length that will fit into one
569 * mbuf cluster or less; the upper layer protocols can then 569 * mbuf cluster or less; the upper layer protocols can then
570 * figure out the length from their own length field(s). 570 * figure out the length from their own length field(s).
571 */ 571 */
572 if (len <= MCLBYTES && 572 if (len <= MCLBYTES &&
573 packet_hdr.next_packet >= sc->rec_page_start && 573 packet_hdr.next_packet >= sc->rec_page_start &&
574 packet_hdr.next_packet < sc->rec_page_stop) { 574 packet_hdr.next_packet < sc->rec_page_stop) {
575 /* Go get packet. */ 575 /* Go get packet. */
576 dp8390_read(sc, 576 dp8390_read(sc,
577 packet_ptr + sizeof(struct dp8390_ring), 577 packet_ptr + sizeof(struct dp8390_ring),
578 len - sizeof(struct dp8390_ring)); 578 len - sizeof(struct dp8390_ring));
579 } else { 579 } else {
580 /* Really BAD. The ring pointers are corrupted. */ 580 /* Really BAD. The ring pointers are corrupted. */
581 log(LOG_ERR, "%s: NIC memory corrupt - " 581 log(LOG_ERR, "%s: NIC memory corrupt - "
582 "invalid packet length %d\n", 582 "invalid packet length %d\n",
583 device_xname(sc->sc_dev), len); 583 device_xname(sc->sc_dev), len);
584 ++sc->sc_ec.ec_if.if_ierrors; 584 if_statinc(&sc->sc_ec.ec_if, if_ierrors);
585 dp8390_reset(sc); 585 dp8390_reset(sc);
586 return; 586 return;
587 } 587 }
588 588
589 /* Update next packet pointer. */ 589 /* Update next packet pointer. */
590 sc->next_packet = packet_hdr.next_packet; 590 sc->next_packet = packet_hdr.next_packet;
591 591
592 /* 592 /*
593 * Update NIC boundary pointer - being careful to keep it one 593 * Update NIC boundary pointer - being careful to keep it one
594 * buffer behind (as recommended by NS databook). 594 * buffer behind (as recommended by NS databook).
595 */ 595 */
596 boundary = sc->next_packet - 1; 596 boundary = sc->next_packet - 1;
597 if (boundary < sc->rec_page_start) 597 if (boundary < sc->rec_page_start)
598 boundary = sc->rec_page_stop - 1; 598 boundary = sc->rec_page_stop - 1;
599 NIC_PUT(regt, regh, ED_P0_BNRY, boundary); 599 NIC_PUT(regt, regh, ED_P0_BNRY, boundary);
600 } while (sc->next_packet != current); 600 } while (sc->next_packet != current);
601 601
602 goto loop; 602 goto loop;
603} 603}
604 604
605/* Ethernet interface interrupt processor. */ 605/* Ethernet interface interrupt processor. */
606int 606int
607dp8390_intr(void *arg) 607dp8390_intr(void *arg)
608{ 608{
609 struct dp8390_softc *sc = arg; 609 struct dp8390_softc *sc = arg;
610 bus_space_tag_t regt = sc->sc_regt; 610 bus_space_tag_t regt = sc->sc_regt;
611 bus_space_handle_t regh = sc->sc_regh; 611 bus_space_handle_t regh = sc->sc_regh;
612 struct ifnet *ifp = &sc->sc_ec.ec_if; 612 struct ifnet *ifp = &sc->sc_ec.ec_if;
613 uint8_t isr; 613 uint8_t isr;
614 uint8_t rndisr; 614 uint8_t rndisr;
615 615
616 if (sc->sc_enabled == 0 || !device_is_active(sc->sc_dev)) 616 if (sc->sc_enabled == 0 || !device_is_active(sc->sc_dev))
617 return 0; 617 return 0;
618 618
619 /* Set NIC to page 0 registers. */ 619 /* Set NIC to page 0 registers. */
620 NIC_BARRIER(regt, regh); 620 NIC_BARRIER(regt, regh);
621 NIC_PUT(regt, regh, ED_P0_CR, sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STA); 621 NIC_PUT(regt, regh, ED_P0_CR, sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STA);
622 NIC_BARRIER(regt, regh); 622 NIC_BARRIER(regt, regh);
623 623
624 isr = NIC_GET(regt, regh, ED_P0_ISR); 624 isr = NIC_GET(regt, regh, ED_P0_ISR);
625 if (isr == 0) 625 if (isr == 0)
626 return 0; 626 return 0;
627 627
628 rndisr = isr; 628 rndisr = isr;
629 629
630 /* Loop until there are no more new interrupts. */ 630 /* Loop until there are no more new interrupts. */
631 for (;;) { 631 for (;;) {
632 /* 632 /*
633 * Reset all the bits that we are 'acknowledging' by writing a 633 * Reset all the bits that we are 'acknowledging' by writing a
634 * '1' to each bit position that was set. 634 * '1' to each bit position that was set.
635 * (Writing a '1' *clears* the bit.) 635 * (Writing a '1' *clears* the bit.)
636 */ 636 */
637 NIC_PUT(regt, regh, ED_P0_ISR, isr); 637 NIC_PUT(regt, regh, ED_P0_ISR, isr);
638 638
639 /* Work around for AX88190 bug */ 639 /* Work around for AX88190 bug */
640 if ((sc->sc_flags & DP8390_DO_AX88190_WORKAROUND) != 0) 640 if ((sc->sc_flags & DP8390_DO_AX88190_WORKAROUND) != 0)
641 while ((NIC_GET(regt, regh, ED_P0_ISR) & isr) != 0) { 641 while ((NIC_GET(regt, regh, ED_P0_ISR) & isr) != 0) {
642 NIC_PUT(regt, regh, ED_P0_ISR, 0); 642 NIC_PUT(regt, regh, ED_P0_ISR, 0);
643 NIC_PUT(regt, regh, ED_P0_ISR, isr); 643 NIC_PUT(regt, regh, ED_P0_ISR, isr);
644 } 644 }
645 645
646 /* 646 /*
647 * Handle transmitter interrupts. Handle these first because 647 * Handle transmitter interrupts. Handle these first because
648 * the receiver will reset the board under some conditions. 648 * the receiver will reset the board under some conditions.
649 * 649 *
650 * If the chip was reset while a packet was transmitting, it 650 * If the chip was reset while a packet was transmitting, it
651 * may still deliver a TX interrupt. In this case, just ignore 651 * may still deliver a TX interrupt. In this case, just ignore
652 * the interrupt. 652 * the interrupt.
653 */ 653 */
654 if ((isr & (ED_ISR_PTX | ED_ISR_TXE)) != 0 && 654 if ((isr & (ED_ISR_PTX | ED_ISR_TXE)) != 0 &&
655 sc->txb_inuse != 0) { 655 sc->txb_inuse != 0) {
 656 net_stat_ref_t nsr = IF_STAT_GETREF(ifp);
656 uint8_t collisions = 657 uint8_t collisions =
657 NIC_GET(regt, regh, ED_P0_NCR) & 0x0f; 658 NIC_GET(regt, regh, ED_P0_NCR) & 0x0f;
658 659
659 /* 660 /*
660 * Check for transmit error. If a TX completed with an 661 * Check for transmit error. If a TX completed with an
661 * error, we end up throwing the packet away. Really 662 * error, we end up throwing the packet away. Really
662 * the only error that is possible is excessive 663 * the only error that is possible is excessive
663 * collisions, and in this case it is best to allow the 664 * collisions, and in this case it is best to allow the
664 * automatic mechanisms of TCP to backoff the flow. Of 665 * automatic mechanisms of TCP to backoff the flow. Of
665 * course, with UDP we're screwed, but this is expected 666 * course, with UDP we're screwed, but this is expected
666 * when a network is heavily loaded. 667 * when a network is heavily loaded.
667 */ 668 */
668 if ((isr & ED_ISR_TXE) != 0) { 669 if ((isr & ED_ISR_TXE) != 0) {
669 /* Excessive collisions (16). */ 670 /* Excessive collisions (16). */
670 if ((NIC_GET(regt, regh, ED_P0_TSR) 671 if ((NIC_GET(regt, regh, ED_P0_TSR)
671 & ED_TSR_ABT) && (collisions == 0)) { 672 & ED_TSR_ABT) && (collisions == 0)) {
672 /* 673 /*
673 * When collisions total 16, the P0_NCR 674 * When collisions total 16, the P0_NCR
674 * will indicate 0, and the TSR_ABT is 675 * will indicate 0, and the TSR_ABT is
675 * set. 676 * set.
676 */ 677 */
677 collisions = 16; 678 collisions = 16;
678 } 679 }
679 680
680 /* Update output errors counter. */ 681 /* Update output errors counter. */
681 ++ifp->if_oerrors; 682 if_statinc_ref(nsr, if_oerrors);
682 } else { 683 } else {
683 /* 684 /*
684 * Throw away the non-error status bits. 685 * Throw away the non-error status bits.
685 * 686 *
686 * XXX 687 * XXX
687 * It may be useful to detect loss of carrier 688 * It may be useful to detect loss of carrier
688 * and late collisions here. 689 * and late collisions here.
689 */ 690 */
690 (void)NIC_GET(regt, regh, ED_P0_TSR); 691 (void)NIC_GET(regt, regh, ED_P0_TSR);
691 692
692 /* 693 /*
693 * Update total number of successfully 694 * Update total number of successfully
694 * transmitted packets. 695 * transmitted packets.
695 */ 696 */
696 ++ifp->if_opackets; 697 if_statinc_ref(nsr, if_opackets);
697 } 698 }
698 699
699 /* Clear watchdog timer. */ 700 /* Clear watchdog timer. */
700 ifp->if_timer = 0; 701 ifp->if_timer = 0;
701 ifp->if_flags &= ~IFF_OACTIVE; 702 ifp->if_flags &= ~IFF_OACTIVE;
702 703
703 /* 704 /*
704 * Add in total number of collisions on last 705 * Add in total number of collisions on last
705 * transmission. 706 * transmission.
706 */ 707 */
707 ifp->if_collisions += collisions; 708 if (collisions)
 709 if_statadd_ref(nsr, if_collisions, collisions);
 710
 711 IF_STAT_PUTREF(ifp);
708 712
709 /* 713 /*
710 * Decrement buffer in-use count if not zero (can only 714 * Decrement buffer in-use count if not zero (can only
711 * be zero if a transmitter interrupt occurred while 715 * be zero if a transmitter interrupt occurred while
712 * not actually transmitting). 716 * not actually transmitting).
713 * If data is ready to transmit, start it transmitting, 717 * If data is ready to transmit, start it transmitting,
714 * otherwise defer until after handling receiver. 718 * otherwise defer until after handling receiver.
715 */ 719 */
716 if (--sc->txb_inuse != 0) 720 if (--sc->txb_inuse != 0)
717 dp8390_xmit(sc); 721 dp8390_xmit(sc);
718 } 722 }
719 723
720 /* Handle receiver interrupts. */ 724 /* Handle receiver interrupts. */
721 if ((isr & (ED_ISR_PRX | ED_ISR_RXE | ED_ISR_OVW)) != 0) { 725 if ((isr & (ED_ISR_PRX | ED_ISR_RXE | ED_ISR_OVW)) != 0) {
722 /* 726 /*
723 * Overwrite warning. In order to make sure that a 727 * Overwrite warning. In order to make sure that a
724 * lockup of the local DMA hasn't occurred, we reset 728 * lockup of the local DMA hasn't occurred, we reset
725 * and re-init the NIC. The NSC manual suggests only a 729 * and re-init the NIC. The NSC manual suggests only a
726 * partial reset/re-init is necessary - but some chips 730 * partial reset/re-init is necessary - but some chips
727 * seem to want more. The DMA lockup has been seen 731 * seem to want more. The DMA lockup has been seen
728 * only with early rev chips - Methinks this bug was 732 * only with early rev chips - Methinks this bug was
729 * fixed in later revs. -DG 733 * fixed in later revs. -DG
730 */ 734 */
731 if ((isr & ED_ISR_OVW) != 0) { 735 if ((isr & ED_ISR_OVW) != 0) {
732 ++ifp->if_ierrors; 736 if_statinc(ifp, if_ierrors);
733#ifdef DIAGNOSTIC 737#ifdef DIAGNOSTIC
734 log(LOG_WARNING, "%s: warning - receiver " 738 log(LOG_WARNING, "%s: warning - receiver "
735 "ring buffer overrun\n", 739 "ring buffer overrun\n",
736 device_xname(sc->sc_dev)); 740 device_xname(sc->sc_dev));
737#endif 741#endif
738 /* Stop/reset/re-init NIC. */ 742 /* Stop/reset/re-init NIC. */
739 dp8390_reset(sc); 743 dp8390_reset(sc);
740 } else { 744 } else {
741 /* 745 /*
742 * Receiver Error. One or more of: CRC error, 746 * Receiver Error. One or more of: CRC error,
743 * frame alignment error FIFO overrun, or 747 * frame alignment error FIFO overrun, or
744 * missed packet. 748 * missed packet.
745 */ 749 */
746 if ((isr & ED_ISR_RXE) != 0) { 750 if ((isr & ED_ISR_RXE) != 0) {
747 ++ifp->if_ierrors; 751 if_statinc(ifp, if_ierrors);
748#ifdef DEBUG 752#ifdef DEBUG
749 if (dp8390_debug) { 753 if (dp8390_debug) {
750 printf("%s: receive error %x\n", 754 printf("%s: receive error %x\n",
751 device_xname(sc->sc_dev), 755 device_xname(sc->sc_dev),
752 NIC_GET(regt, regh, 756 NIC_GET(regt, regh,
753 ED_P0_RSR)); 757 ED_P0_RSR));
754 } 758 }
755#endif 759#endif
756 } 760 }
757 761
758 /* 762 /*
759 * Go get the packet(s) 763 * Go get the packet(s)
760 * XXX - Doing this on an error is dubious 764 * XXX - Doing this on an error is dubious
761 * because there shouldn't be any data to get 765 * because there shouldn't be any data to get
762 * (we've configured the interface to not 766 * (we've configured the interface to not
763 * accept packets with errors). 767 * accept packets with errors).
764 */ 768 */
765 (*sc->recv_int)(sc); 769 (*sc->recv_int)(sc);
766 } 770 }
767 } 771 }
768 772
769 /* 773 /*
770 * If it looks like the transmitter can take more data, attempt 774 * If it looks like the transmitter can take more data, attempt
771 * to start output on the interface. This is done after 775 * to start output on the interface. This is done after
772 * handling the receiver to give the receiver priority. 776 * handling the receiver to give the receiver priority.
773 */ 777 */
774 if_schedule_deferred_start(ifp); 778 if_schedule_deferred_start(ifp);
775 779
776 /* 780 /*
777 * Return NIC CR to standard state: page 0, remote DMA 781 * Return NIC CR to standard state: page 0, remote DMA
778 * complete, start (toggling the TXP bit off, even if was just 782 * complete, start (toggling the TXP bit off, even if was just
779 * set in the transmit routine, is *okay* - it is 'edge' 783 * set in the transmit routine, is *okay* - it is 'edge'
780 * triggered from low to high). 784 * triggered from low to high).
781 */ 785 */
782 NIC_BARRIER(regt, regh); 786 NIC_BARRIER(regt, regh);
783 NIC_PUT(regt, regh, ED_P0_CR, 787 NIC_PUT(regt, regh, ED_P0_CR,
784 sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STA); 788 sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STA);
785 NIC_BARRIER(regt, regh); 789 NIC_BARRIER(regt, regh);
786 790
787 /* 791 /*
788 * If the Network Talley Counters overflow, read them to reset 792 * If the Network Talley Counters overflow, read them to reset
789 * them. It appears that old 8390's won't clear the ISR flag 793 * them. It appears that old 8390's won't clear the ISR flag
790 * otherwise - resulting in an infinite loop. 794 * otherwise - resulting in an infinite loop.
791 */ 795 */
792 if ((isr & ED_ISR_CNT) != 0) { 796 if ((isr & ED_ISR_CNT) != 0) {
793 (void)NIC_GET(regt, regh, ED_P0_CNTR0); 797 (void)NIC_GET(regt, regh, ED_P0_CNTR0);
794 (void)NIC_GET(regt, regh, ED_P0_CNTR1); 798 (void)NIC_GET(regt, regh, ED_P0_CNTR1);
795 (void)NIC_GET(regt, regh, ED_P0_CNTR2); 799 (void)NIC_GET(regt, regh, ED_P0_CNTR2);
796 } 800 }
797 801
798 isr = NIC_GET(regt, regh, ED_P0_ISR); 802 isr = NIC_GET(regt, regh, ED_P0_ISR);
799 if (isr == 0) 803 if (isr == 0)
800 goto out; 804 goto out;
801 } 805 }
802 806
803 out: 807 out:
804 rnd_add_uint32(&sc->rnd_source, rndisr); 808 rnd_add_uint32(&sc->rnd_source, rndisr);
805 return 1; 809 return 1;
806} 810}
807 811
808/* 812/*
809 * Process an ioctl request. This code needs some work - it looks pretty ugly. 813 * Process an ioctl request. This code needs some work - it looks pretty ugly.
810 */ 814 */
811int 815int
812dp8390_ioctl(struct ifnet *ifp, u_long cmd, void *data) 816dp8390_ioctl(struct ifnet *ifp, u_long cmd, void *data)
813{ 817{
814 struct dp8390_softc *sc = ifp->if_softc; 818 struct dp8390_softc *sc = ifp->if_softc;
815 struct ifaddr *ifa = data; 819 struct ifaddr *ifa = data;
816 int s, error = 0; 820 int s, error = 0;
817 821
818 s = splnet(); 822 s = splnet();
819 823
820 switch (cmd) { 824 switch (cmd) {
821 825
822 case SIOCINITIFADDR: 826 case SIOCINITIFADDR:
823 if ((error = dp8390_enable(sc)) != 0) 827 if ((error = dp8390_enable(sc)) != 0)
824 break; 828 break;
825 ifp->if_flags |= IFF_UP; 829 ifp->if_flags |= IFF_UP;
826 830
827 dp8390_init(sc); 831 dp8390_init(sc);
828 switch (ifa->ifa_addr->sa_family) { 832 switch (ifa->ifa_addr->sa_family) {
829#ifdef INET 833#ifdef INET
830 case AF_INET: 834 case AF_INET:
831 arp_ifinit(ifp, ifa); 835 arp_ifinit(ifp, ifa);
832 break; 836 break;
833#endif 837#endif
834 default: 838 default:
835 break; 839 break;
836 } 840 }
837 break; 841 break;
838 842
839 case SIOCSIFFLAGS: 843 case SIOCSIFFLAGS:
840 if ((error = ifioctl_common(ifp, cmd, data)) != 0) 844 if ((error = ifioctl_common(ifp, cmd, data)) != 0)
841 break; 845 break;
842 switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) { 846 switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) {
843 case IFF_RUNNING: 847 case IFF_RUNNING:
844 /* 848 /*
845 * If interface is marked down and it is running, then 849 * If interface is marked down and it is running, then
846 * stop it. 850 * stop it.
847 */ 851 */
848 dp8390_stop(sc); 852 dp8390_stop(sc);
849 ifp->if_flags &= ~IFF_RUNNING; 853 ifp->if_flags &= ~IFF_RUNNING;
850 dp8390_disable(sc); 854 dp8390_disable(sc);
851 break; 855 break;
852 case IFF_UP: 856 case IFF_UP:
853 /* 857 /*
854 * If interface is marked up and it is stopped, then 858 * If interface is marked up and it is stopped, then
855 * start it. 859 * start it.
856 */ 860 */
857 if ((error = dp8390_enable(sc)) != 0) 861 if ((error = dp8390_enable(sc)) != 0)
858 break; 862 break;
859 dp8390_init(sc); 863 dp8390_init(sc);
860 break; 864 break;
861 case IFF_UP | IFF_RUNNING: 865 case IFF_UP | IFF_RUNNING:
862 /* 866 /*
863 * Reset the interface to pick up changes in any other 867 * Reset the interface to pick up changes in any other
864 * flags that affect hardware registers. 868 * flags that affect hardware registers.
865 */ 869 */
866 dp8390_stop(sc); 870 dp8390_stop(sc);
867 dp8390_init(sc); 871 dp8390_init(sc);
868 break; 872 break;
869 default: 873 default:
870 break; 874 break;
871 } 875 }
872 break; 876 break;
873 877
874 case SIOCADDMULTI: 878 case SIOCADDMULTI:
875 case SIOCDELMULTI: 879 case SIOCDELMULTI:
876 if (sc->sc_enabled == 0) { 880 if (sc->sc_enabled == 0) {
877 error = EIO; 881 error = EIO;
878 break; 882 break;
879 } 883 }
880 884
881 /* Update our multicast list. */ 885 /* Update our multicast list. */
882 if ((error = ether_ioctl(ifp, cmd, data)) == ENETRESET) { 886 if ((error = ether_ioctl(ifp, cmd, data)) == ENETRESET) {
883 /* 887 /*
884 * Multicast list has changed; set the hardware filter 888 * Multicast list has changed; set the hardware filter
885 * accordingly. 889 * accordingly.
886 */ 890 */
887 if (ifp->if_flags & IFF_RUNNING) { 891 if (ifp->if_flags & IFF_RUNNING) {
888 dp8390_stop(sc); /* XXX for ds_setmcaf? */ 892 dp8390_stop(sc); /* XXX for ds_setmcaf? */
889 dp8390_init(sc); 893 dp8390_init(sc);
890 } 894 }
891 error = 0; 895 error = 0;
892 } 896 }
893 break; 897 break;
894 898
895 default: 899 default:
896 error = ether_ioctl(ifp, cmd, data); 900 error = ether_ioctl(ifp, cmd, data);
897 break; 901 break;
898 } 902 }
899 903
900 splx(s); 904 splx(s);
901 return error; 905 return error;
902} 906}
903 907
904/* 908/*
905 * Retrieve packet from buffer memory and send to the next level up via 909 * Retrieve packet from buffer memory and send to the next level up via
906 * ether_input(). If there is a BPF listener, give a copy to BPF, too. 910 * ether_input(). If there is a BPF listener, give a copy to BPF, too.
907 */ 911 */
908void 912void
909dp8390_read(struct dp8390_softc *sc, int buf, u_short len) 913dp8390_read(struct dp8390_softc *sc, int buf, u_short len)
910{ 914{
911 struct ifnet *ifp = &sc->sc_ec.ec_if; 915 struct ifnet *ifp = &sc->sc_ec.ec_if;
912 struct mbuf *m; 916 struct mbuf *m;
913 917
914 /* Pull packet off interface. */ 918 /* Pull packet off interface. */
915 m = dp8390_get(sc, buf, len); 919 m = dp8390_get(sc, buf, len);
916 if (m == NULL) { 920 if (m == NULL) {
917 ifp->if_ierrors++; 921 if_statinc(ifp, if_ierrors);
918 return; 922 return;
919 } 923 }
920 924
921 if_percpuq_enqueue(ifp->if_percpuq, m); 925 if_percpuq_enqueue(ifp->if_percpuq, m);
922} 926}
923 927
924 928
925/* 929/*
926 * Supporting routines. 930 * Supporting routines.
927 */ 931 */
928 932
929/* 933/*
930 * Compute the multicast address filter from the list of multicast addresses we 934 * Compute the multicast address filter from the list of multicast addresses we
931 * need to listen to. 935 * need to listen to.
932 */ 936 */
933void 937void
934dp8390_getmcaf(struct ethercom *ec, uint8_t *af) 938dp8390_getmcaf(struct ethercom *ec, uint8_t *af)
935{ 939{
936 struct ifnet *ifp = &ec->ec_if; 940 struct ifnet *ifp = &ec->ec_if;
937 struct ether_multi *enm; 941 struct ether_multi *enm;
938 uint32_t crc; 942 uint32_t crc;
939 int i; 943 int i;
940 struct ether_multistep step; 944 struct ether_multistep step;
941 945
942 /* 946 /*
943 * Set up multicast address filter by passing all multicast addresses 947 * Set up multicast address filter by passing all multicast addresses
944 * through a crc generator, and then using the high order 6 bits as an 948 * through a crc generator, and then using the high order 6 bits as an
945 * index into the 64 bit logical address filter. The high order bit 949 * index into the 64 bit logical address filter. The high order bit
946 * selects the word, while the rest of the bits select the bit within 950 * selects the word, while the rest of the bits select the bit within
947 * the word. 951 * the word.
948 */ 952 */
949 953
950 if (ifp->if_flags & IFF_PROMISC) { 954 if (ifp->if_flags & IFF_PROMISC) {
951 ifp->if_flags |= IFF_ALLMULTI; 955 ifp->if_flags |= IFF_ALLMULTI;
952 for (i = 0; i < 8; i++) 956 for (i = 0; i < 8; i++)
953 af[i] = 0xff; 957 af[i] = 0xff;
954 return; 958 return;
955 } 959 }
956 for (i = 0; i < 8; i++) 960 for (i = 0; i < 8; i++)
957 af[i] = 0; 961 af[i] = 0;
958 ETHER_LOCK(ec); 962 ETHER_LOCK(ec);
959 ETHER_FIRST_MULTI(step, ec, enm); 963 ETHER_FIRST_MULTI(step, ec, enm);
960 while (enm != NULL) { 964 while (enm != NULL) {
961 if (memcmp(enm->enm_addrlo, enm->enm_addrhi, 965 if (memcmp(enm->enm_addrlo, enm->enm_addrhi,
962 sizeof(enm->enm_addrlo)) != 0) { 966 sizeof(enm->enm_addrlo)) != 0) {
963 /* 967 /*
964 * We must listen to a range of multicast addresses. 968 * We must listen to a range of multicast addresses.
965 * For now, just accept all multicasts, rather than 969 * For now, just accept all multicasts, rather than
966 * trying to set only those filter bits needed to match 970 * trying to set only those filter bits needed to match
967 * the range. (At this time, the only use of address 971 * the range. (At this time, the only use of address
968 * ranges is for IP multicast routing, for which the 972 * ranges is for IP multicast routing, for which the
969 * range is big enough to require all bits set.) 973 * range is big enough to require all bits set.)
970 */ 974 */
971 ifp->if_flags |= IFF_ALLMULTI; 975 ifp->if_flags |= IFF_ALLMULTI;
972 for (i = 0; i < 8; i++) 976 for (i = 0; i < 8; i++)
973 af[i] = 0xff; 977 af[i] = 0xff;
974 ETHER_UNLOCK(ec); 978 ETHER_UNLOCK(ec);
975 return; 979 return;
976 } 980 }
977 981
978 crc = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN); 982 crc = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN);
979 983
980 /* Just want the 6 most significant bits. */ 984 /* Just want the 6 most significant bits. */
981 crc >>= 26; 985 crc >>= 26;
982 986
983 /* Turn on the corresponding bit in the filter. */ 987 /* Turn on the corresponding bit in the filter. */
984 af[crc >> 3] |= 1 << (crc & 0x7); 988 af[crc >> 3] |= 1 << (crc & 0x7);
985 989
986 ETHER_NEXT_MULTI(step, enm); 990 ETHER_NEXT_MULTI(step, enm);
987 } 991 }
988 ETHER_UNLOCK(ec); 992 ETHER_UNLOCK(ec);
989 ifp->if_flags &= ~IFF_ALLMULTI; 993 ifp->if_flags &= ~IFF_ALLMULTI;
990} 994}
991 995
992/* 996/*
993 * Copy data from receive buffer to a new mbuf chain allocating mbufs 997 * Copy data from receive buffer to a new mbuf chain allocating mbufs
994 * as needed. Return pointer to first mbuf in chain. 998 * as needed. Return pointer to first mbuf in chain.
995 * sc = dp8390 info (softc) 999 * sc = dp8390 info (softc)
996 * src = pointer in dp8390 ring buffer 1000 * src = pointer in dp8390 ring buffer
997 * total_len = amount of data to copy 1001 * total_len = amount of data to copy
998 */ 1002 */
999struct mbuf * 1003struct mbuf *
1000dp8390_get(struct dp8390_softc *sc, int src, u_short total_len) 1004dp8390_get(struct dp8390_softc *sc, int src, u_short total_len)
1001{ 1005{
1002 struct ifnet *ifp = &sc->sc_ec.ec_if; 1006 struct ifnet *ifp = &sc->sc_ec.ec_if;
1003 struct mbuf *m, *m0, *newm; 1007 struct mbuf *m, *m0, *newm;
1004 u_short len; 1008 u_short len;
1005 1009
1006 MGETHDR(m0, M_DONTWAIT, MT_DATA); 1010 MGETHDR(m0, M_DONTWAIT, MT_DATA);
1007 if (m0 == NULL) 1011 if (m0 == NULL)
1008 return NULL; 1012 return NULL;
1009 m_set_rcvif(m0, ifp); 1013 m_set_rcvif(m0, ifp);
1010 m0->m_pkthdr.len = total_len; 1014 m0->m_pkthdr.len = total_len;
1011 len = MHLEN; 1015 len = MHLEN;
1012 m = m0; 1016 m = m0;
1013 1017
1014 while (total_len > 0) { 1018 while (total_len > 0) {
1015 if (total_len >= MINCLSIZE) { 1019 if (total_len >= MINCLSIZE) {
1016 MCLGET(m, M_DONTWAIT); 1020 MCLGET(m, M_DONTWAIT);
1017 if ((m->m_flags & M_EXT) == 0) 1021 if ((m->m_flags & M_EXT) == 0)
1018 goto bad; 1022 goto bad;
1019 len = MCLBYTES; 1023 len = MCLBYTES;
1020 } 1024 }
1021 1025
1022 /* Make sure the data after the Ethernet header is aligned. */ 1026 /* Make sure the data after the Ethernet header is aligned. */
1023 if (m == m0) { 1027 if (m == m0) {
1024 char *newdata = (char *) 1028 char *newdata = (char *)
1025 ALIGN(m->m_data + sizeof(struct ether_header)) - 1029 ALIGN(m->m_data + sizeof(struct ether_header)) -
1026 sizeof(struct ether_header); 1030 sizeof(struct ether_header);
1027 len -= newdata - m->m_data; 1031 len -= newdata - m->m_data;
1028 m->m_data = newdata; 1032 m->m_data = newdata;
1029 } 1033 }
1030 1034
1031 m->m_len = len = uimin(total_len, len); 1035 m->m_len = len = uimin(total_len, len);
1032 src = (*sc->ring_copy)(sc, src, mtod(m, void *), len); 1036 src = (*sc->ring_copy)(sc, src, mtod(m, void *), len);
1033 1037
1034 total_len -= len; 1038 total_len -= len;
1035 if (total_len > 0) { 1039 if (total_len > 0) {
1036 MGET(newm, M_DONTWAIT, MT_DATA); 1040 MGET(newm, M_DONTWAIT, MT_DATA);
1037 if (newm == NULL) 1041 if (newm == NULL)
1038 goto bad; 1042 goto bad;
1039 len = MLEN; 1043 len = MLEN;
1040 m = m->m_next = newm; 1044 m = m->m_next = newm;
1041 } 1045 }
1042 } 1046 }
1043 1047
1044 return m0; 1048 return m0;
1045 1049
1046 bad: 1050 bad:
1047 m_freem(m0); 1051 m_freem(m0);
1048 return NULL; 1052 return NULL;
1049} 1053}
1050 1054
1051 1055
1052/* 1056/*
1053 * Default driver support functions. 1057 * Default driver support functions.
1054 * 1058 *
1055 * NOTE: all support functions assume 8-bit shared memory. 1059 * NOTE: all support functions assume 8-bit shared memory.
1056 */ 1060 */
1057/* 1061/*
1058 * Zero NIC buffer memory and verify that it is clear. 1062 * Zero NIC buffer memory and verify that it is clear.
1059 */ 1063 */
1060static int 1064static int
1061dp8390_test_mem(struct dp8390_softc *sc) 1065dp8390_test_mem(struct dp8390_softc *sc)
1062{ 1066{
1063 bus_space_tag_t buft = sc->sc_buft; 1067 bus_space_tag_t buft = sc->sc_buft;
1064 bus_space_handle_t bufh = sc->sc_bufh; 1068 bus_space_handle_t bufh = sc->sc_bufh;
1065 int i; 1069 int i;
1066 1070
1067 bus_space_set_region_1(buft, bufh, sc->mem_start, 0, sc->mem_size); 1071 bus_space_set_region_1(buft, bufh, sc->mem_start, 0, sc->mem_size);
1068 1072
1069 for (i = 0; i < sc->mem_size; ++i) { 1073 for (i = 0; i < sc->mem_size; ++i) {
1070 if (bus_space_read_1(buft, bufh, sc->mem_start + i)) { 1074 if (bus_space_read_1(buft, bufh, sc->mem_start + i)) {
1071 printf(": failed to clear NIC buffer at offset %x - " 1075 printf(": failed to clear NIC buffer at offset %x - "
1072 "check configuration\n", (sc->mem_start + i)); 1076 "check configuration\n", (sc->mem_start + i));
1073 return 1; 1077 return 1;
1074 } 1078 }
1075 } 1079 }
1076 1080
1077 return 0; 1081 return 0;
1078} 1082}
1079 1083
1080/* 1084/*
1081 * Read a packet header from the ring, given the source offset. 1085 * Read a packet header from the ring, given the source offset.
1082 */ 1086 */
1083static void 1087static void
1084dp8390_read_hdr(struct dp8390_softc *sc, int src, struct dp8390_ring *hdrp) 1088dp8390_read_hdr(struct dp8390_softc *sc, int src, struct dp8390_ring *hdrp)
1085{ 1089{
1086 bus_space_tag_t buft = sc->sc_buft; 1090 bus_space_tag_t buft = sc->sc_buft;
1087 bus_space_handle_t bufh = sc->sc_bufh; 1091 bus_space_handle_t bufh = sc->sc_bufh;
1088 1092
1089 /* 1093 /*
1090 * The byte count includes a 4 byte header that was added by 1094 * The byte count includes a 4 byte header that was added by
1091 * the NIC. 1095 * the NIC.
1092 */ 1096 */
1093 hdrp->rsr = bus_space_read_1(buft, bufh, src); 1097 hdrp->rsr = bus_space_read_1(buft, bufh, src);
1094 hdrp->next_packet = bus_space_read_1(buft, bufh, src + 1); 1098 hdrp->next_packet = bus_space_read_1(buft, bufh, src + 1);
1095 hdrp->count = bus_space_read_1(buft, bufh, src + 2) | 1099 hdrp->count = bus_space_read_1(buft, bufh, src + 2) |
1096 (bus_space_read_1(buft, bufh, src + 3) << 8); 1100 (bus_space_read_1(buft, bufh, src + 3) << 8);
1097} 1101}
1098 1102
1099/* 1103/*
1100 * Copy `amount' bytes from a packet in the ring buffer to a linear 1104 * Copy `amount' bytes from a packet in the ring buffer to a linear
1101 * destination buffer, given a source offset and destination address. 1105 * destination buffer, given a source offset and destination address.
1102 * Takes into account ring-wrap. 1106 * Takes into account ring-wrap.
1103 */ 1107 */
1104static int 1108static int
1105dp8390_ring_copy(struct dp8390_softc *sc, int src, void *dst, u_short amount) 1109dp8390_ring_copy(struct dp8390_softc *sc, int src, void *dst, u_short amount)
1106{ 1110{
1107 bus_space_tag_t buft = sc->sc_buft; 1111 bus_space_tag_t buft = sc->sc_buft;
1108 bus_space_handle_t bufh = sc->sc_bufh; 1112 bus_space_handle_t bufh = sc->sc_bufh;
1109 u_short tmp_amount; 1113 u_short tmp_amount;
1110 1114
1111 /* Does copy wrap to lower addr in ring buffer? */ 1115 /* Does copy wrap to lower addr in ring buffer? */
1112 if (src + amount > sc->mem_end) { 1116 if (src + amount > sc->mem_end) {
1113 tmp_amount = sc->mem_end - src; 1117 tmp_amount = sc->mem_end - src;
1114 1118
1115 /* Copy amount up to end of NIC memory. */ 1119 /* Copy amount up to end of NIC memory. */
1116 bus_space_read_region_1(buft, bufh, src, dst, tmp_amount); 1120 bus_space_read_region_1(buft, bufh, src, dst, tmp_amount);
1117 1121
1118 amount -= tmp_amount; 1122 amount -= tmp_amount;
1119 src = sc->mem_ring; 1123 src = sc->mem_ring;
1120 dst = (char *)dst + tmp_amount; 1124 dst = (char *)dst + tmp_amount;
1121 } 1125 }
1122 bus_space_read_region_1(buft, bufh, src, dst, amount); 1126 bus_space_read_region_1(buft, bufh, src, dst, amount);
1123 1127
1124 return src + amount; 1128 return src + amount;
1125} 1129}
1126 1130
1127/* 1131/*
1128 * Copy a packet from an mbuf to the transmit buffer on the card. 1132 * Copy a packet from an mbuf to the transmit buffer on the card.
1129 * 1133 *
1130 * Currently uses an extra buffer/extra memory copy, unless the whole 1134 * Currently uses an extra buffer/extra memory copy, unless the whole
1131 * packet fits in one mbuf. 1135 * packet fits in one mbuf.
1132 */ 1136 */
1133static int 1137static int
1134dp8390_write_mbuf(struct dp8390_softc *sc, struct mbuf *m, int buf) 1138dp8390_write_mbuf(struct dp8390_softc *sc, struct mbuf *m, int buf)
1135{ 1139{
1136 bus_space_tag_t buft = sc->sc_buft; 1140 bus_space_tag_t buft = sc->sc_buft;
1137 bus_space_handle_t bufh = sc->sc_bufh; 1141 bus_space_handle_t bufh = sc->sc_bufh;
1138 uint8_t *data; 1142 uint8_t *data;
1139 int len, totlen = 0; 1143 int len, totlen = 0;
1140 1144
1141 for (; m ; m = m->m_next) { 1145 for (; m ; m = m->m_next) {
1142 data = mtod(m, uint8_t *); 1146 data = mtod(m, uint8_t *);
1143 len = m->m_len; 1147 len = m->m_len;
1144 if (len > 0) { 1148 if (len > 0) {
1145 bus_space_write_region_1(buft, bufh, buf, data, len); 1149 bus_space_write_region_1(buft, bufh, buf, data, len);
1146 totlen += len; 1150 totlen += len;
1147 buf += len; 1151 buf += len;
1148 } 1152 }
1149 } 1153 }
1150 if (totlen < ETHER_MIN_LEN - ETHER_CRC_LEN) { 1154 if (totlen < ETHER_MIN_LEN - ETHER_CRC_LEN) {
1151 bus_space_set_region_1(buft, bufh, buf, 0, 1155 bus_space_set_region_1(buft, bufh, buf, 0,
1152 ETHER_MIN_LEN - ETHER_CRC_LEN - totlen); 1156 ETHER_MIN_LEN - ETHER_CRC_LEN - totlen);
1153 totlen = ETHER_MIN_LEN - ETHER_CRC_LEN; 1157 totlen = ETHER_MIN_LEN - ETHER_CRC_LEN;
1154 } 1158 }
1155 return totlen; 1159 return totlen;
1156} 1160}
1157 1161
1158/* 1162/*
1159 * Enable power on the interface. 1163 * Enable power on the interface.
1160 */ 1164 */
1161int 1165int
1162dp8390_enable(struct dp8390_softc *sc) 1166dp8390_enable(struct dp8390_softc *sc)
1163{ 1167{
1164 1168
1165 if (sc->sc_enabled == 0 && sc->sc_enable != NULL) { 1169 if (sc->sc_enabled == 0 && sc->sc_enable != NULL) {
1166 if ((*sc->sc_enable)(sc) != 0) { 1170 if ((*sc->sc_enable)(sc) != 0) {
1167 aprint_error_dev(sc->sc_dev, 1171 aprint_error_dev(sc->sc_dev,
1168 "device enable failed\n"); 1172 "device enable failed\n");
1169 return EIO; 1173 return EIO;
1170 } 1174 }
1171 } 1175 }
1172 1176
1173 sc->sc_enabled = 1; 1177 sc->sc_enabled = 1;
1174 return 0; 1178 return 0;
1175} 1179}
1176 1180
1177/* 1181/*
1178 * Disable power on the interface. 1182 * Disable power on the interface.
1179 */ 1183 */
1180void 1184void
1181dp8390_disable(struct dp8390_softc *sc) 1185dp8390_disable(struct dp8390_softc *sc)
1182{ 1186{
1183 1187
1184 if (sc->sc_enabled != 0 && sc->sc_disable != NULL) { 1188 if (sc->sc_enabled != 0 && sc->sc_disable != NULL) {
1185 (*sc->sc_disable)(sc); 1189 (*sc->sc_disable)(sc);
1186 sc->sc_enabled = 0; 1190 sc->sc_enabled = 0;
1187 } 1191 }
1188} 1192}
1189 1193
1190int 1194int
1191dp8390_activate(device_t self, enum devact act) 1195dp8390_activate(device_t self, enum devact act)
1192{ 1196{
1193 struct dp8390_softc *sc = device_private(self); 1197 struct dp8390_softc *sc = device_private(self);
1194 1198
1195 switch (act) { 1199 switch (act) {
1196 case DVACT_DEACTIVATE: 1200 case DVACT_DEACTIVATE:
1197 if_deactivate(&sc->sc_ec.ec_if); 1201 if_deactivate(&sc->sc_ec.ec_if);
1198 return 0; 1202 return 0;
1199 default: 1203 default:
1200 return EOPNOTSUPP; 1204 return EOPNOTSUPP;
1201 } 1205 }
1202} 1206}
1203 1207
1204int 1208int
1205dp8390_detach(struct dp8390_softc *sc, int flags) 1209dp8390_detach(struct dp8390_softc *sc, int flags)
1206{ 1210{
1207 struct ifnet *ifp = &sc->sc_ec.ec_if; 1211 struct ifnet *ifp = &sc->sc_ec.ec_if;
1208 1212
1209 /* Succeed now if there's no work to do. */ 1213 /* Succeed now if there's no work to do. */
1210 if ((sc->sc_flags & DP8390_ATTACHED) == 0) 1214 if ((sc->sc_flags & DP8390_ATTACHED) == 0)
1211 return 0; 1215 return 0;
1212 1216
1213 /* dp8390_disable() checks sc->sc_enabled */ 1217 /* dp8390_disable() checks sc->sc_enabled */
1214 dp8390_disable(sc); 1218 dp8390_disable(sc);
1215 1219
1216 if (sc->sc_media_fini != NULL) 1220 if (sc->sc_media_fini != NULL)
1217 (*sc->sc_media_fini)(sc); 1221 (*sc->sc_media_fini)(sc);
1218 1222
1219 /* Delete all remaining media. */ 1223 /* Delete all remaining media. */
1220 ifmedia_delete_instance(&sc->sc_media, IFM_INST_ANY); 1224 ifmedia_delete_instance(&sc->sc_media, IFM_INST_ANY);
1221 1225
1222 rnd_detach_source(&sc->rnd_source); 1226 rnd_detach_source(&sc->rnd_source);
1223 ether_ifdetach(ifp); 1227 ether_ifdetach(ifp);
1224 if_detach(ifp); 1228 if_detach(ifp);
1225 1229
1226 return 0; 1230 return 0;
1227} 1231}

cvs diff -r1.44 -r1.45 src/sys/dev/ic/dp83932.c (switch to unified diff)

--- src/sys/dev/ic/dp83932.c 2019/05/28 07:41:48 1.44
+++ src/sys/dev/ic/dp83932.c 2020/01/29 14:14:55 1.45
@@ -1,1262 +1,1266 @@ @@ -1,1262 +1,1266 @@
1/* $NetBSD: dp83932.c,v 1.44 2019/05/28 07:41:48 msaitoh Exp $ */ 1/* $NetBSD: dp83932.c,v 1.45 2020/01/29 14:14:55 thorpej Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2001 The NetBSD Foundation, Inc. 4 * Copyright (c) 2001 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 Jason R. Thorpe. 8 * by Jason R. Thorpe.
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.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
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/* 32/*
33 * Device driver for the National Semiconductor DP83932 33 * Device driver for the National Semiconductor DP83932
34 * Systems-Oriented Network Interface Controller (SONIC). 34 * Systems-Oriented Network Interface Controller (SONIC).
35 */ 35 */
36 36
37#include <sys/cdefs.h> 37#include <sys/cdefs.h>
38__KERNEL_RCSID(0, "$NetBSD: dp83932.c,v 1.44 2019/05/28 07:41:48 msaitoh Exp $"); 38__KERNEL_RCSID(0, "$NetBSD: dp83932.c,v 1.45 2020/01/29 14:14:55 thorpej Exp $");
39 39
40 40
41#include <sys/param.h> 41#include <sys/param.h>
42#include <sys/systm.h> 42#include <sys/systm.h>
43#include <sys/mbuf.h> 43#include <sys/mbuf.h>
44#include <sys/malloc.h> 44#include <sys/malloc.h>
45#include <sys/kernel.h> 45#include <sys/kernel.h>
46#include <sys/socket.h> 46#include <sys/socket.h>
47#include <sys/ioctl.h> 47#include <sys/ioctl.h>
48#include <sys/errno.h> 48#include <sys/errno.h>
49#include <sys/device.h> 49#include <sys/device.h>
50 50
51#include <net/if.h> 51#include <net/if.h>
52#include <net/if_dl.h> 52#include <net/if_dl.h>
53#include <net/if_ether.h> 53#include <net/if_ether.h>
54 54
55#include <net/bpf.h> 55#include <net/bpf.h>
56 56
57#include <sys/bus.h> 57#include <sys/bus.h>
58#include <sys/intr.h> 58#include <sys/intr.h>
59 59
60#include <dev/ic/dp83932reg.h> 60#include <dev/ic/dp83932reg.h>
61#include <dev/ic/dp83932var.h> 61#include <dev/ic/dp83932var.h>
62 62
63static void sonic_start(struct ifnet *); 63static void sonic_start(struct ifnet *);
64static void sonic_watchdog(struct ifnet *); 64static void sonic_watchdog(struct ifnet *);
65static int sonic_ioctl(struct ifnet *, u_long, void *); 65static int sonic_ioctl(struct ifnet *, u_long, void *);
66static int sonic_init(struct ifnet *); 66static int sonic_init(struct ifnet *);
67static void sonic_stop(struct ifnet *, int); 67static void sonic_stop(struct ifnet *, int);
68 68
69static bool sonic_shutdown(device_t, int); 69static bool sonic_shutdown(device_t, int);
70 70
71static void sonic_reset(struct sonic_softc *); 71static void sonic_reset(struct sonic_softc *);
72static void sonic_rxdrain(struct sonic_softc *); 72static void sonic_rxdrain(struct sonic_softc *);
73static int sonic_add_rxbuf(struct sonic_softc *, int); 73static int sonic_add_rxbuf(struct sonic_softc *, int);
74static void sonic_set_filter(struct sonic_softc *); 74static void sonic_set_filter(struct sonic_softc *);
75 75
76static uint16_t sonic_txintr(struct sonic_softc *); 76static uint16_t sonic_txintr(struct sonic_softc *);
77static void sonic_rxintr(struct sonic_softc *); 77static void sonic_rxintr(struct sonic_softc *);
78 78
79int sonic_copy_small = 0; 79int sonic_copy_small = 0;
80 80
81#define ETHER_PAD_LEN (ETHER_MIN_LEN - ETHER_CRC_LEN) 81#define ETHER_PAD_LEN (ETHER_MIN_LEN - ETHER_CRC_LEN)
82 82
83/* 83/*
84 * sonic_attach: 84 * sonic_attach:
85 * 85 *
86 * Attach a SONIC interface to the system. 86 * Attach a SONIC interface to the system.
87 */ 87 */
88void 88void
89sonic_attach(struct sonic_softc *sc, const uint8_t *enaddr) 89sonic_attach(struct sonic_softc *sc, const uint8_t *enaddr)
90{ 90{
91 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 91 struct ifnet *ifp = &sc->sc_ethercom.ec_if;
92 int i, rseg, error; 92 int i, rseg, error;
93 bus_dma_segment_t seg; 93 bus_dma_segment_t seg;
94 size_t cdatasize; 94 size_t cdatasize;
95 uint8_t *nullbuf; 95 uint8_t *nullbuf;
96 96
97 /* 97 /*
98 * Allocate the control data structures, and create and load the 98 * Allocate the control data structures, and create and load the
99 * DMA map for it. 99 * DMA map for it.
100 */ 100 */
101 if (sc->sc_32bit) 101 if (sc->sc_32bit)
102 cdatasize = sizeof(struct sonic_control_data32); 102 cdatasize = sizeof(struct sonic_control_data32);
103 else 103 else
104 cdatasize = sizeof(struct sonic_control_data16); 104 cdatasize = sizeof(struct sonic_control_data16);
105 105
106 if ((error = bus_dmamem_alloc(sc->sc_dmat, cdatasize + ETHER_PAD_LEN, 106 if ((error = bus_dmamem_alloc(sc->sc_dmat, cdatasize + ETHER_PAD_LEN,
107 PAGE_SIZE, (64 * 1024), &seg, 1, &rseg, 107 PAGE_SIZE, (64 * 1024), &seg, 1, &rseg,
108 BUS_DMA_NOWAIT)) != 0) { 108 BUS_DMA_NOWAIT)) != 0) {
109 aprint_error_dev(sc->sc_dev, 109 aprint_error_dev(sc->sc_dev,
110 "unable to allocate control data, error = %d\n", error); 110 "unable to allocate control data, error = %d\n", error);
111 goto fail_0; 111 goto fail_0;
112 } 112 }
113 113
114 if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg, 114 if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg,
115 cdatasize + ETHER_PAD_LEN, (void **) &sc->sc_cdata16, 115 cdatasize + ETHER_PAD_LEN, (void **) &sc->sc_cdata16,
116 BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) != 0) { 116 BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) != 0) {
117 aprint_error_dev(sc->sc_dev, 117 aprint_error_dev(sc->sc_dev,
118 "unable to map control data, error = %d\n", error); 118 "unable to map control data, error = %d\n", error);
119 goto fail_1; 119 goto fail_1;
120 } 120 }
121 nullbuf = (uint8_t *)sc->sc_cdata16 + cdatasize; 121 nullbuf = (uint8_t *)sc->sc_cdata16 + cdatasize;
122 memset(nullbuf, 0, ETHER_PAD_LEN); 122 memset(nullbuf, 0, ETHER_PAD_LEN);
123 123
124 if ((error = bus_dmamap_create(sc->sc_dmat, 124 if ((error = bus_dmamap_create(sc->sc_dmat,
125 cdatasize, 1, cdatasize, 0, BUS_DMA_NOWAIT, 125 cdatasize, 1, cdatasize, 0, BUS_DMA_NOWAIT,
126 &sc->sc_cddmamap)) != 0) { 126 &sc->sc_cddmamap)) != 0) {
127 aprint_error_dev(sc->sc_dev, 127 aprint_error_dev(sc->sc_dev,
128 "unable to create control data DMA map, error = %d\n", 128 "unable to create control data DMA map, error = %d\n",
129 error); 129 error);
130 goto fail_2; 130 goto fail_2;
131 } 131 }
132 132
133 if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_cddmamap, 133 if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_cddmamap,
134 sc->sc_cdata16, cdatasize, NULL, BUS_DMA_NOWAIT)) != 0) { 134 sc->sc_cdata16, cdatasize, NULL, BUS_DMA_NOWAIT)) != 0) {
135 aprint_error_dev(sc->sc_dev, 135 aprint_error_dev(sc->sc_dev,
136 "unable to load control data DMA map, error = %d\n", error); 136 "unable to load control data DMA map, error = %d\n", error);
137 goto fail_3; 137 goto fail_3;
138 } 138 }
139 139
140 /* 140 /*
141 * Create the transmit buffer DMA maps. 141 * Create the transmit buffer DMA maps.
142 */ 142 */
143 for (i = 0; i < SONIC_NTXDESC; i++) { 143 for (i = 0; i < SONIC_NTXDESC; i++) {
144 if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 144 if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES,
145 SONIC_NTXFRAGS, MCLBYTES, 0, BUS_DMA_NOWAIT, 145 SONIC_NTXFRAGS, MCLBYTES, 0, BUS_DMA_NOWAIT,
146 &sc->sc_txsoft[i].ds_dmamap)) != 0) { 146 &sc->sc_txsoft[i].ds_dmamap)) != 0) {
147 aprint_error_dev(sc->sc_dev, 147 aprint_error_dev(sc->sc_dev,
148 "unable to create tx DMA map %d, error = %d\n", 148 "unable to create tx DMA map %d, error = %d\n",
149 i, error); 149 i, error);
150 goto fail_4; 150 goto fail_4;
151 } 151 }
152 } 152 }
153 153
154 /* 154 /*
155 * Create the receive buffer DMA maps. 155 * Create the receive buffer DMA maps.
156 */ 156 */
157 for (i = 0; i < SONIC_NRXDESC; i++) { 157 for (i = 0; i < SONIC_NRXDESC; i++) {
158 if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, 158 if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1,
159 MCLBYTES, 0, BUS_DMA_NOWAIT, 159 MCLBYTES, 0, BUS_DMA_NOWAIT,
160 &sc->sc_rxsoft[i].ds_dmamap)) != 0) { 160 &sc->sc_rxsoft[i].ds_dmamap)) != 0) {
161 aprint_error_dev(sc->sc_dev, 161 aprint_error_dev(sc->sc_dev,
162 "unable to create rx DMA map %d, error = %d\n", 162 "unable to create rx DMA map %d, error = %d\n",
163 i, error); 163 i, error);
164 goto fail_5; 164 goto fail_5;
165 } 165 }
166 sc->sc_rxsoft[i].ds_mbuf = NULL; 166 sc->sc_rxsoft[i].ds_mbuf = NULL;
167 } 167 }
168 168
169 /* 169 /*
170 * create and map the pad buffer 170 * create and map the pad buffer
171 */ 171 */
172 if ((error = bus_dmamap_create(sc->sc_dmat, ETHER_PAD_LEN, 1, 172 if ((error = bus_dmamap_create(sc->sc_dmat, ETHER_PAD_LEN, 1,
173 ETHER_PAD_LEN, 0, BUS_DMA_NOWAIT, &sc->sc_nulldmamap)) != 0) { 173 ETHER_PAD_LEN, 0, BUS_DMA_NOWAIT, &sc->sc_nulldmamap)) != 0) {
174 aprint_error_dev(sc->sc_dev, 174 aprint_error_dev(sc->sc_dev,
175 "unable to create pad buffer DMA map, error = %d\n", error); 175 "unable to create pad buffer DMA map, error = %d\n", error);
176 goto fail_5; 176 goto fail_5;
177 } 177 }
178 178
179 if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_nulldmamap, 179 if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_nulldmamap,
180 nullbuf, ETHER_PAD_LEN, NULL, BUS_DMA_NOWAIT)) != 0) { 180 nullbuf, ETHER_PAD_LEN, NULL, BUS_DMA_NOWAIT)) != 0) {
181 aprint_error_dev(sc->sc_dev, 181 aprint_error_dev(sc->sc_dev,
182 "unable to load pad buffer DMA map, error = %d\n", error); 182 "unable to load pad buffer DMA map, error = %d\n", error);
183 goto fail_6; 183 goto fail_6;
184 } 184 }
185 bus_dmamap_sync(sc->sc_dmat, sc->sc_nulldmamap, 0, ETHER_PAD_LEN, 185 bus_dmamap_sync(sc->sc_dmat, sc->sc_nulldmamap, 0, ETHER_PAD_LEN,
186 BUS_DMASYNC_PREWRITE); 186 BUS_DMASYNC_PREWRITE);
187 187
188 /* 188 /*
189 * Reset the chip to a known state. 189 * Reset the chip to a known state.
190 */ 190 */
191 sonic_reset(sc); 191 sonic_reset(sc);
192 192
193 aprint_normal_dev(sc->sc_dev, "Ethernet address %s\n", 193 aprint_normal_dev(sc->sc_dev, "Ethernet address %s\n",
194 ether_sprintf(enaddr)); 194 ether_sprintf(enaddr));
195 195
196 strlcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ); 196 strlcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ);
197 ifp->if_softc = sc; 197 ifp->if_softc = sc;
198 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 198 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
199 ifp->if_ioctl = sonic_ioctl; 199 ifp->if_ioctl = sonic_ioctl;
200 ifp->if_start = sonic_start; 200 ifp->if_start = sonic_start;
201 ifp->if_watchdog = sonic_watchdog; 201 ifp->if_watchdog = sonic_watchdog;
202 ifp->if_init = sonic_init; 202 ifp->if_init = sonic_init;
203 ifp->if_stop = sonic_stop; 203 ifp->if_stop = sonic_stop;
204 IFQ_SET_READY(&ifp->if_snd); 204 IFQ_SET_READY(&ifp->if_snd);
205 205
206 /* 206 /*
207 * We can support 802.1Q VLAN-sized frames. 207 * We can support 802.1Q VLAN-sized frames.
208 */ 208 */
209 sc->sc_ethercom.ec_capabilities |= ETHERCAP_VLAN_MTU; 209 sc->sc_ethercom.ec_capabilities |= ETHERCAP_VLAN_MTU;
210 210
211 /* 211 /*
212 * Attach the interface. 212 * Attach the interface.
213 */ 213 */
214 if_attach(ifp); 214 if_attach(ifp);
215 if_deferred_start_init(ifp, NULL); 215 if_deferred_start_init(ifp, NULL);
216 ether_ifattach(ifp, enaddr); 216 ether_ifattach(ifp, enaddr);
217 217
218 /* 218 /*
219 * Make sure the interface is shutdown during reboot. 219 * Make sure the interface is shutdown during reboot.
220 */ 220 */
221 if (pmf_device_register1(sc->sc_dev, NULL, NULL, sonic_shutdown)) 221 if (pmf_device_register1(sc->sc_dev, NULL, NULL, sonic_shutdown))
222 pmf_class_network_register(sc->sc_dev, ifp); 222 pmf_class_network_register(sc->sc_dev, ifp);
223 else 223 else
224 aprint_error_dev(sc->sc_dev, 224 aprint_error_dev(sc->sc_dev,
225 "couldn't establish power handler\n"); 225 "couldn't establish power handler\n");
226 226
227 return; 227 return;
228 228
229 /* 229 /*
230 * Free any resources we've allocated during the failed attach 230 * Free any resources we've allocated during the failed attach
231 * attempt. Do this in reverse order and fall through. 231 * attempt. Do this in reverse order and fall through.
232 */ 232 */
233 fail_6: 233 fail_6:
234 bus_dmamap_destroy(sc->sc_dmat, sc->sc_nulldmamap); 234 bus_dmamap_destroy(sc->sc_dmat, sc->sc_nulldmamap);
235 fail_5: 235 fail_5:
236 for (i = 0; i < SONIC_NRXDESC; i++) { 236 for (i = 0; i < SONIC_NRXDESC; i++) {
237 if (sc->sc_rxsoft[i].ds_dmamap != NULL) 237 if (sc->sc_rxsoft[i].ds_dmamap != NULL)
238 bus_dmamap_destroy(sc->sc_dmat, 238 bus_dmamap_destroy(sc->sc_dmat,
239 sc->sc_rxsoft[i].ds_dmamap); 239 sc->sc_rxsoft[i].ds_dmamap);
240 } 240 }
241 fail_4: 241 fail_4:
242 for (i = 0; i < SONIC_NTXDESC; i++) { 242 for (i = 0; i < SONIC_NTXDESC; i++) {
243 if (sc->sc_txsoft[i].ds_dmamap != NULL) 243 if (sc->sc_txsoft[i].ds_dmamap != NULL)
244 bus_dmamap_destroy(sc->sc_dmat, 244 bus_dmamap_destroy(sc->sc_dmat,
245 sc->sc_txsoft[i].ds_dmamap); 245 sc->sc_txsoft[i].ds_dmamap);
246 } 246 }
247 bus_dmamap_unload(sc->sc_dmat, sc->sc_cddmamap); 247 bus_dmamap_unload(sc->sc_dmat, sc->sc_cddmamap);
248 fail_3: 248 fail_3:
249 bus_dmamap_destroy(sc->sc_dmat, sc->sc_cddmamap); 249 bus_dmamap_destroy(sc->sc_dmat, sc->sc_cddmamap);
250 fail_2: 250 fail_2:
251 bus_dmamem_unmap(sc->sc_dmat, (void *)sc->sc_cdata16, cdatasize); 251 bus_dmamem_unmap(sc->sc_dmat, (void *)sc->sc_cdata16, cdatasize);
252 fail_1: 252 fail_1:
253 bus_dmamem_free(sc->sc_dmat, &seg, rseg); 253 bus_dmamem_free(sc->sc_dmat, &seg, rseg);
254 fail_0: 254 fail_0:
255 return; 255 return;
256} 256}
257 257
258/* 258/*
259 * sonic_shutdown: 259 * sonic_shutdown:
260 * 260 *
261 * Make sure the interface is stopped at reboot. 261 * Make sure the interface is stopped at reboot.
262 */ 262 */
263bool 263bool
264sonic_shutdown(device_t self, int howto) 264sonic_shutdown(device_t self, int howto)
265{ 265{
266 struct sonic_softc *sc = device_private(self); 266 struct sonic_softc *sc = device_private(self);
267 267
268 sonic_stop(&sc->sc_ethercom.ec_if, 1); 268 sonic_stop(&sc->sc_ethercom.ec_if, 1);
269 269
270 return true; 270 return true;
271} 271}
272 272
273/* 273/*
274 * sonic_start: [ifnet interface function] 274 * sonic_start: [ifnet interface function]
275 * 275 *
276 * Start packet transmission on the interface. 276 * Start packet transmission on the interface.
277 */ 277 */
278void 278void
279sonic_start(struct ifnet *ifp) 279sonic_start(struct ifnet *ifp)
280{ 280{
281 struct sonic_softc *sc = ifp->if_softc; 281 struct sonic_softc *sc = ifp->if_softc;
282 struct mbuf *m0, *m; 282 struct mbuf *m0, *m;
283 struct sonic_tda16 *tda16; 283 struct sonic_tda16 *tda16;
284 struct sonic_tda32 *tda32; 284 struct sonic_tda32 *tda32;
285 struct sonic_descsoft *ds; 285 struct sonic_descsoft *ds;
286 bus_dmamap_t dmamap; 286 bus_dmamap_t dmamap;
287 int error, olasttx, nexttx, opending, totlen, olseg; 287 int error, olasttx, nexttx, opending, totlen, olseg;
288 int seg = 0; /* XXX: gcc */ 288 int seg = 0; /* XXX: gcc */
289 289
290 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING) 290 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
291 return; 291 return;
292 292
293 /* 293 /*
294 * Remember the previous txpending and the current "last txdesc 294 * Remember the previous txpending and the current "last txdesc
295 * used" index. 295 * used" index.
296 */ 296 */
297 opending = sc->sc_txpending; 297 opending = sc->sc_txpending;
298 olasttx = sc->sc_txlast; 298 olasttx = sc->sc_txlast;
299 299
300 /* 300 /*
301 * Loop through the send queue, setting up transmit descriptors 301 * Loop through the send queue, setting up transmit descriptors
302 * until we drain the queue, or use up all available transmit 302 * until we drain the queue, or use up all available transmit
303 * descriptors. Leave one at the end for sanity's sake. 303 * descriptors. Leave one at the end for sanity's sake.
304 */ 304 */
305 while (sc->sc_txpending < (SONIC_NTXDESC - 1)) { 305 while (sc->sc_txpending < (SONIC_NTXDESC - 1)) {
306 /* 306 /*
307 * Grab a packet off the queue. 307 * Grab a packet off the queue.
308 */ 308 */
309 IFQ_POLL(&ifp->if_snd, m0); 309 IFQ_POLL(&ifp->if_snd, m0);
310 if (m0 == NULL) 310 if (m0 == NULL)
311 break; 311 break;
312 m = NULL; 312 m = NULL;
313 313
314 /* 314 /*
315 * Get the next available transmit descriptor. 315 * Get the next available transmit descriptor.
316 */ 316 */
317 nexttx = SONIC_NEXTTX(sc->sc_txlast); 317 nexttx = SONIC_NEXTTX(sc->sc_txlast);
318 ds = &sc->sc_txsoft[nexttx]; 318 ds = &sc->sc_txsoft[nexttx];
319 dmamap = ds->ds_dmamap; 319 dmamap = ds->ds_dmamap;
320 320
321 /* 321 /*
322 * Load the DMA map. If this fails, the packet either 322 * Load the DMA map. If this fails, the packet either
323 * didn't fit in the allotted number of frags, or we were 323 * didn't fit in the allotted number of frags, or we were
324 * short on resources. In this case, we'll copy and try 324 * short on resources. In this case, we'll copy and try
325 * again. 325 * again.
326 */ 326 */
327 if ((error = bus_dmamap_load_mbuf(sc->sc_dmat, dmamap, m0, 327 if ((error = bus_dmamap_load_mbuf(sc->sc_dmat, dmamap, m0,
328 BUS_DMA_WRITE | BUS_DMA_NOWAIT)) != 0 || 328 BUS_DMA_WRITE | BUS_DMA_NOWAIT)) != 0 ||
329 (m0->m_pkthdr.len < ETHER_PAD_LEN && 329 (m0->m_pkthdr.len < ETHER_PAD_LEN &&
330 dmamap->dm_nsegs == SONIC_NTXFRAGS)) { 330 dmamap->dm_nsegs == SONIC_NTXFRAGS)) {
331 if (error == 0) 331 if (error == 0)
332 bus_dmamap_unload(sc->sc_dmat, dmamap); 332 bus_dmamap_unload(sc->sc_dmat, dmamap);
333 MGETHDR(m, M_DONTWAIT, MT_DATA); 333 MGETHDR(m, M_DONTWAIT, MT_DATA);
334 if (m == NULL) { 334 if (m == NULL) {
335 printf("%s: unable to allocate Tx mbuf\n", 335 printf("%s: unable to allocate Tx mbuf\n",
336 device_xname(sc->sc_dev)); 336 device_xname(sc->sc_dev));
337 break; 337 break;
338 } 338 }
339 if (m0->m_pkthdr.len > MHLEN) { 339 if (m0->m_pkthdr.len > MHLEN) {
340 MCLGET(m, M_DONTWAIT); 340 MCLGET(m, M_DONTWAIT);
341 if ((m->m_flags & M_EXT) == 0) { 341 if ((m->m_flags & M_EXT) == 0) {
342 printf("%s: unable to allocate Tx " 342 printf("%s: unable to allocate Tx "
343 "cluster\n", 343 "cluster\n",
344 device_xname(sc->sc_dev)); 344 device_xname(sc->sc_dev));
345 m_freem(m); 345 m_freem(m);
346 break; 346 break;
347 } 347 }
348 } 348 }
349 m_copydata(m0, 0, m0->m_pkthdr.len, mtod(m, void *)); 349 m_copydata(m0, 0, m0->m_pkthdr.len, mtod(m, void *));
350 m->m_pkthdr.len = m->m_len = m0->m_pkthdr.len; 350 m->m_pkthdr.len = m->m_len = m0->m_pkthdr.len;
351 error = bus_dmamap_load_mbuf(sc->sc_dmat, dmamap, 351 error = bus_dmamap_load_mbuf(sc->sc_dmat, dmamap,
352 m, BUS_DMA_WRITE | BUS_DMA_NOWAIT); 352 m, BUS_DMA_WRITE | BUS_DMA_NOWAIT);
353 if (error) { 353 if (error) {
354 printf("%s: unable to load Tx buffer, " 354 printf("%s: unable to load Tx buffer, "
355 "error = %d\n", device_xname(sc->sc_dev), 355 "error = %d\n", device_xname(sc->sc_dev),
356 error); 356 error);
357 m_freem(m); 357 m_freem(m);
358 break; 358 break;
359 } 359 }
360 } 360 }
361 IFQ_DEQUEUE(&ifp->if_snd, m0); 361 IFQ_DEQUEUE(&ifp->if_snd, m0);
362 if (m != NULL) { 362 if (m != NULL) {
363 m_freem(m0); 363 m_freem(m0);
364 m0 = m; 364 m0 = m;
365 } 365 }
366 366
367 /* 367 /*
368 * WE ARE NOW COMMITTED TO TRANSMITTING THE PACKET. 368 * WE ARE NOW COMMITTED TO TRANSMITTING THE PACKET.
369 */ 369 */
370 370
371 /* Sync the DMA map. */ 371 /* Sync the DMA map. */
372 bus_dmamap_sync(sc->sc_dmat, dmamap, 0, dmamap->dm_mapsize, 372 bus_dmamap_sync(sc->sc_dmat, dmamap, 0, dmamap->dm_mapsize,
373 BUS_DMASYNC_PREWRITE); 373 BUS_DMASYNC_PREWRITE);
374 374
375 /* 375 /*
376 * Store a pointer to the packet so we can free it later. 376 * Store a pointer to the packet so we can free it later.
377 */ 377 */
378 ds->ds_mbuf = m0; 378 ds->ds_mbuf = m0;
379 379
380 /* 380 /*
381 * Initialize the transmit descriptor. 381 * Initialize the transmit descriptor.
382 */ 382 */
383 totlen = 0; 383 totlen = 0;
384 if (sc->sc_32bit) { 384 if (sc->sc_32bit) {
385 tda32 = &sc->sc_tda32[nexttx]; 385 tda32 = &sc->sc_tda32[nexttx];
386 for (seg = 0; seg < dmamap->dm_nsegs; seg++) { 386 for (seg = 0; seg < dmamap->dm_nsegs; seg++) {
387 tda32->tda_frags[seg].frag_ptr1 = 387 tda32->tda_frags[seg].frag_ptr1 =
388 htosonic32(sc, 388 htosonic32(sc,
389 (dmamap->dm_segs[seg].ds_addr >> 16) & 389 (dmamap->dm_segs[seg].ds_addr >> 16) &
390 0xffff); 390 0xffff);
391 tda32->tda_frags[seg].frag_ptr0 = 391 tda32->tda_frags[seg].frag_ptr0 =
392 htosonic32(sc, 392 htosonic32(sc,
393 dmamap->dm_segs[seg].ds_addr & 0xffff); 393 dmamap->dm_segs[seg].ds_addr & 0xffff);
394 tda32->tda_frags[seg].frag_size = 394 tda32->tda_frags[seg].frag_size =
395 htosonic32(sc, dmamap->dm_segs[seg].ds_len); 395 htosonic32(sc, dmamap->dm_segs[seg].ds_len);
396 totlen += dmamap->dm_segs[seg].ds_len; 396 totlen += dmamap->dm_segs[seg].ds_len;
397 } 397 }
398 if (totlen < ETHER_PAD_LEN) { 398 if (totlen < ETHER_PAD_LEN) {
399 tda32->tda_frags[seg].frag_ptr1 = 399 tda32->tda_frags[seg].frag_ptr1 =
400 htosonic32(sc, 400 htosonic32(sc,
401 (sc->sc_nulldma >> 16) & 0xffff); 401 (sc->sc_nulldma >> 16) & 0xffff);
402 tda32->tda_frags[seg].frag_ptr0 = 402 tda32->tda_frags[seg].frag_ptr0 =
403 htosonic32(sc, sc->sc_nulldma & 0xffff); 403 htosonic32(sc, sc->sc_nulldma & 0xffff);
404 tda32->tda_frags[seg].frag_size = 404 tda32->tda_frags[seg].frag_size =
405 htosonic32(sc, ETHER_PAD_LEN - totlen); 405 htosonic32(sc, ETHER_PAD_LEN - totlen);
406 totlen = ETHER_PAD_LEN; 406 totlen = ETHER_PAD_LEN;
407 seg++; 407 seg++;
408 } 408 }
409 409
410 tda32->tda_status = 0; 410 tda32->tda_status = 0;
411 tda32->tda_pktconfig = 0; 411 tda32->tda_pktconfig = 0;
412 tda32->tda_pktsize = htosonic32(sc, totlen); 412 tda32->tda_pktsize = htosonic32(sc, totlen);
413 tda32->tda_fragcnt = htosonic32(sc, seg); 413 tda32->tda_fragcnt = htosonic32(sc, seg);
414 414
415 /* Link it up. */ 415 /* Link it up. */
416 tda32->tda_frags[seg].frag_ptr0 = 416 tda32->tda_frags[seg].frag_ptr0 =
417 htosonic32(sc, SONIC_CDTXADDR32(sc, 417 htosonic32(sc, SONIC_CDTXADDR32(sc,
418 SONIC_NEXTTX(nexttx)) & 0xffff); 418 SONIC_NEXTTX(nexttx)) & 0xffff);
419 419
420 /* Sync the Tx descriptor. */ 420 /* Sync the Tx descriptor. */
421 SONIC_CDTXSYNC32(sc, nexttx, 421 SONIC_CDTXSYNC32(sc, nexttx,
422 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 422 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
423 } else { 423 } else {
424 tda16 = &sc->sc_tda16[nexttx]; 424 tda16 = &sc->sc_tda16[nexttx];
425 for (seg = 0; seg < dmamap->dm_nsegs; seg++) { 425 for (seg = 0; seg < dmamap->dm_nsegs; seg++) {
426 tda16->tda_frags[seg].frag_ptr1 = 426 tda16->tda_frags[seg].frag_ptr1 =
427 htosonic16(sc, 427 htosonic16(sc,
428 (dmamap->dm_segs[seg].ds_addr >> 16) & 428 (dmamap->dm_segs[seg].ds_addr >> 16) &
429 0xffff); 429 0xffff);
430 tda16->tda_frags[seg].frag_ptr0 = 430 tda16->tda_frags[seg].frag_ptr0 =
431 htosonic16(sc, 431 htosonic16(sc,
432 dmamap->dm_segs[seg].ds_addr & 0xffff); 432 dmamap->dm_segs[seg].ds_addr & 0xffff);
433 tda16->tda_frags[seg].frag_size = 433 tda16->tda_frags[seg].frag_size =
434 htosonic16(sc, dmamap->dm_segs[seg].ds_len); 434 htosonic16(sc, dmamap->dm_segs[seg].ds_len);
435 totlen += dmamap->dm_segs[seg].ds_len; 435 totlen += dmamap->dm_segs[seg].ds_len;
436 } 436 }
437 if (totlen < ETHER_PAD_LEN) { 437 if (totlen < ETHER_PAD_LEN) {
438 tda16->tda_frags[seg].frag_ptr1 = 438 tda16->tda_frags[seg].frag_ptr1 =
439 htosonic16(sc, 439 htosonic16(sc,
440 (sc->sc_nulldma >> 16) & 0xffff); 440 (sc->sc_nulldma >> 16) & 0xffff);
441 tda16->tda_frags[seg].frag_ptr0 = 441 tda16->tda_frags[seg].frag_ptr0 =
442 htosonic16(sc, sc->sc_nulldma & 0xffff); 442 htosonic16(sc, sc->sc_nulldma & 0xffff);
443 tda16->tda_frags[seg].frag_size = 443 tda16->tda_frags[seg].frag_size =
444 htosonic16(sc, ETHER_PAD_LEN - totlen); 444 htosonic16(sc, ETHER_PAD_LEN - totlen);
445 totlen = ETHER_PAD_LEN; 445 totlen = ETHER_PAD_LEN;
446 seg++; 446 seg++;
447 } 447 }
448 448
449 tda16->tda_status = 0; 449 tda16->tda_status = 0;
450 tda16->tda_pktconfig = 0; 450 tda16->tda_pktconfig = 0;
451 tda16->tda_pktsize = htosonic16(sc, totlen); 451 tda16->tda_pktsize = htosonic16(sc, totlen);
452 tda16->tda_fragcnt = htosonic16(sc, seg); 452 tda16->tda_fragcnt = htosonic16(sc, seg);
453 453
454 /* Link it up. */ 454 /* Link it up. */
455 tda16->tda_frags[seg].frag_ptr0 = 455 tda16->tda_frags[seg].frag_ptr0 =
456 htosonic16(sc, SONIC_CDTXADDR16(sc, 456 htosonic16(sc, SONIC_CDTXADDR16(sc,
457 SONIC_NEXTTX(nexttx)) & 0xffff); 457 SONIC_NEXTTX(nexttx)) & 0xffff);
458 458
459 /* Sync the Tx descriptor. */ 459 /* Sync the Tx descriptor. */
460 SONIC_CDTXSYNC16(sc, nexttx, 460 SONIC_CDTXSYNC16(sc, nexttx,
461 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 461 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
462 } 462 }
463 463
464 /* Advance the Tx pointer. */ 464 /* Advance the Tx pointer. */
465 sc->sc_txpending++; 465 sc->sc_txpending++;
466 sc->sc_txlast = nexttx; 466 sc->sc_txlast = nexttx;
467 467
468 /* 468 /*
469 * Pass the packet to any BPF listeners. 469 * Pass the packet to any BPF listeners.
470 */ 470 */
471 bpf_mtap(ifp, m0, BPF_D_OUT); 471 bpf_mtap(ifp, m0, BPF_D_OUT);
472 } 472 }
473 473
474 if (sc->sc_txpending == (SONIC_NTXDESC - 1)) { 474 if (sc->sc_txpending == (SONIC_NTXDESC - 1)) {
475 /* No more slots left; notify upper layer. */ 475 /* No more slots left; notify upper layer. */
476 ifp->if_flags |= IFF_OACTIVE; 476 ifp->if_flags |= IFF_OACTIVE;
477 } 477 }
478 478
479 if (sc->sc_txpending != opending) { 479 if (sc->sc_txpending != opending) {
480 /* 480 /*
481 * We enqueued packets. If the transmitter was idle, 481 * We enqueued packets. If the transmitter was idle,
482 * reset the txdirty pointer. 482 * reset the txdirty pointer.
483 */ 483 */
484 if (opending == 0) 484 if (opending == 0)
485 sc->sc_txdirty = SONIC_NEXTTX(olasttx); 485 sc->sc_txdirty = SONIC_NEXTTX(olasttx);
486 486
487 /* 487 /*
488 * Stop the SONIC on the last packet we've set up, 488 * Stop the SONIC on the last packet we've set up,
489 * and clear end-of-list on the descriptor previous 489 * and clear end-of-list on the descriptor previous
490 * to our new chain. 490 * to our new chain.
491 * 491 *
492 * NOTE: our `seg' variable should still be valid! 492 * NOTE: our `seg' variable should still be valid!
493 */ 493 */
494 if (sc->sc_32bit) { 494 if (sc->sc_32bit) {
495 olseg = 495 olseg =
496 sonic32toh(sc, sc->sc_tda32[olasttx].tda_fragcnt); 496 sonic32toh(sc, sc->sc_tda32[olasttx].tda_fragcnt);
497 sc->sc_tda32[sc->sc_txlast].tda_frags[seg].frag_ptr0 |= 497 sc->sc_tda32[sc->sc_txlast].tda_frags[seg].frag_ptr0 |=
498 htosonic32(sc, TDA_LINK_EOL); 498 htosonic32(sc, TDA_LINK_EOL);
499 SONIC_CDTXSYNC32(sc, sc->sc_txlast, 499 SONIC_CDTXSYNC32(sc, sc->sc_txlast,
500 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 500 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
501 sc->sc_tda32[olasttx].tda_frags[olseg].frag_ptr0 &= 501 sc->sc_tda32[olasttx].tda_frags[olseg].frag_ptr0 &=
502 htosonic32(sc, ~TDA_LINK_EOL); 502 htosonic32(sc, ~TDA_LINK_EOL);
503 SONIC_CDTXSYNC32(sc, olasttx, 503 SONIC_CDTXSYNC32(sc, olasttx,
504 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 504 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
505 } else { 505 } else {
506 olseg = 506 olseg =
507 sonic16toh(sc, sc->sc_tda16[olasttx].tda_fragcnt); 507 sonic16toh(sc, sc->sc_tda16[olasttx].tda_fragcnt);
508 sc->sc_tda16[sc->sc_txlast].tda_frags[seg].frag_ptr0 |= 508 sc->sc_tda16[sc->sc_txlast].tda_frags[seg].frag_ptr0 |=
509 htosonic16(sc, TDA_LINK_EOL); 509 htosonic16(sc, TDA_LINK_EOL);
510 SONIC_CDTXSYNC16(sc, sc->sc_txlast, 510 SONIC_CDTXSYNC16(sc, sc->sc_txlast,
511 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 511 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
512 sc->sc_tda16[olasttx].tda_frags[olseg].frag_ptr0 &= 512 sc->sc_tda16[olasttx].tda_frags[olseg].frag_ptr0 &=
513 htosonic16(sc, ~TDA_LINK_EOL); 513 htosonic16(sc, ~TDA_LINK_EOL);
514 SONIC_CDTXSYNC16(sc, olasttx, 514 SONIC_CDTXSYNC16(sc, olasttx,
515 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 515 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
516 } 516 }
517 517
518 /* Start the transmitter. */ 518 /* Start the transmitter. */
519 CSR_WRITE(sc, SONIC_CR, CR_TXP); 519 CSR_WRITE(sc, SONIC_CR, CR_TXP);
520 520
521 /* Set a watchdog timer in case the chip flakes out. */ 521 /* Set a watchdog timer in case the chip flakes out. */
522 ifp->if_timer = 5; 522 ifp->if_timer = 5;
523 } 523 }
524} 524}
525 525
526/* 526/*
527 * sonic_watchdog: [ifnet interface function] 527 * sonic_watchdog: [ifnet interface function]
528 * 528 *
529 * Watchdog timer handler. 529 * Watchdog timer handler.
530 */ 530 */
531void 531void
532sonic_watchdog(struct ifnet *ifp) 532sonic_watchdog(struct ifnet *ifp)
533{ 533{
534 struct sonic_softc *sc = ifp->if_softc; 534 struct sonic_softc *sc = ifp->if_softc;
535 535
536 printf("%s: device timeout\n", device_xname(sc->sc_dev)); 536 printf("%s: device timeout\n", device_xname(sc->sc_dev));
537 ifp->if_oerrors++; 537 if_statinc(ifp, if_oerrors);
538 538
539 (void)sonic_init(ifp); 539 (void)sonic_init(ifp);
540} 540}
541 541
542/* 542/*
543 * sonic_ioctl: [ifnet interface function] 543 * sonic_ioctl: [ifnet interface function]
544 * 544 *
545 * Handle control requests from the operator. 545 * Handle control requests from the operator.
546 */ 546 */
547int 547int
548sonic_ioctl(struct ifnet *ifp, u_long cmd, void *data) 548sonic_ioctl(struct ifnet *ifp, u_long cmd, void *data)
549{ 549{
550 int s, error; 550 int s, error;
551 551
552 s = splnet(); 552 s = splnet();
553 553
554 error = ether_ioctl(ifp, cmd, data); 554 error = ether_ioctl(ifp, cmd, data);
555 if (error == ENETRESET) { 555 if (error == ENETRESET) {
556 /* 556 /*
557 * Multicast list has changed; set the hardware 557 * Multicast list has changed; set the hardware
558 * filter accordingly. 558 * filter accordingly.
559 */ 559 */
560 if (ifp->if_flags & IFF_RUNNING) 560 if (ifp->if_flags & IFF_RUNNING)
561 (void)sonic_init(ifp); 561 (void)sonic_init(ifp);
562 error = 0; 562 error = 0;
563 } 563 }
564 564
565 splx(s); 565 splx(s);
566 return error; 566 return error;
567} 567}
568 568
569/* 569/*
570 * sonic_intr: 570 * sonic_intr:
571 * 571 *
572 * Interrupt service routine. 572 * Interrupt service routine.
573 */ 573 */
574int 574int
575sonic_intr(void *arg) 575sonic_intr(void *arg)
576{ 576{
577 struct sonic_softc *sc = arg; 577 struct sonic_softc *sc = arg;
578 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 578 struct ifnet *ifp = &sc->sc_ethercom.ec_if;
579 uint16_t isr; 579 uint16_t isr;
580 int handled = 0, wantinit; 580 int handled = 0, wantinit;
581 581
582 for (wantinit = 0; wantinit == 0;) { 582 for (wantinit = 0; wantinit == 0;) {
583 isr = CSR_READ(sc, SONIC_ISR) & sc->sc_imr; 583 isr = CSR_READ(sc, SONIC_ISR) & sc->sc_imr;
584 if (isr == 0) 584 if (isr == 0)
585 break; 585 break;
586 CSR_WRITE(sc, SONIC_ISR, isr); /* ACK */ 586 CSR_WRITE(sc, SONIC_ISR, isr); /* ACK */
587 587
588 handled = 1; 588 handled = 1;
589 589
590 if (isr & IMR_PRX) 590 if (isr & IMR_PRX)
591 sonic_rxintr(sc); 591 sonic_rxintr(sc);
592 592
593 if (isr & (IMR_PTX | IMR_TXER)) { 593 if (isr & (IMR_PTX | IMR_TXER)) {
594 if (sonic_txintr(sc) & TCR_FU) { 594 if (sonic_txintr(sc) & TCR_FU) {
595 printf("%s: transmit FIFO underrun\n", 595 printf("%s: transmit FIFO underrun\n",
596 device_xname(sc->sc_dev)); 596 device_xname(sc->sc_dev));
597 wantinit = 1; 597 wantinit = 1;
598 } 598 }
599 } 599 }
600 600
601 if (isr & (IMR_RFO | IMR_RBA | IMR_RBE | IMR_RDE)) { 601 if (isr & (IMR_RFO | IMR_RBA | IMR_RBE | IMR_RDE)) {
602#define PRINTERR(bit, str) \ 602#define PRINTERR(bit, str) \
603 if (isr & (bit)) \ 603 if (isr & (bit)) \
604 printf("%s: %s\n",device_xname(sc->sc_dev), str) 604 printf("%s: %s\n",device_xname(sc->sc_dev), str)
605 PRINTERR(IMR_RFO, "receive FIFO overrun"); 605 PRINTERR(IMR_RFO, "receive FIFO overrun");
606 PRINTERR(IMR_RBA, "receive buffer exceeded"); 606 PRINTERR(IMR_RBA, "receive buffer exceeded");
607 PRINTERR(IMR_RBE, "receive buffers exhausted"); 607 PRINTERR(IMR_RBE, "receive buffers exhausted");
608 PRINTERR(IMR_RDE, "receive descriptors exhausted"); 608 PRINTERR(IMR_RDE, "receive descriptors exhausted");
609 wantinit = 1; 609 wantinit = 1;
610 } 610 }
611 } 611 }
612 612
613 if (handled) { 613 if (handled) {
614 if (wantinit) 614 if (wantinit)
615 (void)sonic_init(ifp); 615 (void)sonic_init(ifp);
616 if_schedule_deferred_start(ifp); 616 if_schedule_deferred_start(ifp);
617 } 617 }
618 618
619 return handled; 619 return handled;
620} 620}
621 621
622/* 622/*
623 * sonic_txintr: 623 * sonic_txintr:
624 * 624 *
625 * Helper; handle transmit complete interrupts. 625 * Helper; handle transmit complete interrupts.
626 */ 626 */
627uint16_t 627uint16_t
628sonic_txintr(struct sonic_softc *sc) 628sonic_txintr(struct sonic_softc *sc)
629{ 629{
630 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 630 struct ifnet *ifp = &sc->sc_ethercom.ec_if;
631 struct sonic_descsoft *ds; 631 struct sonic_descsoft *ds;
632 struct sonic_tda32 *tda32; 632 struct sonic_tda32 *tda32;
633 struct sonic_tda16 *tda16; 633 struct sonic_tda16 *tda16;
634 uint16_t status, totstat = 0; 634 uint16_t status, totstat = 0;
635 int i; 635 int i;
636 636
637 ifp->if_flags &= ~IFF_OACTIVE; 637 ifp->if_flags &= ~IFF_OACTIVE;
638 638
639 for (i = sc->sc_txdirty; sc->sc_txpending != 0; 639 for (i = sc->sc_txdirty; sc->sc_txpending != 0;
640 i = SONIC_NEXTTX(i), sc->sc_txpending--) { 640 i = SONIC_NEXTTX(i), sc->sc_txpending--) {
641 ds = &sc->sc_txsoft[i]; 641 ds = &sc->sc_txsoft[i];
642 642
643 if (sc->sc_32bit) { 643 if (sc->sc_32bit) {
644 SONIC_CDTXSYNC32(sc, i, 644 SONIC_CDTXSYNC32(sc, i,
645 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); 645 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
646 tda32 = &sc->sc_tda32[i]; 646 tda32 = &sc->sc_tda32[i];
647 status = sonic32toh(sc, tda32->tda_status); 647 status = sonic32toh(sc, tda32->tda_status);
648 SONIC_CDTXSYNC32(sc, i, BUS_DMASYNC_PREREAD); 648 SONIC_CDTXSYNC32(sc, i, BUS_DMASYNC_PREREAD);
649 } else { 649 } else {
650 SONIC_CDTXSYNC16(sc, i, 650 SONIC_CDTXSYNC16(sc, i,
651 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); 651 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
652 tda16 = &sc->sc_tda16[i]; 652 tda16 = &sc->sc_tda16[i];
653 status = sonic16toh(sc, tda16->tda_status); 653 status = sonic16toh(sc, tda16->tda_status);
654 SONIC_CDTXSYNC16(sc, i, BUS_DMASYNC_PREREAD); 654 SONIC_CDTXSYNC16(sc, i, BUS_DMASYNC_PREREAD);
655 } 655 }
656 656
657 if ((status & ~(TCR_EXDIS |TCR_CRCI |TCR_POWC |TCR_PINT)) == 0) 657 if ((status & ~(TCR_EXDIS |TCR_CRCI |TCR_POWC |TCR_PINT)) == 0)
658 break; 658 break;
659 659
660 totstat |= status; 660 totstat |= status;
661 661
662 bus_dmamap_sync(sc->sc_dmat, ds->ds_dmamap, 0, 662 bus_dmamap_sync(sc->sc_dmat, ds->ds_dmamap, 0,
663 ds->ds_dmamap->dm_mapsize, BUS_DMASYNC_POSTWRITE); 663 ds->ds_dmamap->dm_mapsize, BUS_DMASYNC_POSTWRITE);
664 bus_dmamap_unload(sc->sc_dmat, ds->ds_dmamap); 664 bus_dmamap_unload(sc->sc_dmat, ds->ds_dmamap);
665 m_freem(ds->ds_mbuf); 665 m_freem(ds->ds_mbuf);
666 ds->ds_mbuf = NULL; 666 ds->ds_mbuf = NULL;
667 667
668 /* 668 /*
669 * Check for errors and collisions. 669 * Check for errors and collisions.
670 */ 670 */
 671 net_stat_ref_t nsr = IF_STAT_GETREF(ifp);
671 if (status & TCR_PTX) 672 if (status & TCR_PTX)
672 ifp->if_opackets++; 673 if_statinc_ref(nsr, if_opackets);
673 else 674 else
674 ifp->if_oerrors++; 675 if_statinc_ref(nsr, if_oerrors);
675 ifp->if_collisions += TDA_STATUS_NCOL(status); 676 if (TDA_STATUS_NCOL(status))
 677 if_statadd_ref(nsr, if_collisions,
 678 TDA_STATUS_NCOL(status));
 679 IF_STAT_PUTREF(ifp);
676 } 680 }
677 681
678 /* Update the dirty transmit buffer pointer. */ 682 /* Update the dirty transmit buffer pointer. */
679 sc->sc_txdirty = i; 683 sc->sc_txdirty = i;
680 684
681 /* 685 /*
682 * Cancel the watchdog timer if there are no pending 686 * Cancel the watchdog timer if there are no pending
683 * transmissions. 687 * transmissions.
684 */ 688 */
685 if (sc->sc_txpending == 0) 689 if (sc->sc_txpending == 0)
686 ifp->if_timer = 0; 690 ifp->if_timer = 0;
687 691
688 return totstat; 692 return totstat;
689} 693}
690 694
691/* 695/*
692 * sonic_rxintr: 696 * sonic_rxintr:
693 * 697 *
694 * Helper; handle receive interrupts. 698 * Helper; handle receive interrupts.
695 */ 699 */
696void 700void
697sonic_rxintr(struct sonic_softc *sc) 701sonic_rxintr(struct sonic_softc *sc)
698{ 702{
699 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 703 struct ifnet *ifp = &sc->sc_ethercom.ec_if;
700 struct sonic_descsoft *ds; 704 struct sonic_descsoft *ds;
701 struct sonic_rda32 *rda32; 705 struct sonic_rda32 *rda32;
702 struct sonic_rda16 *rda16; 706 struct sonic_rda16 *rda16;
703 struct mbuf *m; 707 struct mbuf *m;
704 int i, len; 708 int i, len;
705 uint16_t status, bytecount /*, ptr0, ptr1, seqno */; 709 uint16_t status, bytecount /*, ptr0, ptr1, seqno */;
706 710
707 for (i = sc->sc_rxptr;; i = SONIC_NEXTRX(i)) { 711 for (i = sc->sc_rxptr;; i = SONIC_NEXTRX(i)) {
708 ds = &sc->sc_rxsoft[i]; 712 ds = &sc->sc_rxsoft[i];
709 713
710 if (sc->sc_32bit) { 714 if (sc->sc_32bit) {
711 SONIC_CDRXSYNC32(sc, i, 715 SONIC_CDRXSYNC32(sc, i,
712 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); 716 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
713 rda32 = &sc->sc_rda32[i]; 717 rda32 = &sc->sc_rda32[i];
714 SONIC_CDRXSYNC32(sc, i, BUS_DMASYNC_PREREAD); 718 SONIC_CDRXSYNC32(sc, i, BUS_DMASYNC_PREREAD);
715 if (rda32->rda_inuse != 0) 719 if (rda32->rda_inuse != 0)
716 break; 720 break;
717 status = sonic32toh(sc, rda32->rda_status); 721 status = sonic32toh(sc, rda32->rda_status);
718 bytecount = sonic32toh(sc, rda32->rda_bytecount); 722 bytecount = sonic32toh(sc, rda32->rda_bytecount);
719 /* ptr0 = sonic32toh(sc, rda32->rda_pkt_ptr0); */ 723 /* ptr0 = sonic32toh(sc, rda32->rda_pkt_ptr0); */
720 /* ptr1 = sonic32toh(sc, rda32->rda_pkt_ptr1); */ 724 /* ptr1 = sonic32toh(sc, rda32->rda_pkt_ptr1); */
721 /* seqno = sonic32toh(sc, rda32->rda_seqno); */ 725 /* seqno = sonic32toh(sc, rda32->rda_seqno); */
722 } else { 726 } else {
723 SONIC_CDRXSYNC16(sc, i, 727 SONIC_CDRXSYNC16(sc, i,
724 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); 728 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
725 rda16 = &sc->sc_rda16[i]; 729 rda16 = &sc->sc_rda16[i];
726 SONIC_CDRXSYNC16(sc, i, BUS_DMASYNC_PREREAD); 730 SONIC_CDRXSYNC16(sc, i, BUS_DMASYNC_PREREAD);
727 if (rda16->rda_inuse != 0) 731 if (rda16->rda_inuse != 0)
728 break; 732 break;
729 status = sonic16toh(sc, rda16->rda_status); 733 status = sonic16toh(sc, rda16->rda_status);
730 bytecount = sonic16toh(sc, rda16->rda_bytecount); 734 bytecount = sonic16toh(sc, rda16->rda_bytecount);
731 /* ptr0 = sonic16toh(sc, rda16->rda_pkt_ptr0); */ 735 /* ptr0 = sonic16toh(sc, rda16->rda_pkt_ptr0); */
732 /* ptr1 = sonic16toh(sc, rda16->rda_pkt_ptr1); */ 736 /* ptr1 = sonic16toh(sc, rda16->rda_pkt_ptr1); */
733 /* seqno = sonic16toh(sc, rda16->rda_seqno); */ 737 /* seqno = sonic16toh(sc, rda16->rda_seqno); */
734 } 738 }
735 739
736 /* 740 /*
737 * Make absolutely sure this is the only packet 741 * Make absolutely sure this is the only packet
738 * in this receive buffer. Our entire Rx buffer 742 * in this receive buffer. Our entire Rx buffer
739 * management scheme depends on this, and if the 743 * management scheme depends on this, and if the
740 * SONIC didn't follow our rule, it means we've 744 * SONIC didn't follow our rule, it means we've
741 * misconfigured it. 745 * misconfigured it.
742 */ 746 */
743 KASSERT(status & RCR_LPKT); 747 KASSERT(status & RCR_LPKT);
744 748
745 /* 749 /*
746 * Make sure the packet arrived OK. If an error occurred, 750 * Make sure the packet arrived OK. If an error occurred,
747 * update stats and reset the descriptor. The buffer will 751 * update stats and reset the descriptor. The buffer will
748 * be reused the next time the descriptor comes up in the 752 * be reused the next time the descriptor comes up in the
749 * ring. 753 * ring.
750 */ 754 */
751 if ((status & RCR_PRX) == 0) { 755 if ((status & RCR_PRX) == 0) {
752 if (status & RCR_FAER) 756 if (status & RCR_FAER)
753 printf("%s: Rx frame alignment error\n", 757 printf("%s: Rx frame alignment error\n",
754 device_xname(sc->sc_dev)); 758 device_xname(sc->sc_dev));
755 else if (status & RCR_CRCR) 759 else if (status & RCR_CRCR)
756 printf("%s: Rx CRC error\n", 760 printf("%s: Rx CRC error\n",
757 device_xname(sc->sc_dev)); 761 device_xname(sc->sc_dev));
758 ifp->if_ierrors++; 762 if_statinc(ifp, if_ierrors);
759 SONIC_INIT_RXDESC(sc, i); 763 SONIC_INIT_RXDESC(sc, i);
760 continue; 764 continue;
761 } 765 }
762 766
763 bus_dmamap_sync(sc->sc_dmat, ds->ds_dmamap, 0, 767 bus_dmamap_sync(sc->sc_dmat, ds->ds_dmamap, 0,
764 ds->ds_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD); 768 ds->ds_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD);
765 769
766 /* 770 /*
767 * The SONIC includes the CRC with every packet. 771 * The SONIC includes the CRC with every packet.
768 */ 772 */
769 len = bytecount - ETHER_CRC_LEN; 773 len = bytecount - ETHER_CRC_LEN;
770 774
771 /* 775 /*
772 * Ok, if the chip is in 32-bit mode, then receive 776 * Ok, if the chip is in 32-bit mode, then receive
773 * buffers must be aligned to 32-bit boundaries, 777 * buffers must be aligned to 32-bit boundaries,
774 * which means the payload is misaligned. In this 778 * which means the payload is misaligned. In this
775 * case, we must allocate a new mbuf, and copy the 779 * case, we must allocate a new mbuf, and copy the
776 * packet into it, scooted forward 2 bytes to ensure 780 * packet into it, scooted forward 2 bytes to ensure
777 * proper alignment. 781 * proper alignment.
778 * 782 *
779 * Note, in 16-bit mode, we can configure the SONIC 783 * Note, in 16-bit mode, we can configure the SONIC
780 * to do what we want, and we have. 784 * to do what we want, and we have.
781 */ 785 */
782#ifndef __NO_STRICT_ALIGNMENT 786#ifndef __NO_STRICT_ALIGNMENT
783 if (sc->sc_32bit) { 787 if (sc->sc_32bit) {
784 MGETHDR(m, M_DONTWAIT, MT_DATA); 788 MGETHDR(m, M_DONTWAIT, MT_DATA);
785 if (m == NULL) 789 if (m == NULL)
786 goto dropit; 790 goto dropit;
787 if (len > (MHLEN - 2)) { 791 if (len > (MHLEN - 2)) {
788 MCLGET(m, M_DONTWAIT); 792 MCLGET(m, M_DONTWAIT);
789 if ((m->m_flags & M_EXT) == 0) { 793 if ((m->m_flags & M_EXT) == 0) {
790 m_freem(m); 794 m_freem(m);
791 goto dropit; 795 goto dropit;
792 } 796 }
793 } 797 }
794 m->m_data += 2; 798 m->m_data += 2;
795 /* 799 /*
796 * Note that we use a cluster for incoming frames, 800 * Note that we use a cluster for incoming frames,
797 * so the buffer is virtually contiguous. 801 * so the buffer is virtually contiguous.
798 */ 802 */
799 memcpy(mtod(m, void *), mtod(ds->ds_mbuf, void *), 803 memcpy(mtod(m, void *), mtod(ds->ds_mbuf, void *),
800 len); 804 len);
801 SONIC_INIT_RXDESC(sc, i); 805 SONIC_INIT_RXDESC(sc, i);
802 bus_dmamap_sync(sc->sc_dmat, ds->ds_dmamap, 0, 806 bus_dmamap_sync(sc->sc_dmat, ds->ds_dmamap, 0,
803 ds->ds_dmamap->dm_mapsize, BUS_DMASYNC_PREREAD); 807 ds->ds_dmamap->dm_mapsize, BUS_DMASYNC_PREREAD);
804 } else 808 } else
805#endif /* ! __NO_STRICT_ALIGNMENT */ 809#endif /* ! __NO_STRICT_ALIGNMENT */
806 /* 810 /*
807 * If the packet is small enough to fit in a single 811 * If the packet is small enough to fit in a single
808 * header mbuf, allocate one and copy the data into 812 * header mbuf, allocate one and copy the data into
809 * it. This greatly reduces memory consumption when 813 * it. This greatly reduces memory consumption when
810 * we receive lots of small packets. 814 * we receive lots of small packets.
811 */ 815 */
812 if (sonic_copy_small != 0 && len <= (MHLEN - 2)) { 816 if (sonic_copy_small != 0 && len <= (MHLEN - 2)) {
813 MGETHDR(m, M_DONTWAIT, MT_DATA); 817 MGETHDR(m, M_DONTWAIT, MT_DATA);
814 if (m == NULL) 818 if (m == NULL)
815 goto dropit; 819 goto dropit;
816 m->m_data += 2; 820 m->m_data += 2;
817 /* 821 /*
818 * Note that we use a cluster for incoming frames, 822 * Note that we use a cluster for incoming frames,
819 * so the buffer is virtually contiguous. 823 * so the buffer is virtually contiguous.
820 */ 824 */
821 memcpy(mtod(m, void *), mtod(ds->ds_mbuf, void *), 825 memcpy(mtod(m, void *), mtod(ds->ds_mbuf, void *),
822 len); 826 len);
823 SONIC_INIT_RXDESC(sc, i); 827 SONIC_INIT_RXDESC(sc, i);
824 bus_dmamap_sync(sc->sc_dmat, ds->ds_dmamap, 0, 828 bus_dmamap_sync(sc->sc_dmat, ds->ds_dmamap, 0,
825 ds->ds_dmamap->dm_mapsize, BUS_DMASYNC_PREREAD); 829 ds->ds_dmamap->dm_mapsize, BUS_DMASYNC_PREREAD);
826 } else { 830 } else {
827 m = ds->ds_mbuf; 831 m = ds->ds_mbuf;
828 if (sonic_add_rxbuf(sc, i) != 0) { 832 if (sonic_add_rxbuf(sc, i) != 0) {
829 dropit: 833 dropit:
830 ifp->if_ierrors++; 834 if_statinc(ifp, if_ierrors);
831 SONIC_INIT_RXDESC(sc, i); 835 SONIC_INIT_RXDESC(sc, i);
832 bus_dmamap_sync(sc->sc_dmat, ds->ds_dmamap, 0, 836 bus_dmamap_sync(sc->sc_dmat, ds->ds_dmamap, 0,
833 ds->ds_dmamap->dm_mapsize, 837 ds->ds_dmamap->dm_mapsize,
834 BUS_DMASYNC_PREREAD); 838 BUS_DMASYNC_PREREAD);
835 continue; 839 continue;
836 } 840 }
837 } 841 }
838 842
839 m_set_rcvif(m, ifp); 843 m_set_rcvif(m, ifp);
840 m->m_pkthdr.len = m->m_len = len; 844 m->m_pkthdr.len = m->m_len = len;
841 845
842 /* Pass it on. */ 846 /* Pass it on. */
843 if_percpuq_enqueue(ifp->if_percpuq, m); 847 if_percpuq_enqueue(ifp->if_percpuq, m);
844 } 848 }
845 849
846 /* Update the receive pointer. */ 850 /* Update the receive pointer. */
847 sc->sc_rxptr = i; 851 sc->sc_rxptr = i;
848 CSR_WRITE(sc, SONIC_RWR, SONIC_CDRRADDR(sc, SONIC_PREVRX(i))); 852 CSR_WRITE(sc, SONIC_RWR, SONIC_CDRRADDR(sc, SONIC_PREVRX(i)));
849} 853}
850 854
851/* 855/*
852 * sonic_reset: 856 * sonic_reset:
853 * 857 *
854 * Perform a soft reset on the SONIC. 858 * Perform a soft reset on the SONIC.
855 */ 859 */
856void 860void
857sonic_reset(struct sonic_softc *sc) 861sonic_reset(struct sonic_softc *sc)
858{ 862{
859 863
860 /* stop TX, RX and timer, and ensure RST is clear */ 864 /* stop TX, RX and timer, and ensure RST is clear */
861 CSR_WRITE(sc, SONIC_CR, CR_STP | CR_RXDIS | CR_HTX); 865 CSR_WRITE(sc, SONIC_CR, CR_STP | CR_RXDIS | CR_HTX);
862 delay(1000); 866 delay(1000);
863 867
864 CSR_WRITE(sc, SONIC_CR, CR_RST); 868 CSR_WRITE(sc, SONIC_CR, CR_RST);
865 delay(1000); 869 delay(1000);
866 870
867 /* clear all interrupts */ 871 /* clear all interrupts */
868 CSR_WRITE(sc, SONIC_IMR, 0); 872 CSR_WRITE(sc, SONIC_IMR, 0);
869 CSR_WRITE(sc, SONIC_ISR, IMR_ALL); 873 CSR_WRITE(sc, SONIC_ISR, IMR_ALL);
870 874
871 CSR_WRITE(sc, SONIC_CR, 0); 875 CSR_WRITE(sc, SONIC_CR, 0);
872 delay(1000); 876 delay(1000);
873} 877}
874 878
875/* 879/*
876 * sonic_init: [ifnet interface function] 880 * sonic_init: [ifnet interface function]
877 * 881 *
878 * Initialize the interface. Must be called at splnet(). 882 * Initialize the interface. Must be called at splnet().
879 */ 883 */
880int 884int
881sonic_init(struct ifnet *ifp) 885sonic_init(struct ifnet *ifp)
882{ 886{
883 struct sonic_softc *sc = ifp->if_softc; 887 struct sonic_softc *sc = ifp->if_softc;
884 struct sonic_descsoft *ds; 888 struct sonic_descsoft *ds;
885 int i, error = 0; 889 int i, error = 0;
886 uint16_t reg; 890 uint16_t reg;
887 891
888 /* 892 /*
889 * Cancel any pending I/O. 893 * Cancel any pending I/O.
890 */ 894 */
891 sonic_stop(ifp, 0); 895 sonic_stop(ifp, 0);
892 896
893 /* 897 /*
894 * Reset the SONIC to a known state. 898 * Reset the SONIC to a known state.
895 */ 899 */
896 sonic_reset(sc); 900 sonic_reset(sc);
897 901
898 /* 902 /*
899 * Bring the SONIC into reset state, and program the DCR. 903 * Bring the SONIC into reset state, and program the DCR.
900 * 904 *
901 * Note: We don't bother optimizing the transmit and receive 905 * Note: We don't bother optimizing the transmit and receive
902 * thresholds, here. TFT/RFT values should be set in MD attachments. 906 * thresholds, here. TFT/RFT values should be set in MD attachments.
903 */ 907 */
904 reg = sc->sc_dcr; 908 reg = sc->sc_dcr;
905 if (sc->sc_32bit) 909 if (sc->sc_32bit)
906 reg |= DCR_DW; 910 reg |= DCR_DW;
907 CSR_WRITE(sc, SONIC_CR, CR_RST); 911 CSR_WRITE(sc, SONIC_CR, CR_RST);
908 CSR_WRITE(sc, SONIC_DCR, reg); 912 CSR_WRITE(sc, SONIC_DCR, reg);
909 CSR_WRITE(sc, SONIC_DCR2, sc->sc_dcr2); 913 CSR_WRITE(sc, SONIC_DCR2, sc->sc_dcr2);
910 CSR_WRITE(sc, SONIC_CR, 0); 914 CSR_WRITE(sc, SONIC_CR, 0);
911 915
912 /* 916 /*
913 * Initialize the transmit descriptors. 917 * Initialize the transmit descriptors.
914 */ 918 */
915 if (sc->sc_32bit) { 919 if (sc->sc_32bit) {
916 for (i = 0; i < SONIC_NTXDESC; i++) { 920 for (i = 0; i < SONIC_NTXDESC; i++) {
917 memset(&sc->sc_tda32[i], 0, sizeof(struct sonic_tda32)); 921 memset(&sc->sc_tda32[i], 0, sizeof(struct sonic_tda32));
918 SONIC_CDTXSYNC32(sc, i, 922 SONIC_CDTXSYNC32(sc, i,
919 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 923 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
920 } 924 }
921 } else { 925 } else {
922 for (i = 0; i < SONIC_NTXDESC; i++) { 926 for (i = 0; i < SONIC_NTXDESC; i++) {
923 memset(&sc->sc_tda16[i], 0, sizeof(struct sonic_tda16)); 927 memset(&sc->sc_tda16[i], 0, sizeof(struct sonic_tda16));
924 SONIC_CDTXSYNC16(sc, i, 928 SONIC_CDTXSYNC16(sc, i,
925 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 929 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
926 } 930 }
927 } 931 }
928 sc->sc_txpending = 0; 932 sc->sc_txpending = 0;
929 sc->sc_txdirty = 0; 933 sc->sc_txdirty = 0;
930 sc->sc_txlast = SONIC_NTXDESC - 1; 934 sc->sc_txlast = SONIC_NTXDESC - 1;
931 935
932 /* 936 /*
933 * Initialize the receive descriptor ring. 937 * Initialize the receive descriptor ring.
934 */ 938 */
935 for (i = 0; i < SONIC_NRXDESC; i++) { 939 for (i = 0; i < SONIC_NRXDESC; i++) {
936 ds = &sc->sc_rxsoft[i]; 940 ds = &sc->sc_rxsoft[i];
937 if (ds->ds_mbuf == NULL) { 941 if (ds->ds_mbuf == NULL) {
938 if ((error = sonic_add_rxbuf(sc, i)) != 0) { 942 if ((error = sonic_add_rxbuf(sc, i)) != 0) {
939 printf("%s: unable to allocate or map Rx " 943 printf("%s: unable to allocate or map Rx "
940 "buffer %d, error = %d\n", 944 "buffer %d, error = %d\n",
941 device_xname(sc->sc_dev), i, error); 945 device_xname(sc->sc_dev), i, error);
942 /* 946 /*
943 * XXX Should attempt to run with fewer receive 947 * XXX Should attempt to run with fewer receive
944 * XXX buffers instead of just failing. 948 * XXX buffers instead of just failing.
945 */ 949 */
946 sonic_rxdrain(sc); 950 sonic_rxdrain(sc);
947 goto out; 951 goto out;
948 } 952 }
949 } else 953 } else
950 SONIC_INIT_RXDESC(sc, i); 954 SONIC_INIT_RXDESC(sc, i);
951 } 955 }
952 sc->sc_rxptr = 0; 956 sc->sc_rxptr = 0;
953 957
954 /* Give the transmit ring to the SONIC. */ 958 /* Give the transmit ring to the SONIC. */
955 CSR_WRITE(sc, SONIC_UTDAR, (SONIC_CDTXADDR(sc, 0) >> 16) & 0xffff); 959 CSR_WRITE(sc, SONIC_UTDAR, (SONIC_CDTXADDR(sc, 0) >> 16) & 0xffff);
956 CSR_WRITE(sc, SONIC_CTDAR, SONIC_CDTXADDR(sc, 0) & 0xffff); 960 CSR_WRITE(sc, SONIC_CTDAR, SONIC_CDTXADDR(sc, 0) & 0xffff);
957 961
958 /* Give the receive descriptor ring to the SONIC. */ 962 /* Give the receive descriptor ring to the SONIC. */
959 CSR_WRITE(sc, SONIC_URDAR, (SONIC_CDRXADDR(sc, 0) >> 16) & 0xffff); 963 CSR_WRITE(sc, SONIC_URDAR, (SONIC_CDRXADDR(sc, 0) >> 16) & 0xffff);
960 CSR_WRITE(sc, SONIC_CRDAR, SONIC_CDRXADDR(sc, 0) & 0xffff); 964 CSR_WRITE(sc, SONIC_CRDAR, SONIC_CDRXADDR(sc, 0) & 0xffff);
961 965
962 /* Give the receive buffer ring to the SONIC. */ 966 /* Give the receive buffer ring to the SONIC. */
963 CSR_WRITE(sc, SONIC_URRAR, (SONIC_CDRRADDR(sc, 0) >> 16) & 0xffff); 967 CSR_WRITE(sc, SONIC_URRAR, (SONIC_CDRRADDR(sc, 0) >> 16) & 0xffff);
964 CSR_WRITE(sc, SONIC_RSAR, SONIC_CDRRADDR(sc, 0) & 0xffff); 968 CSR_WRITE(sc, SONIC_RSAR, SONIC_CDRRADDR(sc, 0) & 0xffff);
965 if (sc->sc_32bit) 969 if (sc->sc_32bit)
966 CSR_WRITE(sc, SONIC_REAR, 970 CSR_WRITE(sc, SONIC_REAR,
967 (SONIC_CDRRADDR(sc, SONIC_NRXDESC - 1) + 971 (SONIC_CDRRADDR(sc, SONIC_NRXDESC - 1) +
968 sizeof(struct sonic_rra32)) & 0xffff); 972 sizeof(struct sonic_rra32)) & 0xffff);
969 else 973 else
970 CSR_WRITE(sc, SONIC_REAR, 974 CSR_WRITE(sc, SONIC_REAR,
971 (SONIC_CDRRADDR(sc, SONIC_NRXDESC - 1) + 975 (SONIC_CDRRADDR(sc, SONIC_NRXDESC - 1) +
972 sizeof(struct sonic_rra16)) & 0xffff); 976 sizeof(struct sonic_rra16)) & 0xffff);
973 CSR_WRITE(sc, SONIC_RRR, SONIC_CDRRADDR(sc, 0) & 0xffff); 977 CSR_WRITE(sc, SONIC_RRR, SONIC_CDRRADDR(sc, 0) & 0xffff);
974 CSR_WRITE(sc, SONIC_RWR, SONIC_CDRRADDR(sc, SONIC_NRXDESC - 1)); 978 CSR_WRITE(sc, SONIC_RWR, SONIC_CDRRADDR(sc, SONIC_NRXDESC - 1));
975 979
976 /* 980 /*
977 * Set the End-Of-Buffer counter such that only one packet 981 * Set the End-Of-Buffer counter such that only one packet
978 * will be placed into each buffer we provide. Note we are 982 * will be placed into each buffer we provide. Note we are
979 * following the recommendation of section 3.4.4 of the manual 983 * following the recommendation of section 3.4.4 of the manual
980 * here, and have "lengthened" the receive buffers accordingly. 984 * here, and have "lengthened" the receive buffers accordingly.
981 */ 985 */
982 if (sc->sc_32bit) 986 if (sc->sc_32bit)
983 CSR_WRITE(sc, SONIC_EOBC, (ETHER_MAX_LEN + 2) / 2); 987 CSR_WRITE(sc, SONIC_EOBC, (ETHER_MAX_LEN + 2) / 2);
984 else 988 else
985 CSR_WRITE(sc, SONIC_EOBC, (ETHER_MAX_LEN / 2)); 989 CSR_WRITE(sc, SONIC_EOBC, (ETHER_MAX_LEN / 2));
986 990
987 /* Reset the receive sequence counter. */ 991 /* Reset the receive sequence counter. */
988 CSR_WRITE(sc, SONIC_RSC, 0); 992 CSR_WRITE(sc, SONIC_RSC, 0);
989 993
990 /* Clear the tally registers. */ 994 /* Clear the tally registers. */
991 CSR_WRITE(sc, SONIC_CRCETC, 0xffff); 995 CSR_WRITE(sc, SONIC_CRCETC, 0xffff);
992 CSR_WRITE(sc, SONIC_FAET, 0xffff); 996 CSR_WRITE(sc, SONIC_FAET, 0xffff);
993 CSR_WRITE(sc, SONIC_MPT, 0xffff); 997 CSR_WRITE(sc, SONIC_MPT, 0xffff);
994 998
995 /* Set the receive filter. */ 999 /* Set the receive filter. */
996 sonic_set_filter(sc); 1000 sonic_set_filter(sc);
997 1001
998 /* 1002 /*
999 * Set the interrupt mask register. 1003 * Set the interrupt mask register.
1000 */ 1004 */
1001 sc->sc_imr = IMR_RFO | IMR_RBA | IMR_RBE | IMR_RDE | 1005 sc->sc_imr = IMR_RFO | IMR_RBA | IMR_RBE | IMR_RDE |
1002 IMR_TXER | IMR_PTX | IMR_PRX; 1006 IMR_TXER | IMR_PTX | IMR_PRX;
1003 CSR_WRITE(sc, SONIC_IMR, sc->sc_imr); 1007 CSR_WRITE(sc, SONIC_IMR, sc->sc_imr);
1004 1008
1005 /* 1009 /*
1006 * Start the receive process in motion. Note, we don't 1010 * Start the receive process in motion. Note, we don't
1007 * start the transmit process until we actually try to 1011 * start the transmit process until we actually try to
1008 * transmit packets. 1012 * transmit packets.
1009 */ 1013 */
1010 CSR_WRITE(sc, SONIC_CR, CR_RXEN | CR_RRRA); 1014 CSR_WRITE(sc, SONIC_CR, CR_RXEN | CR_RRRA);
1011 1015
1012 /* 1016 /*
1013 * ...all done! 1017 * ...all done!
1014 */ 1018 */
1015 ifp->if_flags |= IFF_RUNNING; 1019 ifp->if_flags |= IFF_RUNNING;
1016 ifp->if_flags &= ~IFF_OACTIVE; 1020 ifp->if_flags &= ~IFF_OACTIVE;
1017 1021
1018 out: 1022 out:
1019 if (error) 1023 if (error)
1020 printf("%s: interface not running\n", device_xname(sc->sc_dev)); 1024 printf("%s: interface not running\n", device_xname(sc->sc_dev));
1021 return error; 1025 return error;
1022} 1026}
1023 1027
1024/* 1028/*
1025 * sonic_rxdrain: 1029 * sonic_rxdrain:
1026 * 1030 *
1027 * Drain the receive queue. 1031 * Drain the receive queue.
1028 */ 1032 */
1029void 1033void
1030sonic_rxdrain(struct sonic_softc *sc) 1034sonic_rxdrain(struct sonic_softc *sc)
1031{ 1035{
1032 struct sonic_descsoft *ds; 1036 struct sonic_descsoft *ds;
1033 int i; 1037 int i;
1034 1038
1035 for (i = 0; i < SONIC_NRXDESC; i++) { 1039 for (i = 0; i < SONIC_NRXDESC; i++) {
1036 ds = &sc->sc_rxsoft[i]; 1040 ds = &sc->sc_rxsoft[i];
1037 if (ds->ds_mbuf != NULL) { 1041 if (ds->ds_mbuf != NULL) {
1038 bus_dmamap_unload(sc->sc_dmat, ds->ds_dmamap); 1042 bus_dmamap_unload(sc->sc_dmat, ds->ds_dmamap);
1039 m_freem(ds->ds_mbuf); 1043 m_freem(ds->ds_mbuf);
1040 ds->ds_mbuf = NULL; 1044 ds->ds_mbuf = NULL;
1041 } 1045 }
1042 } 1046 }
1043} 1047}
1044 1048
1045/* 1049/*
1046 * sonic_stop: [ifnet interface function] 1050 * sonic_stop: [ifnet interface function]
1047 * 1051 *
1048 * Stop transmission on the interface. 1052 * Stop transmission on the interface.
1049 */ 1053 */
1050void 1054void
1051sonic_stop(struct ifnet *ifp, int disable) 1055sonic_stop(struct ifnet *ifp, int disable)
1052{ 1056{
1053 struct sonic_softc *sc = ifp->if_softc; 1057 struct sonic_softc *sc = ifp->if_softc;
1054 struct sonic_descsoft *ds; 1058 struct sonic_descsoft *ds;
1055 int i; 1059 int i;
1056 1060
1057 /* 1061 /*
1058 * Disable interrupts. 1062 * Disable interrupts.
1059 */ 1063 */
1060 CSR_WRITE(sc, SONIC_IMR, 0); 1064 CSR_WRITE(sc, SONIC_IMR, 0);
1061 1065
1062 /* 1066 /*
1063 * Stop the transmitter, receiver, and timer. 1067 * Stop the transmitter, receiver, and timer.
1064 */ 1068 */
1065 CSR_WRITE(sc, SONIC_CR, CR_HTX | CR_RXDIS | CR_STP); 1069 CSR_WRITE(sc, SONIC_CR, CR_HTX | CR_RXDIS | CR_STP);
1066 for (i = 0; i < 1000; i++) { 1070 for (i = 0; i < 1000; i++) {
1067 if ((CSR_READ(sc, SONIC_CR) & (CR_TXP | CR_RXEN | CR_ST)) == 0) 1071 if ((CSR_READ(sc, SONIC_CR) & (CR_TXP | CR_RXEN | CR_ST)) == 0)
1068 break; 1072 break;
1069 delay(2); 1073 delay(2);
1070 } 1074 }
1071 if ((CSR_READ(sc, SONIC_CR) & (CR_TXP | CR_RXEN | CR_ST)) != 0) 1075 if ((CSR_READ(sc, SONIC_CR) & (CR_TXP | CR_RXEN | CR_ST)) != 0)
1072 printf("%s: SONIC failed to stop\n", device_xname(sc->sc_dev)); 1076 printf("%s: SONIC failed to stop\n", device_xname(sc->sc_dev));
1073 1077
1074 /* 1078 /*
1075 * Release any queued transmit buffers. 1079 * Release any queued transmit buffers.
1076 */ 1080 */
1077 for (i = 0; i < SONIC_NTXDESC; i++) { 1081 for (i = 0; i < SONIC_NTXDESC; i++) {
1078 ds = &sc->sc_txsoft[i]; 1082 ds = &sc->sc_txsoft[i];
1079 if (ds->ds_mbuf != NULL) { 1083 if (ds->ds_mbuf != NULL) {
1080 bus_dmamap_unload(sc->sc_dmat, ds->ds_dmamap); 1084 bus_dmamap_unload(sc->sc_dmat, ds->ds_dmamap);
1081 m_freem(ds->ds_mbuf); 1085 m_freem(ds->ds_mbuf);
1082 ds->ds_mbuf = NULL; 1086 ds->ds_mbuf = NULL;
1083 } 1087 }
1084 } 1088 }
1085 1089
1086 /* 1090 /*
1087 * Mark the interface down and cancel the watchdog timer. 1091 * Mark the interface down and cancel the watchdog timer.
1088 */ 1092 */
1089 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 1093 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
1090 ifp->if_timer = 0; 1094 ifp->if_timer = 0;
1091 1095
1092 if (disable) 1096 if (disable)
1093 sonic_rxdrain(sc); 1097 sonic_rxdrain(sc);
1094} 1098}
1095 1099
1096/* 1100/*
1097 * sonic_add_rxbuf: 1101 * sonic_add_rxbuf:
1098 * 1102 *
1099 * Add a receive buffer to the indicated descriptor. 1103 * Add a receive buffer to the indicated descriptor.
1100 */ 1104 */
1101int 1105int
1102sonic_add_rxbuf(struct sonic_softc *sc, int idx) 1106sonic_add_rxbuf(struct sonic_softc *sc, int idx)
1103{ 1107{
1104 struct sonic_descsoft *ds = &sc->sc_rxsoft[idx]; 1108 struct sonic_descsoft *ds = &sc->sc_rxsoft[idx];
1105 struct mbuf *m; 1109 struct mbuf *m;
1106 int error; 1110 int error;
1107 1111
1108 MGETHDR(m, M_DONTWAIT, MT_DATA); 1112 MGETHDR(m, M_DONTWAIT, MT_DATA);
1109 if (m == NULL) 1113 if (m == NULL)
1110 return ENOBUFS; 1114 return ENOBUFS;
1111 1115
1112 MCLGET(m, M_DONTWAIT); 1116 MCLGET(m, M_DONTWAIT);
1113 if ((m->m_flags & M_EXT) == 0) { 1117 if ((m->m_flags & M_EXT) == 0) {
1114 m_freem(m); 1118 m_freem(m);
1115 return ENOBUFS; 1119 return ENOBUFS;
1116 } 1120 }
1117 1121
1118 if (ds->ds_mbuf != NULL) 1122 if (ds->ds_mbuf != NULL)
1119 bus_dmamap_unload(sc->sc_dmat, ds->ds_dmamap); 1123 bus_dmamap_unload(sc->sc_dmat, ds->ds_dmamap);
1120 1124
1121 ds->ds_mbuf = m; 1125 ds->ds_mbuf = m;
1122 1126
1123 error = bus_dmamap_load(sc->sc_dmat, ds->ds_dmamap, 1127 error = bus_dmamap_load(sc->sc_dmat, ds->ds_dmamap,
1124 m->m_ext.ext_buf, m->m_ext.ext_size, NULL, 1128 m->m_ext.ext_buf, m->m_ext.ext_size, NULL,
1125 BUS_DMA_READ | BUS_DMA_NOWAIT); 1129 BUS_DMA_READ | BUS_DMA_NOWAIT);
1126 if (error) { 1130 if (error) {
1127 printf("%s: can't load rx DMA map %d, error = %d\n", 1131 printf("%s: can't load rx DMA map %d, error = %d\n",
1128 device_xname(sc->sc_dev), idx, error); 1132 device_xname(sc->sc_dev), idx, error);
1129 panic("sonic_add_rxbuf"); /* XXX */ 1133 panic("sonic_add_rxbuf"); /* XXX */
1130 } 1134 }
1131 1135
1132 bus_dmamap_sync(sc->sc_dmat, ds->ds_dmamap, 0, 1136 bus_dmamap_sync(sc->sc_dmat, ds->ds_dmamap, 0,
1133 ds->ds_dmamap->dm_mapsize, BUS_DMASYNC_PREREAD); 1137 ds->ds_dmamap->dm_mapsize, BUS_DMASYNC_PREREAD);
1134 1138
1135 SONIC_INIT_RXDESC(sc, idx); 1139 SONIC_INIT_RXDESC(sc, idx);
1136 1140
1137 return 0; 1141 return 0;
1138} 1142}
1139 1143
1140static void 1144static void
1141sonic_set_camentry(struct sonic_softc *sc, int entry, const uint8_t *enaddr) 1145sonic_set_camentry(struct sonic_softc *sc, int entry, const uint8_t *enaddr)
1142{ 1146{
1143 1147
1144 if (sc->sc_32bit) { 1148 if (sc->sc_32bit) {
1145 struct sonic_cda32 *cda = &sc->sc_cda32[entry]; 1149 struct sonic_cda32 *cda = &sc->sc_cda32[entry];
1146 1150
1147 cda->cda_entry = htosonic32(sc, entry); 1151 cda->cda_entry = htosonic32(sc, entry);
1148 cda->cda_addr0 = htosonic32(sc, enaddr[0] | (enaddr[1] << 8)); 1152 cda->cda_addr0 = htosonic32(sc, enaddr[0] | (enaddr[1] << 8));
1149 cda->cda_addr1 = htosonic32(sc, enaddr[2] | (enaddr[3] << 8)); 1153 cda->cda_addr1 = htosonic32(sc, enaddr[2] | (enaddr[3] << 8));
1150 cda->cda_addr2 = htosonic32(sc, enaddr[4] | (enaddr[5] << 8)); 1154 cda->cda_addr2 = htosonic32(sc, enaddr[4] | (enaddr[5] << 8));
1151 } else { 1155 } else {
1152 struct sonic_cda16 *cda = &sc->sc_cda16[entry]; 1156 struct sonic_cda16 *cda = &sc->sc_cda16[entry];
1153 1157
1154 cda->cda_entry = htosonic16(sc, entry); 1158 cda->cda_entry = htosonic16(sc, entry);
1155 cda->cda_addr0 = htosonic16(sc, enaddr[0] | (enaddr[1] << 8)); 1159 cda->cda_addr0 = htosonic16(sc, enaddr[0] | (enaddr[1] << 8));
1156 cda->cda_addr1 = htosonic16(sc, enaddr[2] | (enaddr[3] << 8)); 1160 cda->cda_addr1 = htosonic16(sc, enaddr[2] | (enaddr[3] << 8));
1157 cda->cda_addr2 = htosonic16(sc, enaddr[4] | (enaddr[5] << 8)); 1161 cda->cda_addr2 = htosonic16(sc, enaddr[4] | (enaddr[5] << 8));
1158 } 1162 }
1159} 1163}
1160 1164
1161/* 1165/*
1162 * sonic_set_filter: 1166 * sonic_set_filter:
1163 * 1167 *
1164 * Set the SONIC receive filter. 1168 * Set the SONIC receive filter.
1165 */ 1169 */
1166void 1170void
1167sonic_set_filter(struct sonic_softc *sc) 1171sonic_set_filter(struct sonic_softc *sc)
1168{ 1172{
1169 struct ethercom *ec = &sc->sc_ethercom; 1173 struct ethercom *ec = &sc->sc_ethercom;
1170 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 1174 struct ifnet *ifp = &sc->sc_ethercom.ec_if;
1171 struct ether_multi *enm; 1175 struct ether_multi *enm;
1172 struct ether_multistep step; 1176 struct ether_multistep step;
1173 int i, entry = 0; 1177 int i, entry = 0;
1174 uint16_t camvalid = 0; 1178 uint16_t camvalid = 0;
1175 uint16_t rcr = 0; 1179 uint16_t rcr = 0;
1176 1180
1177 if (ifp->if_flags & IFF_BROADCAST) 1181 if (ifp->if_flags & IFF_BROADCAST)
1178 rcr |= RCR_BRD; 1182 rcr |= RCR_BRD;
1179 1183
1180 if (ifp->if_flags & IFF_PROMISC) { 1184 if (ifp->if_flags & IFF_PROMISC) {
1181 rcr |= RCR_PRO; 1185 rcr |= RCR_PRO;
1182 goto allmulti; 1186 goto allmulti;
1183 } 1187 }
1184 1188
1185 /* Put our station address in the first CAM slot. */ 1189 /* Put our station address in the first CAM slot. */
1186 sonic_set_camentry(sc, entry, CLLADDR(ifp->if_sadl)); 1190 sonic_set_camentry(sc, entry, CLLADDR(ifp->if_sadl));
1187 camvalid |= (1U << entry); 1191 camvalid |= (1U << entry);
1188 entry++; 1192 entry++;
1189 1193
1190 /* Add the multicast addresses to the CAM. */ 1194 /* Add the multicast addresses to the CAM. */
1191 ETHER_LOCK(ec); 1195 ETHER_LOCK(ec);
1192 ETHER_FIRST_MULTI(step, ec, enm); 1196 ETHER_FIRST_MULTI(step, ec, enm);
1193 while (enm != NULL) { 1197 while (enm != NULL) {
1194 if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) { 1198 if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) {
1195 /* 1199 /*
1196 * We must listen to a range of multicast addresses. 1200 * We must listen to a range of multicast addresses.
1197 * The only way to do this on the SONIC is to enable 1201 * The only way to do this on the SONIC is to enable
1198 * reception of all multicast packets. 1202 * reception of all multicast packets.
1199 */ 1203 */
1200 ETHER_UNLOCK(ec); 1204 ETHER_UNLOCK(ec);
1201 goto allmulti; 1205 goto allmulti;
1202 } 1206 }
1203 1207
1204 if (entry == SONIC_NCAMENT) { 1208 if (entry == SONIC_NCAMENT) {
1205 /* 1209 /*
1206 * Out of CAM slots. Have to enable reception 1210 * Out of CAM slots. Have to enable reception
1207 * of all multicast addresses. 1211 * of all multicast addresses.
1208 */ 1212 */
1209 ETHER_UNLOCK(ec); 1213 ETHER_UNLOCK(ec);
1210 goto allmulti; 1214 goto allmulti;
1211 } 1215 }
1212 1216
1213 sonic_set_camentry(sc, entry, enm->enm_addrlo); 1217 sonic_set_camentry(sc, entry, enm->enm_addrlo);
1214 camvalid |= (1U << entry); 1218 camvalid |= (1U << entry);
1215 entry++; 1219 entry++;
1216 1220
1217 ETHER_NEXT_MULTI(step, enm); 1221 ETHER_NEXT_MULTI(step, enm);
1218 } 1222 }
1219 ETHER_UNLOCK(ec); 1223 ETHER_UNLOCK(ec);
1220 1224
1221 ifp->if_flags &= ~IFF_ALLMULTI; 1225 ifp->if_flags &= ~IFF_ALLMULTI;
1222 goto setit; 1226 goto setit;
1223 1227
1224 allmulti: 1228 allmulti:
1225 /* Use only the first CAM slot (station address). */ 1229 /* Use only the first CAM slot (station address). */
1226 camvalid = 0x0001; 1230 camvalid = 0x0001;
1227 entry = 1; 1231 entry = 1;
1228 rcr |= RCR_AMC; 1232 rcr |= RCR_AMC;
1229 1233
1230 setit: 1234 setit:
1231 /* set mask for the CAM Enable register */ 1235 /* set mask for the CAM Enable register */
1232 if (sc->sc_32bit) { 1236 if (sc->sc_32bit) {
1233 if (entry == SONIC_NCAMENT) 1237 if (entry == SONIC_NCAMENT)
1234 sc->sc_cdaenable32 = htosonic32(sc, camvalid); 1238 sc->sc_cdaenable32 = htosonic32(sc, camvalid);
1235 else 1239 else
1236 sc->sc_cda32[entry].cda_entry = 1240 sc->sc_cda32[entry].cda_entry =
1237 htosonic32(sc, camvalid); 1241 htosonic32(sc, camvalid);
1238 } else { 1242 } else {
1239 if (entry == SONIC_NCAMENT) 1243 if (entry == SONIC_NCAMENT)
1240 sc->sc_cdaenable16 = htosonic16(sc, camvalid); 1244 sc->sc_cdaenable16 = htosonic16(sc, camvalid);
1241 else 1245 else
1242 sc->sc_cda16[entry].cda_entry = 1246 sc->sc_cda16[entry].cda_entry =
1243 htosonic16(sc, camvalid); 1247 htosonic16(sc, camvalid);
1244 } 1248 }
1245 1249
1246 /* Load the CAM. */ 1250 /* Load the CAM. */
1247 SONIC_CDCAMSYNC(sc, BUS_DMASYNC_PREWRITE); 1251 SONIC_CDCAMSYNC(sc, BUS_DMASYNC_PREWRITE);
1248 CSR_WRITE(sc, SONIC_CDP, SONIC_CDCAMADDR(sc) & 0xffff); 1252 CSR_WRITE(sc, SONIC_CDP, SONIC_CDCAMADDR(sc) & 0xffff);
1249 CSR_WRITE(sc, SONIC_CDC, entry); 1253 CSR_WRITE(sc, SONIC_CDC, entry);
1250 CSR_WRITE(sc, SONIC_CR, CR_LCAM); 1254 CSR_WRITE(sc, SONIC_CR, CR_LCAM);
1251 for (i = 0; i < 10000; i++) { 1255 for (i = 0; i < 10000; i++) {
1252 if ((CSR_READ(sc, SONIC_CR) & CR_LCAM) == 0) 1256 if ((CSR_READ(sc, SONIC_CR) & CR_LCAM) == 0)
1253 break; 1257 break;
1254 delay(2); 1258 delay(2);
1255 } 1259 }
1256 if (CSR_READ(sc, SONIC_CR) & CR_LCAM) 1260 if (CSR_READ(sc, SONIC_CR) & CR_LCAM)
1257 printf("%s: CAM load failed\n", device_xname(sc->sc_dev)); 1261 printf("%s: CAM load failed\n", device_xname(sc->sc_dev));
1258 SONIC_CDCAMSYNC(sc, BUS_DMASYNC_POSTWRITE); 1262 SONIC_CDCAMSYNC(sc, BUS_DMASYNC_POSTWRITE);
1259 1263
1260 /* Set the receive control register. */ 1264 /* Set the receive control register. */
1261 CSR_WRITE(sc, SONIC_RCR, rcr); 1265 CSR_WRITE(sc, SONIC_RCR, rcr);
1262} 1266}

cvs diff -r1.68 -r1.69 src/sys/dev/ic/dwc_gmac.c (switch to unified diff)

--- src/sys/dev/ic/dwc_gmac.c 2019/10/19 06:40:20 1.68
+++ src/sys/dev/ic/dwc_gmac.c 2020/01/29 14:14:55 1.69
@@ -1,1740 +1,1740 @@ @@ -1,1740 +1,1740 @@
1/* $NetBSD: dwc_gmac.c,v 1.68 2019/10/19 06:40:20 tnn Exp $ */ 1/* $NetBSD: dwc_gmac.c,v 1.69 2020/01/29 14:14:55 thorpej 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.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
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/* 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.68 2019/10/19 06:40:20 tnn Exp $"); 44__KERNEL_RCSID(1, "$NetBSD: dwc_gmac.c,v 1.69 2020/01/29 14:14:55 thorpej Exp $");
45 45
46/* #define DWC_GMAC_DEBUG 1 */ 46/* #define DWC_GMAC_DEBUG 1 */
47 47
48#ifdef _KERNEL_OPT 48#ifdef _KERNEL_OPT
49#include "opt_inet.h" 49#include "opt_inet.h"
50#include "opt_net_mpsafe.h" 50#include "opt_net_mpsafe.h"
51#endif 51#endif
52 52
53#include <sys/param.h> 53#include <sys/param.h>
54#include <sys/bus.h> 54#include <sys/bus.h>
55#include <sys/device.h> 55#include <sys/device.h>
56#include <sys/intr.h> 56#include <sys/intr.h>
57#include <sys/systm.h> 57#include <sys/systm.h>
58#include <sys/sockio.h> 58#include <sys/sockio.h>
59#include <sys/cprng.h> 59#include <sys/cprng.h>
60#include <sys/rndsource.h> 60#include <sys/rndsource.h>
61 61
62#include <net/if.h> 62#include <net/if.h>
63#include <net/if_ether.h> 63#include <net/if_ether.h>
64#include <net/if_media.h> 64#include <net/if_media.h>
65#include <net/bpf.h> 65#include <net/bpf.h>
66#ifdef INET 66#ifdef INET
67#include <netinet/if_inarp.h> 67#include <netinet/if_inarp.h>
68#endif 68#endif
69 69
70#include <dev/mii/miivar.h> 70#include <dev/mii/miivar.h>
71 71
72#include <dev/ic/dwc_gmac_reg.h> 72#include <dev/ic/dwc_gmac_reg.h>
73#include <dev/ic/dwc_gmac_var.h> 73#include <dev/ic/dwc_gmac_var.h>
74 74
75static int dwc_gmac_miibus_read_reg(device_t, int, int, uint16_t *); 75static int dwc_gmac_miibus_read_reg(device_t, int, int, uint16_t *);
76static int dwc_gmac_miibus_write_reg(device_t, int, int, uint16_t); 76static int dwc_gmac_miibus_write_reg(device_t, int, int, uint16_t);
77static void dwc_gmac_miibus_statchg(struct ifnet *); 77static void dwc_gmac_miibus_statchg(struct ifnet *);
78 78
79static int dwc_gmac_reset(struct dwc_gmac_softc *); 79static int dwc_gmac_reset(struct dwc_gmac_softc *);
80static void dwc_gmac_write_hwaddr(struct dwc_gmac_softc *, uint8_t *); 80static void dwc_gmac_write_hwaddr(struct dwc_gmac_softc *, uint8_t *);
81static int dwc_gmac_alloc_dma_rings(struct dwc_gmac_softc *); 81static int dwc_gmac_alloc_dma_rings(struct dwc_gmac_softc *);
82static void dwc_gmac_free_dma_rings(struct dwc_gmac_softc *); 82static void dwc_gmac_free_dma_rings(struct dwc_gmac_softc *);
83static int dwc_gmac_alloc_rx_ring(struct dwc_gmac_softc *, struct dwc_gmac_rx_ring *); 83static int dwc_gmac_alloc_rx_ring(struct dwc_gmac_softc *, struct dwc_gmac_rx_ring *);
84static void dwc_gmac_reset_rx_ring(struct dwc_gmac_softc *, struct dwc_gmac_rx_ring *); 84static void dwc_gmac_reset_rx_ring(struct dwc_gmac_softc *, struct dwc_gmac_rx_ring *);
85static void dwc_gmac_free_rx_ring(struct dwc_gmac_softc *, struct dwc_gmac_rx_ring *); 85static void dwc_gmac_free_rx_ring(struct dwc_gmac_softc *, struct dwc_gmac_rx_ring *);
86static int dwc_gmac_alloc_tx_ring(struct dwc_gmac_softc *, struct dwc_gmac_tx_ring *); 86static int dwc_gmac_alloc_tx_ring(struct dwc_gmac_softc *, struct dwc_gmac_tx_ring *);
87static void dwc_gmac_reset_tx_ring(struct dwc_gmac_softc *, struct dwc_gmac_tx_ring *); 87static void dwc_gmac_reset_tx_ring(struct dwc_gmac_softc *, struct dwc_gmac_tx_ring *);
88static void dwc_gmac_free_tx_ring(struct dwc_gmac_softc *, struct dwc_gmac_tx_ring *); 88static void dwc_gmac_free_tx_ring(struct dwc_gmac_softc *, struct dwc_gmac_tx_ring *);
89static void dwc_gmac_txdesc_sync(struct dwc_gmac_softc *, int, int, int); 89static void dwc_gmac_txdesc_sync(struct dwc_gmac_softc *, int, int, int);
90static int dwc_gmac_init(struct ifnet *); 90static int dwc_gmac_init(struct ifnet *);
91static int dwc_gmac_init_locked(struct ifnet *); 91static int dwc_gmac_init_locked(struct ifnet *);
92static void dwc_gmac_stop(struct ifnet *, int); 92static void dwc_gmac_stop(struct ifnet *, int);
93static void dwc_gmac_stop_locked(struct ifnet *, int); 93static void dwc_gmac_stop_locked(struct ifnet *, int);
94static void dwc_gmac_start(struct ifnet *); 94static void dwc_gmac_start(struct ifnet *);
95static void dwc_gmac_start_locked(struct ifnet *); 95static void dwc_gmac_start_locked(struct ifnet *);
96static int dwc_gmac_queue(struct dwc_gmac_softc *, struct mbuf *); 96static int dwc_gmac_queue(struct dwc_gmac_softc *, struct mbuf *);
97static int dwc_gmac_ioctl(struct ifnet *, u_long, void *); 97static int dwc_gmac_ioctl(struct ifnet *, u_long, void *);
98static void dwc_gmac_tx_intr(struct dwc_gmac_softc *); 98static void dwc_gmac_tx_intr(struct dwc_gmac_softc *);
99static void dwc_gmac_rx_intr(struct dwc_gmac_softc *); 99static void dwc_gmac_rx_intr(struct dwc_gmac_softc *);
100static void dwc_gmac_setmulti(struct dwc_gmac_softc *); 100static void dwc_gmac_setmulti(struct dwc_gmac_softc *);
101static int dwc_gmac_ifflags_cb(struct ethercom *); 101static int dwc_gmac_ifflags_cb(struct ethercom *);
102static uint32_t bitrev32(uint32_t); 102static uint32_t bitrev32(uint32_t);
103static void dwc_gmac_desc_set_owned_by_dev(struct dwc_gmac_dev_dmadesc *); 103static void dwc_gmac_desc_set_owned_by_dev(struct dwc_gmac_dev_dmadesc *);
104static int dwc_gmac_desc_is_owned_by_dev(struct dwc_gmac_dev_dmadesc *); 104static int dwc_gmac_desc_is_owned_by_dev(struct dwc_gmac_dev_dmadesc *);
105static void dwc_gmac_desc_std_set_len(struct dwc_gmac_dev_dmadesc *, int); 105static void dwc_gmac_desc_std_set_len(struct dwc_gmac_dev_dmadesc *, int);
106static uint32_t dwc_gmac_desc_std_get_len(struct dwc_gmac_dev_dmadesc *); 106static uint32_t dwc_gmac_desc_std_get_len(struct dwc_gmac_dev_dmadesc *);
107static void dwc_gmac_desc_std_tx_init_flags(struct dwc_gmac_dev_dmadesc *); 107static void dwc_gmac_desc_std_tx_init_flags(struct dwc_gmac_dev_dmadesc *);
108static void dwc_gmac_desc_std_tx_set_first_frag(struct dwc_gmac_dev_dmadesc *); 108static void dwc_gmac_desc_std_tx_set_first_frag(struct dwc_gmac_dev_dmadesc *);
109static void dwc_gmac_desc_std_tx_set_last_frag(struct dwc_gmac_dev_dmadesc *); 109static void dwc_gmac_desc_std_tx_set_last_frag(struct dwc_gmac_dev_dmadesc *);
110static void dwc_gmac_desc_std_rx_init_flags(struct dwc_gmac_dev_dmadesc *); 110static void dwc_gmac_desc_std_rx_init_flags(struct dwc_gmac_dev_dmadesc *);
111static int dwc_gmac_desc_std_rx_has_error(struct dwc_gmac_dev_dmadesc *); 111static int dwc_gmac_desc_std_rx_has_error(struct dwc_gmac_dev_dmadesc *);
112static void dwc_gmac_desc_enh_set_len(struct dwc_gmac_dev_dmadesc *, int); 112static void dwc_gmac_desc_enh_set_len(struct dwc_gmac_dev_dmadesc *, int);
113static uint32_t dwc_gmac_desc_enh_get_len(struct dwc_gmac_dev_dmadesc *); 113static uint32_t dwc_gmac_desc_enh_get_len(struct dwc_gmac_dev_dmadesc *);
114static void dwc_gmac_desc_enh_tx_init_flags(struct dwc_gmac_dev_dmadesc *); 114static void dwc_gmac_desc_enh_tx_init_flags(struct dwc_gmac_dev_dmadesc *);
115static void dwc_gmac_desc_enh_tx_set_first_frag(struct dwc_gmac_dev_dmadesc *); 115static void dwc_gmac_desc_enh_tx_set_first_frag(struct dwc_gmac_dev_dmadesc *);
116static void dwc_gmac_desc_enh_tx_set_last_frag(struct dwc_gmac_dev_dmadesc *); 116static void dwc_gmac_desc_enh_tx_set_last_frag(struct dwc_gmac_dev_dmadesc *);
117static void dwc_gmac_desc_enh_rx_init_flags(struct dwc_gmac_dev_dmadesc *); 117static void dwc_gmac_desc_enh_rx_init_flags(struct dwc_gmac_dev_dmadesc *);
118static int dwc_gmac_desc_enh_rx_has_error(struct dwc_gmac_dev_dmadesc *); 118static int dwc_gmac_desc_enh_rx_has_error(struct dwc_gmac_dev_dmadesc *);
119 119
120static const struct dwc_gmac_desc_methods desc_methods_standard = { 120static const struct dwc_gmac_desc_methods desc_methods_standard = {
121 .tx_init_flags = dwc_gmac_desc_std_tx_init_flags, 121 .tx_init_flags = dwc_gmac_desc_std_tx_init_flags,
122 .tx_set_owned_by_dev = dwc_gmac_desc_set_owned_by_dev, 122 .tx_set_owned_by_dev = dwc_gmac_desc_set_owned_by_dev,
123 .tx_is_owned_by_dev = dwc_gmac_desc_is_owned_by_dev, 123 .tx_is_owned_by_dev = dwc_gmac_desc_is_owned_by_dev,
124 .tx_set_len = dwc_gmac_desc_std_set_len, 124 .tx_set_len = dwc_gmac_desc_std_set_len,
125 .tx_set_first_frag = dwc_gmac_desc_std_tx_set_first_frag, 125 .tx_set_first_frag = dwc_gmac_desc_std_tx_set_first_frag,
126 .tx_set_last_frag = dwc_gmac_desc_std_tx_set_last_frag, 126 .tx_set_last_frag = dwc_gmac_desc_std_tx_set_last_frag,
127 .rx_init_flags = dwc_gmac_desc_std_rx_init_flags, 127 .rx_init_flags = dwc_gmac_desc_std_rx_init_flags,
128 .rx_set_owned_by_dev = dwc_gmac_desc_set_owned_by_dev, 128 .rx_set_owned_by_dev = dwc_gmac_desc_set_owned_by_dev,
129 .rx_is_owned_by_dev = dwc_gmac_desc_is_owned_by_dev, 129 .rx_is_owned_by_dev = dwc_gmac_desc_is_owned_by_dev,
130 .rx_set_len = dwc_gmac_desc_std_set_len, 130 .rx_set_len = dwc_gmac_desc_std_set_len,
131 .rx_get_len = dwc_gmac_desc_std_get_len, 131 .rx_get_len = dwc_gmac_desc_std_get_len,
132 .rx_has_error = dwc_gmac_desc_std_rx_has_error 132 .rx_has_error = dwc_gmac_desc_std_rx_has_error
133}; 133};
134 134
135static const struct dwc_gmac_desc_methods desc_methods_enhanced = { 135static const struct dwc_gmac_desc_methods desc_methods_enhanced = {
136 .tx_init_flags = dwc_gmac_desc_enh_tx_init_flags, 136 .tx_init_flags = dwc_gmac_desc_enh_tx_init_flags,
137 .tx_set_owned_by_dev = dwc_gmac_desc_set_owned_by_dev, 137 .tx_set_owned_by_dev = dwc_gmac_desc_set_owned_by_dev,
138 .tx_is_owned_by_dev = dwc_gmac_desc_is_owned_by_dev, 138 .tx_is_owned_by_dev = dwc_gmac_desc_is_owned_by_dev,
139 .tx_set_len = dwc_gmac_desc_enh_set_len, 139 .tx_set_len = dwc_gmac_desc_enh_set_len,
140 .tx_set_first_frag = dwc_gmac_desc_enh_tx_set_first_frag, 140 .tx_set_first_frag = dwc_gmac_desc_enh_tx_set_first_frag,
141 .tx_set_last_frag = dwc_gmac_desc_enh_tx_set_last_frag, 141 .tx_set_last_frag = dwc_gmac_desc_enh_tx_set_last_frag,
142 .rx_init_flags = dwc_gmac_desc_enh_rx_init_flags, 142 .rx_init_flags = dwc_gmac_desc_enh_rx_init_flags,
143 .rx_set_owned_by_dev = dwc_gmac_desc_set_owned_by_dev, 143 .rx_set_owned_by_dev = dwc_gmac_desc_set_owned_by_dev,
144 .rx_is_owned_by_dev = dwc_gmac_desc_is_owned_by_dev, 144 .rx_is_owned_by_dev = dwc_gmac_desc_is_owned_by_dev,
145 .rx_set_len = dwc_gmac_desc_enh_set_len, 145 .rx_set_len = dwc_gmac_desc_enh_set_len,
146 .rx_get_len = dwc_gmac_desc_enh_get_len, 146 .rx_get_len = dwc_gmac_desc_enh_get_len,
147 .rx_has_error = dwc_gmac_desc_enh_rx_has_error 147 .rx_has_error = dwc_gmac_desc_enh_rx_has_error
148}; 148};
149 149
150 150
151#define TX_DESC_OFFSET(N) ((AWGE_RX_RING_COUNT+(N)) \ 151#define TX_DESC_OFFSET(N) ((AWGE_RX_RING_COUNT+(N)) \
152 *sizeof(struct dwc_gmac_dev_dmadesc)) 152 *sizeof(struct dwc_gmac_dev_dmadesc))
153#define TX_NEXT(N) (((N)+1) & (AWGE_TX_RING_COUNT-1)) 153#define TX_NEXT(N) (((N)+1) & (AWGE_TX_RING_COUNT-1))
154 154
155#define RX_DESC_OFFSET(N) ((N)*sizeof(struct dwc_gmac_dev_dmadesc)) 155#define RX_DESC_OFFSET(N) ((N)*sizeof(struct dwc_gmac_dev_dmadesc))
156#define RX_NEXT(N) (((N)+1) & (AWGE_RX_RING_COUNT-1)) 156#define RX_NEXT(N) (((N)+1) & (AWGE_RX_RING_COUNT-1))
157 157
158 158
159 159
160#define GMAC_DEF_DMA_INT_MASK (GMAC_DMA_INT_TIE | GMAC_DMA_INT_RIE | \ 160#define GMAC_DEF_DMA_INT_MASK (GMAC_DMA_INT_TIE | GMAC_DMA_INT_RIE | \
161 GMAC_DMA_INT_NIE | GMAC_DMA_INT_AIE | \ 161 GMAC_DMA_INT_NIE | GMAC_DMA_INT_AIE | \
162 GMAC_DMA_INT_FBE | GMAC_DMA_INT_UNE) 162 GMAC_DMA_INT_FBE | GMAC_DMA_INT_UNE)
163 163
164#define GMAC_DMA_INT_ERRORS (GMAC_DMA_INT_AIE | GMAC_DMA_INT_ERE | \ 164#define GMAC_DMA_INT_ERRORS (GMAC_DMA_INT_AIE | GMAC_DMA_INT_ERE | \
165 GMAC_DMA_INT_FBE | \ 165 GMAC_DMA_INT_FBE | \
166 GMAC_DMA_INT_RWE | GMAC_DMA_INT_RUE | \ 166 GMAC_DMA_INT_RWE | GMAC_DMA_INT_RUE | \
167 GMAC_DMA_INT_UNE | GMAC_DMA_INT_OVE | \ 167 GMAC_DMA_INT_UNE | GMAC_DMA_INT_OVE | \
168 GMAC_DMA_INT_TJE) 168 GMAC_DMA_INT_TJE)
169 169
170#define AWIN_DEF_MAC_INTRMASK \ 170#define AWIN_DEF_MAC_INTRMASK \
171 (AWIN_GMAC_MAC_INT_TSI | AWIN_GMAC_MAC_INT_ANEG | \ 171 (AWIN_GMAC_MAC_INT_TSI | AWIN_GMAC_MAC_INT_ANEG | \
172 AWIN_GMAC_MAC_INT_LINKCHG) 172 AWIN_GMAC_MAC_INT_LINKCHG)
173 173
174#ifdef DWC_GMAC_DEBUG 174#ifdef DWC_GMAC_DEBUG
175static void dwc_gmac_dump_dma(struct dwc_gmac_softc *); 175static void dwc_gmac_dump_dma(struct dwc_gmac_softc *);
176static void dwc_gmac_dump_tx_desc(struct dwc_gmac_softc *); 176static void dwc_gmac_dump_tx_desc(struct dwc_gmac_softc *);
177static void dwc_gmac_dump_rx_desc(struct dwc_gmac_softc *); 177static void dwc_gmac_dump_rx_desc(struct dwc_gmac_softc *);
178static void dwc_dump_and_abort(struct dwc_gmac_softc *, const char *); 178static void dwc_dump_and_abort(struct dwc_gmac_softc *, const char *);
179static void dwc_dump_status(struct dwc_gmac_softc *); 179static void dwc_dump_status(struct dwc_gmac_softc *);
180static void dwc_gmac_dump_ffilt(struct dwc_gmac_softc *, uint32_t); 180static void dwc_gmac_dump_ffilt(struct dwc_gmac_softc *, uint32_t);
181#endif 181#endif
182 182
183int 183int
184dwc_gmac_attach(struct dwc_gmac_softc *sc, int phy_id, uint32_t mii_clk) 184dwc_gmac_attach(struct dwc_gmac_softc *sc, int phy_id, uint32_t mii_clk)
185{ 185{
186 uint8_t enaddr[ETHER_ADDR_LEN]; 186 uint8_t enaddr[ETHER_ADDR_LEN];
187 uint32_t maclo, machi, ver, hwft; 187 uint32_t maclo, machi, ver, hwft;
188 struct mii_data * const mii = &sc->sc_mii; 188 struct mii_data * const mii = &sc->sc_mii;
189 struct ifnet * const ifp = &sc->sc_ec.ec_if; 189 struct ifnet * const ifp = &sc->sc_ec.ec_if;
190 prop_dictionary_t dict; 190 prop_dictionary_t dict;
191 int rv; 191 int rv;
192 192
193 mutex_init(&sc->sc_mdio_lock, MUTEX_DEFAULT, IPL_NET); 193 mutex_init(&sc->sc_mdio_lock, MUTEX_DEFAULT, IPL_NET);
194 sc->sc_mii_clk = mii_clk & 7; 194 sc->sc_mii_clk = mii_clk & 7;
195 195
196 dict = device_properties(sc->sc_dev); 196 dict = device_properties(sc->sc_dev);
197 prop_data_t ea = dict ? prop_dictionary_get(dict, "mac-address") : NULL; 197 prop_data_t ea = dict ? prop_dictionary_get(dict, "mac-address") : NULL;
198 if (ea != NULL) { 198 if (ea != NULL) {
199 /* 199 /*
200 * If the MAC address is overriden by a device property, 200 * If the MAC address is overriden by a device property,
201 * use that. 201 * use that.
202 */ 202 */
203 KASSERT(prop_object_type(ea) == PROP_TYPE_DATA); 203 KASSERT(prop_object_type(ea) == PROP_TYPE_DATA);
204 KASSERT(prop_data_size(ea) == ETHER_ADDR_LEN); 204 KASSERT(prop_data_size(ea) == ETHER_ADDR_LEN);
205 memcpy(enaddr, prop_data_data_nocopy(ea), ETHER_ADDR_LEN); 205 memcpy(enaddr, prop_data_data_nocopy(ea), ETHER_ADDR_LEN);
206 } else { 206 } else {
207 /* 207 /*
208 * If we did not get an externaly configure address, 208 * If we did not get an externaly configure address,
209 * try to read one from the current filter setup, 209 * try to read one from the current filter setup,
210 * before resetting the chip. 210 * before resetting the chip.
211 */ 211 */
212 maclo = bus_space_read_4(sc->sc_bst, sc->sc_bsh, 212 maclo = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
213 AWIN_GMAC_MAC_ADDR0LO); 213 AWIN_GMAC_MAC_ADDR0LO);
214 machi = bus_space_read_4(sc->sc_bst, sc->sc_bsh, 214 machi = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
215 AWIN_GMAC_MAC_ADDR0HI); 215 AWIN_GMAC_MAC_ADDR0HI);
216 216
217 if (maclo == 0xffffffff && (machi & 0xffff) == 0xffff) { 217 if (maclo == 0xffffffff && (machi & 0xffff) == 0xffff) {
218 /* fake MAC address */ 218 /* fake MAC address */
219 maclo = 0x00f2 | (cprng_strong32() << 16); 219 maclo = 0x00f2 | (cprng_strong32() << 16);
220 machi = cprng_strong32(); 220 machi = cprng_strong32();
221 } 221 }
222 222
223 enaddr[0] = maclo & 0x0ff; 223 enaddr[0] = maclo & 0x0ff;
224 enaddr[1] = (maclo >> 8) & 0x0ff; 224 enaddr[1] = (maclo >> 8) & 0x0ff;
225 enaddr[2] = (maclo >> 16) & 0x0ff; 225 enaddr[2] = (maclo >> 16) & 0x0ff;
226 enaddr[3] = (maclo >> 24) & 0x0ff; 226 enaddr[3] = (maclo >> 24) & 0x0ff;
227 enaddr[4] = machi & 0x0ff; 227 enaddr[4] = machi & 0x0ff;
228 enaddr[5] = (machi >> 8) & 0x0ff; 228 enaddr[5] = (machi >> 8) & 0x0ff;
229 } 229 }
230 230
231 ver = bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_VERSION); 231 ver = bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_VERSION);
232 aprint_normal_dev(sc->sc_dev, "Core version: %08x\n", ver); 232 aprint_normal_dev(sc->sc_dev, "Core version: %08x\n", ver);
233 233
234 /* 234 /*
235 * Init chip and do initial setup 235 * Init chip and do initial setup
236 */ 236 */
237 if (dwc_gmac_reset(sc) != 0) 237 if (dwc_gmac_reset(sc) != 0)
238 return ENXIO; /* not much to cleanup, haven't attached yet */ 238 return ENXIO; /* not much to cleanup, haven't attached yet */
239 dwc_gmac_write_hwaddr(sc, enaddr); 239 dwc_gmac_write_hwaddr(sc, enaddr);
240 aprint_normal_dev(sc->sc_dev, "Ethernet address %s\n", 240 aprint_normal_dev(sc->sc_dev, "Ethernet address %s\n",
241 ether_sprintf(enaddr)); 241 ether_sprintf(enaddr));
242 242
243 hwft = 0; 243 hwft = 0;
244 if (ver >= 0x35) { 244 if (ver >= 0x35) {
245 hwft = bus_space_read_4(sc->sc_bst, sc->sc_bsh, 245 hwft = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
246 AWIN_GMAC_DMA_HWFEATURES); 246 AWIN_GMAC_DMA_HWFEATURES);
247 aprint_normal_dev(sc->sc_dev, 247 aprint_normal_dev(sc->sc_dev,
248 "HW feature mask: %x\n", hwft); 248 "HW feature mask: %x\n", hwft);
249 } 249 }
250 if (hwft & GMAC_DMA_FEAT_ENHANCED_DESC) { 250 if (hwft & GMAC_DMA_FEAT_ENHANCED_DESC) {
251 aprint_normal_dev(sc->sc_dev, 251 aprint_normal_dev(sc->sc_dev,
252 "Using enhanced descriptor format\n"); 252 "Using enhanced descriptor format\n");
253 sc->sc_descm = &desc_methods_enhanced; 253 sc->sc_descm = &desc_methods_enhanced;
254 } else { 254 } else {
255 sc->sc_descm = &desc_methods_standard; 255 sc->sc_descm = &desc_methods_standard;
256 } 256 }
257 257
258 /* 258 /*
259 * Allocate Tx and Rx rings 259 * Allocate Tx and Rx rings
260 */ 260 */
261 if (dwc_gmac_alloc_dma_rings(sc) != 0) { 261 if (dwc_gmac_alloc_dma_rings(sc) != 0) {
262 aprint_error_dev(sc->sc_dev, "could not allocate DMA rings\n"); 262 aprint_error_dev(sc->sc_dev, "could not allocate DMA rings\n");
263 goto fail; 263 goto fail;
264 } 264 }
265 265
266 if (dwc_gmac_alloc_tx_ring(sc, &sc->sc_txq) != 0) { 266 if (dwc_gmac_alloc_tx_ring(sc, &sc->sc_txq) != 0) {
267 aprint_error_dev(sc->sc_dev, "could not allocate Tx ring\n"); 267 aprint_error_dev(sc->sc_dev, "could not allocate Tx ring\n");
268 goto fail; 268 goto fail;
269 } 269 }
270 270
271 if (dwc_gmac_alloc_rx_ring(sc, &sc->sc_rxq) != 0) { 271 if (dwc_gmac_alloc_rx_ring(sc, &sc->sc_rxq) != 0) {
272 aprint_error_dev(sc->sc_dev, "could not allocate Rx ring\n"); 272 aprint_error_dev(sc->sc_dev, "could not allocate Rx ring\n");
273 goto fail; 273 goto fail;
274 } 274 }
275 275
276 sc->sc_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NET); 276 sc->sc_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NET);
277 mutex_init(&sc->sc_txq.t_mtx, MUTEX_DEFAULT, IPL_NET); 277 mutex_init(&sc->sc_txq.t_mtx, MUTEX_DEFAULT, IPL_NET);
278 mutex_init(&sc->sc_rxq.r_mtx, MUTEX_DEFAULT, IPL_NET); 278 mutex_init(&sc->sc_rxq.r_mtx, MUTEX_DEFAULT, IPL_NET);
279 279
280 /* 280 /*
281 * Prepare interface data 281 * Prepare interface data
282 */ 282 */
283 ifp->if_softc = sc; 283 ifp->if_softc = sc;
284 strlcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ); 284 strlcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ);
285 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 285 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
286#ifdef DWCGMAC_MPSAFE 286#ifdef DWCGMAC_MPSAFE
287 ifp->if_extflags = IFEF_MPSAFE; 287 ifp->if_extflags = IFEF_MPSAFE;
288#endif 288#endif
289 ifp->if_ioctl = dwc_gmac_ioctl; 289 ifp->if_ioctl = dwc_gmac_ioctl;
290 ifp->if_start = dwc_gmac_start; 290 ifp->if_start = dwc_gmac_start;
291 ifp->if_init = dwc_gmac_init; 291 ifp->if_init = dwc_gmac_init;
292 ifp->if_stop = dwc_gmac_stop; 292 ifp->if_stop = dwc_gmac_stop;
293 IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); 293 IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
294 IFQ_SET_READY(&ifp->if_snd); 294 IFQ_SET_READY(&ifp->if_snd);
295 295
296 /* 296 /*
297 * Attach MII subdevices 297 * Attach MII subdevices
298 */ 298 */
299 sc->sc_ec.ec_mii = &sc->sc_mii; 299 sc->sc_ec.ec_mii = &sc->sc_mii;
300 ifmedia_init(&mii->mii_media, 0, ether_mediachange, ether_mediastatus); 300 ifmedia_init(&mii->mii_media, 0, ether_mediachange, ether_mediastatus);
301 mii->mii_ifp = ifp; 301 mii->mii_ifp = ifp;
302 mii->mii_readreg = dwc_gmac_miibus_read_reg; 302 mii->mii_readreg = dwc_gmac_miibus_read_reg;
303 mii->mii_writereg = dwc_gmac_miibus_write_reg; 303 mii->mii_writereg = dwc_gmac_miibus_write_reg;
304 mii->mii_statchg = dwc_gmac_miibus_statchg; 304 mii->mii_statchg = dwc_gmac_miibus_statchg;
305 mii_attach(sc->sc_dev, mii, 0xffffffff, phy_id, MII_OFFSET_ANY, 305 mii_attach(sc->sc_dev, mii, 0xffffffff, phy_id, MII_OFFSET_ANY,
306 MIIF_DOPAUSE); 306 MIIF_DOPAUSE);
307 307
308 if (LIST_EMPTY(&mii->mii_phys)) { 308 if (LIST_EMPTY(&mii->mii_phys)) {
309 aprint_error_dev(sc->sc_dev, "no PHY found!\n"); 309 aprint_error_dev(sc->sc_dev, "no PHY found!\n");
310 ifmedia_add(&mii->mii_media, IFM_ETHER | IFM_MANUAL, 0, NULL); 310 ifmedia_add(&mii->mii_media, IFM_ETHER | IFM_MANUAL, 0, NULL);
311 ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_MANUAL); 311 ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_MANUAL);
312 } else { 312 } else {
313 ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_AUTO); 313 ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_AUTO);
314 } 314 }
315 315
316 /* 316 /*
317 * We can support 802.1Q VLAN-sized frames. 317 * We can support 802.1Q VLAN-sized frames.
318 */ 318 */
319 sc->sc_ec.ec_capabilities |= ETHERCAP_VLAN_MTU; 319 sc->sc_ec.ec_capabilities |= ETHERCAP_VLAN_MTU;
320 320
321 /* 321 /*
322 * Ready, attach interface 322 * Ready, attach interface
323 */ 323 */
324 /* Attach the interface. */ 324 /* Attach the interface. */
325 rv = if_initialize(ifp); 325 rv = if_initialize(ifp);
326 if (rv != 0) 326 if (rv != 0)
327 goto fail_2; 327 goto fail_2;
328 sc->sc_ipq = if_percpuq_create(&sc->sc_ec.ec_if); 328 sc->sc_ipq = if_percpuq_create(&sc->sc_ec.ec_if);
329 if_deferred_start_init(ifp, NULL); 329 if_deferred_start_init(ifp, NULL);
330 ether_ifattach(ifp, enaddr); 330 ether_ifattach(ifp, enaddr);
331 ether_set_ifflags_cb(&sc->sc_ec, dwc_gmac_ifflags_cb); 331 ether_set_ifflags_cb(&sc->sc_ec, dwc_gmac_ifflags_cb);
332 if_register(ifp); 332 if_register(ifp);
333 rnd_attach_source(&sc->rnd_source, device_xname(sc->sc_dev), 333 rnd_attach_source(&sc->rnd_source, device_xname(sc->sc_dev),
334 RND_TYPE_NET, RND_FLAG_DEFAULT); 334 RND_TYPE_NET, RND_FLAG_DEFAULT);
335 335
336 /* 336 /*
337 * Enable interrupts 337 * Enable interrupts
338 */ 338 */
339 mutex_enter(sc->sc_lock); 339 mutex_enter(sc->sc_lock);
340 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_INTMASK, 340 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_INTMASK,
341 AWIN_DEF_MAC_INTRMASK); 341 AWIN_DEF_MAC_INTRMASK);
342 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_INTENABLE, 342 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_INTENABLE,
343 GMAC_DEF_DMA_INT_MASK); 343 GMAC_DEF_DMA_INT_MASK);
344 mutex_exit(sc->sc_lock); 344 mutex_exit(sc->sc_lock);
345 345
346 return 0; 346 return 0;
347 347
348fail_2: 348fail_2:
349 ifmedia_removeall(&mii->mii_media); 349 ifmedia_removeall(&mii->mii_media);
350 mii_detach(mii, MII_PHY_ANY, MII_OFFSET_ANY); 350 mii_detach(mii, MII_PHY_ANY, MII_OFFSET_ANY);
351 mutex_destroy(&sc->sc_txq.t_mtx); 351 mutex_destroy(&sc->sc_txq.t_mtx);
352 mutex_destroy(&sc->sc_rxq.r_mtx); 352 mutex_destroy(&sc->sc_rxq.r_mtx);
353 mutex_obj_free(sc->sc_lock); 353 mutex_obj_free(sc->sc_lock);
354fail: 354fail:
355 dwc_gmac_free_rx_ring(sc, &sc->sc_rxq); 355 dwc_gmac_free_rx_ring(sc, &sc->sc_rxq);
356 dwc_gmac_free_tx_ring(sc, &sc->sc_txq); 356 dwc_gmac_free_tx_ring(sc, &sc->sc_txq);
357 dwc_gmac_free_dma_rings(sc); 357 dwc_gmac_free_dma_rings(sc);
358 mutex_destroy(&sc->sc_mdio_lock); 358 mutex_destroy(&sc->sc_mdio_lock);
359 359
360 return ENXIO; 360 return ENXIO;
361} 361}
362 362
363 363
364 364
365static int 365static int
366dwc_gmac_reset(struct dwc_gmac_softc *sc) 366dwc_gmac_reset(struct dwc_gmac_softc *sc)
367{ 367{
368 size_t cnt; 368 size_t cnt;
369 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_BUSMODE, 369 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_BUSMODE,
370 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_BUSMODE) 370 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_BUSMODE)
371 | GMAC_BUSMODE_RESET); 371 | GMAC_BUSMODE_RESET);
372 for (cnt = 0; cnt < 3000; cnt++) { 372 for (cnt = 0; cnt < 3000; cnt++) {
373 if ((bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_BUSMODE) 373 if ((bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_BUSMODE)
374 & GMAC_BUSMODE_RESET) == 0) 374 & GMAC_BUSMODE_RESET) == 0)
375 return 0; 375 return 0;
376 delay(10); 376 delay(10);
377 } 377 }
378 378
379 aprint_error_dev(sc->sc_dev, "reset timed out\n"); 379 aprint_error_dev(sc->sc_dev, "reset timed out\n");
380 return EIO; 380 return EIO;
381} 381}
382 382
383static void 383static void
384dwc_gmac_write_hwaddr(struct dwc_gmac_softc *sc, 384dwc_gmac_write_hwaddr(struct dwc_gmac_softc *sc,
385 uint8_t enaddr[ETHER_ADDR_LEN]) 385 uint8_t enaddr[ETHER_ADDR_LEN])
386{ 386{
387 uint32_t hi, lo; 387 uint32_t hi, lo;
388 388
389 hi = enaddr[4] | (enaddr[5] << 8); 389 hi = enaddr[4] | (enaddr[5] << 8);
390 lo = enaddr[0] | (enaddr[1] << 8) | (enaddr[2] << 16) 390 lo = enaddr[0] | (enaddr[1] << 8) | (enaddr[2] << 16)
391 | (enaddr[3] << 24); 391 | (enaddr[3] << 24);
392 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_ADDR0HI, hi); 392 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_ADDR0HI, hi);
393 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_ADDR0LO, lo); 393 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_ADDR0LO, lo);
394} 394}
395 395
396static int 396static int
397dwc_gmac_miibus_read_reg(device_t self, int phy, int reg, uint16_t *val) 397dwc_gmac_miibus_read_reg(device_t self, int phy, int reg, uint16_t *val)
398{ 398{
399 struct dwc_gmac_softc * const sc = device_private(self); 399 struct dwc_gmac_softc * const sc = device_private(self);
400 uint16_t mii; 400 uint16_t mii;
401 size_t cnt; 401 size_t cnt;
402 402
403 mii = __SHIFTIN(phy, GMAC_MII_PHY_MASK) 403 mii = __SHIFTIN(phy, GMAC_MII_PHY_MASK)
404 | __SHIFTIN(reg, GMAC_MII_REG_MASK) 404 | __SHIFTIN(reg, GMAC_MII_REG_MASK)
405 | __SHIFTIN(sc->sc_mii_clk, GMAC_MII_CLKMASK) 405 | __SHIFTIN(sc->sc_mii_clk, GMAC_MII_CLKMASK)
406 | GMAC_MII_BUSY; 406 | GMAC_MII_BUSY;
407 407
408 mutex_enter(&sc->sc_mdio_lock); 408 mutex_enter(&sc->sc_mdio_lock);
409 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_MIIADDR, mii); 409 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_MIIADDR, mii);
410 410
411 for (cnt = 0; cnt < 1000; cnt++) { 411 for (cnt = 0; cnt < 1000; cnt++) {
412 if (!(bus_space_read_4(sc->sc_bst, sc->sc_bsh, 412 if (!(bus_space_read_4(sc->sc_bst, sc->sc_bsh,
413 AWIN_GMAC_MAC_MIIADDR) & GMAC_MII_BUSY)) { 413 AWIN_GMAC_MAC_MIIADDR) & GMAC_MII_BUSY)) {
414 *val = bus_space_read_4(sc->sc_bst, sc->sc_bsh, 414 *val = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
415 AWIN_GMAC_MAC_MIIDATA); 415 AWIN_GMAC_MAC_MIIDATA);
416 break; 416 break;
417 } 417 }
418 delay(10); 418 delay(10);
419 } 419 }
420 420
421 mutex_exit(&sc->sc_mdio_lock); 421 mutex_exit(&sc->sc_mdio_lock);
422 422
423 if (cnt >= 1000) 423 if (cnt >= 1000)
424 return ETIMEDOUT; 424 return ETIMEDOUT;
425 425
426 return 0; 426 return 0;
427} 427}
428 428
429static int 429static int
430dwc_gmac_miibus_write_reg(device_t self, int phy, int reg, uint16_t val) 430dwc_gmac_miibus_write_reg(device_t self, int phy, int reg, uint16_t val)
431{ 431{
432 struct dwc_gmac_softc * const sc = device_private(self); 432 struct dwc_gmac_softc * const sc = device_private(self);
433 uint16_t mii; 433 uint16_t mii;
434 size_t cnt; 434 size_t cnt;
435 435
436 mii = __SHIFTIN(phy, GMAC_MII_PHY_MASK) 436 mii = __SHIFTIN(phy, GMAC_MII_PHY_MASK)
437 | __SHIFTIN(reg, GMAC_MII_REG_MASK) 437 | __SHIFTIN(reg, GMAC_MII_REG_MASK)
438 | __SHIFTIN(sc->sc_mii_clk, GMAC_MII_CLKMASK) 438 | __SHIFTIN(sc->sc_mii_clk, GMAC_MII_CLKMASK)
439 | GMAC_MII_BUSY | GMAC_MII_WRITE; 439 | GMAC_MII_BUSY | GMAC_MII_WRITE;
440 440
441 mutex_enter(&sc->sc_mdio_lock); 441 mutex_enter(&sc->sc_mdio_lock);
442 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_MIIDATA, val); 442 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_MIIDATA, val);
443 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_MIIADDR, mii); 443 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_MIIADDR, mii);
444 444
445 for (cnt = 0; cnt < 1000; cnt++) { 445 for (cnt = 0; cnt < 1000; cnt++) {
446 if (!(bus_space_read_4(sc->sc_bst, sc->sc_bsh, 446 if (!(bus_space_read_4(sc->sc_bst, sc->sc_bsh,
447 AWIN_GMAC_MAC_MIIADDR) & GMAC_MII_BUSY)) 447 AWIN_GMAC_MAC_MIIADDR) & GMAC_MII_BUSY))
448 break; 448 break;
449 delay(10); 449 delay(10);
450 } 450 }
451 451
452 mutex_exit(&sc->sc_mdio_lock); 452 mutex_exit(&sc->sc_mdio_lock);
453 453
454 if (cnt >= 1000) 454 if (cnt >= 1000)
455 return ETIMEDOUT; 455 return ETIMEDOUT;
456 456
457 return 0; 457 return 0;
458} 458}
459 459
460static int 460static int
461dwc_gmac_alloc_rx_ring(struct dwc_gmac_softc *sc, 461dwc_gmac_alloc_rx_ring(struct dwc_gmac_softc *sc,
462 struct dwc_gmac_rx_ring *ring) 462 struct dwc_gmac_rx_ring *ring)
463{ 463{
464 struct dwc_gmac_rx_data *data; 464 struct dwc_gmac_rx_data *data;
465 bus_addr_t physaddr; 465 bus_addr_t physaddr;
466 const size_t descsize = AWGE_RX_RING_COUNT * sizeof(*ring->r_desc); 466 const size_t descsize = AWGE_RX_RING_COUNT * sizeof(*ring->r_desc);
467 int error, i, next; 467 int error, i, next;
468 468
469 ring->r_cur = ring->r_next = 0; 469 ring->r_cur = ring->r_next = 0;
470 memset(ring->r_desc, 0, descsize); 470 memset(ring->r_desc, 0, descsize);
471 471
472 /* 472 /*
473 * Pre-allocate Rx buffers and populate Rx ring. 473 * Pre-allocate Rx buffers and populate Rx ring.
474 */ 474 */
475 for (i = 0; i < AWGE_RX_RING_COUNT; i++) { 475 for (i = 0; i < AWGE_RX_RING_COUNT; i++) {
476 struct dwc_gmac_dev_dmadesc *desc; 476 struct dwc_gmac_dev_dmadesc *desc;
477 477
478 data = &sc->sc_rxq.r_data[i]; 478 data = &sc->sc_rxq.r_data[i];
479 479
480 MGETHDR(data->rd_m, M_DONTWAIT, MT_DATA); 480 MGETHDR(data->rd_m, M_DONTWAIT, MT_DATA);
481 if (data->rd_m == NULL) { 481 if (data->rd_m == NULL) {
482 aprint_error_dev(sc->sc_dev, 482 aprint_error_dev(sc->sc_dev,
483 "could not allocate rx mbuf #%d\n", i); 483 "could not allocate rx mbuf #%d\n", i);
484 error = ENOMEM; 484 error = ENOMEM;
485 goto fail; 485 goto fail;
486 } 486 }
487 error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, 487 error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1,
488 MCLBYTES, 0, BUS_DMA_NOWAIT, &data->rd_map); 488 MCLBYTES, 0, BUS_DMA_NOWAIT, &data->rd_map);
489 if (error != 0) { 489 if (error != 0) {
490 aprint_error_dev(sc->sc_dev, 490 aprint_error_dev(sc->sc_dev,
491 "could not create DMA map\n"); 491 "could not create DMA map\n");
492 data->rd_map = NULL; 492 data->rd_map = NULL;
493 goto fail; 493 goto fail;
494 } 494 }
495 MCLGET(data->rd_m, M_DONTWAIT); 495 MCLGET(data->rd_m, M_DONTWAIT);
496 if (!(data->rd_m->m_flags & M_EXT)) { 496 if (!(data->rd_m->m_flags & M_EXT)) {
497 aprint_error_dev(sc->sc_dev, 497 aprint_error_dev(sc->sc_dev,
498 "could not allocate mbuf cluster #%d\n", i); 498 "could not allocate mbuf cluster #%d\n", i);
499 error = ENOMEM; 499 error = ENOMEM;
500 goto fail; 500 goto fail;
501 } 501 }
502 data->rd_m->m_len = data->rd_m->m_pkthdr.len 502 data->rd_m->m_len = data->rd_m->m_pkthdr.len
503 = data->rd_m->m_ext.ext_size; 503 = data->rd_m->m_ext.ext_size;
504 if (data->rd_m->m_len > AWGE_MAX_PACKET) { 504 if (data->rd_m->m_len > AWGE_MAX_PACKET) {
505 data->rd_m->m_len = data->rd_m->m_pkthdr.len 505 data->rd_m->m_len = data->rd_m->m_pkthdr.len
506 = AWGE_MAX_PACKET; 506 = AWGE_MAX_PACKET;
507 } 507 }
508 508
509 error = bus_dmamap_load_mbuf(sc->sc_dmat, data->rd_map, 509 error = bus_dmamap_load_mbuf(sc->sc_dmat, data->rd_map,
510 data->rd_m, BUS_DMA_READ | BUS_DMA_NOWAIT); 510 data->rd_m, BUS_DMA_READ | BUS_DMA_NOWAIT);
511 if (error != 0) { 511 if (error != 0) {
512 aprint_error_dev(sc->sc_dev, 512 aprint_error_dev(sc->sc_dev,
513 "could not load rx buf DMA map #%d", i); 513 "could not load rx buf DMA map #%d", i);
514 goto fail; 514 goto fail;
515 } 515 }
516 bus_dmamap_sync(sc->sc_dmat, data->rd_map, 0, 516 bus_dmamap_sync(sc->sc_dmat, data->rd_map, 0,
517 data->rd_map->dm_mapsize, BUS_DMASYNC_PREREAD); 517 data->rd_map->dm_mapsize, BUS_DMASYNC_PREREAD);
518 physaddr = data->rd_map->dm_segs[0].ds_addr; 518 physaddr = data->rd_map->dm_segs[0].ds_addr;
519 519
520 desc = &sc->sc_rxq.r_desc[i]; 520 desc = &sc->sc_rxq.r_desc[i];
521 desc->ddesc_data = htole32(physaddr); 521 desc->ddesc_data = htole32(physaddr);
522 next = RX_NEXT(i); 522 next = RX_NEXT(i);
523 desc->ddesc_next = htole32(ring->r_physaddr 523 desc->ddesc_next = htole32(ring->r_physaddr
524 + next * sizeof(*desc)); 524 + next * sizeof(*desc));
525 sc->sc_descm->rx_init_flags(desc); 525 sc->sc_descm->rx_init_flags(desc);
526 sc->sc_descm->rx_set_len(desc, data->rd_m->m_len); 526 sc->sc_descm->rx_set_len(desc, data->rd_m->m_len);
527 sc->sc_descm->rx_set_owned_by_dev(desc); 527 sc->sc_descm->rx_set_owned_by_dev(desc);
528 } 528 }
529 529
530 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 0, 530 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 0,
531 AWGE_RX_RING_COUNT*sizeof(struct dwc_gmac_dev_dmadesc), 531 AWGE_RX_RING_COUNT*sizeof(struct dwc_gmac_dev_dmadesc),
532 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 532 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
533 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_RX_ADDR, 533 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_RX_ADDR,
534 ring->r_physaddr); 534 ring->r_physaddr);
535 535
536 return 0; 536 return 0;
537 537
538fail: 538fail:
539 dwc_gmac_free_rx_ring(sc, ring); 539 dwc_gmac_free_rx_ring(sc, ring);
540 return error; 540 return error;
541} 541}
542 542
543static void 543static void
544dwc_gmac_reset_rx_ring(struct dwc_gmac_softc *sc, 544dwc_gmac_reset_rx_ring(struct dwc_gmac_softc *sc,
545 struct dwc_gmac_rx_ring *ring) 545 struct dwc_gmac_rx_ring *ring)
546{ 546{
547 struct dwc_gmac_dev_dmadesc *desc; 547 struct dwc_gmac_dev_dmadesc *desc;
548 struct dwc_gmac_rx_data *data; 548 struct dwc_gmac_rx_data *data;
549 int i; 549 int i;
550 550
551 mutex_enter(&ring->r_mtx); 551 mutex_enter(&ring->r_mtx);
552 for (i = 0; i < AWGE_RX_RING_COUNT; i++) { 552 for (i = 0; i < AWGE_RX_RING_COUNT; i++) {
553 desc = &sc->sc_rxq.r_desc[i]; 553 desc = &sc->sc_rxq.r_desc[i];
554 data = &sc->sc_rxq.r_data[i]; 554 data = &sc->sc_rxq.r_data[i];
555 sc->sc_descm->rx_init_flags(desc); 555 sc->sc_descm->rx_init_flags(desc);
556 sc->sc_descm->rx_set_len(desc, data->rd_m->m_len); 556 sc->sc_descm->rx_set_len(desc, data->rd_m->m_len);
557 sc->sc_descm->rx_set_owned_by_dev(desc); 557 sc->sc_descm->rx_set_owned_by_dev(desc);
558 } 558 }
559 559
560 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 0, 560 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 0,
561 AWGE_RX_RING_COUNT*sizeof(struct dwc_gmac_dev_dmadesc), 561 AWGE_RX_RING_COUNT*sizeof(struct dwc_gmac_dev_dmadesc),
562 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 562 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
563 563
564 ring->r_cur = ring->r_next = 0; 564 ring->r_cur = ring->r_next = 0;
565 /* reset DMA address to start of ring */ 565 /* reset DMA address to start of ring */
566 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_RX_ADDR, 566 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_RX_ADDR,
567 sc->sc_rxq.r_physaddr); 567 sc->sc_rxq.r_physaddr);
568 mutex_exit(&ring->r_mtx); 568 mutex_exit(&ring->r_mtx);
569} 569}
570 570
571static int 571static int
572dwc_gmac_alloc_dma_rings(struct dwc_gmac_softc *sc) 572dwc_gmac_alloc_dma_rings(struct dwc_gmac_softc *sc)
573{ 573{
574 const size_t descsize = AWGE_TOTAL_RING_COUNT * 574 const size_t descsize = AWGE_TOTAL_RING_COUNT *
575 sizeof(struct dwc_gmac_dev_dmadesc); 575 sizeof(struct dwc_gmac_dev_dmadesc);
576 int error, nsegs; 576 int error, nsegs;
577 void *rings; 577 void *rings;
578 578
579 error = bus_dmamap_create(sc->sc_dmat, descsize, 1, descsize, 0, 579 error = bus_dmamap_create(sc->sc_dmat, descsize, 1, descsize, 0,
580 BUS_DMA_NOWAIT, &sc->sc_dma_ring_map); 580 BUS_DMA_NOWAIT, &sc->sc_dma_ring_map);
581 if (error != 0) { 581 if (error != 0) {
582 aprint_error_dev(sc->sc_dev, 582 aprint_error_dev(sc->sc_dev,
583 "could not create desc DMA map\n"); 583 "could not create desc DMA map\n");
584 sc->sc_dma_ring_map = NULL; 584 sc->sc_dma_ring_map = NULL;
585 goto fail; 585 goto fail;
586 } 586 }
587 587
588 error = bus_dmamem_alloc(sc->sc_dmat, descsize, PAGE_SIZE, 0, 588 error = bus_dmamem_alloc(sc->sc_dmat, descsize, PAGE_SIZE, 0,
589 &sc->sc_dma_ring_seg, 1, &nsegs, BUS_DMA_NOWAIT |BUS_DMA_COHERENT); 589 &sc->sc_dma_ring_seg, 1, &nsegs, BUS_DMA_NOWAIT |BUS_DMA_COHERENT);
590 if (error != 0) { 590 if (error != 0) {
591 aprint_error_dev(sc->sc_dev, 591 aprint_error_dev(sc->sc_dev,
592 "could not map DMA memory\n"); 592 "could not map DMA memory\n");
593 goto fail; 593 goto fail;
594 } 594 }
595 595
596 error = bus_dmamem_map(sc->sc_dmat, &sc->sc_dma_ring_seg, nsegs, 596 error = bus_dmamem_map(sc->sc_dmat, &sc->sc_dma_ring_seg, nsegs,
597 descsize, &rings, BUS_DMA_NOWAIT | BUS_DMA_COHERENT); 597 descsize, &rings, BUS_DMA_NOWAIT | BUS_DMA_COHERENT);
598 if (error != 0) { 598 if (error != 0) {
599 aprint_error_dev(sc->sc_dev, 599 aprint_error_dev(sc->sc_dev,
600 "could not allocate DMA memory\n"); 600 "could not allocate DMA memory\n");
601 goto fail; 601 goto fail;
602 } 602 }
603 603
604 error = bus_dmamap_load(sc->sc_dmat, sc->sc_dma_ring_map, rings, 604 error = bus_dmamap_load(sc->sc_dmat, sc->sc_dma_ring_map, rings,
605 descsize, NULL, BUS_DMA_NOWAIT | BUS_DMA_COHERENT); 605 descsize, NULL, BUS_DMA_NOWAIT | BUS_DMA_COHERENT);
606 if (error != 0) { 606 if (error != 0) {
607 aprint_error_dev(sc->sc_dev, 607 aprint_error_dev(sc->sc_dev,
608 "could not load desc DMA map\n"); 608 "could not load desc DMA map\n");
609 goto fail; 609 goto fail;
610 } 610 }
611 611
612 /* give first AWGE_RX_RING_COUNT to the RX side */ 612 /* give first AWGE_RX_RING_COUNT to the RX side */
613 sc->sc_rxq.r_desc = rings; 613 sc->sc_rxq.r_desc = rings;
614 sc->sc_rxq.r_physaddr = sc->sc_dma_ring_map->dm_segs[0].ds_addr; 614 sc->sc_rxq.r_physaddr = sc->sc_dma_ring_map->dm_segs[0].ds_addr;
615 615
616 /* and next rings to the TX side */ 616 /* and next rings to the TX side */
617 sc->sc_txq.t_desc = sc->sc_rxq.r_desc + AWGE_RX_RING_COUNT; 617 sc->sc_txq.t_desc = sc->sc_rxq.r_desc + AWGE_RX_RING_COUNT;
618 sc->sc_txq.t_physaddr = sc->sc_rxq.r_physaddr + 618 sc->sc_txq.t_physaddr = sc->sc_rxq.r_physaddr +
619 AWGE_RX_RING_COUNT*sizeof(struct dwc_gmac_dev_dmadesc); 619 AWGE_RX_RING_COUNT*sizeof(struct dwc_gmac_dev_dmadesc);
620 620
621 return 0; 621 return 0;
622 622
623fail: 623fail:
624 dwc_gmac_free_dma_rings(sc); 624 dwc_gmac_free_dma_rings(sc);
625 return error; 625 return error;
626} 626}
627 627
628static void 628static void
629dwc_gmac_free_dma_rings(struct dwc_gmac_softc *sc) 629dwc_gmac_free_dma_rings(struct dwc_gmac_softc *sc)
630{ 630{
631 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 0, 631 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 0,
632 sc->sc_dma_ring_map->dm_mapsize, BUS_DMASYNC_POSTWRITE); 632 sc->sc_dma_ring_map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
633 bus_dmamap_unload(sc->sc_dmat, sc->sc_dma_ring_map); 633 bus_dmamap_unload(sc->sc_dmat, sc->sc_dma_ring_map);
634 bus_dmamem_unmap(sc->sc_dmat, sc->sc_rxq.r_desc, 634 bus_dmamem_unmap(sc->sc_dmat, sc->sc_rxq.r_desc,
635 AWGE_TOTAL_RING_COUNT * sizeof(struct dwc_gmac_dev_dmadesc)); 635 AWGE_TOTAL_RING_COUNT * sizeof(struct dwc_gmac_dev_dmadesc));
636 bus_dmamem_free(sc->sc_dmat, &sc->sc_dma_ring_seg, 1); 636 bus_dmamem_free(sc->sc_dmat, &sc->sc_dma_ring_seg, 1);
637} 637}
638 638
639static void 639static void
640dwc_gmac_free_rx_ring(struct dwc_gmac_softc *sc, struct dwc_gmac_rx_ring *ring) 640dwc_gmac_free_rx_ring(struct dwc_gmac_softc *sc, struct dwc_gmac_rx_ring *ring)
641{ 641{
642 struct dwc_gmac_rx_data *data; 642 struct dwc_gmac_rx_data *data;
643 int i; 643 int i;
644 644
645 if (ring->r_desc == NULL) 645 if (ring->r_desc == NULL)
646 return; 646 return;
647 647
648 648
649 for (i = 0; i < AWGE_RX_RING_COUNT; i++) { 649 for (i = 0; i < AWGE_RX_RING_COUNT; i++) {
650 data = &ring->r_data[i]; 650 data = &ring->r_data[i];
651 651
652 if (data->rd_map != NULL) { 652 if (data->rd_map != NULL) {
653 bus_dmamap_sync(sc->sc_dmat, data->rd_map, 0, 653 bus_dmamap_sync(sc->sc_dmat, data->rd_map, 0,
654 AWGE_RX_RING_COUNT 654 AWGE_RX_RING_COUNT
655 *sizeof(struct dwc_gmac_dev_dmadesc), 655 *sizeof(struct dwc_gmac_dev_dmadesc),
656 BUS_DMASYNC_POSTREAD); 656 BUS_DMASYNC_POSTREAD);
657 bus_dmamap_unload(sc->sc_dmat, data->rd_map); 657 bus_dmamap_unload(sc->sc_dmat, data->rd_map);
658 bus_dmamap_destroy(sc->sc_dmat, data->rd_map); 658 bus_dmamap_destroy(sc->sc_dmat, data->rd_map);
659 } 659 }
660 if (data->rd_m != NULL) 660 if (data->rd_m != NULL)
661 m_freem(data->rd_m); 661 m_freem(data->rd_m);
662 } 662 }
663} 663}
664 664
665static int 665static int
666dwc_gmac_alloc_tx_ring(struct dwc_gmac_softc *sc, 666dwc_gmac_alloc_tx_ring(struct dwc_gmac_softc *sc,
667 struct dwc_gmac_tx_ring *ring) 667 struct dwc_gmac_tx_ring *ring)
668{ 668{
669 int i, error = 0; 669 int i, error = 0;
670 670
671 ring->t_queued = 0; 671 ring->t_queued = 0;
672 ring->t_cur = ring->t_next = 0; 672 ring->t_cur = ring->t_next = 0;
673 673
674 memset(ring->t_desc, 0, AWGE_TX_RING_COUNT*sizeof(*ring->t_desc)); 674 memset(ring->t_desc, 0, AWGE_TX_RING_COUNT*sizeof(*ring->t_desc));
675 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 675 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map,
676 TX_DESC_OFFSET(0), 676 TX_DESC_OFFSET(0),
677 AWGE_TX_RING_COUNT*sizeof(struct dwc_gmac_dev_dmadesc), 677 AWGE_TX_RING_COUNT*sizeof(struct dwc_gmac_dev_dmadesc),
678 BUS_DMASYNC_POSTWRITE); 678 BUS_DMASYNC_POSTWRITE);
679 679
680 for (i = 0; i < AWGE_TX_RING_COUNT; i++) { 680 for (i = 0; i < AWGE_TX_RING_COUNT; i++) {
681 error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 681 error = bus_dmamap_create(sc->sc_dmat, MCLBYTES,
682 AWGE_TX_RING_COUNT, MCLBYTES, 0, 682 AWGE_TX_RING_COUNT, MCLBYTES, 0,
683 BUS_DMA_NOWAIT | BUS_DMA_COHERENT, 683 BUS_DMA_NOWAIT | BUS_DMA_COHERENT,
684 &ring->t_data[i].td_map); 684 &ring->t_data[i].td_map);
685 if (error != 0) { 685 if (error != 0) {
686 aprint_error_dev(sc->sc_dev, 686 aprint_error_dev(sc->sc_dev,
687 "could not create TX DMA map #%d\n", i); 687 "could not create TX DMA map #%d\n", i);
688 ring->t_data[i].td_map = NULL; 688 ring->t_data[i].td_map = NULL;
689 goto fail; 689 goto fail;
690 } 690 }
691 ring->t_desc[i].ddesc_next = htole32( 691 ring->t_desc[i].ddesc_next = htole32(
692 ring->t_physaddr + sizeof(struct dwc_gmac_dev_dmadesc) 692 ring->t_physaddr + sizeof(struct dwc_gmac_dev_dmadesc)
693 *TX_NEXT(i)); 693 *TX_NEXT(i));
694 } 694 }
695 695
696 return 0; 696 return 0;
697 697
698fail: 698fail:
699 dwc_gmac_free_tx_ring(sc, ring); 699 dwc_gmac_free_tx_ring(sc, ring);
700 return error; 700 return error;
701} 701}
702 702
703static void 703static void
704dwc_gmac_txdesc_sync(struct dwc_gmac_softc *sc, int start, int end, int ops) 704dwc_gmac_txdesc_sync(struct dwc_gmac_softc *sc, int start, int end, int ops)
705{ 705{
706 /* 'end' is pointing one descriptor beyond the last we want to sync */ 706 /* 'end' is pointing one descriptor beyond the last we want to sync */
707 if (end > start) { 707 if (end > start) {
708 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 708 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map,
709 TX_DESC_OFFSET(start), 709 TX_DESC_OFFSET(start),
710 TX_DESC_OFFSET(end)-TX_DESC_OFFSET(start), 710 TX_DESC_OFFSET(end)-TX_DESC_OFFSET(start),
711 ops); 711 ops);
712 return; 712 return;
713 } 713 }
714 /* sync from 'start' to end of ring */ 714 /* sync from 'start' to end of ring */
715 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 715 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map,
716 TX_DESC_OFFSET(start), 716 TX_DESC_OFFSET(start),
717 TX_DESC_OFFSET(AWGE_TX_RING_COUNT)-TX_DESC_OFFSET(start), 717 TX_DESC_OFFSET(AWGE_TX_RING_COUNT)-TX_DESC_OFFSET(start),
718 ops); 718 ops);
719 if (TX_DESC_OFFSET(end) - TX_DESC_OFFSET(0) > 0) { 719 if (TX_DESC_OFFSET(end) - TX_DESC_OFFSET(0) > 0) {
720 /* sync from start of ring to 'end' */ 720 /* sync from start of ring to 'end' */
721 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 721 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map,
722 TX_DESC_OFFSET(0), 722 TX_DESC_OFFSET(0),
723 TX_DESC_OFFSET(end)-TX_DESC_OFFSET(0), 723 TX_DESC_OFFSET(end)-TX_DESC_OFFSET(0),
724 ops); 724 ops);
725 } 725 }
726} 726}
727 727
728static void 728static void
729dwc_gmac_reset_tx_ring(struct dwc_gmac_softc *sc, 729dwc_gmac_reset_tx_ring(struct dwc_gmac_softc *sc,
730 struct dwc_gmac_tx_ring *ring) 730 struct dwc_gmac_tx_ring *ring)
731{ 731{
732 int i; 732 int i;
733 733
734 mutex_enter(&ring->t_mtx); 734 mutex_enter(&ring->t_mtx);
735 for (i = 0; i < AWGE_TX_RING_COUNT; i++) { 735 for (i = 0; i < AWGE_TX_RING_COUNT; i++) {
736 struct dwc_gmac_tx_data *data = &ring->t_data[i]; 736 struct dwc_gmac_tx_data *data = &ring->t_data[i];
737 737
738 if (data->td_m != NULL) { 738 if (data->td_m != NULL) {
739 bus_dmamap_sync(sc->sc_dmat, data->td_active, 739 bus_dmamap_sync(sc->sc_dmat, data->td_active,
740 0, data->td_active->dm_mapsize, 740 0, data->td_active->dm_mapsize,
741 BUS_DMASYNC_POSTWRITE); 741 BUS_DMASYNC_POSTWRITE);
742 bus_dmamap_unload(sc->sc_dmat, data->td_active); 742 bus_dmamap_unload(sc->sc_dmat, data->td_active);
743 m_freem(data->td_m); 743 m_freem(data->td_m);
744 data->td_m = NULL; 744 data->td_m = NULL;
745 } 745 }
746 } 746 }
747 747
748 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 748 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map,
749 TX_DESC_OFFSET(0), 749 TX_DESC_OFFSET(0),
750 AWGE_TX_RING_COUNT*sizeof(struct dwc_gmac_dev_dmadesc), 750 AWGE_TX_RING_COUNT*sizeof(struct dwc_gmac_dev_dmadesc),
751 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 751 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
752 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_TX_ADDR, 752 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_TX_ADDR,
753 sc->sc_txq.t_physaddr); 753 sc->sc_txq.t_physaddr);
754 754
755 ring->t_queued = 0; 755 ring->t_queued = 0;
756 ring->t_cur = ring->t_next = 0; 756 ring->t_cur = ring->t_next = 0;
757 mutex_exit(&ring->t_mtx); 757 mutex_exit(&ring->t_mtx);
758} 758}
759 759
760static void 760static void
761dwc_gmac_free_tx_ring(struct dwc_gmac_softc *sc, 761dwc_gmac_free_tx_ring(struct dwc_gmac_softc *sc,
762 struct dwc_gmac_tx_ring *ring) 762 struct dwc_gmac_tx_ring *ring)
763{ 763{
764 int i; 764 int i;
765 765
766 /* unload the maps */ 766 /* unload the maps */
767 for (i = 0; i < AWGE_TX_RING_COUNT; i++) { 767 for (i = 0; i < AWGE_TX_RING_COUNT; i++) {
768 struct dwc_gmac_tx_data *data = &ring->t_data[i]; 768 struct dwc_gmac_tx_data *data = &ring->t_data[i];
769 769
770 if (data->td_m != NULL) { 770 if (data->td_m != NULL) {
771 bus_dmamap_sync(sc->sc_dmat, data->td_active, 771 bus_dmamap_sync(sc->sc_dmat, data->td_active,
772 0, data->td_map->dm_mapsize, 772 0, data->td_map->dm_mapsize,
773 BUS_DMASYNC_POSTWRITE); 773 BUS_DMASYNC_POSTWRITE);
774 bus_dmamap_unload(sc->sc_dmat, data->td_active); 774 bus_dmamap_unload(sc->sc_dmat, data->td_active);
775 m_freem(data->td_m); 775 m_freem(data->td_m);
776 data->td_m = NULL; 776 data->td_m = NULL;
777 } 777 }
778 } 778 }
779 779
780 /* and actually free them */ 780 /* and actually free them */
781 for (i = 0; i < AWGE_TX_RING_COUNT; i++) { 781 for (i = 0; i < AWGE_TX_RING_COUNT; i++) {
782 struct dwc_gmac_tx_data *data = &ring->t_data[i]; 782 struct dwc_gmac_tx_data *data = &ring->t_data[i];
783 783
784 bus_dmamap_destroy(sc->sc_dmat, data->td_map); 784 bus_dmamap_destroy(sc->sc_dmat, data->td_map);
785 } 785 }
786} 786}
787 787
788static void 788static void
789dwc_gmac_miibus_statchg(struct ifnet *ifp) 789dwc_gmac_miibus_statchg(struct ifnet *ifp)
790{ 790{
791 struct dwc_gmac_softc * const sc = ifp->if_softc; 791 struct dwc_gmac_softc * const sc = ifp->if_softc;
792 struct mii_data * const mii = &sc->sc_mii; 792 struct mii_data * const mii = &sc->sc_mii;
793 uint32_t conf, flow; 793 uint32_t conf, flow;
794 794
795 /* 795 /*
796 * Set MII or GMII interface based on the speed 796 * Set MII or GMII interface based on the speed
797 * negotiated by the PHY. 797 * negotiated by the PHY.
798 */ 798 */
799 conf = bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_CONF); 799 conf = bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_CONF);
800 conf &= ~(AWIN_GMAC_MAC_CONF_FES100 | AWIN_GMAC_MAC_CONF_MIISEL 800 conf &= ~(AWIN_GMAC_MAC_CONF_FES100 | AWIN_GMAC_MAC_CONF_MIISEL
801 | AWIN_GMAC_MAC_CONF_FULLDPLX); 801 | AWIN_GMAC_MAC_CONF_FULLDPLX);
802 conf |= AWIN_GMAC_MAC_CONF_FRAMEBURST 802 conf |= AWIN_GMAC_MAC_CONF_FRAMEBURST
803 | AWIN_GMAC_MAC_CONF_DISABLERXOWN 803 | AWIN_GMAC_MAC_CONF_DISABLERXOWN
804 | AWIN_GMAC_MAC_CONF_DISABLEJABBER 804 | AWIN_GMAC_MAC_CONF_DISABLEJABBER
805 | AWIN_GMAC_MAC_CONF_ACS 805 | AWIN_GMAC_MAC_CONF_ACS
806 | AWIN_GMAC_MAC_CONF_RXENABLE 806 | AWIN_GMAC_MAC_CONF_RXENABLE
807 | AWIN_GMAC_MAC_CONF_TXENABLE; 807 | AWIN_GMAC_MAC_CONF_TXENABLE;
808 switch (IFM_SUBTYPE(mii->mii_media_active)) { 808 switch (IFM_SUBTYPE(mii->mii_media_active)) {
809 case IFM_10_T: 809 case IFM_10_T:
810 conf |= AWIN_GMAC_MAC_CONF_MIISEL; 810 conf |= AWIN_GMAC_MAC_CONF_MIISEL;
811 break; 811 break;
812 case IFM_100_TX: 812 case IFM_100_TX:
813 conf |= AWIN_GMAC_MAC_CONF_FES100 | 813 conf |= AWIN_GMAC_MAC_CONF_FES100 |
814 AWIN_GMAC_MAC_CONF_MIISEL; 814 AWIN_GMAC_MAC_CONF_MIISEL;
815 break; 815 break;
816 case IFM_1000_T: 816 case IFM_1000_T:
817 break; 817 break;
818 } 818 }
819 if (sc->sc_set_speed) 819 if (sc->sc_set_speed)
820 sc->sc_set_speed(sc, IFM_SUBTYPE(mii->mii_media_active)); 820 sc->sc_set_speed(sc, IFM_SUBTYPE(mii->mii_media_active));
821 821
822 flow = 0; 822 flow = 0;
823 if (IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) { 823 if (IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) {
824 conf |= AWIN_GMAC_MAC_CONF_FULLDPLX; 824 conf |= AWIN_GMAC_MAC_CONF_FULLDPLX;
825 flow |= __SHIFTIN(0x200, AWIN_GMAC_MAC_FLOWCTRL_PAUSE); 825 flow |= __SHIFTIN(0x200, AWIN_GMAC_MAC_FLOWCTRL_PAUSE);
826 } 826 }
827 if (mii->mii_media_active & IFM_ETH_TXPAUSE) { 827 if (mii->mii_media_active & IFM_ETH_TXPAUSE) {
828 flow |= AWIN_GMAC_MAC_FLOWCTRL_TFE; 828 flow |= AWIN_GMAC_MAC_FLOWCTRL_TFE;
829 } 829 }
830 if (mii->mii_media_active & IFM_ETH_RXPAUSE) { 830 if (mii->mii_media_active & IFM_ETH_RXPAUSE) {
831 flow |= AWIN_GMAC_MAC_FLOWCTRL_RFE; 831 flow |= AWIN_GMAC_MAC_FLOWCTRL_RFE;
832 } 832 }
833 bus_space_write_4(sc->sc_bst, sc->sc_bsh, 833 bus_space_write_4(sc->sc_bst, sc->sc_bsh,
834 AWIN_GMAC_MAC_FLOWCTRL, flow); 834 AWIN_GMAC_MAC_FLOWCTRL, flow);
835 835
836#ifdef DWC_GMAC_DEBUG 836#ifdef DWC_GMAC_DEBUG
837 aprint_normal_dev(sc->sc_dev, 837 aprint_normal_dev(sc->sc_dev,
838 "setting MAC conf register: %08x\n", conf); 838 "setting MAC conf register: %08x\n", conf);
839#endif 839#endif
840 840
841 bus_space_write_4(sc->sc_bst, sc->sc_bsh, 841 bus_space_write_4(sc->sc_bst, sc->sc_bsh,
842 AWIN_GMAC_MAC_CONF, conf); 842 AWIN_GMAC_MAC_CONF, conf);
843} 843}
844 844
845static int 845static int
846dwc_gmac_init(struct ifnet *ifp) 846dwc_gmac_init(struct ifnet *ifp)
847{ 847{
848 struct dwc_gmac_softc *sc = ifp->if_softc; 848 struct dwc_gmac_softc *sc = ifp->if_softc;
849 849
850 mutex_enter(sc->sc_lock); 850 mutex_enter(sc->sc_lock);
851 int ret = dwc_gmac_init_locked(ifp); 851 int ret = dwc_gmac_init_locked(ifp);
852 mutex_exit(sc->sc_lock); 852 mutex_exit(sc->sc_lock);
853 853
854 return ret; 854 return ret;
855} 855}
856 856
857static int 857static int
858dwc_gmac_init_locked(struct ifnet *ifp) 858dwc_gmac_init_locked(struct ifnet *ifp)
859{ 859{
860 struct dwc_gmac_softc *sc = ifp->if_softc; 860 struct dwc_gmac_softc *sc = ifp->if_softc;
861 uint32_t ffilt; 861 uint32_t ffilt;
862 862
863 if (ifp->if_flags & IFF_RUNNING) 863 if (ifp->if_flags & IFF_RUNNING)
864 return 0; 864 return 0;
865 865
866 dwc_gmac_stop_locked(ifp, 0); 866 dwc_gmac_stop_locked(ifp, 0);
867 867
868 /* 868 /*
869 * Configure DMA burst/transfer mode and RX/TX priorities. 869 * Configure DMA burst/transfer mode and RX/TX priorities.
870 * XXX - the GMAC_BUSMODE_PRIORXTX bits are undocumented. 870 * XXX - the GMAC_BUSMODE_PRIORXTX bits are undocumented.
871 */ 871 */
872 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_BUSMODE, 872 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_BUSMODE,
873 GMAC_BUSMODE_FIXEDBURST | GMAC_BUSMODE_4PBL | 873 GMAC_BUSMODE_FIXEDBURST | GMAC_BUSMODE_4PBL |
874 __SHIFTIN(2, GMAC_BUSMODE_RPBL) | 874 __SHIFTIN(2, GMAC_BUSMODE_RPBL) |
875 __SHIFTIN(2, GMAC_BUSMODE_PBL)); 875 __SHIFTIN(2, GMAC_BUSMODE_PBL));
876 876
877 /* 877 /*
878 * Set up address filter 878 * Set up address filter
879 */ 879 */
880 ffilt = bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_FFILT); 880 ffilt = bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_FFILT);
881 if (ifp->if_flags & IFF_PROMISC) { 881 if (ifp->if_flags & IFF_PROMISC) {
882 ffilt |= AWIN_GMAC_MAC_FFILT_PR; 882 ffilt |= AWIN_GMAC_MAC_FFILT_PR;
883 } else { 883 } else {
884 ffilt &= ~AWIN_GMAC_MAC_FFILT_PR; 884 ffilt &= ~AWIN_GMAC_MAC_FFILT_PR;
885 } 885 }
886 if (ifp->if_flags & IFF_BROADCAST) { 886 if (ifp->if_flags & IFF_BROADCAST) {
887 ffilt &= ~AWIN_GMAC_MAC_FFILT_DBF; 887 ffilt &= ~AWIN_GMAC_MAC_FFILT_DBF;
888 } else { 888 } else {
889 ffilt |= AWIN_GMAC_MAC_FFILT_DBF; 889 ffilt |= AWIN_GMAC_MAC_FFILT_DBF;
890 } 890 }
891 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_FFILT, ffilt); 891 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_FFILT, ffilt);
892 892
893 /* 893 /*
894 * Set up multicast filter 894 * Set up multicast filter
895 */ 895 */
896 dwc_gmac_setmulti(sc); 896 dwc_gmac_setmulti(sc);
897 897
898 /* 898 /*
899 * Set up dma pointer for RX and TX ring 899 * Set up dma pointer for RX and TX ring
900 */ 900 */
901 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_RX_ADDR, 901 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_RX_ADDR,
902 sc->sc_rxq.r_physaddr); 902 sc->sc_rxq.r_physaddr);
903 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_TX_ADDR, 903 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_TX_ADDR,
904 sc->sc_txq.t_physaddr); 904 sc->sc_txq.t_physaddr);
905 905
906 /* 906 /*
907 * Start RX/TX part 907 * Start RX/TX part
908 */ 908 */
909 uint32_t opmode = GMAC_DMA_OP_RXSTART | GMAC_DMA_OP_TXSTART; 909 uint32_t opmode = GMAC_DMA_OP_RXSTART | GMAC_DMA_OP_TXSTART;
910 if ((sc->sc_flags & DWC_GMAC_FORCE_THRESH_DMA_MODE) == 0) { 910 if ((sc->sc_flags & DWC_GMAC_FORCE_THRESH_DMA_MODE) == 0) {
911 opmode |= GMAC_DMA_OP_RXSTOREFORWARD | GMAC_DMA_OP_TXSTOREFORWARD; 911 opmode |= GMAC_DMA_OP_RXSTOREFORWARD | GMAC_DMA_OP_TXSTOREFORWARD;
912 } 912 }
913 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_OPMODE, opmode); 913 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_OPMODE, opmode);
914 914
915 sc->sc_stopping = false; 915 sc->sc_stopping = false;
916 916
917 ifp->if_flags |= IFF_RUNNING; 917 ifp->if_flags |= IFF_RUNNING;
918 ifp->if_flags &= ~IFF_OACTIVE; 918 ifp->if_flags &= ~IFF_OACTIVE;
919 919
920 return 0; 920 return 0;
921} 921}
922 922
923static void 923static void
924dwc_gmac_start(struct ifnet *ifp) 924dwc_gmac_start(struct ifnet *ifp)
925{ 925{
926 struct dwc_gmac_softc *sc = ifp->if_softc; 926 struct dwc_gmac_softc *sc = ifp->if_softc;
927#ifdef DWCGMAC_MPSAFE 927#ifdef DWCGMAC_MPSAFE
928 KASSERT(if_is_mpsafe(ifp)); 928 KASSERT(if_is_mpsafe(ifp));
929#endif 929#endif
930 930
931 mutex_enter(sc->sc_lock); 931 mutex_enter(sc->sc_lock);
932 if (!sc->sc_stopping) { 932 if (!sc->sc_stopping) {
933 mutex_enter(&sc->sc_txq.t_mtx); 933 mutex_enter(&sc->sc_txq.t_mtx);
934 dwc_gmac_start_locked(ifp); 934 dwc_gmac_start_locked(ifp);
935 mutex_exit(&sc->sc_txq.t_mtx); 935 mutex_exit(&sc->sc_txq.t_mtx);
936 } 936 }
937 mutex_exit(sc->sc_lock); 937 mutex_exit(sc->sc_lock);
938} 938}
939 939
940static void 940static void
941dwc_gmac_start_locked(struct ifnet *ifp) 941dwc_gmac_start_locked(struct ifnet *ifp)
942{ 942{
943 struct dwc_gmac_softc *sc = ifp->if_softc; 943 struct dwc_gmac_softc *sc = ifp->if_softc;
944 int old = sc->sc_txq.t_queued; 944 int old = sc->sc_txq.t_queued;
945 int start = sc->sc_txq.t_cur; 945 int start = sc->sc_txq.t_cur;
946 struct mbuf *m0; 946 struct mbuf *m0;
947 947
948 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING) 948 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
949 return; 949 return;
950 950
951 for (;;) { 951 for (;;) {
952 IFQ_POLL(&ifp->if_snd, m0); 952 IFQ_POLL(&ifp->if_snd, m0);
953 if (m0 == NULL) 953 if (m0 == NULL)
954 break; 954 break;
955 if (dwc_gmac_queue(sc, m0) != 0) { 955 if (dwc_gmac_queue(sc, m0) != 0) {
956 ifp->if_flags |= IFF_OACTIVE; 956 ifp->if_flags |= IFF_OACTIVE;
957 break; 957 break;
958 } 958 }
959 IFQ_DEQUEUE(&ifp->if_snd, m0); 959 IFQ_DEQUEUE(&ifp->if_snd, m0);
960 bpf_mtap(ifp, m0, BPF_D_OUT); 960 bpf_mtap(ifp, m0, BPF_D_OUT);
961 if (sc->sc_txq.t_queued == AWGE_TX_RING_COUNT) { 961 if (sc->sc_txq.t_queued == AWGE_TX_RING_COUNT) {
962 ifp->if_flags |= IFF_OACTIVE; 962 ifp->if_flags |= IFF_OACTIVE;
963 break; 963 break;
964 } 964 }
965 } 965 }
966 966
967 if (sc->sc_txq.t_queued != old) { 967 if (sc->sc_txq.t_queued != old) {
968 /* packets have been queued, kick it off */ 968 /* packets have been queued, kick it off */
969 dwc_gmac_txdesc_sync(sc, start, sc->sc_txq.t_cur, 969 dwc_gmac_txdesc_sync(sc, start, sc->sc_txq.t_cur,
970 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 970 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
971 971
972#ifdef DWC_GMAC_DEBUG 972#ifdef DWC_GMAC_DEBUG
973 dwc_dump_status(sc); 973 dwc_dump_status(sc);
974#endif 974#endif
975 bus_space_write_4(sc->sc_bst, sc->sc_bsh, 975 bus_space_write_4(sc->sc_bst, sc->sc_bsh,
976 AWIN_GMAC_DMA_TXPOLL, ~0U); 976 AWIN_GMAC_DMA_TXPOLL, ~0U);
977 } 977 }
978} 978}
979 979
980static void 980static void
981dwc_gmac_stop(struct ifnet *ifp, int disable) 981dwc_gmac_stop(struct ifnet *ifp, int disable)
982{ 982{
983 struct dwc_gmac_softc *sc = ifp->if_softc; 983 struct dwc_gmac_softc *sc = ifp->if_softc;
984 984
985 mutex_enter(sc->sc_lock); 985 mutex_enter(sc->sc_lock);
986 dwc_gmac_stop_locked(ifp, disable); 986 dwc_gmac_stop_locked(ifp, disable);
987 mutex_exit(sc->sc_lock); 987 mutex_exit(sc->sc_lock);
988} 988}
989 989
990static void 990static void
991dwc_gmac_stop_locked(struct ifnet *ifp, int disable) 991dwc_gmac_stop_locked(struct ifnet *ifp, int disable)
992{ 992{
993 struct dwc_gmac_softc *sc = ifp->if_softc; 993 struct dwc_gmac_softc *sc = ifp->if_softc;
994 994
995 sc->sc_stopping = true; 995 sc->sc_stopping = true;
996 996
997 bus_space_write_4(sc->sc_bst, sc->sc_bsh, 997 bus_space_write_4(sc->sc_bst, sc->sc_bsh,
998 AWIN_GMAC_DMA_OPMODE, 998 AWIN_GMAC_DMA_OPMODE,
999 bus_space_read_4(sc->sc_bst, sc->sc_bsh, 999 bus_space_read_4(sc->sc_bst, sc->sc_bsh,
1000 AWIN_GMAC_DMA_OPMODE) 1000 AWIN_GMAC_DMA_OPMODE)
1001 & ~(GMAC_DMA_OP_TXSTART | GMAC_DMA_OP_RXSTART)); 1001 & ~(GMAC_DMA_OP_TXSTART | GMAC_DMA_OP_RXSTART));
1002 bus_space_write_4(sc->sc_bst, sc->sc_bsh, 1002 bus_space_write_4(sc->sc_bst, sc->sc_bsh,
1003 AWIN_GMAC_DMA_OPMODE, 1003 AWIN_GMAC_DMA_OPMODE,
1004 bus_space_read_4(sc->sc_bst, sc->sc_bsh, 1004 bus_space_read_4(sc->sc_bst, sc->sc_bsh,
1005 AWIN_GMAC_DMA_OPMODE) | GMAC_DMA_OP_FLUSHTX); 1005 AWIN_GMAC_DMA_OPMODE) | GMAC_DMA_OP_FLUSHTX);
1006 1006
1007 mii_down(&sc->sc_mii); 1007 mii_down(&sc->sc_mii);
1008 dwc_gmac_reset_tx_ring(sc, &sc->sc_txq); 1008 dwc_gmac_reset_tx_ring(sc, &sc->sc_txq);
1009 dwc_gmac_reset_rx_ring(sc, &sc->sc_rxq); 1009 dwc_gmac_reset_rx_ring(sc, &sc->sc_rxq);
1010 1010
1011 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 1011 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
1012} 1012}
1013 1013
1014/* 1014/*
1015 * Add m0 to the TX ring 1015 * Add m0 to the TX ring
1016 */ 1016 */
1017static int 1017static int
1018dwc_gmac_queue(struct dwc_gmac_softc *sc, struct mbuf *m0) 1018dwc_gmac_queue(struct dwc_gmac_softc *sc, struct mbuf *m0)
1019{ 1019{
1020 struct dwc_gmac_dev_dmadesc *desc = NULL; 1020 struct dwc_gmac_dev_dmadesc *desc = NULL;
1021 struct dwc_gmac_tx_data *data = NULL; 1021 struct dwc_gmac_tx_data *data = NULL;
1022 bus_dmamap_t map; 1022 bus_dmamap_t map;
1023 int error, i, first; 1023 int error, i, first;
1024 1024
1025#ifdef DWC_GMAC_DEBUG 1025#ifdef DWC_GMAC_DEBUG
1026 aprint_normal_dev(sc->sc_dev, 1026 aprint_normal_dev(sc->sc_dev,
1027 "dwc_gmac_queue: adding mbuf chain %p\n", m0); 1027 "dwc_gmac_queue: adding mbuf chain %p\n", m0);
1028#endif 1028#endif
1029 1029
1030 first = sc->sc_txq.t_cur; 1030 first = sc->sc_txq.t_cur;
1031 map = sc->sc_txq.t_data[first].td_map; 1031 map = sc->sc_txq.t_data[first].td_map;
1032 1032
1033 error = bus_dmamap_load_mbuf(sc->sc_dmat, map, m0, 1033 error = bus_dmamap_load_mbuf(sc->sc_dmat, map, m0,
1034 BUS_DMA_WRITE | BUS_DMA_NOWAIT); 1034 BUS_DMA_WRITE | BUS_DMA_NOWAIT);
1035 if (error != 0) { 1035 if (error != 0) {
1036 aprint_error_dev(sc->sc_dev, "could not map mbuf " 1036 aprint_error_dev(sc->sc_dev, "could not map mbuf "
1037 "(len: %d, error %d)\n", m0->m_pkthdr.len, error); 1037 "(len: %d, error %d)\n", m0->m_pkthdr.len, error);
1038 return error; 1038 return error;
1039 } 1039 }
1040 1040
1041 if (sc->sc_txq.t_queued + map->dm_nsegs > AWGE_TX_RING_COUNT) { 1041 if (sc->sc_txq.t_queued + map->dm_nsegs > AWGE_TX_RING_COUNT) {
1042 bus_dmamap_unload(sc->sc_dmat, map); 1042 bus_dmamap_unload(sc->sc_dmat, map);
1043 return ENOBUFS; 1043 return ENOBUFS;
1044 } 1044 }
1045 1045
1046 for (i = 0; i < map->dm_nsegs; i++) { 1046 for (i = 0; i < map->dm_nsegs; i++) {
1047 data = &sc->sc_txq.t_data[sc->sc_txq.t_cur]; 1047 data = &sc->sc_txq.t_data[sc->sc_txq.t_cur];
1048 desc = &sc->sc_txq.t_desc[sc->sc_txq.t_cur]; 1048 desc = &sc->sc_txq.t_desc[sc->sc_txq.t_cur];
1049 1049
1050 desc->ddesc_data = htole32(map->dm_segs[i].ds_addr); 1050 desc->ddesc_data = htole32(map->dm_segs[i].ds_addr);
1051 1051
1052#ifdef DWC_GMAC_DEBUG 1052#ifdef DWC_GMAC_DEBUG
1053 aprint_normal_dev(sc->sc_dev, "enqueing desc #%d data %08lx " 1053 aprint_normal_dev(sc->sc_dev, "enqueing desc #%d data %08lx "
1054 "len %lu\n", sc->sc_txq.t_cur, 1054 "len %lu\n", sc->sc_txq.t_cur,
1055 (unsigned long)map->dm_segs[i].ds_addr, 1055 (unsigned long)map->dm_segs[i].ds_addr,
1056 (unsigned long)map->dm_segs[i].ds_len); 1056 (unsigned long)map->dm_segs[i].ds_len);
1057#endif 1057#endif
1058 1058
1059 sc->sc_descm->tx_init_flags(desc); 1059 sc->sc_descm->tx_init_flags(desc);
1060 sc->sc_descm->tx_set_len(desc, map->dm_segs[i].ds_len); 1060 sc->sc_descm->tx_set_len(desc, map->dm_segs[i].ds_len);
1061 1061
1062 if (i == 0) 1062 if (i == 0)
1063 sc->sc_descm->tx_set_first_frag(desc); 1063 sc->sc_descm->tx_set_first_frag(desc);
1064 1064
1065 /* 1065 /*
1066 * Defer passing ownership of the first descriptor 1066 * Defer passing ownership of the first descriptor
1067 * until we are done. 1067 * until we are done.
1068 */ 1068 */
1069 if (i != 0) 1069 if (i != 0)
1070 sc->sc_descm->tx_set_owned_by_dev(desc); 1070 sc->sc_descm->tx_set_owned_by_dev(desc);
1071 1071
1072 sc->sc_txq.t_queued++; 1072 sc->sc_txq.t_queued++;
1073 sc->sc_txq.t_cur = TX_NEXT(sc->sc_txq.t_cur); 1073 sc->sc_txq.t_cur = TX_NEXT(sc->sc_txq.t_cur);
1074 } 1074 }
1075 1075
1076 sc->sc_descm->tx_set_last_frag(desc); 1076 sc->sc_descm->tx_set_last_frag(desc);
1077 1077
1078 data->td_m = m0; 1078 data->td_m = m0;
1079 data->td_active = map; 1079 data->td_active = map;
1080 1080
1081 bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize, 1081 bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize,
1082 BUS_DMASYNC_PREWRITE); 1082 BUS_DMASYNC_PREWRITE);
1083 1083
1084 /* Pass first to device */ 1084 /* Pass first to device */
1085 sc->sc_descm->tx_set_owned_by_dev(&sc->sc_txq.t_desc[first]); 1085 sc->sc_descm->tx_set_owned_by_dev(&sc->sc_txq.t_desc[first]);
1086 1086
1087 bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize, 1087 bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize,
1088 BUS_DMASYNC_PREWRITE); 1088 BUS_DMASYNC_PREWRITE);
1089 1089
1090 return 0; 1090 return 0;
1091} 1091}
1092 1092
1093/* 1093/*
1094 * If the interface is up and running, only modify the receive 1094 * If the interface is up and running, only modify the receive
1095 * filter when setting promiscuous or debug mode. Otherwise fall 1095 * filter when setting promiscuous or debug mode. Otherwise fall
1096 * through to ether_ioctl, which will reset the chip. 1096 * through to ether_ioctl, which will reset the chip.
1097 */ 1097 */
1098static int 1098static int
1099dwc_gmac_ifflags_cb(struct ethercom *ec) 1099dwc_gmac_ifflags_cb(struct ethercom *ec)
1100{ 1100{
1101 struct ifnet *ifp = &ec->ec_if; 1101 struct ifnet *ifp = &ec->ec_if;
1102 struct dwc_gmac_softc *sc = ifp->if_softc; 1102 struct dwc_gmac_softc *sc = ifp->if_softc;
1103 int ret = 0; 1103 int ret = 0;
1104 1104
1105 mutex_enter(sc->sc_lock); 1105 mutex_enter(sc->sc_lock);
1106 u_short change = ifp->if_flags ^ sc->sc_if_flags; 1106 u_short change = ifp->if_flags ^ sc->sc_if_flags;
1107 sc->sc_if_flags = ifp->if_flags; 1107 sc->sc_if_flags = ifp->if_flags;
1108 1108
1109 if ((change & ~(IFF_CANTCHANGE | IFF_DEBUG)) != 0) { 1109 if ((change & ~(IFF_CANTCHANGE | IFF_DEBUG)) != 0) {
1110 ret = ENETRESET; 1110 ret = ENETRESET;
1111 goto out; 1111 goto out;
1112 } 1112 }
1113 if ((change & IFF_PROMISC) != 0) { 1113 if ((change & IFF_PROMISC) != 0) {
1114 dwc_gmac_setmulti(sc); 1114 dwc_gmac_setmulti(sc);
1115 } 1115 }
1116out: 1116out:
1117 mutex_exit(sc->sc_lock); 1117 mutex_exit(sc->sc_lock);
1118 1118
1119 return ret; 1119 return ret;
1120} 1120}
1121 1121
1122static int 1122static int
1123dwc_gmac_ioctl(struct ifnet *ifp, u_long cmd, void *data) 1123dwc_gmac_ioctl(struct ifnet *ifp, u_long cmd, void *data)
1124{ 1124{
1125 struct dwc_gmac_softc *sc = ifp->if_softc; 1125 struct dwc_gmac_softc *sc = ifp->if_softc;
1126 int error = 0; 1126 int error = 0;
1127 1127
1128 int s = splnet(); 1128 int s = splnet();
1129 error = ether_ioctl(ifp, cmd, data); 1129 error = ether_ioctl(ifp, cmd, data);
1130 1130
1131#ifdef DWCGMAC_MPSAFE 1131#ifdef DWCGMAC_MPSAFE
1132 splx(s); 1132 splx(s);
1133#endif 1133#endif
1134 1134
1135 if (error == ENETRESET) { 1135 if (error == ENETRESET) {
1136 error = 0; 1136 error = 0;
1137 if (cmd != SIOCADDMULTI && cmd != SIOCDELMULTI) 1137 if (cmd != SIOCADDMULTI && cmd != SIOCDELMULTI)
1138 ; 1138 ;
1139 else if (ifp->if_flags & IFF_RUNNING) { 1139 else if (ifp->if_flags & IFF_RUNNING) {
1140 /* 1140 /*
1141 * Multicast list has changed; set the hardware filter 1141 * Multicast list has changed; set the hardware filter
1142 * accordingly. 1142 * accordingly.
1143 */ 1143 */
1144 mutex_enter(sc->sc_lock); 1144 mutex_enter(sc->sc_lock);
1145 dwc_gmac_setmulti(sc); 1145 dwc_gmac_setmulti(sc);
1146 mutex_exit(sc->sc_lock); 1146 mutex_exit(sc->sc_lock);
1147 } 1147 }
1148 } 1148 }
1149 1149
1150 /* Try to get things going again */ 1150 /* Try to get things going again */
1151 if (ifp->if_flags & IFF_UP) 1151 if (ifp->if_flags & IFF_UP)
1152 dwc_gmac_start(ifp); 1152 dwc_gmac_start(ifp);
1153 sc->sc_if_flags = sc->sc_ec.ec_if.if_flags; 1153 sc->sc_if_flags = sc->sc_ec.ec_if.if_flags;
1154 1154
1155#ifndef DWCGMAC_MPSAFE 1155#ifndef DWCGMAC_MPSAFE
1156 splx(s); 1156 splx(s);
1157#endif 1157#endif
1158 1158
1159 return error; 1159 return error;
1160} 1160}
1161 1161
1162static void 1162static void
1163dwc_gmac_tx_intr(struct dwc_gmac_softc *sc) 1163dwc_gmac_tx_intr(struct dwc_gmac_softc *sc)
1164{ 1164{
1165 struct ifnet *ifp = &sc->sc_ec.ec_if; 1165 struct ifnet *ifp = &sc->sc_ec.ec_if;
1166 struct dwc_gmac_tx_data *data; 1166 struct dwc_gmac_tx_data *data;
1167 struct dwc_gmac_dev_dmadesc *desc; 1167 struct dwc_gmac_dev_dmadesc *desc;
1168 int i, nsegs; 1168 int i, nsegs;
1169 1169
1170 mutex_enter(&sc->sc_txq.t_mtx); 1170 mutex_enter(&sc->sc_txq.t_mtx);
1171 1171
1172 for (i = sc->sc_txq.t_next; sc->sc_txq.t_queued > 0; i = TX_NEXT(i)) { 1172 for (i = sc->sc_txq.t_next; sc->sc_txq.t_queued > 0; i = TX_NEXT(i)) {
1173#ifdef DWC_GMAC_DEBUG 1173#ifdef DWC_GMAC_DEBUG
1174 aprint_normal_dev(sc->sc_dev, 1174 aprint_normal_dev(sc->sc_dev,
1175 "dwc_gmac_tx_intr: checking desc #%d (t_queued: %d)\n", 1175 "dwc_gmac_tx_intr: checking desc #%d (t_queued: %d)\n",
1176 i, sc->sc_txq.t_queued); 1176 i, sc->sc_txq.t_queued);
1177#endif 1177#endif
1178 1178
1179 /* 1179 /*
1180 * i+1 does not need to be a valid descriptor, 1180 * i+1 does not need to be a valid descriptor,
1181 * this is just a special notion to just sync 1181 * this is just a special notion to just sync
1182 * a single tx descriptor (i) 1182 * a single tx descriptor (i)
1183 */ 1183 */
1184 dwc_gmac_txdesc_sync(sc, i, i+1, 1184 dwc_gmac_txdesc_sync(sc, i, i+1,
1185 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); 1185 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
1186 1186
1187 desc = &sc->sc_txq.t_desc[i]; 1187 desc = &sc->sc_txq.t_desc[i];
1188 if (sc->sc_descm->tx_is_owned_by_dev(desc)) 1188 if (sc->sc_descm->tx_is_owned_by_dev(desc))
1189 break; 1189 break;
1190 1190
1191 data = &sc->sc_txq.t_data[i]; 1191 data = &sc->sc_txq.t_data[i];
1192 if (data->td_m == NULL) 1192 if (data->td_m == NULL)
1193 continue; 1193 continue;
1194 1194
1195 ifp->if_opackets++; 1195 if_statinc(ifp, if_opackets);
1196 nsegs = data->td_active->dm_nsegs; 1196 nsegs = data->td_active->dm_nsegs;
1197 bus_dmamap_sync(sc->sc_dmat, data->td_active, 0, 1197 bus_dmamap_sync(sc->sc_dmat, data->td_active, 0,
1198 data->td_active->dm_mapsize, BUS_DMASYNC_POSTWRITE); 1198 data->td_active->dm_mapsize, BUS_DMASYNC_POSTWRITE);
1199 bus_dmamap_unload(sc->sc_dmat, data->td_active); 1199 bus_dmamap_unload(sc->sc_dmat, data->td_active);
1200 1200
1201#ifdef DWC_GMAC_DEBUG 1201#ifdef DWC_GMAC_DEBUG
1202 aprint_normal_dev(sc->sc_dev, 1202 aprint_normal_dev(sc->sc_dev,
1203 "dwc_gmac_tx_intr: done with packet at desc #%d, " 1203 "dwc_gmac_tx_intr: done with packet at desc #%d, "
1204 "freeing mbuf %p\n", i, data->td_m); 1204 "freeing mbuf %p\n", i, data->td_m);
1205#endif 1205#endif
1206 1206
1207 m_freem(data->td_m); 1207 m_freem(data->td_m);
1208 data->td_m = NULL; 1208 data->td_m = NULL;
1209 1209
1210 sc->sc_txq.t_queued -= nsegs; 1210 sc->sc_txq.t_queued -= nsegs;
1211 } 1211 }
1212 1212
1213 sc->sc_txq.t_next = i; 1213 sc->sc_txq.t_next = i;
1214 1214
1215 if (sc->sc_txq.t_queued < AWGE_TX_RING_COUNT) { 1215 if (sc->sc_txq.t_queued < AWGE_TX_RING_COUNT) {
1216 ifp->if_flags &= ~IFF_OACTIVE; 1216 ifp->if_flags &= ~IFF_OACTIVE;
1217 } 1217 }
1218 mutex_exit(&sc->sc_txq.t_mtx); 1218 mutex_exit(&sc->sc_txq.t_mtx);
1219} 1219}
1220 1220
1221static void 1221static void
1222dwc_gmac_rx_intr(struct dwc_gmac_softc *sc) 1222dwc_gmac_rx_intr(struct dwc_gmac_softc *sc)
1223{ 1223{
1224 struct ifnet *ifp = &sc->sc_ec.ec_if; 1224 struct ifnet *ifp = &sc->sc_ec.ec_if;
1225 struct dwc_gmac_dev_dmadesc *desc; 1225 struct dwc_gmac_dev_dmadesc *desc;
1226 struct dwc_gmac_rx_data *data; 1226 struct dwc_gmac_rx_data *data;
1227 bus_addr_t physaddr; 1227 bus_addr_t physaddr;
1228 struct mbuf *m, *mnew; 1228 struct mbuf *m, *mnew;
1229 int i, len, error; 1229 int i, len, error;
1230 1230
1231 mutex_enter(&sc->sc_rxq.r_mtx); 1231 mutex_enter(&sc->sc_rxq.r_mtx);
1232 for (i = sc->sc_rxq.r_cur; ; i = RX_NEXT(i)) { 1232 for (i = sc->sc_rxq.r_cur; ; i = RX_NEXT(i)) {
1233 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 1233 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map,
1234 RX_DESC_OFFSET(i), sizeof(*desc), 1234 RX_DESC_OFFSET(i), sizeof(*desc),
1235 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); 1235 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
1236 desc = &sc->sc_rxq.r_desc[i]; 1236 desc = &sc->sc_rxq.r_desc[i];
1237 data = &sc->sc_rxq.r_data[i]; 1237 data = &sc->sc_rxq.r_data[i];
1238 1238
1239 if (sc->sc_descm->rx_is_owned_by_dev(desc)) 1239 if (sc->sc_descm->rx_is_owned_by_dev(desc))
1240 break; 1240 break;
1241 1241
1242 if (sc->sc_descm->rx_has_error(desc)) { 1242 if (sc->sc_descm->rx_has_error(desc)) {
1243#ifdef DWC_GMAC_DEBUG 1243#ifdef DWC_GMAC_DEBUG
1244 aprint_normal_dev(sc->sc_dev, 1244 aprint_normal_dev(sc->sc_dev,
1245 "RX error: descriptor status %08x, skipping\n", 1245 "RX error: descriptor status %08x, skipping\n",
1246 le32toh(desc->ddesc_status0)); 1246 le32toh(desc->ddesc_status0));
1247#endif 1247#endif
1248 ifp->if_ierrors++; 1248 if_statinc(ifp, if_ierrors);
1249 goto skip; 1249 goto skip;
1250 } 1250 }
1251 1251
1252 len = sc->sc_descm->rx_get_len(desc); 1252 len = sc->sc_descm->rx_get_len(desc);
1253 1253
1254#ifdef DWC_GMAC_DEBUG 1254#ifdef DWC_GMAC_DEBUG
1255 aprint_normal_dev(sc->sc_dev, 1255 aprint_normal_dev(sc->sc_dev,
1256 "rx int: device is done with descriptor #%d, len: %d\n", 1256 "rx int: device is done with descriptor #%d, len: %d\n",
1257 i, len); 1257 i, len);
1258#endif 1258#endif
1259 1259
1260 /* 1260 /*
1261 * Try to get a new mbuf before passing this one 1261 * Try to get a new mbuf before passing this one
1262 * up, if that fails, drop the packet and reuse 1262 * up, if that fails, drop the packet and reuse
1263 * the existing one. 1263 * the existing one.
1264 */ 1264 */
1265 MGETHDR(mnew, M_DONTWAIT, MT_DATA); 1265 MGETHDR(mnew, M_DONTWAIT, MT_DATA);
1266 if (mnew == NULL) { 1266 if (mnew == NULL) {
1267 ifp->if_ierrors++; 1267 if_statinc(ifp, if_ierrors);
1268 goto skip; 1268 goto skip;
1269 } 1269 }
1270 MCLGET(mnew, M_DONTWAIT); 1270 MCLGET(mnew, M_DONTWAIT);
1271 if ((mnew->m_flags & M_EXT) == 0) { 1271 if ((mnew->m_flags & M_EXT) == 0) {
1272 m_freem(mnew); 1272 m_freem(mnew);
1273 ifp->if_ierrors++; 1273 if_statinc(ifp, if_ierrors);
1274 goto skip; 1274 goto skip;
1275 } 1275 }
1276 mnew->m_len = mnew->m_pkthdr.len = mnew->m_ext.ext_size; 1276 mnew->m_len = mnew->m_pkthdr.len = mnew->m_ext.ext_size;
1277 if (mnew->m_len > AWGE_MAX_PACKET) { 1277 if (mnew->m_len > AWGE_MAX_PACKET) {
1278 mnew->m_len = mnew->m_pkthdr.len = AWGE_MAX_PACKET; 1278 mnew->m_len = mnew->m_pkthdr.len = AWGE_MAX_PACKET;
1279 } 1279 }
1280 1280
1281 /* unload old DMA map */ 1281 /* unload old DMA map */
1282 bus_dmamap_sync(sc->sc_dmat, data->rd_map, 0, 1282 bus_dmamap_sync(sc->sc_dmat, data->rd_map, 0,
1283 data->rd_map->dm_mapsize, BUS_DMASYNC_POSTREAD); 1283 data->rd_map->dm_mapsize, BUS_DMASYNC_POSTREAD);
1284 bus_dmamap_unload(sc->sc_dmat, data->rd_map); 1284 bus_dmamap_unload(sc->sc_dmat, data->rd_map);
1285 1285
1286 /* and reload with new mbuf */ 1286 /* and reload with new mbuf */
1287 error = bus_dmamap_load_mbuf(sc->sc_dmat, data->rd_map, 1287 error = bus_dmamap_load_mbuf(sc->sc_dmat, data->rd_map,
1288 mnew, BUS_DMA_READ | BUS_DMA_NOWAIT); 1288 mnew, BUS_DMA_READ | BUS_DMA_NOWAIT);
1289 if (error != 0) { 1289 if (error != 0) {
1290 m_freem(mnew); 1290 m_freem(mnew);
1291 /* try to reload old mbuf */ 1291 /* try to reload old mbuf */
1292 error = bus_dmamap_load_mbuf(sc->sc_dmat, data->rd_map, 1292 error = bus_dmamap_load_mbuf(sc->sc_dmat, data->rd_map,
1293 data->rd_m, BUS_DMA_READ | BUS_DMA_NOWAIT); 1293 data->rd_m, BUS_DMA_READ | BUS_DMA_NOWAIT);
1294 if (error != 0) { 1294 if (error != 0) {
1295 panic("%s: could not load old rx mbuf", 1295 panic("%s: could not load old rx mbuf",
1296 device_xname(sc->sc_dev)); 1296 device_xname(sc->sc_dev));
1297 } 1297 }
1298 ifp->if_ierrors++; 1298 if_statinc(ifp, if_ierrors);
1299 goto skip; 1299 goto skip;
1300 } 1300 }
1301 physaddr = data->rd_map->dm_segs[0].ds_addr; 1301 physaddr = data->rd_map->dm_segs[0].ds_addr;
1302 1302
1303 /* 1303 /*
1304 * New mbuf loaded, update RX ring and continue 1304 * New mbuf loaded, update RX ring and continue
1305 */ 1305 */
1306 m = data->rd_m; 1306 m = data->rd_m;
1307 data->rd_m = mnew; 1307 data->rd_m = mnew;
1308 desc->ddesc_data = htole32(physaddr); 1308 desc->ddesc_data = htole32(physaddr);
1309 1309
1310 /* finalize mbuf */ 1310 /* finalize mbuf */
1311 m->m_pkthdr.len = m->m_len = len; 1311 m->m_pkthdr.len = m->m_len = len;
1312 m_set_rcvif(m, ifp); 1312 m_set_rcvif(m, ifp);
1313 m->m_flags |= M_HASFCS; 1313 m->m_flags |= M_HASFCS;
1314 1314
1315 if_percpuq_enqueue(sc->sc_ipq, m); 1315 if_percpuq_enqueue(sc->sc_ipq, m);
1316 1316
1317skip: 1317skip:
1318 bus_dmamap_sync(sc->sc_dmat, data->rd_map, 0, 1318 bus_dmamap_sync(sc->sc_dmat, data->rd_map, 0,
1319 data->rd_map->dm_mapsize, BUS_DMASYNC_PREREAD); 1319 data->rd_map->dm_mapsize, BUS_DMASYNC_PREREAD);
1320 1320
1321 sc->sc_descm->rx_init_flags(desc); 1321 sc->sc_descm->rx_init_flags(desc);
1322 sc->sc_descm->rx_set_len(desc, data->rd_m->m_len); 1322 sc->sc_descm->rx_set_len(desc, data->rd_m->m_len);
1323 sc->sc_descm->rx_set_owned_by_dev(desc); 1323 sc->sc_descm->rx_set_owned_by_dev(desc);
1324 1324
1325 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 1325 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map,
1326 RX_DESC_OFFSET(i), sizeof(*desc), 1326 RX_DESC_OFFSET(i), sizeof(*desc),
1327 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 1327 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
1328 } 1328 }
1329 1329
1330 /* update RX pointer */ 1330 /* update RX pointer */
1331 sc->sc_rxq.r_cur = i; 1331 sc->sc_rxq.r_cur = i;
1332 1332
1333 mutex_exit(&sc->sc_rxq.r_mtx); 1333 mutex_exit(&sc->sc_rxq.r_mtx);
1334} 1334}
1335 1335
1336/* 1336/*
1337 * Reverse order of bits - http://aggregate.org/MAGIC/#Bit%20Reversal 1337 * Reverse order of bits - http://aggregate.org/MAGIC/#Bit%20Reversal
1338 */ 1338 */
1339static uint32_t 1339static uint32_t
1340bitrev32(uint32_t x) 1340bitrev32(uint32_t x)
1341{ 1341{
1342 x = (((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1)); 1342 x = (((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1));
1343 x = (((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2)); 1343 x = (((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2));
1344 x = (((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4)); 1344 x = (((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4));
1345 x = (((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8)); 1345 x = (((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8));
1346 1346
1347 return (x >> 16) | (x << 16); 1347 return (x >> 16) | (x << 16);
1348} 1348}
1349 1349
1350static void 1350static void
1351dwc_gmac_setmulti(struct dwc_gmac_softc *sc) 1351dwc_gmac_setmulti(struct dwc_gmac_softc *sc)
1352{ 1352{
1353 struct ifnet * const ifp = &sc->sc_ec.ec_if; 1353 struct ifnet * const ifp = &sc->sc_ec.ec_if;
1354 struct ether_multi *enm; 1354 struct ether_multi *enm;
1355 struct ether_multistep step; 1355 struct ether_multistep step;
1356 struct ethercom *ec = &sc->sc_ec; 1356 struct ethercom *ec = &sc->sc_ec;
1357 uint32_t hashes[2] = { 0, 0 }; 1357 uint32_t hashes[2] = { 0, 0 };
1358 uint32_t ffilt, h; 1358 uint32_t ffilt, h;
1359 int mcnt; 1359 int mcnt;
1360 1360
1361 KASSERT(mutex_owned(sc->sc_lock)); 1361 KASSERT(mutex_owned(sc->sc_lock));
1362 1362
1363 ffilt = bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_FFILT); 1363 ffilt = bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_FFILT);
1364 1364
1365 if (ifp->if_flags & IFF_PROMISC) { 1365 if (ifp->if_flags & IFF_PROMISC) {
1366 ffilt |= AWIN_GMAC_MAC_FFILT_PR; 1366 ffilt |= AWIN_GMAC_MAC_FFILT_PR;
1367 goto special_filter; 1367 goto special_filter;
1368 } 1368 }
1369 1369
1370 ffilt &= ~(AWIN_GMAC_MAC_FFILT_PM | AWIN_GMAC_MAC_FFILT_PR); 1370 ffilt &= ~(AWIN_GMAC_MAC_FFILT_PM | AWIN_GMAC_MAC_FFILT_PR);
1371 1371
1372 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTLOW, 0); 1372 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTLOW, 0);
1373 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTHIGH, 0); 1373 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTHIGH, 0);
1374 1374
1375 ETHER_LOCK(ec); 1375 ETHER_LOCK(ec);
1376 ec->ec_flags &= ~ETHER_F_ALLMULTI; 1376 ec->ec_flags &= ~ETHER_F_ALLMULTI;
1377 ETHER_FIRST_MULTI(step, ec, enm); 1377 ETHER_FIRST_MULTI(step, ec, enm);
1378 mcnt = 0; 1378 mcnt = 0;
1379 while (enm != NULL) { 1379 while (enm != NULL) {
1380 if (memcmp(enm->enm_addrlo, enm->enm_addrhi, 1380 if (memcmp(enm->enm_addrlo, enm->enm_addrhi,
1381 ETHER_ADDR_LEN) != 0) { 1381 ETHER_ADDR_LEN) != 0) {
1382 ffilt |= AWIN_GMAC_MAC_FFILT_PM; 1382 ffilt |= AWIN_GMAC_MAC_FFILT_PM;
1383 ec->ec_flags |= ETHER_F_ALLMULTI; 1383 ec->ec_flags |= ETHER_F_ALLMULTI;
1384 ETHER_UNLOCK(ec); 1384 ETHER_UNLOCK(ec);
1385 goto special_filter; 1385 goto special_filter;
1386 } 1386 }
1387 1387
1388 h = bitrev32( 1388 h = bitrev32(
1389 ~ether_crc32_le(enm->enm_addrlo, ETHER_ADDR_LEN) 1389 ~ether_crc32_le(enm->enm_addrlo, ETHER_ADDR_LEN)
1390 ) >> 26; 1390 ) >> 26;
1391 hashes[h >> 5] |= (1 << (h & 0x1f)); 1391 hashes[h >> 5] |= (1 << (h & 0x1f));
1392 1392
1393 mcnt++; 1393 mcnt++;
1394 ETHER_NEXT_MULTI(step, enm); 1394 ETHER_NEXT_MULTI(step, enm);
1395 } 1395 }
1396 ETHER_UNLOCK(ec); 1396 ETHER_UNLOCK(ec);
1397 1397
1398 if (mcnt) 1398 if (mcnt)
1399 ffilt |= AWIN_GMAC_MAC_FFILT_HMC; 1399 ffilt |= AWIN_GMAC_MAC_FFILT_HMC;
1400 else 1400 else
1401 ffilt &= ~AWIN_GMAC_MAC_FFILT_HMC; 1401 ffilt &= ~AWIN_GMAC_MAC_FFILT_HMC;
1402 1402
1403 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_FFILT, ffilt); 1403 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_FFILT, ffilt);
1404 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTLOW, 1404 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTLOW,
1405 hashes[0]); 1405 hashes[0]);
1406 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTHIGH, 1406 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTHIGH,
1407 hashes[1]); 1407 hashes[1]);
1408 sc->sc_if_flags = ifp->if_flags; 1408 sc->sc_if_flags = ifp->if_flags;
1409 1409
1410#ifdef DWC_GMAC_DEBUG 1410#ifdef DWC_GMAC_DEBUG
1411 dwc_gmac_dump_ffilt(sc, ffilt); 1411 dwc_gmac_dump_ffilt(sc, ffilt);
1412#endif 1412#endif
1413 return; 1413 return;
1414 1414
1415special_filter: 1415special_filter:
1416#ifdef DWC_GMAC_DEBUG 1416#ifdef DWC_GMAC_DEBUG
1417 dwc_gmac_dump_ffilt(sc, ffilt); 1417 dwc_gmac_dump_ffilt(sc, ffilt);
1418#endif 1418#endif
1419 /* no MAC hashes, ALLMULTI or PROMISC */ 1419 /* no MAC hashes, ALLMULTI or PROMISC */
1420 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_FFILT, 1420 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_FFILT,
1421 ffilt); 1421 ffilt);
1422 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTLOW, 1422 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTLOW,
1423 0xffffffff); 1423 0xffffffff);
1424 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTHIGH, 1424 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTHIGH,
1425 0xffffffff); 1425 0xffffffff);
1426 sc->sc_if_flags = sc->sc_ec.ec_if.if_flags; 1426 sc->sc_if_flags = sc->sc_ec.ec_if.if_flags;
1427} 1427}
1428 1428
1429int 1429int
1430dwc_gmac_intr(struct dwc_gmac_softc *sc) 1430dwc_gmac_intr(struct dwc_gmac_softc *sc)
1431{ 1431{
1432 uint32_t status, dma_status; 1432 uint32_t status, dma_status;
1433 int rv = 0; 1433 int rv = 0;
1434 1434
1435 if (sc->sc_stopping) 1435 if (sc->sc_stopping)
1436 return 0; 1436 return 0;
1437 1437
1438 status = bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_INTR); 1438 status = bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_INTR);
1439 if (status & AWIN_GMAC_MII_IRQ) { 1439 if (status & AWIN_GMAC_MII_IRQ) {
1440 (void)bus_space_read_4(sc->sc_bst, sc->sc_bsh, 1440 (void)bus_space_read_4(sc->sc_bst, sc->sc_bsh,
1441 AWIN_GMAC_MII_STATUS); 1441 AWIN_GMAC_MII_STATUS);
1442 rv = 1; 1442 rv = 1;
1443 mii_pollstat(&sc->sc_mii); 1443 mii_pollstat(&sc->sc_mii);
1444 } 1444 }
1445 1445
1446 dma_status = bus_space_read_4(sc->sc_bst, sc->sc_bsh, 1446 dma_status = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
1447 AWIN_GMAC_DMA_STATUS); 1447 AWIN_GMAC_DMA_STATUS);
1448 1448
1449 if (dma_status & (GMAC_DMA_INT_NIE | GMAC_DMA_INT_AIE)) 1449 if (dma_status & (GMAC_DMA_INT_NIE | GMAC_DMA_INT_AIE))
1450 rv = 1; 1450 rv = 1;
1451 1451
1452 if (dma_status & GMAC_DMA_INT_TIE) 1452 if (dma_status & GMAC_DMA_INT_TIE)
1453 dwc_gmac_tx_intr(sc); 1453 dwc_gmac_tx_intr(sc);
1454 1454
1455 if (dma_status & GMAC_DMA_INT_RIE) 1455 if (dma_status & GMAC_DMA_INT_RIE)
1456 dwc_gmac_rx_intr(sc); 1456 dwc_gmac_rx_intr(sc);
1457 1457
1458 /* 1458 /*
1459 * Check error conditions 1459 * Check error conditions
1460 */ 1460 */
1461 if (dma_status & GMAC_DMA_INT_ERRORS) { 1461 if (dma_status & GMAC_DMA_INT_ERRORS) {
1462 sc->sc_ec.ec_if.if_oerrors++; 1462 if_statinc(&sc->sc_ec.ec_if, if_oerrors);
1463#ifdef DWC_GMAC_DEBUG 1463#ifdef DWC_GMAC_DEBUG
1464 dwc_dump_and_abort(sc, "interrupt error condition"); 1464 dwc_dump_and_abort(sc, "interrupt error condition");
1465#endif 1465#endif
1466 } 1466 }
1467 1467
1468 rnd_add_uint32(&sc->rnd_source, dma_status); 1468 rnd_add_uint32(&sc->rnd_source, dma_status);
1469 1469
1470 /* ack interrupt */ 1470 /* ack interrupt */
1471 if (dma_status) 1471 if (dma_status)
1472 bus_space_write_4(sc->sc_bst, sc->sc_bsh, 1472 bus_space_write_4(sc->sc_bst, sc->sc_bsh,
1473 AWIN_GMAC_DMA_STATUS, dma_status & GMAC_DMA_INT_MASK); 1473 AWIN_GMAC_DMA_STATUS, dma_status & GMAC_DMA_INT_MASK);
1474 1474
1475 /* 1475 /*
1476 * Get more packets 1476 * Get more packets
1477 */ 1477 */
1478 if (rv) 1478 if (rv)
1479 if_schedule_deferred_start(&sc->sc_ec.ec_if); 1479 if_schedule_deferred_start(&sc->sc_ec.ec_if);
1480 1480
1481 return rv; 1481 return rv;
1482} 1482}
1483 1483
1484static void 1484static void
1485dwc_gmac_desc_set_owned_by_dev(struct dwc_gmac_dev_dmadesc *desc) 1485dwc_gmac_desc_set_owned_by_dev(struct dwc_gmac_dev_dmadesc *desc)
1486{ 1486{
1487 1487
1488 desc->ddesc_status0 |= htole32(DDESC_STATUS_OWNEDBYDEV); 1488 desc->ddesc_status0 |= htole32(DDESC_STATUS_OWNEDBYDEV);
1489} 1489}
1490 1490
1491static int 1491static int
1492dwc_gmac_desc_is_owned_by_dev(struct dwc_gmac_dev_dmadesc *desc) 1492dwc_gmac_desc_is_owned_by_dev(struct dwc_gmac_dev_dmadesc *desc)
1493{ 1493{
1494 1494
1495 return !!(le32toh(desc->ddesc_status0) & DDESC_STATUS_OWNEDBYDEV); 1495 return !!(le32toh(desc->ddesc_status0) & DDESC_STATUS_OWNEDBYDEV);
1496} 1496}
1497 1497
1498static void 1498static void
1499dwc_gmac_desc_std_set_len(struct dwc_gmac_dev_dmadesc *desc, int len) 1499dwc_gmac_desc_std_set_len(struct dwc_gmac_dev_dmadesc *desc, int len)
1500{ 1500{
1501 uint32_t cntl = le32toh(desc->ddesc_cntl1); 1501 uint32_t cntl = le32toh(desc->ddesc_cntl1);
1502 1502
1503 desc->ddesc_cntl1 = htole32((cntl & ~DDESC_CNTL_SIZE1MASK) | 1503 desc->ddesc_cntl1 = htole32((cntl & ~DDESC_CNTL_SIZE1MASK) |
1504 __SHIFTIN(len, DDESC_CNTL_SIZE1MASK)); 1504 __SHIFTIN(len, DDESC_CNTL_SIZE1MASK));
1505} 1505}
1506 1506
1507static uint32_t 1507static uint32_t
1508dwc_gmac_desc_std_get_len(struct dwc_gmac_dev_dmadesc *desc) 1508dwc_gmac_desc_std_get_len(struct dwc_gmac_dev_dmadesc *desc)
1509{ 1509{
1510 1510
1511 return __SHIFTOUT(le32toh(desc->ddesc_status0), DDESC_STATUS_FRMLENMSK); 1511 return __SHIFTOUT(le32toh(desc->ddesc_status0), DDESC_STATUS_FRMLENMSK);
1512} 1512}
1513 1513
1514static void 1514static void
1515dwc_gmac_desc_std_tx_init_flags(struct dwc_gmac_dev_dmadesc *desc) 1515dwc_gmac_desc_std_tx_init_flags(struct dwc_gmac_dev_dmadesc *desc)
1516{ 1516{
1517 1517
1518 desc->ddesc_status0 = 0; 1518 desc->ddesc_status0 = 0;
1519 desc->ddesc_cntl1 = htole32(DDESC_CNTL_TXCHAIN); 1519 desc->ddesc_cntl1 = htole32(DDESC_CNTL_TXCHAIN);
1520} 1520}
1521 1521
1522static void 1522static void
1523dwc_gmac_desc_std_tx_set_first_frag(struct dwc_gmac_dev_dmadesc *desc) 1523dwc_gmac_desc_std_tx_set_first_frag(struct dwc_gmac_dev_dmadesc *desc)
1524{ 1524{
1525 uint32_t cntl = le32toh(desc->ddesc_cntl1); 1525 uint32_t cntl = le32toh(desc->ddesc_cntl1);
1526 1526
1527 desc->ddesc_cntl1 = htole32(cntl | DDESC_CNTL_TXFIRST); 1527 desc->ddesc_cntl1 = htole32(cntl | DDESC_CNTL_TXFIRST);
1528} 1528}
1529 1529
1530static void 1530static void
1531dwc_gmac_desc_std_tx_set_last_frag(struct dwc_gmac_dev_dmadesc *desc) 1531dwc_gmac_desc_std_tx_set_last_frag(struct dwc_gmac_dev_dmadesc *desc)
1532{ 1532{
1533 uint32_t cntl = le32toh(desc->ddesc_cntl1); 1533 uint32_t cntl = le32toh(desc->ddesc_cntl1);
1534 1534
1535 desc->ddesc_cntl1 = htole32(cntl | 1535 desc->ddesc_cntl1 = htole32(cntl |
1536 DDESC_CNTL_TXLAST | DDESC_CNTL_TXINT); 1536 DDESC_CNTL_TXLAST | DDESC_CNTL_TXINT);
1537} 1537}
1538 1538
1539static void 1539static void
1540dwc_gmac_desc_std_rx_init_flags(struct dwc_gmac_dev_dmadesc *desc) 1540dwc_gmac_desc_std_rx_init_flags(struct dwc_gmac_dev_dmadesc *desc)
1541{ 1541{
1542 1542
1543 desc->ddesc_status0 = 0; 1543 desc->ddesc_status0 = 0;
1544 desc->ddesc_cntl1 = htole32(DDESC_CNTL_TXCHAIN); 1544 desc->ddesc_cntl1 = htole32(DDESC_CNTL_TXCHAIN);
1545} 1545}
1546 1546
1547static int 1547static int
1548dwc_gmac_desc_std_rx_has_error(struct dwc_gmac_dev_dmadesc *desc) { 1548dwc_gmac_desc_std_rx_has_error(struct dwc_gmac_dev_dmadesc *desc) {
1549 return !!(le32toh(desc->ddesc_status0) & 1549 return !!(le32toh(desc->ddesc_status0) &
1550 (DDESC_STATUS_RXERROR | DDESC_STATUS_RXTRUNCATED)); 1550 (DDESC_STATUS_RXERROR | DDESC_STATUS_RXTRUNCATED));
1551} 1551}
1552 1552
1553static void 1553static void
1554dwc_gmac_desc_enh_set_len(struct dwc_gmac_dev_dmadesc *desc, int len) 1554dwc_gmac_desc_enh_set_len(struct dwc_gmac_dev_dmadesc *desc, int len)
1555{ 1555{
1556 uint32_t tdes1 = le32toh(desc->ddesc_cntl1); 1556 uint32_t tdes1 = le32toh(desc->ddesc_cntl1);
1557 1557
1558 desc->ddesc_cntl1 = htole32((tdes1 & ~DDESC_DES1_SIZE1MASK) | 1558 desc->ddesc_cntl1 = htole32((tdes1 & ~DDESC_DES1_SIZE1MASK) |
1559 __SHIFTIN(len, DDESC_DES1_SIZE1MASK)); 1559 __SHIFTIN(len, DDESC_DES1_SIZE1MASK));
1560} 1560}
1561 1561
1562static uint32_t 1562static uint32_t
1563dwc_gmac_desc_enh_get_len(struct dwc_gmac_dev_dmadesc *desc) 1563dwc_gmac_desc_enh_get_len(struct dwc_gmac_dev_dmadesc *desc)
1564{ 1564{
1565 1565
1566 return __SHIFTOUT(le32toh(desc->ddesc_status0), DDESC_RDES0_FL); 1566 return __SHIFTOUT(le32toh(desc->ddesc_status0), DDESC_RDES0_FL);
1567} 1567}
1568 1568
1569static void 1569static void
1570dwc_gmac_desc_enh_tx_init_flags(struct dwc_gmac_dev_dmadesc *desc) 1570dwc_gmac_desc_enh_tx_init_flags(struct dwc_gmac_dev_dmadesc *desc)
1571{ 1571{
1572 1572
1573 desc->ddesc_status0 = htole32(DDESC_TDES0_TCH); 1573 desc->ddesc_status0 = htole32(DDESC_TDES0_TCH);
1574 desc->ddesc_cntl1 = 0; 1574 desc->ddesc_cntl1 = 0;
1575} 1575}
1576 1576
1577static void 1577static void
1578dwc_gmac_desc_enh_tx_set_first_frag(struct dwc_gmac_dev_dmadesc *desc) 1578dwc_gmac_desc_enh_tx_set_first_frag(struct dwc_gmac_dev_dmadesc *desc)
1579{ 1579{
1580 uint32_t tdes0 = le32toh(desc->ddesc_status0); 1580 uint32_t tdes0 = le32toh(desc->ddesc_status0);
1581 1581
1582 desc->ddesc_status0 = htole32(tdes0 | DDESC_TDES0_FS); 1582 desc->ddesc_status0 = htole32(tdes0 | DDESC_TDES0_FS);
1583} 1583}
1584 1584
1585static void 1585static void
1586dwc_gmac_desc_enh_tx_set_last_frag(struct dwc_gmac_dev_dmadesc *desc) 1586dwc_gmac_desc_enh_tx_set_last_frag(struct dwc_gmac_dev_dmadesc *desc)
1587{ 1587{
1588 uint32_t tdes0 = le32toh(desc->ddesc_status0); 1588 uint32_t tdes0 = le32toh(desc->ddesc_status0);
1589 1589
1590 desc->ddesc_status0 = htole32(tdes0 | DDESC_TDES0_LS | DDESC_TDES0_IC); 1590 desc->ddesc_status0 = htole32(tdes0 | DDESC_TDES0_LS | DDESC_TDES0_IC);
1591} 1591}
1592 1592
1593static void 1593static void
1594dwc_gmac_desc_enh_rx_init_flags(struct dwc_gmac_dev_dmadesc *desc) 1594dwc_gmac_desc_enh_rx_init_flags(struct dwc_gmac_dev_dmadesc *desc)
1595{ 1595{
1596 1596
1597 desc->ddesc_status0 = 0; 1597 desc->ddesc_status0 = 0;
1598 desc->ddesc_cntl1 = htole32(DDESC_RDES1_RCH); 1598 desc->ddesc_cntl1 = htole32(DDESC_RDES1_RCH);
1599} 1599}
1600 1600
1601static int 1601static int
1602dwc_gmac_desc_enh_rx_has_error(struct dwc_gmac_dev_dmadesc *desc) 1602dwc_gmac_desc_enh_rx_has_error(struct dwc_gmac_dev_dmadesc *desc)
1603{ 1603{
1604 1604
1605 return !!(le32toh(desc->ddesc_status0) & 1605 return !!(le32toh(desc->ddesc_status0) &
1606 (DDESC_RDES0_ES | DDESC_RDES0_LE)); 1606 (DDESC_RDES0_ES | DDESC_RDES0_LE));
1607} 1607}
1608 1608
1609#ifdef DWC_GMAC_DEBUG 1609#ifdef DWC_GMAC_DEBUG
1610static void 1610static void
1611dwc_gmac_dump_dma(struct dwc_gmac_softc *sc) 1611dwc_gmac_dump_dma(struct dwc_gmac_softc *sc)
1612{ 1612{
1613 aprint_normal_dev(sc->sc_dev, "busmode: %08x\n", 1613 aprint_normal_dev(sc->sc_dev, "busmode: %08x\n",
1614 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_BUSMODE)); 1614 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_BUSMODE));
1615 aprint_normal_dev(sc->sc_dev, "tx poll: %08x\n", 1615 aprint_normal_dev(sc->sc_dev, "tx poll: %08x\n",
1616 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_TXPOLL)); 1616 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_TXPOLL));
1617 aprint_normal_dev(sc->sc_dev, "rx poll: %08x\n", 1617 aprint_normal_dev(sc->sc_dev, "rx poll: %08x\n",
1618 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_RXPOLL)); 1618 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_RXPOLL));
1619 aprint_normal_dev(sc->sc_dev, "rx descriptors: %08x\n", 1619 aprint_normal_dev(sc->sc_dev, "rx descriptors: %08x\n",
1620 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_RX_ADDR)); 1620 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_RX_ADDR));
1621 aprint_normal_dev(sc->sc_dev, "tx descriptors: %08x\n", 1621 aprint_normal_dev(sc->sc_dev, "tx descriptors: %08x\n",
1622 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_TX_ADDR)); 1622 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_TX_ADDR));
1623 aprint_normal_dev(sc->sc_dev, "status: %08x\n", 1623 aprint_normal_dev(sc->sc_dev, "status: %08x\n",
1624 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_STATUS)); 1624 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_STATUS));
1625 aprint_normal_dev(sc->sc_dev, "op mode: %08x\n", 1625 aprint_normal_dev(sc->sc_dev, "op mode: %08x\n",
1626 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_OPMODE)); 1626 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_OPMODE));
1627 aprint_normal_dev(sc->sc_dev, "int enable: %08x\n", 1627 aprint_normal_dev(sc->sc_dev, "int enable: %08x\n",
1628 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_INTENABLE)); 1628 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_INTENABLE));
1629 aprint_normal_dev(sc->sc_dev, "cur tx: %08x\n", 1629 aprint_normal_dev(sc->sc_dev, "cur tx: %08x\n",
1630 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_CUR_TX_DESC)); 1630 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_CUR_TX_DESC));
1631 aprint_normal_dev(sc->sc_dev, "cur rx: %08x\n", 1631 aprint_normal_dev(sc->sc_dev, "cur rx: %08x\n",
1632 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_CUR_RX_DESC)); 1632 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_CUR_RX_DESC));
1633 aprint_normal_dev(sc->sc_dev, "cur tx buffer: %08x\n", 1633 aprint_normal_dev(sc->sc_dev, "cur tx buffer: %08x\n",
1634 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_CUR_TX_BUFADDR)); 1634 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_CUR_TX_BUFADDR));
1635 aprint_normal_dev(sc->sc_dev, "cur rx buffer: %08x\n", 1635 aprint_normal_dev(sc->sc_dev, "cur rx buffer: %08x\n",
1636 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_CUR_RX_BUFADDR)); 1636 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_CUR_RX_BUFADDR));
1637} 1637}
1638 1638
1639static void 1639static void
1640dwc_gmac_dump_tx_desc(struct dwc_gmac_softc *sc) 1640dwc_gmac_dump_tx_desc(struct dwc_gmac_softc *sc)
1641{ 1641{
1642 int i; 1642 int i;
1643 1643
1644 aprint_normal_dev(sc->sc_dev, "TX queue: cur=%d, next=%d, queued=%d\n", 1644 aprint_normal_dev(sc->sc_dev, "TX queue: cur=%d, next=%d, queued=%d\n",
1645 sc->sc_txq.t_cur, sc->sc_txq.t_next, sc->sc_txq.t_queued); 1645 sc->sc_txq.t_cur, sc->sc_txq.t_next, sc->sc_txq.t_queued);
1646 aprint_normal_dev(sc->sc_dev, "TX DMA descriptors:\n"); 1646 aprint_normal_dev(sc->sc_dev, "TX DMA descriptors:\n");
1647 for (i = 0; i < AWGE_TX_RING_COUNT; i++) { 1647 for (i = 0; i < AWGE_TX_RING_COUNT; i++) {
1648 struct dwc_gmac_dev_dmadesc *desc = &sc->sc_txq.t_desc[i]; 1648 struct dwc_gmac_dev_dmadesc *desc = &sc->sc_txq.t_desc[i];
1649 aprint_normal("#%d (%08lx): status: %08x cntl: %08x " 1649 aprint_normal("#%d (%08lx): status: %08x cntl: %08x "
1650 "data: %08x next: %08x\n", 1650 "data: %08x next: %08x\n",
1651 i, sc->sc_txq.t_physaddr + 1651 i, sc->sc_txq.t_physaddr +
1652 i*sizeof(struct dwc_gmac_dev_dmadesc), 1652 i*sizeof(struct dwc_gmac_dev_dmadesc),
1653 le32toh(desc->ddesc_status0), le32toh(desc->ddesc_cntl1), 1653 le32toh(desc->ddesc_status0), le32toh(desc->ddesc_cntl1),
1654 le32toh(desc->ddesc_data), le32toh(desc->ddesc_next)); 1654 le32toh(desc->ddesc_data), le32toh(desc->ddesc_next));
1655 } 1655 }
1656} 1656}
1657 1657
1658static void 1658static void
1659dwc_gmac_dump_rx_desc(struct dwc_gmac_softc *sc) 1659dwc_gmac_dump_rx_desc(struct dwc_gmac_softc *sc)
1660{ 1660{
1661 int i; 1661 int i;
1662 1662
1663 aprint_normal_dev(sc->sc_dev, "RX queue: cur=%d, next=%d\n", 1663 aprint_normal_dev(sc->sc_dev, "RX queue: cur=%d, next=%d\n",
1664 sc->sc_rxq.r_cur, sc->sc_rxq.r_next); 1664 sc->sc_rxq.r_cur, sc->sc_rxq.r_next);
1665 aprint_normal_dev(sc->sc_dev, "RX DMA descriptors:\n"); 1665 aprint_normal_dev(sc->sc_dev, "RX DMA descriptors:\n");
1666 for (i = 0; i < AWGE_RX_RING_COUNT; i++) { 1666 for (i = 0; i < AWGE_RX_RING_COUNT; i++) {
1667 struct dwc_gmac_dev_dmadesc *desc = &sc->sc_rxq.r_desc[i]; 1667 struct dwc_gmac_dev_dmadesc *desc = &sc->sc_rxq.r_desc[i];
1668 aprint_normal("#%d (%08lx): status: %08x cntl: %08x " 1668 aprint_normal("#%d (%08lx): status: %08x cntl: %08x "
1669 "data: %08x next: %08x\n", 1669 "data: %08x next: %08x\n",
1670 i, sc->sc_rxq.r_physaddr + 1670 i, sc->sc_rxq.r_physaddr +
1671 i*sizeof(struct dwc_gmac_dev_dmadesc), 1671 i*sizeof(struct dwc_gmac_dev_dmadesc),
1672 le32toh(desc->ddesc_status0), le32toh(desc->ddesc_cntl1), 1672 le32toh(desc->ddesc_status0), le32toh(desc->ddesc_cntl1),
1673 le32toh(desc->ddesc_data), le32toh(desc->ddesc_next)); 1673 le32toh(desc->ddesc_data), le32toh(desc->ddesc_next));
1674 } 1674 }
1675} 1675}
1676 1676
1677static void 1677static void
1678dwc_dump_status(struct dwc_gmac_softc *sc) 1678dwc_dump_status(struct dwc_gmac_softc *sc)
1679{ 1679{
1680 uint32_t status = bus_space_read_4(sc->sc_bst, sc->sc_bsh, 1680 uint32_t status = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
1681 AWIN_GMAC_MAC_INTR); 1681 AWIN_GMAC_MAC_INTR);
1682 uint32_t dma_status = bus_space_read_4(sc->sc_bst, sc->sc_bsh, 1682 uint32_t dma_status = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
1683 AWIN_GMAC_DMA_STATUS); 1683 AWIN_GMAC_DMA_STATUS);
1684 char buf[200]; 1684 char buf[200];
1685 1685
1686 /* print interrupt state */ 1686 /* print interrupt state */
1687 snprintb(buf, sizeof(buf), "\177\20" 1687 snprintb(buf, sizeof(buf), "\177\20"
1688 "b\x10""NI\0" 1688 "b\x10""NI\0"
1689 "b\x0f""AI\0" 1689 "b\x0f""AI\0"
1690 "b\x0e""ER\0" 1690 "b\x0e""ER\0"
1691 "b\x0d""FB\0" 1691 "b\x0d""FB\0"
1692 "b\x0a""ET\0" 1692 "b\x0a""ET\0"
1693 "b\x09""RW\0" 1693 "b\x09""RW\0"
1694 "b\x08""RS\0" 1694 "b\x08""RS\0"
1695 "b\x07""RU\0" 1695 "b\x07""RU\0"
1696 "b\x06""RI\0" 1696 "b\x06""RI\0"
1697 "b\x05""UN\0" 1697 "b\x05""UN\0"
1698 "b\x04""OV\0" 1698 "b\x04""OV\0"
1699 "b\x03""TJ\0" 1699 "b\x03""TJ\0"
1700 "b\x02""TU\0" 1700 "b\x02""TU\0"
1701 "b\x01""TS\0" 1701 "b\x01""TS\0"
1702 "b\x00""TI\0" 1702 "b\x00""TI\0"
1703 "\0", dma_status); 1703 "\0", dma_status);
1704 aprint_normal_dev(sc->sc_dev, "INTR status: %08x, DMA status: %s\n", 1704 aprint_normal_dev(sc->sc_dev, "INTR status: %08x, DMA status: %s\n",
1705 status, buf); 1705 status, buf);
1706} 1706}
1707 1707
1708static void 1708static void
1709dwc_dump_and_abort(struct dwc_gmac_softc *sc, const char *msg) 1709dwc_dump_and_abort(struct dwc_gmac_softc *sc, const char *msg)
1710{ 1710{
1711 dwc_dump_status(sc); 1711 dwc_dump_status(sc);
1712 dwc_gmac_dump_ffilt(sc, 1712 dwc_gmac_dump_ffilt(sc,
1713 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_FFILT)); 1713 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_FFILT));
1714 dwc_gmac_dump_dma(sc); 1714 dwc_gmac_dump_dma(sc);
1715 dwc_gmac_dump_tx_desc(sc); 1715 dwc_gmac_dump_tx_desc(sc);
1716 dwc_gmac_dump_rx_desc(sc); 1716 dwc_gmac_dump_rx_desc(sc);
1717 1717
1718 panic("%s", msg); 1718 panic("%s", msg);
1719} 1719}
1720 1720
1721static void dwc_gmac_dump_ffilt(struct dwc_gmac_softc *sc, uint32_t ffilt) 1721static void dwc_gmac_dump_ffilt(struct dwc_gmac_softc *sc, uint32_t ffilt)
1722{ 1722{
1723 char buf[200]; 1723 char buf[200];
1724 1724
1725 /* print filter setup */ 1725 /* print filter setup */
1726 snprintb(buf, sizeof(buf), "\177\20" 1726 snprintb(buf, sizeof(buf), "\177\20"
1727 "b\x1f""RA\0" 1727 "b\x1f""RA\0"
1728 "b\x0a""HPF\0" 1728 "b\x0a""HPF\0"
1729 "b\x09""SAF\0" 1729 "b\x09""SAF\0"
1730 "b\x08""SAIF\0" 1730 "b\x08""SAIF\0"
1731 "b\x05""DBF\0" 1731 "b\x05""DBF\0"
1732 "b\x04""PM\0" 1732 "b\x04""PM\0"
1733 "b\x03""DAIF\0" 1733 "b\x03""DAIF\0"
1734 "b\x02""HMC\0" 1734 "b\x02""HMC\0"
1735 "b\x01""HUC\0" 1735 "b\x01""HUC\0"
1736 "b\x00""PR\0" 1736 "b\x00""PR\0"
1737 "\0", ffilt); 1737 "\0", ffilt);
1738 aprint_normal_dev(sc->sc_dev, "FFILT: %s\n", buf); 1738 aprint_normal_dev(sc->sc_dev, "FFILT: %s\n", buf);
1739} 1739}
1740#endif 1740#endif