Attachment '0001-net-wireless-add-brcm80211-drivers-v3.patch'

Download

   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 diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
 219 index f354bd4..abd3b71 100644
 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 diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
 231 index 7bba6a8..dd71dc9 100644
 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 diff --git a/drivers/net/wireless/brcm80211/Kconfig b/drivers/net/wireless/brcm80211/Kconfig
 242 new file mode 100644
 243 index 0000000..2069fc8
 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 diff --git a/drivers/net/wireless/brcm80211/Makefile b/drivers/net/wireless/brcm80211/Makefile
 283 new file mode 100644
 284 index 0000000..f41c047
 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 diff --git a/drivers/net/wireless/brcm80211/brcmfmac/Makefile b/drivers/net/wireless/brcm80211/brcmfmac/Makefile
 312 new file mode 100644
 313 index 0000000..b44e309
 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 diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmchip.h b/drivers/net/wireless/brcm80211/brcmfmac/bcmchip.h
 351 new file mode 100644
 352 index 0000000..d7d3afd
 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 diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
 389 new file mode 100644
 390 index 0000000..bff9dcd
 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 diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
 766 new file mode 100644
 767 index 0000000..e919de2
 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 +				&regdata)) != 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 diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
1397 new file mode 100644
1398 index 0000000..3ec7477
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 diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
2176 new file mode 100644
2177 index 0000000..a249407
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 diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c
2239 new file mode 100644
2240 index 0000000..e34c5c3
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 diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
2743 new file mode 100644
2744 index 0000000..4075fd7
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