Mon Dec 30 16:28:15 2019 UTC ()
Follow the Linux driver an use the FDT "compatible" property to build a
filename for the nvram config file, fall back to the standard filename.

E.g.

# ofctl -p /
[Caching 123 nodes and 1093 properties]
#address-cells          00000001 ........ ........ ........     1
#size-cells             00000001 ........ ........ ........     1
compatible              73696e6f 766f6970 2c627069 2d6d322d   "sinovoip,bpi-m2-
            0010:       7a65726f 00...... ........ ........   zero"
            0015:       616c6c77 696e6e65 722c7375 6e38692d   "allwinner,sun8i-
            0025:       68322d70 6c757300 ........ ........   h2-plus"
interrupt-parent        00000001 ........ ........ ........   ....
model                   42616e61 6e612050 69204250 492d4d32   "Banana Pi BPI-M2
            0010:       2d5a6572 6f00.... ........ ........   -Zero"
name                    00...... ........ ........ ........   ""
serial-number           30326330 30303432 65636431 36376566   02c00042ecd167ef
            0010:       00...... ........ ........ ........   .

-rw-r--r--  1 root  wheel     875 Nov  2 12:06 brcmfmac43430-sdio.AP6212.txt
lrwxr-xr-x  1 root  wheel      29 Dec 30 16:19 brcmfmac43430-sdio.sinovoip,bpi-m2-zero.txt -> brcmfmac43430-sdio.AP6212.txt
-rw-r--r--  1 root  wheel     874 Jun 30  2019 brcmfmac43430-sdio.raspberrypi,3-model-b.txt
-rw-r--r--  1 root  wheel    1864 Jun 30  2019 brcmfmac43455-sdio.raspberrypi,3-model-b-plus.txt
lrwxr-xr-x  1 root  wheel      29 Dec 30 11:24 brcmfmac43455-sdio.raspberrypi,4-model-b-plus.txt -> brcmfmac43455-sdio.raspberrypi,3-model-b-plus.txt


(mlelstv)
diff -r1.9 -r1.10 src/sys/dev/sdmmc/if_bwfm_sdio.c

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

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