Mon Jul 20 06:44:55 2020 UTC ()
only ask for SDPCMD_INTSTATUS_HMB_SW_MASK and SDPCMD_INTSTATUS_CHIPACTIVE
interrupts, not all of them.  we only ack these ones.

mostly fixes pinebookpro wifi hard hangs.  still is problematic and can
trigger interrupt storm that appears as a hard hang without NET_MPSAFE,
and a follow up, less clearly right, change will reduce that to a soft
hang of the interface that can be cleared with 'ifconfig bwfm0 down up',
and even often recovers itself now.


(mrg)
diff -r1.19 -r1.20 src/sys/dev/sdmmc/if_bwfm_sdio.c

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

--- src/sys/dev/sdmmc/if_bwfm_sdio.c 2020/06/23 10:09:33 1.19
+++ src/sys/dev/sdmmc/if_bwfm_sdio.c 2020/07/20 06:44:55 1.20
@@ -1,1509 +1,1508 @@ @@ -1,1509 +1,1508 @@
1/* $NetBSD: if_bwfm_sdio.c,v 1.19 2020/06/23 10:09:33 martin Exp $ */ 1/* $NetBSD: if_bwfm_sdio.c,v 1.20 2020/07/20 06:44:55 mrg Exp $ */
2/* $OpenBSD: if_bwfm_sdio.c,v 1.1 2017/10/11 17:19:50 patrick Exp $ */ 2/* $OpenBSD: if_bwfm_sdio.c,v 1.1 2017/10/11 17:19:50 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/endian.h> 23#include <sys/endian.h>
24#include <sys/kernel.h> 24#include <sys/kernel.h>
25#include <sys/malloc.h> 25#include <sys/malloc.h>
26#include <sys/device.h> 26#include <sys/device.h>
27#include <sys/queue.h> 27#include <sys/queue.h>
28#include <sys/socket.h> 28#include <sys/socket.h>
29#include <sys/mutex.h> 29#include <sys/mutex.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 <dev/ofw/openfirm.h> 39#include <dev/ofw/openfirm.h>
40#include <dev/fdt/fdtvar.h> 40#include <dev/fdt/fdtvar.h>
41 41
42#include <net80211/ieee80211_var.h> 42#include <net80211/ieee80211_var.h>
43 43
44#include <dev/sdmmc/sdmmcdevs.h> 44#include <dev/sdmmc/sdmmcdevs.h>
45#include <dev/sdmmc/sdmmcvar.h> 45#include <dev/sdmmc/sdmmcvar.h>
46 46
47#include <dev/ic/bwfmreg.h> 47#include <dev/ic/bwfmreg.h>
48#include <dev/ic/bwfmvar.h> 48#include <dev/ic/bwfmvar.h>
49#include <dev/sdmmc/if_bwfm_sdio.h> 49#include <dev/sdmmc/if_bwfm_sdio.h>
50 50
51#ifdef BWFM_DEBUG 51#ifdef BWFM_DEBUG
52#define DPRINTF(x) do { if (bwfm_debug > 0) printf x; } while (0) 52#define DPRINTF(x) do { if (bwfm_debug > 0) printf x; } while (0)
53#define DPRINTFN(n, x) do { if (bwfm_debug >= (n)) printf x; } while (0) 53#define DPRINTFN(n, x) do { if (bwfm_debug >= (n)) printf x; } while (0)
54static int bwfm_debug = 2; 54static int bwfm_debug = 2;
55#else 55#else
56#define DPRINTF(x) do { ; } while (0) 56#define DPRINTF(x) do { ; } while (0)
57#define DPRINTFN(n, x) do { ; } while (0) 57#define DPRINTFN(n, x) do { ; } while (0)
58#endif 58#endif
59 59
60#define DEVNAME(sc) device_xname((sc)->sc_sc.sc_dev) 60#define DEVNAME(sc) device_xname((sc)->sc_sc.sc_dev)
61 61
62enum bwfm_sdio_clkstate { 62enum bwfm_sdio_clkstate {
63 CLK_NONE, 63 CLK_NONE,
64 CLK_SDONLY, 64 CLK_SDONLY,
65 CLK_PENDING, 65 CLK_PENDING,
66 CLK_AVAIL 66 CLK_AVAIL
67}; 67};
68 68
69struct bwfm_sdio_softc { 69struct bwfm_sdio_softc {
70 struct bwfm_softc sc_sc; 70 struct bwfm_softc sc_sc;
71 kmutex_t sc_lock; 71 kmutex_t sc_lock;
72 72
73 bool sc_bwfm_attached; 73 bool sc_bwfm_attached;
74 74
75 struct sdmmc_function **sc_sf; 75 struct sdmmc_function **sc_sf;
76 size_t sc_sf_size; 76 size_t sc_sf_size;
77 77
78 uint32_t sc_bar0; 78 uint32_t sc_bar0;
79 enum bwfm_sdio_clkstate sc_clkstate; 79 enum bwfm_sdio_clkstate sc_clkstate;
80 bool sc_sr_enabled; 80 bool sc_sr_enabled;
81 bool sc_alp_only; 81 bool sc_alp_only;
82 bool sc_sleeping; 82 bool sc_sleeping;
83 bool sc_rxskip; 83 bool sc_rxskip;
84 84
85 struct sdmmc_task sc_task; 85 struct sdmmc_task sc_task;
86 bool sc_task_queued; 86 bool sc_task_queued;
87 87
88 uint8_t sc_tx_seq; 88 uint8_t sc_tx_seq;
89 uint8_t sc_tx_max_seq; 89 uint8_t sc_tx_max_seq;
90 int sc_tx_count; 90 int sc_tx_count;
91 MBUFQ_HEAD() sc_tx_queue; 91 MBUFQ_HEAD() sc_tx_queue;
92 92
93 struct mbuf *sc_rxctl_queue; 93 struct mbuf *sc_rxctl_queue;
94 kcondvar_t sc_rxctl_cv; 94 kcondvar_t sc_rxctl_cv;
95 95
96 void *sc_ih; 96 void *sc_ih;
97 struct bwfm_core *sc_cc; 97 struct bwfm_core *sc_cc;
98 98
99 char *sc_bounce_buf; 99 char *sc_bounce_buf;
100 size_t sc_bounce_size; 100 size_t sc_bounce_size;
101 101
102 uint32_t sc_console_addr; 102 uint32_t sc_console_addr;
103 char *sc_console_buf; 103 char *sc_console_buf;
104 size_t sc_console_buf_size; 104 size_t sc_console_buf_size;
105 uint32_t sc_console_readidx; 105 uint32_t sc_console_readidx;
106 106
107 int sc_phandle; 107 int sc_phandle;
108 void *sc_fdtih; 108 void *sc_fdtih;
109}; 109};
110 110
111static int bwfm_sdio_match(device_t, cfdata_t, void *); 111static int bwfm_sdio_match(device_t, cfdata_t, void *);
112static void bwfm_sdio_attach(device_t, device_t, void *); 112static void bwfm_sdio_attach(device_t, device_t, void *);
113static int bwfm_sdio_detach(device_t, int); 113static int bwfm_sdio_detach(device_t, int);
114static void bwfm_sdio_attachhook(device_t); 114static void bwfm_sdio_attachhook(device_t);
115static int bwfm_fdt_find_phandle(device_t, device_t); 115static int bwfm_fdt_find_phandle(device_t, device_t);
116static const char *bwfm_fdt_get_model(void); 116static const char *bwfm_fdt_get_model(void);
117 117
118static void bwfm_sdio_backplane(struct bwfm_sdio_softc *, uint32_t); 118static void bwfm_sdio_backplane(struct bwfm_sdio_softc *, uint32_t);
119static uint8_t bwfm_sdio_read_1(struct bwfm_sdio_softc *, uint32_t); 119static uint8_t bwfm_sdio_read_1(struct bwfm_sdio_softc *, uint32_t);
120static uint32_t bwfm_sdio_read_4(struct bwfm_sdio_softc *, uint32_t); 120static uint32_t bwfm_sdio_read_4(struct bwfm_sdio_softc *, uint32_t);
121static void bwfm_sdio_write_1(struct bwfm_sdio_softc *, uint32_t, 121static void bwfm_sdio_write_1(struct bwfm_sdio_softc *, uint32_t,
122 uint8_t); 122 uint8_t);
123static void bwfm_sdio_write_4(struct bwfm_sdio_softc *, uint32_t, 123static void bwfm_sdio_write_4(struct bwfm_sdio_softc *, uint32_t,
124 uint32_t); 124 uint32_t);
125 125
126static uint32_t bwfm_sdio_dev_read(struct bwfm_sdio_softc *, uint32_t); 126static uint32_t bwfm_sdio_dev_read(struct bwfm_sdio_softc *, uint32_t);
127static void bwfm_sdio_dev_write(struct bwfm_sdio_softc *, uint32_t, 127static void bwfm_sdio_dev_write(struct bwfm_sdio_softc *, uint32_t,
128 uint32_t); 128 uint32_t);
129 129
130static uint32_t bwfm_sdio_buscore_read(struct bwfm_softc *, uint32_t); 130static uint32_t bwfm_sdio_buscore_read(struct bwfm_softc *, uint32_t);
131static void bwfm_sdio_buscore_write(struct bwfm_softc *, uint32_t, 131static void bwfm_sdio_buscore_write(struct bwfm_softc *, uint32_t,
132 uint32_t); 132 uint32_t);
133static int bwfm_sdio_buscore_prepare(struct bwfm_softc *); 133static int bwfm_sdio_buscore_prepare(struct bwfm_softc *);
134static void bwfm_sdio_buscore_activate(struct bwfm_softc *, uint32_t); 134static void bwfm_sdio_buscore_activate(struct bwfm_softc *, uint32_t);
135 135
136static int bwfm_sdio_buf_read(struct bwfm_sdio_softc *, 136static int bwfm_sdio_buf_read(struct bwfm_sdio_softc *,
137 struct sdmmc_function *, uint32_t, char *, size_t); 137 struct sdmmc_function *, uint32_t, char *, size_t);
138static int bwfm_sdio_buf_write(struct bwfm_sdio_softc *, 138static int bwfm_sdio_buf_write(struct bwfm_sdio_softc *,
139 struct sdmmc_function *, uint32_t, char *, size_t); 139 struct sdmmc_function *, uint32_t, char *, size_t);
140 140
141static struct mbuf *bwfm_sdio_newbuf(void); 141static struct mbuf *bwfm_sdio_newbuf(void);
142static void bwfm_qput(struct mbuf **, struct mbuf *); 142static void bwfm_qput(struct mbuf **, struct mbuf *);
143static struct mbuf *bwfm_qget(struct mbuf **); 143static struct mbuf *bwfm_qget(struct mbuf **);
144 144
145static uint32_t bwfm_sdio_ram_read_write(struct bwfm_sdio_softc *, 145static uint32_t bwfm_sdio_ram_read_write(struct bwfm_sdio_softc *,
146 uint32_t, char *, size_t, int); 146 uint32_t, char *, size_t, int);
147static uint32_t bwfm_sdio_frame_read_write(struct bwfm_sdio_softc *, 147static uint32_t bwfm_sdio_frame_read_write(struct bwfm_sdio_softc *,
148 char *, size_t, int); 148 char *, size_t, int);
149 149
150static int bwfm_sdio_intr1(void *, const char *); 150static int bwfm_sdio_intr1(void *, const char *);
151static int bwfm_sdio_intr(void *); 151static int bwfm_sdio_intr(void *);
152static void bwfm_sdio_task(void *); 152static void bwfm_sdio_task(void *);
153static void bwfm_sdio_task1(struct bwfm_sdio_softc *); 153static void bwfm_sdio_task1(struct bwfm_sdio_softc *);
154 154
155static int bwfm_nvram_convert(u_char *, size_t, size_t *); 155static int bwfm_nvram_convert(u_char *, size_t, size_t *);
156static int bwfm_sdio_load_microcode(struct bwfm_sdio_softc *, 156static int bwfm_sdio_load_microcode(struct bwfm_sdio_softc *,
157 u_char *, size_t, u_char *, size_t); 157 u_char *, size_t, u_char *, size_t);
158static void bwfm_sdio_clkctl(struct bwfm_sdio_softc *, 158static void bwfm_sdio_clkctl(struct bwfm_sdio_softc *,
159 enum bwfm_sdio_clkstate, bool); 159 enum bwfm_sdio_clkstate, bool);
160static void bwfm_sdio_htclk(struct bwfm_sdio_softc *, bool, bool); 160static void bwfm_sdio_htclk(struct bwfm_sdio_softc *, bool, bool);
161 161
162#ifdef notyet 162#ifdef notyet
163static int bwfm_sdio_bus_sleep(struct bwfm_sdio_softc *, bool, bool); 163static int bwfm_sdio_bus_sleep(struct bwfm_sdio_softc *, bool, bool);
164#endif 164#endif
165static void bwfm_sdio_drivestrength(struct bwfm_sdio_softc *, unsigned); 165static void bwfm_sdio_drivestrength(struct bwfm_sdio_softc *, unsigned);
166static void bwfm_sdio_readshared(struct bwfm_sdio_softc *); 166static void bwfm_sdio_readshared(struct bwfm_sdio_softc *);
167 167
168static int bwfm_sdio_txcheck(struct bwfm_softc *); 168static int bwfm_sdio_txcheck(struct bwfm_softc *);
169static int bwfm_sdio_txdata(struct bwfm_softc *, struct mbuf **); 169static int bwfm_sdio_txdata(struct bwfm_softc *, struct mbuf **);
170static int bwfm_sdio_txctl(struct bwfm_softc *, char *, size_t); 170static int bwfm_sdio_txctl(struct bwfm_softc *, char *, size_t);
171static int bwfm_sdio_rxctl(struct bwfm_softc *, char *, size_t *); 171static int bwfm_sdio_rxctl(struct bwfm_softc *, char *, size_t *);
172 172
173static int bwfm_sdio_tx_ok(struct bwfm_sdio_softc *); 173static int bwfm_sdio_tx_ok(struct bwfm_sdio_softc *);
174static void bwfm_sdio_tx_frames(struct bwfm_sdio_softc *); 174static void bwfm_sdio_tx_frames(struct bwfm_sdio_softc *);
175static void bwfm_sdio_tx_ctrlframe(struct bwfm_sdio_softc *, 175static void bwfm_sdio_tx_ctrlframe(struct bwfm_sdio_softc *,
176 struct mbuf *); 176 struct mbuf *);
177static void bwfm_sdio_tx_dataframe(struct bwfm_sdio_softc *, 177static void bwfm_sdio_tx_dataframe(struct bwfm_sdio_softc *,
178 struct mbuf *); 178 struct mbuf *);
179 179
180static void bwfm_sdio_rx_frames(struct bwfm_sdio_softc *); 180static void bwfm_sdio_rx_frames(struct bwfm_sdio_softc *);
181static void bwfm_sdio_rx_glom(struct bwfm_sdio_softc *, 181static void bwfm_sdio_rx_glom(struct bwfm_sdio_softc *,
182 uint16_t *, int, uint16_t *); 182 uint16_t *, int, uint16_t *);
183 183
184#ifdef BWFM_DEBUG  184#ifdef BWFM_DEBUG
185static void bwfm_sdio_debug_console(struct bwfm_sdio_softc *); 185static void bwfm_sdio_debug_console(struct bwfm_sdio_softc *);
186#endif  186#endif
187 187
188static const struct bwfm_firmware_selector bwfm_sdio_fwtab[] = { 188static const struct bwfm_firmware_selector bwfm_sdio_fwtab[] = {
189 BWFM_FW_ENTRY(BRCM_CC_43143_CHIP_ID, 189 BWFM_FW_ENTRY(BRCM_CC_43143_CHIP_ID,
190 BWFM_FWSEL_ALLREVS, "brcmfmac43143-sdio"), 190 BWFM_FWSEL_ALLREVS, "brcmfmac43143-sdio"),
191 191
192 BWFM_FW_ENTRY(BRCM_CC_43241_CHIP_ID, 192 BWFM_FW_ENTRY(BRCM_CC_43241_CHIP_ID,
193 BWFM_FWSEL_REV_LE(4), "brcmfmac43241b0-sdio"), 193 BWFM_FWSEL_REV_LE(4), "brcmfmac43241b0-sdio"),
194 BWFM_FW_ENTRY(BRCM_CC_43241_CHIP_ID, 194 BWFM_FW_ENTRY(BRCM_CC_43241_CHIP_ID,
195 BWFM_FWSEL_REV_EQ(5), "brcmfmac43241b4-sdio"), 195 BWFM_FWSEL_REV_EQ(5), "brcmfmac43241b4-sdio"),
196 BWFM_FW_ENTRY(BRCM_CC_43241_CHIP_ID, 196 BWFM_FW_ENTRY(BRCM_CC_43241_CHIP_ID,
197 BWFM_FWSEL_REV_GE(6), "brcmfmac43241b5-sdio"), 197 BWFM_FWSEL_REV_GE(6), "brcmfmac43241b5-sdio"),
198 198
199 BWFM_FW_ENTRY(BRCM_CC_4329_CHIP_ID, 199 BWFM_FW_ENTRY(BRCM_CC_4329_CHIP_ID,
200 BWFM_FWSEL_ALLREVS, "brcmfmac4329-sdio"), 200 BWFM_FWSEL_ALLREVS, "brcmfmac4329-sdio"),
201 201
202 BWFM_FW_ENTRY(BRCM_CC_4330_CHIP_ID, 202 BWFM_FW_ENTRY(BRCM_CC_4330_CHIP_ID,
203 BWFM_FWSEL_ALLREVS, "brcmfmac4330-sdio"), 203 BWFM_FWSEL_ALLREVS, "brcmfmac4330-sdio"),
204 204
205 BWFM_FW_ENTRY(BRCM_CC_4334_CHIP_ID, 205 BWFM_FW_ENTRY(BRCM_CC_4334_CHIP_ID,
206 BWFM_FWSEL_ALLREVS, "brcmfmac4334-sdio"), 206 BWFM_FWSEL_ALLREVS, "brcmfmac4334-sdio"),
207 207
208 BWFM_FW_ENTRY(BRCM_CC_43340_CHIP_ID, 208 BWFM_FW_ENTRY(BRCM_CC_43340_CHIP_ID,
209 BWFM_FWSEL_ALLREVS, "brcmfmac43340-sdio"), 209 BWFM_FWSEL_ALLREVS, "brcmfmac43340-sdio"),
210 BWFM_FW_ENTRY(BRCM_CC_43341_CHIP_ID, 210 BWFM_FW_ENTRY(BRCM_CC_43341_CHIP_ID,
211 BWFM_FWSEL_ALLREVS, "brcmfmac43340-sdio"), 211 BWFM_FWSEL_ALLREVS, "brcmfmac43340-sdio"),
212 212
213 BWFM_FW_ENTRY(BRCM_CC_4335_CHIP_ID, 213 BWFM_FW_ENTRY(BRCM_CC_4335_CHIP_ID,
214 BWFM_FWSEL_ALLREVS, "brcmfmac4335-sdio"), 214 BWFM_FWSEL_ALLREVS, "brcmfmac4335-sdio"),
215 215
216 BWFM_FW_ENTRY(BRCM_CC_43362_CHIP_ID, 216 BWFM_FW_ENTRY(BRCM_CC_43362_CHIP_ID,
217 BWFM_FWSEL_REV_GE(1), "brcmfmac43362-sdio"), 217 BWFM_FWSEL_REV_GE(1), "brcmfmac43362-sdio"),
218 218
219 BWFM_FW_ENTRY(BRCM_CC_4339_CHIP_ID, 219 BWFM_FW_ENTRY(BRCM_CC_4339_CHIP_ID,
220 BWFM_FWSEL_ALLREVS, "brcmfmac4339-sdio"), 220 BWFM_FWSEL_ALLREVS, "brcmfmac4339-sdio"),
221 221
222 BWFM_FW_ENTRY(BRCM_CC_43430_CHIP_ID, 222 BWFM_FW_ENTRY(BRCM_CC_43430_CHIP_ID,
223 BWFM_FWSEL_REV_EQ(0), "brcmfmac43430a0-sdio"), 223 BWFM_FWSEL_REV_EQ(0), "brcmfmac43430a0-sdio"),
224 BWFM_FW_ENTRY(BRCM_CC_43430_CHIP_ID, 224 BWFM_FW_ENTRY(BRCM_CC_43430_CHIP_ID,
225 BWFM_FWSEL_REV_GE(1), "brcmfmac43430-sdio"), 225 BWFM_FWSEL_REV_GE(1), "brcmfmac43430-sdio"),
226 226
227 BWFM_FW_ENTRY(BRCM_CC_4345_CHIP_ID, 227 BWFM_FW_ENTRY(BRCM_CC_4345_CHIP_ID,
228 BWFM_FWSEL_REV_EQ(9), "brcmfmac43456-sdio"), 228 BWFM_FWSEL_REV_EQ(9), "brcmfmac43456-sdio"),
229 BWFM_FW_ENTRY(BRCM_CC_4345_CHIP_ID, 229 BWFM_FW_ENTRY(BRCM_CC_4345_CHIP_ID,
230 BWFM_FWSEL_REV_LE(8) + BWFM_FWSEL_REV_GE(10), 230 BWFM_FWSEL_REV_LE(8) + BWFM_FWSEL_REV_GE(10),
231 "brcmfmac43455-sdio"), 231 "brcmfmac43455-sdio"),
232 232
233 BWFM_FW_ENTRY(BRCM_CC_4354_CHIP_ID, 233 BWFM_FW_ENTRY(BRCM_CC_4354_CHIP_ID,
234 BWFM_FWSEL_ALLREVS, "brcmfmac4354-sdio"), 234 BWFM_FWSEL_ALLREVS, "brcmfmac4354-sdio"),
235  235
236 BWFM_FW_ENTRY(BRCM_CC_4356_CHIP_ID, 236 BWFM_FW_ENTRY(BRCM_CC_4356_CHIP_ID,
237 BWFM_FWSEL_ALLREVS, "brcmfmac4356-sdio"), 237 BWFM_FWSEL_ALLREVS, "brcmfmac4356-sdio"),
238 238
239 BWFM_FW_ENTRY(CY_CC_4373_CHIP_ID, 239 BWFM_FW_ENTRY(CY_CC_4373_CHIP_ID,
240 BWFM_FWSEL_ALLREVS, "brcmfmac4373-sdio"), 240 BWFM_FWSEL_ALLREVS, "brcmfmac4373-sdio"),
241 241
242 BWFM_FW_ENTRY(CY_CC_43012_CHIP_ID, 242 BWFM_FW_ENTRY(CY_CC_43012_CHIP_ID,
243 BWFM_FWSEL_ALLREVS, "brcmfmac43012-sdio"), 243 BWFM_FWSEL_ALLREVS, "brcmfmac43012-sdio"),
244 244
245 BWFM_FW_ENTRY_END 245 BWFM_FW_ENTRY_END
246}; 246};
247 247
248static const struct bwfm_bus_ops bwfm_sdio_bus_ops = { 248static const struct bwfm_bus_ops bwfm_sdio_bus_ops = {
249 .bs_init = NULL, 249 .bs_init = NULL,
250 .bs_stop = NULL, 250 .bs_stop = NULL,
251 .bs_txcheck = bwfm_sdio_txcheck, 251 .bs_txcheck = bwfm_sdio_txcheck,
252 .bs_txdata = bwfm_sdio_txdata, 252 .bs_txdata = bwfm_sdio_txdata,
253 .bs_txctl = bwfm_sdio_txctl, 253 .bs_txctl = bwfm_sdio_txctl,
254 .bs_rxctl = bwfm_sdio_rxctl, 254 .bs_rxctl = bwfm_sdio_rxctl,
255}; 255};
256 256
257static const struct bwfm_buscore_ops bwfm_sdio_buscore_ops = { 257static const struct bwfm_buscore_ops bwfm_sdio_buscore_ops = {
258 .bc_read = bwfm_sdio_buscore_read, 258 .bc_read = bwfm_sdio_buscore_read,
259 .bc_write = bwfm_sdio_buscore_write, 259 .bc_write = bwfm_sdio_buscore_write,
260 .bc_prepare = bwfm_sdio_buscore_prepare, 260 .bc_prepare = bwfm_sdio_buscore_prepare,
261 .bc_reset = NULL, 261 .bc_reset = NULL,
262 .bc_setup = NULL, 262 .bc_setup = NULL,
263 .bc_activate = bwfm_sdio_buscore_activate, 263 .bc_activate = bwfm_sdio_buscore_activate,
264}; 264};
265 265
266CFATTACH_DECL_NEW(bwfm_sdio, sizeof(struct bwfm_sdio_softc), 266CFATTACH_DECL_NEW(bwfm_sdio, sizeof(struct bwfm_sdio_softc),
267 bwfm_sdio_match, bwfm_sdio_attach, bwfm_sdio_detach, NULL); 267 bwfm_sdio_match, bwfm_sdio_attach, bwfm_sdio_detach, NULL);
268 268
269static const struct bwfm_sdio_product { 269static const struct bwfm_sdio_product {
270 uint32_t manufacturer; 270 uint32_t manufacturer;
271 uint32_t product; 271 uint32_t product;
272 const char *cisinfo[4]; 272 const char *cisinfo[4];
273} bwfm_sdio_products[] = { 273} bwfm_sdio_products[] = {
274 { 274 {
275 SDMMC_VENDOR_BROADCOM, 275 SDMMC_VENDOR_BROADCOM,
276 SDMMC_PRODUCT_BROADCOM_BCM4330,  276 SDMMC_PRODUCT_BROADCOM_BCM4330,
277 SDMMC_CIS_BROADCOM_BCM4330 277 SDMMC_CIS_BROADCOM_BCM4330
278 }, 278 },
279 { 279 {
280 SDMMC_VENDOR_BROADCOM, 280 SDMMC_VENDOR_BROADCOM,
281 SDMMC_PRODUCT_BROADCOM_BCM4334,  281 SDMMC_PRODUCT_BROADCOM_BCM4334,
282 SDMMC_CIS_BROADCOM_BCM4334 282 SDMMC_CIS_BROADCOM_BCM4334
283 }, 283 },
284 { 284 {
285 SDMMC_VENDOR_BROADCOM, 285 SDMMC_VENDOR_BROADCOM,
286 SDMMC_PRODUCT_BROADCOM_BCM43143,  286 SDMMC_PRODUCT_BROADCOM_BCM43143,
287 SDMMC_CIS_BROADCOM_BCM43143 287 SDMMC_CIS_BROADCOM_BCM43143
288 }, 288 },
289 { 289 {
290 SDMMC_VENDOR_BROADCOM, 290 SDMMC_VENDOR_BROADCOM,
291 SDMMC_PRODUCT_BROADCOM_BCM43430,  291 SDMMC_PRODUCT_BROADCOM_BCM43430,
292 SDMMC_CIS_BROADCOM_BCM43430 292 SDMMC_CIS_BROADCOM_BCM43430
293 }, 293 },
294 { 294 {
295 SDMMC_VENDOR_BROADCOM, 295 SDMMC_VENDOR_BROADCOM,
296 SDMMC_PRODUCT_BROADCOM_BCM43455,  296 SDMMC_PRODUCT_BROADCOM_BCM43455,
297 SDMMC_CIS_BROADCOM_BCM43455 297 SDMMC_CIS_BROADCOM_BCM43455
298 }, 298 },
299 { 299 {
300 SDMMC_VENDOR_BROADCOM, 300 SDMMC_VENDOR_BROADCOM,
301 SDMMC_PRODUCT_BROADCOM_BCM43362,  301 SDMMC_PRODUCT_BROADCOM_BCM43362,
302 SDMMC_CIS_BROADCOM_BCM43362 302 SDMMC_CIS_BROADCOM_BCM43362
303 }, 303 },
304}; 304};
305 305
306static const char * const compatible[] = { 306static const char * const compatible[] = {
307 "brcm,bcm4329-fmac", 307 "brcm,bcm4329-fmac",
308 NULL 308 NULL
309}; 309};
310 310
311static int 311static int
312bwfm_sdio_match(device_t parent, cfdata_t match, void *aux) 312bwfm_sdio_match(device_t parent, cfdata_t match, void *aux)
313{ 313{
314 struct sdmmc_attach_args *saa = aux; 314 struct sdmmc_attach_args *saa = aux;
315 struct sdmmc_function *sf = saa->sf; 315 struct sdmmc_function *sf = saa->sf;
316 struct sdmmc_cis *cis; 316 struct sdmmc_cis *cis;
317 const struct bwfm_sdio_product *bsp; 317 const struct bwfm_sdio_product *bsp;
318 int i; 318 int i;
319 319
320 /* Not SDIO. */ 320 /* Not SDIO. */
321 if (sf == NULL) 321 if (sf == NULL)
322 return 0; 322 return 0;
323 323
324 cis = &sf->sc->sc_fn0->cis; 324 cis = &sf->sc->sc_fn0->cis;
325 for (i = 0; i < __arraycount(bwfm_sdio_products); ++i) { 325 for (i = 0; i < __arraycount(bwfm_sdio_products); ++i) {
326 bsp = &bwfm_sdio_products[i]; 326 bsp = &bwfm_sdio_products[i];
327 if (cis->manufacturer == bsp->manufacturer && 327 if (cis->manufacturer == bsp->manufacturer &&
328 cis->product == bsp->product) 328 cis->product == bsp->product)
329 break; 329 break;
330 } 330 }
331 if (i >= __arraycount(bwfm_sdio_products)) 331 if (i >= __arraycount(bwfm_sdio_products))
332 return 0; 332 return 0;
333 333
334 /* We need both functions, but ... */ 334 /* We need both functions, but ... */
335 if (sf->sc->sc_function_count <= 1) 335 if (sf->sc->sc_function_count <= 1)
336 return 0; 336 return 0;
337 337
338 /* ... only attach for one. */ 338 /* ... only attach for one. */
339 if (sf->number != 1) 339 if (sf->number != 1)
340 return 0; 340 return 0;
341 341
342 return 1; 342 return 1;
343} 343}
344 344
345static void 345static void
346bwfm_sdio_attach(device_t parent, device_t self, void *aux) 346bwfm_sdio_attach(device_t parent, device_t self, void *aux)
347{ 347{
348 struct bwfm_sdio_softc *sc = device_private(self); 348 struct bwfm_sdio_softc *sc = device_private(self);
349 struct sdmmc_attach_args *saa = aux; 349 struct sdmmc_attach_args *saa = aux;
350 struct sdmmc_function *sf = saa->sf; 350 struct sdmmc_function *sf = saa->sf;
351 struct bwfm_core *core; 351 struct bwfm_core *core;
352 uint32_t reg; 352 uint32_t reg;
353 353
354 sc->sc_sc.sc_dev = self; 354 sc->sc_sc.sc_dev = self;
355 355
356 aprint_naive("\n"); 356 aprint_naive("\n");
357 aprint_normal("\n"); 357 aprint_normal("\n");
358 358
359 sc->sc_phandle = bwfm_fdt_find_phandle(self, parent); 359 sc->sc_phandle = bwfm_fdt_find_phandle(self, parent);
360 360
361 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE); 361 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
362 cv_init(&sc->sc_rxctl_cv, "bwfmctl"); 362 cv_init(&sc->sc_rxctl_cv, "bwfmctl");
363 363
364 sdmmc_init_task(&sc->sc_task, bwfm_sdio_task, sc); 364 sdmmc_init_task(&sc->sc_task, bwfm_sdio_task, sc);
365 365
366 sc->sc_bounce_size = 64 * 1024; 366 sc->sc_bounce_size = 64 * 1024;
367 sc->sc_bounce_buf = kmem_alloc(sc->sc_bounce_size, KM_SLEEP); 367 sc->sc_bounce_buf = kmem_alloc(sc->sc_bounce_size, KM_SLEEP);
368 sc->sc_tx_seq = 0xff; 368 sc->sc_tx_seq = 0xff;
369 MBUFQ_INIT(&sc->sc_tx_queue); 369 MBUFQ_INIT(&sc->sc_tx_queue);
370 sc->sc_rxctl_queue = NULL; 370 sc->sc_rxctl_queue = NULL;
371 371
372 sc->sc_sf_size = (sf->sc->sc_function_count + 1) 372 sc->sc_sf_size = (sf->sc->sc_function_count + 1)
373 * sizeof(struct sdmmc_function *); 373 * sizeof(struct sdmmc_function *);
374 sc->sc_sf = kmem_zalloc(sc->sc_sf_size, KM_SLEEP); 374 sc->sc_sf = kmem_zalloc(sc->sc_sf_size, KM_SLEEP);
375 375
376 /* Copy all function pointers. */ 376 /* Copy all function pointers. */
377 SIMPLEQ_FOREACH(sf, &saa->sf->sc->sf_head, sf_list) { 377 SIMPLEQ_FOREACH(sf, &saa->sf->sc->sf_head, sf_list) {
378 sc->sc_sf[sf->number] = sf; 378 sc->sc_sf[sf->number] = sf;
379 } 379 }
380 380
381 sdmmc_io_set_blocklen(sc->sc_sf[1], 64);  381 sdmmc_io_set_blocklen(sc->sc_sf[1], 64);
382 sdmmc_io_set_blocklen(sc->sc_sf[2], 512); 382 sdmmc_io_set_blocklen(sc->sc_sf[2], 512);
383 383
384 /* Enable Function 1. */ 384 /* Enable Function 1. */
385 if (sdmmc_io_function_enable(sc->sc_sf[1]) != 0) { 385 if (sdmmc_io_function_enable(sc->sc_sf[1]) != 0) {
386 printf("%s: cannot enable function 1\n", DEVNAME(sc)); 386 printf("%s: cannot enable function 1\n", DEVNAME(sc));
387 return; 387 return;
388 } 388 }
389 389
390 DPRINTF(("%s: F1 signature read @0x18000000=%x\n", DEVNAME(sc), 390 DPRINTF(("%s: F1 signature read @0x18000000=%x\n", DEVNAME(sc),
391 bwfm_sdio_read_4(sc, 0x18000000))); 391 bwfm_sdio_read_4(sc, 0x18000000)));
392 392
393 /* Force PLL off */ 393 /* Force PLL off */
394 bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_CHIPCLKCSR, 394 bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_CHIPCLKCSR,
395 BWFM_SDIO_FUNC1_CHIPCLKCSR_FORCE_HW_CLKREQ_OFF | 395 BWFM_SDIO_FUNC1_CHIPCLKCSR_FORCE_HW_CLKREQ_OFF |
396 BWFM_SDIO_FUNC1_CHIPCLKCSR_ALP_AVAIL_REQ); 396 BWFM_SDIO_FUNC1_CHIPCLKCSR_ALP_AVAIL_REQ);
397 397
398 sc->sc_sc.sc_buscore_ops = &bwfm_sdio_buscore_ops; 398 sc->sc_sc.sc_buscore_ops = &bwfm_sdio_buscore_ops;
399 if (bwfm_chip_attach(&sc->sc_sc) != 0) { 399 if (bwfm_chip_attach(&sc->sc_sc) != 0) {
400 aprint_error_dev(self, "cannot attach chip\n"); 400 aprint_error_dev(self, "cannot attach chip\n");
401 return; 401 return;
402 } 402 }
403 403
404 sc->sc_cc = bwfm_chip_get_core(&sc->sc_sc, BWFM_AGENT_CORE_CHIPCOMMON); 404 sc->sc_cc = bwfm_chip_get_core(&sc->sc_sc, BWFM_AGENT_CORE_CHIPCOMMON);
405 if (sc->sc_cc == NULL) { 405 if (sc->sc_cc == NULL) {
406 aprint_error_dev(self, "cannot find chipcommon core\n"); 406 aprint_error_dev(self, "cannot find chipcommon core\n");
407 return; 407 return;
408 } 408 }
409 409
410 core = bwfm_chip_get_core(&sc->sc_sc, BWFM_AGENT_CORE_SDIO_DEV); 410 core = bwfm_chip_get_core(&sc->sc_sc, BWFM_AGENT_CORE_SDIO_DEV);
411 if (core->co_rev >= 12) { 411 if (core->co_rev >= 12) {
412 reg = bwfm_sdio_read_1(sc, BWFM_SDIO_FUNC1_SLEEPCSR); 412 reg = bwfm_sdio_read_1(sc, BWFM_SDIO_FUNC1_SLEEPCSR);
413 if ((reg & BWFM_SDIO_FUNC1_SLEEPCSR_KSO) == 0) { 413 if ((reg & BWFM_SDIO_FUNC1_SLEEPCSR_KSO) == 0) {
414 reg |= BWFM_SDIO_FUNC1_SLEEPCSR_KSO; 414 reg |= BWFM_SDIO_FUNC1_SLEEPCSR_KSO;
415 bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_SLEEPCSR, reg); 415 bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_SLEEPCSR, reg);
416 } 416 }
417 } 417 }
418 418
419 /* Default, override from "brcm,drive-strength" */ 419 /* Default, override from "brcm,drive-strength" */
420 bwfm_sdio_drivestrength(sc, 6); 420 bwfm_sdio_drivestrength(sc, 6);
421 421
422 bwfm_sdio_write_1(sc, BWFM_SDIO_CCCR_CARDCTRL, 422 bwfm_sdio_write_1(sc, BWFM_SDIO_CCCR_CARDCTRL,
423 bwfm_sdio_read_1(sc, BWFM_SDIO_CCCR_CARDCTRL) | 423 bwfm_sdio_read_1(sc, BWFM_SDIO_CCCR_CARDCTRL) |
424 BWFM_SDIO_CCCR_CARDCTRL_WLANRESET); 424 BWFM_SDIO_CCCR_CARDCTRL_WLANRESET);
425 425
426 core = bwfm_chip_get_pmu(&sc->sc_sc); 426 core = bwfm_chip_get_pmu(&sc->sc_sc);
427 bwfm_sdio_write_4(sc, core->co_base + BWFM_CHIP_REG_PMUCONTROL, 427 bwfm_sdio_write_4(sc, core->co_base + BWFM_CHIP_REG_PMUCONTROL,
428 bwfm_sdio_read_4(sc, core->co_base + BWFM_CHIP_REG_PMUCONTROL) | 428 bwfm_sdio_read_4(sc, core->co_base + BWFM_CHIP_REG_PMUCONTROL) |
429 (BWFM_CHIP_REG_PMUCONTROL_RES_RELOAD << 429 (BWFM_CHIP_REG_PMUCONTROL_RES_RELOAD <<
430 BWFM_CHIP_REG_PMUCONTROL_RES_SHIFT)); 430 BWFM_CHIP_REG_PMUCONTROL_RES_SHIFT));
431 431
432 sdmmc_io_function_disable(sc->sc_sf[2]); 432 sdmmc_io_function_disable(sc->sc_sf[2]);
433 433
434 bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_CHIPCLKCSR, 0); 434 bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_CHIPCLKCSR, 0);
435 sc->sc_clkstate = CLK_SDONLY; 435 sc->sc_clkstate = CLK_SDONLY;
436 436
437 config_mountroot(self, bwfm_sdio_attachhook); 437 config_mountroot(self, bwfm_sdio_attachhook);
438} 438}
439 439
440static void 440static void
441bwfm_sdio_attachhook(device_t self) 441bwfm_sdio_attachhook(device_t self)
442{ 442{
443 struct bwfm_sdio_softc *sc = device_private(self); 443 struct bwfm_sdio_softc *sc = device_private(self);
444 struct bwfm_softc *bwfm = &sc->sc_sc; 444 struct bwfm_softc *bwfm = &sc->sc_sc;
445 struct bwfm_firmware_context fwctx; 445 struct bwfm_firmware_context fwctx;
446 size_t ucsize = 0, nvlen = 0, nvsize = 0; 446 size_t ucsize = 0, nvlen = 0, nvsize = 0;
447 uint8_t *ucode, *nvram; 447 uint8_t *ucode, *nvram;
448 uint32_t reg, clk; 448 uint32_t reg, clk;
449 449
450 DPRINTF(("%s: chip 0x%08x rev %u\n", DEVNAME(sc), 450 DPRINTF(("%s: chip 0x%08x rev %u\n", DEVNAME(sc),
451 bwfm->sc_chip.ch_chip, bwfm->sc_chip.ch_chiprev)); 451 bwfm->sc_chip.ch_chip, bwfm->sc_chip.ch_chiprev));
452 452
453 /* 453 /*
454 * 4335s >= rev 2 are considered 4339s. 454 * 4335s >= rev 2 are considered 4339s.
455 */ 455 */
456 if (bwfm->sc_chip.ch_chip == BRCM_CC_4335_CHIP_ID && 456 if (bwfm->sc_chip.ch_chip == BRCM_CC_4335_CHIP_ID &&
457 bwfm->sc_chip.ch_chiprev >= 2) 457 bwfm->sc_chip.ch_chiprev >= 2)
458 bwfm->sc_chip.ch_chip = BRCM_CC_4339_CHIP_ID; 458 bwfm->sc_chip.ch_chip = BRCM_CC_4339_CHIP_ID;
459 459
460 bwfm_firmware_context_init(&fwctx, 460 bwfm_firmware_context_init(&fwctx,
461 bwfm->sc_chip.ch_chip, bwfm->sc_chip.ch_chiprev, 461 bwfm->sc_chip.ch_chip, bwfm->sc_chip.ch_chiprev,
462 bwfm_fdt_get_model(), 462 bwfm_fdt_get_model(),
463 BWFM_FWREQ(BWFM_FILETYPE_UCODE) | BWFM_FWREQ(BWFM_FILETYPE_NVRAM)); 463 BWFM_FWREQ(BWFM_FILETYPE_UCODE) | BWFM_FWREQ(BWFM_FILETYPE_NVRAM));
464 464
465 if (!bwfm_firmware_open(bwfm, bwfm_sdio_fwtab, &fwctx)) { 465 if (!bwfm_firmware_open(bwfm, bwfm_sdio_fwtab, &fwctx)) {
466 /* Error message already displayed. */ 466 /* Error message already displayed. */
467 goto err; 467 goto err;
468 } 468 }
469 469
470 ucode = bwfm_firmware_data(&fwctx, BWFM_FILETYPE_UCODE, &ucsize); 470 ucode = bwfm_firmware_data(&fwctx, BWFM_FILETYPE_UCODE, &ucsize);
471 KASSERT(ucode != NULL); 471 KASSERT(ucode != NULL);
472 nvram = bwfm_firmware_data(&fwctx, BWFM_FILETYPE_NVRAM, &nvlen); 472 nvram = bwfm_firmware_data(&fwctx, BWFM_FILETYPE_NVRAM, &nvlen);
473 KASSERT(nvram != NULL); 473 KASSERT(nvram != NULL);
474 474
475 if (bwfm_nvram_convert(nvram, nvlen, &nvsize)) { 475 if (bwfm_nvram_convert(nvram, nvlen, &nvsize)) {
476 aprint_error_dev(bwfm->sc_dev, 476 aprint_error_dev(bwfm->sc_dev,
477 "unable to convert %s file\n", 477 "unable to convert %s file\n",
478 bwfm_firmware_description(BWFM_FILETYPE_NVRAM)); 478 bwfm_firmware_description(BWFM_FILETYPE_NVRAM));
479 goto err; 479 goto err;
480 } 480 }
481 481
482 sc->sc_alp_only = true; 482 sc->sc_alp_only = true;
483 if (bwfm_sdio_load_microcode(sc, ucode, ucsize, nvram, nvsize) != 0) { 483 if (bwfm_sdio_load_microcode(sc, ucode, ucsize, nvram, nvsize) != 0) {
484 aprint_error_dev(bwfm->sc_dev, "could not load microcode\n"); 484 aprint_error_dev(bwfm->sc_dev, "could not load microcode\n");
485 goto err; 485 goto err;
486 } 486 }
487 sc->sc_alp_only = false; 487 sc->sc_alp_only = false;
488 488
489 sdmmc_pause(hztoms(1)*1000, NULL); 489 sdmmc_pause(hztoms(1)*1000, NULL);
490 490
491 bwfm_sdio_clkctl(sc, CLK_AVAIL, false); 491 bwfm_sdio_clkctl(sc, CLK_AVAIL, false);
492 if (sc->sc_clkstate != CLK_AVAIL) { 492 if (sc->sc_clkstate != CLK_AVAIL) {
493 aprint_error_dev(bwfm->sc_dev, "could not access clock\n"); 493 aprint_error_dev(bwfm->sc_dev, "could not access clock\n");
494 goto err; 494 goto err;
495 } 495 }
496 496
497 clk = bwfm_sdio_read_1(sc, BWFM_SDIO_FUNC1_CHIPCLKCSR); 497 clk = bwfm_sdio_read_1(sc, BWFM_SDIO_FUNC1_CHIPCLKCSR);
498 bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_CHIPCLKCSR, 498 bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_CHIPCLKCSR,
499 clk | BWFM_SDIO_FUNC1_CHIPCLKCSR_FORCE_HT); 499 clk | BWFM_SDIO_FUNC1_CHIPCLKCSR_FORCE_HT);
500 500
501 bwfm_sdio_dev_write(sc, SDPCMD_TOSBMAILBOXDATA, 501 bwfm_sdio_dev_write(sc, SDPCMD_TOSBMAILBOXDATA,
502 SDPCM_PROT_VERSION << SDPCM_PROT_VERSION_SHIFT); 502 SDPCM_PROT_VERSION << SDPCM_PROT_VERSION_SHIFT);
503 if (sdmmc_io_function_enable(sc->sc_sf[2])) { 503 if (sdmmc_io_function_enable(sc->sc_sf[2])) {
504 aprint_error_dev(bwfm->sc_dev, "cannot enable function 2\n"); 504 aprint_error_dev(bwfm->sc_dev, "cannot enable function 2\n");
505 goto err; 505 goto err;
506 } 506 }
507 507
508// bwfm_sdio_dev_write(sc, SDPCMD_HOSTINTMASK, 508 bwfm_sdio_dev_write(sc, SDPCMD_HOSTINTMASK,
509// SDPCMD_INTSTATUS_HMB_SW_MASK | SDPCMD_INTSTATUS_CHIPACTIVE); 509 SDPCMD_INTSTATUS_HMB_SW_MASK | SDPCMD_INTSTATUS_CHIPACTIVE);
510 bwfm_sdio_dev_write(sc, SDPCMD_HOSTINTMASK, 0xffffffff); 
511 bwfm_sdio_write_1(sc, BWFM_SDIO_WATERMARK, 8); 510 bwfm_sdio_write_1(sc, BWFM_SDIO_WATERMARK, 8);
512 511
513 if (bwfm_chip_sr_capable(bwfm)) { 512 if (bwfm_chip_sr_capable(bwfm)) {
514 reg = bwfm_sdio_read_1(sc, BWFM_SDIO_FUNC1_WAKEUPCTRL); 513 reg = bwfm_sdio_read_1(sc, BWFM_SDIO_FUNC1_WAKEUPCTRL);
515 reg |= BWFM_SDIO_FUNC1_WAKEUPCTRL_HTWAIT; 514 reg |= BWFM_SDIO_FUNC1_WAKEUPCTRL_HTWAIT;
516 bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_WAKEUPCTRL, reg); 515 bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_WAKEUPCTRL, reg);
517 bwfm_sdio_write_1(sc, BWFM_SDIO_CCCR_CARDCAP, 516 bwfm_sdio_write_1(sc, BWFM_SDIO_CCCR_CARDCAP,
518 BWFM_SDIO_CCCR_CARDCAP_CMD14_SUPPORT | 517 BWFM_SDIO_CCCR_CARDCAP_CMD14_SUPPORT |
519 BWFM_SDIO_CCCR_CARDCAP_CMD14_EXT); 518 BWFM_SDIO_CCCR_CARDCAP_CMD14_EXT);
520 bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_CHIPCLKCSR, 519 bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_CHIPCLKCSR,
521 BWFM_SDIO_FUNC1_CHIPCLKCSR_FORCE_HT); 520 BWFM_SDIO_FUNC1_CHIPCLKCSR_FORCE_HT);
522 sc->sc_sr_enabled = 1; 521 sc->sc_sr_enabled = 1;
523 } else { 522 } else {
524 bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_CHIPCLKCSR, clk); 523 bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_CHIPCLKCSR, clk);
525 } 524 }
526 525
527#ifdef notyet 526#ifdef notyet
528 if (sc->sc_phandle >= 0) { 527 if (sc->sc_phandle >= 0) {
529 sc->sc_fdtih = fdtbus_intr_establish(sc->sc_phandle, 528 sc->sc_fdtih = fdtbus_intr_establish(sc->sc_phandle,
530 0, IPL_SDMMC, IST_LEVEL, bwfm_sdio_intr, sc); 529 0, IPL_SDMMC, IST_LEVEL, bwfm_sdio_intr, sc);
531 } 530 }
532#endif 531#endif
533 if (sc->sc_fdtih != NULL) { 532 if (sc->sc_fdtih != NULL) {
534 aprint_normal_dev(self, "enabling GPIO interrupt\n"); 533 aprint_normal_dev(self, "enabling GPIO interrupt\n");
535 } else { 534 } else {
536 sc->sc_ih = sdmmc_intr_establish(device_parent(self), 535 sc->sc_ih = sdmmc_intr_establish(device_parent(self),
537 bwfm_sdio_intr, sc, DEVNAME(sc)); 536 bwfm_sdio_intr, sc, DEVNAME(sc));
538 } 537 }
539 538
540 if (sc->sc_ih == NULL && sc->sc_fdtih == NULL) { 539 if (sc->sc_ih == NULL && sc->sc_fdtih == NULL) {
541 aprint_error_dev(self, "could not establish interrupt\n"); 540 aprint_error_dev(self, "could not establish interrupt\n");
542 bwfm_sdio_clkctl(sc, CLK_NONE, false); 541 bwfm_sdio_clkctl(sc, CLK_NONE, false);
543 return; 542 return;
544 } 543 }
545 sdmmc_intr_enable(sc->sc_sf[1]); 544 sdmmc_intr_enable(sc->sc_sf[1]);
546 545
547 sdmmc_pause(100000, NULL); 546 sdmmc_pause(100000, NULL);
548 547
549 sc->sc_sc.sc_bus_ops = &bwfm_sdio_bus_ops; 548 sc->sc_sc.sc_bus_ops = &bwfm_sdio_bus_ops;
550 sc->sc_sc.sc_proto_ops = &bwfm_proto_bcdc_ops; 549 sc->sc_sc.sc_proto_ops = &bwfm_proto_bcdc_ops;
551 bwfm_attach(&sc->sc_sc); 550 bwfm_attach(&sc->sc_sc);
552 sc->sc_bwfm_attached = true; 551 sc->sc_bwfm_attached = true;
553 552
554 err: 553 err:
555 bwfm_firmware_close(&fwctx); 554 bwfm_firmware_close(&fwctx);
556} 555}
557 556
558static int 557static int
559bwfm_fdt_find_phandle(device_t self, device_t parent) 558bwfm_fdt_find_phandle(device_t self, device_t parent)
560{ 559{
561 prop_dictionary_t dict; 560 prop_dictionary_t dict;
562 device_t dev; 561 device_t dev;
563 const char *str; 562 const char *str;
564 int phandle; 563 int phandle;
565 564
566 /* locate in FDT */ 565 /* locate in FDT */
567 dict = device_properties(self); 566 dict = device_properties(self);
568 if (prop_dictionary_get_cstring_nocopy(dict, "fdt-path", &str)) { 567 if (prop_dictionary_get_cstring_nocopy(dict, "fdt-path", &str)) {
569 /* search in FDT */ 568 /* search in FDT */
570 phandle = OF_finddevice(str); 569 phandle = OF_finddevice(str);
571 } else { 570 } else {
572 571
573 /* parent parent is sdhc controller */ 572 /* parent parent is sdhc controller */
574 dev = device_parent(parent); 573 dev = device_parent(parent);
575 if (dev == NULL) 574 if (dev == NULL)
576 return -1; 575 return -1;
577 /* locate in FDT */ 576 /* locate in FDT */
578 dict = device_properties(dev); 577 dict = device_properties(dev);
579 if (!prop_dictionary_get_cstring_nocopy(dict, "fdt-path", &str)) 578 if (!prop_dictionary_get_cstring_nocopy(dict, "fdt-path", &str))
580 return -1; 579 return -1;
581 580
582 /* are we the only FDT child ? */ 581 /* are we the only FDT child ? */
583 phandle = OF_child(OF_finddevice(str)); 582 phandle = OF_child(OF_finddevice(str));
584 } 583 }
585 584
586 if (!of_match_compatible(phandle, compatible)) 585 if (!of_match_compatible(phandle, compatible))
587 return -1; 586 return -1;
588 587
589 return phandle; 588 return phandle;
590} 589}
591 590
592static const char * 591static const char *
593bwfm_fdt_get_model(void) 592bwfm_fdt_get_model(void)
594{ 593{
595 int phandle; 594 int phandle;
596 595
597 phandle = OF_finddevice("/"); 596 phandle = OF_finddevice("/");
598 return fdtbus_get_string_index(phandle, "compatible", 0); 597 return fdtbus_get_string_index(phandle, "compatible", 0);
599} 598}
600 599
601static int 600static int
602bwfm_sdio_detach(device_t self, int flags) 601bwfm_sdio_detach(device_t self, int flags)
603{ 602{
604 struct bwfm_sdio_softc *sc = (struct bwfm_sdio_softc *)self; 603 struct bwfm_sdio_softc *sc = (struct bwfm_sdio_softc *)self;
605 604
606#ifdef BWFM_DEBUG 605#ifdef BWFM_DEBUG
607 bwfm_sdio_debug_console(sc); 606 bwfm_sdio_debug_console(sc);
608#endif 607#endif
609 608
610 if (sc->sc_ih || sc->sc_fdtih) { 609 if (sc->sc_ih || sc->sc_fdtih) {
611 sdmmc_intr_disable(sc->sc_sf[1]); 610 sdmmc_intr_disable(sc->sc_sf[1]);
612 if (sc->sc_ih) 611 if (sc->sc_ih)
613 sdmmc_intr_disestablish(sc->sc_ih); 612 sdmmc_intr_disestablish(sc->sc_ih);
614 if (sc->sc_fdtih) 613 if (sc->sc_fdtih)
615 fdtbus_intr_disestablish(sc->sc_phandle, sc->sc_fdtih); 614 fdtbus_intr_disestablish(sc->sc_phandle, sc->sc_fdtih);
616 } 615 }
617 if (sc->sc_bwfm_attached) 616 if (sc->sc_bwfm_attached)
618 bwfm_detach(&sc->sc_sc, flags); 617 bwfm_detach(&sc->sc_sc, flags);
619 618
620 sdmmc_del_task(sc->sc_sf[1]->sc, &sc->sc_task, NULL); 619 sdmmc_del_task(sc->sc_sf[1]->sc, &sc->sc_task, NULL);
621 620
622 kmem_free(sc->sc_sf, sc->sc_sf_size); 621 kmem_free(sc->sc_sf, sc->sc_sf_size);
623 kmem_free(sc->sc_bounce_buf, sc->sc_bounce_size); 622 kmem_free(sc->sc_bounce_buf, sc->sc_bounce_size);
624 623
625 cv_destroy(&sc->sc_rxctl_cv); 624 cv_destroy(&sc->sc_rxctl_cv);
626 mutex_destroy(&sc->sc_lock); 625 mutex_destroy(&sc->sc_lock);
627 626
628 return 0; 627 return 0;
629} 628}
630 629
631static void 630static void
632bwfm_sdio_backplane(struct bwfm_sdio_softc *sc, uint32_t addr) 631bwfm_sdio_backplane(struct bwfm_sdio_softc *sc, uint32_t addr)
633{ 632{
634 uint32_t bar0 = addr & ~BWFM_SDIO_SB_OFT_ADDR_MASK; 633 uint32_t bar0 = addr & ~BWFM_SDIO_SB_OFT_ADDR_MASK;
635 634
636 if (sc->sc_bar0 == bar0) 635 if (sc->sc_bar0 == bar0)
637 return; 636 return;
638 637
639 bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_SBADDRLOW, 638 bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_SBADDRLOW,
640 (bar0 >> 8) & 0xff); 639 (bar0 >> 8) & 0xff);
641 bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_SBADDRMID, 640 bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_SBADDRMID,
642 (bar0 >> 16) & 0xff); 641 (bar0 >> 16) & 0xff);
643 bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_SBADDRHIGH, 642 bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_SBADDRHIGH,
644 (bar0 >> 24) & 0xff); 643 (bar0 >> 24) & 0xff);
645 sc->sc_bar0 = bar0; 644 sc->sc_bar0 = bar0;
646} 645}
647 646
648static uint8_t 647static uint8_t
649bwfm_sdio_read_1(struct bwfm_sdio_softc *sc, uint32_t addr) 648bwfm_sdio_read_1(struct bwfm_sdio_softc *sc, uint32_t addr)
650{ 649{
651 struct sdmmc_function *sf; 650 struct sdmmc_function *sf;
652 uint8_t rv; 651 uint8_t rv;
653 652
654 /* 653 /*
655 * figure out how to read the register based on address range 654 * figure out how to read the register based on address range
656 * 0x00 ~ 0x7FF: function 0 CCCR and FBR 655 * 0x00 ~ 0x7FF: function 0 CCCR and FBR
657 * 0x10000 ~ 0x1FFFF: function 1 miscellaneous registers 656 * 0x10000 ~ 0x1FFFF: function 1 miscellaneous registers
658 * The rest: function 1 silicon backplane core registers 657 * The rest: function 1 silicon backplane core registers
659 */ 658 */
660 if ((addr & ~0x7ff) == 0) 659 if ((addr & ~0x7ff) == 0)
661 sf = sc->sc_sf[0]; 660 sf = sc->sc_sf[0];
662 else 661 else
663 sf = sc->sc_sf[1]; 662 sf = sc->sc_sf[1];
664 663
665 rv = sdmmc_io_read_1(sf, addr); 664 rv = sdmmc_io_read_1(sf, addr);
666 return rv; 665 return rv;
667} 666}
668 667
669static uint32_t 668static uint32_t
670bwfm_sdio_read_4(struct bwfm_sdio_softc *sc, uint32_t addr) 669bwfm_sdio_read_4(struct bwfm_sdio_softc *sc, uint32_t addr)
671{ 670{
672 struct sdmmc_function *sf; 671 struct sdmmc_function *sf;
673 uint32_t rv; 672 uint32_t rv;
674 673
675 bwfm_sdio_backplane(sc, addr); 674 bwfm_sdio_backplane(sc, addr);
676 675
677 addr &= BWFM_SDIO_SB_OFT_ADDR_MASK; 676 addr &= BWFM_SDIO_SB_OFT_ADDR_MASK;
678 addr |= BWFM_SDIO_SB_ACCESS_2_4B_FLAG; 677 addr |= BWFM_SDIO_SB_ACCESS_2_4B_FLAG;
679 678
680 /* 679 /*
681 * figure out how to read the register based on address range 680 * figure out how to read the register based on address range
682 * 0x00 ~ 0x7FF: function 0 CCCR and FBR 681 * 0x00 ~ 0x7FF: function 0 CCCR and FBR
683 * 0x10000 ~ 0x1FFFF: function 1 miscellaneous registers 682 * 0x10000 ~ 0x1FFFF: function 1 miscellaneous registers
684 * The rest: function 1 silicon backplane core registers 683 * The rest: function 1 silicon backplane core registers
685 */ 684 */
686 if ((addr & ~0x7ff) == 0) 685 if ((addr & ~0x7ff) == 0)
687 sf = sc->sc_sf[0]; 686 sf = sc->sc_sf[0];
688 else 687 else
689 sf = sc->sc_sf[1]; 688 sf = sc->sc_sf[1];
690 689
691 rv = sdmmc_io_read_4(sf, addr); 690 rv = sdmmc_io_read_4(sf, addr);
692 return htole32(rv); 691 return htole32(rv);
693} 692}
694 693
695static void 694static void
696bwfm_sdio_write_1(struct bwfm_sdio_softc *sc, uint32_t addr, uint8_t data) 695bwfm_sdio_write_1(struct bwfm_sdio_softc *sc, uint32_t addr, uint8_t data)
697{ 696{
698 struct sdmmc_function *sf; 697 struct sdmmc_function *sf;
699 698
700 /* 699 /*
701 * figure out how to read the register based on address range 700 * figure out how to read the register based on address range
702 * 0x00 ~ 0x7FF: function 0 CCCR and FBR 701 * 0x00 ~ 0x7FF: function 0 CCCR and FBR
703 * 0x10000 ~ 0x1FFFF: function 1 miscellaneous registers 702 * 0x10000 ~ 0x1FFFF: function 1 miscellaneous registers
704 * The rest: function 1 silicon backplane core registers 703 * The rest: function 1 silicon backplane core registers
705 */ 704 */
706 if ((addr & ~0x7ff) == 0) 705 if ((addr & ~0x7ff) == 0)
707 sf = sc->sc_sf[0]; 706 sf = sc->sc_sf[0];
708 else 707 else
709 sf = sc->sc_sf[1]; 708 sf = sc->sc_sf[1];
710 709
711 sdmmc_io_write_1(sf, addr, data); 710 sdmmc_io_write_1(sf, addr, data);
712} 711}
713 712
714static void 713static void
715bwfm_sdio_write_4(struct bwfm_sdio_softc *sc, uint32_t addr, uint32_t data) 714bwfm_sdio_write_4(struct bwfm_sdio_softc *sc, uint32_t addr, uint32_t data)
716{ 715{
717 struct sdmmc_function *sf; 716 struct sdmmc_function *sf;
718 717
719 bwfm_sdio_backplane(sc, addr); 718 bwfm_sdio_backplane(sc, addr);
720 719
721 addr &= BWFM_SDIO_SB_OFT_ADDR_MASK; 720 addr &= BWFM_SDIO_SB_OFT_ADDR_MASK;
722 addr |= BWFM_SDIO_SB_ACCESS_2_4B_FLAG; 721 addr |= BWFM_SDIO_SB_ACCESS_2_4B_FLAG;
723 722
724 /* 723 /*
725 * figure out how to read the register based on address range 724 * figure out how to read the register based on address range
726 * 0x00 ~ 0x7FF: function 0 CCCR and FBR 725 * 0x00 ~ 0x7FF: function 0 CCCR and FBR
727 * 0x10000 ~ 0x1FFFF: function 1 miscellaneous registers 726 * 0x10000 ~ 0x1FFFF: function 1 miscellaneous registers
728 * The rest: function 1 silicon backplane core registers 727 * The rest: function 1 silicon backplane core registers
729 */ 728 */
730 if ((addr & ~0x7ff) == 0) 729 if ((addr & ~0x7ff) == 0)
731 sf = sc->sc_sf[0]; 730 sf = sc->sc_sf[0];
732 else 731 else
733 sf = sc->sc_sf[1]; 732 sf = sc->sc_sf[1];
734 733
735 sdmmc_io_write_4(sf, addr, htole32(data)); 734 sdmmc_io_write_4(sf, addr, htole32(data));
736} 735}
737 736
738static int 737static int
739bwfm_sdio_buf_read(struct bwfm_sdio_softc *sc, struct sdmmc_function *sf, 738bwfm_sdio_buf_read(struct bwfm_sdio_softc *sc, struct sdmmc_function *sf,
740 uint32_t reg, char *data, size_t size) 739 uint32_t reg, char *data, size_t size)
741{ 740{
742 int err; 741 int err;
743 742
744 KASSERT(((vaddr_t)data & 0x3) == 0); 743 KASSERT(((vaddr_t)data & 0x3) == 0);
745 KASSERT((size & 0x3) == 0); 744 KASSERT((size & 0x3) == 0);
746 745
747 if (sf == sc->sc_sf[1]) 746 if (sf == sc->sc_sf[1])
748 err = sdmmc_io_read_region_1(sf, reg, data, size); 747 err = sdmmc_io_read_region_1(sf, reg, data, size);
749 else 748 else
750 err = sdmmc_io_read_multi_1(sf, reg, data, size); 749 err = sdmmc_io_read_multi_1(sf, reg, data, size);
751 750
752 if (err) 751 if (err)
753 printf("%s: error %d\n", __func__, err); 752 printf("%s: error %d\n", __func__, err);
754 753
755 return err; 754 return err;
756} 755}
757 756
758static int 757static int
759bwfm_sdio_buf_write(struct bwfm_sdio_softc *sc, struct sdmmc_function *sf, 758bwfm_sdio_buf_write(struct bwfm_sdio_softc *sc, struct sdmmc_function *sf,
760 uint32_t reg, char *data, size_t size) 759 uint32_t reg, char *data, size_t size)
761{ 760{
762 int err; 761 int err;
763 762
764 KASSERT(((vaddr_t)data & 0x3) == 0); 763 KASSERT(((vaddr_t)data & 0x3) == 0);
765 KASSERT((size & 0x3) == 0); 764 KASSERT((size & 0x3) == 0);
766 765
767 err = sdmmc_io_write_region_1(sf, reg, data, size); 766 err = sdmmc_io_write_region_1(sf, reg, data, size);
768 767
769 if (err) 768 if (err)
770 printf("%s: error %d\n", __func__, err); 769 printf("%s: error %d\n", __func__, err);
771 770
772 return err; 771 return err;
773} 772}
774 773
775static uint32_t 774static uint32_t
776bwfm_sdio_ram_read_write(struct bwfm_sdio_softc *sc, uint32_t reg, 775bwfm_sdio_ram_read_write(struct bwfm_sdio_softc *sc, uint32_t reg,
777 char *data, size_t left, int write) 776 char *data, size_t left, int write)
778{ 777{
779 uint32_t sbaddr, sdaddr, off; 778 uint32_t sbaddr, sdaddr, off;
780 size_t size; 779 size_t size;
781 int err; 780 int err;
782 781
783 err = off = 0; 782 err = off = 0;
784 while (left > 0) { 783 while (left > 0) {
785 sbaddr = reg + off; 784 sbaddr = reg + off;
786 bwfm_sdio_backplane(sc, sbaddr); 785 bwfm_sdio_backplane(sc, sbaddr);
787 786
788 sdaddr = sbaddr & BWFM_SDIO_SB_OFT_ADDR_MASK; 787 sdaddr = sbaddr & BWFM_SDIO_SB_OFT_ADDR_MASK;
789 size = ulmin(left, (BWFM_SDIO_SB_OFT_ADDR_PAGE - sdaddr)); 788 size = ulmin(left, (BWFM_SDIO_SB_OFT_ADDR_PAGE - sdaddr));
790 sdaddr |= BWFM_SDIO_SB_ACCESS_2_4B_FLAG; 789 sdaddr |= BWFM_SDIO_SB_ACCESS_2_4B_FLAG;
791 790
792 if (write) { 791 if (write) {
793 memcpy(sc->sc_bounce_buf, data + off, size); 792 memcpy(sc->sc_bounce_buf, data + off, size);
794 if (roundup(size, 4) != size) 793 if (roundup(size, 4) != size)
795 memset(sc->sc_bounce_buf + size, 0, 794 memset(sc->sc_bounce_buf + size, 0,
796 roundup(size, 4) - size); 795 roundup(size, 4) - size);
797 err = bwfm_sdio_buf_write(sc, sc->sc_sf[1], sdaddr, 796 err = bwfm_sdio_buf_write(sc, sc->sc_sf[1], sdaddr,
798 sc->sc_bounce_buf, roundup(size, 4)); 797 sc->sc_bounce_buf, roundup(size, 4));
799 } else { 798 } else {
800 err = bwfm_sdio_buf_read(sc, sc->sc_sf[1], sdaddr, 799 err = bwfm_sdio_buf_read(sc, sc->sc_sf[1], sdaddr,
801 sc->sc_bounce_buf, roundup(size, 4)); 800 sc->sc_bounce_buf, roundup(size, 4));
802 memcpy(data + off, sc->sc_bounce_buf, size); 801 memcpy(data + off, sc->sc_bounce_buf, size);
803 } 802 }
804 if (err) 803 if (err)
805 break; 804 break;
806 805
807 off += size; 806 off += size;
808 left -= size; 807 left -= size;
809 } 808 }
810 809
811 if (err) 810 if (err)
812 printf("%s: error %d\n", __func__, err); 811 printf("%s: error %d\n", __func__, err);
813 812
814 return err; 813 return err;
815} 814}
816 815
817static uint32_t 816static uint32_t
818bwfm_sdio_frame_read_write(struct bwfm_sdio_softc *sc, 817bwfm_sdio_frame_read_write(struct bwfm_sdio_softc *sc,
819 char *data, size_t size, int write) 818 char *data, size_t size, int write)
820{ 819{
821 uint32_t addr; 820 uint32_t addr;
822 int err; 821 int err;
823 822
824 addr = sc->sc_cc->co_base; 823 addr = sc->sc_cc->co_base;
825 bwfm_sdio_backplane(sc, addr); 824 bwfm_sdio_backplane(sc, addr);
826 825
827 addr &= BWFM_SDIO_SB_OFT_ADDR_MASK; 826 addr &= BWFM_SDIO_SB_OFT_ADDR_MASK;
828 addr |= BWFM_SDIO_SB_ACCESS_2_4B_FLAG; 827 addr |= BWFM_SDIO_SB_ACCESS_2_4B_FLAG;
829 828
830 if (write) 829 if (write)
831 err = bwfm_sdio_buf_write(sc, sc->sc_sf[2], addr, data, size); 830 err = bwfm_sdio_buf_write(sc, sc->sc_sf[2], addr, data, size);
832 else 831 else
833 err = bwfm_sdio_buf_read(sc, sc->sc_sf[2], addr, data, size); 832 err = bwfm_sdio_buf_read(sc, sc->sc_sf[2], addr, data, size);
834 833
835 if (err) 834 if (err)
836 printf("%s: error %d\n", __func__, err); 835 printf("%s: error %d\n", __func__, err);
837 836
838 return err; 837 return err;
839} 838}
840 839
841static uint32_t 840static uint32_t
842bwfm_sdio_dev_read(struct bwfm_sdio_softc *sc, uint32_t reg) 841bwfm_sdio_dev_read(struct bwfm_sdio_softc *sc, uint32_t reg)
843{ 842{
844 struct bwfm_core *core; 843 struct bwfm_core *core;
845 uint32_t val; 844 uint32_t val;
846 845
847 core = bwfm_chip_get_core(&sc->sc_sc, BWFM_AGENT_CORE_SDIO_DEV); 846 core = bwfm_chip_get_core(&sc->sc_sc, BWFM_AGENT_CORE_SDIO_DEV);
848 val = bwfm_sdio_read_4(sc, core->co_base + reg); 847 val = bwfm_sdio_read_4(sc, core->co_base + reg);
849 /* TODO: Workaround for 4335/4339 */ 848 /* TODO: Workaround for 4335/4339 */
850 849
851 return val; 850 return val;
852} 851}
853 852
854static void 853static void
855bwfm_sdio_dev_write(struct bwfm_sdio_softc *sc, uint32_t reg, uint32_t val) 854bwfm_sdio_dev_write(struct bwfm_sdio_softc *sc, uint32_t reg, uint32_t val)
856{ 855{
857 struct bwfm_core *core; 856 struct bwfm_core *core;
858 857
859 core = bwfm_chip_get_core(&sc->sc_sc, BWFM_AGENT_CORE_SDIO_DEV); 858 core = bwfm_chip_get_core(&sc->sc_sc, BWFM_AGENT_CORE_SDIO_DEV);
860 bwfm_sdio_write_4(sc, core->co_base + reg, val); 859 bwfm_sdio_write_4(sc, core->co_base + reg, val);
861} 860}
862 861
863static uint32_t 862static uint32_t
864bwfm_sdio_buscore_read(struct bwfm_softc *bwfm, uint32_t reg) 863bwfm_sdio_buscore_read(struct bwfm_softc *bwfm, uint32_t reg)
865{ 864{
866 struct bwfm_sdio_softc *sc = (void *)bwfm; 865 struct bwfm_sdio_softc *sc = (void *)bwfm;
867 uint32_t val; 866 uint32_t val;
868 867
869 mutex_enter(&sc->sc_lock); 868 mutex_enter(&sc->sc_lock);
870 val = bwfm_sdio_read_4(sc, reg); 869 val = bwfm_sdio_read_4(sc, reg);
871 /* TODO: Workaround for 4335/4339 */ 870 /* TODO: Workaround for 4335/4339 */
872 mutex_exit(&sc->sc_lock); 871 mutex_exit(&sc->sc_lock);
873 872
874 return val; 873 return val;
875} 874}
876 875
877static void 876static void
878bwfm_sdio_buscore_write(struct bwfm_softc *bwfm, uint32_t reg, uint32_t val) 877bwfm_sdio_buscore_write(struct bwfm_softc *bwfm, uint32_t reg, uint32_t val)
879{ 878{
880 struct bwfm_sdio_softc *sc = (void *)bwfm; 879 struct bwfm_sdio_softc *sc = (void *)bwfm;
881 880
882 mutex_enter(&sc->sc_lock); 881 mutex_enter(&sc->sc_lock);
883 bwfm_sdio_write_4(sc, reg, val); 882 bwfm_sdio_write_4(sc, reg, val);
884 mutex_exit(&sc->sc_lock); 883 mutex_exit(&sc->sc_lock);
885} 884}
886 885
887static int 886static int
888bwfm_sdio_buscore_prepare(struct bwfm_softc *bwfm) 887bwfm_sdio_buscore_prepare(struct bwfm_softc *bwfm)
889{ 888{
890 struct bwfm_sdio_softc *sc = (void *)bwfm; 889 struct bwfm_sdio_softc *sc = (void *)bwfm;
891 uint8_t clkval, clkset, clkmask; 890 uint8_t clkval, clkset, clkmask;
892 int i, error = 0; 891 int i, error = 0;
893 892
894 mutex_enter(&sc->sc_lock); 893 mutex_enter(&sc->sc_lock);
895 894
896 clkset = BWFM_SDIO_FUNC1_CHIPCLKCSR_ALP_AVAIL_REQ | 895 clkset = BWFM_SDIO_FUNC1_CHIPCLKCSR_ALP_AVAIL_REQ |
897 BWFM_SDIO_FUNC1_CHIPCLKCSR_FORCE_HW_CLKREQ_OFF; 896 BWFM_SDIO_FUNC1_CHIPCLKCSR_FORCE_HW_CLKREQ_OFF;
898 bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_CHIPCLKCSR, clkset); 897 bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_CHIPCLKCSR, clkset);
899 898
900 clkmask = BWFM_SDIO_FUNC1_CHIPCLKCSR_ALP_AVAIL | 899 clkmask = BWFM_SDIO_FUNC1_CHIPCLKCSR_ALP_AVAIL |
901 BWFM_SDIO_FUNC1_CHIPCLKCSR_HT_AVAIL; 900 BWFM_SDIO_FUNC1_CHIPCLKCSR_HT_AVAIL;
902 clkval = bwfm_sdio_read_1(sc, BWFM_SDIO_FUNC1_CHIPCLKCSR); 901 clkval = bwfm_sdio_read_1(sc, BWFM_SDIO_FUNC1_CHIPCLKCSR);
903 902
904 if ((clkval & ~clkmask) != clkset) { 903 if ((clkval & ~clkmask) != clkset) {
905 printf("%s: wrote 0x%02x read 0x%02x\n", DEVNAME(sc), 904 printf("%s: wrote 0x%02x read 0x%02x\n", DEVNAME(sc),
906 clkset, clkval); 905 clkset, clkval);
907 error = 1; 906 error = 1;
908 goto done; 907 goto done;
909 } 908 }
910 909
911 for (i = 1000; i > 0; i--) { 910 for (i = 1000; i > 0; i--) {
912 clkval = bwfm_sdio_read_1(sc, 911 clkval = bwfm_sdio_read_1(sc,
913 BWFM_SDIO_FUNC1_CHIPCLKCSR); 912 BWFM_SDIO_FUNC1_CHIPCLKCSR);
914 if (clkval & clkmask) 913 if (clkval & clkmask)
915 break; 914 break;
916 } 915 }
917 if (i == 0) { 916 if (i == 0) {
918 printf("%s: timeout on ALPAV wait, clkval 0x%02x\n", 917 printf("%s: timeout on ALPAV wait, clkval 0x%02x\n",
919 DEVNAME(sc), clkval); 918 DEVNAME(sc), clkval);
920 error = 1; 919 error = 1;
921 goto done; 920 goto done;
922 } 921 }
923 922
924 clkset = BWFM_SDIO_FUNC1_CHIPCLKCSR_FORCE_HW_CLKREQ_OFF | 923 clkset = BWFM_SDIO_FUNC1_CHIPCLKCSR_FORCE_HW_CLKREQ_OFF |
925 BWFM_SDIO_FUNC1_CHIPCLKCSR_FORCE_ALP; 924 BWFM_SDIO_FUNC1_CHIPCLKCSR_FORCE_ALP;
926 bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_CHIPCLKCSR, clkset); 925 bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_CHIPCLKCSR, clkset);
927 delay(65); 926 delay(65);
928 927
929 bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_SDIOPULLUP, 0); 928 bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_SDIOPULLUP, 0);
930 929
931done: 930done:
932 mutex_exit(&sc->sc_lock); 931 mutex_exit(&sc->sc_lock);
933 932
934 return error; 933 return error;
935} 934}
936 935
937static void 936static void
938bwfm_sdio_buscore_activate(struct bwfm_softc *bwfm, uint32_t rstvec) 937bwfm_sdio_buscore_activate(struct bwfm_softc *bwfm, uint32_t rstvec)
939{ 938{
940 struct bwfm_sdio_softc *sc = (void *)bwfm; 939 struct bwfm_sdio_softc *sc = (void *)bwfm;
941 struct bwfm_core *core; 940 struct bwfm_core *core;
942 941
943 core = bwfm_chip_get_core(&sc->sc_sc, BWFM_AGENT_CORE_SDIO_DEV); 942 core = bwfm_chip_get_core(&sc->sc_sc, BWFM_AGENT_CORE_SDIO_DEV);
944 bwfm_sdio_buscore_write(&sc->sc_sc, 943 bwfm_sdio_buscore_write(&sc->sc_sc,
945 core->co_base + BWFM_SDPCMD_INTSTATUS, 0xFFFFFFFF); 944 core->co_base + BWFM_SDPCMD_INTSTATUS, 0xFFFFFFFF);
946 945
947 mutex_enter(&sc->sc_lock); 946 mutex_enter(&sc->sc_lock);
948 if (rstvec) 947 if (rstvec)
949 bwfm_sdio_ram_read_write(sc, 0, (char *)&rstvec, 948 bwfm_sdio_ram_read_write(sc, 0, (char *)&rstvec,
950 sizeof(rstvec), 1); 949 sizeof(rstvec), 1);
951 mutex_exit(&sc->sc_lock); 950 mutex_exit(&sc->sc_lock);
952} 951}
953 952
954static struct mbuf * 953static struct mbuf *
955bwfm_sdio_newbuf(void) 954bwfm_sdio_newbuf(void)
956{ 955{
957 struct mbuf *m; 956 struct mbuf *m;
958 957
959 MGETHDR(m, M_DONTWAIT, MT_DATA); 958 MGETHDR(m, M_DONTWAIT, MT_DATA);
960 if (m == NULL) 959 if (m == NULL)
961 return NULL; 960 return NULL;
962 961
963 MCLGET(m, M_DONTWAIT); 962 MCLGET(m, M_DONTWAIT);
964 if (!(m->m_flags & M_EXT)) { 963 if (!(m->m_flags & M_EXT)) {
965 m_freem(m); 964 m_freem(m);
966 return NULL; 965 return NULL;
967 } 966 }
968 967
969 m->m_len = m->m_pkthdr.len = MCLBYTES; 968 m->m_len = m->m_pkthdr.len = MCLBYTES;
970 return m; 969 return m;
971} 970}
972 971
973static struct mbuf * 972static struct mbuf *
974bwfm_qget(struct mbuf **q) 973bwfm_qget(struct mbuf **q)
975{ 974{
976 struct mbuf *m = NULL; 975 struct mbuf *m = NULL;
977 976
978 if (*q != NULL) { 977 if (*q != NULL) {
979 m = *q; 978 m = *q;
980 *q = m->m_next; 979 *q = m->m_next;
981 m->m_next = NULL; 980 m->m_next = NULL;
982 } 981 }
983 982
984 return m; 983 return m;
985} 984}
986 985
987static void 986static void
988bwfm_qput(struct mbuf **q, struct mbuf *m) 987bwfm_qput(struct mbuf **q, struct mbuf *m)
989{ 988{
990 989
991 if (*q == NULL) 990 if (*q == NULL)
992 *q = m; 991 *q = m;
993 else 992 else
994 m_cat(*q, m); 993 m_cat(*q, m);
995} 994}
996 995
997static int 996static int
998bwfm_sdio_txcheck(struct bwfm_softc *bwfm) 997bwfm_sdio_txcheck(struct bwfm_softc *bwfm)
999{ 998{
1000 struct bwfm_sdio_softc *sc = (void *)bwfm; 999 struct bwfm_sdio_softc *sc = (void *)bwfm;
1001 int error = 0; 1000 int error = 0;
1002 1001
1003 mutex_enter(&sc->sc_lock); 1002 mutex_enter(&sc->sc_lock);
1004 if (sc->sc_tx_count >= 64) 1003 if (sc->sc_tx_count >= 64)
1005 error = ENOBUFS; 1004 error = ENOBUFS;
1006 mutex_exit(&sc->sc_lock); 1005 mutex_exit(&sc->sc_lock);
1007 1006
1008 return error; 1007 return error;
1009} 1008}
1010 1009
1011 1010
1012static int 1011static int
1013bwfm_sdio_txdata(struct bwfm_softc *bwfm, struct mbuf **mp) 1012bwfm_sdio_txdata(struct bwfm_softc *bwfm, struct mbuf **mp)
1014{ 1013{
1015 struct bwfm_sdio_softc *sc = (void *)bwfm; 1014 struct bwfm_sdio_softc *sc = (void *)bwfm;
1016 1015
1017 if (sc->sc_tx_count >= 64) { 1016 if (sc->sc_tx_count >= 64) {
1018 printf("%s: tx count limit reached\n",DEVNAME(sc)); 1017 printf("%s: tx count limit reached\n",DEVNAME(sc));
1019 return ENOBUFS; 1018 return ENOBUFS;
1020 } 1019 }
1021 1020
1022 mutex_enter(&sc->sc_lock); 1021 mutex_enter(&sc->sc_lock);
1023 sc->sc_tx_count++; 1022 sc->sc_tx_count++;
1024 MBUFQ_ENQUEUE(&sc->sc_tx_queue, *mp); 1023 MBUFQ_ENQUEUE(&sc->sc_tx_queue, *mp);
1025 mutex_exit(&sc->sc_lock); 1024 mutex_exit(&sc->sc_lock);
1026 1025
1027 bwfm_sdio_intr1(sc, "sdio_txdata"); 1026 bwfm_sdio_intr1(sc, "sdio_txdata");
1028 1027
1029 return 0; 1028 return 0;
1030} 1029}
1031 1030
1032static int 1031static int
1033bwfm_sdio_txctl(struct bwfm_softc *bwfm, char *buf, size_t len) 1032bwfm_sdio_txctl(struct bwfm_softc *bwfm, char *buf, size_t len)
1034{ 1033{
1035 struct bwfm_sdio_softc *sc = (void *)bwfm; 1034 struct bwfm_sdio_softc *sc = (void *)bwfm;
1036 struct mbuf *m; 1035 struct mbuf *m;
1037 1036
1038 KASSERT(len <= MCLBYTES); 1037 KASSERT(len <= MCLBYTES);
1039 1038
1040 MGET(m, M_DONTWAIT, MT_CONTROL); 1039 MGET(m, M_DONTWAIT, MT_CONTROL);
1041 if (m == NULL) 1040 if (m == NULL)
1042 goto fail; 1041 goto fail;
1043 if (len > MLEN) { 1042 if (len > MLEN) {
1044 MCLGET(m, M_DONTWAIT); 1043 MCLGET(m, M_DONTWAIT);
1045 if (!(m->m_flags & M_EXT)) { 1044 if (!(m->m_flags & M_EXT)) {
1046 m_freem(m); 1045 m_freem(m);
1047 goto fail; 1046 goto fail;
1048 } 1047 }
1049 } 1048 }
1050 memcpy(mtod(m, char *), buf, len); 1049 memcpy(mtod(m, char *), buf, len);
1051 m->m_len = len; 1050 m->m_len = len;
1052 1051
1053 mutex_enter(&sc->sc_lock); 1052 mutex_enter(&sc->sc_lock);
1054 MBUFQ_ENQUEUE(&sc->sc_tx_queue, m); 1053 MBUFQ_ENQUEUE(&sc->sc_tx_queue, m);
1055 mutex_exit(&sc->sc_lock); 1054 mutex_exit(&sc->sc_lock);
1056 1055
1057 bwfm_sdio_intr1(sc, "sdio_txctl"); 1056 bwfm_sdio_intr1(sc, "sdio_txctl");
1058 1057
1059 return 0; 1058 return 0;
1060 1059
1061fail: 1060fail:
1062 return ENOBUFS; 1061 return ENOBUFS;
1063} 1062}
1064 1063
1065static int 1064static int
1066bwfm_nvram_convert(u_char *buf, size_t len, size_t *newlenp) 1065bwfm_nvram_convert(u_char *buf, size_t len, size_t *newlenp)
1067{ 1066{
1068 u_char *src, *dst, *end = buf + len; 1067 u_char *src, *dst, *end = buf + len;
1069 bool skip = false; 1068 bool skip = false;
1070 size_t count = 0, pad; 1069 size_t count = 0, pad;
1071 uint32_t token; 1070 uint32_t token;
1072 1071
1073 for (src = buf, dst = buf; src != end; ++src) { 1072 for (src = buf, dst = buf; src != end; ++src) {
1074 if (*src == '\n') { 1073 if (*src == '\n') {
1075 if (count > 0) 1074 if (count > 0)
1076 *dst++ = '\0'; 1075 *dst++ = '\0';
1077 count = 0; 1076 count = 0;
1078 skip = false; 1077 skip = false;
1079 continue; 1078 continue;
1080 } 1079 }
1081 if (skip) 1080 if (skip)
1082 continue; 1081 continue;
1083 if (*src == '#' && count == 0) { 1082 if (*src == '#' && count == 0) {
1084 skip = true; 1083 skip = true;
1085 continue; 1084 continue;
1086 } 1085 }
1087 if (*src == '\r' || *src == ' ') 1086 if (*src == '\r' || *src == ' ')
1088 continue; 1087 continue;
1089 *dst++ = *src; 1088 *dst++ = *src;
1090 ++count; 1089 ++count;
1091 } 1090 }
1092 1091
1093 count = dst - buf; 1092 count = dst - buf;
1094 pad = roundup(count + 1, 4) - count; 1093 pad = roundup(count + 1, 4) - count;
1095 1094
1096 if (count + pad + sizeof(token) > len) 1095 if (count + pad + sizeof(token) > len)
1097 return 1; 1096 return 1;
1098 1097
1099 memset(dst, 0, pad); 1098 memset(dst, 0, pad);
1100 count += pad; 1099 count += pad;
1101 dst += pad; 1100 dst += pad;
1102 1101
1103 token = (count / 4) & 0xffff; 1102 token = (count / 4) & 0xffff;
1104 token |= ~token << 16; 1103 token |= ~token << 16;
1105 token = htole32(token); 1104 token = htole32(token);
1106 1105
1107 memcpy(dst, &token, sizeof(token)); 1106 memcpy(dst, &token, sizeof(token));
1108 count += sizeof(token); 1107 count += sizeof(token);
1109 1108
1110 *newlenp = count; 1109 *newlenp = count;
1111 1110
1112 return 0; 1111 return 0;
1113} 1112}
1114 1113
1115static int 1114static int
1116bwfm_sdio_load_microcode(struct bwfm_sdio_softc *sc, u_char *ucode, size_t size, 1115bwfm_sdio_load_microcode(struct bwfm_sdio_softc *sc, u_char *ucode, size_t size,
1117 u_char *nvram, size_t nvlen) 1116 u_char *nvram, size_t nvlen)
1118{ 1117{
1119 struct bwfm_softc *bwfm = &sc->sc_sc; 1118 struct bwfm_softc *bwfm = &sc->sc_sc;
1120 char *verify = NULL; 1119 char *verify = NULL;
1121 int err = 0; 1120 int err = 0;
1122 1121
1123 bwfm_sdio_clkctl(sc, CLK_AVAIL, false); 1122 bwfm_sdio_clkctl(sc, CLK_AVAIL, false);
1124 1123
1125 DPRINTF(("ucode %zu bytes to 0x%08lx\n", size, 1124 DPRINTF(("ucode %zu bytes to 0x%08lx\n", size,
1126 (u_long)bwfm->sc_chip.ch_rambase)); 1125 (u_long)bwfm->sc_chip.ch_rambase));
1127 /* Upload firmware */ 1126 /* Upload firmware */
1128 err = bwfm_sdio_ram_read_write(sc, bwfm->sc_chip.ch_rambase, 1127 err = bwfm_sdio_ram_read_write(sc, bwfm->sc_chip.ch_rambase,
1129 ucode, size, 1); 1128 ucode, size, 1);
1130 if (err) 1129 if (err)
1131 goto out; 1130 goto out;
1132 1131
1133 /* Verify firmware */ 1132 /* Verify firmware */
1134 verify = kmem_zalloc(size, KM_SLEEP); 1133 verify = kmem_zalloc(size, KM_SLEEP);
1135 err = bwfm_sdio_ram_read_write(sc, bwfm->sc_chip.ch_rambase, 1134 err = bwfm_sdio_ram_read_write(sc, bwfm->sc_chip.ch_rambase,
1136 verify, size, 0); 1135 verify, size, 0);
1137 if (err || memcmp(verify, ucode, size)) { 1136 if (err || memcmp(verify, ucode, size)) {
1138 printf("%s: firmware verification failed\n", 1137 printf("%s: firmware verification failed\n",
1139 DEVNAME(sc)); 1138 DEVNAME(sc));
1140 kmem_free(verify, size); 1139 kmem_free(verify, size);
1141 goto out; 1140 goto out;
1142 } 1141 }
1143 kmem_free(verify, size); 1142 kmem_free(verify, size);
1144 1143
1145 DPRINTF(("nvram %zu bytes to 0x%08lx\n", nvlen, 1144 DPRINTF(("nvram %zu bytes to 0x%08lx\n", nvlen,
1146 (u_long)bwfm->sc_chip.ch_rambase + bwfm->sc_chip.ch_ramsize 1145 (u_long)bwfm->sc_chip.ch_rambase + bwfm->sc_chip.ch_ramsize
1147 - nvlen)); 1146 - nvlen));
1148 /* Upload nvram */ 1147 /* Upload nvram */
1149 err = bwfm_sdio_ram_read_write(sc, bwfm->sc_chip.ch_rambase + 1148 err = bwfm_sdio_ram_read_write(sc, bwfm->sc_chip.ch_rambase +
1150 bwfm->sc_chip.ch_ramsize - nvlen, nvram, nvlen, 1); 1149 bwfm->sc_chip.ch_ramsize - nvlen, nvram, nvlen, 1);
1151 if (err) 1150 if (err)
1152 goto out; 1151 goto out;
1153 1152
1154 /* Verify nvram */ 1153 /* Verify nvram */
1155 verify = kmem_zalloc(nvlen, KM_SLEEP); 1154 verify = kmem_zalloc(nvlen, KM_SLEEP);
1156 err = bwfm_sdio_ram_read_write(sc, bwfm->sc_chip.ch_rambase + 1155 err = bwfm_sdio_ram_read_write(sc, bwfm->sc_chip.ch_rambase +
1157 bwfm->sc_chip.ch_ramsize - nvlen, verify, nvlen, 0); 1156 bwfm->sc_chip.ch_ramsize - nvlen, verify, nvlen, 0);
1158 if (err || memcmp(verify, nvram, nvlen)) { 1157 if (err || memcmp(verify, nvram, nvlen)) {
1159 printf("%s: nvram verification failed\n", 1158 printf("%s: nvram verification failed\n",
1160 DEVNAME(sc)); 1159 DEVNAME(sc));
1161 kmem_free(verify, nvlen); 1160 kmem_free(verify, nvlen);
1162 goto out; 1161 goto out;
1163 } 1162 }
1164 kmem_free(verify, nvlen); 1163 kmem_free(verify, nvlen);
1165 1164
1166 DPRINTF(("Reset core 0x%08x\n", *(uint32_t *)ucode)); 1165 DPRINTF(("Reset core 0x%08x\n", *(uint32_t *)ucode));
1167 /* Load reset vector from firmware and kickstart core. */ 1166 /* Load reset vector from firmware and kickstart core. */
1168 bwfm_chip_set_active(bwfm, *(uint32_t *)ucode); 1167 bwfm_chip_set_active(bwfm, *(uint32_t *)ucode);
1169 1168
1170out: 1169out:
1171 bwfm_sdio_clkctl(sc, CLK_SDONLY, false); 1170 bwfm_sdio_clkctl(sc, CLK_SDONLY, false);
1172 return err; 1171 return err;
1173} 1172}
1174 1173
1175static void 1174static void
1176bwfm_sdio_clkctl(struct bwfm_sdio_softc *sc, enum bwfm_sdio_clkstate newstate, 1175bwfm_sdio_clkctl(struct bwfm_sdio_softc *sc, enum bwfm_sdio_clkstate newstate,
1177 bool pendok) 1176 bool pendok)
1178{ 1177{
1179 enum bwfm_sdio_clkstate oldstate; 1178 enum bwfm_sdio_clkstate oldstate;
1180 1179
1181 oldstate = sc->sc_clkstate; 1180 oldstate = sc->sc_clkstate;
1182 if (oldstate == newstate) 1181 if (oldstate == newstate)
1183 return; 1182 return;
1184 1183
1185 switch (newstate) { 1184 switch (newstate) {
1186 case CLK_AVAIL: 1185 case CLK_AVAIL:
1187 if (oldstate == CLK_NONE) 1186 if (oldstate == CLK_NONE)
1188 sc->sc_clkstate = CLK_SDONLY; /* XXX */ 1187 sc->sc_clkstate = CLK_SDONLY; /* XXX */
1189 bwfm_sdio_htclk(sc, true, pendok); 1188 bwfm_sdio_htclk(sc, true, pendok);
1190 break; 1189 break;
1191 case CLK_SDONLY: 1190 case CLK_SDONLY:
1192 if (oldstate == CLK_NONE) 1191 if (oldstate == CLK_NONE)
1193 sc->sc_clkstate = newstate; 1192 sc->sc_clkstate = newstate;
1194 else if (oldstate == CLK_AVAIL) 1193 else if (oldstate == CLK_AVAIL)
1195 bwfm_sdio_htclk(sc, false, false); 1194 bwfm_sdio_htclk(sc, false, false);
1196 else 1195 else
1197 printf("%s: clkctl %d -> %d\n", DEVNAME(sc), 1196 printf("%s: clkctl %d -> %d\n", DEVNAME(sc),
1198 sc->sc_clkstate, newstate); 1197 sc->sc_clkstate, newstate);
1199 break; 1198 break;
1200 case CLK_NONE: 1199 case CLK_NONE:
1201 if (oldstate == CLK_AVAIL) 1200 if (oldstate == CLK_AVAIL)
1202 bwfm_sdio_htclk(sc, false, false); 1201 bwfm_sdio_htclk(sc, false, false);
1203 sc->sc_clkstate = newstate; 1202 sc->sc_clkstate = newstate;
1204 break; 1203 break;
1205 default: 1204 default:
1206 break; 1205 break;
1207 } 1206 }
1208 1207
1209 DPRINTF(("%s: %d -> %d = %d\n", DEVNAME(sc), oldstate, newstate, 1208 DPRINTF(("%s: %d -> %d = %d\n", DEVNAME(sc), oldstate, newstate,
1210 sc->sc_clkstate)); 1209 sc->sc_clkstate));
1211} 1210}
1212 1211
1213static void 1212static void
1214bwfm_sdio_htclk(struct bwfm_sdio_softc *sc, bool on, bool pendok) 1213bwfm_sdio_htclk(struct bwfm_sdio_softc *sc, bool on, bool pendok)
1215{ 1214{
1216 uint32_t clkctl, devctl, req; 1215 uint32_t clkctl, devctl, req;
1217 int i; 1216 int i;
1218 1217
1219 if (sc->sc_sr_enabled) { 1218 if (sc->sc_sr_enabled) {
1220 if (on) 1219 if (on)
1221 sc->sc_clkstate = CLK_AVAIL; 1220 sc->sc_clkstate = CLK_AVAIL;
1222 else 1221 else
1223 sc->sc_clkstate = CLK_SDONLY; 1222 sc->sc_clkstate = CLK_SDONLY;
1224 return; 1223 return;
1225 } 1224 }
1226 1225
1227 if (on) { 1226 if (on) {
1228 if (sc->sc_alp_only) 1227 if (sc->sc_alp_only)
1229 req = BWFM_SDIO_FUNC1_CHIPCLKCSR_ALP_AVAIL_REQ; 1228 req = BWFM_SDIO_FUNC1_CHIPCLKCSR_ALP_AVAIL_REQ;
1230 else 1229 else
1231 req = BWFM_SDIO_FUNC1_CHIPCLKCSR_HT_AVAIL_REQ; 1230 req = BWFM_SDIO_FUNC1_CHIPCLKCSR_HT_AVAIL_REQ;
1232 bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_CHIPCLKCSR, req); 1231 bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_CHIPCLKCSR, req);
1233 1232
1234 clkctl = bwfm_sdio_read_1(sc, BWFM_SDIO_FUNC1_CHIPCLKCSR); 1233 clkctl = bwfm_sdio_read_1(sc, BWFM_SDIO_FUNC1_CHIPCLKCSR);
1235 if (!BWFM_SDIO_FUNC1_CHIPCLKCSR_CLKAV(clkctl, sc->sc_alp_only) 1234 if (!BWFM_SDIO_FUNC1_CHIPCLKCSR_CLKAV(clkctl, sc->sc_alp_only)
1236 && pendok) { 1235 && pendok) {
1237 devctl = bwfm_sdio_read_1(sc, BWFM_SDIO_DEVICE_CTL); 1236 devctl = bwfm_sdio_read_1(sc, BWFM_SDIO_DEVICE_CTL);
1238 devctl |= BWFM_SDIO_DEVICE_CTL_CA_INT_ONLY; 1237 devctl |= BWFM_SDIO_DEVICE_CTL_CA_INT_ONLY;
1239 bwfm_sdio_write_1(sc, BWFM_SDIO_DEVICE_CTL, devctl); 1238 bwfm_sdio_write_1(sc, BWFM_SDIO_DEVICE_CTL, devctl);
1240 sc->sc_clkstate = CLK_PENDING; 1239 sc->sc_clkstate = CLK_PENDING;
1241 return; 1240 return;
1242 } else if (sc->sc_clkstate == CLK_PENDING) { 1241 } else if (sc->sc_clkstate == CLK_PENDING) {
1243 devctl = bwfm_sdio_read_1(sc, BWFM_SDIO_DEVICE_CTL); 1242 devctl = bwfm_sdio_read_1(sc, BWFM_SDIO_DEVICE_CTL);
1244 devctl &= ~BWFM_SDIO_DEVICE_CTL_CA_INT_ONLY; 1243 devctl &= ~BWFM_SDIO_DEVICE_CTL_CA_INT_ONLY;
1245 bwfm_sdio_write_1(sc, BWFM_SDIO_DEVICE_CTL, devctl); 1244 bwfm_sdio_write_1(sc, BWFM_SDIO_DEVICE_CTL, devctl);
1246 } 1245 }
1247 1246
1248 for (i = 0; i < 50; i++) { 1247 for (i = 0; i < 50; i++) {
1249 if (BWFM_SDIO_FUNC1_CHIPCLKCSR_CLKAV(clkctl, 1248 if (BWFM_SDIO_FUNC1_CHIPCLKCSR_CLKAV(clkctl,
1250 sc->sc_alp_only)) 1249 sc->sc_alp_only))
1251 break; 1250 break;
1252 clkctl = bwfm_sdio_read_1(sc, BWFM_SDIO_FUNC1_CHIPCLKCSR 1251 clkctl = bwfm_sdio_read_1(sc, BWFM_SDIO_FUNC1_CHIPCLKCSR
1253); 1252);
1254 sdmmc_pause(100000, NULL); 1253 sdmmc_pause(100000, NULL);
1255 } 1254 }
1256 if (i >= 50) { 1255 if (i >= 50) {
1257 printf("%s: HT avail timeout\n", DEVNAME(sc)); 1256 printf("%s: HT avail timeout\n", DEVNAME(sc));
1258 return; 1257 return;
1259 } 1258 }
1260 1259
1261 sc->sc_clkstate = CLK_AVAIL; 1260 sc->sc_clkstate = CLK_AVAIL;
1262 } else { 1261 } else {
1263 if (sc->sc_clkstate == CLK_PENDING) { 1262 if (sc->sc_clkstate == CLK_PENDING) {
1264 devctl = bwfm_sdio_read_1(sc, BWFM_SDIO_DEVICE_CTL); 1263 devctl = bwfm_sdio_read_1(sc, BWFM_SDIO_DEVICE_CTL);
1265 devctl &= ~BWFM_SDIO_DEVICE_CTL_CA_INT_ONLY; 1264 devctl &= ~BWFM_SDIO_DEVICE_CTL_CA_INT_ONLY;
1266 bwfm_sdio_write_1(sc, BWFM_SDIO_DEVICE_CTL, devctl); 1265 bwfm_sdio_write_1(sc, BWFM_SDIO_DEVICE_CTL, devctl);
1267 } 1266 }
1268 sc->sc_clkstate = CLK_SDONLY; 1267 sc->sc_clkstate = CLK_SDONLY;
1269 bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_CHIPCLKCSR, 0); 1268 bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_CHIPCLKCSR, 0);
1270 } 1269 }
1271} 1270}
1272 1271
1273struct bwfm_sdio_dstab { 1272struct bwfm_sdio_dstab {
1274 uint8_t milli; 1273 uint8_t milli;
1275 uint8_t val; 1274 uint8_t val;
1276}; 1275};
1277 1276
1278static struct bwfm_sdio_dstab pmu11_1v8[] = { 1277static struct bwfm_sdio_dstab pmu11_1v8[] = {
1279 {32, 0x6}, 1278 {32, 0x6},
1280 {26, 0x7}, 1279 {26, 0x7},
1281 {22, 0x4}, 1280 {22, 0x4},
1282 {16, 0x5}, 1281 {16, 0x5},
1283 {12, 0x2}, 1282 {12, 0x2},
1284 {8, 0x3}, 1283 {8, 0x3},
1285 {4, 0x0}, 1284 {4, 0x0},
1286 {0, 0x1} 1285 {0, 0x1}
1287}, pmu13_1v8[] = { 1286}, pmu13_1v8[] = {
1288 {6, 0x7}, 1287 {6, 0x7},
1289 {5, 0x6}, 1288 {5, 0x6},
1290 {4, 0x5}, 1289 {4, 0x5},
1291 {3, 0x4}, 1290 {3, 0x4},
1292 {2, 0x2}, 1291 {2, 0x2},
1293 {1, 0x1}, 1292 {1, 0x1},
1294 {0, 0x0} 1293 {0, 0x0}
1295}, pmu17_1v8[] = { 1294}, pmu17_1v8[] = {
1296 {3, 0x3},  1295 {3, 0x3},
1297 {2, 0x2},  1296 {2, 0x2},
1298 {1, 0x1},  1297 {1, 0x1},
1299 {0, 0x0} 1298 {0, 0x0}
1300}, pmu17_3v3[] = { 1299}, pmu17_3v3[] = {
1301 {16, 0x7}, 1300 {16, 0x7},
1302 {12, 0x5}, 1301 {12, 0x5},
1303 {8, 0x3}, 1302 {8, 0x3},
1304 {4, 0x1}, 1303 {4, 0x1},
1305 {0, 0x0} 1304 {0, 0x0}
1306}; 1305};
1307 1306
1308static void 1307static void
1309bwfm_sdio_drivestrength(struct bwfm_sdio_softc *sc, unsigned milli) 1308bwfm_sdio_drivestrength(struct bwfm_sdio_softc *sc, unsigned milli)
1310{ 1309{
1311 struct bwfm_softc *bwfm = &sc->sc_sc; 1310 struct bwfm_softc *bwfm = &sc->sc_sc;
1312 struct bwfm_core *core; 1311 struct bwfm_core *core;
1313 struct bwfm_sdio_dstab *tab; 1312 struct bwfm_sdio_dstab *tab;
1314 uint32_t tmp, mask; 1313 uint32_t tmp, mask;
1315 unsigned i; 1314 unsigned i;
1316 1315
1317 if ((bwfm->sc_chip.ch_cc_caps & BWFM_CHIP_REG_CAPABILITIES_PMU) == 0) 1316 if ((bwfm->sc_chip.ch_cc_caps & BWFM_CHIP_REG_CAPABILITIES_PMU) == 0)
1318 return; 1317 return;
1319 1318
1320 switch (bwfm->sc_chip.ch_chip) { 1319 switch (bwfm->sc_chip.ch_chip) {
1321 case BRCM_CC_4330_CHIP_ID: 1320 case BRCM_CC_4330_CHIP_ID:
1322 tab = pmu11_1v8; 1321 tab = pmu11_1v8;
1323 mask = __BITS(11,13); 1322 mask = __BITS(11,13);
1324 break; 1323 break;
1325 case BRCM_CC_4334_CHIP_ID: 1324 case BRCM_CC_4334_CHIP_ID:
1326 tab = pmu17_1v8; 1325 tab = pmu17_1v8;
1327 mask = __BITS(11,12); 1326 mask = __BITS(11,12);
1328 break; 1327 break;
1329 case BRCM_CC_43143_CHIP_ID: 1328 case BRCM_CC_43143_CHIP_ID:
1330 tab = pmu17_3v3; 1329 tab = pmu17_3v3;
1331 mask = __BITS(0,3); 1330 mask = __BITS(0,3);
1332 break; 1331 break;
1333 case BRCM_CC_43362_CHIP_ID: 1332 case BRCM_CC_43362_CHIP_ID:
1334 tab = pmu13_1v8; 1333 tab = pmu13_1v8;
1335 mask = __BITS(11,13); 1334 mask = __BITS(11,13);
1336 break; 1335 break;
1337 default: 1336 default:
1338 return; 1337 return;
1339 } 1338 }
1340 1339
1341 for (i=0; tab[i].milli != 0; ++i) { 1340 for (i=0; tab[i].milli != 0; ++i) {
1342 if (milli >= tab[i].milli) 1341 if (milli >= tab[i].milli)
1343 break; 1342 break;
1344 } 1343 }
1345 if (tab[i].milli == 0) 1344 if (tab[i].milli == 0)
1346 return; 1345 return;
1347 1346
1348 core = bwfm_chip_get_pmu(&sc->sc_sc); 1347 core = bwfm_chip_get_pmu(&sc->sc_sc);
1349 tmp = bwfm_sdio_read_4(sc, core->co_base + BWFM_CHIP_REG_CHIPCONTROL_ADDR); 1348 tmp = bwfm_sdio_read_4(sc, core->co_base + BWFM_CHIP_REG_CHIPCONTROL_ADDR);
1350 tmp &= mask; 1349 tmp &= mask;
1351 tmp |= __SHIFTIN(tab[i].val, mask); 1350 tmp |= __SHIFTIN(tab[i].val, mask);
1352 bwfm_sdio_write_4(sc, core->co_base + BWFM_CHIP_REG_CHIPCONTROL_ADDR, tmp); 1351 bwfm_sdio_write_4(sc, core->co_base + BWFM_CHIP_REG_CHIPCONTROL_ADDR, tmp);
1353} 1352}
1354 1353
1355 1354
1356#if notyet 1355#if notyet
1357static int 1356static int
1358bwfm_sdio_bus_sleep(struct bwfm_sdio_softc *sc, bool sleep, bool pendok) 1357bwfm_sdio_bus_sleep(struct bwfm_sdio_softc *sc, bool sleep, bool pendok)
1359{ 1358{
1360 uint32_t clkctl; 1359 uint32_t clkctl;
1361 1360
1362 if (sc->sleeping == sleep) 1361 if (sc->sleeping == sleep)
1363 return 0; 1362 return 0;
1364 1363
1365 if (sc->sc_sr_enabled) { 1364 if (sc->sc_sr_enabled) {
1366 if (sleep) { 1365 if (sleep) {
1367 clkctl = bwfm_sdio_read_1(sc, BWFM_SDIO_FUNC1_CHIPCLKCSR); 1366 clkctl = bwfm_sdio_read_1(sc, BWFM_SDIO_FUNC1_CHIPCLKCSR);
1368 if ((clkctl & BWFM_SDIO_FUNC1_CHIPCLKCSR_CSR_MASK) == 0) 1367 if ((clkctl & BWFM_SDIO_FUNC1_CHIPCLKCSR_CSR_MASK) == 0)
1369 bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_CHIPCLKCSR, BWFM_SDIO_FUNC1_CHIPCLKCSR_ALP_AVAIL_REQ); 1368 bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_CHIPCLKCSR, BWFM_SDIO_FUNC1_CHIPCLKCSR_ALP_AVAIL_REQ);
1370 } 1369 }
1371 /* kso_ctrl(sc, sleep) */ 1370 /* kso_ctrl(sc, sleep) */
1372 } 1371 }
1373 1372
1374 if (sleep) { 1373 if (sleep) {
1375 if (!sc->sc_sr_enabled) 1374 if (!sc->sc_sr_enabled)
1376 bwfm_sdio_clkctl(sc, CLK_NONE, pendok); 1375 bwfm_sdio_clkctl(sc, CLK_NONE, pendok);
1377 } else { 1376 } else {
1378 bwfm_sdio_clkctl(sc, CLK_AVAIL, pendok); 1377 bwfm_sdio_clkctl(sc, CLK_AVAIL, pendok);
1379 } 1378 }
1380 1379
1381 sc->sleeping = sleep; 1380 sc->sleeping = sleep;
1382 1381
1383 return 0; 1382 return 0;
1384} 1383}
1385#endif 1384#endif
1386 1385
1387static void 1386static void
1388bwfm_sdio_readshared(struct bwfm_sdio_softc *sc) 1387bwfm_sdio_readshared(struct bwfm_sdio_softc *sc)
1389{ 1388{
1390 struct bwfm_softc *bwfm = &sc->sc_sc; 1389 struct bwfm_softc *bwfm = &sc->sc_sc;
1391 struct bwfm_sdio_sdpcm sdpcm; 1390 struct bwfm_sdio_sdpcm sdpcm;
1392 uint32_t addr, shaddr; 1391 uint32_t addr, shaddr;
1393 int err; 1392 int err;
1394 1393
1395 bwfm_sdio_clkctl(sc, CLK_AVAIL, false); 1394 bwfm_sdio_clkctl(sc, CLK_AVAIL, false);
1396 if (sc->sc_clkstate != CLK_AVAIL) 1395 if (sc->sc_clkstate != CLK_AVAIL)
1397 return; 1396 return;
1398 1397
1399 shaddr = bwfm->sc_chip.ch_rambase + bwfm->sc_chip.ch_ramsize - 4; 1398 shaddr = bwfm->sc_chip.ch_rambase + bwfm->sc_chip.ch_ramsize - 4;
1400 if (!bwfm->sc_chip.ch_rambase && sc->sc_sr_enabled) 1399 if (!bwfm->sc_chip.ch_rambase && sc->sc_sr_enabled)
1401 shaddr -= bwfm->sc_chip.ch_srsize; 1400 shaddr -= bwfm->sc_chip.ch_srsize;
1402 1401
1403 err = bwfm_sdio_ram_read_write(sc, shaddr, (char *)&addr, 1402 err = bwfm_sdio_ram_read_write(sc, shaddr, (char *)&addr,
1404 sizeof(addr), 0); 1403 sizeof(addr), 0);
1405 if (err) 1404 if (err)
1406 return; 1405 return;
1407 1406
1408 addr = le32toh(addr); 1407 addr = le32toh(addr);
1409 if (addr == 0 || ((~addr >> 16) & 0xffff) == (addr & 0xffff)) 1408 if (addr == 0 || ((~addr >> 16) & 0xffff) == (addr & 0xffff))
1410 return; 1409 return;
1411 1410
1412 err = bwfm_sdio_ram_read_write(sc, addr, (char *)&sdpcm, 1411 err = bwfm_sdio_ram_read_write(sc, addr, (char *)&sdpcm,
1413 sizeof(sdpcm), 0); 1412 sizeof(sdpcm), 0);
1414 if (err) 1413 if (err)
1415 return; 1414 return;
1416 1415
1417 sc->sc_console_addr = le32toh(sdpcm.console_addr); 1416 sc->sc_console_addr = le32toh(sdpcm.console_addr);
1418} 1417}
1419 1418
1420static int 1419static int
1421bwfm_sdio_intr1(void *v, const char *name) 1420bwfm_sdio_intr1(void *v, const char *name)
1422{ 1421{
1423 struct bwfm_sdio_softc *sc = (void *)v; 1422 struct bwfm_sdio_softc *sc = (void *)v;
1424 1423
1425 DPRINTF(("%s: %s\n", DEVNAME(sc), name)); 1424 DPRINTF(("%s: %s\n", DEVNAME(sc), name));
1426 1425
1427 sdmmc_add_task(sc->sc_sf[1]->sc, &sc->sc_task); 1426 sdmmc_add_task(sc->sc_sf[1]->sc, &sc->sc_task);
1428 return 1; 1427 return 1;
1429} 1428}
1430 1429
1431static int 1430static int
1432bwfm_sdio_intr(void *v) 1431bwfm_sdio_intr(void *v)
1433{ 1432{
1434 return bwfm_sdio_intr1(v, "sdio_intr"); 1433 return bwfm_sdio_intr1(v, "sdio_intr");
1435} 1434}
1436 1435
1437static void 1436static void
1438bwfm_sdio_task(void *v) 1437bwfm_sdio_task(void *v)
1439{ 1438{
1440 struct bwfm_sdio_softc *sc = (void *)v; 1439 struct bwfm_sdio_softc *sc = (void *)v;
1441 1440
1442 mutex_enter(&sc->sc_lock); 1441 mutex_enter(&sc->sc_lock);
1443 bwfm_sdio_task1(sc); 1442 bwfm_sdio_task1(sc);
1444#ifdef BWFM_DEBUG 1443#ifdef BWFM_DEBUG
1445 bwfm_sdio_debug_console(sc); 1444 bwfm_sdio_debug_console(sc);
1446#endif 1445#endif
1447 mutex_exit(&sc->sc_lock); 1446 mutex_exit(&sc->sc_lock);
1448} 1447}
1449 1448
1450static void 1449static void
1451bwfm_sdio_task1(struct bwfm_sdio_softc *sc) 1450bwfm_sdio_task1(struct bwfm_sdio_softc *sc)
1452{ 1451{
1453 uint32_t clkctl, devctl, intstat, hostint; 1452 uint32_t clkctl, devctl, intstat, hostint;
1454 bool dorecv, dosend; 1453 bool dorecv, dosend;
1455 1454
1456 if (!sc->sc_sr_enabled && sc->sc_clkstate == CLK_PENDING) { 1455 if (!sc->sc_sr_enabled && sc->sc_clkstate == CLK_PENDING) {
1457 clkctl = bwfm_sdio_read_1(sc, BWFM_SDIO_FUNC1_CHIPCLKCSR); 1456 clkctl = bwfm_sdio_read_1(sc, BWFM_SDIO_FUNC1_CHIPCLKCSR);
1458 if (BWFM_SDIO_FUNC1_CHIPCLKCSR_HTAV(clkctl)) { 1457 if (BWFM_SDIO_FUNC1_CHIPCLKCSR_HTAV(clkctl)) {
1459 devctl = bwfm_sdio_read_1(sc, BWFM_SDIO_DEVICE_CTL); 1458 devctl = bwfm_sdio_read_1(sc, BWFM_SDIO_DEVICE_CTL);
1460 devctl &= ~BWFM_SDIO_DEVICE_CTL_CA_INT_ONLY; 1459 devctl &= ~BWFM_SDIO_DEVICE_CTL_CA_INT_ONLY;
1461 bwfm_sdio_write_1(sc, BWFM_SDIO_DEVICE_CTL, devctl); 1460 bwfm_sdio_write_1(sc, BWFM_SDIO_DEVICE_CTL, devctl);
1462 sc->sc_clkstate = CLK_AVAIL; 1461 sc->sc_clkstate = CLK_AVAIL;
1463 } 1462 }
1464 } 1463 }
1465 1464
1466 dorecv = dosend = sc->sc_clkstate == CLK_AVAIL; 1465 dorecv = dosend = sc->sc_clkstate == CLK_AVAIL;
1467 1466
1468 intstat = bwfm_sdio_dev_read(sc, BWFM_SDPCMD_INTSTATUS); 1467 intstat = bwfm_sdio_dev_read(sc, BWFM_SDPCMD_INTSTATUS);
1469 DPRINTF(("%s: intstat 0x%" PRIx32 "\n", DEVNAME(sc), intstat)); 1468 DPRINTF(("%s: intstat 0x%" PRIx32 "\n", DEVNAME(sc), intstat));
1470 intstat &= (SDPCMD_INTSTATUS_HMB_SW_MASK|SDPCMD_INTSTATUS_CHIPACTIVE); 1469 intstat &= (SDPCMD_INTSTATUS_HMB_SW_MASK|SDPCMD_INTSTATUS_CHIPACTIVE);
1471 if (intstat) 1470 if (intstat)
1472 bwfm_sdio_dev_write(sc, BWFM_SDPCMD_INTSTATUS, intstat); 1471 bwfm_sdio_dev_write(sc, BWFM_SDPCMD_INTSTATUS, intstat);
1473 1472
1474 if (intstat & SDPCMD_INTSTATUS_CHIPACTIVE) 1473 if (intstat & SDPCMD_INTSTATUS_CHIPACTIVE)
1475 printf("%s: CHIPACTIVE\n", DEVNAME(sc)); 1474 printf("%s: CHIPACTIVE\n", DEVNAME(sc));
1476 1475
1477 if (intstat & SDPCMD_INTSTATUS_HMB_HOST_INT) { 1476 if (intstat & SDPCMD_INTSTATUS_HMB_HOST_INT) {
1478 hostint = bwfm_sdio_dev_read(sc, SDPCMD_TOHOSTMAILBOXDATA); 1477 hostint = bwfm_sdio_dev_read(sc, SDPCMD_TOHOSTMAILBOXDATA);
1479 DPRINTF(("%s: hostint 0x%" PRIx32 "\n", DEVNAME(sc), hostint)); 1478 DPRINTF(("%s: hostint 0x%" PRIx32 "\n", DEVNAME(sc), hostint));
1480 bwfm_sdio_dev_write(sc, SDPCMD_TOSBMAILBOX, 1479 bwfm_sdio_dev_write(sc, SDPCMD_TOSBMAILBOX,
1481 SDPCMD_TOSBMAILBOX_INT_ACK); 1480 SDPCMD_TOSBMAILBOX_INT_ACK);
1482 if (hostint & SDPCMD_TOHOSTMAILBOXDATA_NAKHANDLED) 1481 if (hostint & SDPCMD_TOHOSTMAILBOXDATA_NAKHANDLED)
1483 sc->sc_rxskip = false; 1482 sc->sc_rxskip = false;
1484 if (hostint & SDPCMD_TOHOSTMAILBOXDATA_DEVREADY || 1483 if (hostint & SDPCMD_TOHOSTMAILBOXDATA_DEVREADY ||
1485 hostint & SDPCMD_TOHOSTMAILBOXDATA_FWREADY) 1484 hostint & SDPCMD_TOHOSTMAILBOXDATA_FWREADY)
1486 bwfm_sdio_readshared(sc); 1485 bwfm_sdio_readshared(sc);
1487 } 1486 }
1488 1487
1489 if (intstat & SDPCMD_INTSTATUS_HMB_FRAME_IND) { 1488 if (intstat & SDPCMD_INTSTATUS_HMB_FRAME_IND) {
1490 /* ignore receive indications while recovering */ 1489 /* ignore receive indications while recovering */
1491 if (dorecv && !sc->sc_rxskip) { 1490 if (dorecv && !sc->sc_rxskip) {
1492 DPRINTF(("%s: recv\n", DEVNAME(sc))); 1491 DPRINTF(("%s: recv\n", DEVNAME(sc)));
1493 bwfm_sdio_rx_frames(sc); 1492 bwfm_sdio_rx_frames(sc);
1494 } 1493 }
1495 } 1494 }
1496 1495
1497 if (intstat & SDPCMD_INTSTATUS_HMB_FC_STATE) 1496 if (intstat & SDPCMD_INTSTATUS_HMB_FC_STATE)
1498 dosend = false; 1497 dosend = false;
1499 1498
1500 if (intstat & SDPCMD_INTSTATUS_HMB_FC_CHANGE) { 1499 if (intstat & SDPCMD_INTSTATUS_HMB_FC_CHANGE) {
1501 if (dosend) { 1500 if (dosend) {
1502 intstat = bwfm_sdio_dev_read(sc, BWFM_SDPCMD_INTSTATUS); 1501 intstat = bwfm_sdio_dev_read(sc, BWFM_SDPCMD_INTSTATUS);
1503 DPRINTF(("%s: intstat2 0x%" PRIx32 "\n", DEVNAME(sc), intstat)); 1502 DPRINTF(("%s: intstat2 0x%" PRIx32 "\n", DEVNAME(sc), intstat));
1504 if (intstat & (SDPCMD_INTSTATUS_HMB_FC_STATE | SDPCMD_INTSTATUS_HMB_FC_CHANGE)) 1503 if (intstat & (SDPCMD_INTSTATUS_HMB_FC_STATE | SDPCMD_INTSTATUS_HMB_FC_CHANGE))
1505 dosend = false; 1504 dosend = false;
1506 } 1505 }
1507 } 1506 }
1508 1507
1509if (!dosend && MBUFQ_FIRST(&sc->sc_tx_queue)) printf("%s: flowctl\n", DEVNAME(sc)); 1508if (!dosend && MBUFQ_FIRST(&sc->sc_tx_queue)) printf("%s: flowctl\n", DEVNAME(sc));