1 From 7a64ce11e82573e947e79200960bea5d24fc888a Mon Sep 17 00:00:00 2001
2 From: Arend van Spriel <arend@broadcom.com>
3 Date: Wed, 5 Oct 2011 13:19:03 +0200
4 Subject: [PATCH 3] net: wireless: add brcm80211 drivers
5
6 Add the brcm80211 tree to drivers/net/wireless, and disable the version that's
7 in drivers/staging. This version includes the sources currently in staging,
8 plus any changes that have been sent out for review.
9
10 Sources in staging will be deleted in a followup patch.
11
12 V1:
13 - Move brcm80211 drivers to drivers/net/wireless
14
15 V2:
16 - Resolve checkpatch issues
17 - Fix issues on big-endian platforms (MIPS BE, PPC, and SPARC)
18 - Cleanup architecture-specific code
19 - Fix power save, locking, and scan issues in brcmfmac
20 - Elimimnate 'void *' casts in brcmsmac
21 - Fix entry for brcm80211 drivers in drivers/net/wireless/Kconfig
22 - Use cordic and crc8 kernel library functions
23 - General code cleanup, restructuring, and dead code removal
24
25 V3:
26 - remove -D line from Makefiles
27 - use endian annotated structures
28 - enable sparse endian checking
29 - remove use of (static) global variables
30 - remove own buffer printing implementation
31 - remove static function prototypes
32 - replace macros by inline functions
33 - reduce sparse warnings
34 - remove using string-based iovars
35 - remove driver internal use of ioctls
36 - remove (un)likely
37 - remove uncoditional curly braces for variable scoping
38 - remove error messages upon alloc failures
39 - reduced code indentation levels
40 - cleanup in brcmutil module
41 - remove changing lock state which is acquired by other layer (wpa_supplicant)
42 - brcmfmac:
43 - use ffs() instead of brcmf_find_msb()
44 - replace threads with work queues
45 - cleanup module parameters
46 - store private data in net device structure
47 - brcmsmac:
48 - not modifying ssn value upon AMPDU start
49 - use hweight8() instead of brcmu_bitcount()
50 - remove unnecessary mac80211 callbacks
51 - remove brcms_c_set_par and get_par functions
52 - remove bmac wrapper functions
53 - remove lock related macros
54 - add debugfs based event tracing (not functional in staging)
55
56 Signed-off-by: Arend van Spriel <arend@broadcom.com>
57 ---
58 drivers/net/wireless/Kconfig | 1 +
59 drivers/net/wireless/Makefile | 3 +
60 drivers/net/wireless/brcm80211/Kconfig | 35 +
61 drivers/net/wireless/brcm80211/Makefile | 23 +
62 drivers/net/wireless/brcm80211/brcmfmac/Makefile | 33 +
63 drivers/net/wireless/brcm80211/brcmfmac/bcmchip.h | 32 +
64 drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | 371 +
65 .../net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c | 625 +
66 drivers/net/wireless/brcm80211/brcmfmac/dhd.h | 773 +
67 drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h | 57 +
68 drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c | 498 +
69 .../net/wireless/brcm80211/brcmfmac/dhd_common.c | 872 +
70 drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h | 58 +
71 .../net/wireless/brcm80211/brcmfmac/dhd_linux.c | 1354 +
72 .../net/wireless/brcm80211/brcmfmac/dhd_proto.h | 60 +
73 drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 4581 ++++
74 .../net/wireless/brcm80211/brcmfmac/sdio_host.h | 252 +
75 .../net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 3730 +++
76 .../net/wireless/brcm80211/brcmfmac/wl_cfg80211.h | 375 +
77 drivers/net/wireless/brcm80211/brcmsmac/Makefile | 51 +
78 drivers/net/wireless/brcm80211/brcmsmac/aiutils.c | 2079 ++
79 drivers/net/wireless/brcm80211/brcmsmac/aiutils.h | 378 +
80 drivers/net/wireless/brcm80211/brcmsmac/ampdu.c | 1241 +
81 drivers/net/wireless/brcm80211/brcmsmac/ampdu.h | 30 +
82 drivers/net/wireless/brcm80211/brcmsmac/antsel.c | 307 +
83 drivers/net/wireless/brcm80211/brcmsmac/antsel.h | 29 +
84 .../brcm80211/brcmsmac/brcms_trace_events.c | 23 +
85 .../brcm80211/brcmsmac/brcms_trace_events.h | 92 +
86 drivers/net/wireless/brcm80211/brcmsmac/channel.c | 1565 ++
87 drivers/net/wireless/brcm80211/brcmsmac/channel.h | 53 +
88 drivers/net/wireless/brcm80211/brcmsmac/d11.h | 1898 ++
89 drivers/net/wireless/brcm80211/brcmsmac/dma.c | 1425 +
90 drivers/net/wireless/brcm80211/brcmsmac/dma.h | 120 +
91 .../net/wireless/brcm80211/brcmsmac/mac80211_if.c | 1701 ++
92 .../net/wireless/brcm80211/brcmsmac/mac80211_if.h | 107 +
93 drivers/net/wireless/brcm80211/brcmsmac/main.c | 8841 ++++++
94 drivers/net/wireless/brcm80211/brcmsmac/main.h | 819 +
95 drivers/net/wireless/brcm80211/brcmsmac/nicpci.c | 835 +
96 drivers/net/wireless/brcm80211/brcmsmac/nicpci.h | 82 +
97 drivers/net/wireless/brcm80211/brcmsmac/otp.c | 426 +
98 drivers/net/wireless/brcm80211/brcmsmac/otp.h | 36 +
99 .../net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c | 2988 ++
100 .../net/wireless/brcm80211/brcmsmac/phy/phy_hal.h | 301 +
101 .../net/wireless/brcm80211/brcmsmac/phy/phy_int.h | 1169 +
102 .../net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c | 5154 ++++
103 .../net/wireless/brcm80211/brcmsmac/phy/phy_lcn.h | 121 +
104 .../net/wireless/brcm80211/brcmsmac/phy/phy_n.c |28876 ++++++++++++++++++++
105 .../wireless/brcm80211/brcmsmac/phy/phy_qmath.c | 308 +
106 .../wireless/brcm80211/brcmsmac/phy/phy_qmath.h | 42 +
107 .../wireless/brcm80211/brcmsmac/phy/phy_radio.h | 1533 ++
108 .../net/wireless/brcm80211/brcmsmac/phy/phyreg_n.h | 167 +
109 .../wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c | 3250 +++
110 .../wireless/brcm80211/brcmsmac/phy/phytbl_lcn.h | 54 +
111 .../net/wireless/brcm80211/brcmsmac/phy/phytbl_n.c |10630 +++++++
112 .../net/wireless/brcm80211/brcmsmac/phy/phytbl_n.h | 50 +
113 drivers/net/wireless/brcm80211/brcmsmac/phy_shim.c | 226 +
114 drivers/net/wireless/brcm80211/brcmsmac/phy_shim.h | 185 +
115 drivers/net/wireless/brcm80211/brcmsmac/pmu.c | 458 +
116 drivers/net/wireless/brcm80211/brcmsmac/pmu.h | 38 +
117 drivers/net/wireless/brcm80211/brcmsmac/pub.h | 655 +
118 drivers/net/wireless/brcm80211/brcmsmac/rate.c | 514 +
119 drivers/net/wireless/brcm80211/brcmsmac/rate.h | 250 +
120 drivers/net/wireless/brcm80211/brcmsmac/scb.h | 82 +
121 drivers/net/wireless/brcm80211/brcmsmac/srom.c | 1298 +
122 drivers/net/wireless/brcm80211/brcmsmac/srom.h | 34 +
123 drivers/net/wireless/brcm80211/brcmsmac/stf.c | 438 +
124 drivers/net/wireless/brcm80211/brcmsmac/stf.h | 42 +
125 drivers/net/wireless/brcm80211/brcmsmac/types.h | 352 +
126 .../net/wireless/brcm80211/brcmsmac/ucode_loader.c | 109 +
127 .../net/wireless/brcm80211/brcmsmac/ucode_loader.h | 58 +
128 drivers/net/wireless/brcm80211/brcmutil/Makefile | 29 +
129 drivers/net/wireless/brcm80211/brcmutil/utils.c | 600 +
130 drivers/net/wireless/brcm80211/brcmutil/wifi.c | 136 +
131 .../net/wireless/brcm80211/include/brcm_hw_ids.h | 59 +
132 .../net/wireless/brcm80211/include/brcmu_utils.h | 223 +
133 .../net/wireless/brcm80211/include/brcmu_wifi.h | 275 +
134 .../net/wireless/brcm80211/include/chipcommon.h | 284 +
135 drivers/net/wireless/brcm80211/include/defs.h | 104 +
136 drivers/net/wireless/brcm80211/include/soc.h | 90 +
137 drivers/staging/Kconfig | 2 +-
138 drivers/staging/Makefile | 4 +-
139 81 files changed, 97056 insertions(+), 3 deletions(-)
140 create mode 100644 drivers/net/wireless/brcm80211/Kconfig
141 create mode 100644 drivers/net/wireless/brcm80211/Makefile
142 create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/Makefile
143 create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/bcmchip.h
144 create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
145 create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
146 create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/dhd.h
147 create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
148 create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c
149 create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
150 create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
151 create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
152 create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h
153 create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
154 create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
155 create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
156 create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
157 create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/Makefile
158 create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/aiutils.c
159 create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/aiutils.h
160 create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
161 create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/ampdu.h
162 create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/antsel.c
163 create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/antsel.h
164 create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.c
165 create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h
166 create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/channel.c
167 create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/channel.h
168 create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/d11.h
169 create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/dma.c
170 create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/dma.h
171 create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
172 create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h
173 create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/main.c
174 create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/main.h
175 create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/nicpci.c
176 create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/nicpci.h
177 create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/otp.c
178 create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/otp.h
179 create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c
180 create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy/phy_hal.h
181 create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy/phy_int.h
182 create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
183 create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.h
184 create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c
185 create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy/phy_qmath.c
186 create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy/phy_qmath.h
187 create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy/phy_radio.h
188 create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy/phyreg_n.h
189 create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c
190 create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.h
191 create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_n.c
192 create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_n.h
193 create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy_shim.c
194 create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy_shim.h
195 create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/pmu.c
196 create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/pmu.h
197 create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/pub.h
198 create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/rate.c
199 create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/rate.h
200 create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/scb.h
201 create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/srom.c
202 create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/srom.h
203 create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/stf.c
204 create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/stf.h
205 create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/types.h
206 create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/ucode_loader.c
207 create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/ucode_loader.h
208 create mode 100644 drivers/net/wireless/brcm80211/brcmutil/Makefile
209 create mode 100644 drivers/net/wireless/brcm80211/brcmutil/utils.c
210 create mode 100644 drivers/net/wireless/brcm80211/brcmutil/wifi.c
211 create mode 100644 drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
212 create mode 100644 drivers/net/wireless/brcm80211/include/brcmu_utils.h
213 create mode 100644 drivers/net/wireless/brcm80211/include/brcmu_wifi.h
214 create mode 100644 drivers/net/wireless/brcm80211/include/chipcommon.h
215 create mode 100644 drivers/net/wireless/brcm80211/include/defs.h
216 create mode 100644 drivers/net/wireless/brcm80211/include/soc.h
217
218
219
220 --- a/drivers/net/wireless/Kconfig
221 +++ b/drivers/net/wireless/Kconfig
222 @@ -271,6 +271,7 @@ config MWL8K
223 source "drivers/net/wireless/ath/Kconfig"
224 source "drivers/net/wireless/b43/Kconfig"
225 source "drivers/net/wireless/b43legacy/Kconfig"
226 +source "drivers/net/wireless/brcm80211/Kconfig"
227 source "drivers/net/wireless/hostap/Kconfig"
228 source "drivers/net/wireless/ipw2x00/Kconfig"
229 source "drivers/net/wireless/iwlwifi/Kconfig"
230
231
232 --- a/drivers/net/wireless/Makefile
233 +++ b/drivers/net/wireless/Makefile
234 @@ -58,3 +58,6 @@ obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wl12xx/
235 obj-$(CONFIG_IWM) += iwmc3200wifi/
236
237 obj-$(CONFIG_MWIFIEX) += mwifiex/
238 +obj-$(CONFIG_BRCMFMAC) += brcm80211/
239 +obj-$(CONFIG_BRCMUMAC) += brcm80211/
240 +obj-$(CONFIG_BRCMSMAC) += brcm80211/
241
242 new file mode 100644
243
244 --- /dev/null
245 +++ b/drivers/net/wireless/brcm80211/Kconfig
246 @@ -0,0 +1,35 @@
247 +config BRCMUTIL
248 + tristate
249 +
250 +config BRCMSMAC
251 + tristate "Broadcom IEEE802.11n PCIe SoftMAC WLAN driver"
252 + depends on PCI
253 + depends on MAC80211
254 + depends on BCMA=n
255 + select BRCMUTIL
256 + select FW_LOADER
257 + select CRC_CCITT
258 + select CRC8
259 + select CORDIC
260 + ---help---
261 + This module adds support for PCIe wireless adapters based on Broadcom
262 + IEEE802.11n SoftMAC chipsets. If you choose to build a module, it'll
263 + be called brcmsmac.ko.
264 +
265 +config BRCMFMAC
266 + tristate "Broadcom IEEE802.11n embedded FullMAC WLAN driver"
267 + depends on MMC
268 + depends on CFG80211
269 + select BRCMUTIL
270 + select FW_LOADER
271 + ---help---
272 + This module adds support for embedded wireless adapters based on
273 + Broadcom IEEE802.11n FullMAC chipsets. This driver uses the kernel's
274 + wireless extensions subsystem. If you choose to build a module,
275 + it'll be called brcmfmac.ko.
276 +
277 +config BRCMDBG
278 + bool "Broadcom driver debug functions"
279 + depends on BRCMSMAC || BRCMFMAC
280 + ---help---
281 + Selecting this enables additional code for debug purposes.
282
283 new file mode 100644
284
285 --- /dev/null
286 +++ b/drivers/net/wireless/brcm80211/Makefile
287 @@ -0,0 +1,23 @@
288 +#
289 +# Makefile fragment for Broadcom 802.11n Networking Device Driver
290 +#
291 +# Copyright (c) 2010 Broadcom Corporation
292 +#
293 +# Permission to use, copy, modify, and/or distribute this software for any
294 +# purpose with or without fee is hereby granted, provided that the above
295 +# copyright notice and this permission notice appear in all copies.
296 +#
297 +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
298 +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
299 +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
300 +# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
301 +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
302 +# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
303 +# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
304 +
305 +# common flags
306 +subdir-ccflags-$(CONFIG_BRCMDBG) += -DBCMDBG
307 +
308 +obj-$(CONFIG_BRCMUTIL) += brcmutil/
309 +obj-$(CONFIG_BRCMFMAC) += brcmfmac/
310 +obj-$(CONFIG_BRCMSMAC) += brcmsmac/
311
312 new file mode 100644
313
314 --- /dev/null
315 +++ b/drivers/net/wireless/brcm80211/brcmfmac/Makefile
316 @@ -0,0 +1,33 @@
317 +#
318 +# Makefile fragment for Broadcom 802.11n Networking Device Driver
319 +#
320 +# Copyright (c) 2010 Broadcom Corporation
321 +#
322 +# Permission to use, copy, modify, and/or distribute this software for any
323 +# purpose with or without fee is hereby granted, provided that the above
324 +# copyright notice and this permission notice appear in all copies.
325 +#
326 +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
327 +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
328 +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
329 +# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
330 +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
331 +# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
332 +# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
333 +
334 +ccflags-y += \
335 + -Idrivers/net/wireless/brcm80211/brcmfmac \
336 + -Idrivers/net/wireless/brcm80211/include
337 +
338 +DHDOFILES = \
339 + wl_cfg80211.o \
340 + dhd_cdc.o \
341 + dhd_common.o \
342 + dhd_sdio.o \
343 + dhd_linux.o \
344 + bcmsdh.o \
345 + bcmsdh_sdmmc.o
346 +
347 +obj-$(CONFIG_BRCMFMAC) += brcmfmac.o
348 +brcmfmac-objs += $(DHDOFILES)
349 +ccflags-y += -D__CHECK_ENDIAN__
350
351 new file mode 100644
352
353 --- /dev/null
354 +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmchip.h
355 @@ -0,0 +1,32 @@
356 +/*
357 + * Copyright (c) 2011 Broadcom Corporation
358 + *
359 + * Permission to use, copy, modify, and/or distribute this software for any
360 + * purpose with or without fee is hereby granted, provided that the above
361 + * copyright notice and this permission notice appear in all copies.
362 + *
363 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
364 + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
365 + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
366 + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
367 + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
368 + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
369 + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
370 + */
371 +
372 +#ifndef _bcmchip_h_
373 +#define _bcmchip_h_
374 +
375 +/* bcm4329 */
376 +/* SDIO device core, ID 0x829 */
377 +#define BCM4329_CORE_BUS_BASE 0x18011000
378 +/* internal memory core, ID 0x80e */
379 +#define BCM4329_CORE_SOCRAM_BASE 0x18003000
380 +/* ARM Cortex M3 core, ID 0x82a */
381 +#define BCM4329_CORE_ARM_BASE 0x18002000
382 +#define BCM4329_RAMSIZE 0x48000
383 +/* firmware name */
384 +#define BCM4329_FW_NAME "brcm/bcm4329-fullmac-4.bin"
385 +#define BCM4329_NV_NAME "brcm/bcm4329-fullmac-4.txt"
386 +
387 +#endif /* _bcmchip_h_ */
388
389 new file mode 100644
390
391 --- /dev/null
392 +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
393 @@ -0,0 +1,371 @@
394 +/*
395 + * Copyright (c) 2010 Broadcom Corporation
396 + *
397 + * Permission to use, copy, modify, and/or distribute this software for any
398 + * purpose with or without fee is hereby granted, provided that the above
399 + * copyright notice and this permission notice appear in all copies.
400 + *
401 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
402 + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
403 + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
404 + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
405 + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
406 + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
407 + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
408 + */
409 +/* ****************** SDIO CARD Interface Functions **************************/
410 +
411 +#include <linux/types.h>
412 +#include <linux/netdevice.h>
413 +#include <linux/pci.h>
414 +#include <linux/pci_ids.h>
415 +#include <linux/sched.h>
416 +#include <linux/completion.h>
417 +#include <linux/mmc/sdio.h>
418 +#include <linux/mmc/sdio_func.h>
419 +#include <linux/mmc/card.h>
420 +
421 +#include <defs.h>
422 +#include <brcm_hw_ids.h>
423 +#include <brcmu_utils.h>
424 +#include <brcmu_wifi.h>
425 +#include <soc.h>
426 +#include "dhd.h"
427 +#include "dhd_bus.h"
428 +#include "dhd_dbg.h"
429 +#include "sdio_host.h"
430 +
431 +#define SDIOH_API_ACCESS_RETRY_LIMIT 2
432 +
433 +static void brcmf_sdioh_irqhandler(struct sdio_func *func)
434 +{
435 + struct brcmf_sdio_dev *sdiodev = dev_get_drvdata(&func->card->dev);
436 +
437 + brcmf_dbg(TRACE, "***IRQHandler\n");
438 +
439 + sdio_release_host(func);
440 +
441 + brcmf_sdbrcm_isr(sdiodev->bus);
442 +
443 + sdio_claim_host(func);
444 +}
445 +
446 +int brcmf_sdcard_intr_reg(struct brcmf_sdio_dev *sdiodev)
447 +{
448 + brcmf_dbg(TRACE, "Entering\n");
449 +
450 + sdio_claim_host(sdiodev->func[1]);
451 + sdio_claim_irq(sdiodev->func[1], brcmf_sdioh_irqhandler);
452 + sdio_release_host(sdiodev->func[1]);
453 +
454 + return 0;
455 +}
456 +
457 +int brcmf_sdcard_intr_dereg(struct brcmf_sdio_dev *sdiodev)
458 +{
459 + brcmf_dbg(TRACE, "Entering\n");
460 +
461 + sdio_claim_host(sdiodev->func[1]);
462 + sdio_release_irq(sdiodev->func[1]);
463 + sdio_release_host(sdiodev->func[1]);
464 +
465 + return 0;
466 +}
467 +
468 +u8 brcmf_sdcard_cfg_read(struct brcmf_sdio_dev *sdiodev, uint fnc_num, u32 addr,
469 + int *err)
470 +{
471 + int status;
472 + s32 retry = 0;
473 + u8 data = 0;
474 +
475 + do {
476 + if (retry) /* wait for 1 ms till bus get settled down */
477 + udelay(1000);
478 + status = brcmf_sdioh_request_byte(sdiodev, SDIOH_READ, fnc_num,
479 + addr, (u8 *) &data);
480 + } while (status != 0
481 + && (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT));
482 + if (err)
483 + *err = status;
484 +
485 + brcmf_dbg(INFO, "fun = %d, addr = 0x%x, u8data = 0x%x\n",
486 + fnc_num, addr, data);
487 +
488 + return data;
489 +}
490 +
491 +void
492 +brcmf_sdcard_cfg_write(struct brcmf_sdio_dev *sdiodev, uint fnc_num, u32 addr,
493 + u8 data, int *err)
494 +{
495 + int status;
496 + s32 retry = 0;
497 +
498 + do {
499 + if (retry) /* wait for 1 ms till bus get settled down */
500 + udelay(1000);
501 + status = brcmf_sdioh_request_byte(sdiodev, SDIOH_WRITE, fnc_num,
502 + addr, (u8 *) &data);
503 + } while (status != 0
504 + && (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT));
505 + if (err)
506 + *err = status;
507 +
508 + brcmf_dbg(INFO, "fun = %d, addr = 0x%x, u8data = 0x%x\n",
509 + fnc_num, addr, data);
510 +}
511 +
512 +int
513 +brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address)
514 +{
515 + int err = 0;
516 + brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW,
517 + (address >> 8) & SBSDIO_SBADDRLOW_MASK, &err);
518 + if (!err)
519 + brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_1,
520 + SBSDIO_FUNC1_SBADDRMID,
521 + (address >> 16) & SBSDIO_SBADDRMID_MASK,
522 + &err);
523 + if (!err)
524 + brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_1,
525 + SBSDIO_FUNC1_SBADDRHIGH,
526 + (address >> 24) & SBSDIO_SBADDRHIGH_MASK,
527 + &err);
528 +
529 + return err;
530 +}
531 +
532 +u32 brcmf_sdcard_reg_read(struct brcmf_sdio_dev *sdiodev, u32 addr, uint size)
533 +{
534 + int status;
535 + u32 word = 0;
536 + uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
537 +
538 + brcmf_dbg(INFO, "fun = 1, addr = 0x%x\n", addr);
539 +
540 + if (bar0 != sdiodev->sbwad) {
541 + if (brcmf_sdcard_set_sbaddr_window(sdiodev, bar0))
542 + return 0xFFFFFFFF;
543 +
544 + sdiodev->sbwad = bar0;
545 + }
546 +
547 + addr &= SBSDIO_SB_OFT_ADDR_MASK;
548 + if (size == 4)
549 + addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
550 +
551 + status = brcmf_sdioh_request_word(sdiodev, SDIOH_READ, SDIO_FUNC_1,
552 + addr, &word, size);
553 +
554 + sdiodev->regfail = (status != 0);
555 +
556 + brcmf_dbg(INFO, "u32data = 0x%x\n", word);
557 +
558 + /* if ok, return appropriately masked word */
559 + if (status == 0) {
560 + switch (size) {
561 + case sizeof(u8):
562 + return word & 0xff;
563 + case sizeof(u16):
564 + return word & 0xffff;
565 + case sizeof(u32):
566 + return word;
567 + default:
568 + sdiodev->regfail = true;
569 +
570 + }
571 + }
572 +
573 + /* otherwise, bad sdio access or invalid size */
574 + brcmf_dbg(ERROR, "error reading addr 0x%04x size %d\n", addr, size);
575 + return 0xFFFFFFFF;
576 +}
577 +
578 +u32 brcmf_sdcard_reg_write(struct brcmf_sdio_dev *sdiodev, u32 addr, uint size,
579 + u32 data)
580 +{
581 + int status;
582 + uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
583 + int err = 0;
584 +
585 + brcmf_dbg(INFO, "fun = 1, addr = 0x%x, uint%ddata = 0x%x\n",
586 + addr, size * 8, data);
587 +
588 + if (bar0 != sdiodev->sbwad) {
589 + err = brcmf_sdcard_set_sbaddr_window(sdiodev, bar0);
590 + if (err)
591 + return err;
592 +
593 + sdiodev->sbwad = bar0;
594 + }
595 +
596 + addr &= SBSDIO_SB_OFT_ADDR_MASK;
597 + if (size == 4)
598 + addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
599 + status =
600 + brcmf_sdioh_request_word(sdiodev, SDIOH_WRITE, SDIO_FUNC_1,
601 + addr, &data, size);
602 + sdiodev->regfail = (status != 0);
603 +
604 + if (status == 0)
605 + return 0;
606 +
607 + brcmf_dbg(ERROR, "error writing 0x%08x to addr 0x%04x size %d\n",
608 + data, addr, size);
609 + return 0xFFFFFFFF;
610 +}
611 +
612 +bool brcmf_sdcard_regfail(struct brcmf_sdio_dev *sdiodev)
613 +{
614 + return sdiodev->regfail;
615 +}
616 +
617 +int
618 +brcmf_sdcard_recv_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
619 + uint flags,
620 + u8 *buf, uint nbytes, struct sk_buff *pkt)
621 +{
622 + int status;
623 + uint incr_fix;
624 + uint width;
625 + uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
626 + int err = 0;
627 +
628 + brcmf_dbg(INFO, "fun = %d, addr = 0x%x, size = %d\n", fn, addr, nbytes);
629 +
630 + /* Async not implemented yet */
631 + if (flags & SDIO_REQ_ASYNC)
632 + return -ENOTSUPP;
633 +
634 + if (bar0 != sdiodev->sbwad) {
635 + err = brcmf_sdcard_set_sbaddr_window(sdiodev, bar0);
636 + if (err)
637 + return err;
638 +
639 + sdiodev->sbwad = bar0;
640 + }
641 +
642 + addr &= SBSDIO_SB_OFT_ADDR_MASK;
643 +
644 + incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC;
645 + width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
646 + if (width == 4)
647 + addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
648 +
649 + status = brcmf_sdioh_request_buffer(sdiodev, incr_fix, SDIOH_READ,
650 + fn, addr, width, nbytes, buf, pkt);
651 +
652 + return status;
653 +}
654 +
655 +int
656 +brcmf_sdcard_send_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
657 + uint flags, u8 *buf, uint nbytes, struct sk_buff *pkt)
658 +{
659 + uint incr_fix;
660 + uint width;
661 + uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
662 + int err = 0;
663 +
664 + brcmf_dbg(INFO, "fun = %d, addr = 0x%x, size = %d\n", fn, addr, nbytes);
665 +
666 + /* Async not implemented yet */
667 + if (flags & SDIO_REQ_ASYNC)
668 + return -ENOTSUPP;
669 +
670 + if (bar0 != sdiodev->sbwad) {
671 + err = brcmf_sdcard_set_sbaddr_window(sdiodev, bar0);
672 + if (err)
673 + return err;
674 +
675 + sdiodev->sbwad = bar0;
676 + }
677 +
678 + addr &= SBSDIO_SB_OFT_ADDR_MASK;
679 +
680 + incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC;
681 + width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
682 + if (width == 4)
683 + addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
684 +
685 + return brcmf_sdioh_request_buffer(sdiodev, incr_fix, SDIOH_WRITE, fn,
686 + addr, width, nbytes, buf, pkt);
687 +}
688 +
689 +int brcmf_sdcard_rwdata(struct brcmf_sdio_dev *sdiodev, uint rw, u32 addr,
690 + u8 *buf, uint nbytes)
691 +{
692 + addr &= SBSDIO_SB_OFT_ADDR_MASK;
693 + addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
694 +
695 + return brcmf_sdioh_request_buffer(sdiodev, SDIOH_DATA_INC,
696 + (rw ? SDIOH_WRITE : SDIOH_READ), SDIO_FUNC_1,
697 + addr, 4, nbytes, buf, NULL);
698 +}
699 +
700 +int brcmf_sdcard_abort(struct brcmf_sdio_dev *sdiodev, uint fn)
701 +{
702 + char t_func = (char)fn;
703 + brcmf_dbg(TRACE, "Enter\n");
704 +
705 + /* issue abort cmd52 command through F0 */
706 + brcmf_sdioh_request_byte(sdiodev, SDIOH_WRITE, SDIO_FUNC_0,
707 + SDIO_CCCR_ABORT, &t_func);
708 +
709 + brcmf_dbg(TRACE, "Exit\n");
710 + return 0;
711 +}
712 +
713 +int brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
714 +{
715 + u32 regs = 0;
716 + int ret = 0;
717 +
718 + ret = brcmf_sdioh_attach(sdiodev);
719 + if (ret)
720 + goto out;
721 +
722 + regs = SI_ENUM_BASE;
723 +
724 + /* Report the BAR, to fix if needed */
725 + sdiodev->sbwad = SI_ENUM_BASE;
726 +
727 + /* try to attach to the target device */
728 + sdiodev->bus = brcmf_sdbrcm_probe(0, 0, 0, 0, regs, sdiodev);
729 + if (!sdiodev->bus) {
730 + brcmf_dbg(ERROR, "device attach failed\n");
731 + ret = -ENODEV;
732 + goto out;
733 + }
734 +
735 +out:
736 + if (ret)
737 + brcmf_sdio_remove(sdiodev);
738 +
739 + return ret;
740 +}
741 +EXPORT_SYMBOL(brcmf_sdio_probe);
742 +
743 +int brcmf_sdio_remove(struct brcmf_sdio_dev *sdiodev)
744 +{
745 + if (sdiodev->bus) {
746 + brcmf_sdbrcm_disconnect(sdiodev->bus);
747 + sdiodev->bus = NULL;
748 + }
749 +
750 + brcmf_sdioh_detach(sdiodev);
751 +
752 + sdiodev->sbwad = 0;
753 +
754 + return 0;
755 +}
756 +EXPORT_SYMBOL(brcmf_sdio_remove);
757 +
758 +void brcmf_sdio_wdtmr_enable(struct brcmf_sdio_dev *sdiodev, bool enable)
759 +{
760 + if (enable)
761 + brcmf_sdbrcm_wd_timer(sdiodev->bus, BRCMF_WD_POLL_MS);
762 + else
763 + brcmf_sdbrcm_wd_timer(sdiodev->bus, 0);
764 +}
765
766 new file mode 100644
767
768 --- /dev/null
769 +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
770 @@ -0,0 +1,625 @@
771 +/*
772 + * Copyright (c) 2010 Broadcom Corporation
773 + *
774 + * Permission to use, copy, modify, and/or distribute this software for any
775 + * purpose with or without fee is hereby granted, provided that the above
776 + * copyright notice and this permission notice appear in all copies.
777 + *
778 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
779 + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
780 + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
781 + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
782 + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
783 + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
784 + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
785 + */
786 +#include <linux/types.h>
787 +#include <linux/netdevice.h>
788 +#include <linux/mmc/sdio.h>
789 +#include <linux/mmc/core.h>
790 +#include <linux/mmc/sdio_func.h>
791 +#include <linux/mmc/sdio_ids.h>
792 +#include <linux/mmc/card.h>
793 +#include <linux/suspend.h>
794 +#include <linux/errno.h>
795 +#include <linux/sched.h> /* request_irq() */
796 +#include <net/cfg80211.h>
797 +
798 +#include <defs.h>
799 +#include <brcm_hw_ids.h>
800 +#include <brcmu_utils.h>
801 +#include <brcmu_wifi.h>
802 +#include "sdio_host.h"
803 +#include "dhd.h"
804 +#include "dhd_dbg.h"
805 +#include "wl_cfg80211.h"
806 +
807 +#define SDIO_VENDOR_ID_BROADCOM 0x02d0
808 +
809 +#define DMA_ALIGN_MASK 0x03
810 +
811 +#define SDIO_DEVICE_ID_BROADCOM_4329 0x4329
812 +
813 +#define SDIO_FUNC1_BLOCKSIZE 64
814 +#define SDIO_FUNC2_BLOCKSIZE 512
815 +
816 +/* devices we support, null terminated */
817 +static const struct sdio_device_id brcmf_sdmmc_ids[] = {
818 + {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4329)},
819 + { /* end: all zeroes */ },
820 +};
821 +MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids);
822 +
823 +static bool
824 +brcmf_pm_resume_error(struct brcmf_sdio_dev *sdiodev)
825 +{
826 + bool is_err = false;
827 +#ifdef CONFIG_PM_SLEEP
828 + is_err = atomic_read(&sdiodev->suspend);
829 +#endif
830 + return is_err;
831 +}
832 +
833 +static void
834 +brcmf_pm_resume_wait(struct brcmf_sdio_dev *sdiodev, wait_queue_head_t *wq)
835 +{
836 +#ifdef CONFIG_PM_SLEEP
837 + int retry = 0;
838 + while (atomic_read(&sdiodev->suspend) && retry++ != 30)
839 + wait_event_timeout(*wq, false, HZ/100);
840 +#endif
841 +}
842 +
843 +static inline int brcmf_sdioh_f0_write_byte(struct brcmf_sdio_dev *sdiodev,
844 + uint regaddr, u8 *byte)
845 +{
846 + struct sdio_func *sdfunc = sdiodev->func[0];
847 + int err_ret;
848 +
849 + /*
850 + * Can only directly write to some F0 registers.
851 + * Handle F2 enable/disable and Abort command
852 + * as a special case.
853 + */
854 + if (regaddr == SDIO_CCCR_IOEx) {
855 + sdfunc = sdiodev->func[2];
856 + if (sdfunc) {
857 + sdio_claim_host(sdfunc);
858 + if (*byte & SDIO_FUNC_ENABLE_2) {
859 + /* Enable Function 2 */
860 + err_ret = sdio_enable_func(sdfunc);
861 + if (err_ret)
862 + brcmf_dbg(ERROR,
863 + "enable F2 failed:%d\n",
864 + err_ret);
865 + } else {
866 + /* Disable Function 2 */
867 + err_ret = sdio_disable_func(sdfunc);
868 + if (err_ret)
869 + brcmf_dbg(ERROR,
870 + "Disable F2 failed:%d\n",
871 + err_ret);
872 + }
873 + sdio_release_host(sdfunc);
874 + }
875 + } else if (regaddr == SDIO_CCCR_ABORT) {
876 + sdio_claim_host(sdfunc);
877 + sdio_writeb(sdfunc, *byte, regaddr, &err_ret);
878 + sdio_release_host(sdfunc);
879 + } else if (regaddr < 0xF0) {
880 + brcmf_dbg(ERROR, "F0 Wr:0x%02x: write disallowed\n", regaddr);
881 + err_ret = -EPERM;
882 + } else {
883 + sdio_claim_host(sdfunc);
884 + sdio_f0_writeb(sdfunc, *byte, regaddr, &err_ret);
885 + sdio_release_host(sdfunc);
886 + }
887 +
888 + return err_ret;
889 +}
890 +
891 +int brcmf_sdioh_request_byte(struct brcmf_sdio_dev *sdiodev, uint rw, uint func,
892 + uint regaddr, u8 *byte)
893 +{
894 + int err_ret;
895 +
896 + brcmf_dbg(INFO, "rw=%d, func=%d, addr=0x%05x\n", rw, func, regaddr);
897 +
898 + brcmf_pm_resume_wait(sdiodev, &sdiodev->request_byte_wait);
899 + if (brcmf_pm_resume_error(sdiodev))
900 + return -EIO;
901 +
902 + if (rw && func == 0) {
903 + /* handle F0 separately */
904 + err_ret = brcmf_sdioh_f0_write_byte(sdiodev, regaddr, byte);
905 + } else {
906 + sdio_claim_host(sdiodev->func[func]);
907 + if (rw) /* CMD52 Write */
908 + sdio_writeb(sdiodev->func[func], *byte, regaddr,
909 + &err_ret);
910 + else if (func == 0) {
911 + *byte = sdio_f0_readb(sdiodev->func[func], regaddr,
912 + &err_ret);
913 + } else {
914 + *byte = sdio_readb(sdiodev->func[func], regaddr,
915 + &err_ret);
916 + }
917 + sdio_release_host(sdiodev->func[func]);
918 + }
919 +
920 + if (err_ret)
921 + brcmf_dbg(ERROR, "Failed to %s byte F%d:@0x%05x=%02x, Err: %d\n",
922 + rw ? "write" : "read", func, regaddr, *byte, err_ret);
923 +
924 + return err_ret;
925 +}
926 +
927 +int brcmf_sdioh_request_word(struct brcmf_sdio_dev *sdiodev,
928 + uint rw, uint func, uint addr, u32 *word,
929 + uint nbytes)
930 +{
931 + int err_ret = -EIO;
932 +
933 + if (func == 0) {
934 + brcmf_dbg(ERROR, "Only CMD52 allowed to F0\n");
935 + return -EINVAL;
936 + }
937 +
938 + brcmf_dbg(INFO, "rw=%d, func=%d, addr=0x%05x, nbytes=%d\n",
939 + rw, func, addr, nbytes);
940 +
941 + brcmf_pm_resume_wait(sdiodev, &sdiodev->request_word_wait);
942 + if (brcmf_pm_resume_error(sdiodev))
943 + return -EIO;
944 + /* Claim host controller */
945 + sdio_claim_host(sdiodev->func[func]);
946 +
947 + if (rw) { /* CMD52 Write */
948 + if (nbytes == 4)
949 + sdio_writel(sdiodev->func[func], *word, addr,
950 + &err_ret);
951 + else if (nbytes == 2)
952 + sdio_writew(sdiodev->func[func], (*word & 0xFFFF),
953 + addr, &err_ret);
954 + else
955 + brcmf_dbg(ERROR, "Invalid nbytes: %d\n", nbytes);
956 + } else { /* CMD52 Read */
957 + if (nbytes == 4)
958 + *word = sdio_readl(sdiodev->func[func], addr, &err_ret);
959 + else if (nbytes == 2)
960 + *word = sdio_readw(sdiodev->func[func], addr,
961 + &err_ret) & 0xFFFF;
962 + else
963 + brcmf_dbg(ERROR, "Invalid nbytes: %d\n", nbytes);
964 + }
965 +
966 + /* Release host controller */
967 + sdio_release_host(sdiodev->func[func]);
968 +
969 + if (err_ret)
970 + brcmf_dbg(ERROR, "Failed to %s word, Err: 0x%08x\n",
971 + rw ? "write" : "read", err_ret);
972 +
973 + return err_ret;
974 +}
975 +
976 +static int
977 +brcmf_sdioh_request_packet(struct brcmf_sdio_dev *sdiodev, uint fix_inc,
978 + uint write, uint func, uint addr,
979 + struct sk_buff *pkt)
980 +{
981 + bool fifo = (fix_inc == SDIOH_DATA_FIX);
982 + u32 SGCount = 0;
983 + int err_ret = 0;
984 +
985 + struct sk_buff *pnext;
986 +
987 + brcmf_dbg(TRACE, "Enter\n");
988 +
989 + brcmf_pm_resume_wait(sdiodev, &sdiodev->request_packet_wait);
990 + if (brcmf_pm_resume_error(sdiodev))
991 + return -EIO;
992 +
993 + /* Claim host controller */
994 + sdio_claim_host(sdiodev->func[func]);
995 + for (pnext = pkt; pnext; pnext = pnext->next) {
996 + uint pkt_len = pnext->len;
997 + pkt_len += 3;
998 + pkt_len &= 0xFFFFFFFC;
999 +
1000 + if ((write) && (!fifo)) {
1001 + err_ret = sdio_memcpy_toio(sdiodev->func[func], addr,
1002 + ((u8 *) (pnext->data)),
1003 + pkt_len);
1004 + } else if (write) {
1005 + err_ret = sdio_memcpy_toio(sdiodev->func[func], addr,
1006 + ((u8 *) (pnext->data)),
1007 + pkt_len);
1008 + } else if (fifo) {
1009 + err_ret = sdio_readsb(sdiodev->func[func],
1010 + ((u8 *) (pnext->data)),
1011 + addr, pkt_len);
1012 + } else {
1013 + err_ret = sdio_memcpy_fromio(sdiodev->func[func],
1014 + ((u8 *) (pnext->data)),
1015 + addr, pkt_len);
1016 + }
1017 +
1018 + if (err_ret) {
1019 + brcmf_dbg(ERROR, "%s FAILED %p[%d], addr=0x%05x, pkt_len=%d, ERR=0x%08x\n",
1020 + write ? "TX" : "RX", pnext, SGCount, addr,
1021 + pkt_len, err_ret);
1022 + } else {
1023 + brcmf_dbg(TRACE, "%s xfr'd %p[%d], addr=0x%05x, len=%d\n",
1024 + write ? "TX" : "RX", pnext, SGCount, addr,
1025 + pkt_len);
1026 + }
1027 +
1028 + if (!fifo)
1029 + addr += pkt_len;
1030 + SGCount++;
1031 +
1032 + }
1033 +
1034 + /* Release host controller */
1035 + sdio_release_host(sdiodev->func[func]);
1036 +
1037 + brcmf_dbg(TRACE, "Exit\n");
1038 + return err_ret;
1039 +}
1040 +
1041 +/*
1042 + * This function takes a buffer or packet, and fixes everything up
1043 + * so that in the end, a DMA-able packet is created.
1044 + *
1045 + * A buffer does not have an associated packet pointer,
1046 + * and may or may not be aligned.
1047 + * A packet may consist of a single packet, or a packet chain.
1048 + * If it is a packet chain, then all the packets in the chain
1049 + * must be properly aligned.
1050 + *
1051 + * If the packet data is not aligned, then there may only be
1052 + * one packet, and in this case, it is copied to a new
1053 + * aligned packet.
1054 + *
1055 + */
1056 +int brcmf_sdioh_request_buffer(struct brcmf_sdio_dev *sdiodev,
1057 + uint fix_inc, uint write, uint func, uint addr,
1058 + uint reg_width, uint buflen_u, u8 *buffer,
1059 + struct sk_buff *pkt)
1060 +{
1061 + int Status;
1062 + struct sk_buff *mypkt = NULL;
1063 +
1064 + brcmf_dbg(TRACE, "Enter\n");
1065 +
1066 + brcmf_pm_resume_wait(sdiodev, &sdiodev->request_buffer_wait);
1067 + if (brcmf_pm_resume_error(sdiodev))
1068 + return -EIO;
1069 + /* Case 1: we don't have a packet. */
1070 + if (pkt == NULL) {
1071 + brcmf_dbg(DATA, "Creating new %s Packet, len=%d\n",
1072 + write ? "TX" : "RX", buflen_u);
1073 + mypkt = brcmu_pkt_buf_get_skb(buflen_u);
1074 + if (!mypkt) {
1075 + brcmf_dbg(ERROR, "brcmu_pkt_buf_get_skb failed: len %d\n",
1076 + buflen_u);
1077 + return -EIO;
1078 + }
1079 +
1080 + /* For a write, copy the buffer data into the packet. */
1081 + if (write)
1082 + memcpy(mypkt->data, buffer, buflen_u);
1083 +
1084 + Status = brcmf_sdioh_request_packet(sdiodev, fix_inc, write,
1085 + func, addr, mypkt);
1086 +
1087 + /* For a read, copy the packet data back to the buffer. */
1088 + if (!write)
1089 + memcpy(buffer, mypkt->data, buflen_u);
1090 +
1091 + brcmu_pkt_buf_free_skb(mypkt);
1092 + } else if (((ulong) (pkt->data) & DMA_ALIGN_MASK) != 0) {
1093 + /*
1094 + * Case 2: We have a packet, but it is unaligned.
1095 + * In this case, we cannot have a chain (pkt->next == NULL)
1096 + */
1097 + brcmf_dbg(DATA, "Creating aligned %s Packet, len=%d\n",
1098 + write ? "TX" : "RX", pkt->len);
1099 + mypkt = brcmu_pkt_buf_get_skb(pkt->len);
1100 + if (!mypkt) {
1101 + brcmf_dbg(ERROR, "brcmu_pkt_buf_get_skb failed: len %d\n",
1102 + pkt->len);
1103 + return -EIO;
1104 + }
1105 +
1106 + /* For a write, copy the buffer data into the packet. */
1107 + if (write)
1108 + memcpy(mypkt->data, pkt->data, pkt->len);
1109 +
1110 + Status = brcmf_sdioh_request_packet(sdiodev, fix_inc, write,
1111 + func, addr, mypkt);
1112 +
1113 + /* For a read, copy the packet data back to the buffer. */
1114 + if (!write)
1115 + memcpy(pkt->data, mypkt->data, mypkt->len);
1116 +
1117 + brcmu_pkt_buf_free_skb(mypkt);
1118 + } else { /* case 3: We have a packet and
1119 + it is aligned. */
1120 + brcmf_dbg(DATA, "Aligned %s Packet, direct DMA\n",
1121 + write ? "Tx" : "Rx");
1122 + Status = brcmf_sdioh_request_packet(sdiodev, fix_inc, write,
1123 + func, addr, pkt);
1124 + }
1125 +
1126 + return Status;
1127 +}
1128 +
1129 +/* Read client card reg */
1130 +static int
1131 +brcmf_sdioh_card_regread(struct brcmf_sdio_dev *sdiodev, int func, u32 regaddr,
1132 + int regsize, u32 *data)
1133 +{
1134 +
1135 + if ((func == 0) || (regsize == 1)) {
1136 + u8 temp = 0;
1137 +
1138 + brcmf_sdioh_request_byte(sdiodev, SDIOH_READ, func, regaddr,
1139 + &temp);
1140 + *data = temp;
1141 + *data &= 0xff;
1142 + brcmf_dbg(DATA, "byte read data=0x%02x\n", *data);
1143 + } else {
1144 + brcmf_sdioh_request_word(sdiodev, SDIOH_READ, func, regaddr,
1145 + data, regsize);
1146 + if (regsize == 2)
1147 + *data &= 0xffff;
1148 +
1149 + brcmf_dbg(DATA, "word read data=0x%08x\n", *data);
1150 + }
1151 +
1152 + return SUCCESS;
1153 +}
1154 +
1155 +static int brcmf_sdioh_get_cisaddr(struct brcmf_sdio_dev *sdiodev, u32 regaddr)
1156 +{
1157 + /* read 24 bits and return valid 17 bit addr */
1158 + int i;
1159 + u32 scratch, regdata;
1160 + __le32 scratch_le;
1161 + u8 *ptr = (u8 *)&scratch_le;
1162 +
1163 + for (i = 0; i < 3; i++) {
1164 + if ((brcmf_sdioh_card_regread(sdiodev, 0, regaddr, 1,
1165 + ®data)) != SUCCESS)
1166 + brcmf_dbg(ERROR, "Can't read!\n");
1167 +
1168 + *ptr++ = (u8) regdata;
1169 + regaddr++;
1170 + }
1171 +
1172 + /* Only the lower 17-bits are valid */
1173 + scratch = le32_to_cpu(scratch_le);
1174 + scratch &= 0x0001FFFF;
1175 + return scratch;
1176 +}
1177 +
1178 +static int brcmf_sdioh_enablefuncs(struct brcmf_sdio_dev *sdiodev)
1179 +{
1180 + int err_ret;
1181 + u32 fbraddr;
1182 + u8 func;
1183 +
1184 + brcmf_dbg(TRACE, "\n");
1185 +
1186 + /* Get the Card's common CIS address */
1187 + sdiodev->func_cis_ptr[0] = brcmf_sdioh_get_cisaddr(sdiodev,
1188 + SDIO_CCCR_CIS);
1189 + brcmf_dbg(INFO, "Card's Common CIS Ptr = 0x%x\n",
1190 + sdiodev->func_cis_ptr[0]);
1191 +
1192 + /* Get the Card's function CIS (for each function) */
1193 + for (fbraddr = SDIO_FBR_BASE(1), func = 1;
1194 + func <= sdiodev->num_funcs; func++, fbraddr += SDIOD_FBR_SIZE) {
1195 + sdiodev->func_cis_ptr[func] =
1196 + brcmf_sdioh_get_cisaddr(sdiodev, SDIO_FBR_CIS + fbraddr);
1197 + brcmf_dbg(INFO, "Function %d CIS Ptr = 0x%x\n",
1198 + func, sdiodev->func_cis_ptr[func]);
1199 + }
1200 +
1201 + /* Enable Function 1 */
1202 + sdio_claim_host(sdiodev->func[1]);
1203 + err_ret = sdio_enable_func(sdiodev->func[1]);
1204 + sdio_release_host(sdiodev->func[1]);
1205 + if (err_ret)
1206 + brcmf_dbg(ERROR, "Failed to enable F1 Err: 0x%08x\n", err_ret);
1207 +
1208 + return false;
1209 +}
1210 +
1211 +/*
1212 + * Public entry points & extern's
1213 + */
1214 +int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev)
1215 +{
1216 + int err_ret = 0;
1217 +
1218 + brcmf_dbg(TRACE, "\n");
1219 +
1220 + sdiodev->num_funcs = 2;
1221 +
1222 + sdio_claim_host(sdiodev->func[1]);
1223 + err_ret = sdio_set_block_size(sdiodev->func[1], SDIO_FUNC1_BLOCKSIZE);
1224 + sdio_release_host(sdiodev->func[1]);
1225 + if (err_ret) {
1226 + brcmf_dbg(ERROR, "Failed to set F1 blocksize\n");
1227 + goto out;
1228 + }
1229 +
1230 + sdio_claim_host(sdiodev->func[2]);
1231 + err_ret = sdio_set_block_size(sdiodev->func[2], SDIO_FUNC2_BLOCKSIZE);
1232 + sdio_release_host(sdiodev->func[2]);
1233 + if (err_ret) {
1234 + brcmf_dbg(ERROR, "Failed to set F2 blocksize\n");
1235 + goto out;
1236 + }
1237 +
1238 + brcmf_sdioh_enablefuncs(sdiodev);
1239 +
1240 +out:
1241 + brcmf_dbg(TRACE, "Done\n");
1242 + return err_ret;
1243 +}
1244 +
1245 +void brcmf_sdioh_detach(struct brcmf_sdio_dev *sdiodev)
1246 +{
1247 + brcmf_dbg(TRACE, "\n");
1248 +
1249 + /* Disable Function 2 */
1250 + sdio_claim_host(sdiodev->func[2]);
1251 + sdio_disable_func(sdiodev->func[2]);
1252 + sdio_release_host(sdiodev->func[2]);
1253 +
1254 + /* Disable Function 1 */
1255 + sdio_claim_host(sdiodev->func[1]);
1256 + sdio_disable_func(sdiodev->func[1]);
1257 + sdio_release_host(sdiodev->func[1]);
1258 +
1259 +}
1260 +
1261 +static int brcmf_ops_sdio_probe(struct sdio_func *func,
1262 + const struct sdio_device_id *id)
1263 +{
1264 + int ret = 0;
1265 + struct brcmf_sdio_dev *sdiodev;
1266 + brcmf_dbg(TRACE, "Enter\n");
1267 + brcmf_dbg(TRACE, "func->class=%x\n", func->class);
1268 + brcmf_dbg(TRACE, "sdio_vendor: 0x%04x\n", func->vendor);
1269 + brcmf_dbg(TRACE, "sdio_device: 0x%04x\n", func->device);
1270 + brcmf_dbg(TRACE, "Function#: 0x%04x\n", func->num);
1271 +
1272 + if (func->num == 1) {
1273 + if (dev_get_drvdata(&func->card->dev)) {
1274 + brcmf_dbg(ERROR, "card private drvdata occupied\n");
1275 + return -ENXIO;
1276 + }
1277 + sdiodev = kzalloc(sizeof(struct brcmf_sdio_dev), GFP_KERNEL);
1278 + if (!sdiodev)
1279 + return -ENOMEM;
1280 + sdiodev->func[0] = func->card->sdio_func[0];
1281 + sdiodev->func[1] = func;
1282 + dev_set_drvdata(&func->card->dev, sdiodev);
1283 +
1284 + atomic_set(&sdiodev->suspend, false);
1285 + init_waitqueue_head(&sdiodev->request_byte_wait);
1286 + init_waitqueue_head(&sdiodev->request_word_wait);
1287 + init_waitqueue_head(&sdiodev->request_packet_wait);
1288 + init_waitqueue_head(&sdiodev->request_buffer_wait);
1289 + }
1290 +
1291 + if (func->num == 2) {
1292 + sdiodev = dev_get_drvdata(&func->card->dev);
1293 + if ((!sdiodev) || (sdiodev->func[1]->card != func->card))
1294 + return -ENODEV;
1295 + sdiodev->func[2] = func;
1296 +
1297 + brcmf_dbg(TRACE, "F2 found, calling brcmf_sdio_probe...\n");
1298 + ret = brcmf_sdio_probe(sdiodev);
1299 + }
1300 +
1301 + return ret;
1302 +}
1303 +
1304 +static void brcmf_ops_sdio_remove(struct sdio_func *func)
1305 +{
1306 + struct brcmf_sdio_dev *sdiodev;
1307 + brcmf_dbg(TRACE, "Enter\n");
1308 + brcmf_dbg(INFO, "func->class=%x\n", func->class);
1309 + brcmf_dbg(INFO, "sdio_vendor: 0x%04x\n", func->vendor);
1310 + brcmf_dbg(INFO, "sdio_device: 0x%04x\n", func->device);
1311 + brcmf_dbg(INFO, "Function#: 0x%04x\n", func->num);
1312 +
1313 + if (func->num == 2) {
1314 + sdiodev = dev_get_drvdata(&func->card->dev);
1315 + brcmf_dbg(TRACE, "F2 found, calling brcmf_sdio_remove...\n");
1316 + brcmf_sdio_remove(sdiodev);
1317 + dev_set_drvdata(&func->card->dev, NULL);
1318 + kfree(sdiodev);
1319 + }
1320 +}
1321 +
1322 +#ifdef CONFIG_PM_SLEEP
1323 +static int brcmf_sdio_suspend(struct device *dev)
1324 +{
1325 + mmc_pm_flag_t sdio_flags;
1326 + struct brcmf_sdio_dev *sdiodev;
1327 + struct sdio_func *func = dev_to_sdio_func(dev);
1328 + int ret = 0;
1329 +
1330 + brcmf_dbg(TRACE, "\n");
1331 +
1332 + sdiodev = dev_get_drvdata(&func->card->dev);
1333 +
1334 + atomic_set(&sdiodev->suspend, true);
1335 +
1336 + sdio_flags = sdio_get_host_pm_caps(sdiodev->func[1]);
1337 + if (!(sdio_flags & MMC_PM_KEEP_POWER)) {
1338 + brcmf_dbg(ERROR, "Host can't keep power while suspended\n");
1339 + return -EINVAL;
1340 + }
1341 +
1342 + ret = sdio_set_host_pm_flags(sdiodev->func[1], MMC_PM_KEEP_POWER);
1343 + if (ret) {
1344 + brcmf_dbg(ERROR, "Failed to set pm_flags\n");
1345 + return ret;
1346 + }
1347 +
1348 + brcmf_sdio_wdtmr_enable(sdiodev, false);
1349 +
1350 + return ret;
1351 +}
1352 +
1353 +static int brcmf_sdio_resume(struct device *dev)
1354 +{
1355 + struct brcmf_sdio_dev *sdiodev;
1356 + struct sdio_func *func = dev_to_sdio_func(dev);
1357 +
1358 + sdiodev = dev_get_drvdata(&func->card->dev);
1359 + brcmf_sdio_wdtmr_enable(sdiodev, true);
1360 + atomic_set(&sdiodev->suspend, false);
1361 + return 0;
1362 +}
1363 +
1364 +static const struct dev_pm_ops brcmf_sdio_pm_ops = {
1365 + .suspend = brcmf_sdio_suspend,
1366 + .resume = brcmf_sdio_resume,
1367 +};
1368 +#endif /* CONFIG_PM_SLEEP */
1369 +
1370 +static struct sdio_driver brcmf_sdmmc_driver = {
1371 + .probe = brcmf_ops_sdio_probe,
1372 + .remove = brcmf_ops_sdio_remove,
1373 + .name = "brcmfmac",
1374 + .id_table = brcmf_sdmmc_ids,
1375 +#ifdef CONFIG_PM_SLEEP
1376 + .drv = {
1377 + .pm = &brcmf_sdio_pm_ops,
1378 + },
1379 +#endif /* CONFIG_PM_SLEEP */
1380 +};
1381 +
1382 +/* bus register interface */
1383 +int brcmf_bus_register(void)
1384 +{
1385 + brcmf_dbg(TRACE, "Enter\n");
1386 +
1387 + return sdio_register_driver(&brcmf_sdmmc_driver);
1388 +}
1389 +
1390 +void brcmf_bus_unregister(void)
1391 +{
1392 + brcmf_dbg(TRACE, "Enter\n");
1393 +
1394 + sdio_unregister_driver(&brcmf_sdmmc_driver);
1395 +}
1396
1397 new file mode 100644
1398
1399 --- /dev/null
1400 +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
1401 @@ -0,0 +1,773 @@
1402 +/*
1403 + * Copyright (c) 2010 Broadcom Corporation
1404 + *
1405 + * Permission to use, copy, modify, and/or distribute this software for any
1406 + * purpose with or without fee is hereby granted, provided that the above
1407 + * copyright notice and this permission notice appear in all copies.
1408 + *
1409 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1410 + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1411 + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
1412 + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1413 + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
1414 + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
1415 + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1416 + */
1417 +
1418 +/****************
1419 + * Common types *
1420 + */
1421 +
1422 +#ifndef _BRCMF_H_
1423 +#define _BRCMF_H_
1424 +
1425 +#define BRCMF_VERSION_STR "4.218.248.5"
1426 +
1427 +/*******************************************************************************
1428 + * IO codes that are interpreted by dongle firmware
1429 + ******************************************************************************/
1430 +#define BRCMF_C_UP 2
1431 +#define BRCMF_C_SET_PROMISC 10
1432 +#define BRCMF_C_GET_RATE 12
1433 +#define BRCMF_C_GET_INFRA 19
1434 +#define BRCMF_C_SET_INFRA 20
1435 +#define BRCMF_C_GET_AUTH 21
1436 +#define BRCMF_C_SET_AUTH 22
1437 +#define BRCMF_C_GET_BSSID 23
1438 +#define BRCMF_C_GET_SSID 25
1439 +#define BRCMF_C_SET_SSID 26
1440 +#define BRCMF_C_GET_CHANNEL 29
1441 +#define BRCMF_C_GET_SRL 31
1442 +#define BRCMF_C_GET_LRL 33
1443 +#define BRCMF_C_GET_RADIO 37
1444 +#define BRCMF_C_SET_RADIO 38
1445 +#define BRCMF_C_GET_PHYTYPE 39
1446 +#define BRCMF_C_SET_KEY 45
1447 +#define BRCMF_C_SET_PASSIVE_SCAN 49
1448 +#define BRCMF_C_SCAN 50
1449 +#define BRCMF_C_SCAN_RESULTS 51
1450 +#define BRCMF_C_DISASSOC 52
1451 +#define BRCMF_C_REASSOC 53
1452 +#define BRCMF_C_SET_ROAM_TRIGGER 55
1453 +#define BRCMF_C_SET_ROAM_DELTA 57
1454 +#define BRCMF_C_GET_DTIMPRD 77
1455 +#define BRCMF_C_SET_COUNTRY 84
1456 +#define BRCMF_C_GET_PM 85
1457 +#define BRCMF_C_SET_PM 86
1458 +#define BRCMF_C_GET_AP 117
1459 +#define BRCMF_C_SET_AP 118
1460 +#define BRCMF_C_GET_RSSI 127
1461 +#define BRCMF_C_GET_WSEC 133
1462 +#define BRCMF_C_SET_WSEC 134
1463 +#define BRCMF_C_GET_PHY_NOISE 135
1464 +#define BRCMF_C_GET_BSS_INFO 136
1465 +#define BRCMF_C_SET_SCAN_CHANNEL_TIME 185
1466 +#define BRCMF_C_SET_SCAN_UNASSOC_TIME 187
1467 +#define BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON 201
1468 +#define BRCMF_C_GET_VALID_CHANNELS 217
1469 +#define BRCMF_C_GET_KEY_PRIMARY 235
1470 +#define BRCMF_C_SET_KEY_PRIMARY 236
1471 +#define BRCMF_C_SET_SCAN_PASSIVE_TIME 258
1472 +#define BRCMF_C_GET_VAR 262
1473 +#define BRCMF_C_SET_VAR 263
1474 +
1475 +/* phy types (returned by WLC_GET_PHYTPE) */
1476 +#define WLC_PHY_TYPE_A 0
1477 +#define WLC_PHY_TYPE_B 1
1478 +#define WLC_PHY_TYPE_G 2
1479 +#define WLC_PHY_TYPE_N 4
1480 +#define WLC_PHY_TYPE_LP 5
1481 +#define WLC_PHY_TYPE_SSN 6
1482 +#define WLC_PHY_TYPE_HT 7
1483 +#define WLC_PHY_TYPE_LCN 8
1484 +#define WLC_PHY_TYPE_NULL 0xf
1485 +
1486 +#define BRCMF_EVENTING_MASK_LEN 16
1487 +
1488 +#define TOE_TX_CSUM_OL 0x00000001
1489 +#define TOE_RX_CSUM_OL 0x00000002
1490 +
1491 +#define BRCMF_BSS_INFO_VERSION 108 /* current ver of brcmf_bss_info struct */
1492 +
1493 +/* size of brcmf_scan_params not including variable length array */
1494 +#define BRCMF_SCAN_PARAMS_FIXED_SIZE 64
1495 +
1496 +/* masks for channel and ssid count */
1497 +#define BRCMF_SCAN_PARAMS_COUNT_MASK 0x0000ffff
1498 +#define BRCMF_SCAN_PARAMS_NSSID_SHIFT 16
1499 +
1500 +#define BRCMF_SCAN_ACTION_START 1
1501 +#define BRCMF_SCAN_ACTION_CONTINUE 2
1502 +#define WL_SCAN_ACTION_ABORT 3
1503 +
1504 +#define BRCMF_ISCAN_REQ_VERSION 1
1505 +
1506 +/* brcmf_iscan_results status values */
1507 +#define BRCMF_SCAN_RESULTS_SUCCESS 0
1508 +#define BRCMF_SCAN_RESULTS_PARTIAL 1
1509 +#define BRCMF_SCAN_RESULTS_PENDING 2
1510 +#define BRCMF_SCAN_RESULTS_ABORTED 3
1511 +#define BRCMF_SCAN_RESULTS_NO_MEM 4
1512 +
1513 +/* Indicates this key is using soft encrypt */
1514 +#define WL_SOFT_KEY (1 << 0)
1515 +/* primary (ie tx) key */
1516 +#define BRCMF_PRIMARY_KEY (1 << 1)
1517 +/* Reserved for backward compat */
1518 +#define WL_KF_RES_4 (1 << 4)
1519 +/* Reserved for backward compat */
1520 +#define WL_KF_RES_5 (1 << 5)
1521 +/* Indicates a group key for a IBSS PEER */
1522 +#define WL_IBSS_PEER_GROUP_KEY (1 << 6)
1523 +
1524 +/* For supporting multiple interfaces */
1525 +#define BRCMF_MAX_IFS 16
1526 +#define BRCMF_DEL_IF -0xe
1527 +#define BRCMF_BAD_IF -0xf
1528 +
1529 +#define DOT11_BSSTYPE_ANY 2
1530 +#define DOT11_MAX_DEFAULT_KEYS 4
1531 +
1532 +#define BRCMF_EVENT_MSG_LINK 0x01
1533 +#define BRCMF_EVENT_MSG_FLUSHTXQ 0x02
1534 +#define BRCMF_EVENT_MSG_GROUP 0x04
1535 +
1536 +struct brcmf_event_msg {
1537 + __be16 version;
1538 + __be16 flags;
1539 + __be32 event_type;
1540 + __be32 status;
1541 + __be32 reason;
1542 + __be32 auth_type;
1543 + __be32 datalen;
1544 + u8 addr[ETH_ALEN];
1545 + char ifname[IFNAMSIZ];
1546 +} __packed;
1547 +
1548 +struct brcm_ethhdr {
1549 + u16 subtype;
1550 + u16 length;
1551 + u8 version;
1552 + u8 oui[3];
1553 + u16 usr_subtype;
1554 +} __packed;
1555 +
1556 +struct brcmf_event {
1557 + struct ethhdr eth;
1558 + struct brcm_ethhdr hdr;
1559 + struct brcmf_event_msg msg;
1560 +} __packed;
1561 +
1562 +struct dngl_stats {
1563 + unsigned long rx_packets; /* total packets received */
1564 + unsigned long tx_packets; /* total packets transmitted */
1565 + unsigned long rx_bytes; /* total bytes received */
1566 + unsigned long tx_bytes; /* total bytes transmitted */
1567 + unsigned long rx_errors; /* bad packets received */
1568 + unsigned long tx_errors; /* packet transmit problems */
1569 + unsigned long rx_dropped; /* packets dropped by dongle */
1570 + unsigned long tx_dropped; /* packets dropped by dongle */
1571 + unsigned long multicast; /* multicast packets received */
1572 +};
1573 +
1574 +/* event codes sent by the dongle to this driver */
1575 +#define BRCMF_E_SET_SSID 0
1576 +#define BRCMF_E_JOIN 1
1577 +#define BRCMF_E_START 2
1578 +#define BRCMF_E_AUTH 3
1579 +#define BRCMF_E_AUTH_IND 4
1580 +#define BRCMF_E_DEAUTH 5
1581 +#define BRCMF_E_DEAUTH_IND 6
1582 +#define BRCMF_E_ASSOC 7
1583 +#define BRCMF_E_ASSOC_IND 8
1584 +#define BRCMF_E_REASSOC 9
1585 +#define BRCMF_E_REASSOC_IND 10
1586 +#define BRCMF_E_DISASSOC 11
1587 +#define BRCMF_E_DISASSOC_IND 12
1588 +#define BRCMF_E_QUIET_START 13
1589 +#define BRCMF_E_QUIET_END 14
1590 +#define BRCMF_E_BEACON_RX 15
1591 +#define BRCMF_E_LINK 16
1592 +#define BRCMF_E_MIC_ERROR 17
1593 +#define BRCMF_E_NDIS_LINK 18
1594 +#define BRCMF_E_ROAM 19
1595 +#define BRCMF_E_TXFAIL 20
1596 +#define BRCMF_E_PMKID_CACHE 21
1597 +#define BRCMF_E_RETROGRADE_TSF 22
1598 +#define BRCMF_E_PRUNE 23
1599 +#define BRCMF_E_AUTOAUTH 24
1600 +#define BRCMF_E_EAPOL_MSG 25
1601 +#define BRCMF_E_SCAN_COMPLETE 26
1602 +#define BRCMF_E_ADDTS_IND 27
1603 +#define BRCMF_E_DELTS_IND 28
1604 +#define BRCMF_E_BCNSENT_IND 29
1605 +#define BRCMF_E_BCNRX_MSG 30
1606 +#define BRCMF_E_BCNLOST_MSG 31
1607 +#define BRCMF_E_ROAM_PREP 32
1608 +#define BRCMF_E_PFN_NET_FOUND 33
1609 +#define BRCMF_E_PFN_NET_LOST 34
1610 +#define BRCMF_E_RESET_COMPLETE 35
1611 +#define BRCMF_E_JOIN_START 36
1612 +#define BRCMF_E_ROAM_START 37
1613 +#define BRCMF_E_ASSOC_START 38
1614 +#define BRCMF_E_IBSS_ASSOC 39
1615 +#define BRCMF_E_RADIO 40
1616 +#define BRCMF_E_PSM_WATCHDOG 41
1617 +#define BRCMF_E_PROBREQ_MSG 44
1618 +#define BRCMF_E_SCAN_CONFIRM_IND 45
1619 +#define BRCMF_E_PSK_SUP 46
1620 +#define BRCMF_E_COUNTRY_CODE_CHANGED 47
1621 +#define BRCMF_E_EXCEEDED_MEDIUM_TIME 48
1622 +#define BRCMF_E_ICV_ERROR 49
1623 +#define BRCMF_E_UNICAST_DECODE_ERROR 50
1624 +#define BRCMF_E_MULTICAST_DECODE_ERROR 51
1625 +#define BRCMF_E_TRACE 52
1626 +#define BRCMF_E_IF 54
1627 +#define BRCMF_E_RSSI 56
1628 +#define BRCMF_E_PFN_SCAN_COMPLETE 57
1629 +#define BRCMF_E_EXTLOG_MSG 58
1630 +#define BRCMF_E_ACTION_FRAME 59
1631 +#define BRCMF_E_ACTION_FRAME_COMPLETE 60
1632 +#define BRCMF_E_PRE_ASSOC_IND 61
1633 +#define BRCMF_E_PRE_REASSOC_IND 62
1634 +#define BRCMF_E_CHANNEL_ADOPTED 63
1635 +#define BRCMF_E_AP_STARTED 64
1636 +#define BRCMF_E_DFS_AP_STOP 65
1637 +#define BRCMF_E_DFS_AP_RESUME 66
1638 +#define BRCMF_E_RESERVED1 67
1639 +#define BRCMF_E_RESERVED2 68
1640 +#define BRCMF_E_ESCAN_RESULT 69
1641 +#define BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE 70
1642 +#define BRCMF_E_DCS_REQUEST 73
1643 +
1644 +#define BRCMF_E_FIFO_CREDIT_MAP 74
1645 +
1646 +#define BRCMF_E_LAST 75
1647 +
1648 +#define BRCMF_E_STATUS_SUCCESS 0
1649 +#define BRCMF_E_STATUS_FAIL 1
1650 +#define BRCMF_E_STATUS_TIMEOUT 2
1651 +#define BRCMF_E_STATUS_NO_NETWORKS 3
1652 +#define BRCMF_E_STATUS_ABORT 4
1653 +#define BRCMF_E_STATUS_NO_ACK 5
1654 +#define BRCMF_E_STATUS_UNSOLICITED 6
1655 +#define BRCMF_E_STATUS_ATTEMPT 7
1656 +#define BRCMF_E_STATUS_PARTIAL 8
1657 +#define BRCMF_E_STATUS_NEWSCAN 9
1658 +#define BRCMF_E_STATUS_NEWASSOC 10
1659 +#define BRCMF_E_STATUS_11HQUIET 11
1660 +#define BRCMF_E_STATUS_SUPPRESS 12
1661 +#define BRCMF_E_STATUS_NOCHANS 13
1662 +#define BRCMF_E_STATUS_CS_ABORT 15
1663 +#define BRCMF_E_STATUS_ERROR 16
1664 +
1665 +#define BRCMF_E_REASON_INITIAL_ASSOC 0
1666 +#define BRCMF_E_REASON_LOW_RSSI 1
1667 +#define BRCMF_E_REASON_DEAUTH 2
1668 +#define BRCMF_E_REASON_DISASSOC 3
1669 +#define BRCMF_E_REASON_BCNS_LOST 4
1670 +#define BRCMF_E_REASON_MINTXRATE 9
1671 +#define BRCMF_E_REASON_TXFAIL 10
1672 +
1673 +#define BRCMF_E_REASON_FAST_ROAM_FAILED 5
1674 +#define BRCMF_E_REASON_DIRECTED_ROAM 6
1675 +#define BRCMF_E_REASON_TSPEC_REJECTED 7
1676 +#define BRCMF_E_REASON_BETTER_AP 8
1677 +
1678 +#define BRCMF_E_PRUNE_ENCR_MISMATCH 1
1679 +#define BRCMF_E_PRUNE_BCAST_BSSID 2
1680 +#define BRCMF_E_PRUNE_MAC_DENY 3
1681 +#define BRCMF_E_PRUNE_MAC_NA 4
1682 +#define BRCMF_E_PRUNE_REG_PASSV 5
1683 +#define BRCMF_E_PRUNE_SPCT_MGMT 6
1684 +#define BRCMF_E_PRUNE_RADAR 7
1685 +#define BRCMF_E_RSN_MISMATCH 8
1686 +#define BRCMF_E_PRUNE_NO_COMMON_RATES 9
1687 +#define BRCMF_E_PRUNE_BASIC_RATES 10
1688 +#define BRCMF_E_PRUNE_CIPHER_NA 12
1689 +#define BRCMF_E_PRUNE_KNOWN_STA 13
1690 +#define BRCMF_E_PRUNE_WDS_PEER 15
1691 +#define BRCMF_E_PRUNE_QBSS_LOAD 16
1692 +#define BRCMF_E_PRUNE_HOME_AP 17
1693 +
1694 +#define BRCMF_E_SUP_OTHER 0
1695 +#define BRCMF_E_SUP_DECRYPT_KEY_DATA 1
1696 +#define BRCMF_E_SUP_BAD_UCAST_WEP128 2
1697 +#define BRCMF_E_SUP_BAD_UCAST_WEP40 3
1698 +#define BRCMF_E_SUP_UNSUP_KEY_LEN 4
1699 +#define BRCMF_E_SUP_PW_KEY_CIPHER 5
1700 +#define BRCMF_E_SUP_MSG3_TOO_MANY_IE 6
1701 +#define BRCMF_E_SUP_MSG3_IE_MISMATCH 7
1702 +#define BRCMF_E_SUP_NO_INSTALL_FLAG 8
1703 +#define BRCMF_E_SUP_MSG3_NO_GTK 9
1704 +#define BRCMF_E_SUP_GRP_KEY_CIPHER 10
1705 +#define BRCMF_E_SUP_GRP_MSG1_NO_GTK 11
1706 +#define BRCMF_E_SUP_GTK_DECRYPT_FAIL 12
1707 +#define BRCMF_E_SUP_SEND_FAIL 13
1708 +#define BRCMF_E_SUP_DEAUTH 14
1709 +
1710 +#define BRCMF_E_IF_ADD 1
1711 +#define BRCMF_E_IF_DEL 2
1712 +#define BRCMF_E_IF_CHANGE 3
1713 +
1714 +#define BRCMF_E_IF_ROLE_STA 0
1715 +#define BRCMF_E_IF_ROLE_AP 1
1716 +#define BRCMF_E_IF_ROLE_WDS 2
1717 +
1718 +#define BRCMF_E_LINK_BCN_LOSS 1
1719 +#define BRCMF_E_LINK_DISASSOC 2
1720 +#define BRCMF_E_LINK_ASSOC_REC 3
1721 +#define BRCMF_E_LINK_BSSCFG_DIS 4
1722 +
1723 +/* The level of bus communication with the dongle */
1724 +enum brcmf_bus_state {
1725 + BRCMF_BUS_DOWN, /* Not ready for frame transfers */
1726 + BRCMF_BUS_LOAD, /* Download access only (CPU reset) */
1727 + BRCMF_BUS_DATA /* Ready for frame transfers */
1728 +};
1729 +
1730 +/* Pattern matching filter. Specifies an offset within received packets to
1731 + * start matching, the pattern to match, the size of the pattern, and a bitmask
1732 + * that indicates which bits within the pattern should be matched.
1733 + */
1734 +struct brcmf_pkt_filter_pattern {
1735 + /*
1736 + * Offset within received packet to start pattern matching.
1737 + * Offset '0' is the first byte of the ethernet header.
1738 + */
1739 + u32 offset;
1740 + /* Size of the pattern. Bitmask must be the same size.*/
1741 + u32 size_bytes;
1742 + /*
1743 + * Variable length mask and pattern data. mask starts at offset 0.
1744 + * Pattern immediately follows mask.
1745 + */
1746 + u8 mask_and_pattern[1];
1747 +};
1748 +
1749 +/* IOVAR "pkt_filter_add" parameter. Used to install packet filters. */
1750 +struct brcmf_pkt_filter {
1751 + u32 id; /* Unique filter id, specified by app. */
1752 + u32 type; /* Filter type (WL_PKT_FILTER_TYPE_xxx). */
1753 + u32 negate_match; /* Negate the result of filter matches */
1754 + union { /* Filter definitions */
1755 + struct brcmf_pkt_filter_pattern pattern; /* Filter pattern */
1756 + } u;
1757 +};
1758 +
1759 +/* IOVAR "pkt_filter_enable" parameter. */
1760 +struct brcmf_pkt_filter_enable {
1761 + u32 id; /* Unique filter id */
1762 + u32 enable; /* Enable/disable bool */
1763 +};
1764 +
1765 +/* BSS info structure
1766 + * Applications MUST CHECK ie_offset field and length field to access IEs and
1767 + * next bss_info structure in a vector (in struct brcmf_scan_results)
1768 + */
1769 +struct brcmf_bss_info {
1770 + __le32 version; /* version field */
1771 + __le32 length; /* byte length of data in this record,
1772 + * starting at version and including IEs
1773 + */
1774 + u8 BSSID[ETH_ALEN];
1775 + __le16 beacon_period; /* units are Kusec */
1776 + __le16 capability; /* Capability information */
1777 + u8 SSID_len;
1778 + u8 SSID[32];
1779 + struct {
1780 + __le32 count; /* # rates in this set */
1781 + u8 rates[16]; /* rates in 500kbps units w/hi bit set if basic */
1782 + } rateset; /* supported rates */
1783 + __le16 chanspec; /* chanspec for bss */
1784 + __le16 atim_window; /* units are Kusec */
1785 + u8 dtim_period; /* DTIM period */
1786 + __le16 RSSI; /* receive signal strength (in dBm) */
1787 + s8 phy_noise; /* noise (in dBm) */
1788 +
1789 + u8 n_cap; /* BSS is 802.11N Capable */
1790 + /* 802.11N BSS Capabilities (based on HT_CAP_*): */
1791 + __le32 nbss_cap;
1792 + u8 ctl_ch; /* 802.11N BSS control channel number */
1793 + __le32 reserved32[1]; /* Reserved for expansion of BSS properties */
1794 + u8 flags; /* flags */
1795 + u8 reserved[3]; /* Reserved for expansion of BSS properties */
1796 + u8 basic_mcs[MCSSET_LEN]; /* 802.11N BSS required MCS set */
1797 +
1798 + __le16 ie_offset; /* offset at which IEs start, from beginning */
1799 + __le32 ie_length; /* byte length of Information Elements */
1800 + __le16 SNR; /* average SNR of during frame reception */
1801 + /* Add new fields here */
1802 + /* variable length Information Elements */
1803 +};
1804 +
1805 +struct brcm_rateset_le {
1806 + /* # rates in this set */
1807 + __le32 count;
1808 + /* rates in 500kbps units w/hi bit set if basic */
1809 + u8 rates[WL_NUMRATES];
1810 +};
1811 +
1812 +struct brcmf_ssid {
1813 + u32 SSID_len;
1814 + unsigned char SSID[32];
1815 +};
1816 +
1817 +struct brcmf_ssid_le {
1818 + __le32 SSID_len;
1819 + unsigned char SSID[32];
1820 +};
1821 +
1822 +struct brcmf_scan_params_le {
1823 + struct brcmf_ssid_le ssid_le; /* default: {0, ""} */
1824 + u8 bssid[ETH_ALEN]; /* default: bcast */
1825 + s8 bss_type; /* default: any,
1826 + * DOT11_BSSTYPE_ANY/INFRASTRUCTURE/INDEPENDENT
1827 + */
1828 + u8 scan_type; /* flags, 0 use default */
1829 + __le32 nprobes; /* -1 use default, number of probes per channel */
1830 + __le32 active_time; /* -1 use default, dwell time per channel for
1831 + * active scanning
1832 + */
1833 + __le32 passive_time; /* -1 use default, dwell time per channel
1834 + * for passive scanning
1835 + */
1836 + __le32 home_time; /* -1 use default, dwell time for the
1837 + * home channel between channel scans
1838 + */
1839 + __le32 channel_num; /* count of channels and ssids that follow
1840 + *
1841 + * low half is count of channels in
1842 + * channel_list, 0 means default (use all
1843 + * available channels)
1844 + *
1845 + * high half is entries in struct brcmf_ssid
1846 + * array that follows channel_list, aligned for
1847 + * s32 (4 bytes) meaning an odd channel count
1848 + * implies a 2-byte pad between end of
1849 + * channel_list and first ssid
1850 + *
1851 + * if ssid count is zero, single ssid in the
1852 + * fixed parameter portion is assumed, otherwise
1853 + * ssid in the fixed portion is ignored
1854 + */
1855 + __le16 channel_list[1]; /* list of chanspecs */
1856 +};
1857 +
1858 +/* incremental scan struct */
1859 +struct brcmf_iscan_params_le {
1860 + __le32 version;
1861 + __le16 action;
1862 + __le16 scan_duration;
1863 + struct brcmf_scan_params_le params_le;
1864 +};
1865 +
1866 +struct brcmf_scan_results {
1867 + u32 buflen;
1868 + u32 version;
1869 + u32 count;
1870 + struct brcmf_bss_info bss_info[1];
1871 +};
1872 +
1873 +struct brcmf_scan_results_le {
1874 + __le32 buflen;
1875 + __le32 version;
1876 + __le32 count;
1877 + struct brcmf_bss_info bss_info[1];
1878 +};
1879 +
1880 +/* used for association with a specific BSSID and chanspec list */
1881 +struct brcmf_assoc_params_le {
1882 + /* 00:00:00:00:00:00: broadcast scan */
1883 + u8 bssid[ETH_ALEN];
1884 + /* 0: all available channels, otherwise count of chanspecs in
1885 + * chanspec_list */
1886 + __le32 chanspec_num;
1887 + /* list of chanspecs */
1888 + __le16 chanspec_list[1];
1889 +};
1890 +
1891 +/* used for join with or without a specific bssid and channel list */
1892 +struct brcmf_join_params {
1893 + struct brcmf_ssid_le ssid_le;
1894 + struct brcmf_assoc_params_le params_le;
1895 +};
1896 +
1897 +/* size of brcmf_scan_results not including variable length array */
1898 +#define BRCMF_SCAN_RESULTS_FIXED_SIZE \
1899 + (sizeof(struct brcmf_scan_results) - sizeof(struct brcmf_bss_info))
1900 +
1901 +/* incremental scan results struct */
1902 +struct brcmf_iscan_results {
1903 + union {
1904 + u32 status;
1905 + __le32 status_le;
1906 + };
1907 + union {
1908 + struct brcmf_scan_results results;
1909 + struct brcmf_scan_results_le results_le;
1910 + };
1911 +};
1912 +
1913 +/* size of brcmf_iscan_results not including variable length array */
1914 +#define BRCMF_ISCAN_RESULTS_FIXED_SIZE \
1915 + (BRCMF_SCAN_RESULTS_FIXED_SIZE + \
1916 + offsetof(struct brcmf_iscan_results, results))
1917 +
1918 +struct brcmf_wsec_key {
1919 + u32 index; /* key index */
1920 + u32 len; /* key length */
1921 + u8 data[WLAN_MAX_KEY_LEN]; /* key data */
1922 + u32 pad_1[18];
1923 + u32 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */
1924 + u32 flags; /* misc flags */
1925 + u32 pad_2[3];
1926 + u32 iv_initialized; /* has IV been initialized already? */
1927 + u32 pad_3;
1928 + /* Rx IV */
1929 + struct {
1930 + u32 hi; /* upper 32 bits of IV */
1931 + u16 lo; /* lower 16 bits of IV */
1932 + } rxiv;
1933 + u32 pad_4[2];
1934 + u8 ea[ETH_ALEN]; /* per station */
1935 +};
1936 +
1937 +/*
1938 + * dongle requires same struct as above but with fields in little endian order
1939 + */
1940 +struct brcmf_wsec_key_le {
1941 + __le32 index; /* key index */
1942 + __le32 len; /* key length */
1943 + u8 data[WLAN_MAX_KEY_LEN]; /* key data */
1944 + __le32 pad_1[18];
1945 + __le32 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */
1946 + __le32 flags; /* misc flags */
1947 + __le32 pad_2[3];
1948 + __le32 iv_initialized; /* has IV been initialized already? */
1949 + __le32 pad_3;
1950 + /* Rx IV */
1951 + struct {
1952 + __le32 hi; /* upper 32 bits of IV */
1953 + __le16 lo; /* lower 16 bits of IV */
1954 + } rxiv;
1955 + __le32 pad_4[2];
1956 + u8 ea[ETH_ALEN]; /* per station */
1957 +};
1958 +
1959 +/* Used to get specific STA parameters */
1960 +struct brcmf_scb_val_le {
1961 + __le32 val;
1962 + u8 ea[ETH_ALEN];
1963 +};
1964 +
1965 +/* channel encoding */
1966 +struct brcmf_channel_info_le {
1967 + __le32 hw_channel;
1968 + __le32 target_channel;
1969 + __le32 scan_channel;
1970 +};
1971 +
1972 +/* Bus independent dongle command */
1973 +struct brcmf_dcmd {
1974 + uint cmd; /* common dongle cmd definition */
1975 + void *buf; /* pointer to user buffer */
1976 + uint len; /* length of user buffer */
1977 + u8 set; /* get or set request (optional) */
1978 + uint used; /* bytes read or written (optional) */
1979 + uint needed; /* bytes needed (optional) */
1980 +};
1981 +
1982 +/* Forward decls for struct brcmf_pub (see below) */
1983 +struct brcmf_bus; /* device bus info */
1984 +struct brcmf_proto; /* device communication protocol info */
1985 +struct brcmf_info; /* device driver info */
1986 +struct brcmf_cfg80211_dev; /* cfg80211 device info */
1987 +
1988 +/* Common structure for module and instance linkage */
1989 +struct brcmf_pub {
1990 + /* Linkage ponters */
1991 + struct brcmf_bus *bus;
1992 + struct brcmf_proto *prot;
1993 + struct brcmf_info *info;
1994 + struct brcmf_cfg80211_dev *config;
1995 +
1996 + /* Internal brcmf items */
1997 + bool up; /* Driver up/down (to OS) */
1998 + bool txoff; /* Transmit flow-controlled */
1999 + enum brcmf_bus_state busstate;
2000 + uint hdrlen; /* Total BRCMF header length (proto + bus) */
2001 + uint maxctl; /* Max size rxctl request from proto to bus */
2002 + uint rxsz; /* Rx buffer size bus module should use */
2003 + u8 wme_dp; /* wme discard priority */
2004 +
2005 + /* Dongle media info */
2006 + bool iswl; /* Dongle-resident driver is wl */
2007 + unsigned long drv_version; /* Version of dongle-resident driver */
2008 + u8 mac[ETH_ALEN]; /* MAC address obtained from dongle */
2009 + struct dngl_stats dstats; /* Stats for dongle-based data */
2010 +
2011 + /* Additional stats for the bus level */
2012 +
2013 + /* Data packets sent to dongle */
2014 + unsigned long tx_packets;
2015 + /* Multicast data packets sent to dongle */
2016 + unsigned long tx_multicast;
2017 + /* Errors in sending data to dongle */
2018 + unsigned long tx_errors;
2019 + /* Control packets sent to dongle */
2020 + unsigned long tx_ctlpkts;
2021 + /* Errors sending control frames to dongle */
2022 + unsigned long tx_ctlerrs;
2023 + /* Packets sent up the network interface */
2024 + unsigned long rx_packets;
2025 + /* Multicast packets sent up the network interface */
2026 + unsigned long rx_multicast;
2027 + /* Errors processing rx data packets */
2028 + unsigned long rx_errors;
2029 + /* Control frames processed from dongle */
2030 + unsigned long rx_ctlpkts;
2031 +
2032 + /* Errors in processing rx control frames */
2033 + unsigned long rx_ctlerrs;
2034 + /* Packets dropped locally (no memory) */
2035 + unsigned long rx_dropped;
2036 + /* Packets flushed due to unscheduled sendup thread */
2037 + unsigned long rx_flushed;
2038 + /* Number of times dpc scheduled by watchdog timer */
2039 + unsigned long wd_dpc_sched;
2040 +
2041 + /* Number of packets where header read-ahead was used. */
2042 + unsigned long rx_readahead_cnt;
2043 + /* Number of tx packets we had to realloc for headroom */
2044 + unsigned long tx_realloc;
2045 + /* Number of flow control pkts recvd */
2046 + unsigned long fc_packets;
2047 +
2048 + /* Last error return */
2049 + int bcmerror;
2050 + uint tickcnt;
2051 +
2052 + /* Last error from dongle */
2053 + int dongle_error;
2054 +
2055 + /* Suspend disable flag flag */
2056 + int suspend_disable_flag; /* "1" to disable all extra powersaving
2057 + during suspend */
2058 + int in_suspend; /* flag set to 1 when early suspend called */
2059 + int dtim_skip; /* dtim skip , default 0 means wake each dtim */
2060 +
2061 + /* Pkt filter defination */
2062 + char *pktfilter[100];
2063 + int pktfilter_count;
2064 +
2065 + u8 country_code[BRCM_CNTRY_BUF_SZ];
2066 + char eventmask[BRCMF_EVENTING_MASK_LEN];
2067 +
2068 +};
2069 +
2070 +struct brcmf_if_event {
2071 + u8 ifidx;
2072 + u8 action;
2073 + u8 flags;
2074 + u8 bssidx;
2075 +};
2076 +
2077 +struct bcmevent_name {
2078 + uint event;
2079 + const char *name;
2080 +};
2081 +
2082 +extern const struct bcmevent_name bcmevent_names[];
2083 +
2084 +/* Indication from bus module regarding presence/insertion of dongle.
2085 + * Return struct brcmf_pub pointer, used as handle to OS module in later calls.
2086 + * Returned structure should have bus and prot pointers filled in.
2087 + * bus_hdrlen specifies required headroom for bus module header.
2088 + */
2089 +extern struct brcmf_pub *brcmf_attach(struct brcmf_bus *bus,
2090 + uint bus_hdrlen);
2091 +extern int brcmf_net_attach(struct brcmf_pub *drvr, int idx);
2092 +extern int brcmf_netdev_wait_pend8021x(struct net_device *ndev);
2093 +
2094 +extern s32 brcmf_exec_dcmd(struct net_device *dev, u32 cmd, void *arg, u32 len);
2095 +
2096 +/* Indication from bus module regarding removal/absence of dongle */
2097 +extern void brcmf_detach(struct brcmf_pub *drvr);
2098 +
2099 +/* Indication from bus module to change flow-control state */
2100 +extern void brcmf_txflowcontrol(struct brcmf_pub *drvr, int ifidx, bool on);
2101 +
2102 +extern bool brcmf_c_prec_enq(struct brcmf_pub *drvr, struct pktq *q,
2103 + struct sk_buff *pkt, int prec);
2104 +
2105 +/* Receive frame for delivery to OS. Callee disposes of rxp. */
2106 +extern void brcmf_rx_frame(struct brcmf_pub *drvr, int ifidx,
2107 + struct sk_buff *rxp, int numpkt);
2108 +
2109 +/* Return pointer to interface name */
2110 +extern char *brcmf_ifname(struct brcmf_pub *drvr, int idx);
2111 +
2112 +/* Notify tx completion */
2113 +extern void brcmf_txcomplete(struct brcmf_pub *drvr, struct sk_buff *txp,
2114 + bool success);
2115 +
2116 +/* Query dongle */
2117 +extern int brcmf_proto_cdc_query_dcmd(struct brcmf_pub *drvr, int ifidx,
2118 + uint cmd, void *buf, uint len);
2119 +
2120 +/* OS independent layer functions */
2121 +extern int brcmf_os_proto_block(struct brcmf_pub *drvr);
2122 +extern int brcmf_os_proto_unblock(struct brcmf_pub *drvr);
2123 +#ifdef BCMDBG
2124 +extern int brcmf_write_to_file(struct brcmf_pub *drvr, u8 *buf, int size);
2125 +#endif /* BCMDBG */
2126 +
2127 +extern int brcmf_ifname2idx(struct brcmf_info *drvr_priv, char *name);
2128 +extern int brcmf_c_host_event(struct brcmf_info *drvr_priv, int *idx,
2129 + void *pktdata, struct brcmf_event_msg *,
2130 + void **data_ptr);
2131 +
2132 +extern void brcmf_c_init(void);
2133 +
2134 +extern int brcmf_add_if(struct brcmf_info *drvr_priv, int ifidx,
2135 + struct net_device *ndev, char *name, u8 *mac_addr,
2136 + u32 flags, u8 bssidx);
2137 +extern void brcmf_del_if(struct brcmf_info *drvr_priv, int ifidx);
2138 +
2139 +/* Send packet to dongle via data channel */
2140 +extern int brcmf_sendpkt(struct brcmf_pub *drvr, int ifidx,\
2141 + struct sk_buff *pkt);
2142 +
2143 +extern int brcmf_bus_start(struct brcmf_pub *drvr);
2144 +
2145 +extern void brcmf_c_pktfilter_offload_set(struct brcmf_pub *drvr, char *arg);
2146 +extern void brcmf_c_pktfilter_offload_enable(struct brcmf_pub *drvr, char *arg,
2147 + int enable, int master_mode);
2148 +
2149 +#define BRCMF_DCMD_SMLEN 256 /* "small" cmd buffer required */
2150 +#define BRCMF_DCMD_MEDLEN 1536 /* "med" cmd buffer required */
2151 +#define BRCMF_DCMD_MAXLEN 8192 /* max length cmd buffer required */
2152 +
2153 +/* message levels */
2154 +#define BRCMF_ERROR_VAL 0x0001
2155 +#define BRCMF_TRACE_VAL 0x0002
2156 +#define BRCMF_INFO_VAL 0x0004
2157 +#define BRCMF_DATA_VAL 0x0008
2158 +#define BRCMF_CTL_VAL 0x0010
2159 +#define BRCMF_TIMER_VAL 0x0020
2160 +#define BRCMF_HDRS_VAL 0x0040
2161 +#define BRCMF_BYTES_VAL 0x0080
2162 +#define BRCMF_INTR_VAL 0x0100
2163 +#define BRCMF_GLOM_VAL 0x0400
2164 +#define BRCMF_EVENT_VAL 0x0800
2165 +#define BRCMF_BTA_VAL 0x1000
2166 +#define BRCMF_ISCAN_VAL 0x2000
2167 +
2168 +/* Enter idle immediately (no timeout) */
2169 +#define BRCMF_IDLE_IMMEDIATE (-1)
2170 +#define BRCMF_IDLE_ACTIVE 0 /* Do not request any SD clock change
2171 + when idle */
2172 +#define BRCMF_IDLE_INTERVAL 1
2173 +
2174 +#endif /* _BRCMF_H_ */
2175
2176 new file mode 100644
2177
2178 --- /dev/null
2179 +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
2180 @@ -0,0 +1,57 @@
2181 +/*
2182 + * Copyright (c) 2010 Broadcom Corporation
2183 + *
2184 + * Permission to use, copy, modify, and/or distribute this software for any
2185 + * purpose with or without fee is hereby granted, provided that the above
2186 + * copyright notice and this permission notice appear in all copies.
2187 + *
2188 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
2189 + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
2190 + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
2191 + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
2192 + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
2193 + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
2194 + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
2195 + */
2196 +
2197 +#ifndef _BRCMF_BUS_H_
2198 +#define _BRCMF_BUS_H_
2199 +
2200 +/* Packet alignment for most efficient SDIO (can change based on platform) */
2201 +#define BRCMF_SDALIGN (1 << 6)
2202 +
2203 +/* watchdog polling interval in ms */
2204 +#define BRCMF_WD_POLL_MS 10
2205 +
2206 +/*
2207 + * Exported from brcmf bus module (brcmf_usb, brcmf_sdio)
2208 + */
2209 +
2210 +/* Indicate (dis)interest in finding dongles. */
2211 +extern int brcmf_bus_register(void);
2212 +extern void brcmf_bus_unregister(void);
2213 +
2214 +/* obtain linux device object providing bus function */
2215 +extern struct device *brcmf_bus_get_device(struct brcmf_bus *bus);
2216 +
2217 +/* Stop bus module: clear pending frames, disable data flow */
2218 +extern void brcmf_sdbrcm_bus_stop(struct brcmf_bus *bus);
2219 +
2220 +/* Initialize bus module: prepare for communication w/dongle */
2221 +extern int brcmf_sdbrcm_bus_init(struct brcmf_pub *drvr);
2222 +
2223 +/* Send a data frame to the dongle. Callee disposes of txp. */
2224 +extern int brcmf_sdbrcm_bus_txdata(struct brcmf_bus *bus, struct sk_buff *txp);
2225 +
2226 +/* Send/receive a control message to/from the dongle.
2227 + * Expects caller to enforce a single outstanding transaction.
2228 + */
2229 +extern int
2230 +brcmf_sdbrcm_bus_txctl(struct brcmf_bus *bus, unsigned char *msg, uint msglen);
2231 +
2232 +extern int
2233 +brcmf_sdbrcm_bus_rxctl(struct brcmf_bus *bus, unsigned char *msg, uint msglen);
2234 +
2235 +extern void brcmf_sdbrcm_wd_timer(struct brcmf_bus *bus, uint wdtick);
2236 +
2237 +#endif /* _BRCMF_BUS_H_ */
2238
2239 new file mode 100644
2240
2241 --- /dev/null
2242 +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c
2243 @@ -0,0 +1,498 @@
2244 +/*
2245 + * Copyright (c) 2010 Broadcom Corporation
2246 + *
2247 + * Permission to use, copy, modify, and/or distribute this software for any
2248 + * purpose with or without fee is hereby granted, provided that the above
2249 + * copyright notice and this permission notice appear in all copies.
2250 + *
2251 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
2252 + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
2253 + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
2254 + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
2255 + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
2256 + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
2257 + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
2258 + */
2259 +
2260 +/*******************************************************************************
2261 + * Communicates with the dongle by using dcmd codes.
2262 + * For certain dcmd codes, the dongle interprets string data from the host.
2263 + ******************************************************************************/
2264 +
2265 +#include <linux/types.h>
2266 +#include <linux/netdevice.h>
2267 +#include <linux/sched.h>
2268 +#include <defs.h>
2269 +
2270 +#include <brcmu_utils.h>
2271 +#include <brcmu_wifi.h>
2272 +
2273 +#include "dhd.h"
2274 +#include "dhd_proto.h"
2275 +#include "dhd_bus.h"
2276 +#include "dhd_dbg.h"
2277 +
2278 +struct brcmf_proto_cdc_dcmd {
2279 + __le32 cmd; /* dongle command value */
2280 + __le32 len; /* lower 16: output buflen;
2281 + * upper 16: input buflen (excludes header) */
2282 + __le32 flags; /* flag defns given below */
2283 + __le32 status; /* status code returned from the device */
2284 +};
2285 +
2286 +/* Max valid buffer size that can be sent to the dongle */
2287 +#define CDC_MAX_MSG_SIZE (ETH_FRAME_LEN+ETH_FCS_LEN)
2288 +
2289 +/* CDC flag definitions */
2290 +#define CDC_DCMD_ERROR 0x01 /* 1=cmd failed */
2291 +#define CDC_DCMD_SET 0x02 /* 0=get, 1=set cmd */
2292 +#define CDC_DCMD_IF_MASK 0xF000 /* I/F index */
2293 +#define CDC_DCMD_IF_SHIFT 12
2294 +#define CDC_DCMD_ID_MASK 0xFFFF0000 /* id an cmd pairing */
2295 +#define CDC_DCMD_ID_SHIFT 16 /* ID Mask shift bits */
2296 +#define CDC_DCMD_ID(flags) \
2297 + (((flags) & CDC_DCMD_ID_MASK) >> CDC_DCMD_ID_SHIFT)
2298 +
2299 +/*
2300 + * BDC header - Broadcom specific extension of CDC.
2301 + * Used on data packets to convey priority across USB.
2302 + */
2303 +#define BDC_HEADER_LEN 4
2304 +#define BDC_PROTO_VER 1 /* Protocol version */
2305 +#define BDC_FLAG_VER_MASK 0xf0 /* Protocol version mask */
2306 +#define BDC_FLAG_VER_SHIFT 4 /* Protocol version shift */
2307 +#define BDC_FLAG_SUM_GOOD 0x04 /* Good RX checksums */
2308 +#define BDC_FLAG_SUM_NEEDED 0x08 /* Dongle needs to do TX checksums */
2309 +#define BDC_PRIORITY_MASK 0x7
2310 +#define BDC_FLAG2_IF_MASK 0x0f /* packet rx interface in APSTA */
2311 +#define BDC_FLAG2_IF_SHIFT 0
2312 +
2313 +#define BDC_GET_IF_IDX(hdr) \
2314 + ((int)((((hdr)->flags2) & BDC_FLAG2_IF_MASK) >> BDC_FLAG2_IF_SHIFT))
2315 +#define BDC_SET_IF_IDX(hdr, idx) \
2316 + ((hdr)->flags2 = (((hdr)->flags2 & ~BDC_FLAG2_IF_MASK) | \
2317 + ((idx) << BDC_FLAG2_IF_SHIFT)))
2318 +
2319 +struct brcmf_proto_bdc_header {
2320 + u8 flags;
2321 + u8 priority; /* 802.1d Priority, 4:7 flow control info for usb */
2322 + u8 flags2;
2323 + u8 rssi;
2324 +};
2325 +
2326 +
2327 +#define RETRIES 2 /* # of retries to retrieve matching dcmd response */
2328 +#define BUS_HEADER_LEN (16+BRCMF_SDALIGN) /* Must be atleast SDPCM_RESERVE
2329 + * (amount of header tha might be added)
2330 + * plus any space that might be needed
2331 + * for alignment padding.
2332 + */
2333 +#define ROUND_UP_MARGIN 2048 /* Biggest SDIO block size possible for
2334 + * round off at the end of buffer
2335 + */
2336 +
2337 +struct brcmf_proto {
2338 + u16 reqid;
2339 + u8 pending;
2340 + u32 lastcmd;
2341 + u8 bus_header[BUS_HEADER_LEN];
2342 + struct brcmf_proto_cdc_dcmd msg;
2343 + unsigned char buf[BRCMF_DCMD_MAXLEN + ROUND_UP_MARGIN];
2344 +};
2345 +
2346 +static int brcmf_proto_cdc_msg(struct brcmf_pub *drvr)
2347 +{
2348 + struct brcmf_proto *prot = drvr->prot;
2349 + int len = le32_to_cpu(prot->msg.len) +
2350 + sizeof(struct brcmf_proto_cdc_dcmd);
2351 +
2352 + brcmf_dbg(TRACE, "Enter\n");
2353 +
2354 + /* NOTE : cdc->msg.len holds the desired length of the buffer to be
2355 + * returned. Only up to CDC_MAX_MSG_SIZE of this buffer area
2356 + * is actually sent to the dongle
2357 + */
2358 + if (len > CDC_MAX_MSG_SIZE)
2359 + len = CDC_MAX_MSG_SIZE;
2360 +
2361 + /* Send request */
2362 + return brcmf_sdbrcm_bus_txctl(drvr->bus, (unsigned char *)&prot->msg,
2363 + len);
2364 +}
2365 +
2366 +static int brcmf_proto_cdc_cmplt(struct brcmf_pub *drvr, u32 id, u32 len)
2367 +{
2368 + int ret;
2369 + struct brcmf_proto *prot = drvr->prot;
2370 +
2371 + brcmf_dbg(TRACE, "Enter\n");
2372 +
2373 + do {
2374 + ret = brcmf_sdbrcm_bus_rxctl(drvr->bus,
2375 + (unsigned char *)&prot->msg,
2376 + len + sizeof(struct brcmf_proto_cdc_dcmd));
2377 + if (ret < 0)
2378 + break;
2379 + } while (CDC_DCMD_ID(le32_to_cpu(prot->msg.flags)) != id);
2380 +
2381 + return ret;
2382 +}
2383 +
2384 +int
2385 +brcmf_proto_cdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
2386 + void *buf, uint len)
2387 +{
2388 + struct brcmf_proto *prot = drvr->prot;
2389 + struct brcmf_proto_cdc_dcmd *msg = &prot->msg;
2390 + void *info;
2391 + int ret = 0, retries = 0;
2392 + u32 id, flags;
2393 +
2394 + brcmf_dbg(TRACE, "Enter\n");
2395 + brcmf_dbg(CTL, "cmd %d len %d\n", cmd, len);
2396 +
2397 + /* Respond "bcmerror" and "bcmerrorstr" with local cache */
2398 + if (cmd == BRCMF_C_GET_VAR && buf) {
2399 + if (!strcmp((char *)buf, "bcmerrorstr")) {
2400 + strncpy((char *)buf, "bcm_error",
2401 + BCME_STRLEN);
2402 + goto done;
2403 + } else if (!strcmp((char *)buf, "bcmerror")) {
2404 + *(int *)buf = drvr->dongle_error;
2405 + goto done;
2406 + }
2407 + }
2408 +
2409 + memset(msg, 0, sizeof(struct brcmf_proto_cdc_dcmd));
2410 +
2411 + msg->cmd = cpu_to_le32(cmd);
2412 + msg->len = cpu_to_le32(len);
2413 + flags = (++prot->reqid << CDC_DCMD_ID_SHIFT);
2414 + flags = (flags & ~CDC_DCMD_IF_MASK) |
2415 + (ifidx << CDC_DCMD_IF_SHIFT);
2416 + msg->flags = cpu_to_le32(flags);
2417 +
2418 + if (buf)
2419 + memcpy(prot->buf, buf, len);
2420 +
2421 + ret = brcmf_proto_cdc_msg(drvr);
2422 + if (ret < 0) {
2423 + brcmf_dbg(ERROR, "brcmf_proto_cdc_msg failed w/status %d\n",
2424 + ret);
2425 + goto done;
2426 + }
2427 +
2428 +retry:
2429 + /* wait for interrupt and get first fragment */
2430 + ret = brcmf_proto_cdc_cmplt(drvr, prot->reqid, len);
2431 + if (ret < 0)
2432 + goto done;
2433 +
2434 + flags = le32_to_cpu(msg->flags);
2435 + id = (flags & CDC_DCMD_ID_MASK) >> CDC_DCMD_ID_SHIFT;
2436 +
2437 + if ((id < prot->reqid) && (++retries < RETRIES))
2438 + goto retry;
2439 + if (id != prot->reqid) {
2440 + brcmf_dbg(ERROR, "%s: unexpected request id %d (expected %d)\n",
2441 + brcmf_ifname(drvr, ifidx), id, prot->reqid);
2442 + ret = -EINVAL;
2443 + goto done;
2444 + }
2445 +
2446 + /* Check info buffer */
2447 + info = (void *)&msg[1];
2448 +
2449 + /* Copy info buffer */
2450 + if (buf) {
2451 + if (ret < (int)len)
2452 + len = ret;
2453 + memcpy(buf, info, len);
2454 + }
2455 +
2456 + /* Check the ERROR flag */
2457 + if (flags & CDC_DCMD_ERROR) {
2458 + ret = le32_to_cpu(msg->status);
2459 + /* Cache error from dongle */
2460 + drvr->dongle_error = ret;
2461 + }
2462 +
2463 +done:
2464 + return ret;
2465 +}
2466 +
2467 +int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
2468 + void *buf, uint len)
2469 +{
2470 + struct brcmf_proto *prot = drvr->prot;
2471 + struct brcmf_proto_cdc_dcmd *msg = &prot->msg;
2472 + int ret = 0;
2473 + u32 flags, id;
2474 +
2475 + brcmf_dbg(TRACE, "Enter\n");
2476 + brcmf_dbg(CTL, "cmd %d len %d\n", cmd, len);
2477 +
2478 + memset(msg, 0, sizeof(struct brcmf_proto_cdc_dcmd));
2479 +
2480 + msg->cmd = cpu_to_le32(cmd);
2481 + msg->len = cpu_to_le32(len);
2482 + flags = (++prot->reqid << CDC_DCMD_ID_SHIFT) | CDC_DCMD_SET;
2483 + flags = (flags & ~CDC_DCMD_IF_MASK) |
2484 + (ifidx << CDC_DCMD_IF_SHIFT);
2485 + msg->flags = cpu_to_le32(flags);
2486 +
2487 + if (buf)
2488 + memcpy(prot->buf, buf, len);
2489 +
2490 + ret = brcmf_proto_cdc_msg(drvr);
2491 + if (ret < 0)
2492 + goto done;
2493 +
2494 + ret = brcmf_proto_cdc_cmplt(drvr, prot->reqid, len);
2495 + if (ret < 0)
2496 + goto done;
2497 +
2498 + flags = le32_to_cpu(msg->flags);
2499 + id = (flags & CDC_DCMD_ID_MASK) >> CDC_DCMD_ID_SHIFT;
2500 +
2501 + if (id != prot->reqid) {
2502 + brcmf_dbg(ERROR, "%s: unexpected request id %d (expected %d)\n",
2503 + brcmf_ifname(drvr, ifidx), id, prot->reqid);
2504 + ret = -EINVAL;
2505 + goto done;
2506 + }
2507 +
2508 + /* Check the ERROR flag */
2509 + if (flags & CDC_DCMD_ERROR) {
2510 + ret = le32_to_cpu(msg->status);
2511 + /* Cache error from dongle */
2512 + drvr->dongle_error = ret;
2513 + }
2514 +
2515 +done:
2516 + return ret;
2517 +}
2518 +
2519 +int
2520 +brcmf_proto_dcmd(struct brcmf_pub *drvr, int ifidx, struct brcmf_dcmd *dcmd,
2521 + int len)
2522 +{
2523 + struct brcmf_proto *prot = drvr->prot;
2524 + int ret = -1;
2525 +
2526 + if (drvr->busstate == BRCMF_BUS_DOWN) {
2527 + brcmf_dbg(ERROR, "bus is down. we have nothing to do.\n");
2528 + return ret;
2529 + }
2530 + brcmf_os_proto_block(drvr);
2531 +
2532 + brcmf_dbg(TRACE, "Enter\n");
2533 +
2534 + if (len > BRCMF_DCMD_MAXLEN)
2535 + goto done;
2536 +
2537 + if (prot->pending == true) {
2538 + brcmf_dbg(TRACE, "CDC packet is pending!!!! cmd=0x%x (%lu) lastcmd=0x%x (%lu)\n",
2539 + dcmd->cmd, (unsigned long)dcmd->cmd, prot->lastcmd,
2540 + (unsigned long)prot->lastcmd);
2541 + if (dcmd->cmd == BRCMF_C_SET_VAR ||
2542 + dcmd->cmd == BRCMF_C_GET_VAR)
2543 + brcmf_dbg(TRACE, "iovar cmd=%s\n", (char *)dcmd->buf);
2544 +
2545 + goto done;
2546 + }
2547 +
2548 + prot->pending = true;
2549 + prot->lastcmd = dcmd->cmd;
2550 + if (dcmd->set)
2551 + ret = brcmf_proto_cdc_set_dcmd(drvr, ifidx, dcmd->cmd,
2552 + dcmd->buf, len);
2553 + else {
2554 + ret = brcmf_proto_cdc_query_dcmd(drvr, ifidx, dcmd->cmd,
2555 + dcmd->buf, len);
2556 + if (ret > 0)
2557 + dcmd->used = ret -
2558 + sizeof(struct brcmf_proto_cdc_dcmd);
2559 + }
2560 +
2561 + if (ret >= 0)
2562 + ret = 0;
2563 + else {
2564 + struct brcmf_proto_cdc_dcmd *msg = &prot->msg;
2565 + /* len == needed when set/query fails from dongle */
2566 + dcmd->needed = le32_to_cpu(msg->len);
2567 + }
2568 +
2569 + /* Intercept the wme_dp dongle cmd here */
2570 + if (!ret && dcmd->cmd == BRCMF_C_SET_VAR &&
2571 + !strcmp(dcmd->buf, "wme_dp")) {
2572 + int slen;
2573 + __le32 val = 0;
2574 +
2575 + slen = strlen("wme_dp") + 1;
2576 + if (len >= (int)(slen + sizeof(int)))
2577 + memcpy(&val, (char *)dcmd->buf + slen, sizeof(int));
2578 + drvr->wme_dp = (u8) le32_to_cpu(val);
2579 + }
2580 +
2581 + prot->pending = false;
2582 +
2583 +done:
2584 + brcmf_os_proto_unblock(drvr);
2585 +
2586 + return ret;
2587 +}
2588 +
2589 +static bool pkt_sum_needed(struct sk_buff *skb)
2590 +{
2591 + return skb->ip_summed == CHECKSUM_PARTIAL;
2592 +}
2593 +
2594 +static void pkt_set_sum_good(struct sk_buff *skb, bool x)
2595 +{
2596 + skb->ip_summed = (x ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE);
2597 +}
2598 +
2599 +void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx,
2600 + struct sk_buff *pktbuf)
2601 +{
2602 + struct brcmf_proto_bdc_header *h;
2603 +
2604 + brcmf_dbg(TRACE, "Enter\n");
2605 +
2606 + /* Push BDC header used to convey priority for buses that don't */
2607 +
2608 + skb_push(pktbuf, BDC_HEADER_LEN);
2609 +
2610 + h = (struct brcmf_proto_bdc_header *)(pktbuf->data);
2611 +
2612 + h->flags = (BDC_PROTO_VER << BDC_FLAG_VER_SHIFT);
2613 + if (pkt_sum_needed(pktbuf))
2614 + h->flags |= BDC_FLAG_SUM_NEEDED;
2615 +
2616 + h->priority = (pktbuf->priority & BDC_PRIORITY_MASK);
2617 + h->flags2 = 0;
2618 + h->rssi = 0;
2619 + BDC_SET_IF_IDX(h, ifidx);
2620 +}
2621 +
2622 +int brcmf_proto_hdrpull(struct brcmf_pub *drvr, int *ifidx,
2623 + struct sk_buff *pktbuf)
2624 +{
2625 + struct brcmf_proto_bdc_header *h;
2626 +
2627 + brcmf_dbg(TRACE, "Enter\n");
2628 +
2629 + /* Pop BDC header used to convey priority for buses that don't */
2630 +
2631 + if (pktbuf->len < BDC_HEADER_LEN) {
2632 + brcmf_dbg(ERROR, "rx data too short (%d < %d)\n",
2633 + pktbuf->len, BDC_HEADER_LEN);
2634 + return -EBADE;
2635 + }
2636 +
2637 + h = (struct brcmf_proto_bdc_header *)(pktbuf->data);
2638 +
2639 + *ifidx = BDC_GET_IF_IDX(h);
2640 + if (*ifidx >= BRCMF_MAX_IFS) {
2641 + brcmf_dbg(ERROR, "rx data ifnum out of range (%d)\n", *ifidx);
2642 + return -EBADE;
2643 + }
2644 +
2645 + if (((h->flags & BDC_FLAG_VER_MASK) >> BDC_FLAG_VER_SHIFT) !=
2646 + BDC_PROTO_VER) {
2647 + brcmf_dbg(ERROR, "%s: non-BDC packet received, flags 0x%x\n",
2648 + brcmf_ifname(drvr, *ifidx), h->flags);
2649 + return -EBADE;
2650 + }
2651 +
2652 + if (h->flags & BDC_FLAG_SUM_GOOD) {
2653 + brcmf_dbg(INFO, "%s: BDC packet received with good rx-csum, flags 0x%x\n",
2654 + brcmf_ifname(drvr, *ifidx), h->flags);
2655 + pkt_set_sum_good(pktbuf, true);
2656 + }
2657 +
2658 + pktbuf->priority = h->priority & BDC_PRIORITY_MASK;
2659 +
2660 + skb_pull(pktbuf, BDC_HEADER_LEN);
2661 +
2662 + return 0;
2663 +}
2664 +
2665 +int brcmf_proto_attach(struct brcmf_pub *drvr)
2666 +{
2667 + struct brcmf_proto *cdc;
2668 +
2669 + cdc = kzalloc(sizeof(struct brcmf_proto), GFP_ATOMIC);
2670 + if (!cdc)
2671 + goto fail;
2672 +
2673 + /* ensure that the msg buf directly follows the cdc msg struct */
2674 + if ((unsigned long)(&cdc->msg + 1) != (unsigned long)cdc->buf) {
2675 + brcmf_dbg(ERROR, "struct brcmf_proto is not correctly defined\n");
2676 + goto fail;
2677 + }
2678 +
2679 + drvr->prot = cdc;
2680 + drvr->hdrlen += BDC_HEADER_LEN;
2681 + drvr->maxctl = BRCMF_DCMD_MAXLEN +
2682 + sizeof(struct brcmf_proto_cdc_dcmd) + ROUND_UP_MARGIN;
2683 + return 0;
2684 +
2685 +fail:
2686 + kfree(cdc);
2687 + return -ENOMEM;
2688 +}
2689 +
2690 +/* ~NOTE~ What if another thread is waiting on the semaphore? Holding it? */
2691 +void brcmf_proto_detach(struct brcmf_pub *drvr)
2692 +{
2693 + kfree(drvr->prot);
2694 + drvr->prot = NULL;
2695 +}
2696 +
2697 +void brcmf_proto_dstats(struct brcmf_pub *drvr)
2698 +{
2699 + /* No stats from dongle added yet, copy bus stats */
2700 + drvr->dstats.tx_packets = drvr->tx_packets;
2701 + drvr->dstats.tx_errors = drvr->tx_errors;
2702 + drvr->dstats.rx_packets = drvr->rx_packets;
2703 + drvr->dstats.rx_errors = drvr->rx_errors;
2704 + drvr->dstats.rx_dropped = drvr->rx_dropped;
2705 + drvr->dstats.multicast = drvr->rx_multicast;
2706 + return;
2707 +}
2708 +
2709 +int brcmf_proto_init(struct brcmf_pub *drvr)
2710 +{
2711 + int ret = 0;
2712 + char buf[128];
2713 +
2714 + brcmf_dbg(TRACE, "Enter\n");
2715 +
2716 + brcmf_os_proto_block(drvr);
2717 +
2718 + /* Get the device MAC address */
2719 + strcpy(buf, "cur_etheraddr");
2720 + ret = brcmf_proto_cdc_query_dcmd(drvr, 0, BRCMF_C_GET_VAR,
2721 + buf, sizeof(buf));
2722 + if (ret < 0) {
2723 + brcmf_os_proto_unblock(drvr);
2724 + return ret;
2725 + }
2726 + memcpy(drvr->mac, buf, ETH_ALEN);
2727 +
2728 + brcmf_os_proto_unblock(drvr);
2729 +
2730 + ret = brcmf_c_preinit_dcmds(drvr);
2731 +
2732 + /* Always assumes wl for now */
2733 + drvr->iswl = true;
2734 +
2735 + return ret;
2736 +}
2737 +
2738 +void brcmf_proto_stop(struct brcmf_pub *drvr)
2739 +{
2740 + /* Nothing to do for CDC */
2741 +}
2742
2743 new file mode 100644
2744
2745 --- /dev/null
2746 +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
2747 @@ -0,0 +1,872 @@
2748 +/*
2749 + * Copyright (c) 2010 Broadcom Corporation
2750 + *
2751 + * Permission to use, copy, modify, and/or distribute this software for any
2752 + * purpose with or without fee is hereby granted, provided that the above
2753 + * copyright notice and this permission notice appear in all copies.
2754 + *
2755 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
2756 + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
2757 + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
2758 + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
2759 + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
2760 + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
2761 + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
2762 + */
2763 +#include <linux/kernel.h>
2764 +#include <linux/string.h>
2765 +#include <linux/sched.h>
2766 +#include <linux/netdevice.h>
2767 +#include <asm/unaligned.h>
2768 +#include <defs.h>
2769 +#include <brcmu_wifi.h>
2770 +#include <brcmu_utils.h>
2771 +#include "dhd.h"
2772 +#include "dhd_bus.h"
2773 +#include "dhd_proto.h"
2774 +#include "dhd_dbg.h"
2775 +
2776 +#define BRCM_OUI "\x00\x10\x18"
2777 +#define DOT11_OUI_LEN 3
2778 +#define BCMILCP_BCM_SUBTYPE_EVENT 1
2779 +#define PKTFILTER_BUF_SIZE 2048
2780 +#define BRCMF_ARPOL_MODE 0xb /* agent|snoop|peer_autoreply */
2781 +
2782 +int brcmf_msg_level;
2783 +
2784 +#define MSGTRACE_VERSION 1
2785 +
2786 +#define BRCMF_PKT_FILTER_FIXED_LEN offsetof(struct brcmf_pkt_filter, u)
2787 +#define BRCMF_PKT_FILTER_PATTERN_FIXED_LEN \
2788 + offsetof(struct brcmf_pkt_filter_pattern, mask_and_pattern)
2789 +
2790 +#ifdef BCMDBG
2791 +static const char brcmf_version[] =
2792 + "Dongle Host Driver, version " BRCMF_VERSION_STR "\nCompiled on "
2793 + __DATE__ " at " __TIME__;
2794 +#else
2795 +static const char brcmf_version[] =
2796 + "Dongle Host Driver, version " BRCMF_VERSION_STR;
2797 +#endif
2798 +
2799 +/* Message trace header */
2800 +struct msgtrace_hdr {
2801 + u8 version;
2802 + u8 spare;
2803 + __be16 len; /* Len of the trace */
2804 + __be32 seqnum; /* Sequence number of message. Useful
2805 + * if the messsage has been lost
2806 + * because of DMA error or a bus reset
2807 + * (ex: SDIO Func2)
2808 + */
2809 + __be32 discarded_bytes; /* Number of discarded bytes because of
2810 + trace overflow */
2811 + __be32 discarded_printf; /* Number of discarded printf
2812 + because of trace overflow */
2813 +} __packed;
2814 +
2815 +void brcmf_c_init(void)
2816 +{
2817 + /* Init global variables at run-time, not as part of the declaration.
2818 + * This is required to support init/de-init of the driver.
2819 + * Initialization
2820 + * of globals as part of the declaration results in non-deterministic
2821 + * behaviour since the value of the globals may be different on the
2822 + * first time that the driver is initialized vs subsequent
2823 + * initializations.
2824 + */
2825 + brcmf_msg_level = BRCMF_ERROR_VAL;
2826 +}
2827 +
2828 +bool brcmf_c_prec_enq(struct brcmf_pub *drvr, struct pktq *q,
2829 + struct sk_buff *pkt, int prec)
2830 +{
2831 + struct sk_buff *p;
2832 + int eprec = -1; /* precedence to evict from */
2833 + bool discard_oldest;
2834 +
2835 + /* Fast case, precedence queue is not full and we are also not
2836 + * exceeding total queue length
2837 + */
2838 + if (!pktq_pfull(q, prec) && !pktq_full(q)) {
2839 + brcmu_pktq_penq(q, prec, pkt);
2840 + return true;
2841 + }
2842 +
2843 + /* Determine precedence from which to evict packet, if any */
2844 + if (pktq_pfull(q, prec))
2845 + eprec = prec;
2846 + else if (pktq_full(q)) {
2847 + p = brcmu_pktq_peek_tail(q, &eprec);
2848 + if (eprec > prec)
2849 + return false;
2850 + }
2851 +
2852 + /* Evict if needed */
2853 + if (eprec >= 0) {
2854 + /* Detect queueing to unconfigured precedence */
2855 + discard_oldest = ac_bitmap_tst(drvr->wme_dp, eprec);
2856 + if (eprec == prec && !discard_oldest)
2857 + return false; /* refuse newer (incoming) packet */
2858 + /* Evict packet according to discard policy */
2859 + p = discard_oldest ? brcmu_pktq_pdeq(q, eprec) :
2860 + brcmu_pktq_pdeq_tail(q, eprec);
2861 + if (p == NULL)
2862 + brcmf_dbg(ERROR, "brcmu_pktq_penq() failed, oldest %d\n",
2863 + discard_oldest);
2864 +
2865 + brcmu_pkt_buf_free_skb(p);
2866 + }
2867 +
2868 + /* Enqueue */
2869 + p = brcmu_pktq_penq(q, prec, pkt);
2870 + if (p == NULL)
2871 + brcmf_dbg(ERROR, "brcmu_pktq_penq() failed\n");
2872 +
2873 + return p != NULL;
2874 +}
2875 +
2876 +#ifdef BCMDBG
2877 +static void
2878 +brcmf_c_show_host_event(struct brcmf_event_msg *event, void *event_data)
2879 +{
2880 + uint i, status, reason;
2881 + bool group = false, flush_txq = false, link = false;
2882 + char *auth_str, *event_name;
2883 + unsigned char *buf;
2884 + char err_msg[256], eabuf[ETHER_ADDR_STR_LEN];
2885 + static struct {
2886 + uint event;
2887 + char *event_name;
2888 + } event_names[] = {
2889 + {
2890 + BRCMF_E_SET_SSID, "SET_SSID"}, {
2891 + BRCMF_E_JOIN, "JOIN"}, {
2892 + BRCMF_E_START, "START"}, {
2893 + BRCMF_E_AUTH, "AUTH"}, {
2894 + BRCMF_E_AUTH_IND, "AUTH_IND"}, {
2895 + BRCMF_E_DEAUTH, "DEAUTH"}, {
2896 + BRCMF_E_DEAUTH_IND, "DEAUTH_IND"}, {
2897 + BRCMF_E_ASSOC, "ASSOC"}, {
2898 + BRCMF_E_ASSOC_IND, "ASSOC_IND"}, {
2899 + BRCMF_E_REASSOC, "REASSOC"}, {
2900 + BRCMF_E_REASSOC_IND, "REASSOC_IND"}, {
2901 + BRCMF_E_DISASSOC, "DISASSOC"}, {
2902 + BRCMF_E_DISASSOC_IND, "DISASSOC_IND"}, {
2903 + BRCMF_E_QUIET_START, "START_QUIET"}, {
2904 + BRCMF_E_QUIET_END, "END_QUIET"}, {
2905 + BRCMF_E_BEACON_RX, "BEACON_RX"}, {
2906 + BRCMF_E_LINK, "LINK"}, {
2907 + BRCMF_E_MIC_ERROR, "MIC_ERROR"}, {
2908 + BRCMF_E_NDIS_LINK, "NDIS_LINK"}, {
2909 + BRCMF_E_ROAM, "ROAM"}, {
2910 + BRCMF_E_TXFAIL, "TXFAIL"}, {
2911 + BRCMF_E_PMKID_CACHE, "PMKID_CACHE"}, {
2912 + BRCMF_E_RETROGRADE_TSF, "RETROGRADE_TSF"}, {
2913 + BRCMF_E_PRUNE, "PRUNE"}, {
2914 + BRCMF_E_AUTOAUTH, "AUTOAUTH"}, {
2915 + BRCMF_E_EAPOL_MSG, "EAPOL_MSG"}, {
2916 + BRCMF_E_SCAN_COMPLETE, "SCAN_COMPLETE"}, {
2917 + BRCMF_E_ADDTS_IND, "ADDTS_IND"}, {
2918 + BRCMF_E_DELTS_IND, "DELTS_IND"}, {
2919 + BRCMF_E_BCNSENT_IND, "BCNSENT_IND"}, {
2920 + BRCMF_E_BCNRX_MSG, "BCNRX_MSG"}, {
2921 + BRCMF_E_BCNLOST_MSG, "BCNLOST_MSG"}, {
2922 + BRCMF_E_ROAM_PREP, "ROAM_PREP"}, {
2923 + BRCMF_E_PFN_NET_FOUND, "PNO_NET_FOUND"}, {
2924 + BRCMF_E_PFN_NET_LOST, "PNO_NET_LOST"}, {
2925 + BRCMF_E_RESET_COMPLETE, "RESET_COMPLETE"}, {
2926 + BRCMF_E_JOIN_START, "JOIN_START"}, {
2927 + BRCMF_E_ROAM_START, "ROAM_START"}, {
2928 + BRCMF_E_ASSOC_START, "ASSOC_START"}, {
2929 + BRCMF_E_IBSS_ASSOC, "IBSS_ASSOC"}, {
2930 + BRCMF_E_RADIO, "RADIO"}, {
2931 + BRCMF_E_PSM_WATCHDOG, "PSM_WATCHDOG"}, {
2932 + BRCMF_E_PROBREQ_MSG, "PROBREQ_MSG"}, {
2933 + BRCMF_E_SCAN_CONFIRM_IND, "SCAN_CONFIRM_IND"}, {
2934 + BRCMF_E_PSK_SUP, "PSK_SUP"}, {
2935 + BRCMF_E_COUNTRY_CODE_CHANGED, "COUNTRY_CODE_CHANGED"}, {
2936 + BRCMF_E_EXCEEDED_MEDIUM_TIME, "EXCEEDED_MEDIUM_TIME"}, {
2937 + BRCMF_E_ICV_ERROR, "ICV_ERROR"}, {
2938 + BRCMF_E_UNICAST_DECODE_ERROR, "UNICAST_DECODE_ERROR"}, {
2939 + BRCMF_E_MULTICAST_DECODE_ERROR, "MULTICAST_DECODE_ERROR"}, {
2940 + BRCMF_E_TRACE, "TRACE"}, {
2941 + BRCMF_E_ACTION_FRAME, "ACTION FRAME"}, {
2942 + BRCMF_E_ACTION_FRAME_COMPLETE, "ACTION FRAME TX COMPLETE"}, {
2943 + BRCMF_E_IF, "IF"}, {
2944 + BRCMF_E_RSSI, "RSSI"}, {
2945 + BRCMF_E_PFN_SCAN_COMPLETE, "SCAN_COMPLETE"}
2946 + };
2947 + uint event_type, flags, auth_type, datalen;
2948 + static u32 seqnum_prev;
2949 + struct msgtrace_hdr hdr;
2950 + u32 nblost;
2951 + char *s, *p;
2952 +
2953 + event_type = be32_to_cpu(event->event_type);
2954 + flags = be16_to_cpu(event->flags);
2955 + status = be32_to_cpu(event->status);
2956 + reason = be32_to_cpu(event->reason);
2957 + auth_type = be32_to_cpu(event->auth_type);
2958 + datalen = be32_to_cpu(event->datalen);
2959 + /* debug dump of event messages */
2960 + sprintf(eabuf, "%pM", event->addr);
2961 +
2962 + event_name = "UNKNOWN";
2963 + for (i = 0; i < ARRAY_SIZE(event_names); i++) {
2964 + if (event_names[i].event == event_type)
2965 + event_name = event_names[i].event_name;
2966 + }
2967 +
2968 + brcmf_dbg(EVENT, "EVENT: %s, event ID = %d\n", event_name, event_type);
2969 + brcmf_dbg(EVENT, "flags 0x%04x, status %d, reason %d, auth_type %d MAC %s\n",
2970 + flags, status, reason, auth_type, eabuf);
2971 +
2972 + if (flags & BRCMF_EVENT_MSG_LINK)
2973 + link = true;
2974 + if (flags & BRCMF_EVENT_MSG_GROUP)
2975 + group = true;
2976 + if (flags & BRCMF_EVENT_MSG_FLUSHTXQ)
2977 + flush_txq = true;
2978 +
2979 + switch (event_type) {
2980 + case BRCMF_E_START:
2981 + case BRCMF_E_DEAUTH:
2982 + case BRCMF_E_DISASSOC:
2983 + brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s\n", event_name, eabuf);
2984 + break;
2985 +
2986 + case BRCMF_E_ASSOC_IND:
2987 + case BRCMF_E_REASSOC_IND:
2988 + brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s\n", event_name, eabuf);
2989 + break;
2990 +
2991 + case BRCMF_E_ASSOC:
2992 + case BRCMF_E_REASSOC:
2993 + if (status == BRCMF_E_STATUS_SUCCESS)
2994 + brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, SUCCESS\n",
2995 + event_name, eabuf);
2996 + else if (status == BRCMF_E_STATUS_TIMEOUT)
2997 + brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, TIMEOUT\n",
2998 + event_name, eabuf);
2999 + else if (status == BRCMF_E_STATUS_FAIL)
3000 + brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, FAILURE, reason %d\n",
3001 + event_name, eabuf, (int)reason);
3002 + else
3003