All of lore.kernel.org
 help / color / mirror / Atom feed
From: John Weber <rjohnweber@gmail.com>
To: meta-freescale@yoctoproject.org
Subject: [meta-fsl-arm-extra][PATCH] linux-imx (3.0.35): add brcm80211 driver backported from v3.5
Date: Sat, 16 Mar 2013 08:45:37 -0500	[thread overview]
Message-ID: <1363441542-5300-3-git-send-email-rjohnweber@gmail.com> (raw)
In-Reply-To: <1363441542-5300-1-git-send-email-rjohnweber@gmail.com>

Adds a backported driver from kernel v3.5 for brcm80211.  Used with
bcm4329 and other Broadcom Wifi devices.

Signed-off-by: John Weber <rjohnweber@gmail.com>
---
 ....0.35-Add-brcm80211-driver-backported-fro.patch |94038 ++++++++++++++++++++
 1 files changed, 94039 insertions(+)
 create mode 100644 recipes-kernel/linux/linux-imx-3.0.35/wandboard-dual/0003-linux-imx-3.0.35-Add-brcm80211-driver-backported-fro.patch

diff --git a/recipes-kernel/linux/linux-imx-3.0.35/wandboard-dual/0003-linux-imx-3.0.35-Add-brcm80211-driver-backported-fro.patch b/recipes-kernel/linux/linux-imx-3.0.35/wandboard-dual/0003-linux-imx-3.0.35-Add-brcm80211-driver-backported-fro.patch
new file mode 100644
index 0000000..1ed5f50
--- /dev/null
+++ b/recipes-kernel/linux/linux-imx-3.0.35/wandboard-dual/0003-linux-imx-3.0.35-Add-brcm80211-driver-backported-fro.patch
@@ -0,0 +1,94038 @@
+From 99044f426f004207f6256add552e64a509c205fd Mon Sep 17 00:00:00 2001
+From: John Weber <rjohnweber@gmail.com>
+Date: Sat, 9 Mar 2013 09:25:52 -0600
+Subject: [meta-fsl-arm-extra][PATCH 2/2] linux-imx (3.0.35): Add brcm80211
+ driver backported from 3.5
+
+Upstream-Status: Pending
+
+Signed-off-by: John Weber <rjohnweber@gmail.com>
+---
+ drivers/net/wireless/Kconfig                       |    2 +
+ drivers/net/wireless/Makefile                      |    4 +
+ drivers/net/wireless/brcm80211/Kconfig             |   62 +
+ drivers/net/wireless/brcm80211/Makefile            |   23 +
+ drivers/net/wireless/brcm80211/brcmfmac/Makefile   |   36 +
+ drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c   |  550 +
+ .../net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c |  703 +
+ drivers/net/wireless/brcm80211/brcmfmac/dhd.h      |  669 +
+ drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h  |  118 +
+ drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c  |  495 +
+ .../net/wireless/brcm80211/brcmfmac/dhd_common.c   |  882 +
+ drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h  |   79 +
+ .../net/wireless/brcm80211/brcmfmac/dhd_linux.c    | 1232 +
+ .../net/wireless/brcm80211/brcmfmac/dhd_proto.h    |   53 +
+ drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 4014 +++
+ .../net/wireless/brcm80211/brcmfmac/sdio_chip.c    |  622 +
+ .../net/wireless/brcm80211/brcmfmac/sdio_chip.h    |  136 +
+ .../net/wireless/brcm80211/brcmfmac/sdio_host.h    |  272 +
+ drivers/net/wireless/brcm80211/brcmfmac/usb.c      | 1617 ++
+ drivers/net/wireless/brcm80211/brcmfmac/usb.h      |   61 +
+ drivers/net/wireless/brcm80211/brcmfmac/usb_rdl.h  |   75 +
+ .../net/wireless/brcm80211/brcmfmac/wl_cfg80211.c  | 3881 +++
+ .../net/wireless/brcm80211/brcmfmac/wl_cfg80211.h  |  366 +
+ drivers/net/wireless/brcm80211/brcmsmac/Makefile   |   48 +
+ drivers/net/wireless/brcm80211/brcmsmac/aiutils.c  |  841 +
+ drivers/net/wireless/brcm80211/brcmsmac/aiutils.h  |  248 +
+ drivers/net/wireless/brcm80211/brcmsmac/ampdu.c    | 1236 +
+ drivers/net/wireless/brcm80211/brcmsmac/ampdu.h    |   30 +
+ drivers/net/wireless/brcm80211/brcmsmac/antsel.c   |  307 +
+ drivers/net/wireless/brcm80211/brcmsmac/antsel.h   |   29 +
+ .../brcm80211/brcmsmac/brcms_trace_events.c        |   23 +
+ .../brcm80211/brcmsmac/brcms_trace_events.h        |   92 +
+ drivers/net/wireless/brcm80211/brcmsmac/channel.c  | 1506 +
+ drivers/net/wireless/brcm80211/brcmsmac/channel.h  |   53 +
+ drivers/net/wireless/brcm80211/brcmsmac/d11.h      | 1901 ++
+ drivers/net/wireless/brcm80211/brcmsmac/dma.c      | 1444 +
+ drivers/net/wireless/brcm80211/brcmsmac/dma.h      |  122 +
+ .../net/wireless/brcm80211/brcmsmac/mac80211_if.c  | 1609 ++
+ .../net/wireless/brcm80211/brcmsmac/mac80211_if.h  |  108 +
+ drivers/net/wireless/brcm80211/brcmsmac/main.c     | 8495 ++++++
+ drivers/net/wireless/brcm80211/brcmsmac/main.h     |  720 +
+ .../net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c  | 2961 ++
+ .../net/wireless/brcm80211/brcmsmac/phy/phy_hal.h  |  299 +
+ .../net/wireless/brcm80211/brcmsmac/phy/phy_int.h  | 1162 +
+ .../net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c  | 5137 ++++
+ .../net/wireless/brcm80211/brcmsmac/phy/phy_lcn.h  |  121 +
+ .../net/wireless/brcm80211/brcmsmac/phy/phy_n.c    |28685 ++++++++++++++++++++
+ .../wireless/brcm80211/brcmsmac/phy/phy_qmath.c    |  308 +
+ .../wireless/brcm80211/brcmsmac/phy/phy_qmath.h    |   42 +
+ .../wireless/brcm80211/brcmsmac/phy/phy_radio.h    | 1533 ++
+ .../net/wireless/brcm80211/brcmsmac/phy/phyreg_n.h |  167 +
+ .../wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c   | 3250 +++
+ .../wireless/brcm80211/brcmsmac/phy/phytbl_lcn.h   |   54 +
+ .../net/wireless/brcm80211/brcmsmac/phy/phytbl_n.c |10630 ++++++++
+ .../net/wireless/brcm80211/brcmsmac/phy/phytbl_n.h |   50 +
+ drivers/net/wireless/brcm80211/brcmsmac/phy_shim.c |  216 +
+ drivers/net/wireless/brcm80211/brcmsmac/phy_shim.h |  179 +
+ drivers/net/wireless/brcm80211/brcmsmac/pmu.c      |  375 +
+ drivers/net/wireless/brcm80211/brcmsmac/pmu.h      |   35 +
+ drivers/net/wireless/brcm80211/brcmsmac/pub.h      |  372 +
+ drivers/net/wireless/brcm80211/brcmsmac/rate.c     |  514 +
+ drivers/net/wireless/brcm80211/brcmsmac/rate.h     |  249 +
+ drivers/net/wireless/brcm80211/brcmsmac/scb.h      |   82 +
+ drivers/net/wireless/brcm80211/brcmsmac/stf.c      |  438 +
+ drivers/net/wireless/brcm80211/brcmsmac/stf.h      |   42 +
+ drivers/net/wireless/brcm80211/brcmsmac/types.h    |  304 +
+ .../net/wireless/brcm80211/brcmsmac/ucode_loader.c |  109 +
+ .../net/wireless/brcm80211/brcmsmac/ucode_loader.h |   58 +
+ drivers/net/wireless/brcm80211/brcmutil/Makefile   |   28 +
+ drivers/net/wireless/brcm80211/brcmutil/utils.c    |  278 +
+ .../net/wireless/brcm80211/include/brcm_hw_ids.h   |   41 +
+ .../net/wireless/brcm80211/include/brcmu_utils.h   |  196 +
+ .../net/wireless/brcm80211/include/brcmu_wifi.h    |  239 +
+ .../net/wireless/brcm80211/include/chipcommon.h    |  286 +
+ drivers/net/wireless/brcm80211/include/defs.h      |  103 +
+ drivers/net/wireless/brcm80211/include/soc.h       |   98 +
+ 76 files changed, 93405 insertions(+)
+ create mode 100644 drivers/net/wireless/brcm80211/Kconfig
+ create mode 100644 drivers/net/wireless/brcm80211/Makefile
+ create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/Makefile
+ create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/dhd.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/usb.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/usb.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/usb_rdl.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/Makefile
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/aiutils.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/aiutils.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/ampdu.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/antsel.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/antsel.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/channel.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/channel.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/d11.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/dma.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/dma.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/main.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/main.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy/phy_hal.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy/phy_int.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy/phy_qmath.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy/phy_qmath.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy/phy_radio.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy/phyreg_n.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_n.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_n.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy_shim.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy_shim.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/pmu.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/pmu.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/pub.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/rate.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/rate.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/scb.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/stf.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/stf.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/types.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/ucode_loader.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/ucode_loader.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmutil/Makefile
+ create mode 100644 drivers/net/wireless/brcm80211/brcmutil/utils.c
+ create mode 100644 drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
+ create mode 100644 drivers/net/wireless/brcm80211/include/brcmu_utils.h
+ create mode 100644 drivers/net/wireless/brcm80211/include/brcmu_wifi.h
+ create mode 100644 drivers/net/wireless/brcm80211/include/chipcommon.h
+ create mode 100644 drivers/net/wireless/brcm80211/include/defs.h
+ create mode 100644 drivers/net/wireless/brcm80211/include/soc.h
+
+diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
+index fbcf861..d7da434 100644
+--- a/drivers/net/wireless/Kconfig
++++ b/drivers/net/wireless/Kconfig
+@@ -271,6 +271,7 @@ config MWL8K
+ source "drivers/net/wireless/ath/Kconfig"
+ source "drivers/net/wireless/b43/Kconfig"
+ source "drivers/net/wireless/b43legacy/Kconfig"
++source "drivers/net/wireless/brcm80211/Kconfig"
+ source "drivers/net/wireless/hostap/Kconfig"
+ source "drivers/net/wireless/ipw2x00/Kconfig"
+ source "drivers/net/wireless/iwlwifi/Kconfig"
+@@ -288,4 +289,5 @@ source "drivers/net/wireless/mwifiex/Kconfig"
+ #source "drivers/net/wireless/ath6kl/Kconfig"
+ #source "drivers/net/wireless/ath6kl/Kconfig"
+ 
++
+ endif # WLAN
+diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
+index 60a0a41..69a03f4 100644
+--- a/drivers/net/wireless/Makefile
++++ b/drivers/net/wireless/Makefile
+@@ -59,3 +59,7 @@ obj-$(CONFIG_IWM)	+= iwmc3200wifi/
+ 
+ obj-$(CONFIG_MWIFIEX)	+= mwifiex/
+ #obj-$(CONFIG_ATH6K_LEGACY)	+= ath6kl/
++
++obj-$(CONFIG_BRCMFMAC) += brcm80211/
++obj-$(CONFIG_BRCMUMAC) += brcm80211/
++obj-$(CONFIG_BRCMSMAC) += brcm80211/
+diff --git a/drivers/net/wireless/brcm80211/Kconfig b/drivers/net/wireless/brcm80211/Kconfig
+new file mode 100644
+index 0000000..b480088
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/Kconfig
+@@ -0,0 +1,62 @@
++config BRCMUTIL
++	tristate
++
++config BRCMSMAC
++	tristate "Broadcom IEEE802.11n PCIe SoftMAC WLAN driver"
++	depends on MAC80211
++	depends on BCMA
++	select BRCMUTIL
++	select FW_LOADER
++	select CRC_CCITT
++	select CRC8
++	select CORDIC
++	---help---
++	  This module adds support for PCIe wireless adapters based on Broadcom
++	  IEEE802.11n SoftMAC chipsets.  If you choose to build a module, it'll
++	  be called brcmsmac.ko.
++
++config BRCMFMAC
++	tristate "Broadcom IEEE802.11n embedded FullMAC WLAN driver"
++	depends on CFG80211
++	select BRCMUTIL
++	---help---
++	  This module adds support for embedded wireless adapters based on
++	  Broadcom IEEE802.11n FullMAC chipsets. It has to work with at least
++	  one of the bus interface support. If you choose to build a module,
++	  it'll be called brcmfmac.ko.
++
++config BRCMFMAC_SDIO
++	bool "SDIO bus interface support for FullMAC driver"
++	depends on MMC
++	depends on BRCMFMAC
++	select FW_LOADER
++	default y
++	---help---
++	  This option enables the SDIO bus interface support for Broadcom
++	  IEEE802.11n embedded FullMAC WLAN driver. Say Y if you want to
++	  use the driver for a SDIO wireless card.
++
++config BRCMFMAC_SDIO_OOB
++	bool "Out of band interrupt support for SDIO interface chipset"
++	depends on BRCMFMAC_SDIO
++	---help---
++	  This option enables out-of-band interrupt support for Broadcom
++	  SDIO Wifi chipset using fullmac in order to gain better
++	  performance and deep sleep wake up capability on certain
++	  platforms. Say N if you are unsure.
++
++config BRCMFMAC_USB
++	bool "USB bus interface support for FullMAC driver"
++	depends on USB
++	depends on BRCMFMAC
++	select FW_LOADER
++	---help---
++	  This option enables the USB bus interface support for Broadcom
++	  IEEE802.11n embedded FullMAC WLAN driver. Say Y if you want to
++	  use the driver for an USB wireless card.
++
++config BRCMDBG
++	bool "Broadcom driver debug functions"
++	depends on BRCMSMAC || BRCMFMAC
++	---help---
++	  Selecting this enables additional code for debug purposes.
+diff --git a/drivers/net/wireless/brcm80211/Makefile b/drivers/net/wireless/brcm80211/Makefile
+new file mode 100644
+index 0000000..b987920
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/Makefile
+@@ -0,0 +1,23 @@
++#
++# Makefile fragment for Broadcom 802.11n Networking Device Driver
++#
++# Copyright (c) 2010 Broadcom Corporation
++#
++# Permission to use, copy, modify, and/or distribute this software for any
++# purpose with or without fee is hereby granted, provided that the above
++# copyright notice and this permission notice appear in all copies.
++#
++# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++
++# common flags
++subdir-ccflags-$(CONFIG_BRCMDBG)	+= -DDEBUG
++
++obj-$(CONFIG_BRCMUTIL)	+= brcmutil/
++obj-$(CONFIG_BRCMFMAC)	+= brcmfmac/
++obj-$(CONFIG_BRCMSMAC)	+= brcmsmac/
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/Makefile b/drivers/net/wireless/brcm80211/brcmfmac/Makefile
+new file mode 100644
+index 0000000..a4c4d1c
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmfmac/Makefile
+@@ -0,0 +1,36 @@
++#
++# Makefile fragment for Broadcom 802.11n Networking Device Driver
++#
++# Copyright (c) 2010 Broadcom Corporation
++#
++# Permission to use, copy, modify, and/or distribute this software for any
++# purpose with or without fee is hereby granted, provided that the above
++# copyright notice and this permission notice appear in all copies.
++#
++# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++
++ccflags-y += \
++	-I$(obj)		\
++	-I$(obj)/../include
++
++ccflags-y += -D__CHECK_ENDIAN__
++
++obj-$(CONFIG_BRCMFMAC) += brcmfmac.o
++brcmfmac-objs += \
++		wl_cfg80211.o \
++		dhd_cdc.o \
++		dhd_common.o \
++		dhd_linux.o
++brcmfmac-$(CONFIG_BRCMFMAC_SDIO) += \
++		dhd_sdio.o \
++		bcmsdh.o \
++		bcmsdh_sdmmc.o \
++		sdio_chip.o
++brcmfmac-$(CONFIG_BRCMFMAC_USB) += \
++		usb.o
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+new file mode 100644
+index 0000000..a87f141
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+@@ -0,0 +1,550 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++/* ****************** SDIO CARD Interface Functions **************************/
++
++#undef pr_fmt
++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
++
++#include <linux/types.h>
++#include <linux/netdevice.h>
++#include <linux/module.h>
++#include <linux/printk.h>
++#include <linux/pci.h>
++#include <linux/pci_ids.h>
++#include <linux/sched.h>
++#include <linux/completion.h>
++#include <linux/mmc/sdio.h>
++#include <linux/mmc/sdio_func.h>
++#include <linux/mmc/card.h>
++
++#include <defs.h>
++#include <brcm_hw_ids.h>
++#include <brcmu_utils.h>
++#include <brcmu_wifi.h>
++#include <soc.h>
++#include "dhd_bus.h"
++#include "dhd_dbg.h"
++#include "sdio_host.h"
++
++#define SDIOH_API_ACCESS_RETRY_LIMIT	2
++
++#ifdef CONFIG_BRCMFMAC_SDIO_OOB
++static irqreturn_t brcmf_sdio_irqhandler(int irq, void *dev_id)
++{
++	struct brcmf_sdio_dev *sdiodev = dev_get_drvdata(dev_id);
++
++	brcmf_dbg(INTR, "oob intr triggered\n");
++
++	/*
++	 * out-of-band interrupt is level-triggered which won't
++	 * be cleared until dpc
++	 */
++	if (sdiodev->irq_en) {
++		disable_irq_nosync(irq);
++		sdiodev->irq_en = false;
++	}
++
++	brcmf_sdbrcm_isr(sdiodev->bus);
++
++	return IRQ_HANDLED;
++}
++
++int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev)
++{
++	int ret = 0;
++	u8 data;
++	unsigned long flags;
++
++	brcmf_dbg(TRACE, "Entering\n");
++
++	brcmf_dbg(ERROR, "requesting irq %d\n", sdiodev->irq);
++	ret = request_irq(sdiodev->irq, brcmf_sdio_irqhandler,
++			  sdiodev->irq_flags, "brcmf_oob_intr",
++			  &sdiodev->func[1]->card->dev);
++	if (ret != 0)
++		return ret;
++	spin_lock_init(&sdiodev->irq_en_lock);
++	spin_lock_irqsave(&sdiodev->irq_en_lock, flags);
++	sdiodev->irq_en = true;
++	spin_unlock_irqrestore(&sdiodev->irq_en_lock, flags);
++
++	ret = enable_irq_wake(sdiodev->irq);
++	if (ret != 0)
++		return ret;
++	sdiodev->irq_wake = true;
++
++	/* must configure SDIO_CCCR_IENx to enable irq */
++	data = brcmf_sdio_regrb(sdiodev, SDIO_CCCR_IENx, &ret);
++	data |= 1 << SDIO_FUNC_1 | 1 << SDIO_FUNC_2 | 1;
++	brcmf_sdio_regwb(sdiodev, SDIO_CCCR_IENx, data, &ret);
++
++	/* redirect, configure and enable io for interrupt signal */
++	data = SDIO_SEPINT_MASK | SDIO_SEPINT_OE;
++	if (sdiodev->irq_flags & IRQF_TRIGGER_HIGH)
++		data |= SDIO_SEPINT_ACT_HI;
++	brcmf_sdio_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, data, &ret);
++
++	return 0;
++}
++
++int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev)
++{
++	brcmf_dbg(TRACE, "Entering\n");
++
++	brcmf_sdio_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, 0, NULL);
++	brcmf_sdio_regwb(sdiodev, SDIO_CCCR_IENx, 0, NULL);
++
++	if (sdiodev->irq_wake) {
++		disable_irq_wake(sdiodev->irq);
++		sdiodev->irq_wake = false;
++	}
++	free_irq(sdiodev->irq, &sdiodev->func[1]->card->dev);
++	sdiodev->irq_en = false;
++
++	return 0;
++}
++#else		/* CONFIG_BRCMFMAC_SDIO_OOB */
++static void brcmf_sdio_irqhandler(struct sdio_func *func)
++{
++	struct brcmf_sdio_dev *sdiodev = dev_get_drvdata(&func->card->dev);
++
++	brcmf_dbg(INTR, "ib intr triggered\n");
++
++	sdio_release_host(sdiodev->func[1]);
++	brcmf_sdbrcm_isr(sdiodev->bus);
++	sdio_claim_host(sdiodev->func[1]);
++}
++
++/* dummy handler for SDIO function 2 interrupt */
++static void brcmf_sdio_dummy_irqhandler(struct sdio_func *func)
++{
++}
++
++int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev)
++{
++	brcmf_dbg(TRACE, "Entering\n");
++
++	sdio_claim_host(sdiodev->func[1]);
++	sdio_claim_irq(sdiodev->func[1], brcmf_sdio_irqhandler);
++	sdio_claim_irq(sdiodev->func[2], brcmf_sdio_dummy_irqhandler);
++	sdio_release_host(sdiodev->func[1]);
++
++	return 0;
++}
++
++int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev)
++{
++	brcmf_dbg(TRACE, "Entering\n");
++
++	sdio_claim_host(sdiodev->func[1]);
++	sdio_release_irq(sdiodev->func[2]);
++	sdio_release_irq(sdiodev->func[1]);
++	sdio_release_host(sdiodev->func[1]);
++
++	return 0;
++}
++#endif		/* CONFIG_BRCMFMAC_SDIO_OOB */
++
++int
++brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address)
++{
++	int err = 0, i;
++	u8 addr[3];
++	s32 retry;
++
++	addr[0] = (address >> 8) & SBSDIO_SBADDRLOW_MASK;
++	addr[1] = (address >> 16) & SBSDIO_SBADDRMID_MASK;
++	addr[2] = (address >> 24) & SBSDIO_SBADDRHIGH_MASK;
++
++	for (i = 0; i < 3; i++) {
++		retry = 0;
++		do {
++			if (retry)
++				usleep_range(1000, 2000);
++			err = brcmf_sdioh_request_byte(sdiodev, SDIOH_WRITE,
++					SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW + i,
++					&addr[i]);
++		} while (err != 0 && retry++ < SDIOH_API_ACCESS_RETRY_LIMIT);
++
++		if (err) {
++			brcmf_dbg(ERROR, "failed at addr:0x%0x\n",
++				  SBSDIO_FUNC1_SBADDRLOW + i);
++			break;
++		}
++	}
++
++	return err;
++}
++
++static int
++brcmf_sdio_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr,
++			void *data, bool write)
++{
++	u8 func_num, reg_size;
++	u32 bar;
++	s32 retry = 0;
++	int ret;
++
++	/*
++	 * figure out how to read the register based on address range
++	 * 0x00 ~ 0x7FF: function 0 CCCR and FBR
++	 * 0x10000 ~ 0x1FFFF: function 1 miscellaneous registers
++	 * The rest: function 1 silicon backplane core registers
++	 */
++	if ((addr & ~REG_F0_REG_MASK) == 0) {
++		func_num = SDIO_FUNC_0;
++		reg_size = 1;
++	} else if ((addr & ~REG_F1_MISC_MASK) == 0) {
++		func_num = SDIO_FUNC_1;
++		reg_size = 1;
++	} else {
++		func_num = SDIO_FUNC_1;
++		reg_size = 4;
++
++		/* Set the window for SB core register */
++		bar = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
++		if (bar != sdiodev->sbwad) {
++			ret = brcmf_sdcard_set_sbaddr_window(sdiodev, bar);
++			if (ret != 0) {
++				memset(data, 0xFF, reg_size);
++				return ret;
++			}
++			sdiodev->sbwad = bar;
++		}
++		addr &= SBSDIO_SB_OFT_ADDR_MASK;
++		addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
++	}
++
++	do {
++		if (!write)
++			memset(data, 0, reg_size);
++		if (retry)	/* wait for 1 ms till bus get settled down */
++			usleep_range(1000, 2000);
++		if (reg_size == 1)
++			ret = brcmf_sdioh_request_byte(sdiodev, write,
++						       func_num, addr, data);
++		else
++			ret = brcmf_sdioh_request_word(sdiodev, write,
++						       func_num, addr, data, 4);
++	} while (ret != 0 && retry++ < SDIOH_API_ACCESS_RETRY_LIMIT);
++
++	if (ret != 0)
++		brcmf_dbg(ERROR, "failed with %d\n", ret);
++
++	return ret;
++}
++
++u8 brcmf_sdio_regrb(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret)
++{
++	u8 data;
++	int retval;
++
++	brcmf_dbg(INFO, "addr:0x%08x\n", addr);
++	retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, false);
++	brcmf_dbg(INFO, "data:0x%02x\n", data);
++
++	if (ret)
++		*ret = retval;
++
++	return data;
++}
++
++u32 brcmf_sdio_regrl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret)
++{
++	u32 data;
++	int retval;
++
++	brcmf_dbg(INFO, "addr:0x%08x\n", addr);
++	retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, false);
++	brcmf_dbg(INFO, "data:0x%08x\n", data);
++
++	if (ret)
++		*ret = retval;
++
++	return data;
++}
++
++void brcmf_sdio_regwb(struct brcmf_sdio_dev *sdiodev, u32 addr,
++		      u8 data, int *ret)
++{
++	int retval;
++
++	brcmf_dbg(INFO, "addr:0x%08x, data:0x%02x\n", addr, data);
++	retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, true);
++
++	if (ret)
++		*ret = retval;
++}
++
++void brcmf_sdio_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr,
++		      u32 data, int *ret)
++{
++	int retval;
++
++	brcmf_dbg(INFO, "addr:0x%08x, data:0x%08x\n", addr, data);
++	retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, true);
++
++	if (ret)
++		*ret = retval;
++}
++
++static int brcmf_sdcard_recv_prepare(struct brcmf_sdio_dev *sdiodev, uint fn,
++				     uint flags, uint width, u32 *addr)
++{
++	uint bar0 = *addr & ~SBSDIO_SB_OFT_ADDR_MASK;
++	int err = 0;
++
++	/* Async not implemented yet */
++	if (flags & SDIO_REQ_ASYNC)
++		return -ENOTSUPP;
++
++	if (bar0 != sdiodev->sbwad) {
++		err = brcmf_sdcard_set_sbaddr_window(sdiodev, bar0);
++		if (err)
++			return err;
++
++		sdiodev->sbwad = bar0;
++	}
++
++	*addr &= SBSDIO_SB_OFT_ADDR_MASK;
++
++	if (width == 4)
++		*addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
++
++	return 0;
++}
++
++int
++brcmf_sdcard_recv_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
++		      uint flags, u8 *buf, uint nbytes)
++{
++	struct sk_buff *mypkt;
++	int err;
++
++	mypkt = brcmu_pkt_buf_get_skb(nbytes);
++	if (!mypkt) {
++		brcmf_dbg(ERROR, "brcmu_pkt_buf_get_skb failed: len %d\n",
++			  nbytes);
++		return -EIO;
++	}
++
++	err = brcmf_sdcard_recv_pkt(sdiodev, addr, fn, flags, mypkt);
++	if (!err)
++		memcpy(buf, mypkt->data, nbytes);
++
++	brcmu_pkt_buf_free_skb(mypkt);
++	return err;
++}
++
++int
++brcmf_sdcard_recv_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
++		      uint flags, struct sk_buff *pkt)
++{
++	uint incr_fix;
++	uint width;
++	int err = 0;
++
++	brcmf_dbg(INFO, "fun = %d, addr = 0x%x, size = %d\n",
++		  fn, addr, pkt->len);
++
++	width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
++	err = brcmf_sdcard_recv_prepare(sdiodev, fn, flags, width, &addr);
++	if (err)
++		return err;
++
++	incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC;
++	err = brcmf_sdioh_request_buffer(sdiodev, incr_fix, SDIOH_READ,
++					 fn, addr, pkt);
++
++	return err;
++}
++
++int brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
++			    uint flags, struct sk_buff_head *pktq)
++{
++	uint incr_fix;
++	uint width;
++	int err = 0;
++
++	brcmf_dbg(INFO, "fun = %d, addr = 0x%x, size = %d\n",
++		  fn, addr, pktq->qlen);
++
++	width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
++	err = brcmf_sdcard_recv_prepare(sdiodev, fn, flags, width, &addr);
++	if (err)
++		return err;
++
++	incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC;
++	err = brcmf_sdioh_request_chain(sdiodev, incr_fix, SDIOH_READ, fn, addr,
++					pktq);
++
++	return err;
++}
++
++int
++brcmf_sdcard_send_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
++		      uint flags, u8 *buf, uint nbytes)
++{
++	struct sk_buff *mypkt;
++	int err;
++
++	mypkt = brcmu_pkt_buf_get_skb(nbytes);
++	if (!mypkt) {
++		brcmf_dbg(ERROR, "brcmu_pkt_buf_get_skb failed: len %d\n",
++			  nbytes);
++		return -EIO;
++	}
++
++	memcpy(mypkt->data, buf, nbytes);
++	err = brcmf_sdcard_send_pkt(sdiodev, addr, fn, flags, mypkt);
++
++	brcmu_pkt_buf_free_skb(mypkt);
++	return err;
++
++}
++
++int
++brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
++		      uint flags, struct sk_buff *pkt)
++{
++	uint incr_fix;
++	uint width;
++	uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
++	int err = 0;
++
++	brcmf_dbg(INFO, "fun = %d, addr = 0x%x, size = %d\n",
++		  fn, addr, pkt->len);
++
++	/* Async not implemented yet */
++	if (flags & SDIO_REQ_ASYNC)
++		return -ENOTSUPP;
++
++	if (bar0 != sdiodev->sbwad) {
++		err = brcmf_sdcard_set_sbaddr_window(sdiodev, bar0);
++		if (err)
++			return err;
++
++		sdiodev->sbwad = bar0;
++	}
++
++	addr &= SBSDIO_SB_OFT_ADDR_MASK;
++
++	incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC;
++	width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
++	if (width == 4)
++		addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
++
++	return brcmf_sdioh_request_buffer(sdiodev, incr_fix, SDIOH_WRITE, fn,
++					  addr, pkt);
++}
++
++int brcmf_sdcard_rwdata(struct brcmf_sdio_dev *sdiodev, uint rw, u32 addr,
++			u8 *buf, uint nbytes)
++{
++	struct sk_buff *mypkt;
++	bool write = rw ? SDIOH_WRITE : SDIOH_READ;
++	int err;
++
++	addr &= SBSDIO_SB_OFT_ADDR_MASK;
++	addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
++
++	mypkt = brcmu_pkt_buf_get_skb(nbytes);
++	if (!mypkt) {
++		brcmf_dbg(ERROR, "brcmu_pkt_buf_get_skb failed: len %d\n",
++			  nbytes);
++		return -EIO;
++	}
++
++	/* For a write, copy the buffer data into the packet. */
++	if (write)
++		memcpy(mypkt->data, buf, nbytes);
++
++	err = brcmf_sdioh_request_buffer(sdiodev, SDIOH_DATA_INC, write,
++					 SDIO_FUNC_1, addr, mypkt);
++
++	/* For a read, copy the packet data back to the buffer. */
++	if (!err && !write)
++		memcpy(buf, mypkt->data, nbytes);
++
++	brcmu_pkt_buf_free_skb(mypkt);
++	return err;
++}
++
++int brcmf_sdcard_abort(struct brcmf_sdio_dev *sdiodev, uint fn)
++{
++	char t_func = (char)fn;
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* issue abort cmd52 command through F0 */
++	brcmf_sdioh_request_byte(sdiodev, SDIOH_WRITE, SDIO_FUNC_0,
++				 SDIO_CCCR_ABORT, &t_func);
++
++	brcmf_dbg(TRACE, "Exit\n");
++	return 0;
++}
++
++int brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
++{
++	u32 regs = 0;
++	int ret = 0;
++
++	ret = brcmf_sdioh_attach(sdiodev);
++	if (ret)
++		goto out;
++
++	regs = SI_ENUM_BASE;
++
++	/* Report the BAR, to fix if needed */
++	sdiodev->sbwad = SI_ENUM_BASE;
++
++	/* try to attach to the target device */
++	sdiodev->bus = brcmf_sdbrcm_probe(regs, sdiodev);
++	if (!sdiodev->bus) {
++		brcmf_dbg(ERROR, "device attach failed\n");
++		ret = -ENODEV;
++		goto out;
++	}
++
++out:
++	if (ret)
++		brcmf_sdio_remove(sdiodev);
++
++	return ret;
++}
++EXPORT_SYMBOL(brcmf_sdio_probe);
++
++int brcmf_sdio_remove(struct brcmf_sdio_dev *sdiodev)
++{
++	if (sdiodev->bus) {
++		brcmf_sdbrcm_disconnect(sdiodev->bus);
++		sdiodev->bus = NULL;
++	}
++
++	brcmf_sdioh_detach(sdiodev);
++
++	sdiodev->sbwad = 0;
++
++	return 0;
++}
++EXPORT_SYMBOL(brcmf_sdio_remove);
++
++void brcmf_sdio_wdtmr_enable(struct brcmf_sdio_dev *sdiodev, bool enable)
++{
++	if (enable)
++		brcmf_sdbrcm_wd_timer(sdiodev->bus, BRCMF_WD_POLL_MS);
++	else
++		brcmf_sdbrcm_wd_timer(sdiodev->bus, 0);
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
+new file mode 100644
+index 0000000..391a721
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
+@@ -0,0 +1,703 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#undef pr_fmt
++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
++
++#include <linux/version.h>
++#include <linux/types.h>
++#include <linux/netdevice.h>
++#include <linux/printk.h>
++#include <linux/mmc/sdio.h>
++#include <linux/mmc/core.h>
++#include <linux/mmc/sdio_func.h>
++#include <linux/mmc/sdio_ids.h>
++#include <linux/mmc/card.h>
++#include <linux/suspend.h>
++#include <linux/errno.h>
++#include <linux/sched.h>	/* request_irq() */
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <net/cfg80211.h>
++
++#include <defs.h>
++#include <brcm_hw_ids.h>
++#include <brcmu_utils.h>
++#include <brcmu_wifi.h>
++#include "sdio_host.h"
++#include "dhd_dbg.h"
++#include "dhd_bus.h"
++
++#define SDIO_VENDOR_ID_BROADCOM		0x02d0
++
++#define DMA_ALIGN_MASK	0x03
++
++#define SDIO_DEVICE_ID_BROADCOM_4329	0x4329
++#define SDIO_DEVICE_ID_BROADCOM_4330	0x4330
++
++#define SDIO_FUNC1_BLOCKSIZE		64
++#define SDIO_FUNC2_BLOCKSIZE		512
++
++/* devices we support, null terminated */
++static const struct sdio_device_id brcmf_sdmmc_ids[] = {
++	{SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4329)},
++	{SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4330)},
++	{ /* end: all zeroes */ },
++};
++MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids);
++
++#ifdef CONFIG_BRCMFMAC_SDIO_OOB
++static struct list_head oobirq_lh;
++struct brcmf_sdio_oobirq {
++	unsigned int irq;
++	unsigned long flags;
++	struct list_head list;
++};
++#endif		/* CONFIG_BRCMFMAC_SDIO_OOB */
++
++static bool
++brcmf_pm_resume_error(struct brcmf_sdio_dev *sdiodev)
++{
++	bool is_err = false;
++#if defined(CONFIG_PM_SLEEP) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34))
++	is_err = atomic_read(&sdiodev->suspend);
++#endif
++	return is_err;
++}
++
++static void
++brcmf_pm_resume_wait(struct brcmf_sdio_dev *sdiodev, wait_queue_head_t *wq)
++{
++#if defined(CONFIG_PM_SLEEP) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34))
++	int retry = 0;
++	while (atomic_read(&sdiodev->suspend) && retry++ != 30)
++		wait_event_timeout(*wq, false, HZ/100);
++#endif
++}
++
++static inline int brcmf_sdioh_f0_write_byte(struct brcmf_sdio_dev *sdiodev,
++					    uint regaddr, u8 *byte)
++{
++	struct sdio_func *sdfunc = sdiodev->func[0];
++	int err_ret;
++
++	/*
++	 * Can only directly write to some F0 registers.
++	 * Handle F2 enable/disable and Abort command
++	 * as a special case.
++	 */
++	if (regaddr == SDIO_CCCR_IOEx) {
++		sdfunc = sdiodev->func[2];
++		if (sdfunc) {
++			sdio_claim_host(sdfunc);
++			if (*byte & SDIO_FUNC_ENABLE_2) {
++				/* Enable Function 2 */
++				err_ret = sdio_enable_func(sdfunc);
++				if (err_ret)
++					brcmf_dbg(ERROR,
++						  "enable F2 failed:%d\n",
++						  err_ret);
++			} else {
++				/* Disable Function 2 */
++				err_ret = sdio_disable_func(sdfunc);
++				if (err_ret)
++					brcmf_dbg(ERROR,
++						  "Disable F2 failed:%d\n",
++						  err_ret);
++			}
++			sdio_release_host(sdfunc);
++		}
++	} else if ((regaddr == SDIO_CCCR_ABORT) ||
++		   (regaddr == SDIO_CCCR_IENx)) {
++		sdfunc = kmemdup(sdiodev->func[0], sizeof(struct sdio_func),
++				 GFP_KERNEL);
++		if (!sdfunc)
++			return -ENOMEM;
++		sdfunc->num = 0;
++		sdio_claim_host(sdfunc);
++		sdio_writeb(sdfunc, *byte, regaddr, &err_ret);
++		sdio_release_host(sdfunc);
++		kfree(sdfunc);
++	} else if (regaddr < 0xF0) {
++		brcmf_dbg(ERROR, "F0 Wr:0x%02x: write disallowed\n", regaddr);
++		err_ret = -EPERM;
++	} else {
++		sdio_claim_host(sdfunc);
++		sdio_f0_writeb(sdfunc, *byte, regaddr, &err_ret);
++		sdio_release_host(sdfunc);
++	}
++
++	return err_ret;
++}
++
++int brcmf_sdioh_request_byte(struct brcmf_sdio_dev *sdiodev, uint rw, uint func,
++			     uint regaddr, u8 *byte)
++{
++	int err_ret;
++
++	brcmf_dbg(INFO, "rw=%d, func=%d, addr=0x%05x\n", rw, func, regaddr);
++
++	brcmf_pm_resume_wait(sdiodev, &sdiodev->request_byte_wait);
++	if (brcmf_pm_resume_error(sdiodev))
++		return -EIO;
++
++	if (rw && func == 0) {
++		/* handle F0 separately */
++		err_ret = brcmf_sdioh_f0_write_byte(sdiodev, regaddr, byte);
++	} else {
++		sdio_claim_host(sdiodev->func[func]);
++		if (rw) /* CMD52 Write */
++			sdio_writeb(sdiodev->func[func], *byte, regaddr,
++				    &err_ret);
++		else if (func == 0) {
++			*byte = sdio_f0_readb(sdiodev->func[func], regaddr,
++					      &err_ret);
++		} else {
++			*byte = sdio_readb(sdiodev->func[func], regaddr,
++					   &err_ret);
++		}
++		sdio_release_host(sdiodev->func[func]);
++	}
++
++	if (err_ret)
++		brcmf_dbg(ERROR, "Failed to %s byte F%d:@0x%05x=%02x, Err: %d\n",
++			  rw ? "write" : "read", func, regaddr, *byte, err_ret);
++
++	return err_ret;
++}
++
++int brcmf_sdioh_request_word(struct brcmf_sdio_dev *sdiodev,
++			     uint rw, uint func, uint addr, u32 *word,
++			     uint nbytes)
++{
++	int err_ret = -EIO;
++
++	if (func == 0) {
++		brcmf_dbg(ERROR, "Only CMD52 allowed to F0\n");
++		return -EINVAL;
++	}
++
++	brcmf_dbg(INFO, "rw=%d, func=%d, addr=0x%05x, nbytes=%d\n",
++		  rw, func, addr, nbytes);
++
++	brcmf_pm_resume_wait(sdiodev, &sdiodev->request_word_wait);
++	if (brcmf_pm_resume_error(sdiodev))
++		return -EIO;
++	/* Claim host controller */
++	sdio_claim_host(sdiodev->func[func]);
++
++	if (rw) {		/* CMD52 Write */
++		if (nbytes == 4)
++			sdio_writel(sdiodev->func[func], *word, addr,
++				    &err_ret);
++		else if (nbytes == 2)
++			sdio_writew(sdiodev->func[func], (*word & 0xFFFF),
++				    addr, &err_ret);
++		else
++			brcmf_dbg(ERROR, "Invalid nbytes: %d\n", nbytes);
++	} else {		/* CMD52 Read */
++		if (nbytes == 4)
++			*word = sdio_readl(sdiodev->func[func], addr, &err_ret);
++		else if (nbytes == 2)
++			*word = sdio_readw(sdiodev->func[func], addr,
++					   &err_ret) & 0xFFFF;
++		else
++			brcmf_dbg(ERROR, "Invalid nbytes: %d\n", nbytes);
++	}
++
++	/* Release host controller */
++	sdio_release_host(sdiodev->func[func]);
++
++	if (err_ret)
++		brcmf_dbg(ERROR, "Failed to %s word, Err: 0x%08x\n",
++			  rw ? "write" : "read", err_ret);
++
++	return err_ret;
++}
++
++/* precondition: host controller is claimed */
++static int
++brcmf_sdioh_request_data(struct brcmf_sdio_dev *sdiodev, uint write, bool fifo,
++			 uint func, uint addr, struct sk_buff *pkt, uint pktlen)
++{
++	int err_ret = 0;
++
++	if ((write) && (!fifo)) {
++		err_ret = sdio_memcpy_toio(sdiodev->func[func], addr,
++					   ((u8 *) (pkt->data)), pktlen);
++	} else if (write) {
++		err_ret = sdio_memcpy_toio(sdiodev->func[func], addr,
++					   ((u8 *) (pkt->data)), pktlen);
++	} else if (fifo) {
++		err_ret = sdio_readsb(sdiodev->func[func],
++				      ((u8 *) (pkt->data)), addr, pktlen);
++	} else {
++		err_ret = sdio_memcpy_fromio(sdiodev->func[func],
++					     ((u8 *) (pkt->data)),
++					     addr, pktlen);
++	}
++
++	return err_ret;
++}
++
++/*
++ * This function takes a queue of packets. The packets on the queue
++ * are assumed to be properly aligned by the caller.
++ */
++int
++brcmf_sdioh_request_chain(struct brcmf_sdio_dev *sdiodev, uint fix_inc,
++			  uint write, uint func, uint addr,
++			  struct sk_buff_head *pktq)
++{
++	bool fifo = (fix_inc == SDIOH_DATA_FIX);
++	u32 SGCount = 0;
++	int err_ret = 0;
++
++	struct sk_buff *pkt;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	brcmf_pm_resume_wait(sdiodev, &sdiodev->request_chain_wait);
++	if (brcmf_pm_resume_error(sdiodev))
++		return -EIO;
++
++	/* Claim host controller */
++	sdio_claim_host(sdiodev->func[func]);
++
++	skb_queue_walk(pktq, pkt) {
++		uint pkt_len = pkt->len;
++		pkt_len += 3;
++		pkt_len &= 0xFFFFFFFC;
++
++		err_ret = brcmf_sdioh_request_data(sdiodev, write, fifo, func,
++						   addr, pkt, pkt_len);
++		if (err_ret) {
++			brcmf_dbg(ERROR, "%s FAILED %p[%d], addr=0x%05x, pkt_len=%d, ERR=0x%08x\n",
++				  write ? "TX" : "RX", pkt, SGCount, addr,
++				  pkt_len, err_ret);
++		} else {
++			brcmf_dbg(TRACE, "%s xfr'd %p[%d], addr=0x%05x, len=%d\n",
++				  write ? "TX" : "RX", pkt, SGCount, addr,
++				  pkt_len);
++		}
++		if (!fifo)
++			addr += pkt_len;
++
++		SGCount++;
++	}
++
++	/* Release host controller */
++	sdio_release_host(sdiodev->func[func]);
++
++	brcmf_dbg(TRACE, "Exit\n");
++	return err_ret;
++}
++
++/*
++ * This function takes a single DMA-able packet.
++ */
++int brcmf_sdioh_request_buffer(struct brcmf_sdio_dev *sdiodev,
++			       uint fix_inc, uint write, uint func, uint addr,
++			       struct sk_buff *pkt)
++{
++	int status;
++	uint pkt_len;
++	bool fifo = (fix_inc == SDIOH_DATA_FIX);
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	if (pkt == NULL)
++		return -EINVAL;
++	pkt_len = pkt->len;
++
++	brcmf_pm_resume_wait(sdiodev, &sdiodev->request_buffer_wait);
++	if (brcmf_pm_resume_error(sdiodev))
++		return -EIO;
++
++	/* Claim host controller */
++	sdio_claim_host(sdiodev->func[func]);
++
++	pkt_len += 3;
++	pkt_len &= (uint)~3;
++
++	status = brcmf_sdioh_request_data(sdiodev, write, fifo, func,
++					   addr, pkt, pkt_len);
++	if (status) {
++		brcmf_dbg(ERROR, "%s FAILED %p, addr=0x%05x, pkt_len=%d, ERR=0x%08x\n",
++			  write ? "TX" : "RX", pkt, addr, pkt_len, status);
++	} else {
++		brcmf_dbg(TRACE, "%s xfr'd %p, addr=0x%05x, len=%d\n",
++			  write ? "TX" : "RX", pkt, addr, pkt_len);
++	}
++
++	/* Release host controller */
++	sdio_release_host(sdiodev->func[func]);
++
++	return status;
++}
++
++static int brcmf_sdioh_get_cisaddr(struct brcmf_sdio_dev *sdiodev, u32 regaddr)
++{
++	/* read 24 bits and return valid 17 bit addr */
++	int i, ret;
++	u32 scratch, regdata;
++	__le32 scratch_le;
++	u8 *ptr = (u8 *)&scratch_le;
++
++	for (i = 0; i < 3; i++) {
++		regdata = brcmf_sdio_regrl(sdiodev, regaddr, &ret);
++		if (ret != 0)
++			brcmf_dbg(ERROR, "Can't read!\n");
++
++		*ptr++ = (u8) regdata;
++		regaddr++;
++	}
++
++	/* Only the lower 17-bits are valid */
++	scratch = le32_to_cpu(scratch_le);
++	scratch &= 0x0001FFFF;
++	return scratch;
++}
++
++static int brcmf_sdioh_enablefuncs(struct brcmf_sdio_dev *sdiodev)
++{
++	int err_ret;
++	u32 fbraddr;
++	u8 func;
++
++	brcmf_dbg(TRACE, "\n");
++
++	/* Get the Card's common CIS address */
++	sdiodev->func_cis_ptr[0] = brcmf_sdioh_get_cisaddr(sdiodev,
++							   SDIO_CCCR_CIS);
++	brcmf_dbg(INFO, "Card's Common CIS Ptr = 0x%x\n",
++		  sdiodev->func_cis_ptr[0]);
++
++	/* Get the Card's function CIS (for each function) */
++	for (fbraddr = SDIO_FBR_BASE(1), func = 1;
++	     func <= sdiodev->num_funcs; func++, fbraddr += SDIOD_FBR_SIZE) {
++		sdiodev->func_cis_ptr[func] =
++		    brcmf_sdioh_get_cisaddr(sdiodev, SDIO_FBR_CIS + fbraddr);
++		brcmf_dbg(INFO, "Function %d CIS Ptr = 0x%x\n",
++			  func, sdiodev->func_cis_ptr[func]);
++	}
++
++	/* Enable Function 1 */
++	sdio_claim_host(sdiodev->func[1]);
++	err_ret = sdio_enable_func(sdiodev->func[1]);
++	sdio_release_host(sdiodev->func[1]);
++	if (err_ret)
++		brcmf_dbg(ERROR, "Failed to enable F1 Err: 0x%08x\n", err_ret);
++
++	return false;
++}
++
++/*
++ *	Public entry points & extern's
++ */
++int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev)
++{
++	int err_ret = 0;
++
++	brcmf_dbg(TRACE, "\n");
++
++	sdiodev->num_funcs = 2;
++
++	sdio_claim_host(sdiodev->func[1]);
++	err_ret = sdio_set_block_size(sdiodev->func[1], SDIO_FUNC1_BLOCKSIZE);
++	sdio_release_host(sdiodev->func[1]);
++	if (err_ret) {
++		brcmf_dbg(ERROR, "Failed to set F1 blocksize\n");
++		goto out;
++	}
++
++	sdio_claim_host(sdiodev->func[2]);
++	err_ret = sdio_set_block_size(sdiodev->func[2], SDIO_FUNC2_BLOCKSIZE);
++	sdio_release_host(sdiodev->func[2]);
++	if (err_ret) {
++		brcmf_dbg(ERROR, "Failed to set F2 blocksize\n");
++		goto out;
++	}
++
++	brcmf_sdioh_enablefuncs(sdiodev);
++
++out:
++	brcmf_dbg(TRACE, "Done\n");
++	return err_ret;
++}
++
++void brcmf_sdioh_detach(struct brcmf_sdio_dev *sdiodev)
++{
++	brcmf_dbg(TRACE, "\n");
++
++	/* Disable Function 2 */
++	sdio_claim_host(sdiodev->func[2]);
++	sdio_disable_func(sdiodev->func[2]);
++	sdio_release_host(sdiodev->func[2]);
++
++	/* Disable Function 1 */
++	sdio_claim_host(sdiodev->func[1]);
++	sdio_disable_func(sdiodev->func[1]);
++	sdio_release_host(sdiodev->func[1]);
++
++}
++
++#ifdef CONFIG_BRCMFMAC_SDIO_OOB
++static int brcmf_sdio_getintrcfg(struct brcmf_sdio_dev *sdiodev)
++{
++	struct brcmf_sdio_oobirq *oobirq_entry;
++
++	if (list_empty(&oobirq_lh)) {
++		brcmf_dbg(ERROR, "no valid oob irq resource\n");
++		return -ENXIO;
++	}
++
++	oobirq_entry = list_first_entry(&oobirq_lh, struct brcmf_sdio_oobirq,
++					list);
++
++	sdiodev->irq = oobirq_entry->irq;
++	sdiodev->irq_flags = oobirq_entry->flags;
++	list_del(&oobirq_entry->list);
++	kfree(oobirq_entry);
++
++	return 0;
++}
++#else
++static inline int brcmf_sdio_getintrcfg(struct brcmf_sdio_dev *sdiodev)
++{
++	return 0;
++}
++#endif		/* CONFIG_BRCMFMAC_SDIO_OOB */
++
++static int brcmf_ops_sdio_probe(struct sdio_func *func,
++			      const struct sdio_device_id *id)
++{
++	int ret = 0;
++	struct brcmf_sdio_dev *sdiodev;
++	struct brcmf_bus *bus_if;
++
++	brcmf_dbg(TRACE, "Enter\n");
++	brcmf_dbg(TRACE, "func->class=%x\n", func->class);
++	brcmf_dbg(TRACE, "sdio_vendor: 0x%04x\n", func->vendor);
++	brcmf_dbg(TRACE, "sdio_device: 0x%04x\n", func->device);
++	brcmf_dbg(TRACE, "Function#: 0x%04x\n", func->num);
++
++	if (func->num == 1) {
++		if (dev_get_drvdata(&func->card->dev)) {
++			brcmf_dbg(ERROR, "card private drvdata occupied\n");
++			return -ENXIO;
++		}
++		bus_if = kzalloc(sizeof(struct brcmf_bus), GFP_KERNEL);
++		if (!bus_if)
++			return -ENOMEM;
++		sdiodev = kzalloc(sizeof(struct brcmf_sdio_dev), GFP_KERNEL);
++		if (!sdiodev) {
++			kfree(bus_if);
++			return -ENOMEM;
++		}
++		sdiodev->func[0] = func;
++		sdiodev->func[1] = func;
++		sdiodev->bus_if = bus_if;
++		bus_if->bus_priv.sdio = sdiodev;
++		bus_if->type = SDIO_BUS;
++		bus_if->align = BRCMF_SDALIGN;
++		dev_set_drvdata(&func->card->dev, sdiodev);
++
++		atomic_set(&sdiodev->suspend, false);
++		init_waitqueue_head(&sdiodev->request_byte_wait);
++		init_waitqueue_head(&sdiodev->request_word_wait);
++		init_waitqueue_head(&sdiodev->request_chain_wait);
++		init_waitqueue_head(&sdiodev->request_buffer_wait);
++	}
++
++	if (func->num == 2) {
++		sdiodev = dev_get_drvdata(&func->card->dev);
++		if ((!sdiodev) || (sdiodev->func[1]->card != func->card))
++			return -ENODEV;
++
++		ret = brcmf_sdio_getintrcfg(sdiodev);
++		if (ret)
++			return ret;
++		sdiodev->func[2] = func;
++
++		bus_if = sdiodev->bus_if;
++		sdiodev->dev = &func->dev;
++		dev_set_drvdata(&func->dev, bus_if);
++
++		brcmf_dbg(TRACE, "F2 found, calling brcmf_sdio_probe...\n");
++		ret = brcmf_sdio_probe(sdiodev);
++	}
++
++	return ret;
++}
++
++static void brcmf_ops_sdio_remove(struct sdio_func *func)
++{
++	struct brcmf_bus *bus_if;
++	struct brcmf_sdio_dev *sdiodev;
++	brcmf_dbg(TRACE, "Enter\n");
++	brcmf_dbg(INFO, "func->class=%x\n", func->class);
++	brcmf_dbg(INFO, "sdio_vendor: 0x%04x\n", func->vendor);
++	brcmf_dbg(INFO, "sdio_device: 0x%04x\n", func->device);
++	brcmf_dbg(INFO, "Function#: 0x%04x\n", func->num);
++
++	if (func->num == 2) {
++		bus_if = dev_get_drvdata(&func->dev);
++		sdiodev = bus_if->bus_priv.sdio;
++		brcmf_dbg(TRACE, "F2 found, calling brcmf_sdio_remove...\n");
++		brcmf_sdio_remove(sdiodev);
++		dev_set_drvdata(&func->card->dev, NULL);
++		dev_set_drvdata(&func->dev, NULL);
++		kfree(bus_if);
++		kfree(sdiodev);
++	}
++}
++
++#if defined(CONFIG_PM_SLEEP) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34))
++static int brcmf_sdio_suspend(struct device *dev)
++{
++	mmc_pm_flag_t sdio_flags;
++	struct sdio_func *func = dev_to_sdio_func(dev);
++	struct brcmf_sdio_dev *sdiodev = dev_get_drvdata(&func->card->dev);
++	int ret = 0;
++
++	brcmf_dbg(TRACE, "\n");
++
++	atomic_set(&sdiodev->suspend, true);
++
++	sdio_flags = sdio_get_host_pm_caps(sdiodev->func[1]);
++	if (!(sdio_flags & MMC_PM_KEEP_POWER)) {
++		brcmf_dbg(ERROR, "Host can't keep power while suspended\n");
++		return -EINVAL;
++	}
++
++	ret = sdio_set_host_pm_flags(sdiodev->func[1], MMC_PM_KEEP_POWER);
++	if (ret) {
++		brcmf_dbg(ERROR, "Failed to set pm_flags\n");
++		return ret;
++	}
++
++	brcmf_sdio_wdtmr_enable(sdiodev, false);
++
++	return ret;
++}
++
++static int brcmf_sdio_resume(struct device *dev)
++{
++	struct sdio_func *func = dev_to_sdio_func(dev);
++	struct brcmf_sdio_dev *sdiodev = dev_get_drvdata(&func->card->dev);
++
++	brcmf_sdio_wdtmr_enable(sdiodev, true);
++	atomic_set(&sdiodev->suspend, false);
++	return 0;
++}
++
++static const struct dev_pm_ops brcmf_sdio_pm_ops = {
++	.suspend	= brcmf_sdio_suspend,
++	.resume		= brcmf_sdio_resume,
++};
++#endif	/* CONFIG_PM_SLEEP */
++
++static struct sdio_driver brcmf_sdmmc_driver = {
++	.probe = brcmf_ops_sdio_probe,
++	.remove = brcmf_ops_sdio_remove,
++	.name = "brcmfmac",
++	.id_table = brcmf_sdmmc_ids,
++#if defined(CONFIG_PM_SLEEP) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34))
++	.drv = {
++		.pm = &brcmf_sdio_pm_ops,
++	},
++#endif	/* CONFIG_PM_SLEEP */
++};
++
++#ifdef CONFIG_BRCMFMAC_SDIO_OOB
++static int brcmf_sdio_pd_probe(struct platform_device *pdev)
++{
++	struct resource *res;
++	struct brcmf_sdio_oobirq *oobirq_entry;
++	int i, ret;
++
++	INIT_LIST_HEAD(&oobirq_lh);
++
++	for (i = 0; ; i++) {
++		res = platform_get_resource(pdev, IORESOURCE_IRQ, i);
++		if (!res)
++			break;
++
++		oobirq_entry = kzalloc(sizeof(struct brcmf_sdio_oobirq),
++				       GFP_KERNEL);
++		oobirq_entry->irq = res->start;
++		oobirq_entry->flags = res->flags & IRQF_TRIGGER_MASK;
++		list_add_tail(&oobirq_entry->list, &oobirq_lh);
++	}
++	if (i == 0)
++		return -ENXIO;
++
++	ret = sdio_register_driver(&brcmf_sdmmc_driver);
++
++	if (ret)
++		brcmf_dbg(ERROR, "sdio_register_driver failed: %d\n", ret);
++
++	return ret;
++}
++
++static struct platform_driver brcmf_sdio_pd = {
++	.probe		= brcmf_sdio_pd_probe,
++	.driver		= {
++		.name	= "brcmf_sdio_pd"
++	}
++};
++
++void brcmf_sdio_exit(void)
++{
++	brcmf_dbg(TRACE, "Enter\n");
++
++	sdio_unregister_driver(&brcmf_sdmmc_driver);
++
++	platform_driver_unregister(&brcmf_sdio_pd);
++}
++
++void brcmf_sdio_init(void)
++{
++	int ret;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	ret = platform_driver_register(&brcmf_sdio_pd);
++
++	if (ret)
++		brcmf_dbg(ERROR, "platform_driver_register failed: %d\n", ret);
++}
++#else
++void brcmf_sdio_exit(void)
++{
++	brcmf_dbg(TRACE, "Enter\n");
++
++	sdio_unregister_driver(&brcmf_sdmmc_driver);
++}
++
++void brcmf_sdio_init(void)
++{
++	int ret;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	ret = sdio_register_driver(&brcmf_sdmmc_driver);
++
++	if (ret)
++		brcmf_dbg(ERROR, "sdio_register_driver failed: %d\n", ret);
++}
++#endif		/* CONFIG_BRCMFMAC_SDIO_OOB */
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
+new file mode 100644
+index 0000000..9f63701
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
+@@ -0,0 +1,669 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++/****************
++ * Common types *
++ */
++
++#ifndef _BRCMF_H_
++#define _BRCMF_H_
++
++#define BRCMF_VERSION_STR		"4.218.248.5"
++
++/*******************************************************************************
++ * IO codes that are interpreted by dongle firmware
++ ******************************************************************************/
++#define BRCMF_C_UP				2
++#define BRCMF_C_SET_PROMISC			10
++#define BRCMF_C_GET_RATE			12
++#define BRCMF_C_GET_INFRA			19
++#define BRCMF_C_SET_INFRA			20
++#define BRCMF_C_GET_AUTH			21
++#define BRCMF_C_SET_AUTH			22
++#define BRCMF_C_GET_BSSID			23
++#define BRCMF_C_GET_SSID			25
++#define BRCMF_C_SET_SSID			26
++#define BRCMF_C_GET_CHANNEL			29
++#define BRCMF_C_GET_SRL				31
++#define BRCMF_C_GET_LRL				33
++#define BRCMF_C_GET_RADIO			37
++#define BRCMF_C_SET_RADIO			38
++#define BRCMF_C_GET_PHYTYPE			39
++#define BRCMF_C_SET_KEY				45
++#define BRCMF_C_SET_PASSIVE_SCAN		49
++#define BRCMF_C_SCAN				50
++#define BRCMF_C_SCAN_RESULTS			51
++#define BRCMF_C_DISASSOC			52
++#define BRCMF_C_REASSOC				53
++#define BRCMF_C_SET_ROAM_TRIGGER		55
++#define BRCMF_C_SET_ROAM_DELTA			57
++#define BRCMF_C_GET_DTIMPRD			77
++#define BRCMF_C_SET_COUNTRY			84
++#define BRCMF_C_GET_PM				85
++#define BRCMF_C_SET_PM				86
++#define BRCMF_C_GET_AP				117
++#define BRCMF_C_SET_AP				118
++#define BRCMF_C_GET_RSSI			127
++#define BRCMF_C_GET_WSEC			133
++#define BRCMF_C_SET_WSEC			134
++#define BRCMF_C_GET_PHY_NOISE			135
++#define BRCMF_C_GET_BSS_INFO			136
++#define BRCMF_C_SET_SCAN_CHANNEL_TIME		185
++#define BRCMF_C_SET_SCAN_UNASSOC_TIME		187
++#define BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON	201
++#define BRCMF_C_GET_VALID_CHANNELS		217
++#define BRCMF_C_GET_KEY_PRIMARY			235
++#define BRCMF_C_SET_KEY_PRIMARY			236
++#define BRCMF_C_SET_SCAN_PASSIVE_TIME		258
++#define BRCMF_C_GET_VAR				262
++#define BRCMF_C_SET_VAR				263
++
++/* phy types (returned by WLC_GET_PHYTPE) */
++#define	WLC_PHY_TYPE_A		0
++#define	WLC_PHY_TYPE_B		1
++#define	WLC_PHY_TYPE_G		2
++#define	WLC_PHY_TYPE_N		4
++#define	WLC_PHY_TYPE_LP		5
++#define	WLC_PHY_TYPE_SSN	6
++#define	WLC_PHY_TYPE_HT		7
++#define	WLC_PHY_TYPE_LCN	8
++#define	WLC_PHY_TYPE_NULL	0xf
++
++#define BRCMF_EVENTING_MASK_LEN	16
++
++#define TOE_TX_CSUM_OL		0x00000001
++#define TOE_RX_CSUM_OL		0x00000002
++
++#define	BRCMF_BSS_INFO_VERSION	109 /* curr ver of brcmf_bss_info_le struct */
++
++/* size of brcmf_scan_params not including variable length array */
++#define BRCMF_SCAN_PARAMS_FIXED_SIZE 64
++
++/* masks for channel and ssid count */
++#define BRCMF_SCAN_PARAMS_COUNT_MASK 0x0000ffff
++#define BRCMF_SCAN_PARAMS_NSSID_SHIFT 16
++
++#define BRCMF_SCAN_ACTION_START      1
++#define BRCMF_SCAN_ACTION_CONTINUE   2
++#define WL_SCAN_ACTION_ABORT      3
++
++#define BRCMF_ISCAN_REQ_VERSION 1
++
++/* brcmf_iscan_results status values */
++#define BRCMF_SCAN_RESULTS_SUCCESS	0
++#define BRCMF_SCAN_RESULTS_PARTIAL	1
++#define BRCMF_SCAN_RESULTS_PENDING	2
++#define BRCMF_SCAN_RESULTS_ABORTED	3
++#define BRCMF_SCAN_RESULTS_NO_MEM	4
++
++/* Indicates this key is using soft encrypt */
++#define WL_SOFT_KEY	(1 << 0)
++/* primary (ie tx) key */
++#define BRCMF_PRIMARY_KEY	(1 << 1)
++/* Reserved for backward compat */
++#define WL_KF_RES_4	(1 << 4)
++/* Reserved for backward compat */
++#define WL_KF_RES_5	(1 << 5)
++/* Indicates a group key for a IBSS PEER */
++#define WL_IBSS_PEER_GROUP_KEY	(1 << 6)
++
++/* For supporting multiple interfaces */
++#define BRCMF_MAX_IFS	16
++
++#define DOT11_BSSTYPE_ANY			2
++#define DOT11_MAX_DEFAULT_KEYS	4
++
++#define BRCMF_EVENT_MSG_LINK		0x01
++#define BRCMF_EVENT_MSG_FLUSHTXQ	0x02
++#define BRCMF_EVENT_MSG_GROUP		0x04
++
++struct brcmf_event_msg {
++	__be16 version;
++	__be16 flags;
++	__be32 event_type;
++	__be32 status;
++	__be32 reason;
++	__be32 auth_type;
++	__be32 datalen;
++	u8 addr[ETH_ALEN];
++	char ifname[IFNAMSIZ];
++} __packed;
++
++struct brcm_ethhdr {
++	u16 subtype;
++	u16 length;
++	u8 version;
++	u8 oui[3];
++	u16 usr_subtype;
++} __packed;
++
++struct brcmf_event {
++	struct ethhdr eth;
++	struct brcm_ethhdr hdr;
++	struct brcmf_event_msg msg;
++} __packed;
++
++/* event codes sent by the dongle to this driver */
++#define BRCMF_E_SET_SSID			0
++#define BRCMF_E_JOIN				1
++#define BRCMF_E_START				2
++#define BRCMF_E_AUTH				3
++#define BRCMF_E_AUTH_IND			4
++#define BRCMF_E_DEAUTH				5
++#define BRCMF_E_DEAUTH_IND			6
++#define BRCMF_E_ASSOC				7
++#define BRCMF_E_ASSOC_IND			8
++#define BRCMF_E_REASSOC				9
++#define BRCMF_E_REASSOC_IND			10
++#define BRCMF_E_DISASSOC			11
++#define BRCMF_E_DISASSOC_IND			12
++#define BRCMF_E_QUIET_START			13
++#define BRCMF_E_QUIET_END			14
++#define BRCMF_E_BEACON_RX			15
++#define BRCMF_E_LINK				16
++#define BRCMF_E_MIC_ERROR			17
++#define BRCMF_E_NDIS_LINK			18
++#define BRCMF_E_ROAM				19
++#define BRCMF_E_TXFAIL				20
++#define BRCMF_E_PMKID_CACHE			21
++#define BRCMF_E_RETROGRADE_TSF			22
++#define BRCMF_E_PRUNE				23
++#define BRCMF_E_AUTOAUTH			24
++#define BRCMF_E_EAPOL_MSG			25
++#define BRCMF_E_SCAN_COMPLETE			26
++#define BRCMF_E_ADDTS_IND			27
++#define BRCMF_E_DELTS_IND			28
++#define BRCMF_E_BCNSENT_IND			29
++#define BRCMF_E_BCNRX_MSG			30
++#define BRCMF_E_BCNLOST_MSG			31
++#define BRCMF_E_ROAM_PREP			32
++#define BRCMF_E_PFN_NET_FOUND			33
++#define BRCMF_E_PFN_NET_LOST			34
++#define BRCMF_E_RESET_COMPLETE			35
++#define BRCMF_E_JOIN_START			36
++#define BRCMF_E_ROAM_START			37
++#define BRCMF_E_ASSOC_START			38
++#define BRCMF_E_IBSS_ASSOC			39
++#define BRCMF_E_RADIO				40
++#define BRCMF_E_PSM_WATCHDOG			41
++#define BRCMF_E_PROBREQ_MSG			44
++#define BRCMF_E_SCAN_CONFIRM_IND		45
++#define BRCMF_E_PSK_SUP				46
++#define BRCMF_E_COUNTRY_CODE_CHANGED		47
++#define	BRCMF_E_EXCEEDED_MEDIUM_TIME		48
++#define BRCMF_E_ICV_ERROR			49
++#define BRCMF_E_UNICAST_DECODE_ERROR		50
++#define BRCMF_E_MULTICAST_DECODE_ERROR		51
++#define BRCMF_E_TRACE				52
++#define BRCMF_E_IF				54
++#define BRCMF_E_RSSI				56
++#define BRCMF_E_PFN_SCAN_COMPLETE		57
++#define BRCMF_E_EXTLOG_MSG			58
++#define BRCMF_E_ACTION_FRAME			59
++#define BRCMF_E_ACTION_FRAME_COMPLETE		60
++#define BRCMF_E_PRE_ASSOC_IND			61
++#define BRCMF_E_PRE_REASSOC_IND			62
++#define BRCMF_E_CHANNEL_ADOPTED			63
++#define BRCMF_E_AP_STARTED			64
++#define BRCMF_E_DFS_AP_STOP			65
++#define BRCMF_E_DFS_AP_RESUME			66
++#define BRCMF_E_RESERVED1			67
++#define BRCMF_E_RESERVED2			68
++#define BRCMF_E_ESCAN_RESULT			69
++#define BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE	70
++#define BRCMF_E_DCS_REQUEST			73
++
++#define BRCMF_E_FIFO_CREDIT_MAP			74
++
++#define BRCMF_E_LAST				75
++
++#define BRCMF_E_STATUS_SUCCESS			0
++#define BRCMF_E_STATUS_FAIL			1
++#define BRCMF_E_STATUS_TIMEOUT			2
++#define BRCMF_E_STATUS_NO_NETWORKS		3
++#define BRCMF_E_STATUS_ABORT			4
++#define BRCMF_E_STATUS_NO_ACK			5
++#define BRCMF_E_STATUS_UNSOLICITED		6
++#define BRCMF_E_STATUS_ATTEMPT			7
++#define BRCMF_E_STATUS_PARTIAL			8
++#define BRCMF_E_STATUS_NEWSCAN			9
++#define BRCMF_E_STATUS_NEWASSOC			10
++#define BRCMF_E_STATUS_11HQUIET			11
++#define BRCMF_E_STATUS_SUPPRESS			12
++#define BRCMF_E_STATUS_NOCHANS			13
++#define BRCMF_E_STATUS_CS_ABORT			15
++#define BRCMF_E_STATUS_ERROR			16
++
++#define BRCMF_E_REASON_INITIAL_ASSOC		0
++#define BRCMF_E_REASON_LOW_RSSI			1
++#define BRCMF_E_REASON_DEAUTH			2
++#define BRCMF_E_REASON_DISASSOC			3
++#define BRCMF_E_REASON_BCNS_LOST		4
++#define BRCMF_E_REASON_MINTXRATE		9
++#define BRCMF_E_REASON_TXFAIL			10
++
++#define BRCMF_E_REASON_FAST_ROAM_FAILED		5
++#define BRCMF_E_REASON_DIRECTED_ROAM		6
++#define BRCMF_E_REASON_TSPEC_REJECTED		7
++#define BRCMF_E_REASON_BETTER_AP		8
++
++#define BRCMF_E_PRUNE_ENCR_MISMATCH		1
++#define BRCMF_E_PRUNE_BCAST_BSSID		2
++#define BRCMF_E_PRUNE_MAC_DENY			3
++#define BRCMF_E_PRUNE_MAC_NA			4
++#define BRCMF_E_PRUNE_REG_PASSV			5
++#define BRCMF_E_PRUNE_SPCT_MGMT			6
++#define BRCMF_E_PRUNE_RADAR			7
++#define BRCMF_E_RSN_MISMATCH			8
++#define BRCMF_E_PRUNE_NO_COMMON_RATES		9
++#define BRCMF_E_PRUNE_BASIC_RATES		10
++#define BRCMF_E_PRUNE_CIPHER_NA			12
++#define BRCMF_E_PRUNE_KNOWN_STA			13
++#define BRCMF_E_PRUNE_WDS_PEER			15
++#define BRCMF_E_PRUNE_QBSS_LOAD			16
++#define BRCMF_E_PRUNE_HOME_AP			17
++
++#define BRCMF_E_SUP_OTHER			0
++#define BRCMF_E_SUP_DECRYPT_KEY_DATA		1
++#define BRCMF_E_SUP_BAD_UCAST_WEP128		2
++#define BRCMF_E_SUP_BAD_UCAST_WEP40		3
++#define BRCMF_E_SUP_UNSUP_KEY_LEN		4
++#define BRCMF_E_SUP_PW_KEY_CIPHER		5
++#define BRCMF_E_SUP_MSG3_TOO_MANY_IE		6
++#define BRCMF_E_SUP_MSG3_IE_MISMATCH		7
++#define BRCMF_E_SUP_NO_INSTALL_FLAG		8
++#define BRCMF_E_SUP_MSG3_NO_GTK			9
++#define BRCMF_E_SUP_GRP_KEY_CIPHER		10
++#define BRCMF_E_SUP_GRP_MSG1_NO_GTK		11
++#define BRCMF_E_SUP_GTK_DECRYPT_FAIL		12
++#define BRCMF_E_SUP_SEND_FAIL			13
++#define BRCMF_E_SUP_DEAUTH			14
++
++#define BRCMF_E_IF_ADD				1
++#define BRCMF_E_IF_DEL				2
++#define BRCMF_E_IF_CHANGE			3
++
++#define BRCMF_E_IF_ROLE_STA			0
++#define BRCMF_E_IF_ROLE_AP			1
++#define BRCMF_E_IF_ROLE_WDS			2
++
++#define BRCMF_E_LINK_BCN_LOSS			1
++#define BRCMF_E_LINK_DISASSOC			2
++#define BRCMF_E_LINK_ASSOC_REC			3
++#define BRCMF_E_LINK_BSSCFG_DIS			4
++
++/* Pattern matching filter. Specifies an offset within received packets to
++ * start matching, the pattern to match, the size of the pattern, and a bitmask
++ * that indicates which bits within the pattern should be matched.
++ */
++struct brcmf_pkt_filter_pattern_le {
++	/*
++	 * Offset within received packet to start pattern matching.
++	 * Offset '0' is the first byte of the ethernet header.
++	 */
++	__le32 offset;
++	/* Size of the pattern.  Bitmask must be the same size.*/
++	__le32 size_bytes;
++	/*
++	 * Variable length mask and pattern data. mask starts at offset 0.
++	 * Pattern immediately follows mask.
++	 */
++	u8 mask_and_pattern[1];
++};
++
++/* IOVAR "pkt_filter_add" parameter. Used to install packet filters. */
++struct brcmf_pkt_filter_le {
++	__le32 id;		/* Unique filter id, specified by app. */
++	__le32 type;		/* Filter type (WL_PKT_FILTER_TYPE_xxx). */
++	__le32 negate_match;	/* Negate the result of filter matches */
++	union {			/* Filter definitions */
++		struct brcmf_pkt_filter_pattern_le pattern; /* Filter pattern */
++	} u;
++};
++
++/* IOVAR "pkt_filter_enable" parameter. */
++struct brcmf_pkt_filter_enable_le {
++	__le32 id;		/* Unique filter id */
++	__le32 enable;		/* Enable/disable bool */
++};
++
++/* BSS info structure
++ * Applications MUST CHECK ie_offset field and length field to access IEs and
++ * next bss_info structure in a vector (in struct brcmf_scan_results)
++ */
++struct brcmf_bss_info_le {
++	__le32 version;		/* version field */
++	__le32 length;		/* byte length of data in this record,
++				 * starting at version and including IEs
++				 */
++	u8 BSSID[ETH_ALEN];
++	__le16 beacon_period;	/* units are Kusec */
++	__le16 capability;	/* Capability information */
++	u8 SSID_len;
++	u8 SSID[32];
++	struct {
++		__le32 count;   /* # rates in this set */
++		u8 rates[16]; /* rates in 500kbps units w/hi bit set if basic */
++	} rateset;		/* supported rates */
++	__le16 chanspec;	/* chanspec for bss */
++	__le16 atim_window;	/* units are Kusec */
++	u8 dtim_period;	/* DTIM period */
++	__le16 RSSI;		/* receive signal strength (in dBm) */
++	s8 phy_noise;		/* noise (in dBm) */
++
++	u8 n_cap;		/* BSS is 802.11N Capable */
++	/* 802.11N BSS Capabilities (based on HT_CAP_*): */
++	__le32 nbss_cap;
++	u8 ctl_ch;		/* 802.11N BSS control channel number */
++	__le32 reserved32[1];	/* Reserved for expansion of BSS properties */
++	u8 flags;		/* flags */
++	u8 reserved[3];	/* Reserved for expansion of BSS properties */
++	u8 basic_mcs[MCSSET_LEN];	/* 802.11N BSS required MCS set */
++
++	__le16 ie_offset;	/* offset at which IEs start, from beginning */
++	__le32 ie_length;	/* byte length of Information Elements */
++	__le16 SNR;		/* average SNR of during frame reception */
++	/* Add new fields here */
++	/* variable length Information Elements */
++};
++
++struct brcm_rateset_le {
++	/* # rates in this set */
++	__le32 count;
++	/* rates in 500kbps units w/hi bit set if basic */
++	u8 rates[WL_NUMRATES];
++};
++
++struct brcmf_ssid {
++	u32 SSID_len;
++	unsigned char SSID[32];
++};
++
++struct brcmf_ssid_le {
++	__le32 SSID_len;
++	unsigned char SSID[32];
++};
++
++struct brcmf_scan_params_le {
++	struct brcmf_ssid_le ssid_le;	/* default: {0, ""} */
++	u8 bssid[ETH_ALEN];	/* default: bcast */
++	s8 bss_type;		/* default: any,
++				 * DOT11_BSSTYPE_ANY/INFRASTRUCTURE/INDEPENDENT
++				 */
++	u8 scan_type;	/* flags, 0 use default */
++	__le32 nprobes;	  /* -1 use default, number of probes per channel */
++	__le32 active_time;	/* -1 use default, dwell time per channel for
++				 * active scanning
++				 */
++	__le32 passive_time;	/* -1 use default, dwell time per channel
++				 * for passive scanning
++				 */
++	__le32 home_time;	/* -1 use default, dwell time for the
++				 * home channel between channel scans
++				 */
++	__le32 channel_num;	/* count of channels and ssids that follow
++				 *
++				 * low half is count of channels in
++				 * channel_list, 0 means default (use all
++				 * available channels)
++				 *
++				 * high half is entries in struct brcmf_ssid
++				 * array that follows channel_list, aligned for
++				 * s32 (4 bytes) meaning an odd channel count
++				 * implies a 2-byte pad between end of
++				 * channel_list and first ssid
++				 *
++				 * if ssid count is zero, single ssid in the
++				 * fixed parameter portion is assumed, otherwise
++				 * ssid in the fixed portion is ignored
++				 */
++	__le16 channel_list[1];	/* list of chanspecs */
++};
++
++/* incremental scan struct */
++struct brcmf_iscan_params_le {
++	__le32 version;
++	__le16 action;
++	__le16 scan_duration;
++	struct brcmf_scan_params_le params_le;
++};
++
++struct brcmf_scan_results {
++	u32 buflen;
++	u32 version;
++	u32 count;
++	struct brcmf_bss_info_le bss_info_le[];
++};
++
++struct brcmf_scan_results_le {
++	__le32 buflen;
++	__le32 version;
++	__le32 count;
++};
++
++/* used for association with a specific BSSID and chanspec list */
++struct brcmf_assoc_params_le {
++	/* 00:00:00:00:00:00: broadcast scan */
++	u8 bssid[ETH_ALEN];
++	/* 0: all available channels, otherwise count of chanspecs in
++	 * chanspec_list */
++	__le32 chanspec_num;
++	/* list of chanspecs */
++	__le16 chanspec_list[1];
++};
++
++/* used for join with or without a specific bssid and channel list */
++struct brcmf_join_params {
++	struct brcmf_ssid_le ssid_le;
++	struct brcmf_assoc_params_le params_le;
++};
++
++/* incremental scan results struct */
++struct brcmf_iscan_results {
++	union {
++		u32 status;
++		__le32 status_le;
++	};
++	union {
++		struct brcmf_scan_results results;
++		struct brcmf_scan_results_le results_le;
++	};
++};
++
++/* size of brcmf_iscan_results not including variable length array */
++#define BRCMF_ISCAN_RESULTS_FIXED_SIZE \
++	(sizeof(struct brcmf_scan_results) + \
++	 offsetof(struct brcmf_iscan_results, results))
++
++struct brcmf_wsec_key {
++	u32 index;		/* key index */
++	u32 len;		/* key length */
++	u8 data[WLAN_MAX_KEY_LEN];	/* key data */
++	u32 pad_1[18];
++	u32 algo;	/* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */
++	u32 flags;	/* misc flags */
++	u32 pad_2[3];
++	u32 iv_initialized;	/* has IV been initialized already? */
++	u32 pad_3;
++	/* Rx IV */
++	struct {
++		u32 hi;	/* upper 32 bits of IV */
++		u16 lo;	/* lower 16 bits of IV */
++	} rxiv;
++	u32 pad_4[2];
++	u8 ea[ETH_ALEN];	/* per station */
++};
++
++/*
++ * dongle requires same struct as above but with fields in little endian order
++ */
++struct brcmf_wsec_key_le {
++	__le32 index;		/* key index */
++	__le32 len;		/* key length */
++	u8 data[WLAN_MAX_KEY_LEN];	/* key data */
++	__le32 pad_1[18];
++	__le32 algo;	/* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */
++	__le32 flags;	/* misc flags */
++	__le32 pad_2[3];
++	__le32 iv_initialized;	/* has IV been initialized already? */
++	__le32 pad_3;
++	/* Rx IV */
++	struct {
++		__le32 hi;	/* upper 32 bits of IV */
++		__le16 lo;	/* lower 16 bits of IV */
++	} rxiv;
++	__le32 pad_4[2];
++	u8 ea[ETH_ALEN];	/* per station */
++};
++
++/* Used to get specific STA parameters */
++struct brcmf_scb_val_le {
++	__le32 val;
++	u8 ea[ETH_ALEN];
++};
++
++/* channel encoding */
++struct brcmf_channel_info_le {
++	__le32 hw_channel;
++	__le32 target_channel;
++	__le32 scan_channel;
++};
++
++/* Bus independent dongle command */
++struct brcmf_dcmd {
++	uint cmd;		/* common dongle cmd definition */
++	void *buf;		/* pointer to user buffer */
++	uint len;		/* length of user buffer */
++	u8 set;			/* get or set request (optional) */
++	uint used;		/* bytes read or written (optional) */
++	uint needed;		/* bytes needed (optional) */
++};
++
++/* Forward decls for struct brcmf_pub (see below) */
++struct brcmf_proto;	/* device communication protocol info */
++struct brcmf_cfg80211_dev; /* cfg80211 device info */
++
++/* Common structure for module and instance linkage */
++struct brcmf_pub {
++	/* Linkage ponters */
++	struct brcmf_bus *bus_if;
++	struct brcmf_proto *prot;
++	struct brcmf_cfg80211_dev *config;
++	struct device *dev;		/* fullmac dongle device pointer */
++
++	/* Internal brcmf items */
++	uint hdrlen;		/* Total BRCMF header length (proto + bus) */
++	uint rxsz;		/* Rx buffer size bus module should use */
++	u8 wme_dp;		/* wme discard priority */
++
++	/* Dongle media info */
++	bool iswl;		/* Dongle-resident driver is wl */
++	unsigned long drv_version;	/* Version of dongle-resident driver */
++	u8 mac[ETH_ALEN];		/* MAC address obtained from dongle */
++
++	/* Additional stats for the bus level */
++
++	/* Multicast data packets sent to dongle */
++	unsigned long tx_multicast;
++	/* Packets flushed due to unscheduled sendup thread */
++	unsigned long rx_flushed;
++	/* Number of times dpc scheduled by watchdog timer */
++	unsigned long wd_dpc_sched;
++
++	/* Number of flow control pkts recvd */
++	unsigned long fc_packets;
++
++	/* Last error return */
++	int bcmerror;
++
++	/* Last error from dongle */
++	int dongle_error;
++
++	/* Suspend disable flag  flag */
++	int suspend_disable_flag;	/* "1" to disable all extra powersaving
++					 during suspend */
++	int in_suspend;		/* flag set to 1 when early suspend called */
++	int dtim_skip;		/* dtim skip , default 0 means wake each dtim */
++
++	/* Pkt filter defination */
++	char *pktfilter[100];
++	int pktfilter_count;
++
++	u8 country_code[BRCM_CNTRY_BUF_SZ];
++	char eventmask[BRCMF_EVENTING_MASK_LEN];
++
++	struct brcmf_if *iflist[BRCMF_MAX_IFS];
++
++	struct mutex proto_block;
++
++	struct work_struct setmacaddr_work;
++	struct work_struct multicast_work;
++	u8 macvalue[ETH_ALEN];
++	atomic_t pend_8021x_cnt;
++};
++
++struct brcmf_if_event {
++	u8 ifidx;
++	u8 action;
++	u8 flags;
++	u8 bssidx;
++};
++
++struct bcmevent_name {
++	uint event;
++	const char *name;
++};
++
++extern const struct bcmevent_name bcmevent_names[];
++
++extern uint brcmf_c_mkiovar(char *name, char *data, uint datalen,
++			  char *buf, uint len);
++
++extern int brcmf_netdev_wait_pend8021x(struct net_device *ndev);
++
++extern s32 brcmf_exec_dcmd(struct net_device *dev, u32 cmd, void *arg, u32 len);
++
++/* Return pointer to interface name */
++extern char *brcmf_ifname(struct brcmf_pub *drvr, int idx);
++
++/* Query dongle */
++extern int brcmf_proto_cdc_query_dcmd(struct brcmf_pub *drvr, int ifidx,
++				       uint cmd, void *buf, uint len);
++
++#ifdef DEBUG
++extern int brcmf_write_to_file(struct brcmf_pub *drvr, const u8 *buf, int size);
++#endif				/* DEBUG */
++
++extern int brcmf_ifname2idx(struct brcmf_pub *drvr, char *name);
++extern int brcmf_c_host_event(struct brcmf_pub *drvr, int *idx,
++			      void *pktdata, struct brcmf_event_msg *,
++			      void **data_ptr);
++
++extern void brcmf_del_if(struct brcmf_pub *drvr, int ifidx);
++
++/* Send packet to dongle via data channel */
++extern int brcmf_sendpkt(struct brcmf_pub *drvr, int ifidx,\
++			 struct sk_buff *pkt);
++
++extern void brcmf_c_pktfilter_offload_set(struct brcmf_pub *drvr, char *arg);
++extern void brcmf_c_pktfilter_offload_enable(struct brcmf_pub *drvr, char *arg,
++					     int enable, int master_mode);
++
++#define	BRCMF_DCMD_SMLEN	256	/* "small" cmd buffer required */
++#define BRCMF_DCMD_MEDLEN	1536	/* "med" cmd buffer required */
++#define	BRCMF_DCMD_MAXLEN	8192	/* max length cmd buffer required */
++
++#endif				/* _BRCMF_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
+new file mode 100644
+index 0000000..3669164
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
+@@ -0,0 +1,118 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef _BRCMF_BUS_H_
++#define _BRCMF_BUS_H_
++
++/* The level of bus communication with the dongle */
++enum brcmf_bus_state {
++	BRCMF_BUS_DOWN,		/* Not ready for frame transfers */
++	BRCMF_BUS_LOAD,		/* Download access only (CPU reset) */
++	BRCMF_BUS_DATA		/* Ready for frame transfers */
++};
++
++struct dngl_stats {
++	unsigned long rx_packets;	/* total packets received */
++	unsigned long tx_packets;	/* total packets transmitted */
++	unsigned long rx_bytes;	/* total bytes received */
++	unsigned long tx_bytes;	/* total bytes transmitted */
++	unsigned long rx_errors;	/* bad packets received */
++	unsigned long tx_errors;	/* packet transmit problems */
++	unsigned long rx_dropped;	/* packets dropped by dongle */
++	unsigned long tx_dropped;	/* packets dropped by dongle */
++	unsigned long multicast;	/* multicast packets received */
++};
++
++/* interface structure between common and bus layer */
++struct brcmf_bus {
++	u8 type;		/* bus type */
++	union {
++		struct brcmf_sdio_dev *sdio;
++		struct brcmf_usbdev *usb;
++	} bus_priv;
++	struct brcmf_pub *drvr;	/* pointer to driver pub structure brcmf_pub */
++	enum brcmf_bus_state state;
++	uint maxctl;		/* Max size rxctl request from proto to bus */
++	bool drvr_up;		/* Status flag of driver up/down */
++	unsigned long tx_realloc;	/* Tx packets realloced for headroom */
++	struct dngl_stats dstats;	/* Stats for dongle-based data */
++	u8 align;		/* bus alignment requirement */
++
++	/* interface functions pointers */
++	/* Stop bus module: clear pending frames, disable data flow */
++	void (*brcmf_bus_stop)(struct device *);
++	/* Initialize bus module: prepare for communication w/dongle */
++	int (*brcmf_bus_init)(struct device *);
++	/* Send a data frame to the dongle.  Callee disposes of txp. */
++	int (*brcmf_bus_txdata)(struct device *, struct sk_buff *);
++	/* Send/receive a control message to/from the dongle.
++	 * Expects caller to enforce a single outstanding transaction.
++	 */
++	int (*brcmf_bus_txctl)(struct device *, unsigned char *, uint);
++	int (*brcmf_bus_rxctl)(struct device *, unsigned char *, uint);
++};
++
++/*
++ * interface functions from common layer
++ */
++
++/* Remove any protocol-specific data header. */
++extern int brcmf_proto_hdrpull(struct device *dev, int *ifidx,
++			       struct sk_buff *rxp);
++
++extern bool brcmf_c_prec_enq(struct device *dev, struct pktq *q,
++			 struct sk_buff *pkt, int prec);
++
++/* Receive frame for delivery to OS.  Callee disposes of rxp. */
++extern void brcmf_rx_frame(struct device *dev, int ifidx,
++			   struct sk_buff_head *rxlist);
++static inline void brcmf_rx_packet(struct device *dev, int ifidx,
++				   struct sk_buff *pkt)
++{
++	struct sk_buff_head q;
++
++	skb_queue_head_init(&q);
++	skb_queue_tail(&q, pkt);
++	brcmf_rx_frame(dev, ifidx, &q);
++}
++
++/* Indication from bus module regarding presence/insertion of dongle. */
++extern int brcmf_attach(uint bus_hdrlen, struct device *dev);
++/* Indication from bus module regarding removal/absence of dongle */
++extern void brcmf_detach(struct device *dev);
++
++/* Indication from bus module to change flow-control state */
++extern void brcmf_txflowcontrol(struct device *dev, int ifidx, bool on);
++
++/* Notify tx completion */
++extern void brcmf_txcomplete(struct device *dev, struct sk_buff *txp,
++			     bool success);
++
++extern int brcmf_bus_start(struct device *dev);
++
++extern int brcmf_add_if(struct device *dev, int ifidx,
++			char *name, u8 *mac_addr);
++
++#ifdef CONFIG_BRCMFMAC_SDIO
++extern void brcmf_sdio_exit(void);
++extern void brcmf_sdio_init(void);
++#endif
++#ifdef CONFIG_BRCMFMAC_USB
++extern void brcmf_usb_exit(void);
++extern void brcmf_usb_init(void);
++#endif
++
++#endif				/* _BRCMF_BUS_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c
+new file mode 100644
+index 0000000..ca28295
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c
+@@ -0,0 +1,495 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++/*******************************************************************************
++ * Communicates with the dongle by using dcmd codes.
++ * For certain dcmd codes, the dongle interprets string data from the host.
++ ******************************************************************************/
++
++#undef pr_fmt
++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
++
++#include <linux/types.h>
++#include <linux/netdevice.h>
++#include <linux/printk.h>
++#include <linux/sched.h>
++#include <defs.h>
++
++#include <brcmu_utils.h>
++#include <brcmu_wifi.h>
++
++#include "dhd.h"
++#include "dhd_proto.h"
++#include "dhd_bus.h"
++#include "dhd_dbg.h"
++
++struct brcmf_proto_cdc_dcmd {
++	__le32 cmd;	/* dongle command value */
++	__le32 len;	/* lower 16: output buflen;
++			 * upper 16: input buflen (excludes header) */
++	__le32 flags;	/* flag defns given below */
++	__le32 status;	/* status code returned from the device */
++};
++
++/* Max valid buffer size that can be sent to the dongle */
++#define CDC_MAX_MSG_SIZE	(ETH_FRAME_LEN+ETH_FCS_LEN)
++
++/* CDC flag definitions */
++#define CDC_DCMD_ERROR		0x01	/* 1=cmd failed */
++#define CDC_DCMD_SET		0x02	/* 0=get, 1=set cmd */
++#define CDC_DCMD_IF_MASK	0xF000		/* I/F index */
++#define CDC_DCMD_IF_SHIFT	12
++#define CDC_DCMD_ID_MASK	0xFFFF0000	/* id an cmd pairing */
++#define CDC_DCMD_ID_SHIFT	16		/* ID Mask shift bits */
++#define CDC_DCMD_ID(flags)	\
++	(((flags) & CDC_DCMD_ID_MASK) >> CDC_DCMD_ID_SHIFT)
++
++/*
++ * BDC header - Broadcom specific extension of CDC.
++ * Used on data packets to convey priority across USB.
++ */
++#define	BDC_HEADER_LEN		4
++#define BDC_PROTO_VER		2	/* Protocol version */
++#define BDC_FLAG_VER_MASK	0xf0	/* Protocol version mask */
++#define BDC_FLAG_VER_SHIFT	4	/* Protocol version shift */
++#define BDC_FLAG_SUM_GOOD	0x04	/* Good RX checksums */
++#define BDC_FLAG_SUM_NEEDED	0x08	/* Dongle needs to do TX checksums */
++#define BDC_PRIORITY_MASK	0x7
++#define BDC_FLAG2_IF_MASK	0x0f	/* packet rx interface in APSTA */
++#define BDC_FLAG2_IF_SHIFT	0
++
++#define BDC_GET_IF_IDX(hdr) \
++	((int)((((hdr)->flags2) & BDC_FLAG2_IF_MASK) >> BDC_FLAG2_IF_SHIFT))
++#define BDC_SET_IF_IDX(hdr, idx) \
++	((hdr)->flags2 = (((hdr)->flags2 & ~BDC_FLAG2_IF_MASK) | \
++	((idx) << BDC_FLAG2_IF_SHIFT)))
++
++struct brcmf_proto_bdc_header {
++	u8 flags;
++	u8 priority;	/* 802.1d Priority, 4:7 flow control info for usb */
++	u8 flags2;
++	u8 data_offset;
++};
++
++
++#define RETRIES 2 /* # of retries to retrieve matching dcmd response */
++#define BUS_HEADER_LEN	(16+64)		/* Must be atleast SDPCM_RESERVE
++					 * (amount of header tha might be added)
++					 * plus any space that might be needed
++					 * for bus alignment padding.
++					 */
++#define ROUND_UP_MARGIN	2048	/* Biggest bus block size possible for
++				 * round off at the end of buffer
++				 * Currently is SDIO
++				 */
++
++struct brcmf_proto {
++	u16 reqid;
++	u8 pending;
++	u32 lastcmd;
++	u8 bus_header[BUS_HEADER_LEN];
++	struct brcmf_proto_cdc_dcmd msg;
++	unsigned char buf[BRCMF_DCMD_MAXLEN + ROUND_UP_MARGIN];
++};
++
++static int brcmf_proto_cdc_msg(struct brcmf_pub *drvr)
++{
++	struct brcmf_proto *prot = drvr->prot;
++	int len = le32_to_cpu(prot->msg.len) +
++			sizeof(struct brcmf_proto_cdc_dcmd);
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* NOTE : cdc->msg.len holds the desired length of the buffer to be
++	 *        returned. Only up to CDC_MAX_MSG_SIZE of this buffer area
++	 *        is actually sent to the dongle
++	 */
++	if (len > CDC_MAX_MSG_SIZE)
++		len = CDC_MAX_MSG_SIZE;
++
++	/* Send request */
++	return drvr->bus_if->brcmf_bus_txctl(drvr->dev,
++					     (unsigned char *)&prot->msg,
++					     len);
++}
++
++static int brcmf_proto_cdc_cmplt(struct brcmf_pub *drvr, u32 id, u32 len)
++{
++	int ret;
++	struct brcmf_proto *prot = drvr->prot;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	do {
++		ret = drvr->bus_if->brcmf_bus_rxctl(drvr->dev,
++				(unsigned char *)&prot->msg,
++				len + sizeof(struct brcmf_proto_cdc_dcmd));
++		if (ret < 0)
++			break;
++	} while (CDC_DCMD_ID(le32_to_cpu(prot->msg.flags)) != id);
++
++	return ret;
++}
++
++int
++brcmf_proto_cdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
++			       void *buf, uint len)
++{
++	struct brcmf_proto *prot = drvr->prot;
++	struct brcmf_proto_cdc_dcmd *msg = &prot->msg;
++	void *info;
++	int ret = 0, retries = 0;
++	u32 id, flags;
++
++	brcmf_dbg(TRACE, "Enter\n");
++	brcmf_dbg(CTL, "cmd %d len %d\n", cmd, len);
++
++	/* Respond "bcmerror" and "bcmerrorstr" with local cache */
++	if (cmd == BRCMF_C_GET_VAR && buf) {
++		if (!strcmp((char *)buf, "bcmerrorstr")) {
++			strncpy((char *)buf, "bcm_error",
++				BCME_STRLEN);
++			goto done;
++		} else if (!strcmp((char *)buf, "bcmerror")) {
++			*(int *)buf = drvr->dongle_error;
++			goto done;
++		}
++	}
++
++	memset(msg, 0, sizeof(struct brcmf_proto_cdc_dcmd));
++
++	msg->cmd = cpu_to_le32(cmd);
++	msg->len = cpu_to_le32(len);
++	flags = (++prot->reqid << CDC_DCMD_ID_SHIFT);
++	flags = (flags & ~CDC_DCMD_IF_MASK) |
++		(ifidx << CDC_DCMD_IF_SHIFT);
++	msg->flags = cpu_to_le32(flags);
++
++	if (buf)
++		memcpy(prot->buf, buf, len);
++
++	ret = brcmf_proto_cdc_msg(drvr);
++	if (ret < 0) {
++		brcmf_dbg(ERROR, "brcmf_proto_cdc_msg failed w/status %d\n",
++			  ret);
++		goto done;
++	}
++
++retry:
++	/* wait for interrupt and get first fragment */
++	ret = brcmf_proto_cdc_cmplt(drvr, prot->reqid, len);
++	if (ret < 0)
++		goto done;
++
++	flags = le32_to_cpu(msg->flags);
++	id = (flags & CDC_DCMD_ID_MASK) >> CDC_DCMD_ID_SHIFT;
++
++	if ((id < prot->reqid) && (++retries < RETRIES))
++		goto retry;
++	if (id != prot->reqid) {
++		brcmf_dbg(ERROR, "%s: unexpected request id %d (expected %d)\n",
++			  brcmf_ifname(drvr, ifidx), id, prot->reqid);
++		ret = -EINVAL;
++		goto done;
++	}
++
++	/* Check info buffer */
++	info = (void *)&msg[1];
++
++	/* Copy info buffer */
++	if (buf) {
++		if (ret < (int)len)
++			len = ret;
++		memcpy(buf, info, len);
++	}
++
++	/* Check the ERROR flag */
++	if (flags & CDC_DCMD_ERROR) {
++		ret = le32_to_cpu(msg->status);
++		/* Cache error from dongle */
++		drvr->dongle_error = ret;
++	}
++
++done:
++	return ret;
++}
++
++int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
++				 void *buf, uint len)
++{
++	struct brcmf_proto *prot = drvr->prot;
++	struct brcmf_proto_cdc_dcmd *msg = &prot->msg;
++	int ret = 0;
++	u32 flags, id;
++
++	brcmf_dbg(TRACE, "Enter\n");
++	brcmf_dbg(CTL, "cmd %d len %d\n", cmd, len);
++
++	memset(msg, 0, sizeof(struct brcmf_proto_cdc_dcmd));
++
++	msg->cmd = cpu_to_le32(cmd);
++	msg->len = cpu_to_le32(len);
++	flags = (++prot->reqid << CDC_DCMD_ID_SHIFT) | CDC_DCMD_SET;
++	flags = (flags & ~CDC_DCMD_IF_MASK) |
++		(ifidx << CDC_DCMD_IF_SHIFT);
++	msg->flags = cpu_to_le32(flags);
++
++	if (buf)
++		memcpy(prot->buf, buf, len);
++
++	ret = brcmf_proto_cdc_msg(drvr);
++	if (ret < 0)
++		goto done;
++
++	ret = brcmf_proto_cdc_cmplt(drvr, prot->reqid, len);
++	if (ret < 0)
++		goto done;
++
++	flags = le32_to_cpu(msg->flags);
++	id = (flags & CDC_DCMD_ID_MASK) >> CDC_DCMD_ID_SHIFT;
++
++	if (id != prot->reqid) {
++		brcmf_dbg(ERROR, "%s: unexpected request id %d (expected %d)\n",
++			  brcmf_ifname(drvr, ifidx), id, prot->reqid);
++		ret = -EINVAL;
++		goto done;
++	}
++
++	/* Check the ERROR flag */
++	if (flags & CDC_DCMD_ERROR) {
++		ret = le32_to_cpu(msg->status);
++		/* Cache error from dongle */
++		drvr->dongle_error = ret;
++	}
++
++done:
++	return ret;
++}
++
++int
++brcmf_proto_dcmd(struct brcmf_pub *drvr, int ifidx, struct brcmf_dcmd *dcmd,
++		  int len)
++{
++	struct brcmf_proto *prot = drvr->prot;
++	int ret = -1;
++
++	if (drvr->bus_if->state == BRCMF_BUS_DOWN) {
++		brcmf_dbg(ERROR, "bus is down. we have nothing to do.\n");
++		return ret;
++	}
++	mutex_lock(&drvr->proto_block);
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	if (len > BRCMF_DCMD_MAXLEN)
++		goto done;
++
++	if (prot->pending == true) {
++		brcmf_dbg(TRACE, "CDC packet is pending!!!! cmd=0x%x (%lu) lastcmd=0x%x (%lu)\n",
++			  dcmd->cmd, (unsigned long)dcmd->cmd, prot->lastcmd,
++			  (unsigned long)prot->lastcmd);
++		if (dcmd->cmd == BRCMF_C_SET_VAR ||
++		    dcmd->cmd == BRCMF_C_GET_VAR)
++			brcmf_dbg(TRACE, "iovar cmd=%s\n", (char *)dcmd->buf);
++
++		goto done;
++	}
++
++	prot->pending = true;
++	prot->lastcmd = dcmd->cmd;
++	if (dcmd->set)
++		ret = brcmf_proto_cdc_set_dcmd(drvr, ifidx, dcmd->cmd,
++						   dcmd->buf, len);
++	else {
++		ret = brcmf_proto_cdc_query_dcmd(drvr, ifidx, dcmd->cmd,
++						     dcmd->buf, len);
++		if (ret > 0)
++			dcmd->used = ret -
++					sizeof(struct brcmf_proto_cdc_dcmd);
++	}
++
++	if (ret >= 0)
++		ret = 0;
++	else {
++		struct brcmf_proto_cdc_dcmd *msg = &prot->msg;
++		/* len == needed when set/query fails from dongle */
++		dcmd->needed = le32_to_cpu(msg->len);
++	}
++
++	/* Intercept the wme_dp dongle cmd here */
++	if (!ret && dcmd->cmd == BRCMF_C_SET_VAR &&
++	    !strcmp(dcmd->buf, "wme_dp")) {
++		int slen;
++		__le32 val = 0;
++
++		slen = strlen("wme_dp") + 1;
++		if (len >= (int)(slen + sizeof(int)))
++			memcpy(&val, (char *)dcmd->buf + slen, sizeof(int));
++		drvr->wme_dp = (u8) le32_to_cpu(val);
++	}
++
++	prot->pending = false;
++
++done:
++	mutex_unlock(&drvr->proto_block);
++
++	return ret;
++}
++
++static bool pkt_sum_needed(struct sk_buff *skb)
++{
++	return skb->ip_summed == CHECKSUM_PARTIAL;
++}
++
++static void pkt_set_sum_good(struct sk_buff *skb, bool x)
++{
++	skb->ip_summed = (x ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE);
++}
++
++void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx,
++			 struct sk_buff *pktbuf)
++{
++	struct brcmf_proto_bdc_header *h;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* Push BDC header used to convey priority for buses that don't */
++
++	skb_push(pktbuf, BDC_HEADER_LEN);
++
++	h = (struct brcmf_proto_bdc_header *)(pktbuf->data);
++
++	h->flags = (BDC_PROTO_VER << BDC_FLAG_VER_SHIFT);
++	if (pkt_sum_needed(pktbuf))
++		h->flags |= BDC_FLAG_SUM_NEEDED;
++
++	h->priority = (pktbuf->priority & BDC_PRIORITY_MASK);
++	h->flags2 = 0;
++	h->data_offset = 0;
++	BDC_SET_IF_IDX(h, ifidx);
++}
++
++int brcmf_proto_hdrpull(struct device *dev, int *ifidx,
++			struct sk_buff *pktbuf)
++{
++	struct brcmf_proto_bdc_header *h;
++	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
++	struct brcmf_pub *drvr = bus_if->drvr;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* Pop BDC header used to convey priority for buses that don't */
++
++	if (pktbuf->len < BDC_HEADER_LEN) {
++		brcmf_dbg(ERROR, "rx data too short (%d < %d)\n",
++			  pktbuf->len, BDC_HEADER_LEN);
++		return -EBADE;
++	}
++
++	h = (struct brcmf_proto_bdc_header *)(pktbuf->data);
++
++	*ifidx = BDC_GET_IF_IDX(h);
++	if (*ifidx >= BRCMF_MAX_IFS) {
++		brcmf_dbg(ERROR, "rx data ifnum out of range (%d)\n", *ifidx);
++		return -EBADE;
++	}
++
++	if (((h->flags & BDC_FLAG_VER_MASK) >> BDC_FLAG_VER_SHIFT) !=
++	    BDC_PROTO_VER) {
++		brcmf_dbg(ERROR, "%s: non-BDC packet received, flags 0x%x\n",
++			  brcmf_ifname(drvr, *ifidx), h->flags);
++		return -EBADE;
++	}
++
++	if (h->flags & BDC_FLAG_SUM_GOOD) {
++		brcmf_dbg(INFO, "%s: BDC packet received with good rx-csum, flags 0x%x\n",
++			  brcmf_ifname(drvr, *ifidx), h->flags);
++		pkt_set_sum_good(pktbuf, true);
++	}
++
++	pktbuf->priority = h->priority & BDC_PRIORITY_MASK;
++
++	skb_pull(pktbuf, BDC_HEADER_LEN);
++	skb_pull(pktbuf, h->data_offset << 2);
++
++	return 0;
++}
++
++int brcmf_proto_attach(struct brcmf_pub *drvr)
++{
++	struct brcmf_proto *cdc;
++
++	cdc = kzalloc(sizeof(struct brcmf_proto), GFP_ATOMIC);
++	if (!cdc)
++		goto fail;
++
++	/* ensure that the msg buf directly follows the cdc msg struct */
++	if ((unsigned long)(&cdc->msg + 1) != (unsigned long)cdc->buf) {
++		brcmf_dbg(ERROR, "struct brcmf_proto is not correctly defined\n");
++		goto fail;
++	}
++
++	drvr->prot = cdc;
++	drvr->hdrlen += BDC_HEADER_LEN;
++	drvr->bus_if->maxctl = BRCMF_DCMD_MAXLEN +
++			sizeof(struct brcmf_proto_cdc_dcmd) + ROUND_UP_MARGIN;
++	return 0;
++
++fail:
++	kfree(cdc);
++	return -ENOMEM;
++}
++
++/* ~NOTE~ What if another thread is waiting on the semaphore?  Holding it? */
++void brcmf_proto_detach(struct brcmf_pub *drvr)
++{
++	kfree(drvr->prot);
++	drvr->prot = NULL;
++}
++
++int brcmf_proto_init(struct brcmf_pub *drvr)
++{
++	int ret = 0;
++	char buf[128];
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	mutex_lock(&drvr->proto_block);
++
++	/* Get the device MAC address */
++	strcpy(buf, "cur_etheraddr");
++	ret = brcmf_proto_cdc_query_dcmd(drvr, 0, BRCMF_C_GET_VAR,
++					  buf, sizeof(buf));
++	if (ret < 0) {
++		mutex_unlock(&drvr->proto_block);
++		return ret;
++	}
++	memcpy(drvr->mac, buf, ETH_ALEN);
++
++	mutex_unlock(&drvr->proto_block);
++
++	ret = brcmf_c_preinit_dcmds(drvr);
++
++	/* Always assumes wl for now */
++	drvr->iswl = true;
++
++	return ret;
++}
++
++void brcmf_proto_stop(struct brcmf_pub *drvr)
++{
++	/* Nothing to do for CDC */
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
+new file mode 100644
+index 0000000..2962900
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
+@@ -0,0 +1,882 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#undef pr_fmt
++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
++
++#include <linux/kernel.h>
++#include <linux/printk.h>
++#include <linux/string.h>
++#include <linux/sched.h>
++#include <linux/netdevice.h>
++#include <asm/unaligned.h>
++#include <defs.h>
++#include <brcmu_wifi.h>
++#include <brcmu_utils.h>
++#include "dhd.h"
++#include "dhd_bus.h"
++#include "dhd_proto.h"
++#include "dhd_dbg.h"
++
++#define BRCM_OUI			"\x00\x10\x18"
++#define DOT11_OUI_LEN			3
++#define BCMILCP_BCM_SUBTYPE_EVENT	1
++#define PKTFILTER_BUF_SIZE		2048
++#define BRCMF_ARPOL_MODE		0xb	/* agent|snoop|peer_autoreply */
++
++#define MSGTRACE_VERSION	1
++
++#define BRCMF_PKT_FILTER_FIXED_LEN	offsetof(struct brcmf_pkt_filter_le, u)
++#define BRCMF_PKT_FILTER_PATTERN_FIXED_LEN	\
++	offsetof(struct brcmf_pkt_filter_pattern_le, mask_and_pattern)
++
++#ifdef DEBUG
++static const char brcmf_version[] =
++	"Dongle Host Driver, version " BRCMF_VERSION_STR "\nCompiled on "
++	__DATE__ " at " __TIME__;
++#else
++static const char brcmf_version[] =
++	"Dongle Host Driver, version " BRCMF_VERSION_STR;
++#endif
++
++/* Message trace header */
++struct msgtrace_hdr {
++	u8 version;
++	u8 spare;
++	__be16 len;		/* Len of the trace */
++	__be32 seqnum;		/* Sequence number of message. Useful
++				 * if the messsage has been lost
++				 * because of DMA error or a bus reset
++				 * (ex: SDIO Func2)
++				 */
++	__be32 discarded_bytes;	/* Number of discarded bytes because of
++				 trace overflow  */
++	__be32 discarded_printf;	/* Number of discarded printf
++				 because of trace overflow */
++} __packed;
++
++
++uint
++brcmf_c_mkiovar(char *name, char *data, uint datalen, char *buf, uint buflen)
++{
++	uint len;
++
++	len = strlen(name) + 1;
++
++	if ((len + datalen) > buflen)
++		return 0;
++
++	strncpy(buf, name, buflen);
++
++	/* append data onto the end of the name string */
++	memcpy(&buf[len], data, datalen);
++	len += datalen;
++
++	return len;
++}
++
++bool brcmf_c_prec_enq(struct device *dev, struct pktq *q,
++		      struct sk_buff *pkt, int prec)
++{
++	struct sk_buff *p;
++	int eprec = -1;		/* precedence to evict from */
++	bool discard_oldest;
++	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
++	struct brcmf_pub *drvr = bus_if->drvr;
++
++	/* Fast case, precedence queue is not full and we are also not
++	 * exceeding total queue length
++	 */
++	if (!pktq_pfull(q, prec) && !pktq_full(q)) {
++		brcmu_pktq_penq(q, prec, pkt);
++		return true;
++	}
++
++	/* Determine precedence from which to evict packet, if any */
++	if (pktq_pfull(q, prec))
++		eprec = prec;
++	else if (pktq_full(q)) {
++		p = brcmu_pktq_peek_tail(q, &eprec);
++		if (eprec > prec)
++			return false;
++	}
++
++	/* Evict if needed */
++	if (eprec >= 0) {
++		/* Detect queueing to unconfigured precedence */
++		discard_oldest = ac_bitmap_tst(drvr->wme_dp, eprec);
++		if (eprec == prec && !discard_oldest)
++			return false;	/* refuse newer (incoming) packet */
++		/* Evict packet according to discard policy */
++		p = discard_oldest ? brcmu_pktq_pdeq(q, eprec) :
++			brcmu_pktq_pdeq_tail(q, eprec);
++		if (p == NULL)
++			brcmf_dbg(ERROR, "brcmu_pktq_penq() failed, oldest %d\n",
++				  discard_oldest);
++
++		brcmu_pkt_buf_free_skb(p);
++	}
++
++	/* Enqueue */
++	p = brcmu_pktq_penq(q, prec, pkt);
++	if (p == NULL)
++		brcmf_dbg(ERROR, "brcmu_pktq_penq() failed\n");
++
++	return p != NULL;
++}
++
++#ifdef DEBUG
++static void
++brcmf_c_show_host_event(struct brcmf_event_msg *event, void *event_data)
++{
++	uint i, status, reason;
++	bool group = false, flush_txq = false, link = false;
++	char *auth_str, *event_name;
++	unsigned char *buf;
++	char err_msg[256], eabuf[ETHER_ADDR_STR_LEN];
++	static struct {
++		uint event;
++		char *event_name;
++	} event_names[] = {
++		{
++		BRCMF_E_SET_SSID, "SET_SSID"}, {
++		BRCMF_E_JOIN, "JOIN"}, {
++		BRCMF_E_START, "START"}, {
++		BRCMF_E_AUTH, "AUTH"}, {
++		BRCMF_E_AUTH_IND, "AUTH_IND"}, {
++		BRCMF_E_DEAUTH, "DEAUTH"}, {
++		BRCMF_E_DEAUTH_IND, "DEAUTH_IND"}, {
++		BRCMF_E_ASSOC, "ASSOC"}, {
++		BRCMF_E_ASSOC_IND, "ASSOC_IND"}, {
++		BRCMF_E_REASSOC, "REASSOC"}, {
++		BRCMF_E_REASSOC_IND, "REASSOC_IND"}, {
++		BRCMF_E_DISASSOC, "DISASSOC"}, {
++		BRCMF_E_DISASSOC_IND, "DISASSOC_IND"}, {
++		BRCMF_E_QUIET_START, "START_QUIET"}, {
++		BRCMF_E_QUIET_END, "END_QUIET"}, {
++		BRCMF_E_BEACON_RX, "BEACON_RX"}, {
++		BRCMF_E_LINK, "LINK"}, {
++		BRCMF_E_MIC_ERROR, "MIC_ERROR"}, {
++		BRCMF_E_NDIS_LINK, "NDIS_LINK"}, {
++		BRCMF_E_ROAM, "ROAM"}, {
++		BRCMF_E_TXFAIL, "TXFAIL"}, {
++		BRCMF_E_PMKID_CACHE, "PMKID_CACHE"}, {
++		BRCMF_E_RETROGRADE_TSF, "RETROGRADE_TSF"}, {
++		BRCMF_E_PRUNE, "PRUNE"}, {
++		BRCMF_E_AUTOAUTH, "AUTOAUTH"}, {
++		BRCMF_E_EAPOL_MSG, "EAPOL_MSG"}, {
++		BRCMF_E_SCAN_COMPLETE, "SCAN_COMPLETE"}, {
++		BRCMF_E_ADDTS_IND, "ADDTS_IND"}, {
++		BRCMF_E_DELTS_IND, "DELTS_IND"}, {
++		BRCMF_E_BCNSENT_IND, "BCNSENT_IND"}, {
++		BRCMF_E_BCNRX_MSG, "BCNRX_MSG"}, {
++		BRCMF_E_BCNLOST_MSG, "BCNLOST_MSG"}, {
++		BRCMF_E_ROAM_PREP, "ROAM_PREP"}, {
++		BRCMF_E_PFN_NET_FOUND, "PNO_NET_FOUND"}, {
++		BRCMF_E_PFN_NET_LOST, "PNO_NET_LOST"}, {
++		BRCMF_E_RESET_COMPLETE, "RESET_COMPLETE"}, {
++		BRCMF_E_JOIN_START, "JOIN_START"}, {
++		BRCMF_E_ROAM_START, "ROAM_START"}, {
++		BRCMF_E_ASSOC_START, "ASSOC_START"}, {
++		BRCMF_E_IBSS_ASSOC, "IBSS_ASSOC"}, {
++		BRCMF_E_RADIO, "RADIO"}, {
++		BRCMF_E_PSM_WATCHDOG, "PSM_WATCHDOG"}, {
++		BRCMF_E_PROBREQ_MSG, "PROBREQ_MSG"}, {
++		BRCMF_E_SCAN_CONFIRM_IND, "SCAN_CONFIRM_IND"}, {
++		BRCMF_E_PSK_SUP, "PSK_SUP"}, {
++		BRCMF_E_COUNTRY_CODE_CHANGED, "COUNTRY_CODE_CHANGED"}, {
++		BRCMF_E_EXCEEDED_MEDIUM_TIME, "EXCEEDED_MEDIUM_TIME"}, {
++		BRCMF_E_ICV_ERROR, "ICV_ERROR"}, {
++		BRCMF_E_UNICAST_DECODE_ERROR, "UNICAST_DECODE_ERROR"}, {
++		BRCMF_E_MULTICAST_DECODE_ERROR, "MULTICAST_DECODE_ERROR"}, {
++		BRCMF_E_TRACE, "TRACE"}, {
++		BRCMF_E_ACTION_FRAME, "ACTION FRAME"}, {
++		BRCMF_E_ACTION_FRAME_COMPLETE, "ACTION FRAME TX COMPLETE"}, {
++		BRCMF_E_IF, "IF"}, {
++		BRCMF_E_RSSI, "RSSI"}, {
++		BRCMF_E_PFN_SCAN_COMPLETE, "SCAN_COMPLETE"}
++	};
++	uint event_type, flags, auth_type, datalen;
++	static u32 seqnum_prev;
++	struct msgtrace_hdr hdr;
++	u32 nblost;
++	char *s, *p;
++
++	event_type = be32_to_cpu(event->event_type);
++	flags = be16_to_cpu(event->flags);
++	status = be32_to_cpu(event->status);
++	reason = be32_to_cpu(event->reason);
++	auth_type = be32_to_cpu(event->auth_type);
++	datalen = be32_to_cpu(event->datalen);
++	/* debug dump of event messages */
++	sprintf(eabuf, "%pM", event->addr);
++
++	event_name = "UNKNOWN";
++	for (i = 0; i < ARRAY_SIZE(event_names); i++) {
++		if (event_names[i].event == event_type)
++			event_name = event_names[i].event_name;
++	}
++
++	brcmf_dbg(EVENT, "EVENT: %s, event ID = %d\n", event_name, event_type);
++	brcmf_dbg(EVENT, "flags 0x%04x, status %d, reason %d, auth_type %d MAC %s\n",
++		  flags, status, reason, auth_type, eabuf);
++
++	if (flags & BRCMF_EVENT_MSG_LINK)
++		link = true;
++	if (flags & BRCMF_EVENT_MSG_GROUP)
++		group = true;
++	if (flags & BRCMF_EVENT_MSG_FLUSHTXQ)
++		flush_txq = true;
++
++	switch (event_type) {
++	case BRCMF_E_START:
++	case BRCMF_E_DEAUTH:
++	case BRCMF_E_DISASSOC:
++		brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s\n", event_name, eabuf);
++		break;
++
++	case BRCMF_E_ASSOC_IND:
++	case BRCMF_E_REASSOC_IND:
++		brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s\n", event_name, eabuf);
++		break;
++
++	case BRCMF_E_ASSOC:
++	case BRCMF_E_REASSOC:
++		if (status == BRCMF_E_STATUS_SUCCESS)
++			brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, SUCCESS\n",
++				  event_name, eabuf);
++		else if (status == BRCMF_E_STATUS_TIMEOUT)
++			brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, TIMEOUT\n",
++				  event_name, eabuf);
++		else if (status == BRCMF_E_STATUS_FAIL)
++			brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, FAILURE, reason %d\n",
++				  event_name, eabuf, (int)reason);
++		else
++			brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, unexpected status %d\n",
++				  event_name, eabuf, (int)status);
++		break;
++
++	case BRCMF_E_DEAUTH_IND:
++	case BRCMF_E_DISASSOC_IND:
++		brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, reason %d\n",
++			  event_name, eabuf, (int)reason);
++		break;
++
++	case BRCMF_E_AUTH:
++	case BRCMF_E_AUTH_IND:
++		if (auth_type == WLAN_AUTH_OPEN)
++			auth_str = "Open System";
++		else if (auth_type == WLAN_AUTH_SHARED_KEY)
++			auth_str = "Shared Key";
++		else {
++			sprintf(err_msg, "AUTH unknown: %d", (int)auth_type);
++			auth_str = err_msg;
++		}
++		if (event_type == BRCMF_E_AUTH_IND)
++			brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, %s\n",
++				  event_name, eabuf, auth_str);
++		else if (status == BRCMF_E_STATUS_SUCCESS)
++			brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, %s, SUCCESS\n",
++				  event_name, eabuf, auth_str);
++		else if (status == BRCMF_E_STATUS_TIMEOUT)
++			brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, %s, TIMEOUT\n",
++				  event_name, eabuf, auth_str);
++		else if (status == BRCMF_E_STATUS_FAIL) {
++			brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, %s, FAILURE, reason %d\n",
++				  event_name, eabuf, auth_str, (int)reason);
++		}
++
++		break;
++
++	case BRCMF_E_JOIN:
++	case BRCMF_E_ROAM:
++	case BRCMF_E_SET_SSID:
++		if (status == BRCMF_E_STATUS_SUCCESS)
++			brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s\n",
++				  event_name, eabuf);
++		else if (status == BRCMF_E_STATUS_FAIL)
++			brcmf_dbg(EVENT, "MACEVENT: %s, failed\n", event_name);
++		else if (status == BRCMF_E_STATUS_NO_NETWORKS)
++			brcmf_dbg(EVENT, "MACEVENT: %s, no networks found\n",
++				  event_name);
++		else
++			brcmf_dbg(EVENT, "MACEVENT: %s, unexpected status %d\n",
++				  event_name, (int)status);
++		break;
++
++	case BRCMF_E_BEACON_RX:
++		if (status == BRCMF_E_STATUS_SUCCESS)
++			brcmf_dbg(EVENT, "MACEVENT: %s, SUCCESS\n", event_name);
++		else if (status == BRCMF_E_STATUS_FAIL)
++			brcmf_dbg(EVENT, "MACEVENT: %s, FAIL\n", event_name);
++		else
++			brcmf_dbg(EVENT, "MACEVENT: %s, status %d\n",
++				  event_name, status);
++		break;
++
++	case BRCMF_E_LINK:
++		brcmf_dbg(EVENT, "MACEVENT: %s %s\n",
++			  event_name, link ? "UP" : "DOWN");
++		break;
++
++	case BRCMF_E_MIC_ERROR:
++		brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, Group %d, Flush %d\n",
++			  event_name, eabuf, group, flush_txq);
++		break;
++
++	case BRCMF_E_ICV_ERROR:
++	case BRCMF_E_UNICAST_DECODE_ERROR:
++	case BRCMF_E_MULTICAST_DECODE_ERROR:
++		brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s\n", event_name, eabuf);
++		break;
++
++	case BRCMF_E_TXFAIL:
++		brcmf_dbg(EVENT, "MACEVENT: %s, RA %s\n", event_name, eabuf);
++		break;
++
++	case BRCMF_E_SCAN_COMPLETE:
++	case BRCMF_E_PMKID_CACHE:
++		brcmf_dbg(EVENT, "MACEVENT: %s\n", event_name);
++		break;
++
++	case BRCMF_E_PFN_NET_FOUND:
++	case BRCMF_E_PFN_NET_LOST:
++	case BRCMF_E_PFN_SCAN_COMPLETE:
++		brcmf_dbg(EVENT, "PNOEVENT: %s\n", event_name);
++		break;
++
++	case BRCMF_E_PSK_SUP:
++	case BRCMF_E_PRUNE:
++		brcmf_dbg(EVENT, "MACEVENT: %s, status %d, reason %d\n",
++			  event_name, (int)status, (int)reason);
++		break;
++
++	case BRCMF_E_TRACE:
++		buf = (unsigned char *) event_data;
++		memcpy(&hdr, buf, sizeof(struct msgtrace_hdr));
++
++		if (hdr.version != MSGTRACE_VERSION) {
++			brcmf_dbg(ERROR,
++				  "MACEVENT: %s [unsupported version --> brcmf"
++				  " version:%d dongle version:%d]\n",
++				  event_name, MSGTRACE_VERSION, hdr.version);
++			/* Reset datalen to avoid display below */
++			datalen = 0;
++			break;
++		}
++
++		/* There are 2 bytes available at the end of data */
++		*(buf + sizeof(struct msgtrace_hdr)
++			 + be16_to_cpu(hdr.len)) = '\0';
++
++		if (be32_to_cpu(hdr.discarded_bytes)
++		    || be32_to_cpu(hdr.discarded_printf))
++			brcmf_dbg(ERROR,
++				  "WLC_E_TRACE: [Discarded traces in dongle -->"
++				  " discarded_bytes %d discarded_printf %d]\n",
++				  be32_to_cpu(hdr.discarded_bytes),
++				  be32_to_cpu(hdr.discarded_printf));
++
++		nblost = be32_to_cpu(hdr.seqnum) - seqnum_prev - 1;
++		if (nblost > 0)
++			brcmf_dbg(ERROR, "WLC_E_TRACE: [Event lost --> seqnum "
++				  " %d nblost %d\n", be32_to_cpu(hdr.seqnum),
++				  nblost);
++		seqnum_prev = be32_to_cpu(hdr.seqnum);
++
++		/* Display the trace buffer. Advance from \n to \n to
++		 * avoid display big
++		 * printf (issue with Linux printk )
++		 */
++		p = (char *)&buf[sizeof(struct msgtrace_hdr)];
++		while ((s = strstr(p, "\n")) != NULL) {
++			*s = '\0';
++			pr_debug("%s\n", p);
++			p = s + 1;
++		}
++		pr_debug("%s\n", p);
++
++		/* Reset datalen to avoid display below */
++		datalen = 0;
++		break;
++
++	case BRCMF_E_RSSI:
++		brcmf_dbg(EVENT, "MACEVENT: %s %d\n",
++			  event_name, be32_to_cpu(*((__be32 *)event_data)));
++		break;
++
++	default:
++		brcmf_dbg(EVENT,
++			  "MACEVENT: %s %d, MAC %s, status %d, reason %d, "
++			  "auth %d\n", event_name, event_type, eabuf,
++			  (int)status, (int)reason, (int)auth_type);
++		break;
++	}
++
++	/* show any appended data */
++	if (datalen) {
++		buf = (unsigned char *) event_data;
++		brcmf_dbg(EVENT, " data (%d) : ", datalen);
++		for (i = 0; i < datalen; i++)
++			brcmf_dbg(EVENT, " 0x%02x ", *buf++);
++		brcmf_dbg(EVENT, "\n");
++	}
++}
++#endif				/* DEBUG */
++
++int
++brcmf_c_host_event(struct brcmf_pub *drvr, int *ifidx, void *pktdata,
++		   struct brcmf_event_msg *event, void **data_ptr)
++{
++	/* check whether packet is a BRCM event pkt */
++	struct brcmf_event *pvt_data = (struct brcmf_event *) pktdata;
++	struct brcmf_if_event *ifevent;
++	char *event_data;
++	u32 type, status;
++	u16 flags;
++	int evlen;
++
++	if (memcmp(BRCM_OUI, &pvt_data->hdr.oui[0], DOT11_OUI_LEN)) {
++		brcmf_dbg(ERROR, "mismatched OUI, bailing\n");
++		return -EBADE;
++	}
++
++	/* BRCM event pkt may be unaligned - use xxx_ua to load user_subtype. */
++	if (get_unaligned_be16(&pvt_data->hdr.usr_subtype) !=
++	    BCMILCP_BCM_SUBTYPE_EVENT) {
++		brcmf_dbg(ERROR, "mismatched subtype, bailing\n");
++		return -EBADE;
++	}
++
++	*data_ptr = &pvt_data[1];
++	event_data = *data_ptr;
++
++	/* memcpy since BRCM event pkt may be unaligned. */
++	memcpy(event, &pvt_data->msg, sizeof(struct brcmf_event_msg));
++
++	type = get_unaligned_be32(&event->event_type);
++	flags = get_unaligned_be16(&event->flags);
++	status = get_unaligned_be32(&event->status);
++	evlen = get_unaligned_be32(&event->datalen) +
++		sizeof(struct brcmf_event);
++
++	switch (type) {
++	case BRCMF_E_IF:
++		ifevent = (struct brcmf_if_event *) event_data;
++		brcmf_dbg(TRACE, "if event\n");
++
++		if (ifevent->ifidx > 0 && ifevent->ifidx < BRCMF_MAX_IFS) {
++			if (ifevent->action == BRCMF_E_IF_ADD)
++				brcmf_add_if(drvr->dev, ifevent->ifidx,
++					     event->ifname,
++					     pvt_data->eth.h_dest);
++			else
++				brcmf_del_if(drvr, ifevent->ifidx);
++		} else {
++			brcmf_dbg(ERROR, "Invalid ifidx %d for %s\n",
++				  ifevent->ifidx, event->ifname);
++		}
++
++		/* send up the if event: btamp user needs it */
++		*ifidx = brcmf_ifname2idx(drvr, event->ifname);
++		break;
++
++		/* These are what external supplicant/authenticator wants */
++	case BRCMF_E_LINK:
++	case BRCMF_E_ASSOC_IND:
++	case BRCMF_E_REASSOC_IND:
++	case BRCMF_E_DISASSOC_IND:
++	case BRCMF_E_MIC_ERROR:
++	default:
++		/* Fall through: this should get _everything_  */
++
++		*ifidx = brcmf_ifname2idx(drvr, event->ifname);
++		brcmf_dbg(TRACE, "MAC event %d, flags %x, status %x\n",
++			  type, flags, status);
++
++		/* put it back to BRCMF_E_NDIS_LINK */
++		if (type == BRCMF_E_NDIS_LINK) {
++			u32 temp1;
++			__be32 temp2;
++
++			temp1 = get_unaligned_be32(&event->event_type);
++			brcmf_dbg(TRACE, "Converted to WLC_E_LINK type %d\n",
++				  temp1);
++
++			temp2 = cpu_to_be32(BRCMF_E_NDIS_LINK);
++			memcpy((void *)(&pvt_data->msg.event_type), &temp2,
++			       sizeof(pvt_data->msg.event_type));
++		}
++		break;
++	}
++
++#ifdef DEBUG
++	brcmf_c_show_host_event(event, event_data);
++#endif				/* DEBUG */
++
++	return 0;
++}
++
++/* Convert user's input in hex pattern to byte-size mask */
++static int brcmf_c_pattern_atoh(char *src, char *dst)
++{
++	int i;
++	if (strncmp(src, "0x", 2) != 0 && strncmp(src, "0X", 2) != 0) {
++		brcmf_dbg(ERROR, "Mask invalid format. Needs to start with 0x\n");
++		return -EINVAL;
++	}
++	src = src + 2;		/* Skip past 0x */
++	if (strlen(src) % 2 != 0) {
++		brcmf_dbg(ERROR, "Mask invalid format. Length must be even.\n");
++		return -EINVAL;
++	}
++	for (i = 0; *src != '\0'; i++) {
++		unsigned long res;
++		char num[3];
++		strncpy(num, src, 2);
++		num[2] = '\0';
++		if (kstrtoul(num, 16, &res))
++			return -EINVAL;
++		dst[i] = (u8)res;
++		src += 2;
++	}
++	return i;
++}
++
++void
++brcmf_c_pktfilter_offload_enable(struct brcmf_pub *drvr, char *arg, int enable,
++			     int master_mode)
++{
++	unsigned long res;
++	char *argv[8];
++	int i = 0;
++	const char *str;
++	int buf_len;
++	int str_len;
++	char *arg_save = NULL, *arg_org = NULL;
++	int rc;
++	char buf[128];
++	struct brcmf_pkt_filter_enable_le enable_parm;
++	struct brcmf_pkt_filter_enable_le *pkt_filterp;
++	__le32 mmode_le;
++
++	arg_save = kmalloc(strlen(arg) + 1, GFP_ATOMIC);
++	if (!arg_save)
++		goto fail;
++
++	arg_org = arg_save;
++	memcpy(arg_save, arg, strlen(arg) + 1);
++
++	argv[i] = strsep(&arg_save, " ");
++
++	i = 0;
++	if (NULL == argv[i]) {
++		brcmf_dbg(ERROR, "No args provided\n");
++		goto fail;
++	}
++
++	str = "pkt_filter_enable";
++	str_len = strlen(str);
++	strncpy(buf, str, str_len);
++	buf[str_len] = '\0';
++	buf_len = str_len + 1;
++
++	pkt_filterp = (struct brcmf_pkt_filter_enable_le *) (buf + str_len + 1);
++
++	/* Parse packet filter id. */
++	enable_parm.id = 0;
++	if (!kstrtoul(argv[i], 0, &res))
++		enable_parm.id = cpu_to_le32((u32)res);
++
++	/* Parse enable/disable value. */
++	enable_parm.enable = cpu_to_le32(enable);
++
++	buf_len += sizeof(enable_parm);
++	memcpy((char *)pkt_filterp, &enable_parm, sizeof(enable_parm));
++
++	/* Enable/disable the specified filter. */
++	rc = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, buf, buf_len);
++	rc = rc >= 0 ? 0 : rc;
++	if (rc)
++		brcmf_dbg(TRACE, "failed to add pktfilter %s, retcode = %d\n",
++			  arg, rc);
++	else
++		brcmf_dbg(TRACE, "successfully added pktfilter %s\n", arg);
++
++	/* Contorl the master mode */
++	mmode_le = cpu_to_le32(master_mode);
++	brcmf_c_mkiovar("pkt_filter_mode", (char *)&mmode_le, 4, buf,
++		    sizeof(buf));
++	rc = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, buf,
++				       sizeof(buf));
++	rc = rc >= 0 ? 0 : rc;
++	if (rc)
++		brcmf_dbg(TRACE, "failed to add pktfilter %s, retcode = %d\n",
++			  arg, rc);
++
++fail:
++	kfree(arg_org);
++}
++
++void brcmf_c_pktfilter_offload_set(struct brcmf_pub *drvr, char *arg)
++{
++	const char *str;
++	struct brcmf_pkt_filter_le pkt_filter;
++	struct brcmf_pkt_filter_le *pkt_filterp;
++	unsigned long res;
++	int buf_len;
++	int str_len;
++	int rc;
++	u32 mask_size;
++	u32 pattern_size;
++	char *argv[8], *buf = NULL;
++	int i = 0;
++	char *arg_save = NULL, *arg_org = NULL;
++
++	arg_save = kstrdup(arg, GFP_ATOMIC);
++	if (!arg_save)
++		goto fail;
++
++	arg_org = arg_save;
++
++	buf = kmalloc(PKTFILTER_BUF_SIZE, GFP_ATOMIC);
++	if (!buf)
++		goto fail;
++
++	argv[i] = strsep(&arg_save, " ");
++	while (argv[i++])
++		argv[i] = strsep(&arg_save, " ");
++
++	i = 0;
++	if (NULL == argv[i]) {
++		brcmf_dbg(ERROR, "No args provided\n");
++		goto fail;
++	}
++
++	str = "pkt_filter_add";
++	strcpy(buf, str);
++	str_len = strlen(str);
++	buf_len = str_len + 1;
++
++	pkt_filterp = (struct brcmf_pkt_filter_le *) (buf + str_len + 1);
++
++	/* Parse packet filter id. */
++	pkt_filter.id = 0;
++	if (!kstrtoul(argv[i], 0, &res))
++		pkt_filter.id = cpu_to_le32((u32)res);
++
++	if (NULL == argv[++i]) {
++		brcmf_dbg(ERROR, "Polarity not provided\n");
++		goto fail;
++	}
++
++	/* Parse filter polarity. */
++	pkt_filter.negate_match = 0;
++	if (!kstrtoul(argv[i], 0, &res))
++		pkt_filter.negate_match = cpu_to_le32((u32)res);
++
++	if (NULL == argv[++i]) {
++		brcmf_dbg(ERROR, "Filter type not provided\n");
++		goto fail;
++	}
++
++	/* Parse filter type. */
++	pkt_filter.type = 0;
++	if (!kstrtoul(argv[i], 0, &res))
++		pkt_filter.type = cpu_to_le32((u32)res);
++
++	if (NULL == argv[++i]) {
++		brcmf_dbg(ERROR, "Offset not provided\n");
++		goto fail;
++	}
++
++	/* Parse pattern filter offset. */
++	pkt_filter.u.pattern.offset = 0;
++	if (!kstrtoul(argv[i], 0, &res))
++		pkt_filter.u.pattern.offset = cpu_to_le32((u32)res);
++
++	if (NULL == argv[++i]) {
++		brcmf_dbg(ERROR, "Bitmask not provided\n");
++		goto fail;
++	}
++
++	/* Parse pattern filter mask. */
++	mask_size =
++	    brcmf_c_pattern_atoh
++		   (argv[i], (char *)pkt_filterp->u.pattern.mask_and_pattern);
++
++	if (NULL == argv[++i]) {
++		brcmf_dbg(ERROR, "Pattern not provided\n");
++		goto fail;
++	}
++
++	/* Parse pattern filter pattern. */
++	pattern_size =
++	    brcmf_c_pattern_atoh(argv[i],
++				   (char *)&pkt_filterp->u.pattern.
++				   mask_and_pattern[mask_size]);
++
++	if (mask_size != pattern_size) {
++		brcmf_dbg(ERROR, "Mask and pattern not the same size\n");
++		goto fail;
++	}
++
++	pkt_filter.u.pattern.size_bytes = cpu_to_le32(mask_size);
++	buf_len += BRCMF_PKT_FILTER_FIXED_LEN;
++	buf_len += (BRCMF_PKT_FILTER_PATTERN_FIXED_LEN + 2 * mask_size);
++
++	/* Keep-alive attributes are set in local
++	 * variable (keep_alive_pkt), and
++	 ** then memcpy'ed into buffer (keep_alive_pktp) since there is no
++	 ** guarantee that the buffer is properly aligned.
++	 */
++	memcpy((char *)pkt_filterp,
++	       &pkt_filter,
++	       BRCMF_PKT_FILTER_FIXED_LEN + BRCMF_PKT_FILTER_PATTERN_FIXED_LEN);
++
++	rc = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, buf, buf_len);
++	rc = rc >= 0 ? 0 : rc;
++
++	if (rc)
++		brcmf_dbg(TRACE, "failed to add pktfilter %s, retcode = %d\n",
++			  arg, rc);
++	else
++		brcmf_dbg(TRACE, "successfully added pktfilter %s\n", arg);
++
++fail:
++	kfree(arg_org);
++
++	kfree(buf);
++}
++
++static void brcmf_c_arp_offload_set(struct brcmf_pub *drvr, int arp_mode)
++{
++	char iovbuf[32];
++	int retcode;
++
++	brcmf_c_mkiovar("arp_ol", (char *)&arp_mode, 4, iovbuf, sizeof(iovbuf));
++	retcode = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR,
++				   iovbuf, sizeof(iovbuf));
++	retcode = retcode >= 0 ? 0 : retcode;
++	if (retcode)
++		brcmf_dbg(TRACE, "failed to set ARP offload mode to 0x%x, retcode = %d\n",
++			  arp_mode, retcode);
++	else
++		brcmf_dbg(TRACE, "successfully set ARP offload mode to 0x%x\n",
++			  arp_mode);
++}
++
++static void brcmf_c_arp_offload_enable(struct brcmf_pub *drvr, int arp_enable)
++{
++	char iovbuf[32];
++	int retcode;
++
++	brcmf_c_mkiovar("arpoe", (char *)&arp_enable, 4,
++			iovbuf, sizeof(iovbuf));
++	retcode = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR,
++				   iovbuf, sizeof(iovbuf));
++	retcode = retcode >= 0 ? 0 : retcode;
++	if (retcode)
++		brcmf_dbg(TRACE, "failed to enable ARP offload to %d, retcode = %d\n",
++			  arp_enable, retcode);
++	else
++		brcmf_dbg(TRACE, "successfully enabled ARP offload to %d\n",
++			  arp_enable);
++}
++
++int brcmf_c_preinit_dcmds(struct brcmf_pub *drvr)
++{
++	char iovbuf[BRCMF_EVENTING_MASK_LEN + 12];	/*  Room for
++				 "event_msgs" + '\0' + bitvec  */
++	char buf[128], *ptr;
++	u32 dongle_align = drvr->bus_if->align;
++	u32 glom = 0;
++	u32 roaming = 1;
++	uint bcn_timeout = 3;
++	int scan_assoc_time = 40;
++	int scan_unassoc_time = 40;
++	int i;
++
++	mutex_lock(&drvr->proto_block);
++
++	/* Set Country code */
++	if (drvr->country_code[0] != 0) {
++		if (brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_COUNTRY,
++					      drvr->country_code,
++					      sizeof(drvr->country_code)) < 0)
++			brcmf_dbg(ERROR, "country code setting failed\n");
++	}
++
++	/* query for 'ver' to get version info from firmware */
++	memset(buf, 0, sizeof(buf));
++	ptr = buf;
++	brcmf_c_mkiovar("ver", NULL, 0, buf, sizeof(buf));
++	brcmf_proto_cdc_query_dcmd(drvr, 0, BRCMF_C_GET_VAR, buf, sizeof(buf));
++	strsep(&ptr, "\n");
++	/* Print fw version info */
++	brcmf_dbg(ERROR, "Firmware version = %s\n", buf);
++
++	/* Match Host and Dongle rx alignment */
++	brcmf_c_mkiovar("bus:txglomalign", (char *)&dongle_align, 4, iovbuf,
++		    sizeof(iovbuf));
++	brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf,
++				  sizeof(iovbuf));
++
++	/* disable glom option per default */
++	brcmf_c_mkiovar("bus:txglom", (char *)&glom, 4, iovbuf, sizeof(iovbuf));
++	brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf,
++				  sizeof(iovbuf));
++
++	/* Setup timeout if Beacons are lost and roam is off to report
++		 link down */
++	brcmf_c_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, iovbuf,
++		    sizeof(iovbuf));
++	brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf,
++				  sizeof(iovbuf));
++
++	/* Enable/Disable build-in roaming to allowed ext supplicant to take
++		 of romaing */
++	brcmf_c_mkiovar("roam_off", (char *)&roaming, 4,
++		      iovbuf, sizeof(iovbuf));
++	brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf,
++				  sizeof(iovbuf));
++
++	/* Setup event_msgs */
++	brcmf_c_mkiovar("event_msgs", drvr->eventmask, BRCMF_EVENTING_MASK_LEN,
++		      iovbuf, sizeof(iovbuf));
++	brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf,
++				  sizeof(iovbuf));
++
++	brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_SCAN_CHANNEL_TIME,
++			 (char *)&scan_assoc_time, sizeof(scan_assoc_time));
++	brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_SCAN_UNASSOC_TIME,
++			 (char *)&scan_unassoc_time, sizeof(scan_unassoc_time));
++
++	/* Set and enable ARP offload feature */
++	brcmf_c_arp_offload_set(drvr, BRCMF_ARPOL_MODE);
++	brcmf_c_arp_offload_enable(drvr, true);
++
++	/* Set up pkt filter */
++	for (i = 0; i < drvr->pktfilter_count; i++) {
++		brcmf_c_pktfilter_offload_set(drvr, drvr->pktfilter[i]);
++		brcmf_c_pktfilter_offload_enable(drvr, drvr->pktfilter[i],
++						 0, true);
++	}
++
++	mutex_unlock(&drvr->proto_block);
++
++	return 0;
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
+new file mode 100644
+index 0000000..a2c4576
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
+@@ -0,0 +1,79 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef _BRCMF_DBG_H_
++#define _BRCMF_DBG_H_
++
++/* message levels */
++#define BRCMF_ERROR_VAL	0x0001
++#define BRCMF_TRACE_VAL	0x0002
++#define BRCMF_INFO_VAL	0x0004
++#define BRCMF_DATA_VAL	0x0008
++#define BRCMF_CTL_VAL	0x0010
++#define BRCMF_TIMER_VAL	0x0020
++#define BRCMF_HDRS_VAL	0x0040
++#define BRCMF_BYTES_VAL	0x0080
++#define BRCMF_INTR_VAL	0x0100
++#define BRCMF_GLOM_VAL	0x0400
++#define BRCMF_EVENT_VAL	0x0800
++#define BRCMF_BTA_VAL	0x1000
++#define BRCMF_ISCAN_VAL 0x2000
++
++#if defined(DEBUG)
++
++#define brcmf_dbg(level, fmt, ...)					\
++do {									\
++	if (BRCMF_ERROR_VAL == BRCMF_##level##_VAL) {			\
++		if (brcmf_msg_level & BRCMF_##level##_VAL) {		\
++			if (net_ratelimit())				\
++				pr_debug("%s: " fmt,			\
++					 __func__, ##__VA_ARGS__);	\
++		}							\
++	} else {							\
++		if (brcmf_msg_level & BRCMF_##level##_VAL) {		\
++			pr_debug("%s: " fmt,				\
++				 __func__, ##__VA_ARGS__);		\
++		}							\
++	}								\
++} while (0)
++
++#define BRCMF_DATA_ON()		(brcmf_msg_level & BRCMF_DATA_VAL)
++#define BRCMF_CTL_ON()		(brcmf_msg_level & BRCMF_CTL_VAL)
++#define BRCMF_HDRS_ON()		(brcmf_msg_level & BRCMF_HDRS_VAL)
++#define BRCMF_BYTES_ON()	(brcmf_msg_level & BRCMF_BYTES_VAL)
++#define BRCMF_GLOM_ON()		(brcmf_msg_level & BRCMF_GLOM_VAL)
++
++#else	/* (defined DEBUG) || (defined DEBUG) */
++
++#define brcmf_dbg(level, fmt, ...) no_printk(fmt, ##__VA_ARGS__)
++
++#define BRCMF_DATA_ON()		0
++#define BRCMF_CTL_ON()		0
++#define BRCMF_HDRS_ON()		0
++#define BRCMF_BYTES_ON()	0
++#define BRCMF_GLOM_ON()		0
++
++#endif				/* defined(DEBUG) */
++
++#define brcmf_dbg_hex_dump(test, data, len, fmt, ...)			\
++do {									\
++	if (test)							\
++		brcmu_dbg_hex_dump(data, len, fmt, ##__VA_ARGS__);	\
++} while (0)
++
++extern int brcmf_msg_level;
++
++#endif				/* _BRCMF_DBG_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+new file mode 100644
+index 0000000..7c42840
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+@@ -0,0 +1,1232 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#undef pr_fmt
++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
++
++#include <linux/version.h>
++#include <linux/init.h>
++#include <linux/kernel.h>
++#include <linux/printk.h>
++#include <linux/kthread.h>
++#include <linux/slab.h>
++#include <linux/skbuff.h>
++#include <linux/netdevice.h>
++#include <linux/etherdevice.h>
++#include <linux/mmc/sdio_func.h>
++#include <linux/random.h>
++#include <linux/spinlock.h>
++#include <linux/ethtool.h>
++#include <linux/fcntl.h>
++#include <linux/fs.h>
++#include <linux/uaccess.h>
++#include <linux/hardirq.h>
++#include <linux/mutex.h>
++#include <linux/wait.h>
++#include <linux/module.h>
++#include <net/cfg80211.h>
++#include <net/rtnetlink.h>
++#include <defs.h>
++#include <brcmu_utils.h>
++#include <brcmu_wifi.h>
++
++#include "dhd.h"
++#include "dhd_bus.h"
++#include "dhd_proto.h"
++#include "dhd_dbg.h"
++#include "wl_cfg80211.h"
++
++MODULE_AUTHOR("Broadcom Corporation");
++MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN fullmac driver.");
++MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN fullmac cards");
++MODULE_LICENSE("Dual BSD/GPL");
++
++
++/* Interface control information */
++struct brcmf_if {
++	struct brcmf_pub *drvr;	/* back pointer to brcmf_pub */
++	/* OS/stack specifics */
++	struct net_device *ndev;
++	struct net_device_stats stats;
++	int idx;		/* iface idx in dongle */
++	u8 mac_addr[ETH_ALEN];	/* assigned MAC address */
++};
++
++/* Error bits */
++int brcmf_msg_level = BRCMF_ERROR_VAL;
++module_param(brcmf_msg_level, int, 0);
++
++int brcmf_ifname2idx(struct brcmf_pub *drvr, char *name)
++{
++	int i = BRCMF_MAX_IFS;
++	struct brcmf_if *ifp;
++
++	if (name == NULL || *name == '\0')
++		return 0;
++
++	while (--i > 0) {
++		ifp = drvr->iflist[i];
++		if (ifp && !strncmp(ifp->ndev->name, name, IFNAMSIZ))
++			break;
++	}
++
++	brcmf_dbg(TRACE, "return idx %d for \"%s\"\n", i, name);
++
++	return i;		/* default - the primary interface */
++}
++
++char *brcmf_ifname(struct brcmf_pub *drvr, int ifidx)
++{
++	if (ifidx < 0 || ifidx >= BRCMF_MAX_IFS) {
++		brcmf_dbg(ERROR, "ifidx %d out of range\n", ifidx);
++		return "<if_bad>";
++	}
++
++	if (drvr->iflist[ifidx] == NULL) {
++		brcmf_dbg(ERROR, "null i/f %d\n", ifidx);
++		return "<if_null>";
++	}
++
++	if (drvr->iflist[ifidx]->ndev)
++		return drvr->iflist[ifidx]->ndev->name;
++
++	return "<if_none>";
++}
++
++static void _brcmf_set_multicast_list(struct work_struct *work)
++{
++	struct net_device *ndev;
++	struct netdev_hw_addr *ha;
++	u32 dcmd_value, cnt;
++	__le32 cnt_le;
++	__le32 dcmd_le_value;
++
++	struct brcmf_dcmd dcmd;
++	char *buf, *bufp;
++	uint buflen;
++	int ret;
++
++	struct brcmf_pub *drvr = container_of(work, struct brcmf_pub,
++						    multicast_work);
++
++	ndev = drvr->iflist[0]->ndev;
++	cnt = netdev_mc_count(ndev);
++
++	/* Determine initial value of allmulti flag */
++	dcmd_value = (ndev->flags & IFF_ALLMULTI) ? true : false;
++
++	/* Send down the multicast list first. */
++
++	buflen = sizeof("mcast_list") + sizeof(cnt) + (cnt * ETH_ALEN);
++	bufp = buf = kmalloc(buflen, GFP_ATOMIC);
++	if (!bufp)
++		return;
++
++	strcpy(bufp, "mcast_list");
++	bufp += strlen("mcast_list") + 1;
++
++	cnt_le = cpu_to_le32(cnt);
++	memcpy(bufp, &cnt_le, sizeof(cnt));
++	bufp += sizeof(cnt_le);
++
++	netdev_for_each_mc_addr(ha, ndev) {
++		if (!cnt)
++			break;
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
++		memcpy(bufp, ha->addr, ETH_ALEN);
++#else
++		memcpy(bufp, ha->dmi_addr, ETH_ALEN);
++#endif
++		bufp += ETH_ALEN;
++		cnt--;
++	}
++
++	memset(&dcmd, 0, sizeof(dcmd));
++	dcmd.cmd = BRCMF_C_SET_VAR;
++	dcmd.buf = buf;
++	dcmd.len = buflen;
++	dcmd.set = true;
++
++	ret = brcmf_proto_dcmd(drvr, 0, &dcmd, dcmd.len);
++	if (ret < 0) {
++		brcmf_dbg(ERROR, "%s: set mcast_list failed, cnt %d\n",
++			  brcmf_ifname(drvr, 0), cnt);
++		dcmd_value = cnt ? true : dcmd_value;
++	}
++
++	kfree(buf);
++
++	/* Now send the allmulti setting.  This is based on the setting in the
++	 * net_device flags, but might be modified above to be turned on if we
++	 * were trying to set some addresses and dongle rejected it...
++	 */
++
++	buflen = sizeof("allmulti") + sizeof(dcmd_value);
++	buf = kmalloc(buflen, GFP_ATOMIC);
++	if (!buf)
++		return;
++
++	dcmd_le_value = cpu_to_le32(dcmd_value);
++
++	if (!brcmf_c_mkiovar
++	    ("allmulti", (void *)&dcmd_le_value,
++	    sizeof(dcmd_le_value), buf, buflen)) {
++		brcmf_dbg(ERROR, "%s: mkiovar failed for allmulti, datalen %d buflen %u\n",
++			  brcmf_ifname(drvr, 0),
++			  (int)sizeof(dcmd_value), buflen);
++		kfree(buf);
++		return;
++	}
++
++	memset(&dcmd, 0, sizeof(dcmd));
++	dcmd.cmd = BRCMF_C_SET_VAR;
++	dcmd.buf = buf;
++	dcmd.len = buflen;
++	dcmd.set = true;
++
++	ret = brcmf_proto_dcmd(drvr, 0, &dcmd, dcmd.len);
++	if (ret < 0) {
++		brcmf_dbg(ERROR, "%s: set allmulti %d failed\n",
++			  brcmf_ifname(drvr, 0),
++			  le32_to_cpu(dcmd_le_value));
++	}
++
++	kfree(buf);
++
++	/* Finally, pick up the PROMISC flag as well, like the NIC
++		 driver does */
++
++	dcmd_value = (ndev->flags & IFF_PROMISC) ? true : false;
++	dcmd_le_value = cpu_to_le32(dcmd_value);
++
++	memset(&dcmd, 0, sizeof(dcmd));
++	dcmd.cmd = BRCMF_C_SET_PROMISC;
++	dcmd.buf = &dcmd_le_value;
++	dcmd.len = sizeof(dcmd_le_value);
++	dcmd.set = true;
++
++	ret = brcmf_proto_dcmd(drvr, 0, &dcmd, dcmd.len);
++	if (ret < 0) {
++		brcmf_dbg(ERROR, "%s: set promisc %d failed\n",
++			  brcmf_ifname(drvr, 0),
++			  le32_to_cpu(dcmd_le_value));
++	}
++}
++
++static void
++_brcmf_set_mac_address(struct work_struct *work)
++{
++	char buf[32];
++	struct brcmf_dcmd dcmd;
++	int ret;
++
++	struct brcmf_pub *drvr = container_of(work, struct brcmf_pub,
++						    setmacaddr_work);
++
++	brcmf_dbg(TRACE, "enter\n");
++	if (!brcmf_c_mkiovar("cur_etheraddr", (char *)drvr->macvalue,
++			   ETH_ALEN, buf, 32)) {
++		brcmf_dbg(ERROR, "%s: mkiovar failed for cur_etheraddr\n",
++			  brcmf_ifname(drvr, 0));
++		return;
++	}
++	memset(&dcmd, 0, sizeof(dcmd));
++	dcmd.cmd = BRCMF_C_SET_VAR;
++	dcmd.buf = buf;
++	dcmd.len = 32;
++	dcmd.set = true;
++
++	ret = brcmf_proto_dcmd(drvr, 0, &dcmd, dcmd.len);
++	if (ret < 0)
++		brcmf_dbg(ERROR, "%s: set cur_etheraddr failed\n",
++			  brcmf_ifname(drvr, 0));
++	else
++		memcpy(drvr->iflist[0]->ndev->dev_addr,
++		       drvr->macvalue, ETH_ALEN);
++
++	return;
++}
++
++static int brcmf_netdev_set_mac_address(struct net_device *ndev, void *addr)
++{
++	struct brcmf_if *ifp = netdev_priv(ndev);
++	struct brcmf_pub *drvr = ifp->drvr;
++	struct sockaddr *sa = (struct sockaddr *)addr;
++
++	memcpy(&drvr->macvalue, sa->sa_data, ETH_ALEN);
++	schedule_work(&drvr->setmacaddr_work);
++	return 0;
++}
++
++static void brcmf_netdev_set_multicast_list(struct net_device *ndev)
++{
++	struct brcmf_if *ifp = netdev_priv(ndev);
++	struct brcmf_pub *drvr = ifp->drvr;
++
++	schedule_work(&drvr->multicast_work);
++}
++
++int brcmf_sendpkt(struct brcmf_pub *drvr, int ifidx, struct sk_buff *pktbuf)
++{
++	/* Reject if down */
++	if (!drvr->bus_if->drvr_up || (drvr->bus_if->state == BRCMF_BUS_DOWN))
++		return -ENODEV;
++
++	/* Update multicast statistic */
++	if (pktbuf->len >= ETH_ALEN) {
++		u8 *pktdata = (u8 *) (pktbuf->data);
++		struct ethhdr *eh = (struct ethhdr *)pktdata;
++
++		if (is_multicast_ether_addr(eh->h_dest))
++			drvr->tx_multicast++;
++		if (ntohs(eh->h_proto) == ETH_P_PAE)
++			atomic_inc(&drvr->pend_8021x_cnt);
++	}
++
++	/* If the protocol uses a data header, apply it */
++	brcmf_proto_hdrpush(drvr, ifidx, pktbuf);
++
++	/* Use bus module to send data frame */
++	return drvr->bus_if->brcmf_bus_txdata(drvr->dev, pktbuf);
++}
++
++static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *ndev)
++{
++	int ret;
++	struct brcmf_if *ifp = netdev_priv(ndev);
++	struct brcmf_pub *drvr = ifp->drvr;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* Reject if down */
++	if (!drvr->bus_if->drvr_up ||
++	    (drvr->bus_if->state == BRCMF_BUS_DOWN)) {
++		brcmf_dbg(ERROR, "xmit rejected drvup=%d state=%d\n",
++			  drvr->bus_if->drvr_up,
++			  drvr->bus_if->state);
++		netif_stop_queue(ndev);
++		return -ENODEV;
++	}
++
++	if (!drvr->iflist[ifp->idx]) {
++		brcmf_dbg(ERROR, "bad ifidx %d\n", ifp->idx);
++		netif_stop_queue(ndev);
++		return -ENODEV;
++	}
++
++	/* Make sure there's enough room for any header */
++	if (skb_headroom(skb) < drvr->hdrlen) {
++		struct sk_buff *skb2;
++
++		brcmf_dbg(INFO, "%s: insufficient headroom\n",
++			  brcmf_ifname(drvr, ifp->idx));
++		drvr->bus_if->tx_realloc++;
++		skb2 = skb_realloc_headroom(skb, drvr->hdrlen);
++		dev_kfree_skb(skb);
++		skb = skb2;
++		if (skb == NULL) {
++			brcmf_dbg(ERROR, "%s: skb_realloc_headroom failed\n",
++				  brcmf_ifname(drvr, ifp->idx));
++			ret = -ENOMEM;
++			goto done;
++		}
++	}
++
++	ret = brcmf_sendpkt(drvr, ifp->idx, skb);
++
++done:
++	if (ret)
++		drvr->bus_if->dstats.tx_dropped++;
++	else
++		drvr->bus_if->dstats.tx_packets++;
++
++	/* Return ok: we always eat the packet */
++	return 0;
++}
++
++void brcmf_txflowcontrol(struct device *dev, int ifidx, bool state)
++{
++	struct net_device *ndev;
++	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
++	struct brcmf_pub *drvr = bus_if->drvr;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	ndev = drvr->iflist[ifidx]->ndev;
++	if (state == ON)
++		netif_stop_queue(ndev);
++	else
++		netif_wake_queue(ndev);
++}
++
++static int brcmf_host_event(struct brcmf_pub *drvr, int *ifidx,
++			    void *pktdata, struct brcmf_event_msg *event,
++			    void **data)
++{
++	int bcmerror = 0;
++
++	bcmerror = brcmf_c_host_event(drvr, ifidx, pktdata, event, data);
++	if (bcmerror != 0)
++		return bcmerror;
++
++	if (drvr->iflist[*ifidx]->ndev)
++		brcmf_cfg80211_event(drvr->iflist[*ifidx]->ndev,
++				     event, *data);
++
++	return bcmerror;
++}
++
++void brcmf_rx_frame(struct device *dev, int ifidx,
++		    struct sk_buff_head *skb_list)
++{
++	unsigned char *eth;
++	uint len;
++	void *data;
++	struct sk_buff *skb, *pnext;
++	struct brcmf_if *ifp;
++	struct brcmf_event_msg event;
++	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
++	struct brcmf_pub *drvr = bus_if->drvr;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	skb_queue_walk_safe(skb_list, skb, pnext) {
++		skb_unlink(skb, skb_list);
++
++		/* Get the protocol, maintain skb around eth_type_trans()
++		 * The main reason for this hack is for the limitation of
++		 * Linux 2.4 where 'eth_type_trans' uses the
++		 * 'net->hard_header_len'
++		 * to perform skb_pull inside vs ETH_HLEN. Since to avoid
++		 * coping of the packet coming from the network stack to add
++		 * BDC, Hardware header etc, during network interface
++		 * registration
++		 * we set the 'net->hard_header_len' to ETH_HLEN + extra space
++		 * required
++		 * for BDC, Hardware header etc. and not just the ETH_HLEN
++		 */
++		eth = skb->data;
++		len = skb->len;
++
++		ifp = drvr->iflist[ifidx];
++		if (ifp == NULL)
++			ifp = drvr->iflist[0];
++
++		if (!ifp || !ifp->ndev ||
++		    ifp->ndev->reg_state != NETREG_REGISTERED) {
++			brcmu_pkt_buf_free_skb(skb);
++			continue;
++		}
++
++		skb->dev = ifp->ndev;
++		skb->protocol = eth_type_trans(skb, skb->dev);
++
++		if (skb->pkt_type == PACKET_MULTICAST)
++			bus_if->dstats.multicast++;
++
++		skb->data = eth;
++		skb->len = len;
++
++		/* Strip header, count, deliver upward */
++		skb_pull(skb, ETH_HLEN);
++
++		/* Process special event packets and then discard them */
++		if (ntohs(skb->protocol) == ETH_P_LINK_CTL)
++			brcmf_host_event(drvr, &ifidx,
++					  skb_mac_header(skb),
++					  &event, &data);
++
++		if (drvr->iflist[ifidx]) {
++			ifp = drvr->iflist[ifidx];
++			ifp->ndev->last_rx = jiffies;
++		}
++
++		bus_if->dstats.rx_bytes += skb->len;
++		bus_if->dstats.rx_packets++;	/* Local count */
++
++		if (in_interrupt())
++			netif_rx(skb);
++		else
++			/* If the receive is not processed inside an ISR,
++			 * the softirqd must be woken explicitly to service
++			 * the NET_RX_SOFTIRQ.  In 2.6 kernels, this is handled
++			 * by netif_rx_ni(), but in earlier kernels, we need
++			 * to do it manually.
++			 */
++			netif_rx_ni(skb);
++	}
++}
++
++void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success)
++{
++	uint ifidx;
++	struct ethhdr *eh;
++	u16 type;
++	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
++	struct brcmf_pub *drvr = bus_if->drvr;
++
++	brcmf_proto_hdrpull(dev, &ifidx, txp);
++
++	eh = (struct ethhdr *)(txp->data);
++	type = ntohs(eh->h_proto);
++
++	if (type == ETH_P_PAE)
++		atomic_dec(&drvr->pend_8021x_cnt);
++
++}
++
++static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev)
++{
++	struct brcmf_if *ifp = netdev_priv(ndev);
++	struct brcmf_bus *bus_if = ifp->drvr->bus_if;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* Copy dongle stats to net device stats */
++	ifp->stats.rx_packets = bus_if->dstats.rx_packets;
++	ifp->stats.tx_packets = bus_if->dstats.tx_packets;
++	ifp->stats.rx_bytes = bus_if->dstats.rx_bytes;
++	ifp->stats.tx_bytes = bus_if->dstats.tx_bytes;
++	ifp->stats.rx_errors = bus_if->dstats.rx_errors;
++	ifp->stats.tx_errors = bus_if->dstats.tx_errors;
++	ifp->stats.rx_dropped = bus_if->dstats.rx_dropped;
++	ifp->stats.tx_dropped = bus_if->dstats.tx_dropped;
++	ifp->stats.multicast = bus_if->dstats.multicast;
++
++	return &ifp->stats;
++}
++
++/* Retrieve current toe component enables, which are kept
++	 as a bitmap in toe_ol iovar */
++static int brcmf_toe_get(struct brcmf_pub *drvr, int ifidx, u32 *toe_ol)
++{
++	struct brcmf_dcmd dcmd;
++	__le32 toe_le;
++	char buf[32];
++	int ret;
++
++	memset(&dcmd, 0, sizeof(dcmd));
++
++	dcmd.cmd = BRCMF_C_GET_VAR;
++	dcmd.buf = buf;
++	dcmd.len = (uint) sizeof(buf);
++	dcmd.set = false;
++
++	strcpy(buf, "toe_ol");
++	ret = brcmf_proto_dcmd(drvr, ifidx, &dcmd, dcmd.len);
++	if (ret < 0) {
++		/* Check for older dongle image that doesn't support toe_ol */
++		if (ret == -EIO) {
++			brcmf_dbg(ERROR, "%s: toe not supported by device\n",
++				  brcmf_ifname(drvr, ifidx));
++			return -EOPNOTSUPP;
++		}
++
++		brcmf_dbg(INFO, "%s: could not get toe_ol: ret=%d\n",
++			  brcmf_ifname(drvr, ifidx), ret);
++		return ret;
++	}
++
++	memcpy(&toe_le, buf, sizeof(u32));
++	*toe_ol = le32_to_cpu(toe_le);
++	return 0;
++}
++
++/* Set current toe component enables in toe_ol iovar,
++	 and set toe global enable iovar */
++static int brcmf_toe_set(struct brcmf_pub *drvr, int ifidx, u32 toe_ol)
++{
++	struct brcmf_dcmd dcmd;
++	char buf[32];
++	int ret;
++	__le32 toe_le = cpu_to_le32(toe_ol);
++
++	memset(&dcmd, 0, sizeof(dcmd));
++
++	dcmd.cmd = BRCMF_C_SET_VAR;
++	dcmd.buf = buf;
++	dcmd.len = (uint) sizeof(buf);
++	dcmd.set = true;
++
++	/* Set toe_ol as requested */
++	strcpy(buf, "toe_ol");
++	memcpy(&buf[sizeof("toe_ol")], &toe_le, sizeof(u32));
++
++	ret = brcmf_proto_dcmd(drvr, ifidx, &dcmd, dcmd.len);
++	if (ret < 0) {
++		brcmf_dbg(ERROR, "%s: could not set toe_ol: ret=%d\n",
++			  brcmf_ifname(drvr, ifidx), ret);
++		return ret;
++	}
++
++	/* Enable toe globally only if any components are enabled. */
++	toe_le = cpu_to_le32(toe_ol != 0);
++
++	strcpy(buf, "toe");
++	memcpy(&buf[sizeof("toe")], &toe_le, sizeof(u32));
++
++	ret = brcmf_proto_dcmd(drvr, ifidx, &dcmd, dcmd.len);
++	if (ret < 0) {
++		brcmf_dbg(ERROR, "%s: could not set toe: ret=%d\n",
++			  brcmf_ifname(drvr, ifidx), ret);
++		return ret;
++	}
++
++	return 0;
++}
++
++static void brcmf_ethtool_get_drvinfo(struct net_device *ndev,
++				    struct ethtool_drvinfo *info)
++{
++	struct brcmf_if *ifp = netdev_priv(ndev);
++	struct brcmf_pub *drvr = ifp->drvr;
++
++	sprintf(info->driver, KBUILD_MODNAME);
++	sprintf(info->version, "%lu", drvr->drv_version);
++	sprintf(info->bus_info, "%s", dev_name(drvr->dev));
++}
++
++static const struct ethtool_ops brcmf_ethtool_ops = {
++	.get_drvinfo = brcmf_ethtool_get_drvinfo,
++};
++
++static int brcmf_ethtool(struct brcmf_pub *drvr, void __user *uaddr)
++{
++	struct ethtool_drvinfo info;
++	char drvname[sizeof(info.driver)];
++	u32 cmd;
++	struct ethtool_value edata;
++	u32 toe_cmpnt, csum_dir;
++	int ret;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* all ethtool calls start with a cmd word */
++	if (copy_from_user(&cmd, uaddr, sizeof(u32)))
++		return -EFAULT;
++
++	switch (cmd) {
++	case ETHTOOL_GDRVINFO:
++		/* Copy out any request driver name */
++		if (copy_from_user(&info, uaddr, sizeof(info)))
++			return -EFAULT;
++		strncpy(drvname, info.driver, sizeof(info.driver));
++		drvname[sizeof(info.driver) - 1] = '\0';
++
++		/* clear struct for return */
++		memset(&info, 0, sizeof(info));
++		info.cmd = cmd;
++
++		/* if requested, identify ourselves */
++		if (strcmp(drvname, "?dhd") == 0) {
++			sprintf(info.driver, "dhd");
++			strcpy(info.version, BRCMF_VERSION_STR);
++		}
++
++		/* otherwise, require dongle to be up */
++		else if (!drvr->bus_if->drvr_up) {
++			brcmf_dbg(ERROR, "dongle is not up\n");
++			return -ENODEV;
++		}
++
++		/* finally, report dongle driver type */
++		else if (drvr->iswl)
++			sprintf(info.driver, "wl");
++		else
++			sprintf(info.driver, "xx");
++
++		sprintf(info.version, "%lu", drvr->drv_version);
++		if (copy_to_user(uaddr, &info, sizeof(info)))
++			return -EFAULT;
++		brcmf_dbg(CTL, "given %*s, returning %s\n",
++			  (int)sizeof(drvname), drvname, info.driver);
++		break;
++
++		/* Get toe offload components from dongle */
++	case ETHTOOL_GRXCSUM:
++	case ETHTOOL_GTXCSUM:
++		ret = brcmf_toe_get(drvr, 0, &toe_cmpnt);
++		if (ret < 0)
++			return ret;
++
++		csum_dir =
++		    (cmd == ETHTOOL_GTXCSUM) ? TOE_TX_CSUM_OL : TOE_RX_CSUM_OL;
++
++		edata.cmd = cmd;
++		edata.data = (toe_cmpnt & csum_dir) ? 1 : 0;
++
++		if (copy_to_user(uaddr, &edata, sizeof(edata)))
++			return -EFAULT;
++		break;
++
++		/* Set toe offload components in dongle */
++	case ETHTOOL_SRXCSUM:
++	case ETHTOOL_STXCSUM:
++		if (copy_from_user(&edata, uaddr, sizeof(edata)))
++			return -EFAULT;
++
++		/* Read the current settings, update and write back */
++		ret = brcmf_toe_get(drvr, 0, &toe_cmpnt);
++		if (ret < 0)
++			return ret;
++
++		csum_dir =
++		    (cmd == ETHTOOL_STXCSUM) ? TOE_TX_CSUM_OL : TOE_RX_CSUM_OL;
++
++		if (edata.data != 0)
++			toe_cmpnt |= csum_dir;
++		else
++			toe_cmpnt &= ~csum_dir;
++
++		ret = brcmf_toe_set(drvr, 0, toe_cmpnt);
++		if (ret < 0)
++			return ret;
++
++		/* If setting TX checksum mode, tell Linux the new mode */
++		if (cmd == ETHTOOL_STXCSUM) {
++			if (edata.data)
++				drvr->iflist[0]->ndev->features |=
++				    NETIF_F_IP_CSUM;
++			else
++				drvr->iflist[0]->ndev->features &=
++				    ~NETIF_F_IP_CSUM;
++		}
++
++		break;
++
++	default:
++		return -EOPNOTSUPP;
++	}
++
++	return 0;
++}
++
++static int brcmf_netdev_ioctl_entry(struct net_device *ndev, struct ifreq *ifr,
++				    int cmd)
++{
++	struct brcmf_if *ifp = netdev_priv(ndev);
++	struct brcmf_pub *drvr = ifp->drvr;
++
++	brcmf_dbg(TRACE, "ifidx %d, cmd 0x%04x\n", ifp->idx, cmd);
++
++	if (!drvr->iflist[ifp->idx])
++		return -1;
++
++	if (cmd == SIOCETHTOOL)
++		return brcmf_ethtool(drvr, ifr->ifr_data);
++
++	return -EOPNOTSUPP;
++}
++
++/* called only from within this driver. Sends a command to the dongle. */
++s32 brcmf_exec_dcmd(struct net_device *ndev, u32 cmd, void *arg, u32 len)
++{
++	struct brcmf_dcmd dcmd;
++	s32 err = 0;
++	int buflen = 0;
++	bool is_set_key_cmd;
++	struct brcmf_if *ifp = netdev_priv(ndev);
++	struct brcmf_pub *drvr = ifp->drvr;
++
++	memset(&dcmd, 0, sizeof(dcmd));
++	dcmd.cmd = cmd;
++	dcmd.buf = arg;
++	dcmd.len = len;
++
++	if (dcmd.buf != NULL)
++		buflen = min_t(uint, dcmd.len, BRCMF_DCMD_MAXLEN);
++
++	/* send to dongle (must be up, and wl) */
++	if ((drvr->bus_if->state != BRCMF_BUS_DATA)) {
++		brcmf_dbg(ERROR, "DONGLE_DOWN\n");
++		err = -EIO;
++		goto done;
++	}
++
++	if (!drvr->iswl) {
++		err = -EIO;
++		goto done;
++	}
++
++	/*
++	 * Intercept BRCMF_C_SET_KEY CMD - serialize M4 send and
++	 * set key CMD to prevent M4 encryption.
++	 */
++	is_set_key_cmd = ((dcmd.cmd == BRCMF_C_SET_KEY) ||
++			  ((dcmd.cmd == BRCMF_C_SET_VAR) &&
++			   !(strncmp("wsec_key", dcmd.buf, 9))) ||
++			  ((dcmd.cmd == BRCMF_C_SET_VAR) &&
++			   !(strncmp("bsscfg:wsec_key", dcmd.buf, 15))));
++	if (is_set_key_cmd)
++		brcmf_netdev_wait_pend8021x(ndev);
++
++	err = brcmf_proto_dcmd(drvr, ifp->idx, &dcmd, buflen);
++
++done:
++	if (err > 0)
++		err = 0;
++
++	return err;
++}
++
++static int brcmf_netdev_stop(struct net_device *ndev)
++{
++	struct brcmf_if *ifp = netdev_priv(ndev);
++	struct brcmf_pub *drvr = ifp->drvr;
++
++	brcmf_dbg(TRACE, "Enter\n");
++	brcmf_cfg80211_down(drvr->config);
++	if (drvr->bus_if->drvr_up == 0)
++		return 0;
++
++	/* Set state and stop OS transmissions */
++	drvr->bus_if->drvr_up = false;
++	netif_stop_queue(ndev);
++
++	return 0;
++}
++
++static int brcmf_netdev_open(struct net_device *ndev)
++{
++	struct brcmf_if *ifp = netdev_priv(ndev);
++	struct brcmf_pub *drvr = ifp->drvr;
++	struct brcmf_bus *bus_if = drvr->bus_if;
++	u32 toe_ol;
++	s32 ret = 0;
++	uint up = 0;
++
++	brcmf_dbg(TRACE, "ifidx %d\n", ifp->idx);
++
++	if (ifp->idx == 0) {	/* do it only for primary eth0 */
++		/* If bus is not ready, can't continue */
++		if (bus_if->state != BRCMF_BUS_DATA) {
++			brcmf_dbg(ERROR, "failed bus is not ready\n");
++			return -EAGAIN;
++		}
++
++		atomic_set(&drvr->pend_8021x_cnt, 0);
++
++		memcpy(ndev->dev_addr, drvr->mac, ETH_ALEN);
++
++		/* Get current TOE mode from dongle */
++		if (brcmf_toe_get(drvr, ifp->idx, &toe_ol) >= 0
++		    && (toe_ol & TOE_TX_CSUM_OL) != 0)
++			drvr->iflist[ifp->idx]->ndev->features |=
++				NETIF_F_IP_CSUM;
++		else
++			drvr->iflist[ifp->idx]->ndev->features &=
++				~NETIF_F_IP_CSUM;
++	}
++
++	/* make sure RF is ready for work */
++	brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_UP, (char *)&up, sizeof(up));
++
++	/* Allow transmit calls */
++	netif_start_queue(ndev);
++	drvr->bus_if->drvr_up = true;
++	if (brcmf_cfg80211_up(drvr->config)) {
++		brcmf_dbg(ERROR, "failed to bring up cfg80211\n");
++		return -1;
++	}
++
++	return ret;
++}
++
++static const struct net_device_ops brcmf_netdev_ops_pri = {
++	.ndo_open = brcmf_netdev_open,
++	.ndo_stop = brcmf_netdev_stop,
++	.ndo_get_stats = brcmf_netdev_get_stats,
++	.ndo_do_ioctl = brcmf_netdev_ioctl_entry,
++	.ndo_start_xmit = brcmf_netdev_start_xmit,
++	.ndo_set_mac_address = brcmf_netdev_set_mac_address,
++	.ndo_set_rx_mode = brcmf_netdev_set_multicast_list
++};
++
++static int brcmf_net_attach(struct brcmf_if *ifp)
++{
++	struct brcmf_pub *drvr = ifp->drvr;
++	struct net_device *ndev;
++	u8 temp_addr[ETH_ALEN];
++
++	brcmf_dbg(TRACE, "ifidx %d\n", ifp->idx);
++
++	ndev = drvr->iflist[ifp->idx]->ndev;
++	ndev->netdev_ops = &brcmf_netdev_ops_pri;
++
++	/*
++	 * determine mac address to use
++	 */
++	if (is_valid_ether_addr(ifp->mac_addr))
++		memcpy(temp_addr, ifp->mac_addr, ETH_ALEN);
++	else
++		memcpy(temp_addr, drvr->mac, ETH_ALEN);
++
++	if (ifp->idx == 1) {
++		brcmf_dbg(TRACE, "ACCESS POINT MAC:\n");
++		/*  ACCESSPOINT INTERFACE CASE */
++		temp_addr[0] |= 0X02;	/* set bit 2 ,
++			 - Locally Administered address  */
++
++	}
++	ndev->hard_header_len = ETH_HLEN + drvr->hdrlen;
++	ndev->ethtool_ops = &brcmf_ethtool_ops;
++
++	drvr->rxsz = ndev->mtu + ndev->hard_header_len +
++			      drvr->hdrlen;
++
++	memcpy(ndev->dev_addr, temp_addr, ETH_ALEN);
++
++	/* attach to cfg80211 for primary interface */
++	if (!ifp->idx) {
++		drvr->config = brcmf_cfg80211_attach(ndev, drvr->dev, drvr);
++		if (drvr->config == NULL) {
++			brcmf_dbg(ERROR, "wl_cfg80211_attach failed\n");
++			goto fail;
++		}
++	}
++
++	if (register_netdev(ndev) != 0) {
++		brcmf_dbg(ERROR, "couldn't register the net device\n");
++		goto fail;
++	}
++
++	brcmf_dbg(INFO, "%s: Broadcom Dongle Host Driver\n", ndev->name);
++
++	return 0;
++
++fail:
++	ndev->netdev_ops = NULL;
++	return -EBADE;
++}
++
++int
++brcmf_add_if(struct device *dev, int ifidx, char *name, u8 *mac_addr)
++{
++	struct brcmf_if *ifp;
++	struct net_device *ndev;
++	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
++	struct brcmf_pub *drvr = bus_if->drvr;
++
++	brcmf_dbg(TRACE, "idx %d\n", ifidx);
++
++	ifp = drvr->iflist[ifidx];
++	/*
++	 * Delete the existing interface before overwriting it
++	 * in case we missed the BRCMF_E_IF_DEL event.
++	 */
++	if (ifp) {
++		brcmf_dbg(ERROR, "ERROR: netdev:%s already exists, try free & unregister\n",
++			  ifp->ndev->name);
++		netif_stop_queue(ifp->ndev);
++		unregister_netdev(ifp->ndev);
++		free_netdev(ifp->ndev);
++		drvr->iflist[ifidx] = NULL;
++	}
++
++	/* Allocate netdev, including space for private structure */
++	ndev = alloc_netdev(sizeof(struct brcmf_if), name, ether_setup);
++	if (!ndev) {
++		brcmf_dbg(ERROR, "OOM - alloc_netdev\n");
++		return -ENOMEM;
++	}
++
++	ifp = netdev_priv(ndev);
++	ifp->ndev = ndev;
++	ifp->drvr = drvr;
++	drvr->iflist[ifidx] = ifp;
++	ifp->idx = ifidx;
++	if (mac_addr != NULL)
++		memcpy(&ifp->mac_addr, mac_addr, ETH_ALEN);
++
++	if (brcmf_net_attach(ifp)) {
++		brcmf_dbg(ERROR, "brcmf_net_attach failed");
++		free_netdev(ifp->ndev);
++		drvr->iflist[ifidx] = NULL;
++		return -EOPNOTSUPP;
++	}
++
++	brcmf_dbg(TRACE, " ==== pid:%x, net_device for if:%s created ===\n",
++		  current->pid, ifp->ndev->name);
++
++	return 0;
++}
++
++void brcmf_del_if(struct brcmf_pub *drvr, int ifidx)
++{
++	struct brcmf_if *ifp;
++
++	brcmf_dbg(TRACE, "idx %d\n", ifidx);
++
++	ifp = drvr->iflist[ifidx];
++	if (!ifp) {
++		brcmf_dbg(ERROR, "Null interface\n");
++		return;
++	}
++	if (ifp->ndev) {
++		if (ifidx == 0) {
++			if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) {
++				rtnl_lock();
++				brcmf_netdev_stop(ifp->ndev);
++				rtnl_unlock();
++			}
++		} else {
++			netif_stop_queue(ifp->ndev);
++		}
++
++		unregister_netdev(ifp->ndev);
++		drvr->iflist[ifidx] = NULL;
++		if (ifidx == 0)
++			brcmf_cfg80211_detach(drvr->config);
++		free_netdev(ifp->ndev);
++	}
++}
++
++int brcmf_attach(uint bus_hdrlen, struct device *dev)
++{
++	struct brcmf_pub *drvr = NULL;
++	int ret = 0;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* Allocate primary brcmf_info */
++	drvr = kzalloc(sizeof(struct brcmf_pub), GFP_ATOMIC);
++	if (!drvr)
++		return -ENOMEM;
++
++	mutex_init(&drvr->proto_block);
++
++	/* Link to bus module */
++	drvr->hdrlen = bus_hdrlen;
++	drvr->bus_if = dev_get_drvdata(dev);
++	drvr->bus_if->drvr = drvr;
++	drvr->dev = dev;
++
++	/* Attach and link in the protocol */
++	ret = brcmf_proto_attach(drvr);
++	if (ret != 0) {
++		brcmf_dbg(ERROR, "brcmf_prot_attach failed\n");
++		goto fail;
++	}
++
++	INIT_WORK(&drvr->setmacaddr_work, _brcmf_set_mac_address);
++	INIT_WORK(&drvr->multicast_work, _brcmf_set_multicast_list);
++
++	return ret;
++
++fail:
++	brcmf_detach(dev);
++
++	return ret;
++}
++
++int brcmf_bus_start(struct device *dev)
++{
++	int ret = -1;
++	/* Room for "event_msgs" + '\0' + bitvec */
++	char iovbuf[BRCMF_EVENTING_MASK_LEN + 12];
++	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
++	struct brcmf_pub *drvr = bus_if->drvr;
++
++	brcmf_dbg(TRACE, "\n");
++
++	/* Bring up the bus */
++	ret = bus_if->brcmf_bus_init(dev);
++	if (ret != 0) {
++		brcmf_dbg(ERROR, "brcmf_sdbrcm_bus_init failed %d\n", ret);
++		return ret;
++	}
++
++	brcmf_c_mkiovar("event_msgs", drvr->eventmask, BRCMF_EVENTING_MASK_LEN,
++		      iovbuf, sizeof(iovbuf));
++	brcmf_proto_cdc_query_dcmd(drvr, 0, BRCMF_C_GET_VAR, iovbuf,
++				    sizeof(iovbuf));
++	memcpy(drvr->eventmask, iovbuf, BRCMF_EVENTING_MASK_LEN);
++
++	setbit(drvr->eventmask, BRCMF_E_SET_SSID);
++	setbit(drvr->eventmask, BRCMF_E_PRUNE);
++	setbit(drvr->eventmask, BRCMF_E_AUTH);
++	setbit(drvr->eventmask, BRCMF_E_REASSOC);
++	setbit(drvr->eventmask, BRCMF_E_REASSOC_IND);
++	setbit(drvr->eventmask, BRCMF_E_DEAUTH_IND);
++	setbit(drvr->eventmask, BRCMF_E_DISASSOC_IND);
++	setbit(drvr->eventmask, BRCMF_E_DISASSOC);
++	setbit(drvr->eventmask, BRCMF_E_JOIN);
++	setbit(drvr->eventmask, BRCMF_E_ASSOC_IND);
++	setbit(drvr->eventmask, BRCMF_E_PSK_SUP);
++	setbit(drvr->eventmask, BRCMF_E_LINK);
++	setbit(drvr->eventmask, BRCMF_E_NDIS_LINK);
++	setbit(drvr->eventmask, BRCMF_E_MIC_ERROR);
++	setbit(drvr->eventmask, BRCMF_E_PMKID_CACHE);
++	setbit(drvr->eventmask, BRCMF_E_TXFAIL);
++	setbit(drvr->eventmask, BRCMF_E_JOIN_START);
++	setbit(drvr->eventmask, BRCMF_E_SCAN_COMPLETE);
++
++/* enable dongle roaming event */
++
++	drvr->pktfilter_count = 1;
++	/* Setup filter to allow only unicast */
++	drvr->pktfilter[0] = "100 0 0 0 0x01 0x00";
++
++	/* Bus is ready, do any protocol initialization */
++	ret = brcmf_proto_init(drvr);
++	if (ret < 0)
++		return ret;
++
++	/* add primary networking interface */
++	ret = brcmf_add_if(dev, 0, "wlan%d", drvr->mac);
++	if (ret < 0)
++		return ret;
++
++	/* signal bus ready */
++	bus_if->state = BRCMF_BUS_DATA;
++	return 0;
++}
++
++static void brcmf_bus_detach(struct brcmf_pub *drvr)
++{
++	brcmf_dbg(TRACE, "Enter\n");
++
++	if (drvr) {
++		/* Stop the protocol module */
++		brcmf_proto_stop(drvr);
++
++		/* Stop the bus module */
++		drvr->bus_if->brcmf_bus_stop(drvr->dev);
++	}
++}
++
++void brcmf_detach(struct device *dev)
++{
++	int i;
++	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
++	struct brcmf_pub *drvr = bus_if->drvr;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++
++	/* make sure primary interface removed last */
++	for (i = BRCMF_MAX_IFS-1; i > -1; i--)
++		if (drvr->iflist[i])
++			brcmf_del_if(drvr, i);
++
++	brcmf_bus_detach(drvr);
++
++	if (drvr->prot) {
++		cancel_work_sync(&drvr->setmacaddr_work);
++		cancel_work_sync(&drvr->multicast_work);
++		brcmf_proto_detach(drvr);
++	}
++
++	bus_if->drvr = NULL;
++	kfree(drvr);
++}
++
++static int brcmf_get_pend_8021x_cnt(struct brcmf_pub *drvr)
++{
++	return atomic_read(&drvr->pend_8021x_cnt);
++}
++
++#define MAX_WAIT_FOR_8021X_TX	10
++
++int brcmf_netdev_wait_pend8021x(struct net_device *ndev)
++{
++	struct brcmf_if *ifp = netdev_priv(ndev);
++	struct brcmf_pub *drvr = ifp->drvr;
++	int timeout = 10 * HZ / 1000;
++	int ntimes = MAX_WAIT_FOR_8021X_TX;
++	int pend = brcmf_get_pend_8021x_cnt(drvr);
++
++	while (ntimes && pend) {
++		if (pend) {
++			set_current_state(TASK_INTERRUPTIBLE);
++			schedule_timeout(timeout);
++			set_current_state(TASK_RUNNING);
++			ntimes--;
++		}
++		pend = brcmf_get_pend_8021x_cnt(drvr);
++	}
++	return pend;
++}
++
++#ifdef DEBUG
++int brcmf_write_to_file(struct brcmf_pub *drvr, const u8 *buf, int size)
++{
++	int ret = 0;
++	struct file *fp;
++	mm_segment_t old_fs;
++	loff_t pos = 0;
++
++	/* change to KERNEL_DS address limit */
++	old_fs = get_fs();
++	set_fs(KERNEL_DS);
++
++	/* open file to write */
++	fp = filp_open("/tmp/mem_dump", O_WRONLY | O_CREAT, 0640);
++	if (!fp) {
++		brcmf_dbg(ERROR, "open file error\n");
++		ret = -1;
++		goto exit;
++	}
++
++	/* Write buf to file */
++	fp->f_op->write(fp, (char __user *)buf, size, &pos);
++
++exit:
++	/* free buf before return */
++	kfree(buf);
++	/* close file before return */
++	if (fp)
++		filp_close(fp, current->files);
++	/* restore previous address limit */
++	set_fs(old_fs);
++
++	return ret;
++}
++#endif				/* DEBUG */
++
++static void brcmf_driver_init(struct work_struct *work)
++{
++#ifdef CONFIG_BRCMFMAC_SDIO
++	brcmf_sdio_init();
++#endif
++#ifdef CONFIG_BRCMFMAC_USB
++	brcmf_usb_init();
++#endif
++}
++static DECLARE_WORK(brcmf_driver_work, brcmf_driver_init);
++
++static int __init brcmfmac_module_init(void)
++{
++	if (!schedule_work(&brcmf_driver_work))
++		return -EBUSY;
++
++	return 0;
++}
++
++static void __exit brcmfmac_module_exit(void)
++{
++	cancel_work_sync(&brcmf_driver_work);
++
++#ifdef CONFIG_BRCMFMAC_SDIO
++	brcmf_sdio_exit();
++#endif
++#ifdef CONFIG_BRCMFMAC_USB
++	brcmf_usb_exit();
++#endif
++}
++
++module_init(brcmfmac_module_init);
++module_exit(brcmfmac_module_exit);
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h
+new file mode 100644
+index 0000000..6bc4425
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h
+@@ -0,0 +1,53 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef _BRCMF_PROTO_H_
++#define _BRCMF_PROTO_H_
++
++/*
++ * Exported from the brcmf protocol module (brcmf_cdc)
++ */
++
++/* Linkage, sets prot link and updates hdrlen in pub */
++extern int brcmf_proto_attach(struct brcmf_pub *drvr);
++
++/* Unlink, frees allocated protocol memory (including brcmf_proto) */
++extern void brcmf_proto_detach(struct brcmf_pub *drvr);
++
++/* Initialize protocol: sync w/dongle state.
++ * Sets dongle media info (iswl, drv_version, mac address).
++ */
++extern int brcmf_proto_init(struct brcmf_pub *drvr);
++
++/* Stop protocol: sync w/dongle state. */
++extern void brcmf_proto_stop(struct brcmf_pub *drvr);
++
++/* Add any protocol-specific data header.
++ * Caller must reserve prot_hdrlen prepend space.
++ */
++extern void brcmf_proto_hdrpush(struct brcmf_pub *, int ifidx,
++				struct sk_buff *txp);
++
++/* Use protocol to issue command to dongle */
++extern int brcmf_proto_dcmd(struct brcmf_pub *drvr, int ifidx,
++				struct brcmf_dcmd *dcmd, int len);
++
++extern int brcmf_c_preinit_dcmds(struct brcmf_pub *drvr);
++
++extern int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx,
++				     uint cmd, void *buf, uint len);
++
++#endif				/* _BRCMF_PROTO_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+new file mode 100644
+index 0000000..0d23b8d
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+@@ -0,0 +1,4014 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#undef pr_fmt
++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
++
++#include <linux/types.h>
++#include <linux/kernel.h>
++#include <linux/kthread.h>
++#include <linux/printk.h>
++#include <linux/pci_ids.h>
++#include <linux/netdevice.h>
++#include <linux/interrupt.h>
++#include <linux/sched.h>
++#include <linux/mmc/sdio.h>
++#include <linux/mmc/sdio_func.h>
++#include <linux/mmc/card.h>
++#include <linux/semaphore.h>
++#include <linux/firmware.h>
++#include <linux/module.h>
++#include <linux/bcma/bcma.h>
++#include <asm/unaligned.h>
++#include <defs.h>
++#include <brcmu_wifi.h>
++#include <brcmu_utils.h>
++#include <brcm_hw_ids.h>
++#include <soc.h>
++#include "sdio_host.h"
++#include "sdio_chip.h"
++
++#define DCMD_RESP_TIMEOUT  2000	/* In milli second */
++
++#ifdef DEBUG
++
++#define BRCMF_TRAP_INFO_SIZE	80
++
++#define CBUF_LEN	(128)
++
++struct rte_log_le {
++	__le32 buf;		/* Can't be pointer on (64-bit) hosts */
++	__le32 buf_size;
++	__le32 idx;
++	char *_buf_compat;	/* Redundant pointer for backward compat. */
++};
++
++struct rte_console {
++	/* Virtual UART
++	 * When there is no UART (e.g. Quickturn),
++	 * the host should write a complete
++	 * input line directly into cbuf and then write
++	 * the length into vcons_in.
++	 * This may also be used when there is a real UART
++	 * (at risk of conflicting with
++	 * the real UART).  vcons_out is currently unused.
++	 */
++	uint vcons_in;
++	uint vcons_out;
++
++	/* Output (logging) buffer
++	 * Console output is written to a ring buffer log_buf at index log_idx.
++	 * The host may read the output when it sees log_idx advance.
++	 * Output will be lost if the output wraps around faster than the host
++	 * polls.
++	 */
++	struct rte_log_le log_le;
++
++	/* Console input line buffer
++	 * Characters are read one at a time into cbuf
++	 * until <CR> is received, then
++	 * the buffer is processed as a command line.
++	 * Also used for virtual UART.
++	 */
++	uint cbuf_idx;
++	char cbuf[CBUF_LEN];
++};
++
++#endif				/* DEBUG */
++#include <chipcommon.h>
++
++#include "dhd_bus.h"
++#include "dhd_dbg.h"
++
++#define TXQLEN		2048	/* bulk tx queue length */
++#define TXHI		(TXQLEN - 256)	/* turn on flow control above TXHI */
++#define TXLOW		(TXHI - 256)	/* turn off flow control below TXLOW */
++#define PRIOMASK	7
++
++#define TXRETRIES	2	/* # of retries for tx frames */
++
++#define BRCMF_RXBOUND	50	/* Default for max rx frames in
++				 one scheduling */
++
++#define BRCMF_TXBOUND	20	/* Default for max tx frames in
++				 one scheduling */
++
++#define BRCMF_TXMINMAX	1	/* Max tx frames if rx still pending */
++
++#define MEMBLOCK	2048	/* Block size used for downloading
++				 of dongle image */
++#define MAX_DATA_BUF	(32 * 1024)	/* Must be large enough to hold
++				 biggest possible glom */
++
++#define BRCMF_FIRSTREAD	(1 << 6)
++
++
++/* SBSDIO_DEVICE_CTL */
++
++/* 1: device will assert busy signal when receiving CMD53 */
++#define SBSDIO_DEVCTL_SETBUSY		0x01
++/* 1: assertion of sdio interrupt is synchronous to the sdio clock */
++#define SBSDIO_DEVCTL_SPI_INTR_SYNC	0x02
++/* 1: mask all interrupts to host except the chipActive (rev 8) */
++#define SBSDIO_DEVCTL_CA_INT_ONLY	0x04
++/* 1: isolate internal sdio signals, put external pads in tri-state; requires
++ * sdio bus power cycle to clear (rev 9) */
++#define SBSDIO_DEVCTL_PADS_ISO		0x08
++/* Force SD->SB reset mapping (rev 11) */
++#define SBSDIO_DEVCTL_SB_RST_CTL	0x30
++/*   Determined by CoreControl bit */
++#define SBSDIO_DEVCTL_RST_CORECTL	0x00
++/*   Force backplane reset */
++#define SBSDIO_DEVCTL_RST_BPRESET	0x10
++/*   Force no backplane reset */
++#define SBSDIO_DEVCTL_RST_NOBPRESET	0x20
++
++/* direct(mapped) cis space */
++
++/* MAPPED common CIS address */
++#define SBSDIO_CIS_BASE_COMMON		0x1000
++/* maximum bytes in one CIS */
++#define SBSDIO_CIS_SIZE_LIMIT		0x200
++/* cis offset addr is < 17 bits */
++#define SBSDIO_CIS_OFT_ADDR_MASK	0x1FFFF
++
++/* manfid tuple length, include tuple, link bytes */
++#define SBSDIO_CIS_MANFID_TUPLE_LEN	6
++
++/* intstatus */
++#define I_SMB_SW0	(1 << 0)	/* To SB Mail S/W interrupt 0 */
++#define I_SMB_SW1	(1 << 1)	/* To SB Mail S/W interrupt 1 */
++#define I_SMB_SW2	(1 << 2)	/* To SB Mail S/W interrupt 2 */
++#define I_SMB_SW3	(1 << 3)	/* To SB Mail S/W interrupt 3 */
++#define I_SMB_SW_MASK	0x0000000f	/* To SB Mail S/W interrupts mask */
++#define I_SMB_SW_SHIFT	0	/* To SB Mail S/W interrupts shift */
++#define I_HMB_SW0	(1 << 4)	/* To Host Mail S/W interrupt 0 */
++#define I_HMB_SW1	(1 << 5)	/* To Host Mail S/W interrupt 1 */
++#define I_HMB_SW2	(1 << 6)	/* To Host Mail S/W interrupt 2 */
++#define I_HMB_SW3	(1 << 7)	/* To Host Mail S/W interrupt 3 */
++#define I_HMB_SW_MASK	0x000000f0	/* To Host Mail S/W interrupts mask */
++#define I_HMB_SW_SHIFT	4	/* To Host Mail S/W interrupts shift */
++#define I_WR_OOSYNC	(1 << 8)	/* Write Frame Out Of Sync */
++#define I_RD_OOSYNC	(1 << 9)	/* Read Frame Out Of Sync */
++#define	I_PC		(1 << 10)	/* descriptor error */
++#define	I_PD		(1 << 11)	/* data error */
++#define	I_DE		(1 << 12)	/* Descriptor protocol Error */
++#define	I_RU		(1 << 13)	/* Receive descriptor Underflow */
++#define	I_RO		(1 << 14)	/* Receive fifo Overflow */
++#define	I_XU		(1 << 15)	/* Transmit fifo Underflow */
++#define	I_RI		(1 << 16)	/* Receive Interrupt */
++#define I_BUSPWR	(1 << 17)	/* SDIO Bus Power Change (rev 9) */
++#define I_XMTDATA_AVAIL (1 << 23)	/* bits in fifo */
++#define	I_XI		(1 << 24)	/* Transmit Interrupt */
++#define I_RF_TERM	(1 << 25)	/* Read Frame Terminate */
++#define I_WF_TERM	(1 << 26)	/* Write Frame Terminate */
++#define I_PCMCIA_XU	(1 << 27)	/* PCMCIA Transmit FIFO Underflow */
++#define I_SBINT		(1 << 28)	/* sbintstatus Interrupt */
++#define I_CHIPACTIVE	(1 << 29)	/* chip from doze to active state */
++#define I_SRESET	(1 << 30)	/* CCCR RES interrupt */
++#define I_IOE2		(1U << 31)	/* CCCR IOE2 Bit Changed */
++#define	I_ERRORS	(I_PC | I_PD | I_DE | I_RU | I_RO | I_XU)
++#define I_DMA		(I_RI | I_XI | I_ERRORS)
++
++/* corecontrol */
++#define CC_CISRDY		(1 << 0)	/* CIS Ready */
++#define CC_BPRESEN		(1 << 1)	/* CCCR RES signal */
++#define CC_F2RDY		(1 << 2)	/* set CCCR IOR2 bit */
++#define CC_CLRPADSISO		(1 << 3)	/* clear SDIO pads isolation */
++#define CC_XMTDATAAVAIL_MODE	(1 << 4)
++#define CC_XMTDATAAVAIL_CTRL	(1 << 5)
++
++/* SDA_FRAMECTRL */
++#define SFC_RF_TERM	(1 << 0)	/* Read Frame Terminate */
++#define SFC_WF_TERM	(1 << 1)	/* Write Frame Terminate */
++#define SFC_CRC4WOOS	(1 << 2)	/* CRC error for write out of sync */
++#define SFC_ABORTALL	(1 << 3)	/* Abort all in-progress frames */
++
++/* HW frame tag */
++#define SDPCM_FRAMETAG_LEN	4	/* 2 bytes len, 2 bytes check val */
++
++/* Total length of frame header for dongle protocol */
++#define SDPCM_HDRLEN	(SDPCM_FRAMETAG_LEN + SDPCM_SWHEADER_LEN)
++#define SDPCM_RESERVE	(SDPCM_HDRLEN + BRCMF_SDALIGN)
++
++/*
++ * Software allocation of To SB Mailbox resources
++ */
++
++/* tosbmailbox bits corresponding to intstatus bits */
++#define SMB_NAK		(1 << 0)	/* Frame NAK */
++#define SMB_INT_ACK	(1 << 1)	/* Host Interrupt ACK */
++#define SMB_USE_OOB	(1 << 2)	/* Use OOB Wakeup */
++#define SMB_DEV_INT	(1 << 3)	/* Miscellaneous Interrupt */
++
++/* tosbmailboxdata */
++#define SMB_DATA_VERSION_SHIFT	16	/* host protocol version */
++
++/*
++ * Software allocation of To Host Mailbox resources
++ */
++
++/* intstatus bits */
++#define I_HMB_FC_STATE	I_HMB_SW0	/* Flow Control State */
++#define I_HMB_FC_CHANGE	I_HMB_SW1	/* Flow Control State Changed */
++#define I_HMB_FRAME_IND	I_HMB_SW2	/* Frame Indication */
++#define I_HMB_HOST_INT	I_HMB_SW3	/* Miscellaneous Interrupt */
++
++/* tohostmailboxdata */
++#define HMB_DATA_NAKHANDLED	1	/* retransmit NAK'd frame */
++#define HMB_DATA_DEVREADY	2	/* talk to host after enable */
++#define HMB_DATA_FC		4	/* per prio flowcontrol update flag */
++#define HMB_DATA_FWREADY	8	/* fw ready for protocol activity */
++
++#define HMB_DATA_FCDATA_MASK	0xff000000
++#define HMB_DATA_FCDATA_SHIFT	24
++
++#define HMB_DATA_VERSION_MASK	0x00ff0000
++#define HMB_DATA_VERSION_SHIFT	16
++
++/*
++ * Software-defined protocol header
++ */
++
++/* Current protocol version */
++#define SDPCM_PROT_VERSION	4
++
++/* SW frame header */
++#define SDPCM_PACKET_SEQUENCE(p)	(((u8 *)p)[0] & 0xff)
++
++#define SDPCM_CHANNEL_MASK		0x00000f00
++#define SDPCM_CHANNEL_SHIFT		8
++#define SDPCM_PACKET_CHANNEL(p)		(((u8 *)p)[1] & 0x0f)
++
++#define SDPCM_NEXTLEN_OFFSET		2
++
++/* Data Offset from SOF (HW Tag, SW Tag, Pad) */
++#define SDPCM_DOFFSET_OFFSET		3	/* Data Offset */
++#define SDPCM_DOFFSET_VALUE(p)		(((u8 *)p)[SDPCM_DOFFSET_OFFSET] & 0xff)
++#define SDPCM_DOFFSET_MASK		0xff000000
++#define SDPCM_DOFFSET_SHIFT		24
++#define SDPCM_FCMASK_OFFSET		4	/* Flow control */
++#define SDPCM_FCMASK_VALUE(p)		(((u8 *)p)[SDPCM_FCMASK_OFFSET] & 0xff)
++#define SDPCM_WINDOW_OFFSET		5	/* Credit based fc */
++#define SDPCM_WINDOW_VALUE(p)		(((u8 *)p)[SDPCM_WINDOW_OFFSET] & 0xff)
++
++#define SDPCM_SWHEADER_LEN	8	/* SW header is 64 bits */
++
++/* logical channel numbers */
++#define SDPCM_CONTROL_CHANNEL	0	/* Control channel Id */
++#define SDPCM_EVENT_CHANNEL	1	/* Asyc Event Indication Channel Id */
++#define SDPCM_DATA_CHANNEL	2	/* Data Xmit/Recv Channel Id */
++#define SDPCM_GLOM_CHANNEL	3	/* For coalesced packets */
++#define SDPCM_TEST_CHANNEL	15	/* Reserved for test/debug packets */
++
++#define SDPCM_SEQUENCE_WRAP	256	/* wrap-around val for 8bit frame seq */
++
++#define SDPCM_GLOMDESC(p)	(((u8 *)p)[1] & 0x80)
++
++/*
++ * Shared structure between dongle and the host.
++ * The structure contains pointers to trap or assert information.
++ */
++#define SDPCM_SHARED_VERSION       0x0002
++#define SDPCM_SHARED_VERSION_MASK  0x00FF
++#define SDPCM_SHARED_ASSERT_BUILT  0x0100
++#define SDPCM_SHARED_ASSERT        0x0200
++#define SDPCM_SHARED_TRAP          0x0400
++
++/* Space for header read, limit for data packets */
++#define MAX_HDR_READ	(1 << 6)
++#define MAX_RX_DATASZ	2048
++
++/* Maximum milliseconds to wait for F2 to come up */
++#define BRCMF_WAIT_F2RDY	3000
++
++/* Bump up limit on waiting for HT to account for first startup;
++ * if the image is doing a CRC calculation before programming the PMU
++ * for HT availability, it could take a couple hundred ms more, so
++ * max out at a 1 second (1000000us).
++ */
++#undef PMU_MAX_TRANSITION_DLY
++#define PMU_MAX_TRANSITION_DLY 1000000
++
++/* Value for ChipClockCSR during initial setup */
++#define BRCMF_INIT_CLKCTL1	(SBSDIO_FORCE_HW_CLKREQ_OFF |	\
++					SBSDIO_ALP_AVAIL_REQ)
++
++/* Flags for SDH calls */
++#define F2SYNC	(SDIO_REQ_4BYTE | SDIO_REQ_FIXED)
++
++#define BRCMF_SDIO_FW_NAME	"brcm/brcmfmac-sdio.bin"
++#define BRCMF_SDIO_NV_NAME	"brcm/brcmfmac-sdio.txt"
++MODULE_FIRMWARE(BRCMF_SDIO_FW_NAME);
++MODULE_FIRMWARE(BRCMF_SDIO_NV_NAME);
++
++#define BRCMF_IDLE_IMMEDIATE	(-1)	/* Enter idle immediately */
++#define BRCMF_IDLE_ACTIVE	0	/* Do not request any SD clock change
++					 * when idle
++					 */
++#define BRCMF_IDLE_INTERVAL	1
++
++/*
++ * Conversion of 802.1D priority to precedence level
++ */
++static uint prio2prec(u32 prio)
++{
++	return (prio == PRIO_8021D_NONE || prio == PRIO_8021D_BE) ?
++	       (prio^2) : prio;
++}
++
++/* core registers */
++struct sdpcmd_regs {
++	u32 corecontrol;		/* 0x00, rev8 */
++	u32 corestatus;			/* rev8 */
++	u32 PAD[1];
++	u32 biststatus;			/* rev8 */
++
++	/* PCMCIA access */
++	u16 pcmciamesportaladdr;	/* 0x010, rev8 */
++	u16 PAD[1];
++	u16 pcmciamesportalmask;	/* rev8 */
++	u16 PAD[1];
++	u16 pcmciawrframebc;		/* rev8 */
++	u16 PAD[1];
++	u16 pcmciaunderflowtimer;	/* rev8 */
++	u16 PAD[1];
++
++	/* interrupt */
++	u32 intstatus;			/* 0x020, rev8 */
++	u32 hostintmask;		/* rev8 */
++	u32 intmask;			/* rev8 */
++	u32 sbintstatus;		/* rev8 */
++	u32 sbintmask;			/* rev8 */
++	u32 funcintmask;		/* rev4 */
++	u32 PAD[2];
++	u32 tosbmailbox;		/* 0x040, rev8 */
++	u32 tohostmailbox;		/* rev8 */
++	u32 tosbmailboxdata;		/* rev8 */
++	u32 tohostmailboxdata;		/* rev8 */
++
++	/* synchronized access to registers in SDIO clock domain */
++	u32 sdioaccess;			/* 0x050, rev8 */
++	u32 PAD[3];
++
++	/* PCMCIA frame control */
++	u8 pcmciaframectrl;		/* 0x060, rev8 */
++	u8 PAD[3];
++	u8 pcmciawatermark;		/* rev8 */
++	u8 PAD[155];
++
++	/* interrupt batching control */
++	u32 intrcvlazy;			/* 0x100, rev8 */
++	u32 PAD[3];
++
++	/* counters */
++	u32 cmd52rd;			/* 0x110, rev8 */
++	u32 cmd52wr;			/* rev8 */
++	u32 cmd53rd;			/* rev8 */
++	u32 cmd53wr;			/* rev8 */
++	u32 abort;			/* rev8 */
++	u32 datacrcerror;		/* rev8 */
++	u32 rdoutofsync;		/* rev8 */
++	u32 wroutofsync;		/* rev8 */
++	u32 writebusy;			/* rev8 */
++	u32 readwait;			/* rev8 */
++	u32 readterm;			/* rev8 */
++	u32 writeterm;			/* rev8 */
++	u32 PAD[40];
++	u32 clockctlstatus;		/* rev8 */
++	u32 PAD[7];
++
++	u32 PAD[128];			/* DMA engines */
++
++	/* SDIO/PCMCIA CIS region */
++	char cis[512];			/* 0x400-0x5ff, rev6 */
++
++	/* PCMCIA function control registers */
++	char pcmciafcr[256];		/* 0x600-6ff, rev6 */
++	u16 PAD[55];
++
++	/* PCMCIA backplane access */
++	u16 backplanecsr;		/* 0x76E, rev6 */
++	u16 backplaneaddr0;		/* rev6 */
++	u16 backplaneaddr1;		/* rev6 */
++	u16 backplaneaddr2;		/* rev6 */
++	u16 backplaneaddr3;		/* rev6 */
++	u16 backplanedata0;		/* rev6 */
++	u16 backplanedata1;		/* rev6 */
++	u16 backplanedata2;		/* rev6 */
++	u16 backplanedata3;		/* rev6 */
++	u16 PAD[31];
++
++	/* sprom "size" & "blank" info */
++	u16 spromstatus;		/* 0x7BE, rev2 */
++	u32 PAD[464];
++
++	u16 PAD[0x80];
++};
++
++#ifdef DEBUG
++/* Device console log buffer state */
++struct brcmf_console {
++	uint count;		/* Poll interval msec counter */
++	uint log_addr;		/* Log struct address (fixed) */
++	struct rte_log_le log_le;	/* Log struct (host copy) */
++	uint bufsize;		/* Size of log buffer */
++	u8 *buf;		/* Log buffer (host copy) */
++	uint last;		/* Last buffer read index */
++};
++#endif				/* DEBUG */
++
++struct sdpcm_shared {
++	u32 flags;
++	u32 trap_addr;
++	u32 assert_exp_addr;
++	u32 assert_file_addr;
++	u32 assert_line;
++	u32 console_addr;	/* Address of struct rte_console */
++	u32 msgtrace_addr;
++	u8 tag[32];
++};
++
++struct sdpcm_shared_le {
++	__le32 flags;
++	__le32 trap_addr;
++	__le32 assert_exp_addr;
++	__le32 assert_file_addr;
++	__le32 assert_line;
++	__le32 console_addr;	/* Address of struct rte_console */
++	__le32 msgtrace_addr;
++	u8 tag[32];
++};
++
++
++/* misc chip info needed by some of the routines */
++/* Private data for SDIO bus interaction */
++struct brcmf_sdio {
++	struct brcmf_sdio_dev *sdiodev;	/* sdio device handler */
++	struct chip_info *ci;	/* Chip info struct */
++	char *vars;		/* Variables (from CIS and/or other) */
++	uint varsz;		/* Size of variables buffer */
++
++	u32 ramsize;		/* Size of RAM in SOCRAM (bytes) */
++
++	u32 hostintmask;	/* Copy of Host Interrupt Mask */
++	u32 intstatus;	/* Intstatus bits (events) pending */
++	bool dpc_sched;		/* Indicates DPC schedule (intrpt rcvd) */
++	bool fcstate;		/* State of dongle flow-control */
++
++	uint blocksize;		/* Block size of SDIO transfers */
++	uint roundup;		/* Max roundup limit */
++
++	struct pktq txq;	/* Queue length used for flow-control */
++	u8 flowcontrol;	/* per prio flow control bitmask */
++	u8 tx_seq;		/* Transmit sequence number (next) */
++	u8 tx_max;		/* Maximum transmit sequence allowed */
++
++	u8 hdrbuf[MAX_HDR_READ + BRCMF_SDALIGN];
++	u8 *rxhdr;		/* Header of current rx frame (in hdrbuf) */
++	u16 nextlen;		/* Next Read Len from last header */
++	u8 rx_seq;		/* Receive sequence number (expected) */
++	bool rxskip;		/* Skip receive (awaiting NAK ACK) */
++
++	uint rxbound;		/* Rx frames to read before resched */
++	uint txbound;		/* Tx frames to send before resched */
++	uint txminmax;
++
++	struct sk_buff *glomd;	/* Packet containing glomming descriptor */
++	struct sk_buff_head glom; /* Packet list for glommed superframe */
++	uint glomerr;		/* Glom packet read errors */
++
++	u8 *rxbuf;		/* Buffer for receiving control packets */
++	uint rxblen;		/* Allocated length of rxbuf */
++	u8 *rxctl;		/* Aligned pointer into rxbuf */
++	u8 *databuf;		/* Buffer for receiving big glom packet */
++	u8 *dataptr;		/* Aligned pointer into databuf */
++	uint rxlen;		/* Length of valid data in buffer */
++
++	u8 sdpcm_ver;	/* Bus protocol reported by dongle */
++
++	bool intr;		/* Use interrupts */
++	bool poll;		/* Use polling */
++	bool ipend;		/* Device interrupt is pending */
++	uint intrcount;		/* Count of device interrupt callbacks */
++	uint lastintrs;		/* Count as of last watchdog timer */
++	uint spurious;		/* Count of spurious interrupts */
++	uint pollrate;		/* Ticks between device polls */
++	uint polltick;		/* Tick counter */
++	uint pollcnt;		/* Count of active polls */
++
++#ifdef DEBUG
++	uint console_interval;
++	struct brcmf_console console;	/* Console output polling support */
++	uint console_addr;	/* Console address from shared struct */
++#endif				/* DEBUG */
++
++	uint regfails;		/* Count of R_REG failures */
++
++	uint clkstate;		/* State of sd and backplane clock(s) */
++	bool activity;		/* Activity flag for clock down */
++	s32 idletime;		/* Control for activity timeout */
++	s32 idlecount;	/* Activity timeout counter */
++	s32 idleclock;	/* How to set bus driver when idle */
++	s32 sd_rxchain;
++	bool use_rxchain;	/* If brcmf should use PKT chains */
++	bool sleeping;		/* Is SDIO bus sleeping? */
++	bool rxflow_mode;	/* Rx flow control mode */
++	bool rxflow;		/* Is rx flow control on */
++	bool alp_only;		/* Don't use HT clock (ALP only) */
++/* Field to decide if rx of control frames happen in rxbuf or lb-pool */
++	bool usebufpool;
++
++	/* Some additional counters */
++	uint tx_sderrs;		/* Count of tx attempts with sd errors */
++	uint fcqueued;		/* Tx packets that got queued */
++	uint rxrtx;		/* Count of rtx requests (NAK to dongle) */
++	uint rx_toolong;	/* Receive frames too long to receive */
++	uint rxc_errors;	/* SDIO errors when reading control frames */
++	uint rx_hdrfail;	/* SDIO errors on header reads */
++	uint rx_badhdr;		/* Bad received headers (roosync?) */
++	uint rx_badseq;		/* Mismatched rx sequence number */
++	uint fc_rcvd;		/* Number of flow-control events received */
++	uint fc_xoff;		/* Number which turned on flow-control */
++	uint fc_xon;		/* Number which turned off flow-control */
++	uint rxglomfail;	/* Failed deglom attempts */
++	uint rxglomframes;	/* Number of glom frames (superframes) */
++	uint rxglompkts;	/* Number of packets from glom frames */
++	uint f2rxhdrs;		/* Number of header reads */
++	uint f2rxdata;		/* Number of frame data reads */
++	uint f2txdata;		/* Number of f2 frame writes */
++	uint f1regdata;		/* Number of f1 register accesses */
++	uint tickcnt;		/* Number of watchdog been schedule */
++	unsigned long tx_ctlerrs;	/* Err of sending ctrl frames */
++	unsigned long tx_ctlpkts;	/* Ctrl frames sent to dongle */
++	unsigned long rx_ctlerrs;	/* Err of processing rx ctrl frames */
++	unsigned long rx_ctlpkts;	/* Ctrl frames processed from dongle */
++	unsigned long rx_readahead_cnt;	/* Number of packets where header
++					 * read-ahead was used. */
++
++	u8 *ctrl_frame_buf;
++	u32 ctrl_frame_len;
++	bool ctrl_frame_stat;
++
++	spinlock_t txqlock;
++	wait_queue_head_t ctrl_wait;
++	wait_queue_head_t dcmd_resp_wait;
++
++	struct timer_list timer;
++	struct completion watchdog_wait;
++	struct task_struct *watchdog_tsk;
++	bool wd_timer_valid;
++	uint save_ms;
++
++	struct task_struct *dpc_tsk;
++	struct completion dpc_wait;
++	struct list_head dpc_tsklst;
++	spinlock_t dpc_tl_lock;
++
++	struct semaphore sdsem;
++
++	const struct firmware *firmware;
++	u32 fw_ptr;
++
++	bool txoff;		/* Transmit flow-controlled */
++};
++
++/* clkstate */
++#define CLK_NONE	0
++#define CLK_SDONLY	1
++#define CLK_PENDING	2	/* Not used yet */
++#define CLK_AVAIL	3
++
++#ifdef DEBUG
++static int qcount[NUMPRIO];
++static int tx_packets[NUMPRIO];
++#endif				/* DEBUG */
++
++#define SDIO_DRIVE_STRENGTH	6	/* in milliamps */
++
++#define RETRYCHAN(chan) ((chan) == SDPCM_EVENT_CHANNEL)
++
++/* Retry count for register access failures */
++static const uint retry_limit = 2;
++
++/* Limit on rounding up frames */
++static const uint max_roundup = 512;
++
++#define ALIGNMENT  4
++
++static void pkt_align(struct sk_buff *p, int len, int align)
++{
++	uint datalign;
++	datalign = (unsigned long)(p->data);
++	datalign = roundup(datalign, (align)) - datalign;
++	if (datalign)
++		skb_pull(p, datalign);
++	__skb_trim(p, len);
++}
++
++/* To check if there's window offered */
++static bool data_ok(struct brcmf_sdio *bus)
++{
++	return (u8)(bus->tx_max - bus->tx_seq) != 0 &&
++	       ((u8)(bus->tx_max - bus->tx_seq) & 0x80) == 0;
++}
++
++/*
++ * Reads a register in the SDIO hardware block. This block occupies a series of
++ * adresses on the 32 bit backplane bus.
++ */
++static int
++r_sdreg32(struct brcmf_sdio *bus, u32 *regvar, u32 offset)
++{
++	u8 idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV);
++	int ret;
++
++	*regvar = brcmf_sdio_regrl(bus->sdiodev,
++				   bus->ci->c_inf[idx].base + offset, &ret);
++
++	return ret;
++}
++
++static int
++w_sdreg32(struct brcmf_sdio *bus, u32 regval, u32 reg_offset)
++{
++	u8 idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV);
++	int ret;
++
++	brcmf_sdio_regwl(bus->sdiodev,
++			 bus->ci->c_inf[idx].base + reg_offset,
++			 regval, &ret);
++
++	return ret;
++}
++
++#define PKT_AVAILABLE()		(intstatus & I_HMB_FRAME_IND)
++
++#define HOSTINTMASK		(I_HMB_SW_MASK | I_CHIPACTIVE)
++
++/* Packet free applicable unconditionally for sdio and sdspi.
++ * Conditional if bufpool was present for gspi bus.
++ */
++static void brcmf_sdbrcm_pktfree2(struct brcmf_sdio *bus, struct sk_buff *pkt)
++{
++	if (bus->usebufpool)
++		brcmu_pkt_buf_free_skb(pkt);
++}
++
++/* Turn backplane clock on or off */
++static int brcmf_sdbrcm_htclk(struct brcmf_sdio *bus, bool on, bool pendok)
++{
++	int err;
++	u8 clkctl, clkreq, devctl;
++	unsigned long timeout;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	clkctl = 0;
++
++	if (on) {
++		/* Request HT Avail */
++		clkreq =
++		    bus->alp_only ? SBSDIO_ALP_AVAIL_REQ : SBSDIO_HT_AVAIL_REQ;
++
++		brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
++				 clkreq, &err);
++		if (err) {
++			brcmf_dbg(ERROR, "HT Avail request error: %d\n", err);
++			return -EBADE;
++		}
++
++		/* Check current status */
++		clkctl = brcmf_sdio_regrb(bus->sdiodev,
++					  SBSDIO_FUNC1_CHIPCLKCSR, &err);
++		if (err) {
++			brcmf_dbg(ERROR, "HT Avail read error: %d\n", err);
++			return -EBADE;
++		}
++
++		/* Go to pending and await interrupt if appropriate */
++		if (!SBSDIO_CLKAV(clkctl, bus->alp_only) && pendok) {
++			/* Allow only clock-available interrupt */
++			devctl = brcmf_sdio_regrb(bus->sdiodev,
++						  SBSDIO_DEVICE_CTL, &err);
++			if (err) {
++				brcmf_dbg(ERROR, "Devctl error setting CA: %d\n",
++					  err);
++				return -EBADE;
++			}
++
++			devctl |= SBSDIO_DEVCTL_CA_INT_ONLY;
++			brcmf_sdio_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL,
++					 devctl, &err);
++			brcmf_dbg(INFO, "CLKCTL: set PENDING\n");
++			bus->clkstate = CLK_PENDING;
++
++			return 0;
++		} else if (bus->clkstate == CLK_PENDING) {
++			/* Cancel CA-only interrupt filter */
++			devctl = brcmf_sdio_regrb(bus->sdiodev,
++						  SBSDIO_DEVICE_CTL, &err);
++			devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY;
++			brcmf_sdio_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL,
++					 devctl, &err);
++		}
++
++		/* Otherwise, wait here (polling) for HT Avail */
++		timeout = jiffies +
++			  msecs_to_jiffies(PMU_MAX_TRANSITION_DLY/1000);
++		while (!SBSDIO_CLKAV(clkctl, bus->alp_only)) {
++			clkctl = brcmf_sdio_regrb(bus->sdiodev,
++						  SBSDIO_FUNC1_CHIPCLKCSR,
++						  &err);
++			if (time_after(jiffies, timeout))
++				break;
++			else
++				usleep_range(5000, 10000);
++		}
++		if (err) {
++			brcmf_dbg(ERROR, "HT Avail request error: %d\n", err);
++			return -EBADE;
++		}
++		if (!SBSDIO_CLKAV(clkctl, bus->alp_only)) {
++			brcmf_dbg(ERROR, "HT Avail timeout (%d): clkctl 0x%02x\n",
++				  PMU_MAX_TRANSITION_DLY, clkctl);
++			return -EBADE;
++		}
++
++		/* Mark clock available */
++		bus->clkstate = CLK_AVAIL;
++		brcmf_dbg(INFO, "CLKCTL: turned ON\n");
++
++#if defined(DEBUG)
++		if (!bus->alp_only) {
++			if (SBSDIO_ALPONLY(clkctl))
++				brcmf_dbg(ERROR, "HT Clock should be on\n");
++		}
++#endif				/* defined (DEBUG) */
++
++		bus->activity = true;
++	} else {
++		clkreq = 0;
++
++		if (bus->clkstate == CLK_PENDING) {
++			/* Cancel CA-only interrupt filter */
++			devctl = brcmf_sdio_regrb(bus->sdiodev,
++						  SBSDIO_DEVICE_CTL, &err);
++			devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY;
++			brcmf_sdio_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL,
++					 devctl, &err);
++		}
++
++		bus->clkstate = CLK_SDONLY;
++		brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
++				 clkreq, &err);
++		brcmf_dbg(INFO, "CLKCTL: turned OFF\n");
++		if (err) {
++			brcmf_dbg(ERROR, "Failed access turning clock off: %d\n",
++				  err);
++			return -EBADE;
++		}
++	}
++	return 0;
++}
++
++/* Change idle/active SD state */
++static int brcmf_sdbrcm_sdclk(struct brcmf_sdio *bus, bool on)
++{
++	brcmf_dbg(TRACE, "Enter\n");
++
++	if (on)
++		bus->clkstate = CLK_SDONLY;
++	else
++		bus->clkstate = CLK_NONE;
++
++	return 0;
++}
++
++/* Transition SD and backplane clock readiness */
++static int brcmf_sdbrcm_clkctl(struct brcmf_sdio *bus, uint target, bool pendok)
++{
++#ifdef DEBUG
++	uint oldstate = bus->clkstate;
++#endif				/* DEBUG */
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* Early exit if we're already there */
++	if (bus->clkstate == target) {
++		if (target == CLK_AVAIL) {
++			brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS);
++			bus->activity = true;
++		}
++		return 0;
++	}
++
++	switch (target) {
++	case CLK_AVAIL:
++		/* Make sure SD clock is available */
++		if (bus->clkstate == CLK_NONE)
++			brcmf_sdbrcm_sdclk(bus, true);
++		/* Now request HT Avail on the backplane */
++		brcmf_sdbrcm_htclk(bus, true, pendok);
++		brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS);
++		bus->activity = true;
++		break;
++
++	case CLK_SDONLY:
++		/* Remove HT request, or bring up SD clock */
++		if (bus->clkstate == CLK_NONE)
++			brcmf_sdbrcm_sdclk(bus, true);
++		else if (bus->clkstate == CLK_AVAIL)
++			brcmf_sdbrcm_htclk(bus, false, false);
++		else
++			brcmf_dbg(ERROR, "request for %d -> %d\n",
++				  bus->clkstate, target);
++		brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS);
++		break;
++
++	case CLK_NONE:
++		/* Make sure to remove HT request */
++		if (bus->clkstate == CLK_AVAIL)
++			brcmf_sdbrcm_htclk(bus, false, false);
++		/* Now remove the SD clock */
++		brcmf_sdbrcm_sdclk(bus, false);
++		brcmf_sdbrcm_wd_timer(bus, 0);
++		break;
++	}
++#ifdef DEBUG
++	brcmf_dbg(INFO, "%d -> %d\n", oldstate, bus->clkstate);
++#endif				/* DEBUG */
++
++	return 0;
++}
++
++static int brcmf_sdbrcm_bussleep(struct brcmf_sdio *bus, bool sleep)
++{
++	int ret;
++
++	brcmf_dbg(INFO, "request %s (currently %s)\n",
++		  sleep ? "SLEEP" : "WAKE",
++		  bus->sleeping ? "SLEEP" : "WAKE");
++
++	/* Done if we're already in the requested state */
++	if (sleep == bus->sleeping)
++		return 0;
++
++	/* Going to sleep: set the alarm and turn off the lights... */
++	if (sleep) {
++		/* Don't sleep if something is pending */
++		if (bus->dpc_sched || bus->rxskip || pktq_len(&bus->txq))
++			return -EBUSY;
++
++		/* Make sure the controller has the bus up */
++		brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
++
++		/* Tell device to start using OOB wakeup */
++		ret = w_sdreg32(bus, SMB_USE_OOB,
++				offsetof(struct sdpcmd_regs, tosbmailbox));
++		if (ret != 0)
++			brcmf_dbg(ERROR, "CANNOT SIGNAL CHIP, WILL NOT WAKE UP!!\n");
++
++		/* Turn off our contribution to the HT clock request */
++		brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false);
++
++		brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
++				 SBSDIO_FORCE_HW_CLKREQ_OFF, NULL);
++
++		/* Isolate the bus */
++		brcmf_sdio_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL,
++				 SBSDIO_DEVCTL_PADS_ISO, NULL);
++
++		/* Change state */
++		bus->sleeping = true;
++
++	} else {
++		/* Waking up: bus power up is ok, set local state */
++
++		brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
++				 0, NULL);
++
++		/* Make sure the controller has the bus up */
++		brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
++
++		/* Send misc interrupt to indicate OOB not needed */
++		ret = w_sdreg32(bus, 0,
++				offsetof(struct sdpcmd_regs, tosbmailboxdata));
++		if (ret == 0)
++			ret = w_sdreg32(bus, SMB_DEV_INT,
++				offsetof(struct sdpcmd_regs, tosbmailbox));
++
++		if (ret != 0)
++			brcmf_dbg(ERROR, "CANNOT SIGNAL CHIP TO CLEAR OOB!!\n");
++
++		/* Make sure we have SD bus access */
++		brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false);
++
++		/* Change state */
++		bus->sleeping = false;
++	}
++
++	return 0;
++}
++
++static void bus_wake(struct brcmf_sdio *bus)
++{
++	if (bus->sleeping)
++		brcmf_sdbrcm_bussleep(bus, false);
++}
++
++static u32 brcmf_sdbrcm_hostmail(struct brcmf_sdio *bus)
++{
++	u32 intstatus = 0;
++	u32 hmb_data;
++	u8 fcbits;
++	int ret;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* Read mailbox data and ack that we did so */
++	ret = r_sdreg32(bus, &hmb_data,
++			offsetof(struct sdpcmd_regs, tohostmailboxdata));
++
++	if (ret == 0)
++		w_sdreg32(bus, SMB_INT_ACK,
++			  offsetof(struct sdpcmd_regs, tosbmailbox));
++	bus->f1regdata += 2;
++
++	/* Dongle recomposed rx frames, accept them again */
++	if (hmb_data & HMB_DATA_NAKHANDLED) {
++		brcmf_dbg(INFO, "Dongle reports NAK handled, expect rtx of %d\n",
++			  bus->rx_seq);
++		if (!bus->rxskip)
++			brcmf_dbg(ERROR, "unexpected NAKHANDLED!\n");
++
++		bus->rxskip = false;
++		intstatus |= I_HMB_FRAME_IND;
++	}
++
++	/*
++	 * DEVREADY does not occur with gSPI.
++	 */
++	if (hmb_data & (HMB_DATA_DEVREADY | HMB_DATA_FWREADY)) {
++		bus->sdpcm_ver =
++		    (hmb_data & HMB_DATA_VERSION_MASK) >>
++		    HMB_DATA_VERSION_SHIFT;
++		if (bus->sdpcm_ver != SDPCM_PROT_VERSION)
++			brcmf_dbg(ERROR, "Version mismatch, dongle reports %d, "
++				  "expecting %d\n",
++				  bus->sdpcm_ver, SDPCM_PROT_VERSION);
++		else
++			brcmf_dbg(INFO, "Dongle ready, protocol version %d\n",
++				  bus->sdpcm_ver);
++	}
++
++	/*
++	 * Flow Control has been moved into the RX headers and this out of band
++	 * method isn't used any more.
++	 * remaining backward compatible with older dongles.
++	 */
++	if (hmb_data & HMB_DATA_FC) {
++		fcbits = (hmb_data & HMB_DATA_FCDATA_MASK) >>
++							HMB_DATA_FCDATA_SHIFT;
++
++		if (fcbits & ~bus->flowcontrol)
++			bus->fc_xoff++;
++
++		if (bus->flowcontrol & ~fcbits)
++			bus->fc_xon++;
++
++		bus->fc_rcvd++;
++		bus->flowcontrol = fcbits;
++	}
++
++	/* Shouldn't be any others */
++	if (hmb_data & ~(HMB_DATA_DEVREADY |
++			 HMB_DATA_NAKHANDLED |
++			 HMB_DATA_FC |
++			 HMB_DATA_FWREADY |
++			 HMB_DATA_FCDATA_MASK | HMB_DATA_VERSION_MASK))
++		brcmf_dbg(ERROR, "Unknown mailbox data content: 0x%02x\n",
++			  hmb_data);
++
++	return intstatus;
++}
++
++static void brcmf_sdbrcm_rxfail(struct brcmf_sdio *bus, bool abort, bool rtx)
++{
++	uint retries = 0;
++	u16 lastrbc;
++	u8 hi, lo;
++	int err;
++
++	brcmf_dbg(ERROR, "%sterminate frame%s\n",
++		  abort ? "abort command, " : "",
++		  rtx ? ", send NAK" : "");
++
++	if (abort)
++		brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2);
++
++	brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL,
++			 SFC_RF_TERM, &err);
++	bus->f1regdata++;
++
++	/* Wait until the packet has been flushed (device/FIFO stable) */
++	for (lastrbc = retries = 0xffff; retries > 0; retries--) {
++		hi = brcmf_sdio_regrb(bus->sdiodev,
++				      SBSDIO_FUNC1_RFRAMEBCHI, &err);
++		lo = brcmf_sdio_regrb(bus->sdiodev,
++				      SBSDIO_FUNC1_RFRAMEBCLO, &err);
++		bus->f1regdata += 2;
++
++		if ((hi == 0) && (lo == 0))
++			break;
++
++		if ((hi > (lastrbc >> 8)) && (lo > (lastrbc & 0x00ff))) {
++			brcmf_dbg(ERROR, "count growing: last 0x%04x now 0x%04x\n",
++				  lastrbc, (hi << 8) + lo);
++		}
++		lastrbc = (hi << 8) + lo;
++	}
++
++	if (!retries)
++		brcmf_dbg(ERROR, "count never zeroed: last 0x%04x\n", lastrbc);
++	else
++		brcmf_dbg(INFO, "flush took %d iterations\n", 0xffff - retries);
++
++	if (rtx) {
++		bus->rxrtx++;
++		err = w_sdreg32(bus, SMB_NAK,
++				offsetof(struct sdpcmd_regs, tosbmailbox));
++
++		bus->f1regdata++;
++		if (err == 0)
++			bus->rxskip = true;
++	}
++
++	/* Clear partial in any case */
++	bus->nextlen = 0;
++
++	/* If we can't reach the device, signal failure */
++	if (err)
++		bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
++}
++
++/* copy a buffer into a pkt buffer chain */
++static uint brcmf_sdbrcm_glom_from_buf(struct brcmf_sdio *bus, uint len)
++{
++	uint n, ret = 0;
++	struct sk_buff *p;
++	u8 *buf;
++
++	buf = bus->dataptr;
++
++	/* copy the data */
++	skb_queue_walk(&bus->glom, p) {
++		n = min_t(uint, p->len, len);
++		memcpy(p->data, buf, n);
++		buf += n;
++		len -= n;
++		ret += n;
++		if (!len)
++			break;
++	}
++
++	return ret;
++}
++
++/* return total length of buffer chain */
++static uint brcmf_sdbrcm_glom_len(struct brcmf_sdio *bus)
++{
++	struct sk_buff *p;
++	uint total;
++
++	total = 0;
++	skb_queue_walk(&bus->glom, p)
++		total += p->len;
++	return total;
++}
++
++static void brcmf_sdbrcm_free_glom(struct brcmf_sdio *bus)
++{
++	struct sk_buff *cur, *next;
++
++	skb_queue_walk_safe(&bus->glom, cur, next) {
++		skb_unlink(cur, &bus->glom);
++		brcmu_pkt_buf_free_skb(cur);
++	}
++}
++
++static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
++{
++	u16 dlen, totlen;
++	u8 *dptr, num = 0;
++
++	u16 sublen, check;
++	struct sk_buff *pfirst, *pnext;
++
++	int errcode;
++	u8 chan, seq, doff, sfdoff;
++	u8 txmax;
++
++	int ifidx = 0;
++	bool usechain = bus->use_rxchain;
++
++	/* If packets, issue read(s) and send up packet chain */
++	/* Return sequence numbers consumed? */
++
++	brcmf_dbg(TRACE, "start: glomd %p glom %p\n",
++		  bus->glomd, skb_peek(&bus->glom));
++
++	/* If there's a descriptor, generate the packet chain */
++	if (bus->glomd) {
++		pfirst = pnext = NULL;
++		dlen = (u16) (bus->glomd->len);
++		dptr = bus->glomd->data;
++		if (!dlen || (dlen & 1)) {
++			brcmf_dbg(ERROR, "bad glomd len(%d), ignore descriptor\n",
++				  dlen);
++			dlen = 0;
++		}
++
++		for (totlen = num = 0; dlen; num++) {
++			/* Get (and move past) next length */
++			sublen = get_unaligned_le16(dptr);
++			dlen -= sizeof(u16);
++			dptr += sizeof(u16);
++			if ((sublen < SDPCM_HDRLEN) ||
++			    ((num == 0) && (sublen < (2 * SDPCM_HDRLEN)))) {
++				brcmf_dbg(ERROR, "descriptor len %d bad: %d\n",
++					  num, sublen);
++				pnext = NULL;
++				break;
++			}
++			if (sublen % BRCMF_SDALIGN) {
++				brcmf_dbg(ERROR, "sublen %d not multiple of %d\n",
++					  sublen, BRCMF_SDALIGN);
++				usechain = false;
++			}
++			totlen += sublen;
++
++			/* For last frame, adjust read len so total
++				 is a block multiple */
++			if (!dlen) {
++				sublen +=
++				    (roundup(totlen, bus->blocksize) - totlen);
++				totlen = roundup(totlen, bus->blocksize);
++			}
++
++			/* Allocate/chain packet for next subframe */
++			pnext = brcmu_pkt_buf_get_skb(sublen + BRCMF_SDALIGN);
++			if (pnext == NULL) {
++				brcmf_dbg(ERROR, "bcm_pkt_buf_get_skb failed, num %d len %d\n",
++					  num, sublen);
++				break;
++			}
++			skb_queue_tail(&bus->glom, pnext);
++
++			/* Adhere to start alignment requirements */
++			pkt_align(pnext, sublen, BRCMF_SDALIGN);
++		}
++
++		/* If all allocations succeeded, save packet chain
++			 in bus structure */
++		if (pnext) {
++			brcmf_dbg(GLOM, "allocated %d-byte packet chain for %d subframes\n",
++				  totlen, num);
++			if (BRCMF_GLOM_ON() && bus->nextlen &&
++			    totlen != bus->nextlen) {
++				brcmf_dbg(GLOM, "glomdesc mismatch: nextlen %d glomdesc %d rxseq %d\n",
++					  bus->nextlen, totlen, rxseq);
++			}
++			pfirst = pnext = NULL;
++		} else {
++			brcmf_sdbrcm_free_glom(bus);
++			num = 0;
++		}
++
++		/* Done with descriptor packet */
++		brcmu_pkt_buf_free_skb(bus->glomd);
++		bus->glomd = NULL;
++		bus->nextlen = 0;
++	}
++
++	/* Ok -- either we just generated a packet chain,
++		 or had one from before */
++	if (!skb_queue_empty(&bus->glom)) {
++		if (BRCMF_GLOM_ON()) {
++			brcmf_dbg(GLOM, "try superframe read, packet chain:\n");
++			skb_queue_walk(&bus->glom, pnext) {
++				brcmf_dbg(GLOM, "    %p: %p len 0x%04x (%d)\n",
++					  pnext, (u8 *) (pnext->data),
++					  pnext->len, pnext->len);
++			}
++		}
++
++		pfirst = skb_peek(&bus->glom);
++		dlen = (u16) brcmf_sdbrcm_glom_len(bus);
++
++		/* Do an SDIO read for the superframe.  Configurable iovar to
++		 * read directly into the chained packet, or allocate a large
++		 * packet and and copy into the chain.
++		 */
++		if (usechain) {
++			errcode = brcmf_sdcard_recv_chain(bus->sdiodev,
++					bus->sdiodev->sbwad,
++					SDIO_FUNC_2, F2SYNC, &bus->glom);
++		} else if (bus->dataptr) {
++			errcode = brcmf_sdcard_recv_buf(bus->sdiodev,
++					bus->sdiodev->sbwad,
++					SDIO_FUNC_2, F2SYNC,
++					bus->dataptr, dlen);
++			sublen = (u16) brcmf_sdbrcm_glom_from_buf(bus, dlen);
++			if (sublen != dlen) {
++				brcmf_dbg(ERROR, "FAILED TO COPY, dlen %d sublen %d\n",
++					  dlen, sublen);
++				errcode = -1;
++			}
++			pnext = NULL;
++		} else {
++			brcmf_dbg(ERROR, "COULDN'T ALLOC %d-BYTE GLOM, FORCE FAILURE\n",
++				  dlen);
++			errcode = -1;
++		}
++		bus->f2rxdata++;
++
++		/* On failure, kill the superframe, allow a couple retries */
++		if (errcode < 0) {
++			brcmf_dbg(ERROR, "glom read of %d bytes failed: %d\n",
++				  dlen, errcode);
++			bus->sdiodev->bus_if->dstats.rx_errors++;
++
++			if (bus->glomerr++ < 3) {
++				brcmf_sdbrcm_rxfail(bus, true, true);
++			} else {
++				bus->glomerr = 0;
++				brcmf_sdbrcm_rxfail(bus, true, false);
++				bus->rxglomfail++;
++				brcmf_sdbrcm_free_glom(bus);
++			}
++			return 0;
++		}
++
++		brcmf_dbg_hex_dump(BRCMF_GLOM_ON(),
++				   pfirst->data, min_t(int, pfirst->len, 48),
++				   "SUPERFRAME:\n");
++
++		/* Validate the superframe header */
++		dptr = (u8 *) (pfirst->data);
++		sublen = get_unaligned_le16(dptr);
++		check = get_unaligned_le16(dptr + sizeof(u16));
++
++		chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]);
++		seq = SDPCM_PACKET_SEQUENCE(&dptr[SDPCM_FRAMETAG_LEN]);
++		bus->nextlen = dptr[SDPCM_FRAMETAG_LEN + SDPCM_NEXTLEN_OFFSET];
++		if ((bus->nextlen << 4) > MAX_RX_DATASZ) {
++			brcmf_dbg(INFO, "nextlen too large (%d) seq %d\n",
++				  bus->nextlen, seq);
++			bus->nextlen = 0;
++		}
++		doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]);
++		txmax = SDPCM_WINDOW_VALUE(&dptr[SDPCM_FRAMETAG_LEN]);
++
++		errcode = 0;
++		if ((u16)~(sublen ^ check)) {
++			brcmf_dbg(ERROR, "(superframe): HW hdr error: len/check 0x%04x/0x%04x\n",
++				  sublen, check);
++			errcode = -1;
++		} else if (roundup(sublen, bus->blocksize) != dlen) {
++			brcmf_dbg(ERROR, "(superframe): len 0x%04x, rounded 0x%04x, expect 0x%04x\n",
++				  sublen, roundup(sublen, bus->blocksize),
++				  dlen);
++			errcode = -1;
++		} else if (SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]) !=
++			   SDPCM_GLOM_CHANNEL) {
++			brcmf_dbg(ERROR, "(superframe): bad channel %d\n",
++				  SDPCM_PACKET_CHANNEL(
++					  &dptr[SDPCM_FRAMETAG_LEN]));
++			errcode = -1;
++		} else if (SDPCM_GLOMDESC(&dptr[SDPCM_FRAMETAG_LEN])) {
++			brcmf_dbg(ERROR, "(superframe): got 2nd descriptor?\n");
++			errcode = -1;
++		} else if ((doff < SDPCM_HDRLEN) ||
++			   (doff > (pfirst->len - SDPCM_HDRLEN))) {
++			brcmf_dbg(ERROR, "(superframe): Bad data offset %d: HW %d pkt %d min %d\n",
++				  doff, sublen, pfirst->len, SDPCM_HDRLEN);
++			errcode = -1;
++		}
++
++		/* Check sequence number of superframe SW header */
++		if (rxseq != seq) {
++			brcmf_dbg(INFO, "(superframe) rx_seq %d, expected %d\n",
++				  seq, rxseq);
++			bus->rx_badseq++;
++			rxseq = seq;
++		}
++
++		/* Check window for sanity */
++		if ((u8) (txmax - bus->tx_seq) > 0x40) {
++			brcmf_dbg(ERROR, "unlikely tx max %d with tx_seq %d\n",
++				  txmax, bus->tx_seq);
++			txmax = bus->tx_seq + 2;
++		}
++		bus->tx_max = txmax;
++
++		/* Remove superframe header, remember offset */
++		skb_pull(pfirst, doff);
++		sfdoff = doff;
++		num = 0;
++
++		/* Validate all the subframe headers */
++		skb_queue_walk(&bus->glom, pnext) {
++			/* leave when invalid subframe is found */
++			if (errcode)
++				break;
++
++			dptr = (u8 *) (pnext->data);
++			dlen = (u16) (pnext->len);
++			sublen = get_unaligned_le16(dptr);
++			check = get_unaligned_le16(dptr + sizeof(u16));
++			chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]);
++			doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]);
++			brcmf_dbg_hex_dump(BRCMF_GLOM_ON(),
++					   dptr, 32, "subframe:\n");
++
++			if ((u16)~(sublen ^ check)) {
++				brcmf_dbg(ERROR, "(subframe %d): HW hdr error: len/check 0x%04x/0x%04x\n",
++					  num, sublen, check);
++				errcode = -1;
++			} else if ((sublen > dlen) || (sublen < SDPCM_HDRLEN)) {
++				brcmf_dbg(ERROR, "(subframe %d): length mismatch: len 0x%04x, expect 0x%04x\n",
++					  num, sublen, dlen);
++				errcode = -1;
++			} else if ((chan != SDPCM_DATA_CHANNEL) &&
++				   (chan != SDPCM_EVENT_CHANNEL)) {
++				brcmf_dbg(ERROR, "(subframe %d): bad channel %d\n",
++					  num, chan);
++				errcode = -1;
++			} else if ((doff < SDPCM_HDRLEN) || (doff > sublen)) {
++				brcmf_dbg(ERROR, "(subframe %d): Bad data offset %d: HW %d min %d\n",
++					  num, doff, sublen, SDPCM_HDRLEN);
++				errcode = -1;
++			}
++			/* increase the subframe count */
++			num++;
++		}
++
++		if (errcode) {
++			/* Terminate frame on error, request
++				 a couple retries */
++			if (bus->glomerr++ < 3) {
++				/* Restore superframe header space */
++				skb_push(pfirst, sfdoff);
++				brcmf_sdbrcm_rxfail(bus, true, true);
++			} else {
++				bus->glomerr = 0;
++				brcmf_sdbrcm_rxfail(bus, true, false);
++				bus->rxglomfail++;
++				brcmf_sdbrcm_free_glom(bus);
++			}
++			bus->nextlen = 0;
++			return 0;
++		}
++
++		/* Basic SD framing looks ok - process each packet (header) */
++
++		skb_queue_walk_safe(&bus->glom, pfirst, pnext) {
++			dptr = (u8 *) (pfirst->data);
++			sublen = get_unaligned_le16(dptr);
++			chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]);
++			seq = SDPCM_PACKET_SEQUENCE(&dptr[SDPCM_FRAMETAG_LEN]);
++			doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]);
++
++			brcmf_dbg(GLOM, "Get subframe %d, %p(%p/%d), sublen %d chan %d seq %d\n",
++				  num, pfirst, pfirst->data,
++				  pfirst->len, sublen, chan, seq);
++
++			/* precondition: chan == SDPCM_DATA_CHANNEL ||
++					 chan == SDPCM_EVENT_CHANNEL */
++
++			if (rxseq != seq) {
++				brcmf_dbg(GLOM, "rx_seq %d, expected %d\n",
++					  seq, rxseq);
++				bus->rx_badseq++;
++				rxseq = seq;
++			}
++			rxseq++;
++
++			brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_DATA_ON(),
++					   dptr, dlen, "Rx Subframe Data:\n");
++
++			__skb_trim(pfirst, sublen);
++			skb_pull(pfirst, doff);
++
++			if (pfirst->len == 0) {
++				skb_unlink(pfirst, &bus->glom);
++				brcmu_pkt_buf_free_skb(pfirst);
++				continue;
++			} else if (brcmf_proto_hdrpull(bus->sdiodev->dev,
++						       &ifidx, pfirst) != 0) {
++				brcmf_dbg(ERROR, "rx protocol error\n");
++				bus->sdiodev->bus_if->dstats.rx_errors++;
++				skb_unlink(pfirst, &bus->glom);
++				brcmu_pkt_buf_free_skb(pfirst);
++				continue;
++			}
++
++			brcmf_dbg_hex_dump(BRCMF_GLOM_ON(),
++					   pfirst->data,
++					   min_t(int, pfirst->len, 32),
++					   "subframe %d to stack, %p (%p/%d) nxt/lnk %p/%p\n",
++					   bus->glom.qlen, pfirst, pfirst->data,
++					   pfirst->len, pfirst->next,
++					   pfirst->prev);
++		}
++		/* sent any remaining packets up */
++		if (bus->glom.qlen) {
++			up(&bus->sdsem);
++			brcmf_rx_frame(bus->sdiodev->dev, ifidx, &bus->glom);
++			down(&bus->sdsem);
++		}
++
++		bus->rxglomframes++;
++		bus->rxglompkts += bus->glom.qlen;
++	}
++	return num;
++}
++
++static int brcmf_sdbrcm_dcmd_resp_wait(struct brcmf_sdio *bus, uint *condition,
++					bool *pending)
++{
++	DECLARE_WAITQUEUE(wait, current);
++	int timeout = msecs_to_jiffies(DCMD_RESP_TIMEOUT);
++
++	/* Wait until control frame is available */
++	add_wait_queue(&bus->dcmd_resp_wait, &wait);
++	set_current_state(TASK_INTERRUPTIBLE);
++
++	while (!(*condition) && (!signal_pending(current) && timeout))
++		timeout = schedule_timeout(timeout);
++
++	if (signal_pending(current))
++		*pending = true;
++
++	set_current_state(TASK_RUNNING);
++	remove_wait_queue(&bus->dcmd_resp_wait, &wait);
++
++	return timeout;
++}
++
++static int brcmf_sdbrcm_dcmd_resp_wake(struct brcmf_sdio *bus)
++{
++	if (waitqueue_active(&bus->dcmd_resp_wait))
++		wake_up_interruptible(&bus->dcmd_resp_wait);
++
++	return 0;
++}
++static void
++brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff)
++{
++	uint rdlen, pad;
++
++	int sdret;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* Set rxctl for frame (w/optional alignment) */
++	bus->rxctl = bus->rxbuf;
++	bus->rxctl += BRCMF_FIRSTREAD;
++	pad = ((unsigned long)bus->rxctl % BRCMF_SDALIGN);
++	if (pad)
++		bus->rxctl += (BRCMF_SDALIGN - pad);
++	bus->rxctl -= BRCMF_FIRSTREAD;
++
++	/* Copy the already-read portion over */
++	memcpy(bus->rxctl, hdr, BRCMF_FIRSTREAD);
++	if (len <= BRCMF_FIRSTREAD)
++		goto gotpkt;
++
++	/* Raise rdlen to next SDIO block to avoid tail command */
++	rdlen = len - BRCMF_FIRSTREAD;
++	if (bus->roundup && bus->blocksize && (rdlen > bus->blocksize)) {
++		pad = bus->blocksize - (rdlen % bus->blocksize);
++		if ((pad <= bus->roundup) && (pad < bus->blocksize) &&
++		    ((len + pad) < bus->sdiodev->bus_if->maxctl))
++			rdlen += pad;
++	} else if (rdlen % BRCMF_SDALIGN) {
++		rdlen += BRCMF_SDALIGN - (rdlen % BRCMF_SDALIGN);
++	}
++
++	/* Satisfy length-alignment requirements */
++	if (rdlen & (ALIGNMENT - 1))
++		rdlen = roundup(rdlen, ALIGNMENT);
++
++	/* Drop if the read is too big or it exceeds our maximum */
++	if ((rdlen + BRCMF_FIRSTREAD) > bus->sdiodev->bus_if->maxctl) {
++		brcmf_dbg(ERROR, "%d-byte control read exceeds %d-byte buffer\n",
++			  rdlen, bus->sdiodev->bus_if->maxctl);
++		bus->sdiodev->bus_if->dstats.rx_errors++;
++		brcmf_sdbrcm_rxfail(bus, false, false);
++		goto done;
++	}
++
++	if ((len - doff) > bus->sdiodev->bus_if->maxctl) {
++		brcmf_dbg(ERROR, "%d-byte ctl frame (%d-byte ctl data) exceeds %d-byte limit\n",
++			  len, len - doff, bus->sdiodev->bus_if->maxctl);
++		bus->sdiodev->bus_if->dstats.rx_errors++;
++		bus->rx_toolong++;
++		brcmf_sdbrcm_rxfail(bus, false, false);
++		goto done;
++	}
++
++	/* Read remainder of frame body into the rxctl buffer */
++	sdret = brcmf_sdcard_recv_buf(bus->sdiodev,
++				bus->sdiodev->sbwad,
++				SDIO_FUNC_2,
++				F2SYNC, (bus->rxctl + BRCMF_FIRSTREAD), rdlen);
++	bus->f2rxdata++;
++
++	/* Control frame failures need retransmission */
++	if (sdret < 0) {
++		brcmf_dbg(ERROR, "read %d control bytes failed: %d\n",
++			  rdlen, sdret);
++		bus->rxc_errors++;
++		brcmf_sdbrcm_rxfail(bus, true, true);
++		goto done;
++	}
++
++gotpkt:
++
++	brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_CTL_ON(),
++			   bus->rxctl, len, "RxCtrl:\n");
++
++	/* Point to valid data and indicate its length */
++	bus->rxctl += doff;
++	bus->rxlen = len - doff;
++
++done:
++	/* Awake any waiters */
++	brcmf_sdbrcm_dcmd_resp_wake(bus);
++}
++
++/* Pad read to blocksize for efficiency */
++static void brcmf_pad(struct brcmf_sdio *bus, u16 *pad, u16 *rdlen)
++{
++	if (bus->roundup && bus->blocksize && *rdlen > bus->blocksize) {
++		*pad = bus->blocksize - (*rdlen % bus->blocksize);
++		if (*pad <= bus->roundup && *pad < bus->blocksize &&
++		    *rdlen + *pad + BRCMF_FIRSTREAD < MAX_RX_DATASZ)
++			*rdlen += *pad;
++	} else if (*rdlen % BRCMF_SDALIGN) {
++		*rdlen += BRCMF_SDALIGN - (*rdlen % BRCMF_SDALIGN);
++	}
++}
++
++static void
++brcmf_alloc_pkt_and_read(struct brcmf_sdio *bus, u16 rdlen,
++			 struct sk_buff **pkt, u8 **rxbuf)
++{
++	int sdret;		/* Return code from calls */
++
++	*pkt = brcmu_pkt_buf_get_skb(rdlen + BRCMF_SDALIGN);
++	if (*pkt == NULL)
++		return;
++
++	pkt_align(*pkt, rdlen, BRCMF_SDALIGN);
++	*rxbuf = (u8 *) ((*pkt)->data);
++	/* Read the entire frame */
++	sdret = brcmf_sdcard_recv_pkt(bus->sdiodev, bus->sdiodev->sbwad,
++				      SDIO_FUNC_2, F2SYNC, *pkt);
++	bus->f2rxdata++;
++
++	if (sdret < 0) {
++		brcmf_dbg(ERROR, "(nextlen): read %d bytes failed: %d\n",
++			  rdlen, sdret);
++		brcmu_pkt_buf_free_skb(*pkt);
++		bus->sdiodev->bus_if->dstats.rx_errors++;
++		/* Force retry w/normal header read.
++		 * Don't attempt NAK for
++		 * gSPI
++		 */
++		brcmf_sdbrcm_rxfail(bus, true, true);
++		*pkt = NULL;
++	}
++}
++
++/* Checks the header */
++static int
++brcmf_check_rxbuf(struct brcmf_sdio *bus, struct sk_buff *pkt, u8 *rxbuf,
++		  u8 rxseq, u16 nextlen, u16 *len)
++{
++	u16 check;
++	bool len_consistent;	/* Result of comparing readahead len and
++				   len from hw-hdr */
++
++	memcpy(bus->rxhdr, rxbuf, SDPCM_HDRLEN);
++
++	/* Extract hardware header fields */
++	*len = get_unaligned_le16(bus->rxhdr);
++	check = get_unaligned_le16(bus->rxhdr + sizeof(u16));
++
++	/* All zeros means readahead info was bad */
++	if (!(*len | check)) {
++		brcmf_dbg(INFO, "(nextlen): read zeros in HW header???\n");
++		goto fail;
++	}
++
++	/* Validate check bytes */
++	if ((u16)~(*len ^ check)) {
++		brcmf_dbg(ERROR, "(nextlen): HW hdr error: nextlen/len/check 0x%04x/0x%04x/0x%04x\n",
++			  nextlen, *len, check);
++		bus->rx_badhdr++;
++		brcmf_sdbrcm_rxfail(bus, false, false);
++		goto fail;
++	}
++
++	/* Validate frame length */
++	if (*len < SDPCM_HDRLEN) {
++		brcmf_dbg(ERROR, "(nextlen): HW hdr length invalid: %d\n",
++			  *len);
++		goto fail;
++	}
++
++	/* Check for consistency with readahead info */
++	len_consistent = (nextlen != (roundup(*len, 16) >> 4));
++	if (len_consistent) {
++		/* Mismatch, force retry w/normal
++			header (may be >4K) */
++		brcmf_dbg(ERROR, "(nextlen): mismatch, nextlen %d len %d rnd %d; expected rxseq %d\n",
++			  nextlen, *len, roundup(*len, 16),
++			  rxseq);
++		brcmf_sdbrcm_rxfail(bus, true, true);
++		goto fail;
++	}
++
++	return 0;
++
++fail:
++	brcmf_sdbrcm_pktfree2(bus, pkt);
++	return -EINVAL;
++}
++
++/* Return true if there may be more frames to read */
++static uint
++brcmf_sdbrcm_readframes(struct brcmf_sdio *bus, uint maxframes, bool *finished)
++{
++	u16 len, check;	/* Extracted hardware header fields */
++	u8 chan, seq, doff;	/* Extracted software header fields */
++	u8 fcbits;		/* Extracted fcbits from software header */
++
++	struct sk_buff *pkt;		/* Packet for event or data frames */
++	u16 pad;		/* Number of pad bytes to read */
++	u16 rdlen;		/* Total number of bytes to read */
++	u8 rxseq;		/* Next sequence number to expect */
++	uint rxleft = 0;	/* Remaining number of frames allowed */
++	int sdret;		/* Return code from calls */
++	u8 txmax;		/* Maximum tx sequence offered */
++	u8 *rxbuf;
++	int ifidx = 0;
++	uint rxcount = 0;	/* Total frames read */
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* Not finished unless we encounter no more frames indication */
++	*finished = false;
++
++	for (rxseq = bus->rx_seq, rxleft = maxframes;
++	     !bus->rxskip && rxleft &&
++	     bus->sdiodev->bus_if->state != BRCMF_BUS_DOWN;
++	     rxseq++, rxleft--) {
++
++		/* Handle glomming separately */
++		if (bus->glomd || !skb_queue_empty(&bus->glom)) {
++			u8 cnt;
++			brcmf_dbg(GLOM, "calling rxglom: glomd %p, glom %p\n",
++				  bus->glomd, skb_peek(&bus->glom));
++			cnt = brcmf_sdbrcm_rxglom(bus, rxseq);
++			brcmf_dbg(GLOM, "rxglom returned %d\n", cnt);
++			rxseq += cnt - 1;
++			rxleft = (rxleft > cnt) ? (rxleft - cnt) : 1;
++			continue;
++		}
++
++		/* Try doing single read if we can */
++		if (bus->nextlen) {
++			u16 nextlen = bus->nextlen;
++			bus->nextlen = 0;
++
++			rdlen = len = nextlen << 4;
++			brcmf_pad(bus, &pad, &rdlen);
++
++			/*
++			 * After the frame is received we have to
++			 * distinguish whether it is data
++			 * or non-data frame.
++			 */
++			brcmf_alloc_pkt_and_read(bus, rdlen, &pkt, &rxbuf);
++			if (pkt == NULL) {
++				/* Give up on data, request rtx of events */
++				brcmf_dbg(ERROR, "(nextlen): brcmf_alloc_pkt_and_read failed: len %d rdlen %d expected rxseq %d\n",
++					  len, rdlen, rxseq);
++				continue;
++			}
++
++			if (brcmf_check_rxbuf(bus, pkt, rxbuf, rxseq, nextlen,
++					      &len) < 0)
++				continue;
++
++			/* Extract software header fields */
++			chan = SDPCM_PACKET_CHANNEL(
++					&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
++			seq = SDPCM_PACKET_SEQUENCE(
++					&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
++			doff = SDPCM_DOFFSET_VALUE(
++					&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
++			txmax = SDPCM_WINDOW_VALUE(
++					&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
++
++			bus->nextlen =
++			    bus->rxhdr[SDPCM_FRAMETAG_LEN +
++				       SDPCM_NEXTLEN_OFFSET];
++			if ((bus->nextlen << 4) > MAX_RX_DATASZ) {
++				brcmf_dbg(INFO, "(nextlen): got frame w/nextlen too large (%d), seq %d\n",
++					  bus->nextlen, seq);
++				bus->nextlen = 0;
++			}
++
++			bus->rx_readahead_cnt++;
++
++			/* Handle Flow Control */
++			fcbits = SDPCM_FCMASK_VALUE(
++					&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
++
++			if (bus->flowcontrol != fcbits) {
++				if (~bus->flowcontrol & fcbits)
++					bus->fc_xoff++;
++
++				if (bus->flowcontrol & ~fcbits)
++					bus->fc_xon++;
++
++				bus->fc_rcvd++;
++				bus->flowcontrol = fcbits;
++			}
++
++			/* Check and update sequence number */
++			if (rxseq != seq) {
++				brcmf_dbg(INFO, "(nextlen): rx_seq %d, expected %d\n",
++					  seq, rxseq);
++				bus->rx_badseq++;
++				rxseq = seq;
++			}
++
++			/* Check window for sanity */
++			if ((u8) (txmax - bus->tx_seq) > 0x40) {
++				brcmf_dbg(ERROR, "got unlikely tx max %d with tx_seq %d\n",
++					  txmax, bus->tx_seq);
++				txmax = bus->tx_seq + 2;
++			}
++			bus->tx_max = txmax;
++
++			brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_DATA_ON(),
++					   rxbuf, len, "Rx Data:\n");
++			brcmf_dbg_hex_dump(!(BRCMF_BYTES_ON() &&
++					     BRCMF_DATA_ON()) &&
++					   BRCMF_HDRS_ON(),
++					   bus->rxhdr, SDPCM_HDRLEN,
++					   "RxHdr:\n");
++
++			if (chan == SDPCM_CONTROL_CHANNEL) {
++				brcmf_dbg(ERROR, "(nextlen): readahead on control packet %d?\n",
++					  seq);
++				/* Force retry w/normal header read */
++				bus->nextlen = 0;
++				brcmf_sdbrcm_rxfail(bus, false, true);
++				brcmf_sdbrcm_pktfree2(bus, pkt);
++				continue;
++			}
++
++			/* Validate data offset */
++			if ((doff < SDPCM_HDRLEN) || (doff > len)) {
++				brcmf_dbg(ERROR, "(nextlen): bad data offset %d: HW len %d min %d\n",
++					  doff, len, SDPCM_HDRLEN);
++				brcmf_sdbrcm_rxfail(bus, false, false);
++				brcmf_sdbrcm_pktfree2(bus, pkt);
++				continue;
++			}
++
++			/* All done with this one -- now deliver the packet */
++			goto deliver;
++		}
++
++		/* Read frame header (hardware and software) */
++		sdret = brcmf_sdcard_recv_buf(bus->sdiodev, bus->sdiodev->sbwad,
++					      SDIO_FUNC_2, F2SYNC, bus->rxhdr,
++					      BRCMF_FIRSTREAD);
++		bus->f2rxhdrs++;
++
++		if (sdret < 0) {
++			brcmf_dbg(ERROR, "RXHEADER FAILED: %d\n", sdret);
++			bus->rx_hdrfail++;
++			brcmf_sdbrcm_rxfail(bus, true, true);
++			continue;
++		}
++		brcmf_dbg_hex_dump(BRCMF_BYTES_ON() || BRCMF_HDRS_ON(),
++				   bus->rxhdr, SDPCM_HDRLEN, "RxHdr:\n");
++
++
++		/* Extract hardware header fields */
++		len = get_unaligned_le16(bus->rxhdr);
++		check = get_unaligned_le16(bus->rxhdr + sizeof(u16));
++
++		/* All zeros means no more frames */
++		if (!(len | check)) {
++			*finished = true;
++			break;
++		}
++
++		/* Validate check bytes */
++		if ((u16) ~(len ^ check)) {
++			brcmf_dbg(ERROR, "HW hdr err: len/check 0x%04x/0x%04x\n",
++				  len, check);
++			bus->rx_badhdr++;
++			brcmf_sdbrcm_rxfail(bus, false, false);
++			continue;
++		}
++
++		/* Validate frame length */
++		if (len < SDPCM_HDRLEN) {
++			brcmf_dbg(ERROR, "HW hdr length invalid: %d\n", len);
++			continue;
++		}
++
++		/* Extract software header fields */
++		chan = SDPCM_PACKET_CHANNEL(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
++		seq = SDPCM_PACKET_SEQUENCE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
++		doff = SDPCM_DOFFSET_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
++		txmax = SDPCM_WINDOW_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
++
++		/* Validate data offset */
++		if ((doff < SDPCM_HDRLEN) || (doff > len)) {
++			brcmf_dbg(ERROR, "Bad data offset %d: HW len %d, min %d seq %d\n",
++				  doff, len, SDPCM_HDRLEN, seq);
++			bus->rx_badhdr++;
++			brcmf_sdbrcm_rxfail(bus, false, false);
++			continue;
++		}
++
++		/* Save the readahead length if there is one */
++		bus->nextlen =
++		    bus->rxhdr[SDPCM_FRAMETAG_LEN + SDPCM_NEXTLEN_OFFSET];
++		if ((bus->nextlen << 4) > MAX_RX_DATASZ) {
++			brcmf_dbg(INFO, "(nextlen): got frame w/nextlen too large (%d), seq %d\n",
++				  bus->nextlen, seq);
++			bus->nextlen = 0;
++		}
++
++		/* Handle Flow Control */
++		fcbits = SDPCM_FCMASK_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
++
++		if (bus->flowcontrol != fcbits) {
++			if (~bus->flowcontrol & fcbits)
++				bus->fc_xoff++;
++
++			if (bus->flowcontrol & ~fcbits)
++				bus->fc_xon++;
++
++			bus->fc_rcvd++;
++			bus->flowcontrol = fcbits;
++		}
++
++		/* Check and update sequence number */
++		if (rxseq != seq) {
++			brcmf_dbg(INFO, "rx_seq %d, expected %d\n", seq, rxseq);
++			bus->rx_badseq++;
++			rxseq = seq;
++		}
++
++		/* Check window for sanity */
++		if ((u8) (txmax - bus->tx_seq) > 0x40) {
++			brcmf_dbg(ERROR, "unlikely tx max %d with tx_seq %d\n",
++				  txmax, bus->tx_seq);
++			txmax = bus->tx_seq + 2;
++		}
++		bus->tx_max = txmax;
++
++		/* Call a separate function for control frames */
++		if (chan == SDPCM_CONTROL_CHANNEL) {
++			brcmf_sdbrcm_read_control(bus, bus->rxhdr, len, doff);
++			continue;
++		}
++
++		/* precondition: chan is either SDPCM_DATA_CHANNEL,
++		   SDPCM_EVENT_CHANNEL, SDPCM_TEST_CHANNEL or
++		   SDPCM_GLOM_CHANNEL */
++
++		/* Length to read */
++		rdlen = (len > BRCMF_FIRSTREAD) ? (len - BRCMF_FIRSTREAD) : 0;
++
++		/* May pad read to blocksize for efficiency */
++		if (bus->roundup && bus->blocksize &&
++			(rdlen > bus->blocksize)) {
++			pad = bus->blocksize - (rdlen % bus->blocksize);
++			if ((pad <= bus->roundup) && (pad < bus->blocksize) &&
++			    ((rdlen + pad + BRCMF_FIRSTREAD) < MAX_RX_DATASZ))
++				rdlen += pad;
++		} else if (rdlen % BRCMF_SDALIGN) {
++			rdlen += BRCMF_SDALIGN - (rdlen % BRCMF_SDALIGN);
++		}
++
++		/* Satisfy length-alignment requirements */
++		if (rdlen & (ALIGNMENT - 1))
++			rdlen = roundup(rdlen, ALIGNMENT);
++
++		if ((rdlen + BRCMF_FIRSTREAD) > MAX_RX_DATASZ) {
++			/* Too long -- skip this frame */
++			brcmf_dbg(ERROR, "too long: len %d rdlen %d\n",
++				  len, rdlen);
++			bus->sdiodev->bus_if->dstats.rx_errors++;
++			bus->rx_toolong++;
++			brcmf_sdbrcm_rxfail(bus, false, false);
++			continue;
++		}
++
++		pkt = brcmu_pkt_buf_get_skb(rdlen +
++					    BRCMF_FIRSTREAD + BRCMF_SDALIGN);
++		if (!pkt) {
++			/* Give up on data, request rtx of events */
++			brcmf_dbg(ERROR, "brcmu_pkt_buf_get_skb failed: rdlen %d chan %d\n",
++				  rdlen, chan);
++			bus->sdiodev->bus_if->dstats.rx_dropped++;
++			brcmf_sdbrcm_rxfail(bus, false, RETRYCHAN(chan));
++			continue;
++		}
++
++		/* Leave room for what we already read, and align remainder */
++		skb_pull(pkt, BRCMF_FIRSTREAD);
++		pkt_align(pkt, rdlen, BRCMF_SDALIGN);
++
++		/* Read the remaining frame data */
++		sdret = brcmf_sdcard_recv_pkt(bus->sdiodev, bus->sdiodev->sbwad,
++					      SDIO_FUNC_2, F2SYNC, pkt);
++		bus->f2rxdata++;
++
++		if (sdret < 0) {
++			brcmf_dbg(ERROR, "read %d %s bytes failed: %d\n", rdlen,
++				  ((chan == SDPCM_EVENT_CHANNEL) ? "event"
++				   : ((chan == SDPCM_DATA_CHANNEL) ? "data"
++				      : "test")), sdret);
++			brcmu_pkt_buf_free_skb(pkt);
++			bus->sdiodev->bus_if->dstats.rx_errors++;
++			brcmf_sdbrcm_rxfail(bus, true, RETRYCHAN(chan));
++			continue;
++		}
++
++		/* Copy the already-read portion */
++		skb_push(pkt, BRCMF_FIRSTREAD);
++		memcpy(pkt->data, bus->rxhdr, BRCMF_FIRSTREAD);
++
++		brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_DATA_ON(),
++				   pkt->data, len, "Rx Data:\n");
++
++deliver:
++		/* Save superframe descriptor and allocate packet frame */
++		if (chan == SDPCM_GLOM_CHANNEL) {
++			if (SDPCM_GLOMDESC(&bus->rxhdr[SDPCM_FRAMETAG_LEN])) {
++				brcmf_dbg(GLOM, "glom descriptor, %d bytes:\n",
++					  len);
++				brcmf_dbg_hex_dump(BRCMF_GLOM_ON(),
++						   pkt->data, len,
++						   "Glom Data:\n");
++				__skb_trim(pkt, len);
++				skb_pull(pkt, SDPCM_HDRLEN);
++				bus->glomd = pkt;
++			} else {
++				brcmf_dbg(ERROR, "%s: glom superframe w/o "
++					  "descriptor!\n", __func__);
++				brcmf_sdbrcm_rxfail(bus, false, false);
++			}
++			continue;
++		}
++
++		/* Fill in packet len and prio, deliver upward */
++		__skb_trim(pkt, len);
++		skb_pull(pkt, doff);
++
++		if (pkt->len == 0) {
++			brcmu_pkt_buf_free_skb(pkt);
++			continue;
++		} else if (brcmf_proto_hdrpull(bus->sdiodev->dev, &ifidx,
++			   pkt) != 0) {
++			brcmf_dbg(ERROR, "rx protocol error\n");
++			brcmu_pkt_buf_free_skb(pkt);
++			bus->sdiodev->bus_if->dstats.rx_errors++;
++			continue;
++		}
++
++		/* Unlock during rx call */
++		up(&bus->sdsem);
++		brcmf_rx_packet(bus->sdiodev->dev, ifidx, pkt);
++		down(&bus->sdsem);
++	}
++	rxcount = maxframes - rxleft;
++	/* Message if we hit the limit */
++	if (!rxleft)
++		brcmf_dbg(DATA, "hit rx limit of %d frames\n",
++			  maxframes);
++	else
++		brcmf_dbg(DATA, "processed %d frames\n", rxcount);
++	/* Back off rxseq if awaiting rtx, update rx_seq */
++	if (bus->rxskip)
++		rxseq--;
++	bus->rx_seq = rxseq;
++
++	return rxcount;
++}
++
++static void
++brcmf_sdbrcm_wait_for_event(struct brcmf_sdio *bus, bool *lockvar)
++{
++	up(&bus->sdsem);
++	wait_event_interruptible_timeout(bus->ctrl_wait, !*lockvar, HZ * 2);
++	down(&bus->sdsem);
++	return;
++}
++
++static void
++brcmf_sdbrcm_wait_event_wakeup(struct brcmf_sdio *bus)
++{
++	if (waitqueue_active(&bus->ctrl_wait))
++		wake_up_interruptible(&bus->ctrl_wait);
++	return;
++}
++
++/* Writes a HW/SW header into the packet and sends it. */
++/* Assumes: (a) header space already there, (b) caller holds lock */
++static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt,
++			      uint chan, bool free_pkt)
++{
++	int ret;
++	u8 *frame;
++	u16 len, pad = 0;
++	u32 swheader;
++	struct sk_buff *new;
++	int i;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	frame = (u8 *) (pkt->data);
++
++	/* Add alignment padding, allocate new packet if needed */
++	pad = ((unsigned long)frame % BRCMF_SDALIGN);
++	if (pad) {
++		if (skb_headroom(pkt) < pad) {
++			brcmf_dbg(INFO, "insufficient headroom %d for %d pad\n",
++				  skb_headroom(pkt), pad);
++			bus->sdiodev->bus_if->tx_realloc++;
++			new = brcmu_pkt_buf_get_skb(pkt->len + BRCMF_SDALIGN);
++			if (!new) {
++				brcmf_dbg(ERROR, "couldn't allocate new %d-byte packet\n",
++					  pkt->len + BRCMF_SDALIGN);
++				ret = -ENOMEM;
++				goto done;
++			}
++
++			pkt_align(new, pkt->len, BRCMF_SDALIGN);
++			memcpy(new->data, pkt->data, pkt->len);
++			if (free_pkt)
++				brcmu_pkt_buf_free_skb(pkt);
++			/* free the pkt if canned one is not used */
++			free_pkt = true;
++			pkt = new;
++			frame = (u8 *) (pkt->data);
++			/* precondition: (frame % BRCMF_SDALIGN) == 0) */
++			pad = 0;
++		} else {
++			skb_push(pkt, pad);
++			frame = (u8 *) (pkt->data);
++			/* precondition: pad + SDPCM_HDRLEN <= pkt->len */
++			memset(frame, 0, pad + SDPCM_HDRLEN);
++		}
++	}
++	/* precondition: pad < BRCMF_SDALIGN */
++
++	/* Hardware tag: 2 byte len followed by 2 byte ~len check (all LE) */
++	len = (u16) (pkt->len);
++	*(__le16 *) frame = cpu_to_le16(len);
++	*(((__le16 *) frame) + 1) = cpu_to_le16(~len);
++
++	/* Software tag: channel, sequence number, data offset */
++	swheader =
++	    ((chan << SDPCM_CHANNEL_SHIFT) & SDPCM_CHANNEL_MASK) | bus->tx_seq |
++	    (((pad +
++	       SDPCM_HDRLEN) << SDPCM_DOFFSET_SHIFT) & SDPCM_DOFFSET_MASK);
++
++	put_unaligned_le32(swheader, frame + SDPCM_FRAMETAG_LEN);
++	put_unaligned_le32(0, frame + SDPCM_FRAMETAG_LEN + sizeof(swheader));
++
++#ifdef DEBUG
++	tx_packets[pkt->priority]++;
++#endif
++
++	brcmf_dbg_hex_dump(BRCMF_BYTES_ON() &&
++			   ((BRCMF_CTL_ON() && chan == SDPCM_CONTROL_CHANNEL) ||
++			    (BRCMF_DATA_ON() && chan != SDPCM_CONTROL_CHANNEL)),
++			   frame, len, "Tx Frame:\n");
++	brcmf_dbg_hex_dump(!(BRCMF_BYTES_ON() &&
++			     ((BRCMF_CTL_ON() &&
++			       chan == SDPCM_CONTROL_CHANNEL) ||
++			      (BRCMF_DATA_ON() &&
++			       chan != SDPCM_CONTROL_CHANNEL))) &&
++			   BRCMF_HDRS_ON(),
++			   frame, min_t(u16, len, 16), "TxHdr:\n");
++
++	/* Raise len to next SDIO block to eliminate tail command */
++	if (bus->roundup && bus->blocksize && (len > bus->blocksize)) {
++		u16 pad = bus->blocksize - (len % bus->blocksize);
++		if ((pad <= bus->roundup) && (pad < bus->blocksize))
++				len += pad;
++	} else if (len % BRCMF_SDALIGN) {
++		len += BRCMF_SDALIGN - (len % BRCMF_SDALIGN);
++	}
++
++	/* Some controllers have trouble with odd bytes -- round to even */
++	if (len & (ALIGNMENT - 1))
++			len = roundup(len, ALIGNMENT);
++
++	ret = brcmf_sdcard_send_pkt(bus->sdiodev, bus->sdiodev->sbwad,
++				    SDIO_FUNC_2, F2SYNC, pkt);
++	bus->f2txdata++;
++
++	if (ret < 0) {
++		/* On failure, abort the command and terminate the frame */
++		brcmf_dbg(INFO, "sdio error %d, abort command and terminate frame\n",
++			  ret);
++		bus->tx_sderrs++;
++
++		brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2);
++		brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL,
++				 SFC_WF_TERM, NULL);
++		bus->f1regdata++;
++
++		for (i = 0; i < 3; i++) {
++			u8 hi, lo;
++			hi = brcmf_sdio_regrb(bus->sdiodev,
++					      SBSDIO_FUNC1_WFRAMEBCHI, NULL);
++			lo = brcmf_sdio_regrb(bus->sdiodev,
++					      SBSDIO_FUNC1_WFRAMEBCLO, NULL);
++			bus->f1regdata += 2;
++			if ((hi == 0) && (lo == 0))
++				break;
++		}
++
++	}
++	if (ret == 0)
++		bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP;
++
++done:
++	/* restore pkt buffer pointer before calling tx complete routine */
++	skb_pull(pkt, SDPCM_HDRLEN + pad);
++	up(&bus->sdsem);
++	brcmf_txcomplete(bus->sdiodev->dev, pkt, ret != 0);
++	down(&bus->sdsem);
++
++	if (free_pkt)
++		brcmu_pkt_buf_free_skb(pkt);
++
++	return ret;
++}
++
++static uint brcmf_sdbrcm_sendfromq(struct brcmf_sdio *bus, uint maxframes)
++{
++	struct sk_buff *pkt;
++	u32 intstatus = 0;
++	int ret = 0, prec_out;
++	uint cnt = 0;
++	uint datalen;
++	u8 tx_prec_map;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	tx_prec_map = ~bus->flowcontrol;
++
++	/* Send frames until the limit or some other event */
++	for (cnt = 0; (cnt < maxframes) && data_ok(bus); cnt++) {
++		spin_lock_bh(&bus->txqlock);
++		pkt = brcmu_pktq_mdeq(&bus->txq, tx_prec_map, &prec_out);
++		if (pkt == NULL) {
++			spin_unlock_bh(&bus->txqlock);
++			break;
++		}
++		spin_unlock_bh(&bus->txqlock);
++		datalen = pkt->len - SDPCM_HDRLEN;
++
++		ret = brcmf_sdbrcm_txpkt(bus, pkt, SDPCM_DATA_CHANNEL, true);
++		if (ret)
++			bus->sdiodev->bus_if->dstats.tx_errors++;
++		else
++			bus->sdiodev->bus_if->dstats.tx_bytes += datalen;
++
++		/* In poll mode, need to check for other events */
++		if (!bus->intr && cnt) {
++			/* Check device status, signal pending interrupt */
++			ret = r_sdreg32(bus, &intstatus,
++					offsetof(struct sdpcmd_regs,
++						 intstatus));
++			bus->f2txdata++;
++			if (ret != 0)
++				break;
++			if (intstatus & bus->hostintmask)
++				bus->ipend = true;
++		}
++	}
++
++	/* Deflow-control stack if needed */
++	if (bus->sdiodev->bus_if->drvr_up &&
++	    (bus->sdiodev->bus_if->state == BRCMF_BUS_DATA) &&
++	    bus->txoff && (pktq_len(&bus->txq) < TXLOW)) {
++		bus->txoff = OFF;
++		brcmf_txflowcontrol(bus->sdiodev->dev, 0, OFF);
++	}
++
++	return cnt;
++}
++
++static void brcmf_sdbrcm_bus_stop(struct device *dev)
++{
++	u32 local_hostintmask;
++	u8 saveclk;
++	int err;
++	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
++	struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
++	struct brcmf_sdio *bus = sdiodev->bus;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	if (bus->watchdog_tsk) {
++		send_sig(SIGTERM, bus->watchdog_tsk, 1);
++		kthread_stop(bus->watchdog_tsk);
++		bus->watchdog_tsk = NULL;
++	}
++
++	if (bus->dpc_tsk && bus->dpc_tsk != current) {
++		send_sig(SIGTERM, bus->dpc_tsk, 1);
++		kthread_stop(bus->dpc_tsk);
++		bus->dpc_tsk = NULL;
++	}
++
++	down(&bus->sdsem);
++
++	bus_wake(bus);
++
++	/* Enable clock for device interrupts */
++	brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
++
++	/* Disable and clear interrupts at the chip level also */
++	w_sdreg32(bus, 0, offsetof(struct sdpcmd_regs, hostintmask));
++	local_hostintmask = bus->hostintmask;
++	bus->hostintmask = 0;
++
++	/* Change our idea of bus state */
++	bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
++
++	/* Force clocks on backplane to be sure F2 interrupt propagates */
++	saveclk = brcmf_sdio_regrb(bus->sdiodev,
++				   SBSDIO_FUNC1_CHIPCLKCSR, &err);
++	if (!err) {
++		brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
++				 (saveclk | SBSDIO_FORCE_HT), &err);
++	}
++	if (err)
++		brcmf_dbg(ERROR, "Failed to force clock for F2: err %d\n", err);
++
++	/* Turn off the bus (F2), free any pending packets */
++	brcmf_dbg(INTR, "disable SDIO interrupts\n");
++	brcmf_sdio_regwb(bus->sdiodev, SDIO_CCCR_IOEx, SDIO_FUNC_ENABLE_1,
++			 NULL);
++
++	/* Clear any pending interrupts now that F2 is disabled */
++	w_sdreg32(bus, local_hostintmask,
++		  offsetof(struct sdpcmd_regs, intstatus));
++
++	/* Turn off the backplane clock (only) */
++	brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false);
++
++	/* Clear the data packet queues */
++	brcmu_pktq_flush(&bus->txq, true, NULL, NULL);
++
++	/* Clear any held glomming stuff */
++	if (bus->glomd)
++		brcmu_pkt_buf_free_skb(bus->glomd);
++	brcmf_sdbrcm_free_glom(bus);
++
++	/* Clear rx control and wake any waiters */
++	bus->rxlen = 0;
++	brcmf_sdbrcm_dcmd_resp_wake(bus);
++
++	/* Reset some F2 state stuff */
++	bus->rxskip = false;
++	bus->tx_seq = bus->rx_seq = 0;
++
++	up(&bus->sdsem);
++}
++
++#ifdef CONFIG_BRCMFMAC_SDIO_OOB
++static inline void brcmf_sdbrcm_clrintr(struct brcmf_sdio *bus)
++{
++	unsigned long flags;
++
++	spin_lock_irqsave(&bus->sdiodev->irq_en_lock, flags);
++	if (!bus->sdiodev->irq_en && !bus->ipend) {
++		enable_irq(bus->sdiodev->irq);
++		bus->sdiodev->irq_en = true;
++	}
++	spin_unlock_irqrestore(&bus->sdiodev->irq_en_lock, flags);
++}
++#else
++static inline void brcmf_sdbrcm_clrintr(struct brcmf_sdio *bus)
++{
++}
++#endif		/* CONFIG_BRCMFMAC_SDIO_OOB */
++
++static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
++{
++	u32 intstatus, newstatus = 0;
++	uint rxlimit = bus->rxbound;	/* Rx frames to read before resched */
++	uint txlimit = bus->txbound;	/* Tx frames to send before resched */
++	uint framecnt = 0;	/* Temporary counter of tx/rx frames */
++	bool rxdone = true;	/* Flag for no more read data */
++	bool resched = false;	/* Flag indicating resched wanted */
++	int err = 0;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* Start with leftover status bits */
++	intstatus = bus->intstatus;
++
++	down(&bus->sdsem);
++
++	/* If waiting for HTAVAIL, check status */
++	if (bus->clkstate == CLK_PENDING) {
++		u8 clkctl, devctl = 0;
++
++#ifdef DEBUG
++		/* Check for inconsistent device control */
++		devctl = brcmf_sdio_regrb(bus->sdiodev,
++					  SBSDIO_DEVICE_CTL, &err);
++		if (err) {
++			brcmf_dbg(ERROR, "error reading DEVCTL: %d\n", err);
++			bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
++		}
++#endif				/* DEBUG */
++
++		/* Read CSR, if clock on switch to AVAIL, else ignore */
++		clkctl = brcmf_sdio_regrb(bus->sdiodev,
++					  SBSDIO_FUNC1_CHIPCLKCSR, &err);
++		if (err) {
++			brcmf_dbg(ERROR, "error reading CSR: %d\n",
++				  err);
++			bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
++		}
++
++		brcmf_dbg(INFO, "DPC: PENDING, devctl 0x%02x clkctl 0x%02x\n",
++			  devctl, clkctl);
++
++		if (SBSDIO_HTAV(clkctl)) {
++			devctl = brcmf_sdio_regrb(bus->sdiodev,
++						  SBSDIO_DEVICE_CTL, &err);
++			if (err) {
++				brcmf_dbg(ERROR, "error reading DEVCTL: %d\n",
++					  err);
++				bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
++			}
++			devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY;
++			brcmf_sdio_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL,
++					 devctl, &err);
++			if (err) {
++				brcmf_dbg(ERROR, "error writing DEVCTL: %d\n",
++					  err);
++				bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
++			}
++			bus->clkstate = CLK_AVAIL;
++		} else {
++			goto clkwait;
++		}
++	}
++
++	bus_wake(bus);
++
++	/* Make sure backplane clock is on */
++	brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, true);
++	if (bus->clkstate == CLK_PENDING)
++		goto clkwait;
++
++	/* Pending interrupt indicates new device status */
++	if (bus->ipend) {
++		bus->ipend = false;
++		err = r_sdreg32(bus, &newstatus,
++				offsetof(struct sdpcmd_regs, intstatus));
++		bus->f1regdata++;
++		if (err != 0)
++			newstatus = 0;
++		newstatus &= bus->hostintmask;
++		bus->fcstate = !!(newstatus & I_HMB_FC_STATE);
++		if (newstatus) {
++			err = w_sdreg32(bus, newstatus,
++					offsetof(struct sdpcmd_regs,
++						 intstatus));
++			bus->f1regdata++;
++		}
++	}
++
++	/* Merge new bits with previous */
++	intstatus |= newstatus;
++	bus->intstatus = 0;
++
++	/* Handle flow-control change: read new state in case our ack
++	 * crossed another change interrupt.  If change still set, assume
++	 * FC ON for safety, let next loop through do the debounce.
++	 */
++	if (intstatus & I_HMB_FC_CHANGE) {
++		intstatus &= ~I_HMB_FC_CHANGE;
++		err = w_sdreg32(bus, I_HMB_FC_CHANGE,
++				offsetof(struct sdpcmd_regs, intstatus));
++
++		err = r_sdreg32(bus, &newstatus,
++				offsetof(struct sdpcmd_regs, intstatus));
++		bus->f1regdata += 2;
++		bus->fcstate =
++		    !!(newstatus & (I_HMB_FC_STATE | I_HMB_FC_CHANGE));
++		intstatus |= (newstatus & bus->hostintmask);
++	}
++
++	/* Handle host mailbox indication */
++	if (intstatus & I_HMB_HOST_INT) {
++		intstatus &= ~I_HMB_HOST_INT;
++		intstatus |= brcmf_sdbrcm_hostmail(bus);
++	}
++
++	/* Generally don't ask for these, can get CRC errors... */
++	if (intstatus & I_WR_OOSYNC) {
++		brcmf_dbg(ERROR, "Dongle reports WR_OOSYNC\n");
++		intstatus &= ~I_WR_OOSYNC;
++	}
++
++	if (intstatus & I_RD_OOSYNC) {
++		brcmf_dbg(ERROR, "Dongle reports RD_OOSYNC\n");
++		intstatus &= ~I_RD_OOSYNC;
++	}
++
++	if (intstatus & I_SBINT) {
++		brcmf_dbg(ERROR, "Dongle reports SBINT\n");
++		intstatus &= ~I_SBINT;
++	}
++
++	/* Would be active due to wake-wlan in gSPI */
++	if (intstatus & I_CHIPACTIVE) {
++		brcmf_dbg(INFO, "Dongle reports CHIPACTIVE\n");
++		intstatus &= ~I_CHIPACTIVE;
++	}
++
++	/* Ignore frame indications if rxskip is set */
++	if (bus->rxskip)
++		intstatus &= ~I_HMB_FRAME_IND;
++
++	/* On frame indication, read available frames */
++	if (PKT_AVAILABLE()) {
++		framecnt = brcmf_sdbrcm_readframes(bus, rxlimit, &rxdone);
++		if (rxdone || bus->rxskip)
++			intstatus &= ~I_HMB_FRAME_IND;
++		rxlimit -= min(framecnt, rxlimit);
++	}
++
++	/* Keep still-pending events for next scheduling */
++	bus->intstatus = intstatus;
++
++clkwait:
++	brcmf_sdbrcm_clrintr(bus);
++
++	if (data_ok(bus) && bus->ctrl_frame_stat &&
++		(bus->clkstate == CLK_AVAIL)) {
++		int ret, i;
++
++		ret = brcmf_sdcard_send_buf(bus->sdiodev, bus->sdiodev->sbwad,
++			SDIO_FUNC_2, F2SYNC, (u8 *) bus->ctrl_frame_buf,
++			(u32) bus->ctrl_frame_len);
++
++		if (ret < 0) {
++			/* On failure, abort the command and
++				terminate the frame */
++			brcmf_dbg(INFO, "sdio error %d, abort command and terminate frame\n",
++				  ret);
++			bus->tx_sderrs++;
++
++			brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2);
++
++			brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL,
++					 SFC_WF_TERM, &err);
++			bus->f1regdata++;
++
++			for (i = 0; i < 3; i++) {
++				u8 hi, lo;
++				hi = brcmf_sdio_regrb(bus->sdiodev,
++						      SBSDIO_FUNC1_WFRAMEBCHI,
++						      &err);
++				lo = brcmf_sdio_regrb(bus->sdiodev,
++						      SBSDIO_FUNC1_WFRAMEBCLO,
++						      &err);
++				bus->f1regdata += 2;
++				if ((hi == 0) && (lo == 0))
++					break;
++			}
++
++		}
++		if (ret == 0)
++			bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP;
++
++		brcmf_dbg(INFO, "Return_dpc value is : %d\n", ret);
++		bus->ctrl_frame_stat = false;
++		brcmf_sdbrcm_wait_event_wakeup(bus);
++	}
++	/* Send queued frames (limit 1 if rx may still be pending) */
++	else if ((bus->clkstate == CLK_AVAIL) && !bus->fcstate &&
++		 brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) && txlimit
++		 && data_ok(bus)) {
++		framecnt = rxdone ? txlimit : min(txlimit, bus->txminmax);
++		framecnt = brcmf_sdbrcm_sendfromq(bus, framecnt);
++		txlimit -= framecnt;
++	}
++
++	/* Resched if events or tx frames are pending,
++		 else await next interrupt */
++	/* On failed register access, all bets are off:
++		 no resched or interrupts */
++	if ((bus->sdiodev->bus_if->state == BRCMF_BUS_DOWN) || (err != 0)) {
++		brcmf_dbg(ERROR, "failed backplane access over SDIO, halting operation\n");
++		bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
++		bus->intstatus = 0;
++	} else if (bus->clkstate == CLK_PENDING) {
++		brcmf_dbg(INFO, "rescheduled due to CLK_PENDING awaiting I_CHIPACTIVE interrupt\n");
++		resched = true;
++	} else if (bus->intstatus || bus->ipend ||
++		(!bus->fcstate && brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol)
++		 && data_ok(bus)) || PKT_AVAILABLE()) {
++		resched = true;
++	}
++
++	bus->dpc_sched = resched;
++
++	/* If we're done for now, turn off clock request. */
++	if ((bus->clkstate != CLK_PENDING)
++	    && bus->idletime == BRCMF_IDLE_IMMEDIATE) {
++		bus->activity = false;
++		brcmf_sdbrcm_clkctl(bus, CLK_NONE, false);
++	}
++
++	up(&bus->sdsem);
++
++	return resched;
++}
++
++static inline void brcmf_sdbrcm_adddpctsk(struct brcmf_sdio *bus)
++{
++	struct list_head *new_hd;
++	unsigned long flags;
++
++	if (in_interrupt())
++		new_hd = kzalloc(sizeof(struct list_head), GFP_ATOMIC);
++	else
++		new_hd = kzalloc(sizeof(struct list_head), GFP_KERNEL);
++	if (new_hd == NULL)
++		return;
++
++	spin_lock_irqsave(&bus->dpc_tl_lock, flags);
++	list_add_tail(new_hd, &bus->dpc_tsklst);
++	spin_unlock_irqrestore(&bus->dpc_tl_lock, flags);
++}
++
++static int brcmf_sdbrcm_dpc_thread(void *data)
++{
++	struct brcmf_sdio *bus = (struct brcmf_sdio *) data;
++	struct list_head *cur_hd, *tmp_hd;
++	unsigned long flags;
++
++	allow_signal(SIGTERM);
++	/* Run until signal received */
++	while (1) {
++		if (kthread_should_stop())
++			break;
++
++		if (list_empty(&bus->dpc_tsklst))
++			if (wait_for_completion_interruptible(&bus->dpc_wait))
++				break;
++
++		spin_lock_irqsave(&bus->dpc_tl_lock, flags);
++		list_for_each_safe(cur_hd, tmp_hd, &bus->dpc_tsklst) {
++			spin_unlock_irqrestore(&bus->dpc_tl_lock, flags);
++
++			if (bus->sdiodev->bus_if->state == BRCMF_BUS_DOWN) {
++				/* after stopping the bus, exit thread */
++				brcmf_sdbrcm_bus_stop(bus->sdiodev->dev);
++				bus->dpc_tsk = NULL;
++				spin_lock_irqsave(&bus->dpc_tl_lock, flags);
++				break;
++			}
++
++			if (brcmf_sdbrcm_dpc(bus))
++				brcmf_sdbrcm_adddpctsk(bus);
++
++			spin_lock_irqsave(&bus->dpc_tl_lock, flags);
++			list_del(cur_hd);
++			kfree(cur_hd);
++		}
++		spin_unlock_irqrestore(&bus->dpc_tl_lock, flags);
++	}
++	return 0;
++}
++
++static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt)
++{
++	int ret = -EBADE;
++	uint datalen, prec;
++	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
++	struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
++	struct brcmf_sdio *bus = sdiodev->bus;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	datalen = pkt->len;
++
++	/* Add space for the header */
++	skb_push(pkt, SDPCM_HDRLEN);
++	/* precondition: IS_ALIGNED((unsigned long)(pkt->data), 2) */
++
++	prec = prio2prec((pkt->priority & PRIOMASK));
++
++	/* Check for existing queue, current flow-control,
++			 pending event, or pending clock */
++	brcmf_dbg(TRACE, "deferring pktq len %d\n", pktq_len(&bus->txq));
++	bus->fcqueued++;
++
++	/* Priority based enq */
++	spin_lock_bh(&bus->txqlock);
++	if (!brcmf_c_prec_enq(bus->sdiodev->dev, &bus->txq, pkt, prec)) {
++		skb_pull(pkt, SDPCM_HDRLEN);
++		brcmf_txcomplete(bus->sdiodev->dev, pkt, false);
++		brcmu_pkt_buf_free_skb(pkt);
++		brcmf_dbg(ERROR, "out of bus->txq !!!\n");
++		ret = -ENOSR;
++	} else {
++		ret = 0;
++	}
++	spin_unlock_bh(&bus->txqlock);
++
++	if (pktq_len(&bus->txq) >= TXHI) {
++		bus->txoff = ON;
++		brcmf_txflowcontrol(bus->sdiodev->dev, 0, ON);
++	}
++
++#ifdef DEBUG
++	if (pktq_plen(&bus->txq, prec) > qcount[prec])
++		qcount[prec] = pktq_plen(&bus->txq, prec);
++#endif
++	/* Schedule DPC if needed to send queued packet(s) */
++	if (!bus->dpc_sched) {
++		bus->dpc_sched = true;
++		if (bus->dpc_tsk) {
++			brcmf_sdbrcm_adddpctsk(bus);
++			complete(&bus->dpc_wait);
++		}
++	}
++
++	return ret;
++}
++
++static int
++brcmf_sdbrcm_membytes(struct brcmf_sdio *bus, bool write, u32 address, u8 *data,
++		 uint size)
++{
++	int bcmerror = 0;
++	u32 sdaddr;
++	uint dsize;
++
++	/* Determine initial transfer parameters */
++	sdaddr = address & SBSDIO_SB_OFT_ADDR_MASK;
++	if ((sdaddr + size) & SBSDIO_SBWINDOW_MASK)
++		dsize = (SBSDIO_SB_OFT_ADDR_LIMIT - sdaddr);
++	else
++		dsize = size;
++
++	/* Set the backplane window to include the start address */
++	bcmerror = brcmf_sdcard_set_sbaddr_window(bus->sdiodev, address);
++	if (bcmerror) {
++		brcmf_dbg(ERROR, "window change failed\n");
++		goto xfer_done;
++	}
++
++	/* Do the transfer(s) */
++	while (size) {
++		brcmf_dbg(INFO, "%s %d bytes at offset 0x%08x in window 0x%08x\n",
++			  write ? "write" : "read", dsize,
++			  sdaddr, address & SBSDIO_SBWINDOW_MASK);
++		bcmerror = brcmf_sdcard_rwdata(bus->sdiodev, write,
++					       sdaddr, data, dsize);
++		if (bcmerror) {
++			brcmf_dbg(ERROR, "membytes transfer failed\n");
++			break;
++		}
++
++		/* Adjust for next transfer (if any) */
++		size -= dsize;
++		if (size) {
++			data += dsize;
++			address += dsize;
++			bcmerror = brcmf_sdcard_set_sbaddr_window(bus->sdiodev,
++								  address);
++			if (bcmerror) {
++				brcmf_dbg(ERROR, "window change failed\n");
++				break;
++			}
++			sdaddr = 0;
++			dsize = min_t(uint, SBSDIO_SB_OFT_ADDR_LIMIT, size);
++		}
++	}
++
++xfer_done:
++	/* Return the window to backplane enumeration space for core access */
++	if (brcmf_sdcard_set_sbaddr_window(bus->sdiodev, bus->sdiodev->sbwad))
++		brcmf_dbg(ERROR, "FAILED to set window back to 0x%x\n",
++			  bus->sdiodev->sbwad);
++
++	return bcmerror;
++}
++
++#ifdef DEBUG
++#define CONSOLE_LINE_MAX	192
++
++static int brcmf_sdbrcm_readconsole(struct brcmf_sdio *bus)
++{
++	struct brcmf_console *c = &bus->console;
++	u8 line[CONSOLE_LINE_MAX], ch;
++	u32 n, idx, addr;
++	int rv;
++
++	/* Don't do anything until FWREADY updates console address */
++	if (bus->console_addr == 0)
++		return 0;
++
++	/* Read console log struct */
++	addr = bus->console_addr + offsetof(struct rte_console, log_le);
++	rv = brcmf_sdbrcm_membytes(bus, false, addr, (u8 *)&c->log_le,
++				   sizeof(c->log_le));
++	if (rv < 0)
++		return rv;
++
++	/* Allocate console buffer (one time only) */
++	if (c->buf == NULL) {
++		c->bufsize = le32_to_cpu(c->log_le.buf_size);
++		c->buf = kmalloc(c->bufsize, GFP_ATOMIC);
++		if (c->buf == NULL)
++			return -ENOMEM;
++	}
++
++	idx = le32_to_cpu(c->log_le.idx);
++
++	/* Protect against corrupt value */
++	if (idx > c->bufsize)
++		return -EBADE;
++
++	/* Skip reading the console buffer if the index pointer
++	 has not moved */
++	if (idx == c->last)
++		return 0;
++
++	/* Read the console buffer */
++	addr = le32_to_cpu(c->log_le.buf);
++	rv = brcmf_sdbrcm_membytes(bus, false, addr, c->buf, c->bufsize);
++	if (rv < 0)
++		return rv;
++
++	while (c->last != idx) {
++		for (n = 0; n < CONSOLE_LINE_MAX - 2; n++) {
++			if (c->last == idx) {
++				/* This would output a partial line.
++				 * Instead, back up
++				 * the buffer pointer and output this
++				 * line next time around.
++				 */
++				if (c->last >= n)
++					c->last -= n;
++				else
++					c->last = c->bufsize - n;
++				goto break2;
++			}
++			ch = c->buf[c->last];
++			c->last = (c->last + 1) % c->bufsize;
++			if (ch == '\n')
++				break;
++			line[n] = ch;
++		}
++
++		if (n > 0) {
++			if (line[n - 1] == '\r')
++				n--;
++			line[n] = 0;
++			pr_debug("CONSOLE: %s\n", line);
++		}
++	}
++break2:
++
++	return 0;
++}
++#endif				/* DEBUG */
++
++static int brcmf_tx_frame(struct brcmf_sdio *bus, u8 *frame, u16 len)
++{
++	int i;
++	int ret;
++
++	bus->ctrl_frame_stat = false;
++	ret = brcmf_sdcard_send_buf(bus->sdiodev, bus->sdiodev->sbwad,
++				    SDIO_FUNC_2, F2SYNC, frame, len);
++
++	if (ret < 0) {
++		/* On failure, abort the command and terminate the frame */
++		brcmf_dbg(INFO, "sdio error %d, abort command and terminate frame\n",
++			  ret);
++		bus->tx_sderrs++;
++
++		brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2);
++
++		brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL,
++				 SFC_WF_TERM, NULL);
++		bus->f1regdata++;
++
++		for (i = 0; i < 3; i++) {
++			u8 hi, lo;
++			hi = brcmf_sdio_regrb(bus->sdiodev,
++					      SBSDIO_FUNC1_WFRAMEBCHI, NULL);
++			lo = brcmf_sdio_regrb(bus->sdiodev,
++					      SBSDIO_FUNC1_WFRAMEBCLO, NULL);
++			bus->f1regdata += 2;
++			if (hi == 0 && lo == 0)
++				break;
++		}
++		return ret;
++	}
++
++	bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP;
++
++	return ret;
++}
++
++static int
++brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
++{
++	u8 *frame;
++	u16 len;
++	u32 swheader;
++	uint retries = 0;
++	u8 doff = 0;
++	int ret = -1;
++	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
++	struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
++	struct brcmf_sdio *bus = sdiodev->bus;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* Back the pointer to make a room for bus header */
++	frame = msg - SDPCM_HDRLEN;
++	len = (msglen += SDPCM_HDRLEN);
++
++	/* Add alignment padding (optional for ctl frames) */
++	doff = ((unsigned long)frame % BRCMF_SDALIGN);
++	if (doff) {
++		frame -= doff;
++		len += doff;
++		msglen += doff;
++		memset(frame, 0, doff + SDPCM_HDRLEN);
++	}
++	/* precondition: doff < BRCMF_SDALIGN */
++	doff += SDPCM_HDRLEN;
++
++	/* Round send length to next SDIO block */
++	if (bus->roundup && bus->blocksize && (len > bus->blocksize)) {
++		u16 pad = bus->blocksize - (len % bus->blocksize);
++		if ((pad <= bus->roundup) && (pad < bus->blocksize))
++			len += pad;
++	} else if (len % BRCMF_SDALIGN) {
++		len += BRCMF_SDALIGN - (len % BRCMF_SDALIGN);
++	}
++
++	/* Satisfy length-alignment requirements */
++	if (len & (ALIGNMENT - 1))
++		len = roundup(len, ALIGNMENT);
++
++	/* precondition: IS_ALIGNED((unsigned long)frame, 2) */
++
++	/* Need to lock here to protect txseq and SDIO tx calls */
++	down(&bus->sdsem);
++
++	bus_wake(bus);
++
++	/* Make sure backplane clock is on */
++	brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
++
++	/* Hardware tag: 2 byte len followed by 2 byte ~len check (all LE) */
++	*(__le16 *) frame = cpu_to_le16((u16) msglen);
++	*(((__le16 *) frame) + 1) = cpu_to_le16(~msglen);
++
++	/* Software tag: channel, sequence number, data offset */
++	swheader =
++	    ((SDPCM_CONTROL_CHANNEL << SDPCM_CHANNEL_SHIFT) &
++	     SDPCM_CHANNEL_MASK)
++	    | bus->tx_seq | ((doff << SDPCM_DOFFSET_SHIFT) &
++			     SDPCM_DOFFSET_MASK);
++	put_unaligned_le32(swheader, frame + SDPCM_FRAMETAG_LEN);
++	put_unaligned_le32(0, frame + SDPCM_FRAMETAG_LEN + sizeof(swheader));
++
++	if (!data_ok(bus)) {
++		brcmf_dbg(INFO, "No bus credit bus->tx_max %d, bus->tx_seq %d\n",
++			  bus->tx_max, bus->tx_seq);
++		bus->ctrl_frame_stat = true;
++		/* Send from dpc */
++		bus->ctrl_frame_buf = frame;
++		bus->ctrl_frame_len = len;
++
++		brcmf_sdbrcm_wait_for_event(bus, &bus->ctrl_frame_stat);
++
++		if (!bus->ctrl_frame_stat) {
++			brcmf_dbg(INFO, "ctrl_frame_stat == false\n");
++			ret = 0;
++		} else {
++			brcmf_dbg(INFO, "ctrl_frame_stat == true\n");
++			ret = -1;
++		}
++	}
++
++	if (ret == -1) {
++		brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_CTL_ON(),
++				   frame, len, "Tx Frame:\n");
++		brcmf_dbg_hex_dump(!(BRCMF_BYTES_ON() && BRCMF_CTL_ON()) &&
++				   BRCMF_HDRS_ON(),
++				   frame, min_t(u16, len, 16), "TxHdr:\n");
++
++		do {
++			ret = brcmf_tx_frame(bus, frame, len);
++		} while (ret < 0 && retries++ < TXRETRIES);
++	}
++
++	if ((bus->idletime == BRCMF_IDLE_IMMEDIATE) && !bus->dpc_sched) {
++		bus->activity = false;
++		brcmf_sdbrcm_clkctl(bus, CLK_NONE, true);
++	}
++
++	up(&bus->sdsem);
++
++	if (ret)
++		bus->tx_ctlerrs++;
++	else
++		bus->tx_ctlpkts++;
++
++	return ret ? -EIO : 0;
++}
++
++static int
++brcmf_sdbrcm_bus_rxctl(struct device *dev, unsigned char *msg, uint msglen)
++{
++	int timeleft;
++	uint rxlen = 0;
++	bool pending;
++	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
++	struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
++	struct brcmf_sdio *bus = sdiodev->bus;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* Wait until control frame is available */
++	timeleft = brcmf_sdbrcm_dcmd_resp_wait(bus, &bus->rxlen, &pending);
++
++	down(&bus->sdsem);
++	rxlen = bus->rxlen;
++	memcpy(msg, bus->rxctl, min(msglen, rxlen));
++	bus->rxlen = 0;
++	up(&bus->sdsem);
++
++	if (rxlen) {
++		brcmf_dbg(CTL, "resumed on rxctl frame, got %d expected %d\n",
++			  rxlen, msglen);
++	} else if (timeleft == 0) {
++		brcmf_dbg(ERROR, "resumed on timeout\n");
++	} else if (pending) {
++		brcmf_dbg(CTL, "cancelled\n");
++		return -ERESTARTSYS;
++	} else {
++		brcmf_dbg(CTL, "resumed for unknown reason?\n");
++	}
++
++	if (rxlen)
++		bus->rx_ctlpkts++;
++	else
++		bus->rx_ctlerrs++;
++
++	return rxlen ? (int)rxlen : -ETIMEDOUT;
++}
++
++static int brcmf_sdbrcm_downloadvars(struct brcmf_sdio *bus, void *arg, int len)
++{
++	int bcmerror = 0;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* Basic sanity checks */
++	if (bus->sdiodev->bus_if->drvr_up) {
++		bcmerror = -EISCONN;
++		goto err;
++	}
++	if (!len) {
++		bcmerror = -EOVERFLOW;
++		goto err;
++	}
++
++	/* Free the old ones and replace with passed variables */
++	kfree(bus->vars);
++
++	bus->vars = kmalloc(len, GFP_ATOMIC);
++	bus->varsz = bus->vars ? len : 0;
++	if (bus->vars == NULL) {
++		bcmerror = -ENOMEM;
++		goto err;
++	}
++
++	/* Copy the passed variables, which should include the
++		 terminating double-null */
++	memcpy(bus->vars, arg, bus->varsz);
++err:
++	return bcmerror;
++}
++
++static int brcmf_sdbrcm_write_vars(struct brcmf_sdio *bus)
++{
++	int bcmerror = 0;
++	u32 varsize;
++	u32 varaddr;
++	u8 *vbuffer;
++	u32 varsizew;
++	__le32 varsizew_le;
++#ifdef DEBUG
++	char *nvram_ularray;
++#endif				/* DEBUG */
++
++	/* Even if there are no vars are to be written, we still
++		 need to set the ramsize. */
++	varsize = bus->varsz ? roundup(bus->varsz, 4) : 0;
++	varaddr = (bus->ramsize - 4) - varsize;
++
++	if (bus->vars) {
++		vbuffer = kzalloc(varsize, GFP_ATOMIC);
++		if (!vbuffer)
++			return -ENOMEM;
++
++		memcpy(vbuffer, bus->vars, bus->varsz);
++
++		/* Write the vars list */
++		bcmerror =
++		    brcmf_sdbrcm_membytes(bus, true, varaddr, vbuffer, varsize);
++#ifdef DEBUG
++		/* Verify NVRAM bytes */
++		brcmf_dbg(INFO, "Compare NVRAM dl & ul; varsize=%d\n", varsize);
++		nvram_ularray = kmalloc(varsize, GFP_ATOMIC);
++		if (!nvram_ularray) {
++			kfree(vbuffer);
++			return -ENOMEM;
++		}
++
++		/* Upload image to verify downloaded contents. */
++		memset(nvram_ularray, 0xaa, varsize);
++
++		/* Read the vars list to temp buffer for comparison */
++		bcmerror =
++		    brcmf_sdbrcm_membytes(bus, false, varaddr, nvram_ularray,
++				     varsize);
++		if (bcmerror) {
++			brcmf_dbg(ERROR, "error %d on reading %d nvram bytes at 0x%08x\n",
++				  bcmerror, varsize, varaddr);
++		}
++		/* Compare the org NVRAM with the one read from RAM */
++		if (memcmp(vbuffer, nvram_ularray, varsize))
++			brcmf_dbg(ERROR, "Downloaded NVRAM image is corrupted\n");
++		else
++			brcmf_dbg(ERROR, "Download/Upload/Compare of NVRAM ok\n");
++
++		kfree(nvram_ularray);
++#endif				/* DEBUG */
++
++		kfree(vbuffer);
++	}
++
++	/* adjust to the user specified RAM */
++	brcmf_dbg(INFO, "Physical memory size: %d\n", bus->ramsize);
++	brcmf_dbg(INFO, "Vars are at %d, orig varsize is %d\n",
++		  varaddr, varsize);
++	varsize = ((bus->ramsize - 4) - varaddr);
++
++	/*
++	 * Determine the length token:
++	 * Varsize, converted to words, in lower 16-bits, checksum
++	 * in upper 16-bits.
++	 */
++	if (bcmerror) {
++		varsizew = 0;
++		varsizew_le = cpu_to_le32(0);
++	} else {
++		varsizew = varsize / 4;
++		varsizew = (~varsizew << 16) | (varsizew & 0x0000FFFF);
++		varsizew_le = cpu_to_le32(varsizew);
++	}
++
++	brcmf_dbg(INFO, "New varsize is %d, length token=0x%08x\n",
++		  varsize, varsizew);
++
++	/* Write the length token to the last word */
++	bcmerror = brcmf_sdbrcm_membytes(bus, true, (bus->ramsize - 4),
++					 (u8 *)&varsizew_le, 4);
++
++	return bcmerror;
++}
++
++static int brcmf_sdbrcm_download_state(struct brcmf_sdio *bus, bool enter)
++{
++	int bcmerror = 0;
++	struct chip_info *ci = bus->ci;
++
++	/* To enter download state, disable ARM and reset SOCRAM.
++	 * To exit download state, simply reset ARM (default is RAM boot).
++	 */
++	if (enter) {
++		bus->alp_only = true;
++
++		ci->coredisable(bus->sdiodev, ci, BCMA_CORE_ARM_CM3);
++
++		ci->resetcore(bus->sdiodev, ci, BCMA_CORE_INTERNAL_MEM);
++
++		/* Clear the top bit of memory */
++		if (bus->ramsize) {
++			u32 zeros = 0;
++			brcmf_sdbrcm_membytes(bus, true, bus->ramsize - 4,
++					 (u8 *)&zeros, 4);
++		}
++	} else {
++		if (!ci->iscoreup(bus->sdiodev, ci, BCMA_CORE_INTERNAL_MEM)) {
++			brcmf_dbg(ERROR, "SOCRAM core is down after reset?\n");
++			bcmerror = -EBADE;
++			goto fail;
++		}
++
++		bcmerror = brcmf_sdbrcm_write_vars(bus);
++		if (bcmerror) {
++			brcmf_dbg(ERROR, "no vars written to RAM\n");
++			bcmerror = 0;
++		}
++
++		w_sdreg32(bus, 0xFFFFFFFF,
++			  offsetof(struct sdpcmd_regs, intstatus));
++
++		ci->resetcore(bus->sdiodev, ci, BCMA_CORE_ARM_CM3);
++
++		/* Allow HT Clock now that the ARM is running. */
++		bus->alp_only = false;
++
++		bus->sdiodev->bus_if->state = BRCMF_BUS_LOAD;
++	}
++fail:
++	return bcmerror;
++}
++
++static int brcmf_sdbrcm_get_image(char *buf, int len, struct brcmf_sdio *bus)
++{
++	if (bus->firmware->size < bus->fw_ptr + len)
++		len = bus->firmware->size - bus->fw_ptr;
++
++	memcpy(buf, &bus->firmware->data[bus->fw_ptr], len);
++	bus->fw_ptr += len;
++	return len;
++}
++
++static int brcmf_sdbrcm_download_code_file(struct brcmf_sdio *bus)
++{
++	int offset = 0;
++	uint len;
++	u8 *memblock = NULL, *memptr;
++	int ret;
++
++	brcmf_dbg(INFO, "Enter\n");
++
++	ret = request_firmware(&bus->firmware, BRCMF_SDIO_FW_NAME,
++			       &bus->sdiodev->func[2]->dev);
++	if (ret) {
++		brcmf_dbg(ERROR, "Fail to request firmware %d\n", ret);
++		return ret;
++	}
++	bus->fw_ptr = 0;
++
++	memptr = memblock = kmalloc(MEMBLOCK + BRCMF_SDALIGN, GFP_ATOMIC);
++	if (memblock == NULL) {
++		ret = -ENOMEM;
++		goto err;
++	}
++	if ((u32)(unsigned long)memblock % BRCMF_SDALIGN)
++		memptr += (BRCMF_SDALIGN -
++			   ((u32)(unsigned long)memblock % BRCMF_SDALIGN));
++
++	/* Download image */
++	while ((len =
++		brcmf_sdbrcm_get_image((char *)memptr, MEMBLOCK, bus))) {
++		ret = brcmf_sdbrcm_membytes(bus, true, offset, memptr, len);
++		if (ret) {
++			brcmf_dbg(ERROR, "error %d on writing %d membytes at 0x%08x\n",
++				  ret, MEMBLOCK, offset);
++			goto err;
++		}
++
++		offset += MEMBLOCK;
++	}
++
++err:
++	kfree(memblock);
++
++	release_firmware(bus->firmware);
++	bus->fw_ptr = 0;
++
++	return ret;
++}
++
++/*
++ * ProcessVars:Takes a buffer of "<var>=<value>\n" lines read from a file
++ * and ending in a NUL.
++ * Removes carriage returns, empty lines, comment lines, and converts
++ * newlines to NULs.
++ * Shortens buffer as needed and pads with NULs.  End of buffer is marked
++ * by two NULs.
++*/
++
++static uint brcmf_process_nvram_vars(char *varbuf, uint len)
++{
++	char *dp;
++	bool findNewline;
++	int column;
++	uint buf_len, n;
++
++	dp = varbuf;
++
++	findNewline = false;
++	column = 0;
++
++	for (n = 0; n < len; n++) {
++		if (varbuf[n] == 0)
++			break;
++		if (varbuf[n] == '\r')
++			continue;
++		if (findNewline && varbuf[n] != '\n')
++			continue;
++		findNewline = false;
++		if (varbuf[n] == '#') {
++			findNewline = true;
++			continue;
++		}
++		if (varbuf[n] == '\n') {
++			if (column == 0)
++				continue;
++			*dp++ = 0;
++			column = 0;
++			continue;
++		}
++		*dp++ = varbuf[n];
++		column++;
++	}
++	buf_len = dp - varbuf;
++
++	while (dp < varbuf + n)
++		*dp++ = 0;
++
++	return buf_len;
++}
++
++static int brcmf_sdbrcm_download_nvram(struct brcmf_sdio *bus)
++{
++	uint len;
++	char *memblock = NULL;
++	char *bufp;
++	int ret;
++
++	ret = request_firmware(&bus->firmware, BRCMF_SDIO_NV_NAME,
++			       &bus->sdiodev->func[2]->dev);
++	if (ret) {
++		brcmf_dbg(ERROR, "Fail to request nvram %d\n", ret);
++		return ret;
++	}
++	bus->fw_ptr = 0;
++
++	memblock = kmalloc(MEMBLOCK, GFP_ATOMIC);
++	if (memblock == NULL) {
++		ret = -ENOMEM;
++		goto err;
++	}
++
++	len = brcmf_sdbrcm_get_image(memblock, MEMBLOCK, bus);
++
++	if (len > 0 && len < MEMBLOCK) {
++		bufp = (char *)memblock;
++		bufp[len] = 0;
++		len = brcmf_process_nvram_vars(bufp, len);
++		bufp += len;
++		*bufp++ = 0;
++		if (len)
++			ret = brcmf_sdbrcm_downloadvars(bus, memblock, len + 1);
++		if (ret)
++			brcmf_dbg(ERROR, "error downloading vars: %d\n", ret);
++	} else {
++		brcmf_dbg(ERROR, "error reading nvram file: %d\n", len);
++		ret = -EIO;
++	}
++
++err:
++	kfree(memblock);
++
++	release_firmware(bus->firmware);
++	bus->fw_ptr = 0;
++
++	return ret;
++}
++
++static int _brcmf_sdbrcm_download_firmware(struct brcmf_sdio *bus)
++{
++	int bcmerror = -1;
++
++	/* Keep arm in reset */
++	if (brcmf_sdbrcm_download_state(bus, true)) {
++		brcmf_dbg(ERROR, "error placing ARM core in reset\n");
++		goto err;
++	}
++
++	/* External image takes precedence if specified */
++	if (brcmf_sdbrcm_download_code_file(bus)) {
++		brcmf_dbg(ERROR, "dongle image file download failed\n");
++		goto err;
++	}
++
++	/* External nvram takes precedence if specified */
++	if (brcmf_sdbrcm_download_nvram(bus))
++		brcmf_dbg(ERROR, "dongle nvram file download failed\n");
++
++	/* Take arm out of reset */
++	if (brcmf_sdbrcm_download_state(bus, false)) {
++		brcmf_dbg(ERROR, "error getting out of ARM core reset\n");
++		goto err;
++	}
++
++	bcmerror = 0;
++
++err:
++	return bcmerror;
++}
++
++static bool
++brcmf_sdbrcm_download_firmware(struct brcmf_sdio *bus)
++{
++	bool ret;
++
++	/* Download the firmware */
++	brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
++
++	ret = _brcmf_sdbrcm_download_firmware(bus) == 0;
++
++	brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false);
++
++	return ret;
++}
++
++static int brcmf_sdbrcm_bus_init(struct device *dev)
++{
++	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
++	struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
++	struct brcmf_sdio *bus = sdiodev->bus;
++	unsigned long timeout;
++	u8 ready, enable;
++	int err, ret = 0;
++	u8 saveclk;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* try to download image and nvram to the dongle */
++	if (bus_if->state == BRCMF_BUS_DOWN) {
++		if (!(brcmf_sdbrcm_download_firmware(bus)))
++			return -1;
++	}
++
++	if (!bus->sdiodev->bus_if->drvr)
++		return 0;
++
++	/* Start the watchdog timer */
++	bus->tickcnt = 0;
++	brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS);
++
++	down(&bus->sdsem);
++
++	/* Make sure backplane clock is on, needed to generate F2 interrupt */
++	brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
++	if (bus->clkstate != CLK_AVAIL)
++		goto exit;
++
++	/* Force clocks on backplane to be sure F2 interrupt propagates */
++	saveclk = brcmf_sdio_regrb(bus->sdiodev,
++				   SBSDIO_FUNC1_CHIPCLKCSR, &err);
++	if (!err) {
++		brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
++				 (saveclk | SBSDIO_FORCE_HT), &err);
++	}
++	if (err) {
++		brcmf_dbg(ERROR, "Failed to force clock for F2: err %d\n", err);
++		goto exit;
++	}
++
++	/* Enable function 2 (frame transfers) */
++	w_sdreg32(bus, SDPCM_PROT_VERSION << SMB_DATA_VERSION_SHIFT,
++		  offsetof(struct sdpcmd_regs, tosbmailboxdata));
++	enable = (SDIO_FUNC_ENABLE_1 | SDIO_FUNC_ENABLE_2);
++
++	brcmf_sdio_regwb(bus->sdiodev, SDIO_CCCR_IOEx, enable, NULL);
++
++	timeout = jiffies + msecs_to_jiffies(BRCMF_WAIT_F2RDY);
++	ready = 0;
++	while (enable != ready) {
++		ready = brcmf_sdio_regrb(bus->sdiodev,
++					 SDIO_CCCR_IORx, NULL);
++		if (time_after(jiffies, timeout))
++			break;
++		else if (time_after(jiffies, timeout - BRCMF_WAIT_F2RDY + 50))
++			/* prevent busy waiting if it takes too long */
++			msleep_interruptible(20);
++	}
++
++	brcmf_dbg(INFO, "enable 0x%02x, ready 0x%02x\n", enable, ready);
++
++	/* If F2 successfully enabled, set core and enable interrupts */
++	if (ready == enable) {
++		/* Set up the interrupt mask and enable interrupts */
++		bus->hostintmask = HOSTINTMASK;
++		w_sdreg32(bus, bus->hostintmask,
++			  offsetof(struct sdpcmd_regs, hostintmask));
++
++		brcmf_sdio_regwb(bus->sdiodev, SBSDIO_WATERMARK, 8, &err);
++	} else {
++		/* Disable F2 again */
++		enable = SDIO_FUNC_ENABLE_1;
++		brcmf_sdio_regwb(bus->sdiodev, SDIO_CCCR_IOEx, enable, NULL);
++		ret = -ENODEV;
++	}
++
++	/* Restore previous clock setting */
++	brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, saveclk, &err);
++
++	if (ret == 0) {
++		ret = brcmf_sdio_intr_register(bus->sdiodev);
++		if (ret != 0)
++			brcmf_dbg(ERROR, "intr register failed:%d\n", ret);
++	}
++
++	/* If we didn't come up, turn off backplane clock */
++	if (bus_if->state != BRCMF_BUS_DATA)
++		brcmf_sdbrcm_clkctl(bus, CLK_NONE, false);
++
++exit:
++	up(&bus->sdsem);
++
++	return ret;
++}
++
++void brcmf_sdbrcm_isr(void *arg)
++{
++	struct brcmf_sdio *bus = (struct brcmf_sdio *) arg;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	if (!bus) {
++		brcmf_dbg(ERROR, "bus is null pointer, exiting\n");
++		return;
++	}
++
++	if (bus->sdiodev->bus_if->state == BRCMF_BUS_DOWN) {
++		brcmf_dbg(ERROR, "bus is down. we have nothing to do\n");
++		return;
++	}
++	/* Count the interrupt call */
++	bus->intrcount++;
++	bus->ipend = true;
++
++	/* Shouldn't get this interrupt if we're sleeping? */
++	if (bus->sleeping) {
++		brcmf_dbg(ERROR, "INTERRUPT WHILE SLEEPING??\n");
++		return;
++	}
++
++	/* Disable additional interrupts (is this needed now)? */
++	if (!bus->intr)
++		brcmf_dbg(ERROR, "isr w/o interrupt configured!\n");
++
++#ifndef CONFIG_BRCMFMAC_SDIO_OOB
++	while (brcmf_sdbrcm_dpc(bus))
++		;
++#else
++	bus->dpc_sched = true;
++	if (bus->dpc_tsk) {
++		brcmf_sdbrcm_adddpctsk(bus);
++		complete(&bus->dpc_wait);
++	}
++#endif
++}
++
++static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus)
++{
++#ifdef DEBUG
++	struct brcmf_bus *bus_if = dev_get_drvdata(bus->sdiodev->dev);
++#endif	/* DEBUG */
++
++	brcmf_dbg(TIMER, "Enter\n");
++
++	/* Ignore the timer if simulating bus down */
++	if (bus->sleeping)
++		return false;
++
++	down(&bus->sdsem);
++
++	/* Poll period: check device if appropriate. */
++	if (bus->poll && (++bus->polltick >= bus->pollrate)) {
++		u32 intstatus = 0;
++
++		/* Reset poll tick */
++		bus->polltick = 0;
++
++		/* Check device if no interrupts */
++		if (!bus->intr || (bus->intrcount == bus->lastintrs)) {
++
++			if (!bus->dpc_sched) {
++				u8 devpend;
++				devpend = brcmf_sdio_regrb(bus->sdiodev,
++							   SDIO_CCCR_INTx,
++							   NULL);
++				intstatus =
++				    devpend & (INTR_STATUS_FUNC1 |
++					       INTR_STATUS_FUNC2);
++			}
++
++			/* If there is something, make like the ISR and
++				 schedule the DPC */
++			if (intstatus) {
++				bus->pollcnt++;
++				bus->ipend = true;
++
++				bus->dpc_sched = true;
++				if (bus->dpc_tsk) {
++					brcmf_sdbrcm_adddpctsk(bus);
++					complete(&bus->dpc_wait);
++				}
++			}
++		}
++
++		/* Update interrupt tracking */
++		bus->lastintrs = bus->intrcount;
++	}
++#ifdef DEBUG
++	/* Poll for console output periodically */
++	if (bus_if->state == BRCMF_BUS_DATA &&
++	    bus->console_interval != 0) {
++		bus->console.count += BRCMF_WD_POLL_MS;
++		if (bus->console.count >= bus->console_interval) {
++			bus->console.count -= bus->console_interval;
++			/* Make sure backplane clock is on */
++			brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
++			if (brcmf_sdbrcm_readconsole(bus) < 0)
++				/* stop on error */
++				bus->console_interval = 0;
++		}
++	}
++#endif				/* DEBUG */
++
++	/* On idle timeout clear activity flag and/or turn off clock */
++	if ((bus->idletime > 0) && (bus->clkstate == CLK_AVAIL)) {
++		if (++bus->idlecount >= bus->idletime) {
++			bus->idlecount = 0;
++			if (bus->activity) {
++				bus->activity = false;
++				brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS);
++			} else {
++				brcmf_sdbrcm_clkctl(bus, CLK_NONE, false);
++			}
++		}
++	}
++
++	up(&bus->sdsem);
++
++	return bus->ipend;
++}
++
++static bool brcmf_sdbrcm_chipmatch(u16 chipid)
++{
++	if (chipid == BCM4329_CHIP_ID)
++		return true;
++	if (chipid == BCM4330_CHIP_ID)
++		return true;
++	return false;
++}
++
++static void brcmf_sdbrcm_release_malloc(struct brcmf_sdio *bus)
++{
++	brcmf_dbg(TRACE, "Enter\n");
++
++	kfree(bus->rxbuf);
++	bus->rxctl = bus->rxbuf = NULL;
++	bus->rxlen = 0;
++
++	kfree(bus->databuf);
++	bus->databuf = NULL;
++}
++
++static bool brcmf_sdbrcm_probe_malloc(struct brcmf_sdio *bus)
++{
++	brcmf_dbg(TRACE, "Enter\n");
++
++	if (bus->sdiodev->bus_if->maxctl) {
++		bus->rxblen =
++		    roundup((bus->sdiodev->bus_if->maxctl + SDPCM_HDRLEN),
++			    ALIGNMENT) + BRCMF_SDALIGN;
++		bus->rxbuf = kmalloc(bus->rxblen, GFP_ATOMIC);
++		if (!(bus->rxbuf))
++			goto fail;
++	}
++
++	/* Allocate buffer to receive glomed packet */
++	bus->databuf = kmalloc(MAX_DATA_BUF, GFP_ATOMIC);
++	if (!(bus->databuf)) {
++		/* release rxbuf which was already located as above */
++		if (!bus->rxblen)
++			kfree(bus->rxbuf);
++		goto fail;
++	}
++
++	/* Align the buffer */
++	if ((unsigned long)bus->databuf % BRCMF_SDALIGN)
++		bus->dataptr = bus->databuf + (BRCMF_SDALIGN -
++			       ((unsigned long)bus->databuf % BRCMF_SDALIGN));
++	else
++		bus->dataptr = bus->databuf;
++
++	return true;
++
++fail:
++	return false;
++}
++
++static bool
++brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus, u32 regsva)
++{
++	u8 clkctl = 0;
++	int err = 0;
++	int reg_addr;
++	u32 reg_val;
++	u8 idx;
++
++	bus->alp_only = true;
++
++	pr_debug("F1 signature read @0x18000000=0x%4x\n",
++		 brcmf_sdio_regrl(bus->sdiodev, SI_ENUM_BASE, NULL));
++
++	/*
++	 * Force PLL off until brcmf_sdio_chip_attach()
++	 * programs PLL control regs
++	 */
++
++	brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
++			 BRCMF_INIT_CLKCTL1, &err);
++	if (!err)
++		clkctl = brcmf_sdio_regrb(bus->sdiodev,
++					  SBSDIO_FUNC1_CHIPCLKCSR, &err);
++
++	if (err || ((clkctl & ~SBSDIO_AVBITS) != BRCMF_INIT_CLKCTL1)) {
++		brcmf_dbg(ERROR, "ChipClkCSR access: err %d wrote 0x%02x read 0x%02x\n",
++			  err, BRCMF_INIT_CLKCTL1, clkctl);
++		goto fail;
++	}
++
++	if (brcmf_sdio_chip_attach(bus->sdiodev, &bus->ci, regsva)) {
++		brcmf_dbg(ERROR, "brcmf_sdio_chip_attach failed!\n");
++		goto fail;
++	}
++
++	if (!brcmf_sdbrcm_chipmatch((u16) bus->ci->chip)) {
++		brcmf_dbg(ERROR, "unsupported chip: 0x%04x\n", bus->ci->chip);
++		goto fail;
++	}
++
++	brcmf_sdio_chip_drivestrengthinit(bus->sdiodev, bus->ci,
++					  SDIO_DRIVE_STRENGTH);
++
++	/* Get info on the SOCRAM cores... */
++	bus->ramsize = bus->ci->ramsize;
++	if (!(bus->ramsize)) {
++		brcmf_dbg(ERROR, "failed to find SOCRAM memory!\n");
++		goto fail;
++	}
++
++	/* Set core control so an SDIO reset does a backplane reset */
++	idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV);
++	reg_addr = bus->ci->c_inf[idx].base +
++		   offsetof(struct sdpcmd_regs, corecontrol);
++	reg_val = brcmf_sdio_regrl(bus->sdiodev, reg_addr, NULL);
++	brcmf_sdio_regwl(bus->sdiodev, reg_addr, reg_val | CC_BPRESEN, NULL);
++
++	brcmu_pktq_init(&bus->txq, (PRIOMASK + 1), TXQLEN);
++
++	/* Locate an appropriately-aligned portion of hdrbuf */
++	bus->rxhdr = (u8 *) roundup((unsigned long)&bus->hdrbuf[0],
++				    BRCMF_SDALIGN);
++
++	/* Set the poll and/or interrupt flags */
++	bus->intr = true;
++	bus->poll = false;
++	if (bus->poll)
++		bus->pollrate = 1;
++
++	return true;
++
++fail:
++	return false;
++}
++
++static bool brcmf_sdbrcm_probe_init(struct brcmf_sdio *bus)
++{
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* Disable F2 to clear any intermediate frame state on the dongle */
++	brcmf_sdio_regwb(bus->sdiodev, SDIO_CCCR_IOEx,
++			 SDIO_FUNC_ENABLE_1, NULL);
++
++	bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
++	bus->sleeping = false;
++	bus->rxflow = false;
++
++	/* Done with backplane-dependent accesses, can drop clock... */
++	brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL);
++
++	/* ...and initialize clock/power states */
++	bus->clkstate = CLK_SDONLY;
++	bus->idletime = BRCMF_IDLE_INTERVAL;
++	bus->idleclock = BRCMF_IDLE_ACTIVE;
++
++	/* Query the F2 block size, set roundup accordingly */
++	bus->blocksize = bus->sdiodev->func[2]->cur_blksize;
++	bus->roundup = min(max_roundup, bus->blocksize);
++
++	/* bus module does not support packet chaining */
++	bus->use_rxchain = false;
++	bus->sd_rxchain = false;
++
++	return true;
++}
++
++static int
++brcmf_sdbrcm_watchdog_thread(void *data)
++{
++	struct brcmf_sdio *bus = (struct brcmf_sdio *)data;
++
++	allow_signal(SIGTERM);
++	/* Run until signal received */
++	while (1) {
++		if (kthread_should_stop())
++			break;
++		if (!wait_for_completion_interruptible(&bus->watchdog_wait)) {
++			brcmf_sdbrcm_bus_watchdog(bus);
++			/* Count the tick for reference */
++			bus->tickcnt++;
++		} else
++			break;
++	}
++	return 0;
++}
++
++static void
++brcmf_sdbrcm_watchdog(unsigned long data)
++{
++	struct brcmf_sdio *bus = (struct brcmf_sdio *)data;
++
++	if (bus->watchdog_tsk) {
++		complete(&bus->watchdog_wait);
++		/* Reschedule the watchdog */
++		if (bus->wd_timer_valid)
++			mod_timer(&bus->timer,
++				  jiffies + BRCMF_WD_POLL_MS * HZ / 1000);
++	}
++}
++
++static void brcmf_sdbrcm_release_dongle(struct brcmf_sdio *bus)
++{
++	brcmf_dbg(TRACE, "Enter\n");
++
++	if (bus->ci) {
++		brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
++		brcmf_sdbrcm_clkctl(bus, CLK_NONE, false);
++		brcmf_sdio_chip_detach(&bus->ci);
++		if (bus->vars && bus->varsz)
++			kfree(bus->vars);
++		bus->vars = NULL;
++	}
++
++	brcmf_dbg(TRACE, "Disconnected\n");
++}
++
++/* Detach and free everything */
++static void brcmf_sdbrcm_release(struct brcmf_sdio *bus)
++{
++	brcmf_dbg(TRACE, "Enter\n");
++
++	if (bus) {
++		/* De-register interrupt handler */
++		brcmf_sdio_intr_unregister(bus->sdiodev);
++
++		if (bus->sdiodev->bus_if->drvr) {
++			brcmf_detach(bus->sdiodev->dev);
++			brcmf_sdbrcm_release_dongle(bus);
++		}
++
++		brcmf_sdbrcm_release_malloc(bus);
++
++		kfree(bus);
++	}
++
++	brcmf_dbg(TRACE, "Disconnected\n");
++}
++
++void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev)
++{
++	int ret;
++	struct brcmf_sdio *bus;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* We make an assumption about address window mappings:
++	 * regsva == SI_ENUM_BASE*/
++
++	/* Allocate private bus interface state */
++	bus = kzalloc(sizeof(struct brcmf_sdio), GFP_ATOMIC);
++	if (!bus)
++		goto fail;
++
++	bus->sdiodev = sdiodev;
++	sdiodev->bus = bus;
++	skb_queue_head_init(&bus->glom);
++	bus->txbound = BRCMF_TXBOUND;
++	bus->rxbound = BRCMF_RXBOUND;
++	bus->txminmax = BRCMF_TXMINMAX;
++	bus->tx_seq = SDPCM_SEQUENCE_WRAP - 1;
++	bus->usebufpool = false;	/* Use bufpool if allocated,
++					 else use locally malloced rxbuf */
++
++	/* attempt to attach to the dongle */
++	if (!(brcmf_sdbrcm_probe_attach(bus, regsva))) {
++		brcmf_dbg(ERROR, "brcmf_sdbrcm_probe_attach failed\n");
++		goto fail;
++	}
++
++	spin_lock_init(&bus->txqlock);
++	init_waitqueue_head(&bus->ctrl_wait);
++	init_waitqueue_head(&bus->dcmd_resp_wait);
++
++	/* Set up the watchdog timer */
++	init_timer(&bus->timer);
++	bus->timer.data = (unsigned long)bus;
++	bus->timer.function = brcmf_sdbrcm_watchdog;
++
++	/* Initialize thread based operation and lock */
++	sema_init(&bus->sdsem, 1);
++
++	/* Initialize watchdog thread */
++	init_completion(&bus->watchdog_wait);
++	bus->watchdog_tsk = kthread_run(brcmf_sdbrcm_watchdog_thread,
++					bus, "brcmf_watchdog");
++	if (IS_ERR(bus->watchdog_tsk)) {
++		pr_warn("brcmf_watchdog thread failed to start\n");
++		bus->watchdog_tsk = NULL;
++	}
++	/* Initialize DPC thread */
++	init_completion(&bus->dpc_wait);
++	INIT_LIST_HEAD(&bus->dpc_tsklst);
++	spin_lock_init(&bus->dpc_tl_lock);
++	bus->dpc_tsk = kthread_run(brcmf_sdbrcm_dpc_thread,
++				   bus, "brcmf_dpc");
++	if (IS_ERR(bus->dpc_tsk)) {
++		pr_warn("brcmf_dpc thread failed to start\n");
++		bus->dpc_tsk = NULL;
++	}
++
++	/* Assign bus interface call back */
++	bus->sdiodev->bus_if->brcmf_bus_stop = brcmf_sdbrcm_bus_stop;
++	bus->sdiodev->bus_if->brcmf_bus_init = brcmf_sdbrcm_bus_init;
++	bus->sdiodev->bus_if->brcmf_bus_txdata = brcmf_sdbrcm_bus_txdata;
++	bus->sdiodev->bus_if->brcmf_bus_txctl = brcmf_sdbrcm_bus_txctl;
++	bus->sdiodev->bus_if->brcmf_bus_rxctl = brcmf_sdbrcm_bus_rxctl;
++	/* Attach to the brcmf/OS/network interface */
++	ret = brcmf_attach(SDPCM_RESERVE, bus->sdiodev->dev);
++	if (ret != 0) {
++		brcmf_dbg(ERROR, "brcmf_attach failed\n");
++		goto fail;
++	}
++
++	/* Allocate buffers */
++	if (!(brcmf_sdbrcm_probe_malloc(bus))) {
++		brcmf_dbg(ERROR, "brcmf_sdbrcm_probe_malloc failed\n");
++		goto fail;
++	}
++
++	if (!(brcmf_sdbrcm_probe_init(bus))) {
++		brcmf_dbg(ERROR, "brcmf_sdbrcm_probe_init failed\n");
++		goto fail;
++	}
++
++	brcmf_dbg(INFO, "completed!!\n");
++
++	/* if firmware path present try to download and bring up bus */
++	ret = brcmf_bus_start(bus->sdiodev->dev);
++	if (ret != 0) {
++		if (ret == -ENOLINK) {
++			brcmf_dbg(ERROR, "dongle is not responding\n");
++			goto fail;
++		}
++	}
++
++	return bus;
++
++fail:
++	brcmf_sdbrcm_release(bus);
++	return NULL;
++}
++
++void brcmf_sdbrcm_disconnect(void *ptr)
++{
++	struct brcmf_sdio *bus = (struct brcmf_sdio *)ptr;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	if (bus)
++		brcmf_sdbrcm_release(bus);
++
++	brcmf_dbg(TRACE, "Disconnected\n");
++}
++
++void
++brcmf_sdbrcm_wd_timer(struct brcmf_sdio *bus, uint wdtick)
++{
++	/* Totally stop the timer */
++	if (!wdtick && bus->wd_timer_valid) {
++		del_timer_sync(&bus->timer);
++		bus->wd_timer_valid = false;
++		bus->save_ms = wdtick;
++		return;
++	}
++
++	/* don't start the wd until fw is loaded */
++	if (bus->sdiodev->bus_if->state == BRCMF_BUS_DOWN)
++		return;
++
++	if (wdtick) {
++		if (bus->save_ms != BRCMF_WD_POLL_MS) {
++			if (bus->wd_timer_valid)
++				/* Stop timer and restart at new value */
++				del_timer_sync(&bus->timer);
++
++			/* Create timer again when watchdog period is
++			   dynamically changed or in the first instance
++			 */
++			bus->timer.expires =
++				jiffies + BRCMF_WD_POLL_MS * HZ / 1000;
++			add_timer(&bus->timer);
++
++		} else {
++			/* Re arm the timer, at last watchdog period */
++			mod_timer(&bus->timer,
++				jiffies + BRCMF_WD_POLL_MS * HZ / 1000);
++		}
++
++		bus->wd_timer_valid = true;
++		bus->save_ms = wdtick;
++	}
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c
+new file mode 100644
+index 0000000..13f630c
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c
+@@ -0,0 +1,622 @@
++/*
++ * Copyright (c) 2011 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++/* ***** SDIO interface chip backplane handle functions ***** */
++
++#undef pr_fmt
++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
++
++#include <linux/types.h>
++#include <linux/netdevice.h>
++#include <linux/printk.h>
++#include <linux/mmc/card.h>
++#include <linux/ssb/ssb_regs.h>
++#include <linux/bcma/bcma.h>
++
++#include <chipcommon.h>
++#include <brcm_hw_ids.h>
++#include <brcmu_wifi.h>
++#include <brcmu_utils.h>
++#include <soc.h>
++#include "dhd_dbg.h"
++#include "sdio_host.h"
++#include "sdio_chip.h"
++
++/* chip core base & ramsize */
++/* bcm4329 */
++/* SDIO device core, ID 0x829 */
++#define BCM4329_CORE_BUS_BASE		0x18011000
++/* internal memory core, ID 0x80e */
++#define BCM4329_CORE_SOCRAM_BASE	0x18003000
++/* ARM Cortex M3 core, ID 0x82a */
++#define BCM4329_CORE_ARM_BASE		0x18002000
++#define BCM4329_RAMSIZE			0x48000
++
++#define	SBCOREREV(sbidh) \
++	((((sbidh) & SSB_IDHIGH_RCHI) >> SSB_IDHIGH_RCHI_SHIFT) | \
++	  ((sbidh) & SSB_IDHIGH_RCLO))
++
++/* SOC Interconnect types (aka chip types) */
++#define SOCI_SB		0
++#define SOCI_AI		1
++
++/* EROM CompIdentB */
++#define CIB_REV_MASK		0xff000000
++#define CIB_REV_SHIFT		24
++
++#define SDIOD_DRVSTR_KEY(chip, pmu)     (((chip) << 16) | (pmu))
++/* SDIO Pad drive strength to select value mappings */
++struct sdiod_drive_str {
++	u8 strength;	/* Pad Drive Strength in mA */
++	u8 sel;		/* Chip-specific select value */
++};
++/* SDIO Drive Strength to sel value table for PMU Rev 11 (1.8V) */
++static const struct sdiod_drive_str sdiod_drvstr_tab1_1v8[] = {
++	{32, 0x6},
++	{26, 0x7},
++	{22, 0x4},
++	{16, 0x5},
++	{12, 0x2},
++	{8, 0x3},
++	{4, 0x0},
++	{0, 0x1}
++};
++
++u8
++brcmf_sdio_chip_getinfidx(struct chip_info *ci, u16 coreid)
++{
++	u8 idx;
++
++	for (idx = 0; idx < BRCMF_MAX_CORENUM; idx++)
++		if (coreid == ci->c_inf[idx].id)
++			return idx;
++
++	return BRCMF_MAX_CORENUM;
++}
++
++static u32
++brcmf_sdio_sb_corerev(struct brcmf_sdio_dev *sdiodev,
++		      struct chip_info *ci, u16 coreid)
++{
++	u32 regdata;
++	u8 idx;
++
++	idx = brcmf_sdio_chip_getinfidx(ci, coreid);
++
++	regdata = brcmf_sdio_regrl(sdiodev,
++				   CORE_SB(ci->c_inf[idx].base, sbidhigh),
++				   NULL);
++	return SBCOREREV(regdata);
++}
++
++static u32
++brcmf_sdio_ai_corerev(struct brcmf_sdio_dev *sdiodev,
++		      struct chip_info *ci, u16 coreid)
++{
++	u8 idx;
++
++	idx = brcmf_sdio_chip_getinfidx(ci, coreid);
++
++	return (ci->c_inf[idx].cib & CIB_REV_MASK) >> CIB_REV_SHIFT;
++}
++
++static bool
++brcmf_sdio_sb_iscoreup(struct brcmf_sdio_dev *sdiodev,
++		       struct chip_info *ci, u16 coreid)
++{
++	u32 regdata;
++	u8 idx;
++
++	idx = brcmf_sdio_chip_getinfidx(ci, coreid);
++
++	regdata = brcmf_sdio_regrl(sdiodev,
++				   CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
++				   NULL);
++	regdata &= (SSB_TMSLOW_RESET | SSB_TMSLOW_REJECT |
++		    SSB_IMSTATE_REJECT | SSB_TMSLOW_CLOCK);
++	return (SSB_TMSLOW_CLOCK == regdata);
++}
++
++static bool
++brcmf_sdio_ai_iscoreup(struct brcmf_sdio_dev *sdiodev,
++		       struct chip_info *ci, u16 coreid)
++{
++	u32 regdata;
++	u8 idx;
++	bool ret;
++
++	idx = brcmf_sdio_chip_getinfidx(ci, coreid);
++
++	regdata = brcmf_sdio_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
++				   NULL);
++	ret = (regdata & (BCMA_IOCTL_FGC | BCMA_IOCTL_CLK)) == BCMA_IOCTL_CLK;
++
++	regdata = brcmf_sdio_regrl(sdiodev,
++				   ci->c_inf[idx].wrapbase+BCMA_RESET_CTL,
++				   NULL);
++	ret = ret && ((regdata & BCMA_RESET_CTL_RESET) == 0);
++
++	return ret;
++}
++
++static void
++brcmf_sdio_sb_coredisable(struct brcmf_sdio_dev *sdiodev,
++			  struct chip_info *ci, u16 coreid)
++{
++	u32 regdata, base;
++	u8 idx;
++
++	idx = brcmf_sdio_chip_getinfidx(ci, coreid);
++	base = ci->c_inf[idx].base;
++
++	regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbtmstatelow), NULL);
++	if (regdata & SSB_TMSLOW_RESET)
++		return;
++
++	regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbtmstatelow), NULL);
++	if ((regdata & SSB_TMSLOW_CLOCK) != 0) {
++		/*
++		 * set target reject and spin until busy is clear
++		 * (preserve core-specific bits)
++		 */
++		regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbtmstatelow),
++					   NULL);
++		brcmf_sdio_regwl(sdiodev, CORE_SB(base, sbtmstatelow),
++				 regdata | SSB_TMSLOW_REJECT, NULL);
++
++		regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbtmstatelow),
++					   NULL);
++		udelay(1);
++		SPINWAIT((brcmf_sdio_regrl(sdiodev,
++					   CORE_SB(base, sbtmstatehigh),
++					   NULL) &
++			SSB_TMSHIGH_BUSY), 100000);
++
++		regdata = brcmf_sdio_regrl(sdiodev,
++					   CORE_SB(base, sbtmstatehigh),
++					   NULL);
++		if (regdata & SSB_TMSHIGH_BUSY)
++			brcmf_dbg(ERROR, "core state still busy\n");
++
++		regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbidlow),
++					   NULL);
++		if (regdata & SSB_IDLOW_INITIATOR) {
++			regdata = brcmf_sdio_regrl(sdiodev,
++						   CORE_SB(base, sbimstate),
++						   NULL);
++			regdata |= SSB_IMSTATE_REJECT;
++			brcmf_sdio_regwl(sdiodev, CORE_SB(base, sbimstate),
++					 regdata, NULL);
++			regdata = brcmf_sdio_regrl(sdiodev,
++						   CORE_SB(base, sbimstate),
++						   NULL);
++			udelay(1);
++			SPINWAIT((brcmf_sdio_regrl(sdiodev,
++						   CORE_SB(base, sbimstate),
++						   NULL) &
++				SSB_IMSTATE_BUSY), 100000);
++		}
++
++		/* set reset and reject while enabling the clocks */
++		regdata = SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK |
++			  SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET;
++		brcmf_sdio_regwl(sdiodev, CORE_SB(base, sbtmstatelow),
++				 regdata, NULL);
++		regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbtmstatelow),
++					   NULL);
++		udelay(10);
++
++		/* clear the initiator reject bit */
++		regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbidlow),
++					   NULL);
++		if (regdata & SSB_IDLOW_INITIATOR) {
++			regdata = brcmf_sdio_regrl(sdiodev,
++						   CORE_SB(base, sbimstate),
++						   NULL);
++			regdata &= ~SSB_IMSTATE_REJECT;
++			brcmf_sdio_regwl(sdiodev, CORE_SB(base, sbimstate),
++					 regdata, NULL);
++		}
++	}
++
++	/* leave reset and reject asserted */
++	brcmf_sdio_regwl(sdiodev, CORE_SB(base, sbtmstatelow),
++			 (SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET), NULL);
++	udelay(1);
++}
++
++static void
++brcmf_sdio_ai_coredisable(struct brcmf_sdio_dev *sdiodev,
++			  struct chip_info *ci, u16 coreid)
++{
++	u8 idx;
++	u32 regdata;
++
++	idx = brcmf_sdio_chip_getinfidx(ci, coreid);
++
++	/* if core is already in reset, just return */
++	regdata = brcmf_sdio_regrl(sdiodev,
++				   ci->c_inf[idx].wrapbase+BCMA_RESET_CTL,
++				   NULL);
++	if ((regdata & BCMA_RESET_CTL_RESET) != 0)
++		return;
++
++	brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, 0, NULL);
++	regdata = brcmf_sdio_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
++				   NULL);
++	udelay(10);
++
++	brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_RESET_CTL,
++			 BCMA_RESET_CTL_RESET, NULL);
++	udelay(1);
++}
++
++static void
++brcmf_sdio_sb_resetcore(struct brcmf_sdio_dev *sdiodev,
++			struct chip_info *ci, u16 coreid)
++{
++	u32 regdata;
++	u8 idx;
++
++	idx = brcmf_sdio_chip_getinfidx(ci, coreid);
++
++	/*
++	 * Must do the disable sequence first to work for
++	 * arbitrary current core state.
++	 */
++	brcmf_sdio_sb_coredisable(sdiodev, ci, coreid);
++
++	/*
++	 * Now do the initialization sequence.
++	 * set reset while enabling the clock and
++	 * forcing them on throughout the core
++	 */
++	brcmf_sdio_regwl(sdiodev,
++			 CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
++			 SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK | SSB_TMSLOW_RESET,
++			 NULL);
++	regdata = brcmf_sdio_regrl(sdiodev,
++				   CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
++				   NULL);
++	udelay(1);
++
++	/* clear any serror */
++	regdata = brcmf_sdio_regrl(sdiodev,
++				   CORE_SB(ci->c_inf[idx].base, sbtmstatehigh),
++				   NULL);
++	if (regdata & SSB_TMSHIGH_SERR)
++		brcmf_sdio_regwl(sdiodev,
++				 CORE_SB(ci->c_inf[idx].base, sbtmstatehigh),
++				 0, NULL);
++
++	regdata = brcmf_sdio_regrl(sdiodev,
++				   CORE_SB(ci->c_inf[idx].base, sbimstate),
++				   NULL);
++	if (regdata & (SSB_IMSTATE_IBE | SSB_IMSTATE_TO))
++		brcmf_sdio_regwl(sdiodev,
++				 CORE_SB(ci->c_inf[idx].base, sbimstate),
++				 regdata & ~(SSB_IMSTATE_IBE | SSB_IMSTATE_TO),
++				 NULL);
++
++	/* clear reset and allow it to propagate throughout the core */
++	brcmf_sdio_regwl(sdiodev, CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
++			 SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK, NULL);
++	regdata = brcmf_sdio_regrl(sdiodev,
++				   CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
++				   NULL);
++	udelay(1);
++
++	/* leave clock enabled */
++	brcmf_sdio_regwl(sdiodev, CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
++			 SSB_TMSLOW_CLOCK, NULL);
++	regdata = brcmf_sdio_regrl(sdiodev,
++				   CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
++				   NULL);
++	udelay(1);
++}
++
++static void
++brcmf_sdio_ai_resetcore(struct brcmf_sdio_dev *sdiodev,
++			struct chip_info *ci, u16 coreid)
++{
++	u8 idx;
++	u32 regdata;
++
++	idx = brcmf_sdio_chip_getinfidx(ci, coreid);
++
++	/* must disable first to work for arbitrary current core state */
++	brcmf_sdio_ai_coredisable(sdiodev, ci, coreid);
++
++	/* now do initialization sequence */
++	brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
++			 BCMA_IOCTL_FGC | BCMA_IOCTL_CLK, NULL);
++	regdata = brcmf_sdio_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
++				   NULL);
++	brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_RESET_CTL,
++			 0, NULL);
++	udelay(1);
++
++	brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
++			 BCMA_IOCTL_CLK, NULL);
++	regdata = brcmf_sdio_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
++				   NULL);
++	udelay(1);
++}
++
++static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev,
++				       struct chip_info *ci, u32 regs)
++{
++	u32 regdata;
++
++	/*
++	 * Get CC core rev
++	 * Chipid is assume to be at offset 0 from regs arg
++	 * For different chiptypes or old sdio hosts w/o chipcommon,
++	 * other ways of recognition should be added here.
++	 */
++	ci->c_inf[0].id = BCMA_CORE_CHIPCOMMON;
++	ci->c_inf[0].base = regs;
++	regdata = brcmf_sdio_regrl(sdiodev,
++				   CORE_CC_REG(ci->c_inf[0].base, chipid),
++				   NULL);
++	ci->chip = regdata & CID_ID_MASK;
++	ci->chiprev = (regdata & CID_REV_MASK) >> CID_REV_SHIFT;
++	ci->socitype = (regdata & CID_TYPE_MASK) >> CID_TYPE_SHIFT;
++
++	brcmf_dbg(INFO, "chipid=0x%x chiprev=%d\n", ci->chip, ci->chiprev);
++
++	/* Address of cores for new chips should be added here */
++	switch (ci->chip) {
++	case BCM4329_CHIP_ID:
++		ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
++		ci->c_inf[1].base = BCM4329_CORE_BUS_BASE;
++		ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
++		ci->c_inf[2].base = BCM4329_CORE_SOCRAM_BASE;
++		ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
++		ci->c_inf[3].base = BCM4329_CORE_ARM_BASE;
++		ci->ramsize = BCM4329_RAMSIZE;
++		break;
++	case BCM4330_CHIP_ID:
++		ci->c_inf[0].wrapbase = 0x18100000;
++		ci->c_inf[0].cib = 0x27004211;
++		ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
++		ci->c_inf[1].base = 0x18002000;
++		ci->c_inf[1].wrapbase = 0x18102000;
++		ci->c_inf[1].cib = 0x07004211;
++		ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
++		ci->c_inf[2].base = 0x18004000;
++		ci->c_inf[2].wrapbase = 0x18104000;
++		ci->c_inf[2].cib = 0x0d080401;
++		ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
++		ci->c_inf[3].base = 0x18003000;
++		ci->c_inf[3].wrapbase = 0x18103000;
++		ci->c_inf[3].cib = 0x03004211;
++		ci->ramsize = 0x48000;
++		break;
++	default:
++		brcmf_dbg(ERROR, "chipid 0x%x is not supported\n", ci->chip);
++		return -ENODEV;
++	}
++
++	switch (ci->socitype) {
++	case SOCI_SB:
++		ci->iscoreup = brcmf_sdio_sb_iscoreup;
++		ci->corerev = brcmf_sdio_sb_corerev;
++		ci->coredisable = brcmf_sdio_sb_coredisable;
++		ci->resetcore = brcmf_sdio_sb_resetcore;
++		break;
++	case SOCI_AI:
++		ci->iscoreup = brcmf_sdio_ai_iscoreup;
++		ci->corerev = brcmf_sdio_ai_corerev;
++		ci->coredisable = brcmf_sdio_ai_coredisable;
++		ci->resetcore = brcmf_sdio_ai_resetcore;
++		break;
++	default:
++		brcmf_dbg(ERROR, "socitype %u not supported\n", ci->socitype);
++		return -ENODEV;
++	}
++
++	return 0;
++}
++
++static int
++brcmf_sdio_chip_buscoreprep(struct brcmf_sdio_dev *sdiodev)
++{
++	int err = 0;
++	u8 clkval, clkset;
++
++	/* Try forcing SDIO core to do ALPAvail request only */
++	clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ;
++	brcmf_sdio_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
++	if (err) {
++		brcmf_dbg(ERROR, "error writing for HT off\n");
++		return err;
++	}
++
++	/* If register supported, wait for ALPAvail and then force ALP */
++	/* This may take up to 15 milliseconds */
++	clkval = brcmf_sdio_regrb(sdiodev,
++				  SBSDIO_FUNC1_CHIPCLKCSR, NULL);
++
++	if ((clkval & ~SBSDIO_AVBITS) != clkset) {
++		brcmf_dbg(ERROR, "ChipClkCSR access: wrote 0x%02x read 0x%02x\n",
++			  clkset, clkval);
++		return -EACCES;
++	}
++
++	SPINWAIT(((clkval = brcmf_sdio_regrb(sdiodev,
++					     SBSDIO_FUNC1_CHIPCLKCSR, NULL)),
++			!SBSDIO_ALPAV(clkval)),
++			PMU_MAX_TRANSITION_DLY);
++	if (!SBSDIO_ALPAV(clkval)) {
++		brcmf_dbg(ERROR, "timeout on ALPAV wait, clkval 0x%02x\n",
++			  clkval);
++		return -EBUSY;
++	}
++
++	clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_FORCE_ALP;
++	brcmf_sdio_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
++	udelay(65);
++
++	/* Also, disable the extra SDIO pull-ups */
++	brcmf_sdio_regwb(sdiodev, SBSDIO_FUNC1_SDIOPULLUP, 0, NULL);
++
++	return 0;
++}
++
++static void
++brcmf_sdio_chip_buscoresetup(struct brcmf_sdio_dev *sdiodev,
++			     struct chip_info *ci)
++{
++	u32 base = ci->c_inf[0].base;
++
++	/* get chipcommon rev */
++	ci->c_inf[0].rev = ci->corerev(sdiodev, ci, ci->c_inf[0].id);
++
++	/* get chipcommon capabilites */
++	ci->c_inf[0].caps = brcmf_sdio_regrl(sdiodev,
++					     CORE_CC_REG(base, capabilities),
++					     NULL);
++
++	/* get pmu caps & rev */
++	if (ci->c_inf[0].caps & CC_CAP_PMU) {
++		ci->pmucaps =
++			brcmf_sdio_regrl(sdiodev,
++					 CORE_CC_REG(base, pmucapabilities),
++					 NULL);
++		ci->pmurev = ci->pmucaps & PCAP_REV_MASK;
++	}
++
++	ci->c_inf[1].rev = ci->corerev(sdiodev, ci, ci->c_inf[1].id);
++
++	brcmf_dbg(INFO, "ccrev=%d, pmurev=%d, buscore rev/type=%d/0x%x\n",
++		  ci->c_inf[0].rev, ci->pmurev,
++		  ci->c_inf[1].rev, ci->c_inf[1].id);
++
++	/*
++	 * Make sure any on-chip ARM is off (in case strapping is wrong),
++	 * or downloaded code was already running.
++	 */
++	ci->coredisable(sdiodev, ci, BCMA_CORE_ARM_CM3);
++}
++
++int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev,
++			   struct chip_info **ci_ptr, u32 regs)
++{
++	int ret;
++	struct chip_info *ci;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* alloc chip_info_t */
++	ci = kzalloc(sizeof(struct chip_info), GFP_ATOMIC);
++	if (!ci)
++		return -ENOMEM;
++
++	ret = brcmf_sdio_chip_buscoreprep(sdiodev);
++	if (ret != 0)
++		goto err;
++
++	ret = brcmf_sdio_chip_recognition(sdiodev, ci, regs);
++	if (ret != 0)
++		goto err;
++
++	brcmf_sdio_chip_buscoresetup(sdiodev, ci);
++
++	brcmf_sdio_regwl(sdiodev, CORE_CC_REG(ci->c_inf[0].base, gpiopullup),
++			 0, NULL);
++	brcmf_sdio_regwl(sdiodev, CORE_CC_REG(ci->c_inf[0].base, gpiopulldown),
++			 0, NULL);
++
++	*ci_ptr = ci;
++	return 0;
++
++err:
++	kfree(ci);
++	return ret;
++}
++
++void
++brcmf_sdio_chip_detach(struct chip_info **ci_ptr)
++{
++	brcmf_dbg(TRACE, "Enter\n");
++
++	kfree(*ci_ptr);
++	*ci_ptr = NULL;
++}
++
++static char *brcmf_sdio_chip_name(uint chipid, char *buf, uint len)
++{
++	const char *fmt;
++
++	fmt = ((chipid > 0xa000) || (chipid < 0x4000)) ? "%d" : "%x";
++	snprintf(buf, len, fmt, chipid);
++	return buf;
++}
++
++void
++brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev,
++				  struct chip_info *ci, u32 drivestrength)
++{
++	struct sdiod_drive_str *str_tab = NULL;
++	u32 str_mask = 0;
++	u32 str_shift = 0;
++	char chn[8];
++	u32 base = ci->c_inf[0].base;
++
++	if (!(ci->c_inf[0].caps & CC_CAP_PMU))
++		return;
++
++	switch (SDIOD_DRVSTR_KEY(ci->chip, ci->pmurev)) {
++	case SDIOD_DRVSTR_KEY(BCM4330_CHIP_ID, 12):
++		str_tab = (struct sdiod_drive_str *)&sdiod_drvstr_tab1_1v8;
++		str_mask = 0x00003800;
++		str_shift = 11;
++		break;
++	default:
++		brcmf_dbg(ERROR, "No SDIO Drive strength init done for chip %s rev %d pmurev %d\n",
++			  brcmf_sdio_chip_name(ci->chip, chn, 8),
++			  ci->chiprev, ci->pmurev);
++		break;
++	}
++
++	if (str_tab != NULL) {
++		u32 drivestrength_sel = 0;
++		u32 cc_data_temp;
++		int i;
++
++		for (i = 0; str_tab[i].strength != 0; i++) {
++			if (drivestrength >= str_tab[i].strength) {
++				drivestrength_sel = str_tab[i].sel;
++				break;
++			}
++		}
++
++		brcmf_sdio_regwl(sdiodev, CORE_CC_REG(base, chipcontrol_addr),
++				 1, NULL);
++		cc_data_temp =
++			brcmf_sdio_regrl(sdiodev,
++					 CORE_CC_REG(base, chipcontrol_addr),
++					 NULL);
++		cc_data_temp &= ~str_mask;
++		drivestrength_sel <<= str_shift;
++		cc_data_temp |= drivestrength_sel;
++		brcmf_sdio_regwl(sdiodev, CORE_CC_REG(base, chipcontrol_addr),
++				 cc_data_temp, NULL);
++
++		brcmf_dbg(INFO, "SDIO: %dmA drive strength selected, set to 0x%08x\n",
++			  drivestrength, cc_data_temp);
++	}
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h
+new file mode 100644
+index 0000000..ce974d7
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h
+@@ -0,0 +1,136 @@
++/*
++ * Copyright (c) 2011 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef _BRCMFMAC_SDIO_CHIP_H_
++#define _BRCMFMAC_SDIO_CHIP_H_
++
++/*
++ * Core reg address translation.
++ * Both macro's returns a 32 bits byte address on the backplane bus.
++ */
++#define CORE_CC_REG(base, field) \
++		(base + offsetof(struct chipcregs, field))
++#define CORE_BUS_REG(base, field) \
++		(base + offsetof(struct sdpcmd_regs, field))
++#define CORE_SB(base, field) \
++		(base + SBCONFIGOFF + offsetof(struct sbconfig, field))
++
++/* SDIO function 1 register CHIPCLKCSR */
++/* Force ALP request to backplane */
++#define SBSDIO_FORCE_ALP		0x01
++/* Force HT request to backplane */
++#define SBSDIO_FORCE_HT			0x02
++/* Force ILP request to backplane */
++#define SBSDIO_FORCE_ILP		0x04
++/* Make ALP ready (power up xtal) */
++#define SBSDIO_ALP_AVAIL_REQ		0x08
++/* Make HT ready (power up PLL) */
++#define SBSDIO_HT_AVAIL_REQ		0x10
++/* Squelch clock requests from HW */
++#define SBSDIO_FORCE_HW_CLKREQ_OFF	0x20
++/* Status: ALP is ready */
++#define SBSDIO_ALP_AVAIL		0x40
++/* Status: HT is ready */
++#define SBSDIO_HT_AVAIL			0x80
++#define SBSDIO_AVBITS		(SBSDIO_HT_AVAIL | SBSDIO_ALP_AVAIL)
++#define SBSDIO_ALPAV(regval)	((regval) & SBSDIO_AVBITS)
++#define SBSDIO_HTAV(regval)	(((regval) & SBSDIO_AVBITS) == SBSDIO_AVBITS)
++#define SBSDIO_ALPONLY(regval)	(SBSDIO_ALPAV(regval) && !SBSDIO_HTAV(regval))
++#define SBSDIO_CLKAV(regval, alponly) \
++	(SBSDIO_ALPAV(regval) && (alponly ? 1 : SBSDIO_HTAV(regval)))
++
++#define BRCMF_MAX_CORENUM	6
++
++struct chip_core_info {
++	u16 id;
++	u16 rev;
++	u32 base;
++	u32 wrapbase;
++	u32 caps;
++	u32 cib;
++};
++
++struct chip_info {
++	u32 chip;
++	u32 chiprev;
++	u32 socitype;
++	/* core info */
++	/* always put chipcommon core at 0, bus core at 1 */
++	struct chip_core_info c_inf[BRCMF_MAX_CORENUM];
++	u32 pmurev;
++	u32 pmucaps;
++	u32 ramsize;
++
++	bool (*iscoreup)(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci,
++			 u16 coreid);
++	u32 (*corerev)(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci,
++			 u16 coreid);
++	void (*coredisable)(struct brcmf_sdio_dev *sdiodev,
++			struct chip_info *ci, u16 coreid);
++	void (*resetcore)(struct brcmf_sdio_dev *sdiodev,
++			struct chip_info *ci, u16 coreid);
++};
++
++struct sbconfig {
++	u32 PAD[2];
++	u32 sbipsflag;	/* initiator port ocp slave flag */
++	u32 PAD[3];
++	u32 sbtpsflag;	/* target port ocp slave flag */
++	u32 PAD[11];
++	u32 sbtmerrloga;	/* (sonics >= 2.3) */
++	u32 PAD;
++	u32 sbtmerrlog;	/* (sonics >= 2.3) */
++	u32 PAD[3];
++	u32 sbadmatch3;	/* address match3 */
++	u32 PAD;
++	u32 sbadmatch2;	/* address match2 */
++	u32 PAD;
++	u32 sbadmatch1;	/* address match1 */
++	u32 PAD[7];
++	u32 sbimstate;	/* initiator agent state */
++	u32 sbintvec;	/* interrupt mask */
++	u32 sbtmstatelow;	/* target state */
++	u32 sbtmstatehigh;	/* target state */
++	u32 sbbwa0;		/* bandwidth allocation table0 */
++	u32 PAD;
++	u32 sbimconfiglow;	/* initiator configuration */
++	u32 sbimconfighigh;	/* initiator configuration */
++	u32 sbadmatch0;	/* address match0 */
++	u32 PAD;
++	u32 sbtmconfiglow;	/* target configuration */
++	u32 sbtmconfighigh;	/* target configuration */
++	u32 sbbconfig;	/* broadcast configuration */
++	u32 PAD;
++	u32 sbbstate;	/* broadcast state */
++	u32 PAD[3];
++	u32 sbactcnfg;	/* activate configuration */
++	u32 PAD[3];
++	u32 sbflagst;	/* current sbflags */
++	u32 PAD[3];
++	u32 sbidlow;		/* identification */
++	u32 sbidhigh;	/* identification */
++};
++
++extern int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev,
++				  struct chip_info **ci_ptr, u32 regs);
++extern void brcmf_sdio_chip_detach(struct chip_info **ci_ptr);
++extern void brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev,
++					      struct chip_info *ci,
++					      u32 drivestrength);
++extern u8 brcmf_sdio_chip_getinfidx(struct chip_info *ci, u16 coreid);
++
++
++#endif		/* _BRCMFMAC_SDIO_CHIP_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
+new file mode 100644
+index 0000000..29bf78d2
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
+@@ -0,0 +1,272 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef	_BRCM_SDH_H_
++#define	_BRCM_SDH_H_
++
++#include <linux/skbuff.h>
++
++#define SDIO_FUNC_0		0
++#define SDIO_FUNC_1		1
++#define SDIO_FUNC_2		2
++
++#define SDIOD_FBR_SIZE		0x100
++
++/* io_en */
++#define SDIO_FUNC_ENABLE_1	0x02
++#define SDIO_FUNC_ENABLE_2	0x04
++
++/* io_rdys */
++#define SDIO_FUNC_READY_1	0x02
++#define SDIO_FUNC_READY_2	0x04
++
++/* intr_status */
++#define INTR_STATUS_FUNC1	0x2
++#define INTR_STATUS_FUNC2	0x4
++
++/* Maximum number of I/O funcs */
++#define SDIOD_MAX_IOFUNCS	7
++
++/* mask of register map */
++#define REG_F0_REG_MASK		0x7FF
++#define REG_F1_MISC_MASK	0x1FFFF
++
++/* as of sdiod rev 0, supports 3 functions */
++#define SBSDIO_NUM_FUNCTION		3
++
++/* function 0 vendor specific CCCR registers */
++#define SDIO_CCCR_BRCM_SEPINT		0xf2
++
++#define  SDIO_SEPINT_MASK		0x01
++#define  SDIO_SEPINT_OE			0x02
++#define  SDIO_SEPINT_ACT_HI		0x04
++
++/* function 1 miscellaneous registers */
++
++/* sprom command and status */
++#define SBSDIO_SPROM_CS			0x10000
++/* sprom info register */
++#define SBSDIO_SPROM_INFO		0x10001
++/* sprom indirect access data byte 0 */
++#define SBSDIO_SPROM_DATA_LOW		0x10002
++/* sprom indirect access data byte 1 */
++#define SBSDIO_SPROM_DATA_HIGH		0x10003
++/* sprom indirect access addr byte 0 */
++#define SBSDIO_SPROM_ADDR_LOW		0x10004
++/* sprom indirect access addr byte 0 */
++#define SBSDIO_SPROM_ADDR_HIGH		0x10005
++/* xtal_pu (gpio) output */
++#define SBSDIO_CHIP_CTRL_DATA		0x10006
++/* xtal_pu (gpio) enable */
++#define SBSDIO_CHIP_CTRL_EN		0x10007
++/* rev < 7, watermark for sdio device */
++#define SBSDIO_WATERMARK		0x10008
++/* control busy signal generation */
++#define SBSDIO_DEVICE_CTL		0x10009
++
++/* SB Address Window Low (b15) */
++#define SBSDIO_FUNC1_SBADDRLOW		0x1000A
++/* SB Address Window Mid (b23:b16) */
++#define SBSDIO_FUNC1_SBADDRMID		0x1000B
++/* SB Address Window High (b31:b24)    */
++#define SBSDIO_FUNC1_SBADDRHIGH		0x1000C
++/* Frame Control (frame term/abort) */
++#define SBSDIO_FUNC1_FRAMECTRL		0x1000D
++/* ChipClockCSR (ALP/HT ctl/status) */
++#define SBSDIO_FUNC1_CHIPCLKCSR		0x1000E
++/* SdioPullUp (on cmd, d0-d2) */
++#define SBSDIO_FUNC1_SDIOPULLUP		0x1000F
++/* Write Frame Byte Count Low */
++#define SBSDIO_FUNC1_WFRAMEBCLO		0x10019
++/* Write Frame Byte Count High */
++#define SBSDIO_FUNC1_WFRAMEBCHI		0x1001A
++/* Read Frame Byte Count Low */
++#define SBSDIO_FUNC1_RFRAMEBCLO		0x1001B
++/* Read Frame Byte Count High */
++#define SBSDIO_FUNC1_RFRAMEBCHI		0x1001C
++
++#define SBSDIO_FUNC1_MISC_REG_START	0x10000	/* f1 misc register start */
++#define SBSDIO_FUNC1_MISC_REG_LIMIT	0x1001C	/* f1 misc register end */
++
++/* function 1 OCP space */
++
++/* sb offset addr is <= 15 bits, 32k */
++#define SBSDIO_SB_OFT_ADDR_MASK		0x07FFF
++#define SBSDIO_SB_OFT_ADDR_LIMIT	0x08000
++/* with b15, maps to 32-bit SB access */
++#define SBSDIO_SB_ACCESS_2_4B_FLAG	0x08000
++
++/* valid bits in SBSDIO_FUNC1_SBADDRxxx regs */
++
++#define SBSDIO_SBADDRLOW_MASK		0x80	/* Valid bits in SBADDRLOW */
++#define SBSDIO_SBADDRMID_MASK		0xff	/* Valid bits in SBADDRMID */
++#define SBSDIO_SBADDRHIGH_MASK		0xffU	/* Valid bits in SBADDRHIGH */
++/* Address bits from SBADDR regs */
++#define SBSDIO_SBWINDOW_MASK		0xffff8000
++
++#define SDIOH_READ              0	/* Read request */
++#define SDIOH_WRITE             1	/* Write request */
++
++#define SDIOH_DATA_FIX          0	/* Fixed addressing */
++#define SDIOH_DATA_INC          1	/* Incremental addressing */
++
++/* internal return code */
++#define SUCCESS	0
++#define ERROR	1
++
++/* Packet alignment for most efficient SDIO (can change based on platform) */
++#define BRCMF_SDALIGN	(1 << 6)
++
++/* watchdog polling interval in ms */
++#define BRCMF_WD_POLL_MS	10
++
++struct brcmf_sdreg {
++	int func;
++	int offset;
++	int value;
++};
++
++struct brcmf_sdio;
++
++struct brcmf_sdio_dev {
++	struct sdio_func *func[SDIO_MAX_FUNCS];
++	u8 num_funcs;			/* Supported funcs on client */
++	u32 func_cis_ptr[SDIOD_MAX_IOFUNCS];
++	u32 sbwad;			/* Save backplane window address */
++	void *bus;
++	atomic_t suspend;		/* suspend flag */
++	wait_queue_head_t request_byte_wait;
++	wait_queue_head_t request_word_wait;
++	wait_queue_head_t request_chain_wait;
++	wait_queue_head_t request_buffer_wait;
++	struct device *dev;
++	struct brcmf_bus *bus_if;
++#ifdef CONFIG_BRCMFMAC_SDIO_OOB
++	unsigned int irq;		/* oob interrupt number */
++	unsigned long irq_flags;	/* board specific oob flags */
++	bool irq_en;			/* irq enable flags */
++	spinlock_t irq_en_lock;
++	bool irq_wake;			/* irq wake enable flags */
++#endif		/* CONFIG_BRCMFMAC_SDIO_OOB */
++};
++
++/* Register/deregister interrupt handler. */
++extern int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev);
++extern int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev);
++
++/* sdio device register access interface */
++extern u8 brcmf_sdio_regrb(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret);
++extern u32 brcmf_sdio_regrl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret);
++extern void brcmf_sdio_regwb(struct brcmf_sdio_dev *sdiodev, u32 addr,
++			     u8 data, int *ret);
++extern void brcmf_sdio_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr,
++			     u32 data, int *ret);
++
++/* Buffer transfer to/from device (client) core via cmd53.
++ *   fn:       function number
++ *   addr:     backplane address (i.e. >= regsva from attach)
++ *   flags:    backplane width, address increment, sync/async
++ *   buf:      pointer to memory data buffer
++ *   nbytes:   number of bytes to transfer to/from buf
++ *   pkt:      pointer to packet associated with buf (if any)
++ *   complete: callback function for command completion (async only)
++ *   handle:   handle for completion callback (first arg in callback)
++ * Returns 0 or error code.
++ * NOTE: Async operation is not currently supported.
++ */
++extern int
++brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
++		      uint flags, struct sk_buff *pkt);
++extern int
++brcmf_sdcard_send_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
++		      uint flags, u8 *buf, uint nbytes);
++
++extern int
++brcmf_sdcard_recv_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
++		      uint flags, struct sk_buff *pkt);
++extern int
++brcmf_sdcard_recv_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
++		      uint flags, u8 *buf, uint nbytes);
++extern int
++brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
++			uint flags, struct sk_buff_head *pktq);
++
++/* Flags bits */
++
++/* Four-byte target (backplane) width (vs. two-byte) */
++#define SDIO_REQ_4BYTE	0x1
++/* Fixed address (FIFO) (vs. incrementing address) */
++#define SDIO_REQ_FIXED	0x2
++/* Async request (vs. sync request) */
++#define SDIO_REQ_ASYNC	0x4
++
++/* Read/write to memory block (F1, no FIFO) via CMD53 (sync only).
++ *   rw:       read or write (0/1)
++ *   addr:     direct SDIO address
++ *   buf:      pointer to memory data buffer
++ *   nbytes:   number of bytes to transfer to/from buf
++ * Returns 0 or error code.
++ */
++extern int brcmf_sdcard_rwdata(struct brcmf_sdio_dev *sdiodev, uint rw,
++			       u32 addr, u8 *buf, uint nbytes);
++
++/* Issue an abort to the specified function */
++extern int brcmf_sdcard_abort(struct brcmf_sdio_dev *sdiodev, uint fn);
++
++/* platform specific/high level functions */
++extern int brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev);
++extern int brcmf_sdio_remove(struct brcmf_sdio_dev *sdiodev);
++
++extern int brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev,
++					  u32 address);
++
++/* attach, return handler on success, NULL if failed.
++ *  The handler shall be provided by all subsequent calls. No local cache
++ *  cfghdl points to the starting address of pci device mapped memory
++ */
++extern int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev);
++extern void brcmf_sdioh_detach(struct brcmf_sdio_dev *sdiodev);
++
++/* read or write one byte using cmd52 */
++extern int brcmf_sdioh_request_byte(struct brcmf_sdio_dev *sdiodev, uint rw,
++				    uint fnc, uint addr, u8 *byte);
++
++/* read or write 2/4 bytes using cmd53 */
++extern int
++brcmf_sdioh_request_word(struct brcmf_sdio_dev *sdiodev,
++			 uint rw, uint fnc, uint addr,
++			 u32 *word, uint nbyte);
++
++/* read or write any buffer using cmd53 */
++extern int
++brcmf_sdioh_request_buffer(struct brcmf_sdio_dev *sdiodev,
++			   uint fix_inc, uint rw, uint fnc_num, u32 addr,
++			   struct sk_buff *pkt);
++extern int
++brcmf_sdioh_request_chain(struct brcmf_sdio_dev *sdiodev, uint fix_inc,
++			  uint write, uint func, uint addr,
++			  struct sk_buff_head *pktq);
++
++/* Watchdog timer interface for pm ops */
++extern void brcmf_sdio_wdtmr_enable(struct brcmf_sdio_dev *sdiodev,
++				    bool enable);
++
++extern void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev);
++extern void brcmf_sdbrcm_disconnect(void *ptr);
++extern void brcmf_sdbrcm_isr(void *arg);
++
++extern void brcmf_sdbrcm_wd_timer(struct brcmf_sdio *bus, uint wdtick);
++#endif				/* _BRCM_SDH_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
+new file mode 100644
+index 0000000..be1edc8
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
+@@ -0,0 +1,1617 @@
++/*
++ * Copyright (c) 2011 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#include <linux/init.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/kthread.h>
++#include <linux/slab.h>
++#include <linux/skbuff.h>
++#include <linux/netdevice.h>
++#include <linux/spinlock.h>
++#include <linux/ethtool.h>
++#include <linux/fcntl.h>
++#include <linux/fs.h>
++#include <linux/uaccess.h>
++#include <linux/firmware.h>
++#include <linux/usb.h>
++#include <linux/vmalloc.h>
++#include <net/cfg80211.h>
++
++#include <defs.h>
++#include <brcmu_utils.h>
++#include <brcmu_wifi.h>
++#include <dhd_bus.h>
++#include <dhd_dbg.h>
++
++#include "usb_rdl.h"
++#include "usb.h"
++
++#define IOCTL_RESP_TIMEOUT  2000
++
++#define BRCMF_USB_SYNC_TIMEOUT		300	/* ms */
++#define BRCMF_USB_DLIMAGE_SPINWAIT	100	/* in unit of ms */
++#define BRCMF_USB_DLIMAGE_LIMIT		500	/* spinwait limit (ms) */
++
++#define BRCMF_POSTBOOT_ID		0xA123  /* ID to detect if dongle
++						   has boot up */
++#define BRCMF_USB_RESETCFG_SPINWAIT	1	/* wait after resetcfg (ms) */
++
++#define BRCMF_USB_NRXQ	50
++#define BRCMF_USB_NTXQ	50
++
++#define CONFIGDESC(usb)         (&((usb)->actconfig)->desc)
++#define IFPTR(usb, idx)         ((usb)->actconfig->interface[(idx)])
++#define IFALTS(usb, idx)        (IFPTR((usb), (idx))->altsetting[0])
++#define IFDESC(usb, idx)        IFALTS((usb), (idx)).desc
++#define IFEPDESC(usb, idx, ep)  (IFALTS((usb), (idx)).endpoint[(ep)]).desc
++
++#define CONTROL_IF              0
++#define BULK_IF                 0
++
++#define BRCMF_USB_CBCTL_WRITE	0
++#define BRCMF_USB_CBCTL_READ	1
++#define BRCMF_USB_MAX_PKT_SIZE	1600
++
++#define BRCMF_USB_43236_FW_NAME	"brcm/brcmfmac43236b.bin"
++
++enum usbdev_suspend_state {
++	USBOS_SUSPEND_STATE_DEVICE_ACTIVE = 0, /* Device is busy, won't allow
++						  suspend */
++	USBOS_SUSPEND_STATE_SUSPEND_PENDING,	/* Device is idle, can be
++						 * suspended. Wating PM to
++						 * suspend the device
++						 */
++	USBOS_SUSPEND_STATE_SUSPENDED	/* Device suspended */
++};
++
++struct brcmf_usb_probe_info {
++	void *usbdev_info;
++	struct usb_device *usb; /* USB device pointer from OS */
++	uint rx_pipe, tx_pipe, intr_pipe, rx_pipe2;
++	int intr_size; /* Size of interrupt message */
++	int interval;  /* Interrupt polling interval */
++	int vid;
++	int pid;
++	enum usb_device_speed device_speed;
++	enum usbdev_suspend_state suspend_state;
++	struct usb_interface *intf;
++};
++static struct brcmf_usb_probe_info usbdev_probe_info;
++
++struct brcmf_usb_image {
++	void *data;
++	u32 len;
++};
++static struct brcmf_usb_image g_image = { NULL, 0 };
++
++struct intr_transfer_buf {
++	u32 notification;
++	u32 reserved;
++};
++
++struct brcmf_usbdev_info {
++	struct brcmf_usbdev bus_pub; /* MUST BE FIRST */
++	spinlock_t qlock;
++	struct list_head rx_freeq;
++	struct list_head rx_postq;
++	struct list_head tx_freeq;
++	struct list_head tx_postq;
++	enum usbdev_suspend_state suspend_state;
++	uint rx_pipe, tx_pipe, intr_pipe, rx_pipe2;
++
++	bool activity;
++	int rx_low_watermark;
++	int tx_low_watermark;
++	int tx_high_watermark;
++	bool txoff;
++	bool rxoff;
++	bool txoverride;
++
++	struct brcmf_usbreq *tx_reqs;
++	struct brcmf_usbreq *rx_reqs;
++
++	u8 *image;	/* buffer for combine fw and nvram */
++	int image_len;
++
++	wait_queue_head_t wait;
++	bool waitdone;
++	int sync_urb_status;
++
++	struct usb_device *usbdev;
++	struct device *dev;
++	enum usb_device_speed  device_speed;
++
++	int ctl_in_pipe, ctl_out_pipe;
++	struct urb *ctl_urb; /* URB for control endpoint */
++	struct usb_ctrlrequest ctl_write;
++	struct usb_ctrlrequest ctl_read;
++	u32 ctl_urb_actual_length;
++	int ctl_urb_status;
++	int ctl_completed;
++	wait_queue_head_t ioctl_resp_wait;
++	wait_queue_head_t ctrl_wait;
++	ulong ctl_op;
++
++	bool rxctl_deferrespok;
++
++	struct urb *bulk_urb; /* used for FW download */
++	struct urb *intr_urb; /* URB for interrupt endpoint */
++	int intr_size;          /* Size of interrupt message */
++	int interval;           /* Interrupt polling interval */
++	struct intr_transfer_buf intr; /* Data buffer for interrupt endpoint */
++
++	struct brcmf_usb_probe_info probe_info;
++
++};
++
++static void brcmf_usb_rx_refill(struct brcmf_usbdev_info *devinfo,
++				struct brcmf_usbreq  *req);
++
++MODULE_AUTHOR("Broadcom Corporation");
++MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN fullmac usb driver.");
++MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN fullmac usb cards");
++MODULE_LICENSE("Dual BSD/GPL");
++
++static struct brcmf_usbdev *brcmf_usb_get_buspub(struct device *dev)
++{
++	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
++	return bus_if->bus_priv.usb;
++}
++
++static struct brcmf_usbdev_info *brcmf_usb_get_businfo(struct device *dev)
++{
++	return brcmf_usb_get_buspub(dev)->devinfo;
++}
++
++#if 0
++static void
++brcmf_usb_txflowcontrol(struct brcmf_usbdev_info *devinfo, bool onoff)
++{
++	dhd_txflowcontrol(devinfo->bus_pub.netdev, 0, onoff);
++}
++#endif
++
++static int brcmf_usb_ioctl_resp_wait(struct brcmf_usbdev_info *devinfo,
++	 uint *condition, bool *pending)
++{
++	DECLARE_WAITQUEUE(wait, current);
++	int timeout = IOCTL_RESP_TIMEOUT;
++
++	/* Convert timeout in millsecond to jiffies */
++	timeout = msecs_to_jiffies(timeout);
++	/* Wait until control frame is available */
++	add_wait_queue(&devinfo->ioctl_resp_wait, &wait);
++	set_current_state(TASK_INTERRUPTIBLE);
++
++	smp_mb();
++	while (!(*condition) && (!signal_pending(current) && timeout)) {
++		timeout = schedule_timeout(timeout);
++		/* Wait until control frame is available */
++		smp_mb();
++	}
++
++	if (signal_pending(current))
++		*pending = true;
++
++	set_current_state(TASK_RUNNING);
++	remove_wait_queue(&devinfo->ioctl_resp_wait, &wait);
++
++	return timeout;
++}
++
++static int brcmf_usb_ioctl_resp_wake(struct brcmf_usbdev_info *devinfo)
++{
++	if (waitqueue_active(&devinfo->ioctl_resp_wait))
++		wake_up_interruptible(&devinfo->ioctl_resp_wait);
++
++	return 0;
++}
++
++static void
++brcmf_usb_ctl_complete(struct brcmf_usbdev_info *devinfo, int type, int status)
++{
++
++	if (unlikely(devinfo == NULL))
++		return;
++
++	if (type == BRCMF_USB_CBCTL_READ) {
++		if (status == 0)
++			devinfo->bus_pub.stats.rx_ctlpkts++;
++		else
++			devinfo->bus_pub.stats.rx_ctlerrs++;
++	} else if (type == BRCMF_USB_CBCTL_WRITE) {
++		if (status == 0)
++			devinfo->bus_pub.stats.tx_ctlpkts++;
++		else
++			devinfo->bus_pub.stats.tx_ctlerrs++;
++	}
++
++	devinfo->ctl_urb_status = status;
++	devinfo->ctl_completed = true;
++	brcmf_usb_ioctl_resp_wake(devinfo);
++}
++
++static void
++brcmf_usb_ctlread_complete(struct urb *urb)
++{
++	struct brcmf_usbdev_info *devinfo =
++		(struct brcmf_usbdev_info *)urb->context;
++
++	devinfo->ctl_urb_actual_length = urb->actual_length;
++	brcmf_usb_ctl_complete(devinfo, BRCMF_USB_CBCTL_READ,
++		urb->status);
++}
++
++static void
++brcmf_usb_ctlwrite_complete(struct urb *urb)
++{
++	struct brcmf_usbdev_info *devinfo =
++		(struct brcmf_usbdev_info *)urb->context;
++
++	brcmf_usb_ctl_complete(devinfo, BRCMF_USB_CBCTL_WRITE,
++		urb->status);
++}
++
++static int brcmf_usb_pnp(struct brcmf_usbdev_info *devinfo, uint state)
++{
++	return 0;
++}
++
++static int
++brcmf_usb_send_ctl(struct brcmf_usbdev_info *devinfo, u8 *buf, int len)
++{
++	int ret;
++	u16 size;
++
++	if (devinfo == NULL || buf == NULL ||
++	    len == 0 || devinfo->ctl_urb == NULL)
++		return -EINVAL;
++
++	/* If the USB/HSIC bus in sleep state, wake it up */
++	if (devinfo->suspend_state == USBOS_SUSPEND_STATE_SUSPENDED)
++		if (brcmf_usb_pnp(devinfo, BCMFMAC_USB_PNP_RESUME) != 0) {
++			brcmf_dbg(ERROR, "Could not Resume the bus!\n");
++			return -EIO;
++		}
++
++	devinfo->activity = true;
++	size = len;
++	devinfo->ctl_write.wLength = cpu_to_le16p(&size);
++	devinfo->ctl_urb->transfer_buffer_length = size;
++	devinfo->ctl_urb_status = 0;
++	devinfo->ctl_urb_actual_length = 0;
++
++	usb_fill_control_urb(devinfo->ctl_urb,
++		devinfo->usbdev,
++		devinfo->ctl_out_pipe,
++		(unsigned char *) &devinfo->ctl_write,
++		buf, size,
++		(usb_complete_t)brcmf_usb_ctlwrite_complete,
++		devinfo);
++
++	ret = usb_submit_urb(devinfo->ctl_urb, GFP_ATOMIC);
++	if (ret < 0)
++		brcmf_dbg(ERROR, "usb_submit_urb failed %d\n", ret);
++
++	return ret;
++}
++
++static int
++brcmf_usb_recv_ctl(struct brcmf_usbdev_info *devinfo, u8 *buf, int len)
++{
++	int ret;
++	u16 size;
++
++	if ((devinfo == NULL) || (buf == NULL) || (len == 0)
++		|| (devinfo->ctl_urb == NULL))
++		return -EINVAL;
++
++	size = len;
++	devinfo->ctl_read.wLength = cpu_to_le16p(&size);
++	devinfo->ctl_urb->transfer_buffer_length = size;
++
++	if (devinfo->rxctl_deferrespok) {
++		/* BMAC model */
++		devinfo->ctl_read.bRequestType = USB_DIR_IN
++			| USB_TYPE_VENDOR | USB_RECIP_INTERFACE;
++		devinfo->ctl_read.bRequest = DL_DEFER_RESP_OK;
++	} else {
++		/* full dongle model */
++		devinfo->ctl_read.bRequestType = USB_DIR_IN
++			| USB_TYPE_CLASS | USB_RECIP_INTERFACE;
++		devinfo->ctl_read.bRequest = 1;
++	}
++
++	usb_fill_control_urb(devinfo->ctl_urb,
++		devinfo->usbdev,
++		devinfo->ctl_in_pipe,
++		(unsigned char *) &devinfo->ctl_read,
++		buf, size,
++		(usb_complete_t)brcmf_usb_ctlread_complete,
++		devinfo);
++
++	ret = usb_submit_urb(devinfo->ctl_urb, GFP_ATOMIC);
++	if (ret < 0)
++		brcmf_dbg(ERROR, "usb_submit_urb failed %d\n", ret);
++
++	return ret;
++}
++
++static int brcmf_usb_tx_ctlpkt(struct device *dev, u8 *buf, u32 len)
++{
++	int err = 0;
++	int timeout = 0;
++	bool pending;
++	struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);
++
++	if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) {
++		/* TODO: handle suspend/resume */
++		return -EIO;
++	}
++
++	if (test_and_set_bit(0, &devinfo->ctl_op))
++		return -EIO;
++
++	err = brcmf_usb_send_ctl(devinfo, buf, len);
++	if (err) {
++		brcmf_dbg(ERROR, "fail %d bytes: %d\n", err, len);
++		return err;
++	}
++
++	devinfo->ctl_completed = false;
++	timeout = brcmf_usb_ioctl_resp_wait(devinfo, &devinfo->ctl_completed,
++					    &pending);
++	clear_bit(0, &devinfo->ctl_op);
++	if (!timeout) {
++		brcmf_dbg(ERROR, "Txctl wait timed out\n");
++		err = -EIO;
++	}
++	return err;
++}
++
++static int brcmf_usb_rx_ctlpkt(struct device *dev, u8 *buf, u32 len)
++{
++	int err = 0;
++	int timeout = 0;
++	bool pending;
++	struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);
++
++	if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) {
++		/* TODO: handle suspend/resume */
++		return -EIO;
++	}
++	if (test_and_set_bit(0, &devinfo->ctl_op))
++		return -EIO;
++
++	err = brcmf_usb_recv_ctl(devinfo, buf, len);
++	if (err) {
++		brcmf_dbg(ERROR, "fail %d bytes: %d\n", err, len);
++		return err;
++	}
++	devinfo->ctl_completed = false;
++	timeout = brcmf_usb_ioctl_resp_wait(devinfo, &devinfo->ctl_completed,
++					    &pending);
++	err = devinfo->ctl_urb_status;
++	clear_bit(0, &devinfo->ctl_op);
++	if (!timeout) {
++		brcmf_dbg(ERROR, "rxctl wait timed out\n");
++		err = -EIO;
++	}
++	if (!err)
++		return devinfo->ctl_urb_actual_length;
++	else
++		return err;
++}
++
++static struct brcmf_usbreq *brcmf_usb_deq(struct brcmf_usbdev_info *devinfo,
++					  struct list_head *q)
++{
++	unsigned long flags;
++	struct brcmf_usbreq  *req;
++	spin_lock_irqsave(&devinfo->qlock, flags);
++	if (list_empty(q)) {
++		spin_unlock_irqrestore(&devinfo->qlock, flags);
++		return NULL;
++	}
++	req = list_entry(q->next, struct brcmf_usbreq, list);
++	list_del_init(q->next);
++	spin_unlock_irqrestore(&devinfo->qlock, flags);
++	return req;
++
++}
++
++static void brcmf_usb_enq(struct brcmf_usbdev_info *devinfo,
++			  struct list_head *q, struct brcmf_usbreq *req)
++{
++	unsigned long flags;
++	spin_lock_irqsave(&devinfo->qlock, flags);
++	list_add_tail(&req->list, q);
++	spin_unlock_irqrestore(&devinfo->qlock, flags);
++}
++
++static struct brcmf_usbreq *
++brcmf_usbdev_qinit(struct list_head *q, int qsize)
++{
++	int i;
++	struct brcmf_usbreq *req, *reqs;
++
++	reqs = kzalloc(sizeof(struct brcmf_usbreq) * qsize, GFP_ATOMIC);
++	if (reqs == NULL) {
++		brcmf_dbg(ERROR, "fail to allocate memory!\n");
++		return NULL;
++	}
++	req = reqs;
++
++	for (i = 0; i < qsize; i++) {
++		req->urb = usb_alloc_urb(0, GFP_ATOMIC);
++		if (!req->urb)
++			goto fail;
++
++		INIT_LIST_HEAD(&req->list);
++		list_add_tail(&req->list, q);
++		req++;
++	}
++	return reqs;
++fail:
++	brcmf_dbg(ERROR, "fail!\n");
++	while (!list_empty(q)) {
++		req = list_entry(q->next, struct brcmf_usbreq, list);
++		if (req && req->urb)
++			usb_free_urb(req->urb);
++		list_del(q->next);
++	}
++	return NULL;
++
++}
++
++static void brcmf_usb_free_q(struct list_head *q, bool pending)
++{
++	struct brcmf_usbreq *req, *next;
++	int i = 0;
++	list_for_each_entry_safe(req, next, q, list) {
++		if (!req->urb) {
++			brcmf_dbg(ERROR, "bad req\n");
++			break;
++		}
++		i++;
++		if (pending) {
++			usb_kill_urb(req->urb);
++		} else {
++			usb_free_urb(req->urb);
++			list_del_init(&req->list);
++		}
++	}
++}
++
++static void brcmf_usb_del_fromq(struct brcmf_usbdev_info *devinfo,
++				struct brcmf_usbreq *req)
++{
++	unsigned long flags;
++
++	spin_lock_irqsave(&devinfo->qlock, flags);
++	list_del_init(&req->list);
++	spin_unlock_irqrestore(&devinfo->qlock, flags);
++}
++
++
++static void brcmf_usb_tx_complete(struct urb *urb)
++{
++	struct brcmf_usbreq *req = (struct brcmf_usbreq *)urb->context;
++	struct brcmf_usbdev_info *devinfo = req->devinfo;
++
++	brcmf_usb_del_fromq(devinfo, req);
++	if (urb->status == 0)
++		devinfo->bus_pub.bus->dstats.tx_packets++;
++	else
++		devinfo->bus_pub.bus->dstats.tx_errors++;
++
++	dev_kfree_skb(req->skb);
++	req->skb = NULL;
++	brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req);
++
++}
++
++static void brcmf_usb_rx_complete(struct urb *urb)
++{
++	struct brcmf_usbreq  *req = (struct brcmf_usbreq *)urb->context;
++	struct brcmf_usbdev_info *devinfo = req->devinfo;
++	struct sk_buff *skb;
++	int ifidx = 0;
++
++	brcmf_usb_del_fromq(devinfo, req);
++	skb = req->skb;
++	req->skb = NULL;
++
++	if (urb->status == 0) {
++		devinfo->bus_pub.bus->dstats.rx_packets++;
++	} else {
++		devinfo->bus_pub.bus->dstats.rx_errors++;
++		dev_kfree_skb(skb);
++		brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req);
++		return;
++	}
++
++	if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_UP) {
++		skb_put(skb, urb->actual_length);
++		if (brcmf_proto_hdrpull(devinfo->dev, &ifidx, skb) != 0) {
++			brcmf_dbg(ERROR, "rx protocol error\n");
++			brcmu_pkt_buf_free_skb(skb);
++			devinfo->bus_pub.bus->dstats.rx_errors++;
++		} else {
++			brcmf_rx_packet(devinfo->dev, ifidx, skb);
++			brcmf_usb_rx_refill(devinfo, req);
++		}
++	} else {
++		dev_kfree_skb(skb);
++	}
++	return;
++
++}
++
++static void brcmf_usb_rx_refill(struct brcmf_usbdev_info *devinfo,
++				struct brcmf_usbreq  *req)
++{
++	struct sk_buff *skb;
++	int ret;
++
++	if (!req || !devinfo)
++		return;
++
++	skb = dev_alloc_skb(devinfo->bus_pub.bus_mtu);
++	if (!skb) {
++		brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req);
++		return;
++	}
++	req->skb = skb;
++
++	usb_fill_bulk_urb(req->urb, devinfo->usbdev, devinfo->rx_pipe,
++			  skb->data, skb_tailroom(skb), brcmf_usb_rx_complete,
++			  req);
++	req->urb->transfer_flags |= URB_ZERO_PACKET;
++	req->devinfo = devinfo;
++
++	ret = usb_submit_urb(req->urb, GFP_ATOMIC);
++	if (ret == 0) {
++		brcmf_usb_enq(devinfo, &devinfo->rx_postq, req);
++	} else {
++		dev_kfree_skb(req->skb);
++		req->skb = NULL;
++		brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req);
++	}
++	return;
++}
++
++static void brcmf_usb_rx_fill_all(struct brcmf_usbdev_info *devinfo)
++{
++	struct brcmf_usbreq *req;
++
++	if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) {
++		brcmf_dbg(ERROR, "bus is not up\n");
++		return;
++	}
++	while ((req = brcmf_usb_deq(devinfo, &devinfo->rx_freeq)) != NULL)
++		brcmf_usb_rx_refill(devinfo, req);
++}
++
++static void
++brcmf_usb_state_change(struct brcmf_usbdev_info *devinfo, int state)
++{
++	struct brcmf_bus *bcmf_bus = devinfo->bus_pub.bus;
++	int old_state;
++
++
++	if (devinfo->bus_pub.state == state)
++		return;
++
++	old_state = devinfo->bus_pub.state;
++	brcmf_dbg(TRACE, "dbus state change from %d to to %d\n",
++		  old_state, state);
++
++	/* Don't update state if it's PnP firmware re-download */
++	if (state != BCMFMAC_USB_STATE_PNP_FWDL) /* TODO */
++		devinfo->bus_pub.state = state;
++
++	if ((old_state  == BCMFMAC_USB_STATE_SLEEP)
++		&& (state == BCMFMAC_USB_STATE_UP)) {
++		brcmf_usb_rx_fill_all(devinfo);
++	}
++
++	/* update state of upper layer */
++	if (state == BCMFMAC_USB_STATE_DOWN) {
++		brcmf_dbg(INFO, "DBUS is down\n");
++		bcmf_bus->state = BRCMF_BUS_DOWN;
++	} else {
++		brcmf_dbg(INFO, "DBUS current state=%d\n", state);
++	}
++}
++
++static void
++brcmf_usb_intr_complete(struct urb *urb)
++{
++	struct brcmf_usbdev_info *devinfo =
++			(struct brcmf_usbdev_info *)urb->context;
++	bool killed;
++
++	if (devinfo == NULL)
++		return;
++
++	if (unlikely(urb->status)) {
++		if (devinfo->suspend_state ==
++			USBOS_SUSPEND_STATE_SUSPEND_PENDING)
++			killed = true;
++
++		if ((urb->status == -ENOENT && (!killed))
++			|| urb->status == -ESHUTDOWN ||
++			urb->status == -ENODEV) {
++			brcmf_usb_state_change(devinfo, BCMFMAC_USB_STATE_DOWN);
++		}
++	}
++
++	if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_DOWN) {
++		brcmf_dbg(ERROR, "intr cb when DBUS down, ignoring\n");
++		return;
++	}
++
++	if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_UP)
++		usb_submit_urb(devinfo->intr_urb, GFP_ATOMIC);
++}
++
++static int brcmf_usb_tx(struct device *dev, struct sk_buff *skb)
++{
++	struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);
++	struct brcmf_usbreq  *req;
++	int ret;
++
++	if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) {
++		/* TODO: handle suspend/resume */
++		return -EIO;
++	}
++
++	req = brcmf_usb_deq(devinfo, &devinfo->tx_freeq);
++	if (!req) {
++		brcmf_dbg(ERROR, "no req to send\n");
++		return -ENOMEM;
++	}
++	if (!req->urb) {
++		brcmf_dbg(ERROR, "no urb for req %p\n", req);
++		return -ENOBUFS;
++	}
++
++	req->skb = skb;
++	req->devinfo = devinfo;
++	usb_fill_bulk_urb(req->urb, devinfo->usbdev, devinfo->tx_pipe,
++			  skb->data, skb->len, brcmf_usb_tx_complete, req);
++	req->urb->transfer_flags |= URB_ZERO_PACKET;
++	ret = usb_submit_urb(req->urb, GFP_ATOMIC);
++	if (!ret) {
++		brcmf_usb_enq(devinfo, &devinfo->tx_postq, req);
++	} else {
++		req->skb = NULL;
++		brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req);
++	}
++
++	return ret;
++}
++
++
++static int brcmf_usb_up(struct device *dev)
++{
++	struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);
++	u16 ifnum;
++
++	if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_UP)
++		return 0;
++
++	/* If the USB/HSIC bus in sleep state, wake it up */
++	if (devinfo->suspend_state == USBOS_SUSPEND_STATE_SUSPENDED) {
++		if (brcmf_usb_pnp(devinfo, BCMFMAC_USB_PNP_RESUME) != 0) {
++			brcmf_dbg(ERROR, "Could not Resume the bus!\n");
++			return -EIO;
++		}
++	}
++	devinfo->activity = true;
++
++	/* Success, indicate devinfo is fully up */
++	brcmf_usb_state_change(devinfo, BCMFMAC_USB_STATE_UP);
++
++	if (devinfo->intr_urb) {
++		int ret;
++
++		usb_fill_int_urb(devinfo->intr_urb, devinfo->usbdev,
++			devinfo->intr_pipe,
++			&devinfo->intr,
++			devinfo->intr_size,
++			(usb_complete_t)brcmf_usb_intr_complete,
++			devinfo,
++			devinfo->interval);
++
++		ret = usb_submit_urb(devinfo->intr_urb, GFP_ATOMIC);
++		if (ret) {
++			brcmf_dbg(ERROR, "USB_SUBMIT_URB failed with status %d\n",
++				  ret);
++			return -EINVAL;
++		}
++	}
++
++	if (devinfo->ctl_urb) {
++		devinfo->ctl_in_pipe = usb_rcvctrlpipe(devinfo->usbdev, 0);
++		devinfo->ctl_out_pipe = usb_sndctrlpipe(devinfo->usbdev, 0);
++
++		ifnum = IFDESC(devinfo->usbdev, CONTROL_IF).bInterfaceNumber;
++
++		/* CTL Write */
++		devinfo->ctl_write.bRequestType =
++			USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
++		devinfo->ctl_write.bRequest = 0;
++		devinfo->ctl_write.wValue = cpu_to_le16(0);
++		devinfo->ctl_write.wIndex = cpu_to_le16p(&ifnum);
++
++		/* CTL Read */
++		devinfo->ctl_read.bRequestType =
++			USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
++		devinfo->ctl_read.bRequest = 1;
++		devinfo->ctl_read.wValue = cpu_to_le16(0);
++		devinfo->ctl_read.wIndex = cpu_to_le16p(&ifnum);
++	}
++	brcmf_usb_rx_fill_all(devinfo);
++	return 0;
++}
++
++static void brcmf_usb_down(struct device *dev)
++{
++	struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);
++
++	if (devinfo == NULL)
++		return;
++
++	brcmf_dbg(TRACE, "enter\n");
++	if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_DOWN)
++		return;
++
++	brcmf_usb_state_change(devinfo, BCMFMAC_USB_STATE_DOWN);
++	if (devinfo->intr_urb)
++		usb_kill_urb(devinfo->intr_urb);
++
++	if (devinfo->ctl_urb)
++		usb_kill_urb(devinfo->ctl_urb);
++
++	if (devinfo->bulk_urb)
++		usb_kill_urb(devinfo->bulk_urb);
++	brcmf_usb_free_q(&devinfo->tx_postq, true);
++
++	brcmf_usb_free_q(&devinfo->rx_postq, true);
++}
++
++static int
++brcmf_usb_sync_wait(struct brcmf_usbdev_info *devinfo, u16 time)
++{
++	int ret;
++	int err = 0;
++	int ms = time;
++
++	ret = wait_event_interruptible_timeout(devinfo->wait,
++		devinfo->waitdone == true, (ms * HZ / 1000));
++
++	if ((devinfo->waitdone == false) || (devinfo->sync_urb_status)) {
++		brcmf_dbg(ERROR, "timeout(%d) or urb err=%d\n",
++			  ret, devinfo->sync_urb_status);
++		err = -EINVAL;
++	}
++	devinfo->waitdone = false;
++	return err;
++}
++
++static void
++brcmf_usb_sync_complete(struct urb *urb)
++{
++	struct brcmf_usbdev_info *devinfo =
++			(struct brcmf_usbdev_info *)urb->context;
++
++	devinfo->waitdone = true;
++	wake_up_interruptible(&devinfo->wait);
++	devinfo->sync_urb_status = urb->status;
++}
++
++static bool brcmf_usb_dl_cmd(struct brcmf_usbdev_info *devinfo, u8 cmd,
++			     void *buffer, int buflen)
++{
++	int ret = 0;
++	char *tmpbuf;
++	u16 size;
++
++	if ((!devinfo) || (devinfo->ctl_urb == NULL))
++		return false;
++
++	tmpbuf = kmalloc(buflen, GFP_ATOMIC);
++	if (!tmpbuf)
++		return false;
++
++	size = buflen;
++	devinfo->ctl_urb->transfer_buffer_length = size;
++
++	devinfo->ctl_read.wLength = cpu_to_le16p(&size);
++	devinfo->ctl_read.bRequestType = USB_DIR_IN | USB_TYPE_VENDOR |
++		USB_RECIP_INTERFACE;
++	devinfo->ctl_read.bRequest = cmd;
++
++	usb_fill_control_urb(devinfo->ctl_urb,
++		devinfo->usbdev,
++		usb_rcvctrlpipe(devinfo->usbdev, 0),
++		(unsigned char *) &devinfo->ctl_read,
++		(void *) tmpbuf, size,
++		(usb_complete_t)brcmf_usb_sync_complete, devinfo);
++
++	ret = usb_submit_urb(devinfo->ctl_urb, GFP_ATOMIC);
++	if (ret < 0) {
++		brcmf_dbg(ERROR, "usb_submit_urb failed %d\n", ret);
++		kfree(tmpbuf);
++		return false;
++	}
++
++	ret = brcmf_usb_sync_wait(devinfo, BRCMF_USB_SYNC_TIMEOUT);
++	memcpy(buffer, tmpbuf, buflen);
++	kfree(tmpbuf);
++
++	return (ret == 0);
++}
++
++static bool
++brcmf_usb_dlneeded(struct brcmf_usbdev_info *devinfo)
++{
++	struct bootrom_id_le id;
++	u32 chipid, chiprev;
++
++	brcmf_dbg(TRACE, "enter\n");
++
++	if (devinfo == NULL)
++		return false;
++
++	/* Check if firmware downloaded already by querying runtime ID */
++	id.chip = cpu_to_le32(0xDEAD);
++	brcmf_usb_dl_cmd(devinfo, DL_GETVER, &id,
++		sizeof(struct bootrom_id_le));
++
++	chipid = le32_to_cpu(id.chip);
++	chiprev = le32_to_cpu(id.chiprev);
++
++	if ((chipid & 0x4300) == 0x4300)
++		brcmf_dbg(INFO, "chip %x rev 0x%x\n", chipid, chiprev);
++	else
++		brcmf_dbg(INFO, "chip %d rev 0x%x\n", chipid, chiprev);
++	if (chipid == BRCMF_POSTBOOT_ID) {
++		brcmf_dbg(INFO, "firmware already downloaded\n");
++		brcmf_usb_dl_cmd(devinfo, DL_RESETCFG, &id,
++			sizeof(struct bootrom_id_le));
++		return false;
++	} else {
++		devinfo->bus_pub.devid = chipid;
++		devinfo->bus_pub.chiprev = chiprev;
++	}
++	return true;
++}
++
++static int
++brcmf_usb_resetcfg(struct brcmf_usbdev_info *devinfo)
++{
++	struct bootrom_id_le id;
++	u16 wait = 0, wait_time;
++
++	brcmf_dbg(TRACE, "enter\n");
++
++	if (devinfo == NULL)
++		return -EINVAL;
++
++	/* Give dongle chance to boot */
++	wait_time = BRCMF_USB_DLIMAGE_SPINWAIT;
++	while (wait < BRCMF_USB_DLIMAGE_LIMIT) {
++		mdelay(wait_time);
++		wait += wait_time;
++		id.chip = cpu_to_le32(0xDEAD);       /* Get the ID */
++		brcmf_usb_dl_cmd(devinfo, DL_GETVER, &id,
++			sizeof(struct bootrom_id_le));
++		if (id.chip == cpu_to_le32(BRCMF_POSTBOOT_ID))
++			break;
++	}
++
++	if (id.chip == cpu_to_le32(BRCMF_POSTBOOT_ID)) {
++		brcmf_dbg(INFO, "download done %d ms postboot chip 0x%x/rev 0x%x\n",
++			  wait, le32_to_cpu(id.chip), le32_to_cpu(id.chiprev));
++
++		brcmf_usb_dl_cmd(devinfo, DL_RESETCFG, &id,
++			sizeof(struct bootrom_id_le));
++
++		/* XXX this wait may not be necessary */
++		mdelay(BRCMF_USB_RESETCFG_SPINWAIT);
++		return 0;
++	} else {
++		brcmf_dbg(ERROR, "Cannot talk to Dongle. Firmware is not UP, %d ms\n",
++			  wait);
++		return -EINVAL;
++	}
++}
++
++
++static int
++brcmf_usb_dl_send_bulk(struct brcmf_usbdev_info *devinfo, void *buffer, int len)
++{
++	int ret;
++
++	if ((devinfo == NULL) || (devinfo->bulk_urb == NULL))
++		return -EINVAL;
++
++	/* Prepare the URB */
++	usb_fill_bulk_urb(devinfo->bulk_urb, devinfo->usbdev,
++			  devinfo->tx_pipe, buffer, len,
++			  (usb_complete_t)brcmf_usb_sync_complete, devinfo);
++
++	devinfo->bulk_urb->transfer_flags |= URB_ZERO_PACKET;
++
++	ret = usb_submit_urb(devinfo->bulk_urb, GFP_ATOMIC);
++	if (ret) {
++		brcmf_dbg(ERROR, "usb_submit_urb failed %d\n", ret);
++		return ret;
++	}
++	ret = brcmf_usb_sync_wait(devinfo, BRCMF_USB_SYNC_TIMEOUT);
++	return ret;
++}
++
++static int
++brcmf_usb_dl_writeimage(struct brcmf_usbdev_info *devinfo, u8 *fw, int fwlen)
++{
++	unsigned int sendlen, sent, dllen;
++	char *bulkchunk = NULL, *dlpos;
++	struct rdl_state_le state;
++	u32 rdlstate, rdlbytes;
++	int err = 0;
++	brcmf_dbg(TRACE, "fw %p, len %d\n", fw, fwlen);
++
++	bulkchunk = kmalloc(RDL_CHUNK, GFP_ATOMIC);
++	if (bulkchunk == NULL) {
++		err = -ENOMEM;
++		goto fail;
++	}
++
++	/* 1) Prepare USB boot loader for runtime image */
++	brcmf_usb_dl_cmd(devinfo, DL_START, &state,
++			 sizeof(struct rdl_state_le));
++
++	rdlstate = le32_to_cpu(state.state);
++	rdlbytes = le32_to_cpu(state.bytes);
++
++	/* 2) Check we are in the Waiting state */
++	if (rdlstate != DL_WAITING) {
++		brcmf_dbg(ERROR, "Failed to DL_START\n");
++		err = -EINVAL;
++		goto fail;
++	}
++	sent = 0;
++	dlpos = fw;
++	dllen = fwlen;
++
++	/* Get chip id and rev */
++	while (rdlbytes != dllen) {
++		/* Wait until the usb device reports it received all
++		 * the bytes we sent */
++		if ((rdlbytes == sent) && (rdlbytes != dllen)) {
++			if ((dllen-sent) < RDL_CHUNK)
++				sendlen = dllen-sent;
++			else
++				sendlen = RDL_CHUNK;
++
++			/* simply avoid having to send a ZLP by ensuring we
++			 * never have an even
++			 * multiple of 64
++			 */
++			if (!(sendlen % 64))
++				sendlen -= 4;
++
++			/* send data */
++			memcpy(bulkchunk, dlpos, sendlen);
++			if (brcmf_usb_dl_send_bulk(devinfo, bulkchunk,
++						   sendlen)) {
++				brcmf_dbg(ERROR, "send_bulk failed\n");
++				err = -EINVAL;
++				goto fail;
++			}
++
++			dlpos += sendlen;
++			sent += sendlen;
++		}
++		if (!brcmf_usb_dl_cmd(devinfo, DL_GETSTATE, &state,
++				      sizeof(struct rdl_state_le))) {
++			brcmf_dbg(ERROR, "DL_GETSTATE Failed xxxx\n");
++			err = -EINVAL;
++			goto fail;
++		}
++
++		rdlstate = le32_to_cpu(state.state);
++		rdlbytes = le32_to_cpu(state.bytes);
++
++		/* restart if an error is reported */
++		if (rdlstate == DL_BAD_HDR || rdlstate == DL_BAD_CRC) {
++			brcmf_dbg(ERROR, "Bad Hdr or Bad CRC state %d\n",
++				  rdlstate);
++			err = -EINVAL;
++			goto fail;
++		}
++	}
++
++fail:
++	kfree(bulkchunk);
++	brcmf_dbg(TRACE, "err=%d\n", err);
++	return err;
++}
++
++static int brcmf_usb_dlstart(struct brcmf_usbdev_info *devinfo, u8 *fw, int len)
++{
++	int err;
++
++	brcmf_dbg(TRACE, "enter\n");
++
++	if (devinfo == NULL)
++		return -EINVAL;
++
++	if (devinfo->bus_pub.devid == 0xDEAD)
++		return -EINVAL;
++
++	err = brcmf_usb_dl_writeimage(devinfo, fw, len);
++	if (err == 0)
++		devinfo->bus_pub.state = BCMFMAC_USB_STATE_DL_DONE;
++	else
++		devinfo->bus_pub.state = BCMFMAC_USB_STATE_DL_PENDING;
++	brcmf_dbg(TRACE, "exit: err=%d\n", err);
++
++	return err;
++}
++
++static int brcmf_usb_dlrun(struct brcmf_usbdev_info *devinfo)
++{
++	struct rdl_state_le state;
++
++	brcmf_dbg(TRACE, "enter\n");
++	if (!devinfo)
++		return -EINVAL;
++
++	if (devinfo->bus_pub.devid == 0xDEAD)
++		return -EINVAL;
++
++	/* Check we are runnable */
++	brcmf_usb_dl_cmd(devinfo, DL_GETSTATE, &state,
++		sizeof(struct rdl_state_le));
++
++	/* Start the image */
++	if (state.state == cpu_to_le32(DL_RUNNABLE)) {
++		if (!brcmf_usb_dl_cmd(devinfo, DL_GO, &state,
++			sizeof(struct rdl_state_le)))
++			return -ENODEV;
++		if (brcmf_usb_resetcfg(devinfo))
++			return -ENODEV;
++		/* The Dongle may go for re-enumeration. */
++	} else {
++		brcmf_dbg(ERROR, "Dongle not runnable\n");
++		return -EINVAL;
++	}
++	brcmf_dbg(TRACE, "exit\n");
++	return 0;
++}
++
++static bool brcmf_usb_chip_support(int chipid, int chiprev)
++{
++	switch(chipid) {
++	case 43235:
++	case 43236:
++	case 43238:
++		return (chiprev == 3);
++	default:
++		break;
++	}
++	return false;
++}
++
++static int
++brcmf_usb_fw_download(struct brcmf_usbdev_info *devinfo)
++{
++	int devid, chiprev;
++	int err;
++
++	brcmf_dbg(TRACE, "enter\n");
++	if (devinfo == NULL)
++		return -ENODEV;
++
++	devid = devinfo->bus_pub.devid;
++	chiprev = devinfo->bus_pub.chiprev;
++
++	if (!brcmf_usb_chip_support(devid, chiprev)) {
++		brcmf_dbg(ERROR, "unsupported chip %d rev %d\n",
++			  devid, chiprev);
++		return -EINVAL;
++	}
++
++	if (!devinfo->image) {
++		brcmf_dbg(ERROR, "No firmware!\n");
++		return -ENOENT;
++	}
++
++	err = brcmf_usb_dlstart(devinfo,
++		devinfo->image, devinfo->image_len);
++	if (err == 0)
++		err = brcmf_usb_dlrun(devinfo);
++	return err;
++}
++
++
++static void brcmf_usb_detach(const struct brcmf_usbdev *bus_pub)
++{
++	struct brcmf_usbdev_info *devinfo =
++		(struct brcmf_usbdev_info *)bus_pub;
++
++	brcmf_dbg(TRACE, "devinfo %p\n", devinfo);
++
++	/* store the image globally */
++	g_image.data = devinfo->image;
++	g_image.len = devinfo->image_len;
++
++	/* free the URBS */
++	brcmf_usb_free_q(&devinfo->rx_freeq, false);
++	brcmf_usb_free_q(&devinfo->tx_freeq, false);
++
++	usb_free_urb(devinfo->intr_urb);
++	usb_free_urb(devinfo->ctl_urb);
++	usb_free_urb(devinfo->bulk_urb);
++
++	kfree(devinfo->tx_reqs);
++	kfree(devinfo->rx_reqs);
++	kfree(devinfo);
++}
++
++#define TRX_MAGIC       0x30524448      /* "HDR0" */
++#define TRX_VERSION     1               /* Version 1 */
++#define TRX_MAX_LEN     0x3B0000        /* Max length */
++#define TRX_NO_HEADER   1               /* Do not write TRX header */
++#define TRX_MAX_OFFSET  3               /* Max number of individual files */
++#define TRX_UNCOMP_IMAGE        0x20    /* Trx contains uncompressed image */
++
++struct trx_header_le {
++	__le32 magic;		/* "HDR0" */
++	__le32 len;		/* Length of file including header */
++	__le32 crc32;		/* CRC from flag_version to end of file */
++	__le32 flag_version;	/* 0:15 flags, 16:31 version */
++	__le32 offsets[TRX_MAX_OFFSET]; /* Offsets of partitions from start of
++					 * header */
++};
++
++static int check_file(const u8 *headers)
++{
++	struct trx_header_le *trx;
++	int actual_len = -1;
++
++	/* Extract trx header */
++	trx = (struct trx_header_le *) headers;
++	if (trx->magic != cpu_to_le32(TRX_MAGIC))
++		return -1;
++
++	headers += sizeof(struct trx_header_le);
++
++	if (le32_to_cpu(trx->flag_version) & TRX_UNCOMP_IMAGE) {
++		actual_len = le32_to_cpu(trx->offsets[TRX_OFFSETS_DLFWLEN_IDX]);
++		return actual_len + sizeof(struct trx_header_le);
++	}
++	return -1;
++}
++
++static int brcmf_usb_get_fw(struct brcmf_usbdev_info *devinfo)
++{
++	s8 *fwname;
++	const struct firmware *fw;
++	int err;
++
++	devinfo->image = g_image.data;
++	devinfo->image_len = g_image.len;
++
++	/*
++	 * if we have an image we can leave here.
++	 */
++	if (devinfo->image)
++		return 0;
++
++	fwname = BRCMF_USB_43236_FW_NAME;
++
++	err = request_firmware(&fw, fwname, devinfo->dev);
++	if (!fw) {
++		brcmf_dbg(ERROR, "fail to request firmware %s\n", fwname);
++		return err;
++	}
++	if (check_file(fw->data) < 0) {
++		brcmf_dbg(ERROR, "invalid firmware %s\n", fwname);
++		return -EINVAL;
++	}
++
++	devinfo->image = vmalloc(fw->size); /* plus nvram */
++	if (!devinfo->image)
++		return -ENOMEM;
++
++	memcpy(devinfo->image, fw->data, fw->size);
++	devinfo->image_len = fw->size;
++
++	release_firmware(fw);
++	return 0;
++}
++
++
++static
++struct brcmf_usbdev *brcmf_usb_attach(int nrxq, int ntxq, struct device *dev)
++{
++	struct brcmf_usbdev_info *devinfo;
++
++	devinfo = kzalloc(sizeof(struct brcmf_usbdev_info), GFP_ATOMIC);
++	if (devinfo == NULL)
++		return NULL;
++
++	devinfo->bus_pub.nrxq = nrxq;
++	devinfo->rx_low_watermark = nrxq / 2;
++	devinfo->bus_pub.devinfo = devinfo;
++	devinfo->bus_pub.ntxq = ntxq;
++
++	/* flow control when too many tx urbs posted */
++	devinfo->tx_low_watermark = ntxq / 4;
++	devinfo->tx_high_watermark = devinfo->tx_low_watermark * 3;
++	devinfo->dev = dev;
++	devinfo->usbdev = usbdev_probe_info.usb;
++	devinfo->tx_pipe = usbdev_probe_info.tx_pipe;
++	devinfo->rx_pipe = usbdev_probe_info.rx_pipe;
++	devinfo->rx_pipe2 = usbdev_probe_info.rx_pipe2;
++	devinfo->intr_pipe = usbdev_probe_info.intr_pipe;
++
++	devinfo->interval = usbdev_probe_info.interval;
++	devinfo->intr_size = usbdev_probe_info.intr_size;
++
++	memcpy(&devinfo->probe_info, &usbdev_probe_info,
++		sizeof(struct brcmf_usb_probe_info));
++	devinfo->bus_pub.bus_mtu = BRCMF_USB_MAX_PKT_SIZE;
++
++	/* Initialize other structure content */
++	init_waitqueue_head(&devinfo->ioctl_resp_wait);
++
++	/* Initialize the spinlocks */
++	spin_lock_init(&devinfo->qlock);
++
++	INIT_LIST_HEAD(&devinfo->rx_freeq);
++	INIT_LIST_HEAD(&devinfo->rx_postq);
++
++	INIT_LIST_HEAD(&devinfo->tx_freeq);
++	INIT_LIST_HEAD(&devinfo->tx_postq);
++
++	devinfo->rx_reqs = brcmf_usbdev_qinit(&devinfo->rx_freeq, nrxq);
++	if (!devinfo->rx_reqs)
++		goto error;
++
++	devinfo->tx_reqs = brcmf_usbdev_qinit(&devinfo->tx_freeq, ntxq);
++	if (!devinfo->tx_reqs)
++		goto error;
++
++	devinfo->intr_urb = usb_alloc_urb(0, GFP_ATOMIC);
++	if (!devinfo->intr_urb) {
++		brcmf_dbg(ERROR, "usb_alloc_urb (intr) failed\n");
++		goto error;
++	}
++	devinfo->ctl_urb = usb_alloc_urb(0, GFP_ATOMIC);
++	if (!devinfo->ctl_urb) {
++		brcmf_dbg(ERROR, "usb_alloc_urb (ctl) failed\n");
++		goto error;
++	}
++	devinfo->rxctl_deferrespok = 0;
++
++	devinfo->bulk_urb = usb_alloc_urb(0, GFP_ATOMIC);
++	if (!devinfo->bulk_urb) {
++		brcmf_dbg(ERROR, "usb_alloc_urb (bulk) failed\n");
++		goto error;
++	}
++
++	init_waitqueue_head(&devinfo->wait);
++	if (!brcmf_usb_dlneeded(devinfo))
++		return &devinfo->bus_pub;
++
++	brcmf_dbg(TRACE, "start fw downloading\n");
++	if (brcmf_usb_get_fw(devinfo))
++		goto error;
++
++	if (brcmf_usb_fw_download(devinfo))
++		goto error;
++
++	return &devinfo->bus_pub;
++
++error:
++	brcmf_dbg(ERROR, "failed!\n");
++	brcmf_usb_detach(&devinfo->bus_pub);
++	return NULL;
++}
++
++static int brcmf_usb_probe_cb(struct device *dev, const char *desc,
++				u32 bustype, u32 hdrlen)
++{
++	struct brcmf_bus *bus = NULL;
++	struct brcmf_usbdev *bus_pub = NULL;
++	int ret;
++
++
++	bus_pub = brcmf_usb_attach(BRCMF_USB_NRXQ, BRCMF_USB_NTXQ, dev);
++	if (!bus_pub) {
++		ret = -ENODEV;
++		goto fail;
++	}
++
++	bus = kzalloc(sizeof(struct brcmf_bus), GFP_ATOMIC);
++	if (!bus) {
++		ret = -ENOMEM;
++		goto fail;
++	}
++
++	bus_pub->bus = bus;
++	bus->brcmf_bus_txdata = brcmf_usb_tx;
++	bus->brcmf_bus_init = brcmf_usb_up;
++	bus->brcmf_bus_stop = brcmf_usb_down;
++	bus->brcmf_bus_txctl = brcmf_usb_tx_ctlpkt;
++	bus->brcmf_bus_rxctl = brcmf_usb_rx_ctlpkt;
++	bus->type = bustype;
++	bus->bus_priv.usb = bus_pub;
++	dev_set_drvdata(dev, bus);
++
++	/* Attach to the common driver interface */
++	ret = brcmf_attach(hdrlen, dev);
++	if (ret) {
++		brcmf_dbg(ERROR, "dhd_attach failed\n");
++		goto fail;
++	}
++
++	ret = brcmf_bus_start(dev);
++	if (ret == -ENOLINK) {
++		brcmf_dbg(ERROR, "dongle is not responding\n");
++		brcmf_detach(dev);
++		goto fail;
++	}
++
++	return 0;
++fail:
++	/* Release resources in reverse order */
++	if (bus_pub)
++		brcmf_usb_detach(bus_pub);
++	kfree(bus);
++	return ret;
++}
++
++static void
++brcmf_usb_disconnect_cb(struct brcmf_usbdev *bus_pub)
++{
++	if (!bus_pub)
++		return;
++	brcmf_dbg(TRACE, "enter: bus_pub %p\n", bus_pub);
++
++	brcmf_detach(bus_pub->devinfo->dev);
++	kfree(bus_pub->bus);
++	brcmf_usb_detach(bus_pub);
++
++}
++
++static int
++brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
++{
++	int ep;
++	struct usb_endpoint_descriptor *endpoint;
++	int ret = 0;
++	struct usb_device *usb = interface_to_usbdev(intf);
++	int num_of_eps;
++	u8 endpoint_num;
++
++	brcmf_dbg(TRACE, "enter\n");
++
++	usbdev_probe_info.usb = usb;
++	usbdev_probe_info.intf = intf;
++
++	if (id != NULL) {
++		usbdev_probe_info.vid = id->idVendor;
++		usbdev_probe_info.pid = id->idProduct;
++	}
++
++	usb_set_intfdata(intf, &usbdev_probe_info);
++
++	/* Check that the device supports only one configuration */
++	if (usb->descriptor.bNumConfigurations != 1) {
++		ret = -1;
++		goto fail;
++	}
++
++	if (usb->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC) {
++		ret = -1;
++		goto fail;
++	}
++
++	/*
++	 * Only the BDC interface configuration is supported:
++	 *	Device class: USB_CLASS_VENDOR_SPEC
++	 *	if0 class: USB_CLASS_VENDOR_SPEC
++	 *	if0/ep0: control
++	 *	if0/ep1: bulk in
++	 *	if0/ep2: bulk out (ok if swapped with bulk in)
++	 */
++	if (CONFIGDESC(usb)->bNumInterfaces != 1) {
++		ret = -1;
++		goto fail;
++	}
++
++	/* Check interface */
++	if (IFDESC(usb, CONTROL_IF).bInterfaceClass != USB_CLASS_VENDOR_SPEC ||
++	    IFDESC(usb, CONTROL_IF).bInterfaceSubClass != 2 ||
++	    IFDESC(usb, CONTROL_IF).bInterfaceProtocol != 0xff) {
++		brcmf_dbg(ERROR, "invalid control interface: class %d, subclass %d, proto %d\n",
++			  IFDESC(usb, CONTROL_IF).bInterfaceClass,
++			  IFDESC(usb, CONTROL_IF).bInterfaceSubClass,
++			  IFDESC(usb, CONTROL_IF).bInterfaceProtocol);
++		ret = -1;
++		goto fail;
++	}
++
++	/* Check control endpoint */
++	endpoint = &IFEPDESC(usb, CONTROL_IF, 0);
++	if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
++		!= USB_ENDPOINT_XFER_INT) {
++		brcmf_dbg(ERROR, "invalid control endpoint %d\n",
++			  endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK);
++		ret = -1;
++		goto fail;
++	}
++
++	endpoint_num = endpoint->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
++	usbdev_probe_info.intr_pipe = usb_rcvintpipe(usb, endpoint_num);
++
++	usbdev_probe_info.rx_pipe = 0;
++	usbdev_probe_info.rx_pipe2 = 0;
++	usbdev_probe_info.tx_pipe = 0;
++	num_of_eps = IFDESC(usb, BULK_IF).bNumEndpoints - 1;
++
++	/* Check data endpoints and get pipes */
++	for (ep = 1; ep <= num_of_eps; ep++) {
++		endpoint = &IFEPDESC(usb, BULK_IF, ep);
++		if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) !=
++		    USB_ENDPOINT_XFER_BULK) {
++			brcmf_dbg(ERROR, "invalid data endpoint %d\n", ep);
++			ret = -1;
++			goto fail;
++		}
++
++		endpoint_num = endpoint->bEndpointAddress &
++			       USB_ENDPOINT_NUMBER_MASK;
++		if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
++			== USB_DIR_IN) {
++			if (!usbdev_probe_info.rx_pipe) {
++				usbdev_probe_info.rx_pipe =
++					usb_rcvbulkpipe(usb, endpoint_num);
++			} else {
++				usbdev_probe_info.rx_pipe2 =
++					usb_rcvbulkpipe(usb, endpoint_num);
++			}
++		} else {
++			usbdev_probe_info.tx_pipe =
++					usb_sndbulkpipe(usb, endpoint_num);
++		}
++	}
++
++	/* Allocate interrupt URB and data buffer */
++	/* RNDIS says 8-byte intr, our old drivers used 4-byte */
++	if (IFEPDESC(usb, CONTROL_IF, 0).wMaxPacketSize == cpu_to_le16(16))
++		usbdev_probe_info.intr_size = 8;
++	else
++		usbdev_probe_info.intr_size = 4;
++
++	usbdev_probe_info.interval = IFEPDESC(usb, CONTROL_IF, 0).bInterval;
++
++	usbdev_probe_info.device_speed = usb->speed;
++	if (usb->speed == USB_SPEED_HIGH)
++		brcmf_dbg(INFO, "Broadcom high speed USB wireless device detected\n");
++	else
++		brcmf_dbg(INFO, "Broadcom full speed USB wireless device detected\n");
++
++	ret = brcmf_usb_probe_cb(&usb->dev, "", USB_BUS, 0);
++	if (ret)
++		goto fail;
++
++	/* Success */
++	return 0;
++
++fail:
++	brcmf_dbg(ERROR, "failed with errno %d\n", ret);
++	usb_set_intfdata(intf, NULL);
++	return ret;
++
++}
++
++static void
++brcmf_usb_disconnect(struct usb_interface *intf)
++{
++	struct usb_device *usb = interface_to_usbdev(intf);
++
++	brcmf_dbg(TRACE, "enter\n");
++	brcmf_usb_disconnect_cb(brcmf_usb_get_buspub(&usb->dev));
++	usb_set_intfdata(intf, NULL);
++}
++
++/*
++ *	only need to signal the bus being down and update the suspend state.
++ */
++static int brcmf_usb_suspend(struct usb_interface *intf, pm_message_t state)
++{
++	struct usb_device *usb = interface_to_usbdev(intf);
++	struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev);
++
++	brcmf_dbg(TRACE, "enter\n");
++	devinfo->bus_pub.state = BCMFMAC_USB_STATE_DOWN;
++	devinfo->suspend_state = USBOS_SUSPEND_STATE_SUSPENDED;
++	return 0;
++}
++
++/*
++ *	mark suspend state active and crank up the bus.
++ */
++static int brcmf_usb_resume(struct usb_interface *intf)
++{
++	struct usb_device *usb = interface_to_usbdev(intf);
++	struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev);
++
++	brcmf_dbg(TRACE, "enter\n");
++	devinfo->suspend_state = USBOS_SUSPEND_STATE_DEVICE_ACTIVE;
++	brcmf_bus_start(&usb->dev);
++	return 0;
++}
++
++#define BRCMF_USB_VENDOR_ID_BROADCOM	0x0a5c
++#define BRCMF_USB_DEVICE_ID_43236	0xbd17
++#define BRCMF_USB_DEVICE_ID_BCMFW	0x0bdc
++
++static struct usb_device_id brcmf_usb_devid_table[] = {
++	{ USB_DEVICE(BRCMF_USB_VENDOR_ID_BROADCOM, BRCMF_USB_DEVICE_ID_43236) },
++	/* special entry for device with firmware loaded and running */
++	{ USB_DEVICE(BRCMF_USB_VENDOR_ID_BROADCOM, BRCMF_USB_DEVICE_ID_BCMFW) },
++	{ }
++};
++MODULE_DEVICE_TABLE(usb, brcmf_usb_devid_table);
++MODULE_FIRMWARE(BRCMF_USB_43236_FW_NAME);
++
++/* TODO: suspend and resume entries */
++static struct usb_driver brcmf_usbdrvr = {
++	.name = KBUILD_MODNAME,
++	.probe = brcmf_usb_probe,
++	.disconnect = brcmf_usb_disconnect,
++	.id_table = brcmf_usb_devid_table,
++	.suspend = brcmf_usb_suspend,
++	.resume = brcmf_usb_resume,
++	.supports_autosuspend = 1,
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0))
++	.disable_hub_initiated_lpm = 1,
++#endif
++};
++
++void brcmf_usb_exit(void)
++{
++	usb_deregister(&brcmf_usbdrvr);
++	vfree(g_image.data);
++	g_image.data = NULL;
++	g_image.len = 0;
++}
++
++void brcmf_usb_init(void)
++{
++	usb_register(&brcmf_usbdrvr);
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.h b/drivers/net/wireless/brcm80211/brcmfmac/usb.h
+new file mode 100644
+index 0000000..acfa5e8
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.h
+@@ -0,0 +1,61 @@
++/*
++ * Copyright (c) 2011 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++#ifndef BRCMFMAC_USB_H
++#define BRCMFMAC_USB_H
++
++enum brcmf_usb_state {
++	BCMFMAC_USB_STATE_DL_PENDING,
++	BCMFMAC_USB_STATE_DL_DONE,
++	BCMFMAC_USB_STATE_UP,
++	BCMFMAC_USB_STATE_DOWN,
++	BCMFMAC_USB_STATE_PNP_FWDL,
++	BCMFMAC_USB_STATE_DISCONNECT,
++	BCMFMAC_USB_STATE_SLEEP
++};
++
++enum brcmf_usb_pnp_state {
++	BCMFMAC_USB_PNP_DISCONNECT,
++	BCMFMAC_USB_PNP_SLEEP,
++	BCMFMAC_USB_PNP_RESUME,
++};
++
++struct brcmf_stats {
++	u32 tx_ctlpkts;
++	u32 tx_ctlerrs;
++	u32 rx_ctlpkts;
++	u32 rx_ctlerrs;
++};
++
++struct brcmf_usbdev {
++	struct brcmf_bus *bus;
++	struct brcmf_usbdev_info *devinfo;
++	enum brcmf_usb_state state;
++	struct brcmf_stats stats;
++	int ntxq, nrxq, rxsize;
++	u32 bus_mtu;
++	int devid;
++	int chiprev; /* chip revsion number */
++};
++
++/* IO Request Block (IRB) */
++struct brcmf_usbreq {
++	struct list_head list;
++	struct brcmf_usbdev_info *devinfo;
++	struct urb *urb;
++	struct sk_buff  *skb;
++};
++
++#endif /* BRCMFMAC_USB_H */
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb_rdl.h b/drivers/net/wireless/brcm80211/brcmfmac/usb_rdl.h
+new file mode 100644
+index 0000000..0a35c51
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmfmac/usb_rdl.h
+@@ -0,0 +1,75 @@
++/*
++ * Copyright (c) 2011 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef _USB_RDL_H
++#define _USB_RDL_H
++
++/* Control messages: bRequest values */
++#define DL_GETSTATE	0	/* returns the rdl_state_t struct */
++#define DL_CHECK_CRC	1	/* currently unused */
++#define DL_GO		2	/* execute downloaded image */
++#define DL_START	3	/* initialize dl state */
++#define DL_REBOOT	4	/* reboot the device in 2 seconds */
++#define DL_GETVER	5	/* returns the bootrom_id_t struct */
++#define DL_GO_PROTECTED	6	/* execute the downloaded code and set reset
++				 * event to occur in 2 seconds.  It is the
++				 * responsibility of the downloaded code to
++				 * clear this event
++				 */
++#define DL_EXEC		7	/* jump to a supplied address */
++#define DL_RESETCFG	8	/* To support single enum on dongle
++				 * - Not used by bootloader
++				 */
++#define DL_DEFER_RESP_OK 9	/* Potentially defer the response to setup
++				 * if resp unavailable
++				 */
++
++/* states */
++#define DL_WAITING	0	/* waiting to rx first pkt */
++#define DL_READY	1	/* hdr was good, waiting for more of the
++				 * compressed image */
++#define DL_BAD_HDR	2	/* hdr was corrupted */
++#define DL_BAD_CRC	3	/* compressed image was corrupted */
++#define DL_RUNNABLE	4	/* download was successful,waiting for go cmd */
++#define DL_START_FAIL	5	/* failed to initialize correctly */
++#define DL_NVRAM_TOOBIG	6	/* host specified nvram data exceeds DL_NVRAM
++				 * value */
++#define DL_IMAGE_TOOBIG	7	/* download image too big (exceeds DATA_START
++				 *  for rdl) */
++
++struct rdl_state_le {
++	__le32 state;
++	__le32 bytes;
++};
++
++struct bootrom_id_le {
++	__le32 chip;	/* Chip id */
++	__le32 chiprev;	/* Chip rev */
++	__le32 ramsize;	/* Size of  RAM */
++	__le32 remapbase;	/* Current remap base address */
++	__le32 boardtype;	/* Type of board */
++	__le32 boardrev;	/* Board revision */
++};
++
++#define RDL_CHUNK	1500  /* size of each dl transfer */
++
++#define TRX_OFFSETS_DLFWLEN_IDX	0
++#define TRX_OFFSETS_JUMPTO_IDX	1
++#define TRX_OFFSETS_NVM_LEN_IDX	2
++
++#define TRX_OFFSETS_DLBASE_IDX  0
++
++#endif  /* _USB_RDL_H */
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+new file mode 100644
+index 0000000..65e48d7
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+@@ -0,0 +1,3881 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++/* Toplevel file. Relies on dhd_linux.c to send commands to the dongle. */
++
++#undef pr_fmt
++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
++
++#include <linux/kernel.h>
++#include <linux/printk.h>
++#include <linux/if_arp.h>
++#include <linux/sched.h>
++#include <linux/kthread.h>
++#include <linux/netdevice.h>
++#include <linux/bitops.h>
++#include <linux/etherdevice.h>
++#include <linux/ieee80211.h>
++#include <linux/uaccess.h>
++#include <net/cfg80211.h>
++
++#include <brcmu_utils.h>
++#include <defs.h>
++#include <brcmu_wifi.h>
++#include "dhd.h"
++#include "wl_cfg80211.h"
++
++#define BRCMF_ASSOC_PARAMS_FIXED_SIZE \
++	(sizeof(struct brcmf_assoc_params_le) - sizeof(u16))
++
++static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255};
++
++static u32 brcmf_dbg_level = WL_DBG_ERR;
++
++static void brcmf_set_drvdata(struct brcmf_cfg80211_dev *dev, void *data)
++{
++	dev->driver_data = data;
++}
++
++static void *brcmf_get_drvdata(struct brcmf_cfg80211_dev *dev)
++{
++	void *data = NULL;
++
++	if (dev)
++		data = dev->driver_data;
++	return data;
++}
++
++static
++struct brcmf_cfg80211_priv *brcmf_priv_get(struct brcmf_cfg80211_dev *cfg_dev)
++{
++	struct brcmf_cfg80211_iface *ci = brcmf_get_drvdata(cfg_dev);
++	return ci->cfg_priv;
++}
++
++static bool check_sys_up(struct wiphy *wiphy)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
++	if (!test_bit(WL_STATUS_READY, &cfg_priv->status)) {
++		WL_INFO("device is not ready : status (%d)\n",
++			(int)cfg_priv->status);
++		return false;
++	}
++	return true;
++}
++
++#define CHAN2G(_channel, _freq, _flags) {			\
++	.band			= IEEE80211_BAND_2GHZ,		\
++	.center_freq		= (_freq),			\
++	.hw_value		= (_channel),			\
++	.flags			= (_flags),			\
++	.max_antenna_gain	= 0,				\
++	.max_power		= 30,				\
++}
++
++#define CHAN5G(_channel, _flags) {				\
++	.band			= IEEE80211_BAND_5GHZ,		\
++	.center_freq		= 5000 + (5 * (_channel)),	\
++	.hw_value		= (_channel),			\
++	.flags			= (_flags),			\
++	.max_antenna_gain	= 0,				\
++	.max_power		= 30,				\
++}
++
++#define RATE_TO_BASE100KBPS(rate)   (((rate) * 10) / 2)
++#define RATETAB_ENT(_rateid, _flags) \
++	{                                                               \
++		.bitrate        = RATE_TO_BASE100KBPS(_rateid),     \
++		.hw_value       = (_rateid),                            \
++		.flags          = (_flags),                             \
++	}
++
++static struct ieee80211_rate __wl_rates[] = {
++	RATETAB_ENT(BRCM_RATE_1M, 0),
++	RATETAB_ENT(BRCM_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
++	RATETAB_ENT(BRCM_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
++	RATETAB_ENT(BRCM_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
++	RATETAB_ENT(BRCM_RATE_6M, 0),
++	RATETAB_ENT(BRCM_RATE_9M, 0),
++	RATETAB_ENT(BRCM_RATE_12M, 0),
++	RATETAB_ENT(BRCM_RATE_18M, 0),
++	RATETAB_ENT(BRCM_RATE_24M, 0),
++	RATETAB_ENT(BRCM_RATE_36M, 0),
++	RATETAB_ENT(BRCM_RATE_48M, 0),
++	RATETAB_ENT(BRCM_RATE_54M, 0),
++};
++
++#define wl_a_rates		(__wl_rates + 4)
++#define wl_a_rates_size	8
++#define wl_g_rates		(__wl_rates + 0)
++#define wl_g_rates_size	12
++
++static struct ieee80211_channel __wl_2ghz_channels[] = {
++	CHAN2G(1, 2412, 0),
++	CHAN2G(2, 2417, 0),
++	CHAN2G(3, 2422, 0),
++	CHAN2G(4, 2427, 0),
++	CHAN2G(5, 2432, 0),
++	CHAN2G(6, 2437, 0),
++	CHAN2G(7, 2442, 0),
++	CHAN2G(8, 2447, 0),
++	CHAN2G(9, 2452, 0),
++	CHAN2G(10, 2457, 0),
++	CHAN2G(11, 2462, 0),
++	CHAN2G(12, 2467, 0),
++	CHAN2G(13, 2472, 0),
++	CHAN2G(14, 2484, 0),
++};
++
++static struct ieee80211_channel __wl_5ghz_a_channels[] = {
++	CHAN5G(34, 0), CHAN5G(36, 0),
++	CHAN5G(38, 0), CHAN5G(40, 0),
++	CHAN5G(42, 0), CHAN5G(44, 0),
++	CHAN5G(46, 0), CHAN5G(48, 0),
++	CHAN5G(52, 0), CHAN5G(56, 0),
++	CHAN5G(60, 0), CHAN5G(64, 0),
++	CHAN5G(100, 0), CHAN5G(104, 0),
++	CHAN5G(108, 0), CHAN5G(112, 0),
++	CHAN5G(116, 0), CHAN5G(120, 0),
++	CHAN5G(124, 0), CHAN5G(128, 0),
++	CHAN5G(132, 0), CHAN5G(136, 0),
++	CHAN5G(140, 0), CHAN5G(149, 0),
++	CHAN5G(153, 0), CHAN5G(157, 0),
++	CHAN5G(161, 0), CHAN5G(165, 0),
++	CHAN5G(184, 0), CHAN5G(188, 0),
++	CHAN5G(192, 0), CHAN5G(196, 0),
++	CHAN5G(200, 0), CHAN5G(204, 0),
++	CHAN5G(208, 0), CHAN5G(212, 0),
++	CHAN5G(216, 0),
++};
++
++static struct ieee80211_channel __wl_5ghz_n_channels[] = {
++	CHAN5G(32, 0), CHAN5G(34, 0),
++	CHAN5G(36, 0), CHAN5G(38, 0),
++	CHAN5G(40, 0), CHAN5G(42, 0),
++	CHAN5G(44, 0), CHAN5G(46, 0),
++	CHAN5G(48, 0), CHAN5G(50, 0),
++	CHAN5G(52, 0), CHAN5G(54, 0),
++	CHAN5G(56, 0), CHAN5G(58, 0),
++	CHAN5G(60, 0), CHAN5G(62, 0),
++	CHAN5G(64, 0), CHAN5G(66, 0),
++	CHAN5G(68, 0), CHAN5G(70, 0),
++	CHAN5G(72, 0), CHAN5G(74, 0),
++	CHAN5G(76, 0), CHAN5G(78, 0),
++	CHAN5G(80, 0), CHAN5G(82, 0),
++	CHAN5G(84, 0), CHAN5G(86, 0),
++	CHAN5G(88, 0), CHAN5G(90, 0),
++	CHAN5G(92, 0), CHAN5G(94, 0),
++	CHAN5G(96, 0), CHAN5G(98, 0),
++	CHAN5G(100, 0), CHAN5G(102, 0),
++	CHAN5G(104, 0), CHAN5G(106, 0),
++	CHAN5G(108, 0), CHAN5G(110, 0),
++	CHAN5G(112, 0), CHAN5G(114, 0),
++	CHAN5G(116, 0), CHAN5G(118, 0),
++	CHAN5G(120, 0), CHAN5G(122, 0),
++	CHAN5G(124, 0), CHAN5G(126, 0),
++	CHAN5G(128, 0), CHAN5G(130, 0),
++	CHAN5G(132, 0), CHAN5G(134, 0),
++	CHAN5G(136, 0), CHAN5G(138, 0),
++	CHAN5G(140, 0), CHAN5G(142, 0),
++	CHAN5G(144, 0), CHAN5G(145, 0),
++	CHAN5G(146, 0), CHAN5G(147, 0),
++	CHAN5G(148, 0), CHAN5G(149, 0),
++	CHAN5G(150, 0), CHAN5G(151, 0),
++	CHAN5G(152, 0), CHAN5G(153, 0),
++	CHAN5G(154, 0), CHAN5G(155, 0),
++	CHAN5G(156, 0), CHAN5G(157, 0),
++	CHAN5G(158, 0), CHAN5G(159, 0),
++	CHAN5G(160, 0), CHAN5G(161, 0),
++	CHAN5G(162, 0), CHAN5G(163, 0),
++	CHAN5G(164, 0), CHAN5G(165, 0),
++	CHAN5G(166, 0), CHAN5G(168, 0),
++	CHAN5G(170, 0), CHAN5G(172, 0),
++	CHAN5G(174, 0), CHAN5G(176, 0),
++	CHAN5G(178, 0), CHAN5G(180, 0),
++	CHAN5G(182, 0), CHAN5G(184, 0),
++	CHAN5G(186, 0), CHAN5G(188, 0),
++	CHAN5G(190, 0), CHAN5G(192, 0),
++	CHAN5G(194, 0), CHAN5G(196, 0),
++	CHAN5G(198, 0), CHAN5G(200, 0),
++	CHAN5G(202, 0), CHAN5G(204, 0),
++	CHAN5G(206, 0), CHAN5G(208, 0),
++	CHAN5G(210, 0), CHAN5G(212, 0),
++	CHAN5G(214, 0), CHAN5G(216, 0),
++	CHAN5G(218, 0), CHAN5G(220, 0),
++	CHAN5G(222, 0), CHAN5G(224, 0),
++	CHAN5G(226, 0), CHAN5G(228, 0),
++};
++
++static struct ieee80211_supported_band __wl_band_2ghz = {
++	.band = IEEE80211_BAND_2GHZ,
++	.channels = __wl_2ghz_channels,
++	.n_channels = ARRAY_SIZE(__wl_2ghz_channels),
++	.bitrates = wl_g_rates,
++	.n_bitrates = wl_g_rates_size,
++};
++
++static struct ieee80211_supported_band __wl_band_5ghz_a = {
++	.band = IEEE80211_BAND_5GHZ,
++	.channels = __wl_5ghz_a_channels,
++	.n_channels = ARRAY_SIZE(__wl_5ghz_a_channels),
++	.bitrates = wl_a_rates,
++	.n_bitrates = wl_a_rates_size,
++};
++
++static struct ieee80211_supported_band __wl_band_5ghz_n = {
++	.band = IEEE80211_BAND_5GHZ,
++	.channels = __wl_5ghz_n_channels,
++	.n_channels = ARRAY_SIZE(__wl_5ghz_n_channels),
++	.bitrates = wl_a_rates,
++	.n_bitrates = wl_a_rates_size,
++};
++
++static const u32 __wl_cipher_suites[] = {
++	WLAN_CIPHER_SUITE_WEP40,
++	WLAN_CIPHER_SUITE_WEP104,
++	WLAN_CIPHER_SUITE_TKIP,
++	WLAN_CIPHER_SUITE_CCMP,
++	WLAN_CIPHER_SUITE_AES_CMAC,
++};
++
++/* tag_ID/length/value_buffer tuple */
++struct brcmf_tlv {
++	u8 id;
++	u8 len;
++	u8 data[1];
++};
++
++/* Quarter dBm units to mW
++ * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153
++ * Table is offset so the last entry is largest mW value that fits in
++ * a u16.
++ */
++
++#define QDBM_OFFSET 153		/* Offset for first entry */
++#define QDBM_TABLE_LEN 40	/* Table size */
++
++/* Smallest mW value that will round up to the first table entry, QDBM_OFFSET.
++ * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2
++ */
++#define QDBM_TABLE_LOW_BOUND 6493	/* Low bound */
++
++/* Largest mW value that will round down to the last table entry,
++ * QDBM_OFFSET + QDBM_TABLE_LEN-1.
++ * Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) +
++ * mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2.
++ */
++#define QDBM_TABLE_HIGH_BOUND 64938	/* High bound */
++
++static const u16 nqdBm_to_mW_map[QDBM_TABLE_LEN] = {
++/* qdBm:	+0	+1	+2	+3	+4	+5	+6	+7 */
++/* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000,
++/* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849,
++/* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119,
++/* 177: */ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811,
++/* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096
++};
++
++static u16 brcmf_qdbm_to_mw(u8 qdbm)
++{
++	uint factor = 1;
++	int idx = qdbm - QDBM_OFFSET;
++
++	if (idx >= QDBM_TABLE_LEN)
++		/* clamp to max u16 mW value */
++		return 0xFFFF;
++
++	/* scale the qdBm index up to the range of the table 0-40
++	 * where an offset of 40 qdBm equals a factor of 10 mW.
++	 */
++	while (idx < 0) {
++		idx += 40;
++		factor *= 10;
++	}
++
++	/* return the mW value scaled down to the correct factor of 10,
++	 * adding in factor/2 to get proper rounding.
++	 */
++	return (nqdBm_to_mW_map[idx] + factor / 2) / factor;
++}
++
++static u8 brcmf_mw_to_qdbm(u16 mw)
++{
++	u8 qdbm;
++	int offset;
++	uint mw_uint = mw;
++	uint boundary;
++
++	/* handle boundary case */
++	if (mw_uint <= 1)
++		return 0;
++
++	offset = QDBM_OFFSET;
++
++	/* move mw into the range of the table */
++	while (mw_uint < QDBM_TABLE_LOW_BOUND) {
++		mw_uint *= 10;
++		offset -= 40;
++	}
++
++	for (qdbm = 0; qdbm < QDBM_TABLE_LEN - 1; qdbm++) {
++		boundary = nqdBm_to_mW_map[qdbm] + (nqdBm_to_mW_map[qdbm + 1] -
++						    nqdBm_to_mW_map[qdbm]) / 2;
++		if (mw_uint < boundary)
++			break;
++	}
++
++	qdbm += (u8) offset;
++
++	return qdbm;
++}
++
++/* function for reading/writing a single u32 from/to the dongle */
++static int
++brcmf_exec_dcmd_u32(struct net_device *ndev, u32 cmd, u32 *par)
++{
++	int err;
++	__le32 par_le = cpu_to_le32(*par);
++
++	err = brcmf_exec_dcmd(ndev, cmd, &par_le, sizeof(__le32));
++	*par = le32_to_cpu(par_le);
++
++	return err;
++}
++
++static void convert_key_from_CPU(struct brcmf_wsec_key *key,
++				 struct brcmf_wsec_key_le *key_le)
++{
++	key_le->index = cpu_to_le32(key->index);
++	key_le->len = cpu_to_le32(key->len);
++	key_le->algo = cpu_to_le32(key->algo);
++	key_le->flags = cpu_to_le32(key->flags);
++	key_le->rxiv.hi = cpu_to_le32(key->rxiv.hi);
++	key_le->rxiv.lo = cpu_to_le16(key->rxiv.lo);
++	key_le->iv_initialized = cpu_to_le32(key->iv_initialized);
++	memcpy(key_le->data, key->data, sizeof(key->data));
++	memcpy(key_le->ea, key->ea, sizeof(key->ea));
++}
++
++static int send_key_to_dongle(struct net_device *ndev,
++			      struct brcmf_wsec_key *key)
++{
++	int err;
++	struct brcmf_wsec_key_le key_le;
++
++	convert_key_from_CPU(key, &key_le);
++	err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_KEY, &key_le, sizeof(key_le));
++	if (err)
++		WL_ERR("WLC_SET_KEY error (%d)\n", err);
++	return err;
++}
++
++static s32
++brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
++			 enum nl80211_iftype type, u32 *flags,
++			 struct vif_params *params)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
++	struct wireless_dev *wdev;
++	s32 infra = 0;
++	s32 err = 0;
++
++	WL_TRACE("Enter\n");
++	if (!check_sys_up(wiphy))
++		return -EIO;
++
++	switch (type) {
++	case NL80211_IFTYPE_MONITOR:
++	case NL80211_IFTYPE_WDS:
++		WL_ERR("type (%d) : currently we do not support this type\n",
++		       type);
++		return -EOPNOTSUPP;
++	case NL80211_IFTYPE_ADHOC:
++		cfg_priv->conf->mode = WL_MODE_IBSS;
++		infra = 0;
++		break;
++	case NL80211_IFTYPE_STATION:
++		cfg_priv->conf->mode = WL_MODE_BSS;
++		infra = 1;
++		break;
++	default:
++		err = -EINVAL;
++		goto done;
++	}
++
++	err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &infra);
++	if (err) {
++		WL_ERR("WLC_SET_INFRA error (%d)\n", err);
++		err = -EAGAIN;
++	} else {
++		wdev = ndev->ieee80211_ptr;
++		wdev->iftype = type;
++	}
++
++	WL_INFO("IF Type = %s\n",
++		(cfg_priv->conf->mode == WL_MODE_IBSS) ? "Adhoc" : "Infra");
++
++done:
++	WL_TRACE("Exit\n");
++
++	return err;
++}
++
++static s32 brcmf_dev_intvar_set(struct net_device *ndev, s8 *name, s32 val)
++{
++	s8 buf[BRCMF_DCMD_SMLEN];
++	u32 len;
++	s32 err = 0;
++	__le32 val_le;
++
++	val_le = cpu_to_le32(val);
++	len = brcmf_c_mkiovar(name, (char *)(&val_le), sizeof(val_le), buf,
++			    sizeof(buf));
++	BUG_ON(!len);
++
++	err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, buf, len);
++	if (err)
++		WL_ERR("error (%d)\n", err);
++
++	return err;
++}
++
++static s32
++brcmf_dev_intvar_get(struct net_device *ndev, s8 *name, s32 *retval)
++{
++	union {
++		s8 buf[BRCMF_DCMD_SMLEN];
++		__le32 val;
++	} var;
++	u32 len;
++	u32 data_null;
++	s32 err = 0;
++
++	len =
++	    brcmf_c_mkiovar(name, (char *)(&data_null), 0, (char *)(&var),
++			sizeof(var.buf));
++	BUG_ON(!len);
++	err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, &var, len);
++	if (err)
++		WL_ERR("error (%d)\n", err);
++
++	*retval = le32_to_cpu(var.val);
++
++	return err;
++}
++
++static void brcmf_set_mpc(struct net_device *ndev, int mpc)
++{
++	s32 err = 0;
++	struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
++
++	if (test_bit(WL_STATUS_READY, &cfg_priv->status)) {
++		err = brcmf_dev_intvar_set(ndev, "mpc", mpc);
++		if (err) {
++			WL_ERR("fail to set mpc\n");
++			return;
++		}
++		WL_INFO("MPC : %d\n", mpc);
++	}
++}
++
++static void wl_iscan_prep(struct brcmf_scan_params_le *params_le,
++			  struct brcmf_ssid *ssid)
++{
++	memcpy(params_le->bssid, ether_bcast, ETH_ALEN);
++	params_le->bss_type = DOT11_BSSTYPE_ANY;
++	params_le->scan_type = 0;
++	params_le->channel_num = 0;
++	params_le->nprobes = cpu_to_le32(-1);
++	params_le->active_time = cpu_to_le32(-1);
++	params_le->passive_time = cpu_to_le32(-1);
++	params_le->home_time = cpu_to_le32(-1);
++	if (ssid && ssid->SSID_len)
++		memcpy(&params_le->ssid_le, ssid, sizeof(struct brcmf_ssid));
++}
++
++static s32
++brcmf_dev_iovar_setbuf(struct net_device *ndev, s8 * iovar, void *param,
++		    s32 paramlen, void *bufptr, s32 buflen)
++{
++	s32 iolen;
++
++	iolen = brcmf_c_mkiovar(iovar, param, paramlen, bufptr, buflen);
++	BUG_ON(!iolen);
++
++	return brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, bufptr, iolen);
++}
++
++static s32
++brcmf_dev_iovar_getbuf(struct net_device *ndev, s8 * iovar, void *param,
++		    s32 paramlen, void *bufptr, s32 buflen)
++{
++	s32 iolen;
++
++	iolen = brcmf_c_mkiovar(iovar, param, paramlen, bufptr, buflen);
++	BUG_ON(!iolen);
++
++	return brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, bufptr, buflen);
++}
++
++static s32
++brcmf_run_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan,
++		struct brcmf_ssid *ssid, u16 action)
++{
++	s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE +
++			  offsetof(struct brcmf_iscan_params_le, params_le);
++	struct brcmf_iscan_params_le *params;
++	s32 err = 0;
++
++	if (ssid && ssid->SSID_len)
++		params_size += sizeof(struct brcmf_ssid);
++	params = kzalloc(params_size, GFP_KERNEL);
++	if (!params)
++		return -ENOMEM;
++	BUG_ON(params_size >= BRCMF_DCMD_SMLEN);
++
++	wl_iscan_prep(&params->params_le, ssid);
++
++	params->version = cpu_to_le32(BRCMF_ISCAN_REQ_VERSION);
++	params->action = cpu_to_le16(action);
++	params->scan_duration = cpu_to_le16(0);
++
++	err = brcmf_dev_iovar_setbuf(iscan->ndev, "iscan", params, params_size,
++				     iscan->dcmd_buf, BRCMF_DCMD_SMLEN);
++	if (err) {
++		if (err == -EBUSY)
++			WL_INFO("system busy : iscan canceled\n");
++		else
++			WL_ERR("error (%d)\n", err);
++	}
++
++	kfree(params);
++	return err;
++}
++
++static s32 brcmf_do_iscan(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
++	struct net_device *ndev = cfg_to_ndev(cfg_priv);
++	struct brcmf_ssid ssid;
++	__le32 passive_scan;
++	s32 err = 0;
++
++	/* Broadcast scan by default */
++	memset(&ssid, 0, sizeof(ssid));
++
++	iscan->state = WL_ISCAN_STATE_SCANING;
++
++	passive_scan = cfg_priv->active_scan ? 0 : cpu_to_le32(1);
++	err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCMF_C_SET_PASSIVE_SCAN,
++			&passive_scan, sizeof(passive_scan));
++	if (err) {
++		WL_ERR("error (%d)\n", err);
++		return err;
++	}
++	brcmf_set_mpc(ndev, 0);
++	cfg_priv->iscan_kickstart = true;
++	err = brcmf_run_iscan(iscan, &ssid, BRCMF_SCAN_ACTION_START);
++	if (err) {
++		brcmf_set_mpc(ndev, 1);
++		cfg_priv->iscan_kickstart = false;
++		return err;
++	}
++	mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
++	iscan->timer_on = 1;
++	return err;
++}
++
++static s32
++__brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
++		   struct cfg80211_scan_request *request,
++		   struct cfg80211_ssid *this_ssid)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
++	struct cfg80211_ssid *ssids;
++	struct brcmf_cfg80211_scan_req *sr = cfg_priv->scan_req_int;
++	__le32 passive_scan;
++	bool iscan_req;
++	bool spec_scan;
++	s32 err = 0;
++	u32 SSID_len;
++
++	if (test_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
++		WL_ERR("Scanning already : status (%lu)\n", cfg_priv->status);
++		return -EAGAIN;
++	}
++	if (test_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status)) {
++		WL_ERR("Scanning being aborted : status (%lu)\n",
++		       cfg_priv->status);
++		return -EAGAIN;
++	}
++	if (test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) {
++		WL_ERR("Connecting : status (%lu)\n",
++		       cfg_priv->status);
++		return -EAGAIN;
++	}
++
++	iscan_req = false;
++	spec_scan = false;
++	if (request) {
++		/* scan bss */
++		ssids = request->ssids;
++		if (cfg_priv->iscan_on && (!ssids || !ssids->ssid_len))
++			iscan_req = true;
++	} else {
++		/* scan in ibss */
++		/* we don't do iscan in ibss */
++		ssids = this_ssid;
++	}
++
++	cfg_priv->scan_request = request;
++	set_bit(WL_STATUS_SCANNING, &cfg_priv->status);
++	if (iscan_req) {
++		err = brcmf_do_iscan(cfg_priv);
++		if (!err)
++			return err;
++		else
++			goto scan_out;
++	} else {
++		WL_SCAN("ssid \"%s\", ssid_len (%d)\n",
++		       ssids->ssid, ssids->ssid_len);
++		memset(&sr->ssid_le, 0, sizeof(sr->ssid_le));
++		SSID_len = min_t(u8, sizeof(sr->ssid_le.SSID), ssids->ssid_len);
++		sr->ssid_le.SSID_len = cpu_to_le32(0);
++		if (SSID_len) {
++			memcpy(sr->ssid_le.SSID, ssids->ssid, SSID_len);
++			sr->ssid_le.SSID_len = cpu_to_le32(SSID_len);
++			spec_scan = true;
++		} else {
++			WL_SCAN("Broadcast scan\n");
++		}
++
++		passive_scan = cfg_priv->active_scan ? 0 : cpu_to_le32(1);
++		err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_PASSIVE_SCAN,
++				&passive_scan, sizeof(passive_scan));
++		if (err) {
++			WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
++			goto scan_out;
++		}
++		brcmf_set_mpc(ndev, 0);
++		err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN, &sr->ssid_le,
++				      sizeof(sr->ssid_le));
++		if (err) {
++			if (err == -EBUSY)
++				WL_INFO("system busy : scan for \"%s\" "
++					"canceled\n", sr->ssid_le.SSID);
++			else
++				WL_ERR("WLC_SCAN error (%d)\n", err);
++
++			brcmf_set_mpc(ndev, 1);
++			goto scan_out;
++		}
++	}
++
++	return 0;
++
++scan_out:
++	clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
++	cfg_priv->scan_request = NULL;
++	return err;
++}
++
++static s32
++brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
++		 struct cfg80211_scan_request *request)
++{
++	s32 err = 0;
++
++	WL_TRACE("Enter\n");
++
++	if (!check_sys_up(wiphy))
++		return -EIO;
++
++	err = __brcmf_cfg80211_scan(wiphy, ndev, request, NULL);
++	if (err)
++		WL_ERR("scan error (%d)\n", err);
++
++	WL_TRACE("Exit\n");
++	return err;
++}
++
++static s32 brcmf_set_rts(struct net_device *ndev, u32 rts_threshold)
++{
++	s32 err = 0;
++
++	err = brcmf_dev_intvar_set(ndev, "rtsthresh", rts_threshold);
++	if (err)
++		WL_ERR("Error (%d)\n", err);
++
++	return err;
++}
++
++static s32 brcmf_set_frag(struct net_device *ndev, u32 frag_threshold)
++{
++	s32 err = 0;
++
++	err = brcmf_dev_intvar_set(ndev, "fragthresh", frag_threshold);
++	if (err)
++		WL_ERR("Error (%d)\n", err);
++
++	return err;
++}
++
++static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l)
++{
++	s32 err = 0;
++	u32 cmd = (l ? BRCM_SET_LRL : BRCM_SET_SRL);
++
++	err = brcmf_exec_dcmd_u32(ndev, cmd, &retry);
++	if (err) {
++		WL_ERR("cmd (%d) , error (%d)\n", cmd, err);
++		return err;
++	}
++	return err;
++}
++
++static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
++	struct net_device *ndev = cfg_to_ndev(cfg_priv);
++	s32 err = 0;
++
++	WL_TRACE("Enter\n");
++	if (!check_sys_up(wiphy))
++		return -EIO;
++
++	if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
++	    (cfg_priv->conf->rts_threshold != wiphy->rts_threshold)) {
++		cfg_priv->conf->rts_threshold = wiphy->rts_threshold;
++		err = brcmf_set_rts(ndev, cfg_priv->conf->rts_threshold);
++		if (!err)
++			goto done;
++	}
++	if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
++	    (cfg_priv->conf->frag_threshold != wiphy->frag_threshold)) {
++		cfg_priv->conf->frag_threshold = wiphy->frag_threshold;
++		err = brcmf_set_frag(ndev, cfg_priv->conf->frag_threshold);
++		if (!err)
++			goto done;
++	}
++	if (changed & WIPHY_PARAM_RETRY_LONG
++	    && (cfg_priv->conf->retry_long != wiphy->retry_long)) {
++		cfg_priv->conf->retry_long = wiphy->retry_long;
++		err = brcmf_set_retry(ndev, cfg_priv->conf->retry_long, true);
++		if (!err)
++			goto done;
++	}
++	if (changed & WIPHY_PARAM_RETRY_SHORT
++	    && (cfg_priv->conf->retry_short != wiphy->retry_short)) {
++		cfg_priv->conf->retry_short = wiphy->retry_short;
++		err = brcmf_set_retry(ndev, cfg_priv->conf->retry_short, false);
++		if (!err)
++			goto done;
++	}
++
++done:
++	WL_TRACE("Exit\n");
++	return err;
++}
++
++static void *brcmf_read_prof(struct brcmf_cfg80211_priv *cfg_priv, s32 item)
++{
++	switch (item) {
++	case WL_PROF_SEC:
++		return &cfg_priv->profile->sec;
++	case WL_PROF_BSSID:
++		return &cfg_priv->profile->bssid;
++	case WL_PROF_SSID:
++		return &cfg_priv->profile->ssid;
++	}
++	WL_ERR("invalid item (%d)\n", item);
++	return NULL;
++}
++
++static s32
++brcmf_update_prof(struct brcmf_cfg80211_priv *cfg_priv,
++		  const struct brcmf_event_msg *e, void *data, s32 item)
++{
++	s32 err = 0;
++	struct brcmf_ssid *ssid;
++
++	switch (item) {
++	case WL_PROF_SSID:
++		ssid = (struct brcmf_ssid *) data;
++		memset(cfg_priv->profile->ssid.SSID, 0,
++		       sizeof(cfg_priv->profile->ssid.SSID));
++		memcpy(cfg_priv->profile->ssid.SSID,
++		       ssid->SSID, ssid->SSID_len);
++		cfg_priv->profile->ssid.SSID_len = ssid->SSID_len;
++		break;
++	case WL_PROF_BSSID:
++		if (data)
++			memcpy(cfg_priv->profile->bssid, data, ETH_ALEN);
++		else
++			memset(cfg_priv->profile->bssid, 0, ETH_ALEN);
++		break;
++	case WL_PROF_SEC:
++		memcpy(&cfg_priv->profile->sec, data,
++		       sizeof(cfg_priv->profile->sec));
++		break;
++	case WL_PROF_BEACONINT:
++		cfg_priv->profile->beacon_interval = *(u16 *)data;
++		break;
++	case WL_PROF_DTIMPERIOD:
++		cfg_priv->profile->dtim_period = *(u8 *)data;
++		break;
++	default:
++		WL_ERR("unsupported item (%d)\n", item);
++		err = -EOPNOTSUPP;
++		break;
++	}
++
++	return err;
++}
++
++static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof)
++{
++	memset(prof, 0, sizeof(*prof));
++}
++
++static void brcmf_ch_to_chanspec(int ch, struct brcmf_join_params *join_params,
++	size_t *join_params_size)
++{
++	u16 chanspec = 0;
++
++	if (ch != 0) {
++		if (ch <= CH_MAX_2G_CHANNEL)
++			chanspec |= WL_CHANSPEC_BAND_2G;
++		else
++			chanspec |= WL_CHANSPEC_BAND_5G;
++
++		chanspec |= WL_CHANSPEC_BW_20;
++		chanspec |= WL_CHANSPEC_CTL_SB_NONE;
++
++		*join_params_size += BRCMF_ASSOC_PARAMS_FIXED_SIZE +
++				     sizeof(u16);
++
++		chanspec |= (ch & WL_CHANSPEC_CHAN_MASK);
++		join_params->params_le.chanspec_list[0] = cpu_to_le16(chanspec);
++		join_params->params_le.chanspec_num = cpu_to_le32(1);
++
++		WL_CONN("join_params->params.chanspec_list[0]= %#X,"
++			"channel %d, chanspec %#X\n",
++			chanspec, ch, chanspec);
++	}
++}
++
++static void brcmf_link_down(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	struct net_device *ndev = NULL;
++	s32 err = 0;
++
++	WL_TRACE("Enter\n");
++
++	if (cfg_priv->link_up) {
++		ndev = cfg_to_ndev(cfg_priv);
++		WL_INFO("Call WLC_DISASSOC to stop excess roaming\n ");
++		err = brcmf_exec_dcmd(ndev, BRCMF_C_DISASSOC, NULL, 0);
++		if (err)
++			WL_ERR("WLC_DISASSOC failed (%d)\n", err);
++		cfg_priv->link_up = false;
++	}
++	WL_TRACE("Exit\n");
++}
++
++static s32
++brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
++		      struct cfg80211_ibss_params *params)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
++	struct brcmf_join_params join_params;
++	size_t join_params_size = 0;
++	s32 err = 0;
++	s32 wsec = 0;
++	s32 bcnprd;
++	struct brcmf_ssid ssid;
++
++	WL_TRACE("Enter\n");
++	if (!check_sys_up(wiphy))
++		return -EIO;
++
++	if (params->ssid)
++		WL_CONN("SSID: %s\n", params->ssid);
++	else {
++		WL_CONN("SSID: NULL, Not supported\n");
++		return -EOPNOTSUPP;
++	}
++
++	set_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
++
++	if (params->bssid)
++		WL_CONN("BSSID: %02X %02X %02X %02X %02X %02X\n",
++		params->bssid[0], params->bssid[1], params->bssid[2],
++		params->bssid[3], params->bssid[4], params->bssid[5]);
++	else
++		WL_CONN("No BSSID specified\n");
++
++	if (params->channel)
++		WL_CONN("channel: %d\n", params->channel->center_freq);
++	else
++		WL_CONN("no channel specified\n");
++
++	if (params->channel_fixed)
++		WL_CONN("fixed channel required\n");
++	else
++		WL_CONN("no fixed channel required\n");
++
++	if (params->ie && params->ie_len)
++		WL_CONN("ie len: %d\n", params->ie_len);
++	else
++		WL_CONN("no ie specified\n");
++
++	if (params->beacon_interval)
++		WL_CONN("beacon interval: %d\n", params->beacon_interval);
++	else
++		WL_CONN("no beacon interval specified\n");
++
++	if (params->basic_rates)
++		WL_CONN("basic rates: %08X\n", params->basic_rates);
++	else
++		WL_CONN("no basic rates specified\n");
++
++	if (params->privacy)
++		WL_CONN("privacy required\n");
++	else
++		WL_CONN("no privacy required\n");
++
++	/* Configure Privacy for starter */
++	if (params->privacy)
++		wsec |= WEP_ENABLED;
++
++	err = brcmf_dev_intvar_set(ndev, "wsec", wsec);
++	if (err) {
++		WL_ERR("wsec failed (%d)\n", err);
++		goto done;
++	}
++
++	/* Configure Beacon Interval for starter */
++	if (params->beacon_interval)
++		bcnprd = params->beacon_interval;
++	else
++		bcnprd = 100;
++
++	err = brcmf_exec_dcmd_u32(ndev, BRCM_SET_BCNPRD, &bcnprd);
++	if (err) {
++		WL_ERR("WLC_SET_BCNPRD failed (%d)\n", err);
++		goto done;
++	}
++
++	/* Configure required join parameter */
++	memset(&join_params, 0, sizeof(struct brcmf_join_params));
++
++	/* SSID */
++	ssid.SSID_len = min_t(u32, params->ssid_len, 32);
++	memcpy(ssid.SSID, params->ssid, ssid.SSID_len);
++	memcpy(join_params.ssid_le.SSID, params->ssid, ssid.SSID_len);
++	join_params.ssid_le.SSID_len = cpu_to_le32(ssid.SSID_len);
++	join_params_size = sizeof(join_params.ssid_le);
++	brcmf_update_prof(cfg_priv, NULL, &ssid, WL_PROF_SSID);
++
++	/* BSSID */
++	if (params->bssid) {
++		memcpy(join_params.params_le.bssid, params->bssid, ETH_ALEN);
++		join_params_size = sizeof(join_params.ssid_le) +
++				   BRCMF_ASSOC_PARAMS_FIXED_SIZE;
++	} else {
++		memcpy(join_params.params_le.bssid, ether_bcast, ETH_ALEN);
++	}
++
++	brcmf_update_prof(cfg_priv, NULL,
++			  &join_params.params_le.bssid, WL_PROF_BSSID);
++
++	/* Channel */
++	if (params->channel) {
++		u32 target_channel;
++
++		cfg_priv->channel =
++			ieee80211_frequency_to_channel(
++				params->channel->center_freq);
++		if (params->channel_fixed) {
++			/* adding chanspec */
++			brcmf_ch_to_chanspec(cfg_priv->channel,
++				&join_params, &join_params_size);
++		}
++
++		/* set channel for starter */
++		target_channel = cfg_priv->channel;
++		err = brcmf_exec_dcmd_u32(ndev, BRCM_SET_CHANNEL,
++					  &target_channel);
++		if (err) {
++			WL_ERR("WLC_SET_CHANNEL failed (%d)\n", err);
++			goto done;
++		}
++	} else
++		cfg_priv->channel = 0;
++
++	cfg_priv->ibss_starter = false;
++
++
++	err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID,
++			   &join_params, join_params_size);
++	if (err) {
++		WL_ERR("WLC_SET_SSID failed (%d)\n", err);
++		goto done;
++	}
++
++done:
++	if (err)
++		clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
++	WL_TRACE("Exit\n");
++	return err;
++}
++
++static s32
++brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
++	s32 err = 0;
++
++	WL_TRACE("Enter\n");
++	if (!check_sys_up(wiphy))
++		return -EIO;
++
++	brcmf_link_down(cfg_priv);
++
++	WL_TRACE("Exit\n");
++
++	return err;
++}
++
++static s32 brcmf_set_wpa_version(struct net_device *ndev,
++				 struct cfg80211_connect_params *sme)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
++	struct brcmf_cfg80211_security *sec;
++	s32 val = 0;
++	s32 err = 0;
++
++	if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
++		val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
++	else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
++		val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
++	else
++		val = WPA_AUTH_DISABLED;
++	WL_CONN("setting wpa_auth to 0x%0x\n", val);
++	err = brcmf_dev_intvar_set(ndev, "wpa_auth", val);
++	if (err) {
++		WL_ERR("set wpa_auth failed (%d)\n", err);
++		return err;
++	}
++	sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
++	sec->wpa_versions = sme->crypto.wpa_versions;
++	return err;
++}
++
++static s32 brcmf_set_auth_type(struct net_device *ndev,
++			       struct cfg80211_connect_params *sme)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
++	struct brcmf_cfg80211_security *sec;
++	s32 val = 0;
++	s32 err = 0;
++
++	switch (sme->auth_type) {
++	case NL80211_AUTHTYPE_OPEN_SYSTEM:
++		val = 0;
++		WL_CONN("open system\n");
++		break;
++	case NL80211_AUTHTYPE_SHARED_KEY:
++		val = 1;
++		WL_CONN("shared key\n");
++		break;
++	case NL80211_AUTHTYPE_AUTOMATIC:
++		val = 2;
++		WL_CONN("automatic\n");
++		break;
++	case NL80211_AUTHTYPE_NETWORK_EAP:
++		WL_CONN("network eap\n");
++	default:
++		val = 2;
++		WL_ERR("invalid auth type (%d)\n", sme->auth_type);
++		break;
++	}
++
++	err = brcmf_dev_intvar_set(ndev, "auth", val);
++	if (err) {
++		WL_ERR("set auth failed (%d)\n", err);
++		return err;
++	}
++	sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
++	sec->auth_type = sme->auth_type;
++	return err;
++}
++
++static s32
++brcmf_set_set_cipher(struct net_device *ndev,
++		     struct cfg80211_connect_params *sme)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
++	struct brcmf_cfg80211_security *sec;
++	s32 pval = 0;
++	s32 gval = 0;
++	s32 err = 0;
++
++	if (sme->crypto.n_ciphers_pairwise) {
++		switch (sme->crypto.ciphers_pairwise[0]) {
++		case WLAN_CIPHER_SUITE_WEP40:
++		case WLAN_CIPHER_SUITE_WEP104:
++			pval = WEP_ENABLED;
++			break;
++		case WLAN_CIPHER_SUITE_TKIP:
++			pval = TKIP_ENABLED;
++			break;
++		case WLAN_CIPHER_SUITE_CCMP:
++			pval = AES_ENABLED;
++			break;
++		case WLAN_CIPHER_SUITE_AES_CMAC:
++			pval = AES_ENABLED;
++			break;
++		default:
++			WL_ERR("invalid cipher pairwise (%d)\n",
++			       sme->crypto.ciphers_pairwise[0]);
++			return -EINVAL;
++		}
++	}
++	if (sme->crypto.cipher_group) {
++		switch (sme->crypto.cipher_group) {
++		case WLAN_CIPHER_SUITE_WEP40:
++		case WLAN_CIPHER_SUITE_WEP104:
++			gval = WEP_ENABLED;
++			break;
++		case WLAN_CIPHER_SUITE_TKIP:
++			gval = TKIP_ENABLED;
++			break;
++		case WLAN_CIPHER_SUITE_CCMP:
++			gval = AES_ENABLED;
++			break;
++		case WLAN_CIPHER_SUITE_AES_CMAC:
++			gval = AES_ENABLED;
++			break;
++		default:
++			WL_ERR("invalid cipher group (%d)\n",
++			       sme->crypto.cipher_group);
++			return -EINVAL;
++		}
++	}
++
++	WL_CONN("pval (%d) gval (%d)\n", pval, gval);
++	err = brcmf_dev_intvar_set(ndev, "wsec", pval | gval);
++	if (err) {
++		WL_ERR("error (%d)\n", err);
++		return err;
++	}
++
++	sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
++	sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
++	sec->cipher_group = sme->crypto.cipher_group;
++
++	return err;
++}
++
++static s32
++brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
++	struct brcmf_cfg80211_security *sec;
++	s32 val = 0;
++	s32 err = 0;
++
++	if (sme->crypto.n_akm_suites) {
++		err = brcmf_dev_intvar_get(ndev, "wpa_auth", &val);
++		if (err) {
++			WL_ERR("could not get wpa_auth (%d)\n", err);
++			return err;
++		}
++		if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
++			switch (sme->crypto.akm_suites[0]) {
++			case WLAN_AKM_SUITE_8021X:
++				val = WPA_AUTH_UNSPECIFIED;
++				break;
++			case WLAN_AKM_SUITE_PSK:
++				val = WPA_AUTH_PSK;
++				break;
++			default:
++				WL_ERR("invalid cipher group (%d)\n",
++				       sme->crypto.cipher_group);
++				return -EINVAL;
++			}
++		} else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
++			switch (sme->crypto.akm_suites[0]) {
++			case WLAN_AKM_SUITE_8021X:
++				val = WPA2_AUTH_UNSPECIFIED;
++				break;
++			case WLAN_AKM_SUITE_PSK:
++				val = WPA2_AUTH_PSK;
++				break;
++			default:
++				WL_ERR("invalid cipher group (%d)\n",
++				       sme->crypto.cipher_group);
++				return -EINVAL;
++			}
++		}
++
++		WL_CONN("setting wpa_auth to %d\n", val);
++		err = brcmf_dev_intvar_set(ndev, "wpa_auth", val);
++		if (err) {
++			WL_ERR("could not set wpa_auth (%d)\n", err);
++			return err;
++		}
++	}
++	sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
++	sec->wpa_auth = sme->crypto.akm_suites[0];
++
++	return err;
++}
++
++static s32
++brcmf_set_wep_sharedkey(struct net_device *ndev,
++		     struct cfg80211_connect_params *sme)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
++	struct brcmf_cfg80211_security *sec;
++	struct brcmf_wsec_key key;
++	s32 val;
++	s32 err = 0;
++
++	WL_CONN("key len (%d)\n", sme->key_len);
++
++	if (sme->key_len == 0)
++		return 0;
++
++	sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
++	WL_CONN("wpa_versions 0x%x cipher_pairwise 0x%x\n",
++		sec->wpa_versions, sec->cipher_pairwise);
++
++	if (sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
++		return 0;
++
++	if (sec->cipher_pairwise &
++	    (WLAN_CIPHER_SUITE_WEP40 | WLAN_CIPHER_SUITE_WEP104)) {
++		memset(&key, 0, sizeof(key));
++		key.len = (u32) sme->key_len;
++		key.index = (u32) sme->key_idx;
++		if (key.len > sizeof(key.data)) {
++			WL_ERR("Too long key length (%u)\n", key.len);
++			return -EINVAL;
++		}
++		memcpy(key.data, sme->key, key.len);
++		key.flags = BRCMF_PRIMARY_KEY;
++		switch (sec->cipher_pairwise) {
++		case WLAN_CIPHER_SUITE_WEP40:
++			key.algo = CRYPTO_ALGO_WEP1;
++			break;
++		case WLAN_CIPHER_SUITE_WEP104:
++			key.algo = CRYPTO_ALGO_WEP128;
++			break;
++		default:
++			WL_ERR("Invalid algorithm (%d)\n",
++			       sme->crypto.ciphers_pairwise[0]);
++			return -EINVAL;
++		}
++		/* Set the new key/index */
++		WL_CONN("key length (%d) key index (%d) algo (%d)\n",
++			key.len, key.index, key.algo);
++		WL_CONN("key \"%s\"\n", key.data);
++		err = send_key_to_dongle(ndev, &key);
++		if (err)
++			return err;
++
++		if (sec->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) {
++			WL_CONN("set auth_type to shared key\n");
++			val = 1;	/* shared key */
++			err = brcmf_dev_intvar_set(ndev, "auth", val);
++			if (err) {
++				WL_ERR("set auth failed (%d)\n", err);
++				return err;
++			}
++		}
++	}
++	return err;
++}
++
++static s32
++brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
++		    struct cfg80211_connect_params *sme)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
++	struct ieee80211_channel *chan = sme->channel;
++	struct brcmf_join_params join_params;
++	size_t join_params_size;
++	struct brcmf_ssid ssid;
++
++	s32 err = 0;
++
++	WL_TRACE("Enter\n");
++	if (!check_sys_up(wiphy))
++		return -EIO;
++
++	if (!sme->ssid) {
++		WL_ERR("Invalid ssid\n");
++		return -EOPNOTSUPP;
++	}
++
++	set_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
++
++	if (chan) {
++		cfg_priv->channel =
++			ieee80211_frequency_to_channel(chan->center_freq);
++		WL_CONN("channel (%d), center_req (%d)\n",
++				cfg_priv->channel, chan->center_freq);
++	} else
++		cfg_priv->channel = 0;
++
++	WL_INFO("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
++
++	err = brcmf_set_wpa_version(ndev, sme);
++	if (err) {
++		WL_ERR("wl_set_wpa_version failed (%d)\n", err);
++		goto done;
++	}
++
++	err = brcmf_set_auth_type(ndev, sme);
++	if (err) {
++		WL_ERR("wl_set_auth_type failed (%d)\n", err);
++		goto done;
++	}
++
++	err = brcmf_set_set_cipher(ndev, sme);
++	if (err) {
++		WL_ERR("wl_set_set_cipher failed (%d)\n", err);
++		goto done;
++	}
++
++	err = brcmf_set_key_mgmt(ndev, sme);
++	if (err) {
++		WL_ERR("wl_set_key_mgmt failed (%d)\n", err);
++		goto done;
++	}
++
++	err = brcmf_set_wep_sharedkey(ndev, sme);
++	if (err) {
++		WL_ERR("brcmf_set_wep_sharedkey failed (%d)\n", err);
++		goto done;
++	}
++
++	memset(&join_params, 0, sizeof(join_params));
++	join_params_size = sizeof(join_params.ssid_le);
++
++	ssid.SSID_len = min_t(u32, sizeof(ssid.SSID), (u32)sme->ssid_len);
++	memcpy(&join_params.ssid_le.SSID, sme->ssid, ssid.SSID_len);
++	memcpy(&ssid.SSID, sme->ssid, ssid.SSID_len);
++	join_params.ssid_le.SSID_len = cpu_to_le32(ssid.SSID_len);
++	brcmf_update_prof(cfg_priv, NULL, &ssid, WL_PROF_SSID);
++
++	memcpy(join_params.params_le.bssid, ether_bcast, ETH_ALEN);
++
++	if (ssid.SSID_len < IEEE80211_MAX_SSID_LEN)
++		WL_CONN("ssid \"%s\", len (%d)\n",
++		       ssid.SSID, ssid.SSID_len);
++
++	brcmf_ch_to_chanspec(cfg_priv->channel,
++			     &join_params, &join_params_size);
++	err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID,
++			   &join_params, join_params_size);
++	if (err)
++		WL_ERR("WLC_SET_SSID failed (%d)\n", err);
++
++done:
++	if (err)
++		clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
++	WL_TRACE("Exit\n");
++	return err;
++}
++
++static s32
++brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
++		       u16 reason_code)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
++	struct brcmf_scb_val_le scbval;
++	s32 err = 0;
++
++	WL_TRACE("Enter. Reason code = %d\n", reason_code);
++	if (!check_sys_up(wiphy))
++		return -EIO;
++
++	clear_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
++
++	memcpy(&scbval.ea, brcmf_read_prof(cfg_priv, WL_PROF_BSSID), ETH_ALEN);
++	scbval.val = cpu_to_le32(reason_code);
++	err = brcmf_exec_dcmd(ndev, BRCMF_C_DISASSOC, &scbval,
++			      sizeof(struct brcmf_scb_val_le));
++	if (err)
++		WL_ERR("error (%d)\n", err);
++
++	cfg_priv->link_up = false;
++
++	WL_TRACE("Exit\n");
++	return err;
++}
++
++static s32
++brcmf_cfg80211_set_tx_power(struct wiphy *wiphy,
++			    enum nl80211_tx_power_setting type, s32 mbm)
++{
++
++	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
++	struct net_device *ndev = cfg_to_ndev(cfg_priv);
++	u16 txpwrmw;
++	s32 err = 0;
++	s32 disable = 0;
++	s32 dbm = MBM_TO_DBM(mbm);
++
++	WL_TRACE("Enter\n");
++	if (!check_sys_up(wiphy))
++		return -EIO;
++
++	switch (type) {
++	case NL80211_TX_POWER_AUTOMATIC:
++		break;
++	case NL80211_TX_POWER_LIMITED:
++	case NL80211_TX_POWER_FIXED:
++		if (dbm < 0) {
++			WL_ERR("TX_POWER_FIXED - dbm is negative\n");
++			err = -EINVAL;
++			goto done;
++		}
++		break;
++	}
++	/* Make sure radio is off or on as far as software is concerned */
++	disable = WL_RADIO_SW_DISABLE << 16;
++	err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_RADIO, &disable);
++	if (err)
++		WL_ERR("WLC_SET_RADIO error (%d)\n", err);
++
++	if (dbm > 0xffff)
++		txpwrmw = 0xffff;
++	else
++		txpwrmw = (u16) dbm;
++	err = brcmf_dev_intvar_set(ndev, "qtxpower",
++			(s32) (brcmf_mw_to_qdbm(txpwrmw)));
++	if (err)
++		WL_ERR("qtxpower error (%d)\n", err);
++	cfg_priv->conf->tx_power = dbm;
++
++done:
++	WL_TRACE("Exit\n");
++	return err;
++}
++
++static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
++	struct net_device *ndev = cfg_to_ndev(cfg_priv);
++	s32 txpwrdbm;
++	u8 result;
++	s32 err = 0;
++
++	WL_TRACE("Enter\n");
++	if (!check_sys_up(wiphy))
++		return -EIO;
++
++	err = brcmf_dev_intvar_get(ndev, "qtxpower", &txpwrdbm);
++	if (err) {
++		WL_ERR("error (%d)\n", err);
++		goto done;
++	}
++
++	result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
++	*dbm = (s32) brcmf_qdbm_to_mw(result);
++
++done:
++	WL_TRACE("Exit\n");
++	return err;
++}
++
++static s32
++brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev,
++			       u8 key_idx, bool unicast, bool multicast)
++{
++	u32 index;
++	u32 wsec;
++	s32 err = 0;
++
++	WL_TRACE("Enter\n");
++	WL_CONN("key index (%d)\n", key_idx);
++	if (!check_sys_up(wiphy))
++		return -EIO;
++
++	err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_WSEC, &wsec);
++	if (err) {
++		WL_ERR("WLC_GET_WSEC error (%d)\n", err);
++		goto done;
++	}
++
++	if (wsec & WEP_ENABLED) {
++		/* Just select a new current key */
++		index = key_idx;
++		err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_KEY_PRIMARY,
++					  &index);
++		if (err)
++			WL_ERR("error (%d)\n", err);
++	}
++done:
++	WL_TRACE("Exit\n");
++	return err;
++}
++
++static s32
++brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
++	      u8 key_idx, const u8 *mac_addr, struct key_params *params)
++{
++	struct brcmf_wsec_key key;
++	struct brcmf_wsec_key_le key_le;
++	s32 err = 0;
++
++	memset(&key, 0, sizeof(key));
++	key.index = (u32) key_idx;
++	/* Instead of bcast for ea address for default wep keys,
++		 driver needs it to be Null */
++	if (!is_multicast_ether_addr(mac_addr))
++		memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN);
++	key.len = (u32) params->key_len;
++	/* check for key index change */
++	if (key.len == 0) {
++		/* key delete */
++		err = send_key_to_dongle(ndev, &key);
++		if (err)
++			return err;
++	} else {
++		if (key.len > sizeof(key.data)) {
++			WL_ERR("Invalid key length (%d)\n", key.len);
++			return -EINVAL;
++		}
++
++		WL_CONN("Setting the key index %d\n", key.index);
++		memcpy(key.data, params->key, key.len);
++
++		if (params->cipher == WLAN_CIPHER_SUITE_TKIP) {
++			u8 keybuf[8];
++			memcpy(keybuf, &key.data[24], sizeof(keybuf));
++			memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
++			memcpy(&key.data[16], keybuf, sizeof(keybuf));
++		}
++
++		/* if IW_ENCODE_EXT_RX_SEQ_VALID set */
++		if (params->seq && params->seq_len == 6) {
++			/* rx iv */
++			u8 *ivptr;
++			ivptr = (u8 *) params->seq;
++			key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
++			    (ivptr[3] << 8) | ivptr[2];
++			key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
++			key.iv_initialized = true;
++		}
++
++		switch (params->cipher) {
++		case WLAN_CIPHER_SUITE_WEP40:
++			key.algo = CRYPTO_ALGO_WEP1;
++			WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
++			break;
++		case WLAN_CIPHER_SUITE_WEP104:
++			key.algo = CRYPTO_ALGO_WEP128;
++			WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
++			break;
++		case WLAN_CIPHER_SUITE_TKIP:
++			key.algo = CRYPTO_ALGO_TKIP;
++			WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
++			break;
++		case WLAN_CIPHER_SUITE_AES_CMAC:
++			key.algo = CRYPTO_ALGO_AES_CCM;
++			WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
++			break;
++		case WLAN_CIPHER_SUITE_CCMP:
++			key.algo = CRYPTO_ALGO_AES_CCM;
++			WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
++			break;
++		default:
++			WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
++			return -EINVAL;
++		}
++		convert_key_from_CPU(&key, &key_le);
++
++		brcmf_netdev_wait_pend8021x(ndev);
++		err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_KEY, &key_le,
++				      sizeof(key_le));
++		if (err) {
++			WL_ERR("WLC_SET_KEY error (%d)\n", err);
++			return err;
++		}
++	}
++	return err;
++}
++
++static s32
++brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
++		    u8 key_idx, bool pairwise, const u8 *mac_addr,
++		    struct key_params *params)
++{
++	struct brcmf_wsec_key key;
++	s32 val;
++	s32 wsec;
++	s32 err = 0;
++	u8 keybuf[8];
++
++	WL_TRACE("Enter\n");
++	WL_CONN("key index (%d)\n", key_idx);
++	if (!check_sys_up(wiphy))
++		return -EIO;
++
++	if (mac_addr) {
++		WL_TRACE("Exit");
++		return brcmf_add_keyext(wiphy, ndev, key_idx, mac_addr, params);
++	}
++	memset(&key, 0, sizeof(key));
++
++	key.len = (u32) params->key_len;
++	key.index = (u32) key_idx;
++
++	if (key.len > sizeof(key.data)) {
++		WL_ERR("Too long key length (%u)\n", key.len);
++		err = -EINVAL;
++		goto done;
++	}
++	memcpy(key.data, params->key, key.len);
++
++	key.flags = BRCMF_PRIMARY_KEY;
++	switch (params->cipher) {
++	case WLAN_CIPHER_SUITE_WEP40:
++		key.algo = CRYPTO_ALGO_WEP1;
++		WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
++		break;
++	case WLAN_CIPHER_SUITE_WEP104:
++		key.algo = CRYPTO_ALGO_WEP128;
++		WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
++		break;
++	case WLAN_CIPHER_SUITE_TKIP:
++		memcpy(keybuf, &key.data[24], sizeof(keybuf));
++		memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
++		memcpy(&key.data[16], keybuf, sizeof(keybuf));
++		key.algo = CRYPTO_ALGO_TKIP;
++		WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
++		break;
++	case WLAN_CIPHER_SUITE_AES_CMAC:
++		key.algo = CRYPTO_ALGO_AES_CCM;
++		WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
++		break;
++	case WLAN_CIPHER_SUITE_CCMP:
++		key.algo = CRYPTO_ALGO_AES_CCM;
++		WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
++		break;
++	default:
++		WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
++		err = -EINVAL;
++		goto done;
++	}
++
++	err = send_key_to_dongle(ndev, &key); /* Set the new key/index */
++	if (err)
++		goto done;
++
++	val = WEP_ENABLED;
++	err = brcmf_dev_intvar_get(ndev, "wsec", &wsec);
++	if (err) {
++		WL_ERR("get wsec error (%d)\n", err);
++		goto done;
++	}
++	wsec &= ~(WEP_ENABLED);
++	wsec |= val;
++	err = brcmf_dev_intvar_set(ndev, "wsec", wsec);
++	if (err) {
++		WL_ERR("set wsec error (%d)\n", err);
++		goto done;
++	}
++
++	val = 1;		/* assume shared key. otherwise 0 */
++	err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_AUTH, &val);
++	if (err)
++		WL_ERR("WLC_SET_AUTH error (%d)\n", err);
++done:
++	WL_TRACE("Exit\n");
++	return err;
++}
++
++static s32
++brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
++		    u8 key_idx, bool pairwise, const u8 *mac_addr)
++{
++	struct brcmf_wsec_key key;
++	s32 err = 0;
++	s32 val;
++	s32 wsec;
++
++	WL_TRACE("Enter\n");
++	if (!check_sys_up(wiphy))
++		return -EIO;
++
++	memset(&key, 0, sizeof(key));
++
++	key.index = (u32) key_idx;
++	key.flags = BRCMF_PRIMARY_KEY;
++	key.algo = CRYPTO_ALGO_OFF;
++
++	WL_CONN("key index (%d)\n", key_idx);
++
++	/* Set the new key/index */
++	err = send_key_to_dongle(ndev, &key);
++	if (err) {
++		if (err == -EINVAL) {
++			if (key.index >= DOT11_MAX_DEFAULT_KEYS)
++				/* we ignore this key index in this case */
++				WL_ERR("invalid key index (%d)\n", key_idx);
++		}
++		/* Ignore this error, may happen during DISASSOC */
++		err = -EAGAIN;
++		goto done;
++	}
++
++	val = 0;
++	err = brcmf_dev_intvar_get(ndev, "wsec", &wsec);
++	if (err) {
++		WL_ERR("get wsec error (%d)\n", err);
++		/* Ignore this error, may happen during DISASSOC */
++		err = -EAGAIN;
++		goto done;
++	}
++	wsec &= ~(WEP_ENABLED);
++	wsec |= val;
++	err = brcmf_dev_intvar_set(ndev, "wsec", wsec);
++	if (err) {
++		WL_ERR("set wsec error (%d)\n", err);
++		/* Ignore this error, may happen during DISASSOC */
++		err = -EAGAIN;
++		goto done;
++	}
++
++	val = 0;		/* assume open key. otherwise 1 */
++	err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_AUTH, &val);
++	if (err) {
++		WL_ERR("WLC_SET_AUTH error (%d)\n", err);
++		/* Ignore this error, may happen during DISASSOC */
++		err = -EAGAIN;
++	}
++done:
++	WL_TRACE("Exit\n");
++	return err;
++}
++
++static s32
++brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
++		    u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
++		    void (*callback) (void *cookie, struct key_params * params))
++{
++	struct key_params params;
++	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
++	struct brcmf_cfg80211_security *sec;
++	s32 wsec;
++	s32 err = 0;
++
++	WL_TRACE("Enter\n");
++	WL_CONN("key index (%d)\n", key_idx);
++	if (!check_sys_up(wiphy))
++		return -EIO;
++
++	memset(&params, 0, sizeof(params));
++
++	err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_WSEC, &wsec);
++	if (err) {
++		WL_ERR("WLC_GET_WSEC error (%d)\n", err);
++		/* Ignore this error, may happen during DISASSOC */
++		err = -EAGAIN;
++		goto done;
++	}
++	switch (wsec) {
++	case WEP_ENABLED:
++		sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
++		if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
++			params.cipher = WLAN_CIPHER_SUITE_WEP40;
++			WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
++		} else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
++			params.cipher = WLAN_CIPHER_SUITE_WEP104;
++			WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
++		}
++		break;
++	case TKIP_ENABLED:
++		params.cipher = WLAN_CIPHER_SUITE_TKIP;
++		WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
++		break;
++	case AES_ENABLED:
++		params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
++		WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
++		break;
++	default:
++		WL_ERR("Invalid algo (0x%x)\n", wsec);
++		err = -EINVAL;
++		goto done;
++	}
++	callback(cookie, &params);
++
++done:
++	WL_TRACE("Exit\n");
++	return err;
++}
++
++static s32
++brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
++				    struct net_device *ndev, u8 key_idx)
++{
++	WL_INFO("Not supported\n");
++
++	return -EOPNOTSUPP;
++}
++
++static s32
++brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
++			u8 *mac, struct station_info *sinfo)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
++	struct brcmf_scb_val_le scb_val;
++	int rssi;
++	s32 rate;
++	s32 err = 0;
++	u8 *bssid = brcmf_read_prof(cfg_priv, WL_PROF_BSSID);
++
++	WL_TRACE("Enter\n");
++	if (!check_sys_up(wiphy))
++		return -EIO;
++
++	if (memcmp(mac, bssid, ETH_ALEN)) {
++		WL_ERR("Wrong Mac address cfg_mac-%X:%X:%X:%X:%X:%X"
++			"wl_bssid-%X:%X:%X:%X:%X:%X\n",
++			mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
++			bssid[0], bssid[1], bssid[2], bssid[3],
++			bssid[4], bssid[5]);
++		err = -ENOENT;
++		goto done;
++	}
++
++	/* Report the current tx rate */
++	err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_RATE, &rate);
++	if (err) {
++		WL_ERR("Could not get rate (%d)\n", err);
++	} else {
++		sinfo->filled |= STATION_INFO_TX_BITRATE;
++		sinfo->txrate.legacy = rate * 5;
++		WL_CONN("Rate %d Mbps\n", rate / 2);
++	}
++
++	if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status)) {
++		scb_val.val = cpu_to_le32(0);
++		err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_RSSI, &scb_val,
++				      sizeof(struct brcmf_scb_val_le));
++		if (err)
++			WL_ERR("Could not get rssi (%d)\n", err);
++
++		rssi = le32_to_cpu(scb_val.val);
++		sinfo->filled |= STATION_INFO_SIGNAL;
++		sinfo->signal = rssi;
++		WL_CONN("RSSI %d dBm\n", rssi);
++	}
++
++done:
++	WL_TRACE("Exit\n");
++	return err;
++}
++
++static s32
++brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
++			   bool enabled, s32 timeout)
++{
++	s32 pm;
++	s32 err = 0;
++	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
++
++	WL_TRACE("Enter\n");
++
++	/*
++	 * Powersave enable/disable request is coming from the
++	 * cfg80211 even before the interface is up. In that
++	 * scenario, driver will be storing the power save
++	 * preference in cfg_priv struct to apply this to
++	 * FW later while initializing the dongle
++	 */
++	cfg_priv->pwr_save = enabled;
++	if (!test_bit(WL_STATUS_READY, &cfg_priv->status)) {
++
++		WL_INFO("Device is not ready,"
++			"storing the value in cfg_priv struct\n");
++		goto done;
++	}
++
++	pm = enabled ? PM_FAST : PM_OFF;
++	WL_INFO("power save %s\n", (pm ? "enabled" : "disabled"));
++
++	err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_PM, &pm);
++	if (err) {
++		if (err == -ENODEV)
++			WL_ERR("net_device is not ready yet\n");
++		else
++			WL_ERR("error (%d)\n", err);
++	}
++done:
++	WL_TRACE("Exit\n");
++	return err;
++}
++
++static s32
++brcmf_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *ndev,
++			     const u8 *addr,
++			     const struct cfg80211_bitrate_mask *mask)
++{
++	struct brcm_rateset_le rateset_le;
++	s32 rate;
++	s32 val;
++	s32 err_bg;
++	s32 err_a;
++	u32 legacy;
++	s32 err = 0;
++
++	WL_TRACE("Enter\n");
++	if (!check_sys_up(wiphy))
++		return -EIO;
++
++	/* addr param is always NULL. ignore it */
++	/* Get current rateset */
++	err = brcmf_exec_dcmd(ndev, BRCM_GET_CURR_RATESET, &rateset_le,
++			      sizeof(rateset_le));
++	if (err) {
++		WL_ERR("could not get current rateset (%d)\n", err);
++		goto done;
++	}
++
++	legacy = ffs(mask->control[IEEE80211_BAND_2GHZ].legacy & 0xFFFF);
++	if (!legacy)
++		legacy = ffs(mask->control[IEEE80211_BAND_5GHZ].legacy &
++			     0xFFFF);
++
++	val = wl_g_rates[legacy - 1].bitrate * 100000;
++
++	if (val < le32_to_cpu(rateset_le.count))
++		/* Select rate by rateset index */
++		rate = rateset_le.rates[val] & 0x7f;
++	else
++		/* Specified rate in bps */
++		rate = val / 500000;
++
++	WL_CONN("rate %d mbps\n", rate / 2);
++
++	/*
++	 *
++	 *      Set rate override,
++	 *      Since the is a/b/g-blind, both a/bg_rate are enforced.
++	 */
++	err_bg = brcmf_dev_intvar_set(ndev, "bg_rate", rate);
++	err_a = brcmf_dev_intvar_set(ndev, "a_rate", rate);
++	if (err_bg && err_a) {
++		WL_ERR("could not set fixed rate (%d) (%d)\n", err_bg, err_a);
++		err = err_bg | err_a;
++	}
++
++done:
++	WL_TRACE("Exit\n");
++	return err;
++}
++
++static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_priv *cfg_priv,
++				   struct brcmf_bss_info_le *bi)
++{
++	struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
++	struct ieee80211_channel *notify_channel;
++	struct cfg80211_bss *bss;
++	struct ieee80211_supported_band *band;
++	s32 err = 0;
++	u16 channel;
++	u32 freq;
++	u16 notify_capability;
++	u16 notify_interval;
++	u8 *notify_ie;
++	size_t notify_ielen;
++	s32 notify_signal;
++
++	if (le32_to_cpu(bi->length) > WL_BSS_INFO_MAX) {
++		WL_ERR("Bss info is larger than buffer. Discarding\n");
++		return 0;
++	}
++
++	channel = bi->ctl_ch ? bi->ctl_ch :
++				CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
++
++	if (channel <= CH_MAX_2G_CHANNEL)
++		band = wiphy->bands[IEEE80211_BAND_2GHZ];
++	else
++		band = wiphy->bands[IEEE80211_BAND_5GHZ];
++
++	freq = ieee80211_channel_to_frequency(channel, band->band);
++	notify_channel = ieee80211_get_channel(wiphy, freq);
++
++	notify_capability = le16_to_cpu(bi->capability);
++	notify_interval = le16_to_cpu(bi->beacon_period);
++	notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
++	notify_ielen = le32_to_cpu(bi->ie_length);
++	notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
++
++	WL_CONN("bssid: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
++			bi->BSSID[0], bi->BSSID[1], bi->BSSID[2],
++			bi->BSSID[3], bi->BSSID[4], bi->BSSID[5]);
++	WL_CONN("Channel: %d(%d)\n", channel, freq);
++	WL_CONN("Capability: %X\n", notify_capability);
++	WL_CONN("Beacon interval: %d\n", notify_interval);
++	WL_CONN("Signal: %d\n", notify_signal);
++
++	bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)bi->BSSID,
++		0, notify_capability, notify_interval, notify_ie,
++		notify_ielen, notify_signal, GFP_KERNEL);
++
++	if (!bss)
++		return -ENOMEM;
++
++	cfg80211_put_bss(bss);
++
++	return err;
++}
++
++static struct brcmf_bss_info_le *
++next_bss_le(struct brcmf_scan_results *list, struct brcmf_bss_info_le *bss)
++{
++	if (bss == NULL)
++		return list->bss_info_le;
++	return (struct brcmf_bss_info_le *)((unsigned long)bss +
++					    le32_to_cpu(bss->length));
++}
++
++static s32 brcmf_inform_bss(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	struct brcmf_scan_results *bss_list;
++	struct brcmf_bss_info_le *bi = NULL;	/* must be initialized */
++	s32 err = 0;
++	int i;
++
++	bss_list = cfg_priv->bss_list;
++	if (bss_list->version != BRCMF_BSS_INFO_VERSION) {
++		WL_ERR("Version %d != WL_BSS_INFO_VERSION\n",
++		       bss_list->version);
++		return -EOPNOTSUPP;
++	}
++	WL_SCAN("scanned AP count (%d)\n", bss_list->count);
++	for (i = 0; i < bss_list->count && i < WL_AP_MAX; i++) {
++		bi = next_bss_le(bss_list, bi);
++		err = brcmf_inform_single_bss(cfg_priv, bi);
++		if (err)
++			break;
++	}
++	return err;
++}
++
++static s32 wl_inform_ibss(struct brcmf_cfg80211_priv *cfg_priv,
++			  struct net_device *ndev, const u8 *bssid)
++{
++	struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
++	struct ieee80211_channel *notify_channel;
++	struct brcmf_bss_info_le *bi = NULL;
++	struct ieee80211_supported_band *band;
++	struct cfg80211_bss *bss;
++	u8 *buf = NULL;
++	s32 err = 0;
++	u16 channel;
++	u32 freq;
++	u16 notify_capability;
++	u16 notify_interval;
++	u8 *notify_ie;
++	size_t notify_ielen;
++	s32 notify_signal;
++
++	WL_TRACE("Enter\n");
++
++	buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
++	if (buf == NULL) {
++		err = -ENOMEM;
++		goto CleanUp;
++	}
++
++	*(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
++
++	err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_BSS_INFO, buf, WL_BSS_INFO_MAX);
++	if (err) {
++		WL_ERR("WLC_GET_BSS_INFO failed: %d\n", err);
++		goto CleanUp;
++	}
++
++	bi = (struct brcmf_bss_info_le *)(buf + 4);
++
++	channel = bi->ctl_ch ? bi->ctl_ch :
++				CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
++
++	if (channel <= CH_MAX_2G_CHANNEL)
++		band = wiphy->bands[IEEE80211_BAND_2GHZ];
++	else
++		band = wiphy->bands[IEEE80211_BAND_5GHZ];
++
++	freq = ieee80211_channel_to_frequency(channel, band->band);
++	notify_channel = ieee80211_get_channel(wiphy, freq);
++
++	notify_capability = le16_to_cpu(bi->capability);
++	notify_interval = le16_to_cpu(bi->beacon_period);
++	notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
++	notify_ielen = le32_to_cpu(bi->ie_length);
++	notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
++
++	WL_CONN("channel: %d(%d)\n", channel, freq);
++	WL_CONN("capability: %X\n", notify_capability);
++	WL_CONN("beacon interval: %d\n", notify_interval);
++	WL_CONN("signal: %d\n", notify_signal);
++
++	bss = cfg80211_inform_bss(wiphy, notify_channel, bssid,
++		0, notify_capability, notify_interval,
++		notify_ie, notify_ielen, notify_signal, GFP_KERNEL);
++
++	if (!bss) {
++		err = -ENOMEM;
++		goto CleanUp;
++	}
++
++	cfg80211_put_bss(bss);
++
++CleanUp:
++
++	kfree(buf);
++
++	WL_TRACE("Exit\n");
++
++	return err;
++}
++
++static bool brcmf_is_ibssmode(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	return cfg_priv->conf->mode == WL_MODE_IBSS;
++}
++
++/*
++ * Traverse a string of 1-byte tag/1-byte length/variable-length value
++ * triples, returning a pointer to the substring whose first element
++ * matches tag
++ */
++static struct brcmf_tlv *brcmf_parse_tlvs(void *buf, int buflen, uint key)
++{
++	struct brcmf_tlv *elt;
++	int totlen;
++
++	elt = (struct brcmf_tlv *) buf;
++	totlen = buflen;
++
++	/* find tagged parameter */
++	while (totlen >= 2) {
++		int len = elt->len;
++
++		/* validate remaining totlen */
++		if ((elt->id == key) && (totlen >= (len + 2)))
++			return elt;
++
++		elt = (struct brcmf_tlv *) ((u8 *) elt + (len + 2));
++		totlen -= (len + 2);
++	}
++
++	return NULL;
++}
++
++static s32 brcmf_update_bss_info(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	struct brcmf_bss_info_le *bi;
++	struct brcmf_ssid *ssid;
++	struct brcmf_tlv *tim;
++	u16 beacon_interval;
++	u8 dtim_period;
++	size_t ie_len;
++	u8 *ie;
++	s32 err = 0;
++
++	WL_TRACE("Enter\n");
++	if (brcmf_is_ibssmode(cfg_priv))
++		return err;
++
++	ssid = (struct brcmf_ssid *)brcmf_read_prof(cfg_priv, WL_PROF_SSID);
++
++	*(__le32 *)cfg_priv->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
++	err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCMF_C_GET_BSS_INFO,
++			cfg_priv->extra_buf, WL_EXTRA_BUF_MAX);
++	if (err) {
++		WL_ERR("Could not get bss info %d\n", err);
++		goto update_bss_info_out;
++	}
++
++	bi = (struct brcmf_bss_info_le *)(cfg_priv->extra_buf + 4);
++	err = brcmf_inform_single_bss(cfg_priv, bi);
++	if (err)
++		goto update_bss_info_out;
++
++	ie = ((u8 *)bi) + le16_to_cpu(bi->ie_offset);
++	ie_len = le32_to_cpu(bi->ie_length);
++	beacon_interval = le16_to_cpu(bi->beacon_period);
++
++	tim = brcmf_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
++	if (tim)
++		dtim_period = tim->data[1];
++	else {
++		/*
++		* active scan was done so we could not get dtim
++		* information out of probe response.
++		* so we speficially query dtim information to dongle.
++		*/
++		u32 var;
++		err = brcmf_dev_intvar_get(cfg_to_ndev(cfg_priv),
++					   "dtim_assoc", &var);
++		if (err) {
++			WL_ERR("wl dtim_assoc failed (%d)\n", err);
++			goto update_bss_info_out;
++		}
++		dtim_period = (u8)var;
++	}
++
++	brcmf_update_prof(cfg_priv, NULL, &beacon_interval, WL_PROF_BEACONINT);
++	brcmf_update_prof(cfg_priv, NULL, &dtim_period, WL_PROF_DTIMPERIOD);
++
++update_bss_info_out:
++	WL_TRACE("Exit");
++	return err;
++}
++
++static void brcmf_term_iscan(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
++	struct brcmf_ssid ssid;
++
++	if (cfg_priv->iscan_on) {
++		iscan->state = WL_ISCAN_STATE_IDLE;
++
++		if (iscan->timer_on) {
++			del_timer_sync(&iscan->timer);
++			iscan->timer_on = 0;
++		}
++
++		cancel_work_sync(&iscan->work);
++
++		/* Abort iscan running in FW */
++		memset(&ssid, 0, sizeof(ssid));
++		brcmf_run_iscan(iscan, &ssid, WL_SCAN_ACTION_ABORT);
++	}
++}
++
++static void brcmf_notify_iscan_complete(struct brcmf_cfg80211_iscan_ctrl *iscan,
++					bool aborted)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = iscan_to_cfg(iscan);
++	struct net_device *ndev = cfg_to_ndev(cfg_priv);
++
++	if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
++		WL_ERR("Scan complete while device not scanning\n");
++		return;
++	}
++	if (cfg_priv->scan_request) {
++		WL_SCAN("ISCAN Completed scan: %s\n",
++				aborted ? "Aborted" : "Done");
++		cfg80211_scan_done(cfg_priv->scan_request, aborted);
++		brcmf_set_mpc(ndev, 1);
++		cfg_priv->scan_request = NULL;
++	}
++	cfg_priv->iscan_kickstart = false;
++}
++
++static s32 brcmf_wakeup_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan)
++{
++	if (iscan->state != WL_ISCAN_STATE_IDLE) {
++		WL_SCAN("wake up iscan\n");
++		schedule_work(&iscan->work);
++		return 0;
++	}
++
++	return -EIO;
++}
++
++static s32
++brcmf_get_iscan_results(struct brcmf_cfg80211_iscan_ctrl *iscan, u32 *status,
++		     struct brcmf_scan_results **bss_list)
++{
++	struct brcmf_iscan_results list;
++	struct brcmf_scan_results *results;
++	struct brcmf_scan_results_le *results_le;
++	struct brcmf_iscan_results *list_buf;
++	s32 err = 0;
++
++	memset(iscan->scan_buf, 0, WL_ISCAN_BUF_MAX);
++	list_buf = (struct brcmf_iscan_results *)iscan->scan_buf;
++	results = &list_buf->results;
++	results_le = &list_buf->results_le;
++	results->buflen = BRCMF_ISCAN_RESULTS_FIXED_SIZE;
++	results->version = 0;
++	results->count = 0;
++
++	memset(&list, 0, sizeof(list));
++	list.results_le.buflen = cpu_to_le32(WL_ISCAN_BUF_MAX);
++	err = brcmf_dev_iovar_getbuf(iscan->ndev, "iscanresults", &list,
++				     BRCMF_ISCAN_RESULTS_FIXED_SIZE,
++				     iscan->scan_buf, WL_ISCAN_BUF_MAX);
++	if (err) {
++		WL_ERR("error (%d)\n", err);
++		return err;
++	}
++	results->buflen = le32_to_cpu(results_le->buflen);
++	results->version = le32_to_cpu(results_le->version);
++	results->count = le32_to_cpu(results_le->count);
++	WL_SCAN("results->count = %d\n", results_le->count);
++	WL_SCAN("results->buflen = %d\n", results_le->buflen);
++	*status = le32_to_cpu(list_buf->status_le);
++	WL_SCAN("status = %d\n", *status);
++	*bss_list = results;
++
++	return err;
++}
++
++static s32 brcmf_iscan_done(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
++	s32 err = 0;
++
++	iscan->state = WL_ISCAN_STATE_IDLE;
++	brcmf_inform_bss(cfg_priv);
++	brcmf_notify_iscan_complete(iscan, false);
++
++	return err;
++}
++
++static s32 brcmf_iscan_pending(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
++	s32 err = 0;
++
++	/* Reschedule the timer */
++	mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
++	iscan->timer_on = 1;
++
++	return err;
++}
++
++static s32 brcmf_iscan_inprogress(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
++	s32 err = 0;
++
++	brcmf_inform_bss(cfg_priv);
++	brcmf_run_iscan(iscan, NULL, BRCMF_SCAN_ACTION_CONTINUE);
++	/* Reschedule the timer */
++	mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
++	iscan->timer_on = 1;
++
++	return err;
++}
++
++static s32 brcmf_iscan_aborted(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
++	s32 err = 0;
++
++	iscan->state = WL_ISCAN_STATE_IDLE;
++	brcmf_notify_iscan_complete(iscan, true);
++
++	return err;
++}
++
++static void brcmf_cfg80211_iscan_handler(struct work_struct *work)
++{
++	struct brcmf_cfg80211_iscan_ctrl *iscan =
++			container_of(work, struct brcmf_cfg80211_iscan_ctrl,
++				     work);
++	struct brcmf_cfg80211_priv *cfg_priv = iscan_to_cfg(iscan);
++	struct brcmf_cfg80211_iscan_eloop *el = &iscan->el;
++	u32 status = BRCMF_SCAN_RESULTS_PARTIAL;
++
++	if (iscan->timer_on) {
++		del_timer_sync(&iscan->timer);
++		iscan->timer_on = 0;
++	}
++
++	if (brcmf_get_iscan_results(iscan, &status, &cfg_priv->bss_list)) {
++		status = BRCMF_SCAN_RESULTS_ABORTED;
++		WL_ERR("Abort iscan\n");
++	}
++
++	el->handler[status](cfg_priv);
++}
++
++static void brcmf_iscan_timer(unsigned long data)
++{
++	struct brcmf_cfg80211_iscan_ctrl *iscan =
++			(struct brcmf_cfg80211_iscan_ctrl *)data;
++
++	if (iscan) {
++		iscan->timer_on = 0;
++		WL_SCAN("timer expired\n");
++		brcmf_wakeup_iscan(iscan);
++	}
++}
++
++static s32 brcmf_invoke_iscan(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
++
++	if (cfg_priv->iscan_on) {
++		iscan->state = WL_ISCAN_STATE_IDLE;
++		INIT_WORK(&iscan->work, brcmf_cfg80211_iscan_handler);
++	}
++
++	return 0;
++}
++
++static void brcmf_init_iscan_eloop(struct brcmf_cfg80211_iscan_eloop *el)
++{
++	memset(el, 0, sizeof(*el));
++	el->handler[BRCMF_SCAN_RESULTS_SUCCESS] = brcmf_iscan_done;
++	el->handler[BRCMF_SCAN_RESULTS_PARTIAL] = brcmf_iscan_inprogress;
++	el->handler[BRCMF_SCAN_RESULTS_PENDING] = brcmf_iscan_pending;
++	el->handler[BRCMF_SCAN_RESULTS_ABORTED] = brcmf_iscan_aborted;
++	el->handler[BRCMF_SCAN_RESULTS_NO_MEM] = brcmf_iscan_aborted;
++}
++
++static s32 brcmf_init_iscan(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
++	int err = 0;
++
++	if (cfg_priv->iscan_on) {
++		iscan->ndev = cfg_to_ndev(cfg_priv);
++		brcmf_init_iscan_eloop(&iscan->el);
++		iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS;
++		init_timer(&iscan->timer);
++		iscan->timer.data = (unsigned long) iscan;
++		iscan->timer.function = brcmf_iscan_timer;
++		err = brcmf_invoke_iscan(cfg_priv);
++		if (!err)
++			iscan->data = cfg_priv;
++	}
++
++	return err;
++}
++
++static __always_inline void brcmf_delay(u32 ms)
++{
++	if (ms < 1000 / HZ) {
++		cond_resched();
++		mdelay(ms);
++	} else {
++		msleep(ms);
++	}
++}
++
++static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
++
++	/*
++	 * Check for WL_STATUS_READY before any function call which
++	 * could result is bus access. Don't block the resume for
++	 * any driver error conditions
++	 */
++	WL_TRACE("Enter\n");
++
++	if (test_bit(WL_STATUS_READY, &cfg_priv->status))
++		brcmf_invoke_iscan(wiphy_to_cfg(wiphy));
++
++	WL_TRACE("Exit\n");
++	return 0;
++}
++
++static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
++				  struct cfg80211_wowlan *wow)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
++	struct net_device *ndev = cfg_to_ndev(cfg_priv);
++
++	WL_TRACE("Enter\n");
++
++	/*
++	 * Check for WL_STATUS_READY before any function call which
++	 * could result is bus access. Don't block the suspend for
++	 * any driver error conditions
++	 */
++
++	/*
++	 * While going to suspend if associated with AP disassociate
++	 * from AP to save power while system is in suspended state
++	 */
++	if ((test_bit(WL_STATUS_CONNECTED, &cfg_priv->status) ||
++	     test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) &&
++	     test_bit(WL_STATUS_READY, &cfg_priv->status)) {
++		WL_INFO("Disassociating from AP"
++			" while entering suspend state\n");
++		brcmf_link_down(cfg_priv);
++
++		/*
++		 * Make sure WPA_Supplicant receives all the event
++		 * generated due to DISASSOC call to the fw to keep
++		 * the state fw and WPA_Supplicant state consistent
++		 */
++		brcmf_delay(500);
++	}
++
++	set_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
++	if (test_bit(WL_STATUS_READY, &cfg_priv->status))
++		brcmf_term_iscan(cfg_priv);
++
++	if (cfg_priv->scan_request) {
++		/* Indidate scan abort to cfg80211 layer */
++		WL_INFO("Terminating scan in progress\n");
++		cfg80211_scan_done(cfg_priv->scan_request, true);
++		cfg_priv->scan_request = NULL;
++	}
++	clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
++	clear_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
++
++	/* Turn off watchdog timer */
++	if (test_bit(WL_STATUS_READY, &cfg_priv->status)) {
++		WL_INFO("Enable MPC\n");
++		brcmf_set_mpc(ndev, 1);
++	}
++
++	WL_TRACE("Exit\n");
++
++	return 0;
++}
++
++static __used s32
++brcmf_dev_bufvar_set(struct net_device *ndev, s8 *name, s8 *buf, s32 len)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
++	u32 buflen;
++
++	buflen = brcmf_c_mkiovar(name, buf, len, cfg_priv->dcmd_buf,
++			       WL_DCMD_LEN_MAX);
++	BUG_ON(!buflen);
++
++	return brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, cfg_priv->dcmd_buf,
++			       buflen);
++}
++
++static s32
++brcmf_dev_bufvar_get(struct net_device *ndev, s8 *name, s8 *buf,
++		  s32 buf_len)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
++	u32 len;
++	s32 err = 0;
++
++	len = brcmf_c_mkiovar(name, NULL, 0, cfg_priv->dcmd_buf,
++			    WL_DCMD_LEN_MAX);
++	BUG_ON(!len);
++	err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, cfg_priv->dcmd_buf,
++			      WL_DCMD_LEN_MAX);
++	if (err) {
++		WL_ERR("error (%d)\n", err);
++		return err;
++	}
++	memcpy(buf, cfg_priv->dcmd_buf, buf_len);
++
++	return err;
++}
++
++static __used s32
++brcmf_update_pmklist(struct net_device *ndev,
++		     struct brcmf_cfg80211_pmk_list *pmk_list, s32 err)
++{
++	int i, j;
++	int pmkid_len;
++
++	pmkid_len = le32_to_cpu(pmk_list->pmkids.npmkid);
++
++	WL_CONN("No of elements %d\n", pmkid_len);
++	for (i = 0; i < pmkid_len; i++) {
++		WL_CONN("PMKID[%d]: %pM =\n", i,
++			&pmk_list->pmkids.pmkid[i].BSSID);
++		for (j = 0; j < WLAN_PMKID_LEN; j++)
++			WL_CONN("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j]);
++	}
++
++	if (!err)
++		brcmf_dev_bufvar_set(ndev, "pmkid_info", (char *)pmk_list,
++					sizeof(*pmk_list));
++
++	return err;
++}
++
++static s32
++brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
++			 struct cfg80211_pmksa *pmksa)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
++	struct pmkid_list *pmkids = &cfg_priv->pmk_list->pmkids;
++	s32 err = 0;
++	int i;
++	int pmkid_len;
++
++	WL_TRACE("Enter\n");
++	if (!check_sys_up(wiphy))
++		return -EIO;
++
++	pmkid_len = le32_to_cpu(pmkids->npmkid);
++	for (i = 0; i < pmkid_len; i++)
++		if (!memcmp(pmksa->bssid, pmkids->pmkid[i].BSSID, ETH_ALEN))
++			break;
++	if (i < WL_NUM_PMKIDS_MAX) {
++		memcpy(pmkids->pmkid[i].BSSID, pmksa->bssid, ETH_ALEN);
++		memcpy(pmkids->pmkid[i].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
++		if (i == pmkid_len) {
++			pmkid_len++;
++			pmkids->npmkid = cpu_to_le32(pmkid_len);
++		}
++	} else
++		err = -EINVAL;
++
++	WL_CONN("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
++		pmkids->pmkid[pmkid_len].BSSID);
++	for (i = 0; i < WLAN_PMKID_LEN; i++)
++		WL_CONN("%02x\n", pmkids->pmkid[pmkid_len].PMKID[i]);
++
++	err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err);
++
++	WL_TRACE("Exit\n");
++	return err;
++}
++
++static s32
++brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
++		      struct cfg80211_pmksa *pmksa)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
++	struct pmkid_list pmkid;
++	s32 err = 0;
++	int i, pmkid_len;
++
++	WL_TRACE("Enter\n");
++	if (!check_sys_up(wiphy))
++		return -EIO;
++
++	memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN);
++	memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
++
++	WL_CONN("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
++	       &pmkid.pmkid[0].BSSID);
++	for (i = 0; i < WLAN_PMKID_LEN; i++)
++		WL_CONN("%02x\n", pmkid.pmkid[0].PMKID[i]);
++
++	pmkid_len = le32_to_cpu(cfg_priv->pmk_list->pmkids.npmkid);
++	for (i = 0; i < pmkid_len; i++)
++		if (!memcmp
++		    (pmksa->bssid, &cfg_priv->pmk_list->pmkids.pmkid[i].BSSID,
++		     ETH_ALEN))
++			break;
++
++	if ((pmkid_len > 0)
++	    && (i < pmkid_len)) {
++		memset(&cfg_priv->pmk_list->pmkids.pmkid[i], 0,
++		       sizeof(struct pmkid));
++		for (; i < (pmkid_len - 1); i++) {
++			memcpy(&cfg_priv->pmk_list->pmkids.pmkid[i].BSSID,
++			       &cfg_priv->pmk_list->pmkids.pmkid[i + 1].BSSID,
++			       ETH_ALEN);
++			memcpy(&cfg_priv->pmk_list->pmkids.pmkid[i].PMKID,
++			       &cfg_priv->pmk_list->pmkids.pmkid[i + 1].PMKID,
++			       WLAN_PMKID_LEN);
++		}
++		cfg_priv->pmk_list->pmkids.npmkid = cpu_to_le32(pmkid_len - 1);
++	} else
++		err = -EINVAL;
++
++	err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err);
++
++	WL_TRACE("Exit\n");
++	return err;
++
++}
++
++static s32
++brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
++	s32 err = 0;
++
++	WL_TRACE("Enter\n");
++	if (!check_sys_up(wiphy))
++		return -EIO;
++
++	memset(cfg_priv->pmk_list, 0, sizeof(*cfg_priv->pmk_list));
++	err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err);
++
++	WL_TRACE("Exit\n");
++	return err;
++
++}
++
++static struct cfg80211_ops wl_cfg80211_ops = {
++	.change_virtual_intf = brcmf_cfg80211_change_iface,
++	.scan = brcmf_cfg80211_scan,
++	.set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
++	.join_ibss = brcmf_cfg80211_join_ibss,
++	.leave_ibss = brcmf_cfg80211_leave_ibss,
++	.get_station = brcmf_cfg80211_get_station,
++	.set_tx_power = brcmf_cfg80211_set_tx_power,
++	.get_tx_power = brcmf_cfg80211_get_tx_power,
++	.add_key = brcmf_cfg80211_add_key,
++	.del_key = brcmf_cfg80211_del_key,
++	.get_key = brcmf_cfg80211_get_key,
++	.set_default_key = brcmf_cfg80211_config_default_key,
++	.set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
++	.set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
++	.set_bitrate_mask = brcmf_cfg80211_set_bitrate_mask,
++	.connect = brcmf_cfg80211_connect,
++	.disconnect = brcmf_cfg80211_disconnect,
++	.suspend = brcmf_cfg80211_suspend,
++	.resume = brcmf_cfg80211_resume,
++	.set_pmksa = brcmf_cfg80211_set_pmksa,
++	.del_pmksa = brcmf_cfg80211_del_pmksa,
++	.flush_pmksa = brcmf_cfg80211_flush_pmksa
++};
++
++static s32 brcmf_mode_to_nl80211_iftype(s32 mode)
++{
++	s32 err = 0;
++
++	switch (mode) {
++	case WL_MODE_BSS:
++		return NL80211_IFTYPE_STATION;
++	case WL_MODE_IBSS:
++		return NL80211_IFTYPE_ADHOC;
++	default:
++		return NL80211_IFTYPE_UNSPECIFIED;
++	}
++
++	return err;
++}
++
++static struct wireless_dev *brcmf_alloc_wdev(s32 sizeof_iface,
++					  struct device *ndev)
++{
++	struct wireless_dev *wdev;
++	s32 err = 0;
++
++	wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
++	if (!wdev)
++		return ERR_PTR(-ENOMEM);
++
++	wdev->wiphy =
++	    wiphy_new(&wl_cfg80211_ops,
++		      sizeof(struct brcmf_cfg80211_priv) + sizeof_iface);
++	if (!wdev->wiphy) {
++		WL_ERR("Could not allocate wiphy device\n");
++		err = -ENOMEM;
++		goto wiphy_new_out;
++	}
++	set_wiphy_dev(wdev->wiphy, ndev);
++	wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
++	wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
++	wdev->wiphy->interface_modes =
++	    BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
++	wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
++	wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a;	/* Set
++						* it as 11a by default.
++						* This will be updated with
++						* 11n phy tables in
++						* "ifconfig up"
++						* if phy has 11n capability
++						*/
++	wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
++	wdev->wiphy->cipher_suites = __wl_cipher_suites;
++	wdev->wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
++	wdev->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;	/* enable power
++								 * save mode
++								 * by default
++								 */
++	err = wiphy_register(wdev->wiphy);
++	if (err < 0) {
++		WL_ERR("Could not register wiphy device (%d)\n", err);
++		goto wiphy_register_out;
++	}
++	return wdev;
++
++wiphy_register_out:
++	wiphy_free(wdev->wiphy);
++
++wiphy_new_out:
++	kfree(wdev);
++
++	return ERR_PTR(err);
++}
++
++static void brcmf_free_wdev(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	struct wireless_dev *wdev = cfg_priv->wdev;
++
++	if (!wdev) {
++		WL_ERR("wdev is invalid\n");
++		return;
++	}
++	wiphy_unregister(wdev->wiphy);
++	wiphy_free(wdev->wiphy);
++	kfree(wdev);
++	cfg_priv->wdev = NULL;
++}
++
++static bool brcmf_is_linkup(struct brcmf_cfg80211_priv *cfg_priv,
++			    const struct brcmf_event_msg *e)
++{
++	u32 event = be32_to_cpu(e->event_type);
++	u32 status = be32_to_cpu(e->status);
++
++	if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
++		WL_CONN("Processing set ssid\n");
++		cfg_priv->link_up = true;
++		return true;
++	}
++
++	return false;
++}
++
++static bool brcmf_is_linkdown(struct brcmf_cfg80211_priv *cfg_priv,
++			      const struct brcmf_event_msg *e)
++{
++	u32 event = be32_to_cpu(e->event_type);
++	u16 flags = be16_to_cpu(e->flags);
++
++	if (event == BRCMF_E_LINK && (!(flags & BRCMF_EVENT_MSG_LINK))) {
++		WL_CONN("Processing link down\n");
++		return true;
++	}
++	return false;
++}
++
++static bool brcmf_is_nonetwork(struct brcmf_cfg80211_priv *cfg_priv,
++			       const struct brcmf_event_msg *e)
++{
++	u32 event = be32_to_cpu(e->event_type);
++	u32 status = be32_to_cpu(e->status);
++
++	if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
++		WL_CONN("Processing Link %s & no network found\n",
++				be16_to_cpu(e->flags) & BRCMF_EVENT_MSG_LINK ?
++				"up" : "down");
++		return true;
++	}
++
++	if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
++		WL_CONN("Processing connecting & no network found\n");
++		return true;
++	}
++
++	return false;
++}
++
++static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
++
++	kfree(conn_info->req_ie);
++	conn_info->req_ie = NULL;
++	conn_info->req_ie_len = 0;
++	kfree(conn_info->resp_ie);
++	conn_info->resp_ie = NULL;
++	conn_info->resp_ie_len = 0;
++}
++
++static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	struct net_device *ndev = cfg_to_ndev(cfg_priv);
++	struct brcmf_cfg80211_assoc_ielen_le *assoc_info;
++	struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
++	u32 req_len;
++	u32 resp_len;
++	s32 err = 0;
++
++	brcmf_clear_assoc_ies(cfg_priv);
++
++	err = brcmf_dev_bufvar_get(ndev, "assoc_info", cfg_priv->extra_buf,
++				WL_ASSOC_INFO_MAX);
++	if (err) {
++		WL_ERR("could not get assoc info (%d)\n", err);
++		return err;
++	}
++	assoc_info =
++		(struct brcmf_cfg80211_assoc_ielen_le *)cfg_priv->extra_buf;
++	req_len = le32_to_cpu(assoc_info->req_len);
++	resp_len = le32_to_cpu(assoc_info->resp_len);
++	if (req_len) {
++		err = brcmf_dev_bufvar_get(ndev, "assoc_req_ies",
++					   cfg_priv->extra_buf,
++					   WL_ASSOC_INFO_MAX);
++		if (err) {
++			WL_ERR("could not get assoc req (%d)\n", err);
++			return err;
++		}
++		conn_info->req_ie_len = req_len;
++		conn_info->req_ie =
++		    kmemdup(cfg_priv->extra_buf, conn_info->req_ie_len,
++			    GFP_KERNEL);
++	} else {
++		conn_info->req_ie_len = 0;
++		conn_info->req_ie = NULL;
++	}
++	if (resp_len) {
++		err = brcmf_dev_bufvar_get(ndev, "assoc_resp_ies",
++					   cfg_priv->extra_buf,
++					   WL_ASSOC_INFO_MAX);
++		if (err) {
++			WL_ERR("could not get assoc resp (%d)\n", err);
++			return err;
++		}
++		conn_info->resp_ie_len = resp_len;
++		conn_info->resp_ie =
++		    kmemdup(cfg_priv->extra_buf, conn_info->resp_ie_len,
++			    GFP_KERNEL);
++	} else {
++		conn_info->resp_ie_len = 0;
++		conn_info->resp_ie = NULL;
++	}
++	WL_CONN("req len (%d) resp len (%d)\n",
++	       conn_info->req_ie_len, conn_info->resp_ie_len);
++
++	return err;
++}
++
++static s32
++brcmf_bss_roaming_done(struct brcmf_cfg80211_priv *cfg_priv,
++		       struct net_device *ndev,
++		       const struct brcmf_event_msg *e)
++{
++	struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
++	struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
++	struct brcmf_channel_info_le channel_le;
++	struct ieee80211_channel *notify_channel;
++	struct ieee80211_supported_band *band;
++	u32 freq;
++	s32 err = 0;
++	u32 target_channel;
++
++	WL_TRACE("Enter\n");
++
++	brcmf_get_assoc_ies(cfg_priv);
++	brcmf_update_prof(cfg_priv, NULL, &e->addr, WL_PROF_BSSID);
++	brcmf_update_bss_info(cfg_priv);
++
++	brcmf_exec_dcmd(ndev, BRCMF_C_GET_CHANNEL, &channel_le,
++			sizeof(channel_le));
++
++	target_channel = le32_to_cpu(channel_le.target_channel);
++	WL_CONN("Roamed to channel %d\n", target_channel);
++
++	if (target_channel <= CH_MAX_2G_CHANNEL)
++		band = wiphy->bands[IEEE80211_BAND_2GHZ];
++	else
++		band = wiphy->bands[IEEE80211_BAND_5GHZ];
++
++	freq = ieee80211_channel_to_frequency(target_channel, band->band);
++	notify_channel = ieee80211_get_channel(wiphy, freq);
++
++	cfg80211_roamed(ndev, notify_channel,
++			(u8 *)brcmf_read_prof(cfg_priv, WL_PROF_BSSID),
++			conn_info->req_ie, conn_info->req_ie_len,
++			conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
++	WL_CONN("Report roaming result\n");
++
++	set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
++	WL_TRACE("Exit\n");
++	return err;
++}
++
++static s32
++brcmf_bss_connect_done(struct brcmf_cfg80211_priv *cfg_priv,
++		       struct net_device *ndev, const struct brcmf_event_msg *e,
++		       bool completed)
++{
++	struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
++	s32 err = 0;
++
++	WL_TRACE("Enter\n");
++
++	if (test_and_clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) {
++		if (completed) {
++			brcmf_get_assoc_ies(cfg_priv);
++			brcmf_update_prof(cfg_priv, NULL, &e->addr,
++					  WL_PROF_BSSID);
++			brcmf_update_bss_info(cfg_priv);
++		}
++		cfg80211_connect_result(ndev,
++					(u8 *)brcmf_read_prof(cfg_priv,
++							      WL_PROF_BSSID),
++					conn_info->req_ie,
++					conn_info->req_ie_len,
++					conn_info->resp_ie,
++					conn_info->resp_ie_len,
++					completed ? WLAN_STATUS_SUCCESS :
++						    WLAN_STATUS_AUTH_TIMEOUT,
++					GFP_KERNEL);
++		if (completed)
++			set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
++		WL_CONN("Report connect result - connection %s\n",
++				completed ? "succeeded" : "failed");
++	}
++	WL_TRACE("Exit\n");
++	return err;
++}
++
++static s32
++brcmf_notify_connect_status(struct brcmf_cfg80211_priv *cfg_priv,
++			    struct net_device *ndev,
++			    const struct brcmf_event_msg *e, void *data)
++{
++	s32 err = 0;
++
++	if (brcmf_is_linkup(cfg_priv, e)) {
++		WL_CONN("Linkup\n");
++		if (brcmf_is_ibssmode(cfg_priv)) {
++			brcmf_update_prof(cfg_priv, NULL, (void *)e->addr,
++				WL_PROF_BSSID);
++			wl_inform_ibss(cfg_priv, ndev, e->addr);
++			cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
++			clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
++			set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
++		} else
++			brcmf_bss_connect_done(cfg_priv, ndev, e, true);
++	} else if (brcmf_is_linkdown(cfg_priv, e)) {
++		WL_CONN("Linkdown\n");
++		if (brcmf_is_ibssmode(cfg_priv)) {
++			clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
++			if (test_and_clear_bit(WL_STATUS_CONNECTED,
++				&cfg_priv->status))
++				brcmf_link_down(cfg_priv);
++		} else {
++			brcmf_bss_connect_done(cfg_priv, ndev, e, false);
++			if (test_and_clear_bit(WL_STATUS_CONNECTED,
++				&cfg_priv->status)) {
++				cfg80211_disconnected(ndev, 0, NULL, 0,
++					GFP_KERNEL);
++				brcmf_link_down(cfg_priv);
++			}
++		}
++		brcmf_init_prof(cfg_priv->profile);
++	} else if (brcmf_is_nonetwork(cfg_priv, e)) {
++		if (brcmf_is_ibssmode(cfg_priv))
++			clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
++		else
++			brcmf_bss_connect_done(cfg_priv, ndev, e, false);
++	}
++
++	return err;
++}
++
++static s32
++brcmf_notify_roaming_status(struct brcmf_cfg80211_priv *cfg_priv,
++			    struct net_device *ndev,
++			    const struct brcmf_event_msg *e, void *data)
++{
++	s32 err = 0;
++	u32 event = be32_to_cpu(e->event_type);
++	u32 status = be32_to_cpu(e->status);
++
++	if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
++		if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status))
++			brcmf_bss_roaming_done(cfg_priv, ndev, e);
++		else
++			brcmf_bss_connect_done(cfg_priv, ndev, e, true);
++	}
++
++	return err;
++}
++
++static s32
++brcmf_notify_mic_status(struct brcmf_cfg80211_priv *cfg_priv,
++			struct net_device *ndev,
++			const struct brcmf_event_msg *e, void *data)
++{
++	u16 flags = be16_to_cpu(e->flags);
++	enum nl80211_key_type key_type;
++
++	if (flags & BRCMF_EVENT_MSG_GROUP)
++		key_type = NL80211_KEYTYPE_GROUP;
++	else
++		key_type = NL80211_KEYTYPE_PAIRWISE;
++
++	cfg80211_michael_mic_failure(ndev, (u8 *)&e->addr, key_type, -1,
++				     NULL, GFP_KERNEL);
++
++	return 0;
++}
++
++static s32
++brcmf_notify_scan_status(struct brcmf_cfg80211_priv *cfg_priv,
++			 struct net_device *ndev,
++			 const struct brcmf_event_msg *e, void *data)
++{
++	struct brcmf_channel_info_le channel_inform_le;
++	struct brcmf_scan_results_le *bss_list_le;
++	u32 len = WL_SCAN_BUF_MAX;
++	s32 err = 0;
++	bool scan_abort = false;
++	u32 scan_channel;
++
++	WL_TRACE("Enter\n");
++
++	if (cfg_priv->iscan_on && cfg_priv->iscan_kickstart) {
++		WL_TRACE("Exit\n");
++		return brcmf_wakeup_iscan(cfg_to_iscan(cfg_priv));
++	}
++
++	if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
++		WL_ERR("Scan complete while device not scanning\n");
++		scan_abort = true;
++		err = -EINVAL;
++		goto scan_done_out;
++	}
++
++	err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_CHANNEL, &channel_inform_le,
++			      sizeof(channel_inform_le));
++	if (err) {
++		WL_ERR("scan busy (%d)\n", err);
++		scan_abort = true;
++		goto scan_done_out;
++	}
++	scan_channel = le32_to_cpu(channel_inform_le.scan_channel);
++	if (scan_channel)
++		WL_CONN("channel_inform.scan_channel (%d)\n", scan_channel);
++	cfg_priv->bss_list = cfg_priv->scan_results;
++	bss_list_le = (struct brcmf_scan_results_le *) cfg_priv->bss_list;
++
++	memset(cfg_priv->scan_results, 0, len);
++	bss_list_le->buflen = cpu_to_le32(len);
++	err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN_RESULTS,
++			      cfg_priv->scan_results, len);
++	if (err) {
++		WL_ERR("%s Scan_results error (%d)\n", ndev->name, err);
++		err = -EINVAL;
++		scan_abort = true;
++		goto scan_done_out;
++	}
++	cfg_priv->scan_results->buflen = le32_to_cpu(bss_list_le->buflen);
++	cfg_priv->scan_results->version = le32_to_cpu(bss_list_le->version);
++	cfg_priv->scan_results->count = le32_to_cpu(bss_list_le->count);
++
++	err = brcmf_inform_bss(cfg_priv);
++	if (err) {
++		scan_abort = true;
++		goto scan_done_out;
++	}
++
++scan_done_out:
++	if (cfg_priv->scan_request) {
++		WL_SCAN("calling cfg80211_scan_done\n");
++		cfg80211_scan_done(cfg_priv->scan_request, scan_abort);
++		brcmf_set_mpc(ndev, 1);
++		cfg_priv->scan_request = NULL;
++	}
++
++	WL_TRACE("Exit\n");
++
++	return err;
++}
++
++static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
++{
++	conf->mode = (u32)-1;
++	conf->frag_threshold = (u32)-1;
++	conf->rts_threshold = (u32)-1;
++	conf->retry_short = (u32)-1;
++	conf->retry_long = (u32)-1;
++	conf->tx_power = -1;
++}
++
++static void brcmf_init_eloop_handler(struct brcmf_cfg80211_event_loop *el)
++{
++	memset(el, 0, sizeof(*el));
++	el->handler[BRCMF_E_SCAN_COMPLETE] = brcmf_notify_scan_status;
++	el->handler[BRCMF_E_LINK] = brcmf_notify_connect_status;
++	el->handler[BRCMF_E_ROAM] = brcmf_notify_roaming_status;
++	el->handler[BRCMF_E_MIC_ERROR] = brcmf_notify_mic_status;
++	el->handler[BRCMF_E_SET_SSID] = brcmf_notify_connect_status;
++}
++
++static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	kfree(cfg_priv->scan_results);
++	cfg_priv->scan_results = NULL;
++	kfree(cfg_priv->bss_info);
++	cfg_priv->bss_info = NULL;
++	kfree(cfg_priv->conf);
++	cfg_priv->conf = NULL;
++	kfree(cfg_priv->profile);
++	cfg_priv->profile = NULL;
++	kfree(cfg_priv->scan_req_int);
++	cfg_priv->scan_req_int = NULL;
++	kfree(cfg_priv->dcmd_buf);
++	cfg_priv->dcmd_buf = NULL;
++	kfree(cfg_priv->extra_buf);
++	cfg_priv->extra_buf = NULL;
++	kfree(cfg_priv->iscan);
++	cfg_priv->iscan = NULL;
++	kfree(cfg_priv->pmk_list);
++	cfg_priv->pmk_list = NULL;
++}
++
++static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	cfg_priv->scan_results = kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL);
++	if (!cfg_priv->scan_results)
++		goto init_priv_mem_out;
++	cfg_priv->conf = kzalloc(sizeof(*cfg_priv->conf), GFP_KERNEL);
++	if (!cfg_priv->conf)
++		goto init_priv_mem_out;
++	cfg_priv->profile = kzalloc(sizeof(*cfg_priv->profile), GFP_KERNEL);
++	if (!cfg_priv->profile)
++		goto init_priv_mem_out;
++	cfg_priv->bss_info = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
++	if (!cfg_priv->bss_info)
++		goto init_priv_mem_out;
++	cfg_priv->scan_req_int = kzalloc(sizeof(*cfg_priv->scan_req_int),
++					 GFP_KERNEL);
++	if (!cfg_priv->scan_req_int)
++		goto init_priv_mem_out;
++	cfg_priv->dcmd_buf = kzalloc(WL_DCMD_LEN_MAX, GFP_KERNEL);
++	if (!cfg_priv->dcmd_buf)
++		goto init_priv_mem_out;
++	cfg_priv->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
++	if (!cfg_priv->extra_buf)
++		goto init_priv_mem_out;
++	cfg_priv->iscan = kzalloc(sizeof(*cfg_priv->iscan), GFP_KERNEL);
++	if (!cfg_priv->iscan)
++		goto init_priv_mem_out;
++	cfg_priv->pmk_list = kzalloc(sizeof(*cfg_priv->pmk_list), GFP_KERNEL);
++	if (!cfg_priv->pmk_list)
++		goto init_priv_mem_out;
++
++	return 0;
++
++init_priv_mem_out:
++	brcmf_deinit_priv_mem(cfg_priv);
++
++	return -ENOMEM;
++}
++
++/*
++* retrieve first queued event from head
++*/
++
++static struct brcmf_cfg80211_event_q *brcmf_deq_event(
++	struct brcmf_cfg80211_priv *cfg_priv)
++{
++	struct brcmf_cfg80211_event_q *e = NULL;
++
++	spin_lock_irq(&cfg_priv->evt_q_lock);
++	if (!list_empty(&cfg_priv->evt_q_list)) {
++		e = list_first_entry(&cfg_priv->evt_q_list,
++				     struct brcmf_cfg80211_event_q, evt_q_list);
++		list_del(&e->evt_q_list);
++	}
++	spin_unlock_irq(&cfg_priv->evt_q_lock);
++
++	return e;
++}
++
++/*
++*	push event to tail of the queue
++*
++*	remark: this function may not sleep as it is called in atomic context.
++*/
++
++static s32
++brcmf_enq_event(struct brcmf_cfg80211_priv *cfg_priv, u32 event,
++		const struct brcmf_event_msg *msg)
++{
++	struct brcmf_cfg80211_event_q *e;
++	s32 err = 0;
++	ulong flags;
++
++	e = kzalloc(sizeof(struct brcmf_cfg80211_event_q), GFP_ATOMIC);
++	if (!e)
++		return -ENOMEM;
++
++	e->etype = event;
++	memcpy(&e->emsg, msg, sizeof(struct brcmf_event_msg));
++
++	spin_lock_irqsave(&cfg_priv->evt_q_lock, flags);
++	list_add_tail(&e->evt_q_list, &cfg_priv->evt_q_list);
++	spin_unlock_irqrestore(&cfg_priv->evt_q_lock, flags);
++
++	return err;
++}
++
++static void brcmf_put_event(struct brcmf_cfg80211_event_q *e)
++{
++	kfree(e);
++}
++
++static void brcmf_cfg80211_event_handler(struct work_struct *work)
++{
++	struct brcmf_cfg80211_priv *cfg_priv =
++			container_of(work, struct brcmf_cfg80211_priv,
++				     event_work);
++	struct brcmf_cfg80211_event_q *e;
++
++	e = brcmf_deq_event(cfg_priv);
++	if (unlikely(!e)) {
++		WL_ERR("event queue empty...\n");
++		return;
++	}
++
++	do {
++		WL_INFO("event type (%d)\n", e->etype);
++		if (cfg_priv->el.handler[e->etype])
++			cfg_priv->el.handler[e->etype](cfg_priv,
++						       cfg_to_ndev(cfg_priv),
++						       &e->emsg, e->edata);
++		else
++			WL_INFO("Unknown Event (%d): ignoring\n", e->etype);
++		brcmf_put_event(e);
++	} while ((e = brcmf_deq_event(cfg_priv)));
++
++}
++
++static void brcmf_init_eq(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	spin_lock_init(&cfg_priv->evt_q_lock);
++	INIT_LIST_HEAD(&cfg_priv->evt_q_list);
++}
++
++static void brcmf_flush_eq(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	struct brcmf_cfg80211_event_q *e;
++
++	spin_lock_irq(&cfg_priv->evt_q_lock);
++	while (!list_empty(&cfg_priv->evt_q_list)) {
++		e = list_first_entry(&cfg_priv->evt_q_list,
++				     struct brcmf_cfg80211_event_q, evt_q_list);
++		list_del(&e->evt_q_list);
++		kfree(e);
++	}
++	spin_unlock_irq(&cfg_priv->evt_q_lock);
++}
++
++static s32 wl_init_priv(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	s32 err = 0;
++
++	cfg_priv->scan_request = NULL;
++	cfg_priv->pwr_save = true;
++	cfg_priv->iscan_on = true;	/* iscan on & off switch.
++				 we enable iscan per default */
++	cfg_priv->roam_on = true;	/* roam on & off switch.
++				 we enable roam per default */
++
++	cfg_priv->iscan_kickstart = false;
++	cfg_priv->active_scan = true;	/* we do active scan for
++				 specific scan per default */
++	cfg_priv->dongle_up = false;	/* dongle is not up yet */
++	brcmf_init_eq(cfg_priv);
++	err = brcmf_init_priv_mem(cfg_priv);
++	if (err)
++		return err;
++	INIT_WORK(&cfg_priv->event_work, brcmf_cfg80211_event_handler);
++	brcmf_init_eloop_handler(&cfg_priv->el);
++	mutex_init(&cfg_priv->usr_sync);
++	err = brcmf_init_iscan(cfg_priv);
++	if (err)
++		return err;
++	brcmf_init_conf(cfg_priv->conf);
++	brcmf_init_prof(cfg_priv->profile);
++	brcmf_link_down(cfg_priv);
++
++	return err;
++}
++
++static void wl_deinit_priv(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	cancel_work_sync(&cfg_priv->event_work);
++	cfg_priv->dongle_up = false;	/* dongle down */
++	brcmf_flush_eq(cfg_priv);
++	brcmf_link_down(cfg_priv);
++	brcmf_term_iscan(cfg_priv);
++	brcmf_deinit_priv_mem(cfg_priv);
++}
++
++struct brcmf_cfg80211_dev *brcmf_cfg80211_attach(struct net_device *ndev,
++						 struct device *busdev,
++						 void *data)
++{
++	struct wireless_dev *wdev;
++	struct brcmf_cfg80211_priv *cfg_priv;
++	struct brcmf_cfg80211_iface *ci;
++	struct brcmf_cfg80211_dev *cfg_dev;
++	s32 err = 0;
++
++	if (!ndev) {
++		WL_ERR("ndev is invalid\n");
++		return NULL;
++	}
++	cfg_dev = kzalloc(sizeof(struct brcmf_cfg80211_dev), GFP_KERNEL);
++	if (!cfg_dev)
++		return NULL;
++
++	wdev = brcmf_alloc_wdev(sizeof(struct brcmf_cfg80211_iface), busdev);
++	if (IS_ERR(wdev)) {
++		kfree(cfg_dev);
++		return NULL;
++	}
++
++	wdev->iftype = brcmf_mode_to_nl80211_iftype(WL_MODE_BSS);
++	cfg_priv = wdev_to_cfg(wdev);
++	cfg_priv->wdev = wdev;
++	cfg_priv->pub = data;
++	ci = (struct brcmf_cfg80211_iface *)&cfg_priv->ci;
++	ci->cfg_priv = cfg_priv;
++	ndev->ieee80211_ptr = wdev;
++	SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
++	wdev->netdev = ndev;
++	err = wl_init_priv(cfg_priv);
++	if (err) {
++		WL_ERR("Failed to init iwm_priv (%d)\n", err);
++		goto cfg80211_attach_out;
++	}
++	brcmf_set_drvdata(cfg_dev, ci);
++
++	return cfg_dev;
++
++cfg80211_attach_out:
++	brcmf_free_wdev(cfg_priv);
++	kfree(cfg_dev);
++	return NULL;
++}
++
++void brcmf_cfg80211_detach(struct brcmf_cfg80211_dev *cfg_dev)
++{
++	struct brcmf_cfg80211_priv *cfg_priv;
++
++	cfg_priv = brcmf_priv_get(cfg_dev);
++
++	wl_deinit_priv(cfg_priv);
++	brcmf_free_wdev(cfg_priv);
++	brcmf_set_drvdata(cfg_dev, NULL);
++	kfree(cfg_dev);
++}
++
++void
++brcmf_cfg80211_event(struct net_device *ndev,
++		  const struct brcmf_event_msg *e, void *data)
++{
++	u32 event_type = be32_to_cpu(e->event_type);
++	struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
++
++	if (!brcmf_enq_event(cfg_priv, event_type, e))
++		schedule_work(&cfg_priv->event_work);
++}
++
++static s32 brcmf_dongle_mode(struct net_device *ndev, s32 iftype)
++{
++	s32 infra = 0;
++	s32 err = 0;
++
++	switch (iftype) {
++	case NL80211_IFTYPE_MONITOR:
++	case NL80211_IFTYPE_WDS:
++		WL_ERR("type (%d) : currently we do not support this mode\n",
++		       iftype);
++		err = -EINVAL;
++		return err;
++	case NL80211_IFTYPE_ADHOC:
++		infra = 0;
++		break;
++	case NL80211_IFTYPE_STATION:
++		infra = 1;
++		break;
++	default:
++		err = -EINVAL;
++		WL_ERR("invalid type (%d)\n", iftype);
++		return err;
++	}
++	err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &infra);
++	if (err) {
++		WL_ERR("WLC_SET_INFRA error (%d)\n", err);
++		return err;
++	}
++
++	return 0;
++}
++
++static s32 brcmf_dongle_eventmsg(struct net_device *ndev)
++{
++	/* Room for "event_msgs" + '\0' + bitvec */
++	s8 iovbuf[BRCMF_EVENTING_MASK_LEN + 12];
++	s8 eventmask[BRCMF_EVENTING_MASK_LEN];
++	s32 err = 0;
++
++	WL_TRACE("Enter\n");
++
++	/* Setup event_msgs */
++	brcmf_c_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN,
++			iovbuf, sizeof(iovbuf));
++	err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, iovbuf, sizeof(iovbuf));
++	if (err) {
++		WL_ERR("Get event_msgs error (%d)\n", err);
++		goto dongle_eventmsg_out;
++	}
++	memcpy(eventmask, iovbuf, BRCMF_EVENTING_MASK_LEN);
++
++	setbit(eventmask, BRCMF_E_SET_SSID);
++	setbit(eventmask, BRCMF_E_ROAM);
++	setbit(eventmask, BRCMF_E_PRUNE);
++	setbit(eventmask, BRCMF_E_AUTH);
++	setbit(eventmask, BRCMF_E_REASSOC);
++	setbit(eventmask, BRCMF_E_REASSOC_IND);
++	setbit(eventmask, BRCMF_E_DEAUTH_IND);
++	setbit(eventmask, BRCMF_E_DISASSOC_IND);
++	setbit(eventmask, BRCMF_E_DISASSOC);
++	setbit(eventmask, BRCMF_E_JOIN);
++	setbit(eventmask, BRCMF_E_ASSOC_IND);
++	setbit(eventmask, BRCMF_E_PSK_SUP);
++	setbit(eventmask, BRCMF_E_LINK);
++	setbit(eventmask, BRCMF_E_NDIS_LINK);
++	setbit(eventmask, BRCMF_E_MIC_ERROR);
++	setbit(eventmask, BRCMF_E_PMKID_CACHE);
++	setbit(eventmask, BRCMF_E_TXFAIL);
++	setbit(eventmask, BRCMF_E_JOIN_START);
++	setbit(eventmask, BRCMF_E_SCAN_COMPLETE);
++
++	brcmf_c_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN,
++			iovbuf, sizeof(iovbuf));
++	err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
++	if (err) {
++		WL_ERR("Set event_msgs error (%d)\n", err);
++		goto dongle_eventmsg_out;
++	}
++
++dongle_eventmsg_out:
++	WL_TRACE("Exit\n");
++	return err;
++}
++
++static s32
++brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
++{
++	s8 iovbuf[32];
++	s32 err = 0;
++	__le32 roamtrigger[2];
++	__le32 roam_delta[2];
++	__le32 bcn_to_le;
++	__le32 roamvar_le;
++
++	/*
++	 * Setup timeout if Beacons are lost and roam is
++	 * off to report link down
++	 */
++	if (roamvar) {
++		bcn_to_le = cpu_to_le32(bcn_timeout);
++		brcmf_c_mkiovar("bcn_timeout", (char *)&bcn_to_le,
++			sizeof(bcn_to_le), iovbuf, sizeof(iovbuf));
++		err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR,
++				   iovbuf, sizeof(iovbuf));
++		if (err) {
++			WL_ERR("bcn_timeout error (%d)\n", err);
++			goto dongle_rom_out;
++		}
++	}
++
++	/*
++	 * Enable/Disable built-in roaming to allow supplicant
++	 * to take care of roaming
++	 */
++	WL_INFO("Internal Roaming = %s\n", roamvar ? "Off" : "On");
++	roamvar_le = cpu_to_le32(roamvar);
++	brcmf_c_mkiovar("roam_off", (char *)&roamvar_le,
++				sizeof(roamvar_le), iovbuf, sizeof(iovbuf));
++	err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
++	if (err) {
++		WL_ERR("roam_off error (%d)\n", err);
++		goto dongle_rom_out;
++	}
++
++	roamtrigger[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL);
++	roamtrigger[1] = cpu_to_le32(BRCM_BAND_ALL);
++	err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_ROAM_TRIGGER,
++			(void *)roamtrigger, sizeof(roamtrigger));
++	if (err) {
++		WL_ERR("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
++		goto dongle_rom_out;
++	}
++
++	roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA);
++	roam_delta[1] = cpu_to_le32(BRCM_BAND_ALL);
++	err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_ROAM_DELTA,
++				(void *)roam_delta, sizeof(roam_delta));
++	if (err) {
++		WL_ERR("WLC_SET_ROAM_DELTA error (%d)\n", err);
++		goto dongle_rom_out;
++	}
++
++dongle_rom_out:
++	return err;
++}
++
++static s32
++brcmf_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
++		      s32 scan_unassoc_time, s32 scan_passive_time)
++{
++	s32 err = 0;
++	__le32 scan_assoc_tm_le = cpu_to_le32(scan_assoc_time);
++	__le32 scan_unassoc_tm_le = cpu_to_le32(scan_unassoc_time);
++	__le32 scan_passive_tm_le = cpu_to_le32(scan_passive_time);
++
++	err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_CHANNEL_TIME,
++			   &scan_assoc_tm_le, sizeof(scan_assoc_tm_le));
++	if (err) {
++		if (err == -EOPNOTSUPP)
++			WL_INFO("Scan assoc time is not supported\n");
++		else
++			WL_ERR("Scan assoc time error (%d)\n", err);
++		goto dongle_scantime_out;
++	}
++	err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_UNASSOC_TIME,
++			   &scan_unassoc_tm_le, sizeof(scan_unassoc_tm_le));
++	if (err) {
++		if (err == -EOPNOTSUPP)
++			WL_INFO("Scan unassoc time is not supported\n");
++		else
++			WL_ERR("Scan unassoc time error (%d)\n", err);
++		goto dongle_scantime_out;
++	}
++
++	err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_PASSIVE_TIME,
++			   &scan_passive_tm_le, sizeof(scan_passive_tm_le));
++	if (err) {
++		if (err == -EOPNOTSUPP)
++			WL_INFO("Scan passive time is not supported\n");
++		else
++			WL_ERR("Scan passive time error (%d)\n", err);
++		goto dongle_scantime_out;
++	}
++
++dongle_scantime_out:
++	return err;
++}
++
++static s32 wl_update_wiphybands(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	struct wiphy *wiphy;
++	s32 phy_list;
++	s8 phy;
++	s32 err = 0;
++
++	err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCM_GET_PHYLIST,
++			      &phy_list, sizeof(phy_list));
++	if (err) {
++		WL_ERR("error (%d)\n", err);
++		return err;
++	}
++
++	phy = ((char *)&phy_list)[1];
++	WL_INFO("%c phy\n", phy);
++	if (phy == 'n' || phy == 'a') {
++		wiphy = cfg_to_wiphy(cfg_priv);
++		wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
++	}
++
++	return err;
++}
++
++static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	return wl_update_wiphybands(cfg_priv);
++}
++
++static s32 brcmf_config_dongle(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	struct net_device *ndev;
++	struct wireless_dev *wdev;
++	s32 power_mode;
++	s32 err = 0;
++
++	if (cfg_priv->dongle_up)
++		return err;
++
++	ndev = cfg_to_ndev(cfg_priv);
++	wdev = ndev->ieee80211_ptr;
++
++	brcmf_dongle_scantime(ndev, WL_SCAN_CHANNEL_TIME,
++			WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
++
++	err = brcmf_dongle_eventmsg(ndev);
++	if (err)
++		goto default_conf_out;
++
++	power_mode = cfg_priv->pwr_save ? PM_FAST : PM_OFF;
++	err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_PM, &power_mode);
++	if (err)
++		goto default_conf_out;
++	WL_INFO("power save set to %s\n",
++		(power_mode ? "enabled" : "disabled"));
++
++	err = brcmf_dongle_roam(ndev, (cfg_priv->roam_on ? 0 : 1),
++				WL_BEACON_TIMEOUT);
++	if (err)
++		goto default_conf_out;
++	err = brcmf_dongle_mode(ndev, wdev->iftype);
++	if (err && err != -EINPROGRESS)
++		goto default_conf_out;
++	err = brcmf_dongle_probecap(cfg_priv);
++	if (err)
++		goto default_conf_out;
++
++	/* -EINPROGRESS: Call commit handler */
++
++default_conf_out:
++
++	cfg_priv->dongle_up = true;
++
++	return err;
++
++}
++
++static int brcmf_debugfs_add_netdev_params(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	char buf[10+IFNAMSIZ];
++	struct dentry *fd;
++	s32 err = 0;
++
++	sprintf(buf, "netdev:%s", cfg_to_ndev(cfg_priv)->name);
++	cfg_priv->debugfsdir = debugfs_create_dir(buf,
++					cfg_to_wiphy(cfg_priv)->debugfsdir);
++
++	fd = debugfs_create_u16("beacon_int", S_IRUGO, cfg_priv->debugfsdir,
++		(u16 *)&cfg_priv->profile->beacon_interval);
++	if (!fd) {
++		err = -ENOMEM;
++		goto err_out;
++	}
++
++	fd = debugfs_create_u8("dtim_period", S_IRUGO, cfg_priv->debugfsdir,
++		(u8 *)&cfg_priv->profile->dtim_period);
++	if (!fd) {
++		err = -ENOMEM;
++		goto err_out;
++	}
++
++err_out:
++	return err;
++}
++
++static void brcmf_debugfs_remove_netdev(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	debugfs_remove_recursive(cfg_priv->debugfsdir);
++	cfg_priv->debugfsdir = NULL;
++}
++
++static s32 __brcmf_cfg80211_up(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	s32 err = 0;
++
++	set_bit(WL_STATUS_READY, &cfg_priv->status);
++
++	brcmf_debugfs_add_netdev_params(cfg_priv);
++
++	err = brcmf_config_dongle(cfg_priv);
++	if (err)
++		return err;
++
++	brcmf_invoke_iscan(cfg_priv);
++
++	return err;
++}
++
++static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	/*
++	 * While going down, if associated with AP disassociate
++	 * from AP to save power
++	 */
++	if ((test_bit(WL_STATUS_CONNECTED, &cfg_priv->status) ||
++	     test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) &&
++	     test_bit(WL_STATUS_READY, &cfg_priv->status)) {
++		WL_INFO("Disassociating from AP");
++		brcmf_link_down(cfg_priv);
++
++		/* Make sure WPA_Supplicant receives all the event
++		   generated due to DISASSOC call to the fw to keep
++		   the state fw and WPA_Supplicant state consistent
++		 */
++		brcmf_delay(500);
++	}
++
++	set_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
++	brcmf_term_iscan(cfg_priv);
++	if (cfg_priv->scan_request) {
++		cfg80211_scan_done(cfg_priv->scan_request, true);
++		/* May need to perform this to cover rmmod */
++		/* wl_set_mpc(cfg_to_ndev(wl), 1); */
++		cfg_priv->scan_request = NULL;
++	}
++	clear_bit(WL_STATUS_READY, &cfg_priv->status);
++	clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
++	clear_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
++
++	brcmf_debugfs_remove_netdev(cfg_priv);
++
++	return 0;
++}
++
++s32 brcmf_cfg80211_up(struct brcmf_cfg80211_dev *cfg_dev)
++{
++	struct brcmf_cfg80211_priv *cfg_priv;
++	s32 err = 0;
++
++	cfg_priv = brcmf_priv_get(cfg_dev);
++	mutex_lock(&cfg_priv->usr_sync);
++	err = __brcmf_cfg80211_up(cfg_priv);
++	mutex_unlock(&cfg_priv->usr_sync);
++
++	return err;
++}
++
++s32 brcmf_cfg80211_down(struct brcmf_cfg80211_dev *cfg_dev)
++{
++	struct brcmf_cfg80211_priv *cfg_priv;
++	s32 err = 0;
++
++	cfg_priv = brcmf_priv_get(cfg_dev);
++	mutex_lock(&cfg_priv->usr_sync);
++	err = __brcmf_cfg80211_down(cfg_priv);
++	mutex_unlock(&cfg_priv->usr_sync);
++
++	return err;
++}
++
++static __used s32 brcmf_add_ie(struct brcmf_cfg80211_priv *cfg_priv,
++			       u8 t, u8 l, u8 *v)
++{
++	struct brcmf_cfg80211_ie *ie = &cfg_priv->ie;
++	s32 err = 0;
++
++	if (ie->offset + l + 2 > WL_TLV_INFO_MAX) {
++		WL_ERR("ei crosses buffer boundary\n");
++		return -ENOSPC;
++	}
++	ie->buf[ie->offset] = t;
++	ie->buf[ie->offset + 1] = l;
++	memcpy(&ie->buf[ie->offset + 2], v, l);
++	ie->offset += l + 2;
++
++	return err;
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
+new file mode 100644
+index 0000000..b5d9b36
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
+@@ -0,0 +1,366 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef _wl_cfg80211_h_
++#define _wl_cfg80211_h_
++
++struct brcmf_cfg80211_conf;
++struct brcmf_cfg80211_iface;
++struct brcmf_cfg80211_priv;
++struct brcmf_cfg80211_security;
++struct brcmf_cfg80211_ibss;
++
++#define WL_DBG_NONE		0
++#define WL_DBG_CONN		(1 << 5)
++#define WL_DBG_SCAN		(1 << 4)
++#define WL_DBG_TRACE		(1 << 3)
++#define WL_DBG_INFO		(1 << 1)
++#define WL_DBG_ERR		(1 << 0)
++#define WL_DBG_MASK		((WL_DBG_INFO | WL_DBG_ERR | WL_DBG_TRACE) | \
++				(WL_DBG_SCAN) | (WL_DBG_CONN))
++
++#define	WL_ERR(fmt, ...)					\
++do {								\
++	if (brcmf_dbg_level & WL_DBG_ERR) {			\
++		if (net_ratelimit()) {				\
++			pr_err("ERROR @%s : " fmt,		\
++			       __func__, ##__VA_ARGS__);	\
++		}						\
++	}							\
++} while (0)
++
++#if (defined DEBUG)
++#define	WL_INFO(fmt, ...)					\
++do {								\
++	if (brcmf_dbg_level & WL_DBG_INFO) {			\
++		if (net_ratelimit()) {				\
++			pr_err("INFO @%s : " fmt,		\
++			       __func__, ##__VA_ARGS__);	\
++		}						\
++	}							\
++} while (0)
++
++#define	WL_TRACE(fmt, ...)					\
++do {								\
++	if (brcmf_dbg_level & WL_DBG_TRACE) {			\
++		if (net_ratelimit()) {				\
++			pr_err("TRACE @%s : " fmt,		\
++			       __func__, ##__VA_ARGS__);	\
++		}						\
++	}							\
++} while (0)
++
++#define	WL_SCAN(fmt, ...)					\
++do {								\
++	if (brcmf_dbg_level & WL_DBG_SCAN) {			\
++		if (net_ratelimit()) {				\
++			pr_err("SCAN @%s : " fmt,		\
++			       __func__, ##__VA_ARGS__);	\
++		}						\
++	}							\
++} while (0)
++
++#define	WL_CONN(fmt, ...)					\
++do {								\
++	if (brcmf_dbg_level & WL_DBG_CONN) {			\
++		if (net_ratelimit()) {				\
++			pr_err("CONN @%s : " fmt,		\
++			       __func__, ##__VA_ARGS__);	\
++		}						\
++	}							\
++} while (0)
++
++#else /* (defined DEBUG) */
++#define	WL_INFO(fmt, args...)
++#define	WL_TRACE(fmt, args...)
++#define	WL_SCAN(fmt, args...)
++#define	WL_CONN(fmt, args...)
++#endif /* (defined DEBUG) */
++
++#define WL_NUM_SCAN_MAX		1
++#define WL_NUM_PMKIDS_MAX	MAXPMKID	/* will be used
++						 * for 2.6.33 kernel
++						 * or later
++						 */
++#define WL_SCAN_BUF_MAX			(1024 * 8)
++#define WL_TLV_INFO_MAX			1024
++#define WL_BSS_INFO_MAX			2048
++#define WL_ASSOC_INFO_MAX	512	/*
++				 * needs to grab assoc info from dongle to
++				 * report it to cfg80211 through "connect"
++				 * event
++				 */
++#define WL_DCMD_LEN_MAX	1024
++#define WL_EXTRA_BUF_MAX	2048
++#define WL_ISCAN_BUF_MAX	2048	/*
++				 * the buf length can be BRCMF_DCMD_MAXLEN
++				 * to reduce iteration
++				 */
++#define WL_ISCAN_TIMER_INTERVAL_MS	3000
++#define WL_SCAN_ERSULTS_LAST	(BRCMF_SCAN_RESULTS_NO_MEM+1)
++#define WL_AP_MAX	256	/* virtually unlimitted as long
++				 * as kernel memory allows
++				 */
++
++#define WL_ROAM_TRIGGER_LEVEL		-75
++#define WL_ROAM_DELTA			20
++#define WL_BEACON_TIMEOUT		3
++
++#define WL_SCAN_CHANNEL_TIME		40
++#define WL_SCAN_UNASSOC_TIME		40
++#define WL_SCAN_PASSIVE_TIME		120
++
++/* dongle status */
++enum wl_status {
++	WL_STATUS_READY,
++	WL_STATUS_SCANNING,
++	WL_STATUS_SCAN_ABORTING,
++	WL_STATUS_CONNECTING,
++	WL_STATUS_CONNECTED
++};
++
++/* wi-fi mode */
++enum wl_mode {
++	WL_MODE_BSS,
++	WL_MODE_IBSS,
++	WL_MODE_AP
++};
++
++/* dongle profile list */
++enum wl_prof_list {
++	WL_PROF_MODE,
++	WL_PROF_SSID,
++	WL_PROF_SEC,
++	WL_PROF_IBSS,
++	WL_PROF_BAND,
++	WL_PROF_BSSID,
++	WL_PROF_ACT,
++	WL_PROF_BEACONINT,
++	WL_PROF_DTIMPERIOD
++};
++
++/* dongle iscan state */
++enum wl_iscan_state {
++	WL_ISCAN_STATE_IDLE,
++	WL_ISCAN_STATE_SCANING
++};
++
++/* dongle configuration */
++struct brcmf_cfg80211_conf {
++	u32 mode;		/* adhoc , infrastructure or ap */
++	u32 frag_threshold;
++	u32 rts_threshold;
++	u32 retry_short;
++	u32 retry_long;
++	s32 tx_power;
++	struct ieee80211_channel channel;
++};
++
++/* cfg80211 main event loop */
++struct brcmf_cfg80211_event_loop {
++	s32(*handler[BRCMF_E_LAST]) (struct brcmf_cfg80211_priv *cfg_priv,
++				     struct net_device *ndev,
++				     const struct brcmf_event_msg *e,
++				     void *data);
++};
++
++/* representing interface of cfg80211 plane */
++struct brcmf_cfg80211_iface {
++	struct brcmf_cfg80211_priv *cfg_priv;
++};
++
++struct brcmf_cfg80211_dev {
++	void *driver_data;	/* to store cfg80211 object information */
++};
++
++/* basic structure of scan request */
++struct brcmf_cfg80211_scan_req {
++	struct brcmf_ssid_le ssid_le;
++};
++
++/* basic structure of information element */
++struct brcmf_cfg80211_ie {
++	u16 offset;
++	u8 buf[WL_TLV_INFO_MAX];
++};
++
++/* event queue for cfg80211 main event */
++struct brcmf_cfg80211_event_q {
++	struct list_head evt_q_list;
++	u32 etype;
++	struct brcmf_event_msg emsg;
++	s8 edata[1];
++};
++
++/* security information with currently associated ap */
++struct brcmf_cfg80211_security {
++	u32 wpa_versions;
++	u32 auth_type;
++	u32 cipher_pairwise;
++	u32 cipher_group;
++	u32 wpa_auth;
++};
++
++/* ibss information for currently joined ibss network */
++struct brcmf_cfg80211_ibss {
++	u8 beacon_interval;	/* in millisecond */
++	u8 atim;		/* in millisecond */
++	s8 join_only;
++	u8 band;
++	u8 channel;
++};
++
++/* dongle profile */
++struct brcmf_cfg80211_profile {
++	u32 mode;
++	struct brcmf_ssid ssid;
++	u8 bssid[ETH_ALEN];
++	u16 beacon_interval;
++	u8 dtim_period;
++	struct brcmf_cfg80211_security sec;
++	struct brcmf_cfg80211_ibss ibss;
++	s32 band;
++};
++
++/* dongle iscan event loop */
++struct brcmf_cfg80211_iscan_eloop {
++	s32 (*handler[WL_SCAN_ERSULTS_LAST])
++		(struct brcmf_cfg80211_priv *cfg_priv);
++};
++
++/* dongle iscan controller */
++struct brcmf_cfg80211_iscan_ctrl {
++	struct net_device *ndev;
++	struct timer_list timer;
++	u32 timer_ms;
++	u32 timer_on;
++	s32 state;
++	struct work_struct work;
++	struct brcmf_cfg80211_iscan_eloop el;
++	void *data;
++	s8 dcmd_buf[BRCMF_DCMD_SMLEN];
++	s8 scan_buf[WL_ISCAN_BUF_MAX];
++};
++
++/* association inform */
++struct brcmf_cfg80211_connect_info {
++	u8 *req_ie;
++	s32 req_ie_len;
++	u8 *resp_ie;
++	s32 resp_ie_len;
++};
++
++/* assoc ie length */
++struct brcmf_cfg80211_assoc_ielen_le {
++	__le32 req_len;
++	__le32 resp_len;
++};
++
++/* wpa2 pmk list */
++struct brcmf_cfg80211_pmk_list {
++	struct pmkid_list pmkids;
++	struct pmkid foo[MAXPMKID - 1];
++};
++
++/* dongle private data of cfg80211 interface */
++struct brcmf_cfg80211_priv {
++	struct wireless_dev *wdev;	/* representing wl cfg80211 device */
++	struct brcmf_cfg80211_conf *conf;	/* dongle configuration */
++	struct cfg80211_scan_request *scan_request;	/* scan request
++							 object */
++	struct brcmf_cfg80211_event_loop el;	/* main event loop */
++	struct list_head evt_q_list;	/* used for event queue */
++	spinlock_t	 evt_q_lock;	/* for event queue synchronization */
++	struct mutex usr_sync;	/* maily for dongle up/down synchronization */
++	struct brcmf_scan_results *bss_list;	/* bss_list holding scanned
++						 ap information */
++	struct brcmf_scan_results *scan_results;
++	struct brcmf_cfg80211_scan_req *scan_req_int;	/* scan request object
++						 for internal purpose */
++	struct wl_cfg80211_bss_info *bss_info;	/* bss information for
++						 cfg80211 layer */
++	struct brcmf_cfg80211_ie ie;	/* information element object for
++					 internal purpose */
++	struct brcmf_cfg80211_profile *profile;	/* holding dongle profile */
++	struct brcmf_cfg80211_iscan_ctrl *iscan;	/* iscan controller */
++	struct brcmf_cfg80211_connect_info conn_info; /* association info */
++	struct brcmf_cfg80211_pmk_list *pmk_list;	/* wpa2 pmk list */
++	struct work_struct event_work;	/* event handler work struct */
++	unsigned long status;		/* current dongle status */
++	void *pub;
++	u32 channel;		/* current channel */
++	bool iscan_on;		/* iscan on/off switch */
++	bool iscan_kickstart;	/* indicate iscan already started */
++	bool active_scan;	/* current scan mode */
++	bool ibss_starter;	/* indicates this sta is ibss starter */
++	bool link_up;		/* link/connection up flag */
++	bool pwr_save;		/* indicate whether dongle to support
++					 power save mode */
++	bool dongle_up;		/* indicate whether dongle up or not */
++	bool roam_on;		/* on/off switch for dongle self-roaming */
++	bool scan_tried;	/* indicates if first scan attempted */
++	u8 *dcmd_buf;		/* dcmd buffer */
++	u8 *extra_buf;		/* maily to grab assoc information */
++	struct dentry *debugfsdir;
++	u8 ci[0] __aligned(NETDEV_ALIGN);
++};
++
++static inline struct wiphy *cfg_to_wiphy(struct brcmf_cfg80211_priv *w)
++{
++	return w->wdev->wiphy;
++}
++
++static inline struct brcmf_cfg80211_priv *wiphy_to_cfg(struct wiphy *w)
++{
++	return (struct brcmf_cfg80211_priv *)(wiphy_priv(w));
++}
++
++static inline struct brcmf_cfg80211_priv *wdev_to_cfg(struct wireless_dev *wd)
++{
++	return (struct brcmf_cfg80211_priv *)(wdev_priv(wd));
++}
++
++static inline struct net_device *cfg_to_ndev(struct brcmf_cfg80211_priv *cfg)
++{
++	return cfg->wdev->netdev;
++}
++
++static inline struct brcmf_cfg80211_priv *ndev_to_cfg(struct net_device *ndev)
++{
++	return wdev_to_cfg(ndev->ieee80211_ptr);
++}
++
++#define iscan_to_cfg(i) ((struct brcmf_cfg80211_priv *)(i->data))
++#define cfg_to_iscan(w) (w->iscan)
++
++static inline struct
++brcmf_cfg80211_connect_info *cfg_to_conn(struct brcmf_cfg80211_priv *cfg)
++{
++	return &cfg->conn_info;
++}
++
++extern struct brcmf_cfg80211_dev *brcmf_cfg80211_attach(struct net_device *ndev,
++							struct device *busdev,
++							void *data);
++extern void brcmf_cfg80211_detach(struct brcmf_cfg80211_dev *cfg);
++
++/* event handler from dongle */
++extern void brcmf_cfg80211_event(struct net_device *ndev,
++				 const struct brcmf_event_msg *e, void *data);
++extern s32 brcmf_cfg80211_up(struct brcmf_cfg80211_dev *cfg_dev);
++extern s32 brcmf_cfg80211_down(struct brcmf_cfg80211_dev *cfg_dev);
++
++#endif				/* _wl_cfg80211_h_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/Makefile b/drivers/net/wireless/brcm80211/brcmsmac/Makefile
+new file mode 100644
+index 0000000..3c1f39d
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/Makefile
+@@ -0,0 +1,48 @@
++#
++# Makefile fragment for Broadcom 802.11n Networking Device Driver
++#
++# Copyright (c) 2010 Broadcom Corporation
++#
++# Permission to use, copy, modify, and/or distribute this software for any
++# purpose with or without fee is hereby granted, provided that the above
++# copyright notice and this permission notice appear in all copies.
++#
++# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++
++ccflags-y := \
++	-D__CHECK_ENDIAN__ \
++	-I$(obj)				\
++	-I$(obj)/phy				\
++	-I$(obj)/../include
++
++BRCMSMAC_OFILES := \
++	mac80211_if.o \
++	ucode_loader.o \
++	ampdu.o \
++	antsel.o \
++	channel.o \
++	main.o \
++	phy_shim.o \
++	pmu.o \
++	rate.o \
++	stf.o \
++	aiutils.o \
++	phy/phy_cmn.o \
++	phy/phy_lcn.o \
++	phy/phy_n.o \
++	phy/phytbl_lcn.o \
++	phy/phytbl_n.o \
++	phy/phy_qmath.o \
++	dma.o \
++	brcms_trace_events.o
++
++MODULEPFX := brcmsmac
++
++obj-$(CONFIG_BRCMSMAC)	+= $(MODULEPFX).o
++$(MODULEPFX)-objs	= $(BRCMSMAC_OFILES)
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c
+new file mode 100644
+index 0000000..94e040a
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c
+@@ -0,0 +1,841 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ *
++ * File contents: support functions for PCI/PCIe
++ */
++
++#undef pr_fmt
++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
++
++#include <linux/printk.h>
++#include <linux/delay.h>
++
++#include <defs.h>
++#include <chipcommon.h>
++#include <brcmu_utils.h>
++#include <brcm_hw_ids.h>
++#include <soc.h>
++#include "types.h"
++#include "pub.h"
++#include "pmu.h"
++#include "aiutils.h"
++
++/* slow_clk_ctl */
++ /* slow clock source mask */
++#define SCC_SS_MASK		0x00000007
++ /* source of slow clock is LPO */
++#define	SCC_SS_LPO		0x00000000
++ /* source of slow clock is crystal */
++#define	SCC_SS_XTAL		0x00000001
++ /* source of slow clock is PCI */
++#define	SCC_SS_PCI		0x00000002
++ /* LPOFreqSel, 1: 160Khz, 0: 32KHz */
++#define SCC_LF			0x00000200
++ /* LPOPowerDown, 1: LPO is disabled, 0: LPO is enabled */
++#define SCC_LP			0x00000400
++ /* ForceSlowClk, 1: sb/cores running on slow clock, 0: power logic control */
++#define SCC_FS			0x00000800
++ /* IgnorePllOffReq, 1/0:
++  *  power logic ignores/honors PLL clock disable requests from core
++  */
++#define SCC_IP			0x00001000
++ /* XtalControlEn, 1/0:
++  *  power logic does/doesn't disable crystal when appropriate
++  */
++#define SCC_XC			0x00002000
++ /* XtalPU (RO), 1/0: crystal running/disabled */
++#define SCC_XP			0x00004000
++ /* ClockDivider (SlowClk = 1/(4+divisor)) */
++#define SCC_CD_MASK		0xffff0000
++#define SCC_CD_SHIFT		16
++
++/* system_clk_ctl */
++ /* ILPen: Enable Idle Low Power */
++#define	SYCC_IE			0x00000001
++ /* ALPen: Enable Active Low Power */
++#define	SYCC_AE			0x00000002
++ /* ForcePLLOn */
++#define	SYCC_FP			0x00000004
++ /* Force ALP (or HT if ALPen is not set */
++#define	SYCC_AR			0x00000008
++ /* Force HT */
++#define	SYCC_HR			0x00000010
++ /* ClkDiv  (ILP = 1/(4 * (divisor + 1)) */
++#define SYCC_CD_MASK		0xffff0000
++#define SYCC_CD_SHIFT		16
++
++#define CST4329_SPROM_OTP_SEL_MASK	0x00000003
++ /* OTP is powered up, use def. CIS, no SPROM */
++#define CST4329_DEFCIS_SEL		0
++ /* OTP is powered up, SPROM is present */
++#define CST4329_SPROM_SEL		1
++ /* OTP is powered up, no SPROM */
++#define CST4329_OTP_SEL			2
++ /* OTP is powered down, SPROM is present */
++#define CST4329_OTP_PWRDN		3
++
++#define CST4329_SPI_SDIO_MODE_MASK	0x00000004
++#define CST4329_SPI_SDIO_MODE_SHIFT	2
++
++/* 43224 chip-specific ChipControl register bits */
++#define CCTRL43224_GPIO_TOGGLE          0x8000
++ /* 12 mA drive strength */
++#define CCTRL_43224A0_12MA_LED_DRIVE    0x00F000F0
++ /* 12 mA drive strength for later 43224s */
++#define CCTRL_43224B0_12MA_LED_DRIVE    0xF0
++
++/* 43236 Chip specific ChipStatus register bits */
++#define CST43236_SFLASH_MASK		0x00000040
++#define CST43236_OTP_MASK		0x00000080
++#define CST43236_HSIC_MASK		0x00000100	/* USB/HSIC */
++#define CST43236_BP_CLK			0x00000200	/* 120/96Mbps */
++#define CST43236_BOOT_MASK		0x00001800
++#define CST43236_BOOT_SHIFT		11
++#define CST43236_BOOT_FROM_SRAM		0 /* boot from SRAM, ARM in reset */
++#define CST43236_BOOT_FROM_ROM		1 /* boot from ROM */
++#define CST43236_BOOT_FROM_FLASH	2 /* boot from FLASH */
++#define CST43236_BOOT_FROM_INVALID	3
++
++/* 4331 chip-specific ChipControl register bits */
++ /* 0 disable */
++#define CCTRL4331_BT_COEXIST		(1<<0)
++ /* 0 SECI is disabled (JTAG functional) */
++#define CCTRL4331_SECI			(1<<1)
++ /* 0 disable */
++#define CCTRL4331_EXT_LNA		(1<<2)
++ /* sprom/gpio13-15 mux */
++#define CCTRL4331_SPROM_GPIO13_15       (1<<3)
++ /* 0 ext pa disable, 1 ext pa enabled */
++#define CCTRL4331_EXTPA_EN		(1<<4)
++ /* set drive out GPIO_CLK on sprom_cs pin */
++#define CCTRL4331_GPIOCLK_ON_SPROMCS	(1<<5)
++ /* use sprom_cs pin as PCIE mdio interface */
++#define CCTRL4331_PCIE_MDIO_ON_SPROMCS	(1<<6)
++ /* aband extpa will be at gpio2/5 and sprom_dout */
++#define CCTRL4331_EXTPA_ON_GPIO2_5	(1<<7)
++ /* override core control on pipe_AuxClkEnable */
++#define CCTRL4331_OVR_PIPEAUXCLKEN	(1<<8)
++ /* override core control on pipe_AuxPowerDown */
++#define CCTRL4331_OVR_PIPEAUXPWRDOWN	(1<<9)
++ /* pcie_auxclkenable */
++#define CCTRL4331_PCIE_AUXCLKEN		(1<<10)
++ /* pcie_pipe_pllpowerdown */
++#define CCTRL4331_PCIE_PIPE_PLLDOWN	(1<<11)
++ /* enable bt_shd0 at gpio4 */
++#define CCTRL4331_BT_SHD0_ON_GPIO4	(1<<16)
++ /* enable bt_shd1 at gpio5 */
++#define CCTRL4331_BT_SHD1_ON_GPIO5	(1<<17)
++
++/* 4331 Chip specific ChipStatus register bits */
++ /* crystal frequency 20/40Mhz */
++#define	CST4331_XTAL_FREQ		0x00000001
++#define	CST4331_SPROM_PRESENT		0x00000002
++#define	CST4331_OTP_PRESENT		0x00000004
++#define	CST4331_LDO_RF			0x00000008
++#define	CST4331_LDO_PAR			0x00000010
++
++/* 4319 chip-specific ChipStatus register bits */
++#define	CST4319_SPI_CPULESSUSB		0x00000001
++#define	CST4319_SPI_CLK_POL		0x00000002
++#define	CST4319_SPI_CLK_PH		0x00000008
++ /* gpio [7:6], SDIO CIS selection */
++#define	CST4319_SPROM_OTP_SEL_MASK	0x000000c0
++#define	CST4319_SPROM_OTP_SEL_SHIFT	6
++ /* use default CIS, OTP is powered up */
++#define	CST4319_DEFCIS_SEL		0x00000000
++ /* use SPROM, OTP is powered up */
++#define	CST4319_SPROM_SEL		0x00000040
++ /* use OTP, OTP is powered up */
++#define	CST4319_OTP_SEL			0x00000080
++ /* use SPROM, OTP is powered down */
++#define	CST4319_OTP_PWRDN		0x000000c0
++ /* gpio [8], sdio/usb mode */
++#define	CST4319_SDIO_USB_MODE		0x00000100
++#define	CST4319_REMAP_SEL_MASK		0x00000600
++#define	CST4319_ILPDIV_EN		0x00000800
++#define	CST4319_XTAL_PD_POL		0x00001000
++#define	CST4319_LPO_SEL			0x00002000
++#define	CST4319_RES_INIT_MODE		0x0000c000
++ /* PALDO is configured with external PNP */
++#define	CST4319_PALDO_EXTPNP		0x00010000
++#define	CST4319_CBUCK_MODE_MASK		0x00060000
++#define CST4319_CBUCK_MODE_BURST	0x00020000
++#define CST4319_CBUCK_MODE_LPBURST	0x00060000
++#define	CST4319_RCAL_VALID		0x01000000
++#define	CST4319_RCAL_VALUE_MASK		0x3e000000
++#define	CST4319_RCAL_VALUE_SHIFT	25
++
++/* 4336 chip-specific ChipStatus register bits */
++#define	CST4336_SPI_MODE_MASK		0x00000001
++#define	CST4336_SPROM_PRESENT		0x00000002
++#define	CST4336_OTP_PRESENT		0x00000004
++#define	CST4336_ARMREMAP_0		0x00000008
++#define	CST4336_ILPDIV_EN_MASK		0x00000010
++#define	CST4336_ILPDIV_EN_SHIFT		4
++#define	CST4336_XTAL_PD_POL_MASK	0x00000020
++#define	CST4336_XTAL_PD_POL_SHIFT	5
++#define	CST4336_LPO_SEL_MASK		0x00000040
++#define	CST4336_LPO_SEL_SHIFT		6
++#define	CST4336_RES_INIT_MODE_MASK	0x00000180
++#define	CST4336_RES_INIT_MODE_SHIFT	7
++#define	CST4336_CBUCK_MODE_MASK		0x00000600
++#define	CST4336_CBUCK_MODE_SHIFT	9
++
++/* 4313 chip-specific ChipStatus register bits */
++#define	CST4313_SPROM_PRESENT			1
++#define	CST4313_OTP_PRESENT			2
++#define	CST4313_SPROM_OTP_SEL_MASK		0x00000002
++#define	CST4313_SPROM_OTP_SEL_SHIFT		0
++
++/* 4313 Chip specific ChipControl register bits */
++ /* 12 mA drive strengh for later 4313 */
++#define CCTRL_4313_12MA_LED_DRIVE    0x00000007
++
++/* Manufacturer Ids */
++#define	MFGID_ARM		0x43b
++#define	MFGID_BRCM		0x4bf
++#define	MFGID_MIPS		0x4a7
++
++/* Enumeration ROM registers */
++#define	ER_EROMENTRY		0x000
++#define	ER_REMAPCONTROL		0xe00
++#define	ER_REMAPSELECT		0xe04
++#define	ER_MASTERSELECT		0xe10
++#define	ER_ITCR			0xf00
++#define	ER_ITIP			0xf04
++
++/* Erom entries */
++#define	ER_TAG			0xe
++#define	ER_TAG1			0x6
++#define	ER_VALID		1
++#define	ER_CI			0
++#define	ER_MP			2
++#define	ER_ADD			4
++#define	ER_END			0xe
++#define	ER_BAD			0xffffffff
++
++/* EROM CompIdentA */
++#define	CIA_MFG_MASK		0xfff00000
++#define	CIA_MFG_SHIFT		20
++#define	CIA_CID_MASK		0x000fff00
++#define	CIA_CID_SHIFT		8
++#define	CIA_CCL_MASK		0x000000f0
++#define	CIA_CCL_SHIFT		4
++
++/* EROM CompIdentB */
++#define	CIB_REV_MASK		0xff000000
++#define	CIB_REV_SHIFT		24
++#define	CIB_NSW_MASK		0x00f80000
++#define	CIB_NSW_SHIFT		19
++#define	CIB_NMW_MASK		0x0007c000
++#define	CIB_NMW_SHIFT		14
++#define	CIB_NSP_MASK		0x00003e00
++#define	CIB_NSP_SHIFT		9
++#define	CIB_NMP_MASK		0x000001f0
++#define	CIB_NMP_SHIFT		4
++
++/* EROM AddrDesc */
++#define	AD_ADDR_MASK		0xfffff000
++#define	AD_SP_MASK		0x00000f00
++#define	AD_SP_SHIFT		8
++#define	AD_ST_MASK		0x000000c0
++#define	AD_ST_SHIFT		6
++#define	AD_ST_SLAVE		0x00000000
++#define	AD_ST_BRIDGE		0x00000040
++#define	AD_ST_SWRAP		0x00000080
++#define	AD_ST_MWRAP		0x000000c0
++#define	AD_SZ_MASK		0x00000030
++#define	AD_SZ_SHIFT		4
++#define	AD_SZ_4K		0x00000000
++#define	AD_SZ_8K		0x00000010
++#define	AD_SZ_16K		0x00000020
++#define	AD_SZ_SZD		0x00000030
++#define	AD_AG32			0x00000008
++#define	AD_ADDR_ALIGN		0x00000fff
++#define	AD_SZ_BASE		0x00001000	/* 4KB */
++
++/* EROM SizeDesc */
++#define	SD_SZ_MASK		0xfffff000
++#define	SD_SG32			0x00000008
++#define	SD_SZ_ALIGN		0x00000fff
++
++/* PCI config space bit 4 for 4306c0 slow clock source */
++#define	PCI_CFG_GPIO_SCS	0x10
++/* PCI config space GPIO 14 for Xtal power-up */
++#define PCI_CFG_GPIO_XTAL	0x40
++/* PCI config space GPIO 15 for PLL power-down */
++#define PCI_CFG_GPIO_PLL	0x80
++
++/* power control defines */
++#define PLL_DELAY		150	/* us pll on delay */
++#define FREF_DELAY		200	/* us fref change delay */
++#define	XTAL_ON_DELAY		1000	/* us crystal power-on delay */
++
++/* resetctrl */
++#define	AIRC_RESET		1
++
++#define	NOREV		-1	/* Invalid rev */
++
++/* GPIO Based LED powersave defines */
++#define DEFAULT_GPIO_ONTIME	10	/* Default: 10% on */
++#define DEFAULT_GPIO_OFFTIME	90	/* Default: 10% on */
++
++/* When Srom support present, fields in sromcontrol */
++#define	SRC_START		0x80000000
++#define	SRC_BUSY		0x80000000
++#define	SRC_OPCODE		0x60000000
++#define	SRC_OP_READ		0x00000000
++#define	SRC_OP_WRITE		0x20000000
++#define	SRC_OP_WRDIS		0x40000000
++#define	SRC_OP_WREN		0x60000000
++#define	SRC_OTPSEL		0x00000010
++#define	SRC_LOCK		0x00000008
++#define	SRC_SIZE_MASK		0x00000006
++#define	SRC_SIZE_1K		0x00000000
++#define	SRC_SIZE_4K		0x00000002
++#define	SRC_SIZE_16K		0x00000004
++#define	SRC_SIZE_SHIFT		1
++#define	SRC_PRESENT		0x00000001
++
++/* External PA enable mask */
++#define GPIO_CTRL_EPA_EN_MASK 0x40
++
++#define DEFAULT_GPIOTIMERVAL \
++	((DEFAULT_GPIO_ONTIME << GPIO_ONTIME_SHIFT) | DEFAULT_GPIO_OFFTIME)
++
++#define	BADIDX		(SI_MAXCORES + 1)
++
++#define	IS_SIM(chippkg)	\
++	((chippkg == HDLSIM_PKG_ID) || (chippkg == HWSIM_PKG_ID))
++
++#define PCIE(sih)	(ai_get_buscoretype(sih) == PCIE_CORE_ID)
++
++#define PCI_FORCEHT(sih) (PCIE(sih) && (ai_get_chip_id(sih) == BCM4716_CHIP_ID))
++
++#ifdef DEBUG
++#define	SI_MSG(fmt, ...)	pr_debug(fmt, ##__VA_ARGS__)
++#else
++#define	SI_MSG(fmt, ...)	no_printk(fmt, ##__VA_ARGS__)
++#endif				/* DEBUG */
++
++#define	GOODCOREADDR(x, b) \
++	(((x) >= (b)) && ((x) < ((b) + SI_MAXCORES * SI_CORE_SIZE)) && \
++		IS_ALIGNED((x), SI_CORE_SIZE))
++
++struct aidmp {
++	u32 oobselina30;	/* 0x000 */
++	u32 oobselina74;	/* 0x004 */
++	u32 PAD[6];
++	u32 oobselinb30;	/* 0x020 */
++	u32 oobselinb74;	/* 0x024 */
++	u32 PAD[6];
++	u32 oobselinc30;	/* 0x040 */
++	u32 oobselinc74;	/* 0x044 */
++	u32 PAD[6];
++	u32 oobselind30;	/* 0x060 */
++	u32 oobselind74;	/* 0x064 */
++	u32 PAD[38];
++	u32 oobselouta30;	/* 0x100 */
++	u32 oobselouta74;	/* 0x104 */
++	u32 PAD[6];
++	u32 oobseloutb30;	/* 0x120 */
++	u32 oobseloutb74;	/* 0x124 */
++	u32 PAD[6];
++	u32 oobseloutc30;	/* 0x140 */
++	u32 oobseloutc74;	/* 0x144 */
++	u32 PAD[6];
++	u32 oobseloutd30;	/* 0x160 */
++	u32 oobseloutd74;	/* 0x164 */
++	u32 PAD[38];
++	u32 oobsynca;	/* 0x200 */
++	u32 oobseloutaen;	/* 0x204 */
++	u32 PAD[6];
++	u32 oobsyncb;	/* 0x220 */
++	u32 oobseloutben;	/* 0x224 */
++	u32 PAD[6];
++	u32 oobsyncc;	/* 0x240 */
++	u32 oobseloutcen;	/* 0x244 */
++	u32 PAD[6];
++	u32 oobsyncd;	/* 0x260 */
++	u32 oobseloutden;	/* 0x264 */
++	u32 PAD[38];
++	u32 oobaextwidth;	/* 0x300 */
++	u32 oobainwidth;	/* 0x304 */
++	u32 oobaoutwidth;	/* 0x308 */
++	u32 PAD[5];
++	u32 oobbextwidth;	/* 0x320 */
++	u32 oobbinwidth;	/* 0x324 */
++	u32 oobboutwidth;	/* 0x328 */
++	u32 PAD[5];
++	u32 oobcextwidth;	/* 0x340 */
++	u32 oobcinwidth;	/* 0x344 */
++	u32 oobcoutwidth;	/* 0x348 */
++	u32 PAD[5];
++	u32 oobdextwidth;	/* 0x360 */
++	u32 oobdinwidth;	/* 0x364 */
++	u32 oobdoutwidth;	/* 0x368 */
++	u32 PAD[37];
++	u32 ioctrlset;	/* 0x400 */
++	u32 ioctrlclear;	/* 0x404 */
++	u32 ioctrl;		/* 0x408 */
++	u32 PAD[61];
++	u32 iostatus;	/* 0x500 */
++	u32 PAD[127];
++	u32 ioctrlwidth;	/* 0x700 */
++	u32 iostatuswidth;	/* 0x704 */
++	u32 PAD[62];
++	u32 resetctrl;	/* 0x800 */
++	u32 resetstatus;	/* 0x804 */
++	u32 resetreadid;	/* 0x808 */
++	u32 resetwriteid;	/* 0x80c */
++	u32 PAD[60];
++	u32 errlogctrl;	/* 0x900 */
++	u32 errlogdone;	/* 0x904 */
++	u32 errlogstatus;	/* 0x908 */
++	u32 errlogaddrlo;	/* 0x90c */
++	u32 errlogaddrhi;	/* 0x910 */
++	u32 errlogid;	/* 0x914 */
++	u32 errloguser;	/* 0x918 */
++	u32 errlogflags;	/* 0x91c */
++	u32 PAD[56];
++	u32 intstatus;	/* 0xa00 */
++	u32 PAD[127];
++	u32 config;		/* 0xe00 */
++	u32 PAD[63];
++	u32 itcr;		/* 0xf00 */
++	u32 PAD[3];
++	u32 itipooba;	/* 0xf10 */
++	u32 itipoobb;	/* 0xf14 */
++	u32 itipoobc;	/* 0xf18 */
++	u32 itipoobd;	/* 0xf1c */
++	u32 PAD[4];
++	u32 itipoobaout;	/* 0xf30 */
++	u32 itipoobbout;	/* 0xf34 */
++	u32 itipoobcout;	/* 0xf38 */
++	u32 itipoobdout;	/* 0xf3c */
++	u32 PAD[4];
++	u32 itopooba;	/* 0xf50 */
++	u32 itopoobb;	/* 0xf54 */
++	u32 itopoobc;	/* 0xf58 */
++	u32 itopoobd;	/* 0xf5c */
++	u32 PAD[4];
++	u32 itopoobain;	/* 0xf70 */
++	u32 itopoobbin;	/* 0xf74 */
++	u32 itopoobcin;	/* 0xf78 */
++	u32 itopoobdin;	/* 0xf7c */
++	u32 PAD[4];
++	u32 itopreset;	/* 0xf90 */
++	u32 PAD[15];
++	u32 peripherialid4;	/* 0xfd0 */
++	u32 peripherialid5;	/* 0xfd4 */
++	u32 peripherialid6;	/* 0xfd8 */
++	u32 peripherialid7;	/* 0xfdc */
++	u32 peripherialid0;	/* 0xfe0 */
++	u32 peripherialid1;	/* 0xfe4 */
++	u32 peripherialid2;	/* 0xfe8 */
++	u32 peripherialid3;	/* 0xfec */
++	u32 componentid0;	/* 0xff0 */
++	u32 componentid1;	/* 0xff4 */
++	u32 componentid2;	/* 0xff8 */
++	u32 componentid3;	/* 0xffc */
++};
++
++static bool
++ai_buscore_setup(struct si_info *sii, struct bcma_device *cc)
++{
++	/* no cores found, bail out */
++	if (cc->bus->nr_cores == 0)
++		return false;
++
++	/* get chipcommon rev */
++	sii->pub.ccrev = cc->id.rev;
++
++	/* get chipcommon chipstatus */
++	sii->chipst = bcma_read32(cc, CHIPCREGOFFS(chipstatus));
++
++	/* get chipcommon capabilites */
++	sii->pub.cccaps = bcma_read32(cc, CHIPCREGOFFS(capabilities));
++
++	/* get pmu rev and caps */
++	if (ai_get_cccaps(&sii->pub) & CC_CAP_PMU) {
++		sii->pub.pmucaps = bcma_read32(cc,
++					       CHIPCREGOFFS(pmucapabilities));
++		sii->pub.pmurev = sii->pub.pmucaps & PCAP_REV_MASK;
++	}
++
++	/* figure out buscore */
++	sii->buscore = ai_findcore(&sii->pub, PCIE_CORE_ID, 0);
++
++	return true;
++}
++
++static struct si_info *ai_doattach(struct si_info *sii,
++				   struct bcma_bus *pbus)
++{
++	struct si_pub *sih = &sii->pub;
++	u32 w, savewin;
++	struct bcma_device *cc;
++	struct ssb_sprom *sprom = &pbus->sprom;
++
++	savewin = 0;
++
++	sii->icbus = pbus;
++	sii->pcibus = pbus->host_pci;
++
++	/* switch to Chipcommon core */
++	cc = pbus->drv_cc.core;
++
++	sih->chip = pbus->chipinfo.id;
++	sih->chiprev = pbus->chipinfo.rev;
++	sih->chippkg = pbus->chipinfo.pkg;
++	sih->boardvendor = pbus->boardinfo.vendor;
++	sih->boardtype = pbus->boardinfo.type;
++
++	if (!ai_buscore_setup(sii, cc))
++		goto exit;
++
++	/* === NVRAM, clock is ready === */
++	bcma_write32(cc, CHIPCREGOFFS(gpiopullup), 0);
++	bcma_write32(cc, CHIPCREGOFFS(gpiopulldown), 0);
++
++	/* PMU specific initializations */
++	if (ai_get_cccaps(sih) & CC_CAP_PMU) {
++		si_pmu_init(sih);
++		(void)si_pmu_measure_alpclk(sih);
++		si_pmu_res_init(sih);
++	}
++
++	/* setup the GPIO based LED powersave register */
++	w = (sprom->leddc_on_time << BCMA_CC_GPIOTIMER_ONTIME_SHIFT) |
++		 (sprom->leddc_off_time << BCMA_CC_GPIOTIMER_OFFTIME_SHIFT);
++	if (w == 0)
++		w = DEFAULT_GPIOTIMERVAL;
++	ai_cc_reg(sih, offsetof(struct chipcregs, gpiotimerval),
++		  ~0, w);
++
++	if (ai_get_chip_id(sih) == BCM43224_CHIP_ID) {
++		/*
++		 * enable 12 mA drive strenth for 43224 and
++		 * set chipControl register bit 15
++		 */
++		if (ai_get_chiprev(sih) == 0) {
++			SI_MSG("Applying 43224A0 WARs\n");
++			ai_cc_reg(sih, offsetof(struct chipcregs, chipcontrol),
++				  CCTRL43224_GPIO_TOGGLE,
++				  CCTRL43224_GPIO_TOGGLE);
++			si_pmu_chipcontrol(sih, 0, CCTRL_43224A0_12MA_LED_DRIVE,
++					   CCTRL_43224A0_12MA_LED_DRIVE);
++		}
++		if (ai_get_chiprev(sih) >= 1) {
++			SI_MSG("Applying 43224B0+ WARs\n");
++			si_pmu_chipcontrol(sih, 0, CCTRL_43224B0_12MA_LED_DRIVE,
++					   CCTRL_43224B0_12MA_LED_DRIVE);
++		}
++	}
++
++	if (ai_get_chip_id(sih) == BCM4313_CHIP_ID) {
++		/*
++		 * enable 12 mA drive strenth for 4313 and
++		 * set chipControl register bit 1
++		 */
++		SI_MSG("Applying 4313 WARs\n");
++		si_pmu_chipcontrol(sih, 0, CCTRL_4313_12MA_LED_DRIVE,
++				   CCTRL_4313_12MA_LED_DRIVE);
++	}
++
++	return sii;
++
++ exit:
++
++	return NULL;
++}
++
++/*
++ * Allocate a si handle and do the attach.
++ */
++struct si_pub *
++ai_attach(struct bcma_bus *pbus)
++{
++	struct si_info *sii;
++
++	/* alloc struct si_info */
++	sii = kzalloc(sizeof(struct si_info), GFP_ATOMIC);
++	if (sii == NULL)
++		return NULL;
++
++	if (ai_doattach(sii, pbus) == NULL) {
++		kfree(sii);
++		return NULL;
++	}
++
++	return (struct si_pub *) sii;
++}
++
++/* may be called with core in reset */
++void ai_detach(struct si_pub *sih)
++{
++	struct si_info *sii;
++
++	struct si_pub *si_local = NULL;
++	memcpy(&si_local, &sih, sizeof(struct si_pub **));
++
++	sii = (struct si_info *)sih;
++
++	if (sii == NULL)
++		return;
++
++	kfree(sii);
++}
++
++/* return index of coreid or BADIDX if not found */
++struct bcma_device *ai_findcore(struct si_pub *sih, u16 coreid, u16 coreunit)
++{
++	struct bcma_device *core;
++	struct si_info *sii;
++	uint found;
++
++	sii = (struct si_info *)sih;
++
++	found = 0;
++
++	list_for_each_entry(core, &sii->icbus->cores, list)
++		if (core->id.id == coreid) {
++			if (found == coreunit)
++				return core;
++			found++;
++		}
++
++	return NULL;
++}
++
++/*
++ * read/modify chipcommon core register.
++ */
++uint ai_cc_reg(struct si_pub *sih, uint regoff, u32 mask, u32 val)
++{
++	struct bcma_device *cc;
++	u32 w;
++	struct si_info *sii;
++
++	sii = (struct si_info *)sih;
++	cc = sii->icbus->drv_cc.core;
++
++	/* mask and set */
++	if (mask || val) {
++		bcma_maskset32(cc, regoff, ~mask, val);
++	}
++
++	/* readback */
++	w = bcma_read32(cc, regoff);
++
++	return w;
++}
++
++/* return the slow clock source - LPO, XTAL, or PCI */
++static uint ai_slowclk_src(struct si_pub *sih, struct bcma_device *cc)
++{
++	return SCC_SS_XTAL;
++}
++
++/*
++* return the ILP (slowclock) min or max frequency
++* precondition: we've established the chip has dynamic clk control
++*/
++static uint ai_slowclk_freq(struct si_pub *sih, bool max_freq,
++			    struct bcma_device *cc)
++{
++	uint div;
++
++	/* Chipc rev 10 is InstaClock */
++	div = bcma_read32(cc, CHIPCREGOFFS(system_clk_ctl));
++	div = 4 * ((div >> SYCC_CD_SHIFT) + 1);
++	return max_freq ? XTALMAXFREQ : (XTALMINFREQ / div);
++}
++
++static void
++ai_clkctl_setdelay(struct si_pub *sih, struct bcma_device *cc)
++{
++	uint slowmaxfreq, pll_delay, slowclk;
++	uint pll_on_delay, fref_sel_delay;
++
++	pll_delay = PLL_DELAY;
++
++	/*
++	 * If the slow clock is not sourced by the xtal then
++	 * add the xtal_on_delay since the xtal will also be
++	 * powered down by dynamic clk control logic.
++	 */
++
++	slowclk = ai_slowclk_src(sih, cc);
++	if (slowclk != SCC_SS_XTAL)
++		pll_delay += XTAL_ON_DELAY;
++
++	/* Starting with 4318 it is ILP that is used for the delays */
++	slowmaxfreq =
++	    ai_slowclk_freq(sih, false, cc);
++
++	pll_on_delay = ((slowmaxfreq * pll_delay) + 999999) / 1000000;
++	fref_sel_delay = ((slowmaxfreq * FREF_DELAY) + 999999) / 1000000;
++
++	bcma_write32(cc, CHIPCREGOFFS(pll_on_delay), pll_on_delay);
++	bcma_write32(cc, CHIPCREGOFFS(fref_sel_delay), fref_sel_delay);
++}
++
++/* initialize power control delay registers */
++void ai_clkctl_init(struct si_pub *sih)
++{
++	struct bcma_device *cc;
++
++	if (!(ai_get_cccaps(sih) & CC_CAP_PWR_CTL))
++		return;
++
++	cc = ai_findcore(sih, BCMA_CORE_CHIPCOMMON, 0);
++	if (cc == NULL)
++		return;
++
++	/* set all Instaclk chip ILP to 1 MHz */
++	bcma_maskset32(cc, CHIPCREGOFFS(system_clk_ctl), SYCC_CD_MASK,
++		       (ILP_DIV_1MHZ << SYCC_CD_SHIFT));
++
++	ai_clkctl_setdelay(sih, cc);
++}
++
++/*
++ * return the value suitable for writing to the
++ * dot11 core FAST_PWRUP_DELAY register
++ */
++u16 ai_clkctl_fast_pwrup_delay(struct si_pub *sih)
++{
++	struct si_info *sii;
++	struct bcma_device *cc;
++	uint slowminfreq;
++	u16 fpdelay;
++
++	sii = (struct si_info *)sih;
++	if (ai_get_cccaps(sih) & CC_CAP_PMU) {
++		fpdelay = si_pmu_fast_pwrup_delay(sih);
++		return fpdelay;
++	}
++
++	if (!(ai_get_cccaps(sih) & CC_CAP_PWR_CTL))
++		return 0;
++
++	fpdelay = 0;
++	cc = ai_findcore(sih, CC_CORE_ID, 0);
++	if (cc) {
++		slowminfreq = ai_slowclk_freq(sih, false, cc);
++		fpdelay = (((bcma_read32(cc, CHIPCREGOFFS(pll_on_delay)) + 2)
++			    * 1000000) + (slowminfreq - 1)) / slowminfreq;
++	}
++	return fpdelay;
++}
++
++/*
++ *  clock control policy function throught chipcommon
++ *
++ *    set dynamic clk control mode (forceslow, forcefast, dynamic)
++ *    returns true if we are forcing fast clock
++ *    this is a wrapper over the next internal function
++ *      to allow flexible policy settings for outside caller
++ */
++bool ai_clkctl_cc(struct si_pub *sih, enum bcma_clkmode mode)
++{
++	struct si_info *sii;
++	struct bcma_device *cc;
++
++	sii = (struct si_info *)sih;
++
++	if (PCI_FORCEHT(sih))
++		return mode == BCMA_CLKMODE_FAST;
++
++	cc = ai_findcore(&sii->pub, BCMA_CORE_CHIPCOMMON, 0);
++	bcma_core_set_clockmode(cc, mode);
++	return mode == BCMA_CLKMODE_FAST;
++}
++
++void ai_pci_up(struct si_pub *sih)
++{
++	struct si_info *sii;
++	struct bcma_device *cc;
++
++	sii = (struct si_info *)sih;
++
++	if (PCI_FORCEHT(sih)) {
++		cc = ai_findcore(&sii->pub, BCMA_CORE_CHIPCOMMON, 0);
++		bcma_core_set_clockmode(cc, BCMA_CLKMODE_FAST);
++	}
++
++	if (PCIE(sih))
++		bcma_core_pci_extend_L1timer(&sii->icbus->drv_pci, true);
++}
++
++/* Unconfigure and/or apply various WARs when going down */
++void ai_pci_down(struct si_pub *sih)
++{
++	struct si_info *sii;
++	struct bcma_device *cc;
++
++	sii = (struct si_info *)sih;
++
++	/* release FORCEHT since chip is going to "down" state */
++	if (PCI_FORCEHT(sih)) {
++		cc = ai_findcore(&sii->pub, BCMA_CORE_CHIPCOMMON, 0);
++		bcma_core_set_clockmode(cc, BCMA_CLKMODE_DYNAMIC);
++	}
++
++	if (PCIE(sih))
++		bcma_core_pci_extend_L1timer(&sii->icbus->drv_pci, false);
++}
++
++/* Enable BT-COEX & Ex-PA for 4313 */
++void ai_epa_4313war(struct si_pub *sih)
++{
++	struct bcma_device *cc;
++
++	cc = ai_findcore(sih, CC_CORE_ID, 0);
++
++	/* EPA Fix */
++	bcma_set32(cc, CHIPCREGOFFS(gpiocontrol), GPIO_CTRL_EPA_EN_MASK);
++}
++
++/* check if the device is removed */
++bool ai_deviceremoved(struct si_pub *sih)
++{
++	u32 w;
++	struct si_info *sii;
++
++	sii = (struct si_info *)sih;
++
++	if (sii->icbus->hosttype != BCMA_HOSTTYPE_PCI)
++		return false;
++
++	pci_read_config_dword(sii->pcibus, PCI_VENDOR_ID, &w);
++	if ((w & 0xFFFF) != PCI_VENDOR_ID_BROADCOM)
++		return true;
++
++	return false;
++}
++
++uint ai_get_buscoretype(struct si_pub *sih)
++{
++	struct si_info *sii = (struct si_info *)sih;
++	return sii->buscore->id.id;
++}
++
++uint ai_get_buscorerev(struct si_pub *sih)
++{
++	struct si_info *sii = (struct si_info *)sih;
++	return sii->buscore->id.rev;
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/aiutils.h b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.h
+new file mode 100644
+index 0000000..d9f04a6
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.h
+@@ -0,0 +1,248 @@
++/*
++ * Copyright (c) 2011 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef	_BRCM_AIUTILS_H_
++#define	_BRCM_AIUTILS_H_
++
++#include <linux/bcma/bcma.h>
++
++#include "types.h"
++
++/*
++ * SOC Interconnect Address Map.
++ * All regions may not exist on all chips.
++ */
++/* each core gets 4Kbytes for registers */
++#define SI_CORE_SIZE		0x1000
++/*
++ * Max cores (this is arbitrary, for software
++ * convenience and could be changed if we
++ * make any larger chips
++ */
++#define	SI_MAXCORES		16
++
++/* Client Mode sb2pcitranslation2 size in bytes */
++#define SI_PCI_DMA_SZ		0x40000000
++
++/* PCIE Client Mode sb2pcitranslation2 (2 ZettaBytes), high 32 bits */
++#define SI_PCIE_DMA_H32		0x80000000
++
++/* chipcommon being the first core: */
++#define	SI_CC_IDX		0
++
++/* SOC Interconnect types (aka chip types) */
++#define	SOCI_AI			1
++
++/* A register that is common to all cores to
++ * communicate w/PMU regarding clock control.
++ */
++#define SI_CLK_CTL_ST		0x1e0	/* clock control and status */
++
++/* clk_ctl_st register */
++#define	CCS_FORCEALP		0x00000001	/* force ALP request */
++#define	CCS_FORCEHT		0x00000002	/* force HT request */
++#define	CCS_FORCEILP		0x00000004	/* force ILP request */
++#define	CCS_ALPAREQ		0x00000008	/* ALP Avail Request */
++#define	CCS_HTAREQ		0x00000010	/* HT Avail Request */
++#define	CCS_FORCEHWREQOFF	0x00000020	/* Force HW Clock Request Off */
++#define CCS_ERSRC_REQ_MASK	0x00000700	/* external resource requests */
++#define CCS_ERSRC_REQ_SHIFT	8
++#define	CCS_ALPAVAIL		0x00010000	/* ALP is available */
++#define	CCS_HTAVAIL		0x00020000	/* HT is available */
++#define CCS_BP_ON_APL		0x00040000	/* RO: running on ALP clock */
++#define CCS_BP_ON_HT		0x00080000	/* RO: running on HT clock */
++#define CCS_ERSRC_STS_MASK	0x07000000	/* external resource status */
++#define CCS_ERSRC_STS_SHIFT	24
++
++/* HT avail in chipc and pcmcia on 4328a0 */
++#define	CCS0_HTAVAIL		0x00010000
++/* ALP avail in chipc and pcmcia on 4328a0 */
++#define	CCS0_ALPAVAIL		0x00020000
++
++/* Not really related to SOC Interconnect, but a couple of software
++ * conventions for the use the flash space:
++ */
++
++/* Minumum amount of flash we support */
++#define FLASH_MIN		0x00020000	/* Minimum flash size */
++
++#define	CC_SROM_OTP		0x800	/* SROM/OTP address space */
++
++/* gpiotimerval */
++#define GPIO_ONTIME_SHIFT	16
++
++/* Fields in clkdiv */
++#define	CLKD_OTP		0x000f0000
++#define	CLKD_OTP_SHIFT		16
++
++/* Package IDs */
++#define	BCM4717_PKG_ID		9	/* 4717 package id */
++#define	BCM4718_PKG_ID		10	/* 4718 package id */
++#define BCM43224_FAB_SMIC	0xa	/* the chip is manufactured by SMIC */
++
++/* these are router chips */
++#define	BCM4716_CHIP_ID		0x4716	/* 4716 chipcommon chipid */
++#define	BCM47162_CHIP_ID	47162	/* 47162 chipcommon chipid */
++#define	BCM4748_CHIP_ID		0x4748	/* 4716 chipcommon chipid (OTP, RBBU) */
++
++/* dynamic clock control defines */
++#define	LPOMINFREQ		25000	/* low power oscillator min */
++#define	LPOMAXFREQ		43000	/* low power oscillator max */
++#define	XTALMINFREQ		19800000	/* 20 MHz - 1% */
++#define	XTALMAXFREQ		20200000	/* 20 MHz + 1% */
++#define	PCIMINFREQ		25000000	/* 25 MHz */
++#define	PCIMAXFREQ		34000000	/* 33 MHz + fudge */
++
++#define	ILP_DIV_5MHZ		0	/* ILP = 5 MHz */
++#define	ILP_DIV_1MHZ		4	/* ILP = 1 MHz */
++
++/* clkctl xtal what flags */
++#define	XTAL			0x1	/* primary crystal oscillator (2050) */
++#define	PLL			0x2	/* main chip pll */
++
++/* GPIO usage priorities */
++#define GPIO_DRV_PRIORITY	0	/* Driver */
++#define GPIO_APP_PRIORITY	1	/* Application */
++#define GPIO_HI_PRIORITY	2	/* Highest priority. Ignore GPIO
++					 * reservation
++					 */
++
++/* GPIO pull up/down */
++#define GPIO_PULLUP		0
++#define GPIO_PULLDN		1
++
++/* GPIO event regtype */
++#define GPIO_REGEVT		0	/* GPIO register event */
++#define GPIO_REGEVT_INTMSK	1	/* GPIO register event int mask */
++#define GPIO_REGEVT_INTPOL	2	/* GPIO register event int polarity */
++
++/* device path */
++#define SI_DEVPATH_BUFSZ	16	/* min buffer size in bytes */
++
++/* SI routine enumeration: to be used by update function with multiple hooks */
++#define	SI_DOATTACH	1
++#define SI_PCIDOWN	2
++#define SI_PCIUP	3
++
++/*
++ * Data structure to export all chip specific common variables
++ *   public (read-only) portion of aiutils handle returned by si_attach()
++ */
++struct si_pub {
++	int ccrev;		/* chip common core rev */
++	u32 cccaps;		/* chip common capabilities */
++	int pmurev;		/* pmu core rev */
++	u32 pmucaps;		/* pmu capabilities */
++	uint boardtype;		/* board type */
++	uint boardvendor;	/* board vendor */
++	uint chip;		/* chip number */
++	uint chiprev;		/* chip revision */
++	uint chippkg;		/* chip package option */
++};
++
++struct pci_dev;
++
++struct gpioh_item {
++	void *arg;
++	bool level;
++	void (*handler) (u32 stat, void *arg);
++	u32 event;
++	struct gpioh_item *next;
++};
++
++/* misc si info needed by some of the routines */
++struct si_info {
++	struct si_pub pub;	/* back plane public state (must be first) */
++	struct bcma_bus *icbus;	/* handle to soc interconnect bus */
++	struct pci_dev *pcibus;	/* handle to pci bus */
++	struct bcma_device *buscore;
++
++	u32 chipst;		/* chip status */
++};
++
++/*
++ * Many of the routines below take an 'sih' handle as their first arg.
++ * Allocate this by calling si_attach().  Free it by calling si_detach().
++ * At any one time, the sih is logically focused on one particular si core
++ * (the "current core").
++ * Use si_setcore() or si_setcoreidx() to change the association to another core
++ */
++
++
++/* AMBA Interconnect exported externs */
++extern struct bcma_device *ai_findcore(struct si_pub *sih,
++				       u16 coreid, u16 coreunit);
++extern u32 ai_core_cflags(struct bcma_device *core, u32 mask, u32 val);
++
++/* === exported functions === */
++extern struct si_pub *ai_attach(struct bcma_bus *pbus);
++extern void ai_detach(struct si_pub *sih);
++extern uint ai_cc_reg(struct si_pub *sih, uint regoff, u32 mask, u32 val);
++extern void ai_clkctl_init(struct si_pub *sih);
++extern u16 ai_clkctl_fast_pwrup_delay(struct si_pub *sih);
++extern bool ai_clkctl_cc(struct si_pub *sih, uint mode);
++extern bool ai_deviceremoved(struct si_pub *sih);
++
++extern void ai_pci_down(struct si_pub *sih);
++extern void ai_pci_up(struct si_pub *sih);
++
++/* Enable Ex-PA for 4313 */
++extern void ai_epa_4313war(struct si_pub *sih);
++
++extern uint ai_get_buscoretype(struct si_pub *sih);
++extern uint ai_get_buscorerev(struct si_pub *sih);
++
++static inline u32 ai_get_cccaps(struct si_pub *sih)
++{
++	return sih->cccaps;
++}
++
++static inline int ai_get_pmurev(struct si_pub *sih)
++{
++	return sih->pmurev;
++}
++
++static inline u32 ai_get_pmucaps(struct si_pub *sih)
++{
++	return sih->pmucaps;
++}
++
++static inline uint ai_get_boardtype(struct si_pub *sih)
++{
++	return sih->boardtype;
++}
++
++static inline uint ai_get_boardvendor(struct si_pub *sih)
++{
++	return sih->boardvendor;
++}
++
++static inline uint ai_get_chip_id(struct si_pub *sih)
++{
++	return sih->chip;
++}
++
++static inline uint ai_get_chiprev(struct si_pub *sih)
++{
++	return sih->chiprev;
++}
++
++static inline uint ai_get_chippkg(struct si_pub *sih)
++{
++	return sih->chippkg;
++}
++
++#endif				/* _BRCM_AIUTILS_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
+new file mode 100644
+index 0000000..95b5902
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
+@@ -0,0 +1,1236 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++#include <net/mac80211.h>
++
++#include "rate.h"
++#include "scb.h"
++#include "phy/phy_hal.h"
++#include "antsel.h"
++#include "main.h"
++#include "ampdu.h"
++
++/* max number of mpdus in an ampdu */
++#define AMPDU_MAX_MPDU			32
++/* max number of mpdus in an ampdu to a legacy */
++#define AMPDU_NUM_MPDU_LEGACY		16
++/* max Tx ba window size (in pdu) */
++#define AMPDU_TX_BA_MAX_WSIZE		64
++/* default Tx ba window size (in pdu) */
++#define AMPDU_TX_BA_DEF_WSIZE		64
++/* default Rx ba window size (in pdu) */
++#define AMPDU_RX_BA_DEF_WSIZE		64
++/* max Rx ba window size (in pdu) */
++#define AMPDU_RX_BA_MAX_WSIZE		64
++/* max dur of tx ampdu (in msec) */
++#define	AMPDU_MAX_DUR			5
++/* default tx retry limit */
++#define AMPDU_DEF_RETRY_LIMIT		5
++/* default tx retry limit at reg rate */
++#define AMPDU_DEF_RR_RETRY_LIMIT	2
++/* default weight of ampdu in txfifo */
++#define AMPDU_DEF_TXPKT_WEIGHT		2
++/* default ffpld reserved bytes */
++#define AMPDU_DEF_FFPLD_RSVD		2048
++/* # of inis to be freed on detach */
++#define AMPDU_INI_FREE			10
++/* max # of mpdus released at a time */
++#define	AMPDU_SCB_MAX_RELEASE		20
++
++#define NUM_FFPLD_FIFO 4	/* number of fifo concerned by pre-loading */
++#define FFPLD_TX_MAX_UNFL   200	/* default value of the average number of ampdu
++				 * without underflows
++				 */
++#define FFPLD_MPDU_SIZE 1800	/* estimate of maximum mpdu size */
++#define FFPLD_MAX_MCS 23	/* we don't deal with mcs 32 */
++#define FFPLD_PLD_INCR 1000	/* increments in bytes */
++#define FFPLD_MAX_AMPDU_CNT 5000	/* maximum number of ampdu we
++					 * accumulate between resets.
++					 */
++
++#define AMPDU_DELIMITER_LEN	4
++
++/* max allowed number of mpdus in an ampdu (2 streams) */
++#define AMPDU_NUM_MPDU		16
++
++#define TX_SEQ_TO_INDEX(seq) ((seq) % AMPDU_TX_BA_MAX_WSIZE)
++
++/* max possible overhead per mpdu in the ampdu; 3 is for roundup if needed */
++#define AMPDU_MAX_MPDU_OVERHEAD (FCS_LEN + DOT11_ICV_AES_LEN +\
++	AMPDU_DELIMITER_LEN + 3\
++	+ DOT11_A4_HDR_LEN + DOT11_QOS_LEN + DOT11_IV_MAX_LEN)
++
++/* modulo add/sub, bound = 2^k */
++#define MODADD_POW2(x, y, bound) (((x) + (y)) & ((bound) - 1))
++#define MODSUB_POW2(x, y, bound) (((x) - (y)) & ((bound) - 1))
++
++/* structure to hold tx fifo information and pre-loading state
++ * counters specific to tx underflows of ampdus
++ * some counters might be redundant with the ones in wlc or ampdu structures.
++ * This allows to maintain a specific state independently of
++ * how often and/or when the wlc counters are updated.
++ *
++ * ampdu_pld_size: number of bytes to be pre-loaded
++ * mcs2ampdu_table: per-mcs max # of mpdus in an ampdu
++ * prev_txfunfl: num of underflows last read from the HW macstats counter
++ * accum_txfunfl: num of underflows since we modified pld params
++ * accum_txampdu: num of tx ampdu since we modified pld params
++ * prev_txampdu: previous reading of tx ampdu
++ * dmaxferrate: estimated dma avg xfer rate in kbits/sec
++ */
++struct brcms_fifo_info {
++	u16 ampdu_pld_size;
++	u8 mcs2ampdu_table[FFPLD_MAX_MCS + 1];
++	u16 prev_txfunfl;
++	u32 accum_txfunfl;
++	u32 accum_txampdu;
++	u32 prev_txampdu;
++	u32 dmaxferrate;
++};
++
++/* AMPDU module specific state
++ *
++ * wlc: pointer to main wlc structure
++ * scb_handle: scb cubby handle to retrieve data from scb
++ * ini_enable: per-tid initiator enable/disable of ampdu
++ * ba_tx_wsize: Tx ba window size (in pdu)
++ * ba_rx_wsize: Rx ba window size (in pdu)
++ * retry_limit: mpdu transmit retry limit
++ * rr_retry_limit: mpdu transmit retry limit at regular rate
++ * retry_limit_tid: per-tid mpdu transmit retry limit
++ * rr_retry_limit_tid: per-tid mpdu transmit retry limit at regular rate
++ * mpdu_density: min mpdu spacing (0-7) ==> 2^(x-1)/8 usec
++ * max_pdu: max pdus allowed in ampdu
++ * dur: max duration of an ampdu (in msec)
++ * txpkt_weight: weight of ampdu in txfifo; reduces rate lag
++ * rx_factor: maximum rx ampdu factor (0-3) ==> 2^(13+x) bytes
++ * ffpld_rsvd: number of bytes to reserve for preload
++ * max_txlen: max size of ampdu per mcs, bw and sgi
++ * mfbr: enable multiple fallback rate
++ * tx_max_funl: underflows should be kept such that
++ *		(tx_max_funfl*underflows) < tx frames
++ * fifo_tb: table of fifo infos
++ */
++struct ampdu_info {
++	struct brcms_c_info *wlc;
++	int scb_handle;
++	u8 ini_enable[AMPDU_MAX_SCB_TID];
++	u8 ba_tx_wsize;
++	u8 ba_rx_wsize;
++	u8 retry_limit;
++	u8 rr_retry_limit;
++	u8 retry_limit_tid[AMPDU_MAX_SCB_TID];
++	u8 rr_retry_limit_tid[AMPDU_MAX_SCB_TID];
++	u8 mpdu_density;
++	s8 max_pdu;
++	u8 dur;
++	u8 txpkt_weight;
++	u8 rx_factor;
++	u32 ffpld_rsvd;
++	u32 max_txlen[MCS_TABLE_SIZE][2][2];
++	bool mfbr;
++	u32 tx_max_funl;
++	struct brcms_fifo_info fifo_tb[NUM_FFPLD_FIFO];
++};
++
++/* used for flushing ampdu packets */
++struct cb_del_ampdu_pars {
++	struct ieee80211_sta *sta;
++	u16 tid;
++};
++
++static void brcms_c_scb_ampdu_update_max_txlen(struct ampdu_info *ampdu, u8 dur)
++{
++	u32 rate, mcs;
++
++	for (mcs = 0; mcs < MCS_TABLE_SIZE; mcs++) {
++		/* rate is in Kbps; dur is in msec ==> len = (rate * dur) / 8 */
++		/* 20MHz, No SGI */
++		rate = mcs_2_rate(mcs, false, false);
++		ampdu->max_txlen[mcs][0][0] = (rate * dur) >> 3;
++		/* 40 MHz, No SGI */
++		rate = mcs_2_rate(mcs, true, false);
++		ampdu->max_txlen[mcs][1][0] = (rate * dur) >> 3;
++		/* 20MHz, SGI */
++		rate = mcs_2_rate(mcs, false, true);
++		ampdu->max_txlen[mcs][0][1] = (rate * dur) >> 3;
++		/* 40 MHz, SGI */
++		rate = mcs_2_rate(mcs, true, true);
++		ampdu->max_txlen[mcs][1][1] = (rate * dur) >> 3;
++	}
++}
++
++static bool brcms_c_ampdu_cap(struct ampdu_info *ampdu)
++{
++	if (BRCMS_PHY_11N_CAP(ampdu->wlc->band))
++		return true;
++	else
++		return false;
++}
++
++static int brcms_c_ampdu_set(struct ampdu_info *ampdu, bool on)
++{
++	struct brcms_c_info *wlc = ampdu->wlc;
++
++	wlc->pub->_ampdu = false;
++
++	if (on) {
++		if (!(wlc->pub->_n_enab & SUPPORT_11N)) {
++			wiphy_err(ampdu->wlc->wiphy, "wl%d: driver not "
++				"nmode enabled\n", wlc->pub->unit);
++			return -ENOTSUPP;
++		}
++		if (!brcms_c_ampdu_cap(ampdu)) {
++			wiphy_err(ampdu->wlc->wiphy, "wl%d: device not "
++				"ampdu capable\n", wlc->pub->unit);
++			return -ENOTSUPP;
++		}
++		wlc->pub->_ampdu = on;
++	}
++
++	return 0;
++}
++
++static void brcms_c_ffpld_init(struct ampdu_info *ampdu)
++{
++	int i, j;
++	struct brcms_fifo_info *fifo;
++
++	for (j = 0; j < NUM_FFPLD_FIFO; j++) {
++		fifo = (ampdu->fifo_tb + j);
++		fifo->ampdu_pld_size = 0;
++		for (i = 0; i <= FFPLD_MAX_MCS; i++)
++			fifo->mcs2ampdu_table[i] = 255;
++		fifo->dmaxferrate = 0;
++		fifo->accum_txampdu = 0;
++		fifo->prev_txfunfl = 0;
++		fifo->accum_txfunfl = 0;
++
++	}
++}
++
++struct ampdu_info *brcms_c_ampdu_attach(struct brcms_c_info *wlc)
++{
++	struct ampdu_info *ampdu;
++	int i;
++
++	ampdu = kzalloc(sizeof(struct ampdu_info), GFP_ATOMIC);
++	if (!ampdu)
++		return NULL;
++
++	ampdu->wlc = wlc;
++
++	for (i = 0; i < AMPDU_MAX_SCB_TID; i++)
++		ampdu->ini_enable[i] = true;
++	/* Disable ampdu for VO by default */
++	ampdu->ini_enable[PRIO_8021D_VO] = false;
++	ampdu->ini_enable[PRIO_8021D_NC] = false;
++
++	/* Disable ampdu for BK by default since not enough fifo space */
++	ampdu->ini_enable[PRIO_8021D_NONE] = false;
++	ampdu->ini_enable[PRIO_8021D_BK] = false;
++
++	ampdu->ba_tx_wsize = AMPDU_TX_BA_DEF_WSIZE;
++	ampdu->ba_rx_wsize = AMPDU_RX_BA_DEF_WSIZE;
++	ampdu->mpdu_density = AMPDU_DEF_MPDU_DENSITY;
++	ampdu->max_pdu = AUTO;
++	ampdu->dur = AMPDU_MAX_DUR;
++	ampdu->txpkt_weight = AMPDU_DEF_TXPKT_WEIGHT;
++
++	ampdu->ffpld_rsvd = AMPDU_DEF_FFPLD_RSVD;
++	/*
++	 * bump max ampdu rcv size to 64k for all 11n
++	 * devices except 4321A0 and 4321A1
++	 */
++	if (BRCMS_ISNPHY(wlc->band) && NREV_LT(wlc->band->phyrev, 2))
++		ampdu->rx_factor = IEEE80211_HT_MAX_AMPDU_32K;
++	else
++		ampdu->rx_factor = IEEE80211_HT_MAX_AMPDU_64K;
++	ampdu->retry_limit = AMPDU_DEF_RETRY_LIMIT;
++	ampdu->rr_retry_limit = AMPDU_DEF_RR_RETRY_LIMIT;
++
++	for (i = 0; i < AMPDU_MAX_SCB_TID; i++) {
++		ampdu->retry_limit_tid[i] = ampdu->retry_limit;
++		ampdu->rr_retry_limit_tid[i] = ampdu->rr_retry_limit;
++	}
++
++	brcms_c_scb_ampdu_update_max_txlen(ampdu, ampdu->dur);
++	ampdu->mfbr = false;
++	/* try to set ampdu to the default value */
++	brcms_c_ampdu_set(ampdu, wlc->pub->_ampdu);
++
++	ampdu->tx_max_funl = FFPLD_TX_MAX_UNFL;
++	brcms_c_ffpld_init(ampdu);
++
++	return ampdu;
++}
++
++void brcms_c_ampdu_detach(struct ampdu_info *ampdu)
++{
++	kfree(ampdu);
++}
++
++static void brcms_c_scb_ampdu_update_config(struct ampdu_info *ampdu,
++					    struct scb *scb)
++{
++	struct scb_ampdu *scb_ampdu = &scb->scb_ampdu;
++	int i;
++
++	scb_ampdu->max_pdu = AMPDU_NUM_MPDU;
++
++	/* go back to legacy size if some preloading is occurring */
++	for (i = 0; i < NUM_FFPLD_FIFO; i++) {
++		if (ampdu->fifo_tb[i].ampdu_pld_size > FFPLD_PLD_INCR)
++			scb_ampdu->max_pdu = AMPDU_NUM_MPDU_LEGACY;
++	}
++
++	/* apply user override */
++	if (ampdu->max_pdu != AUTO)
++		scb_ampdu->max_pdu = (u8) ampdu->max_pdu;
++
++	scb_ampdu->release = min_t(u8, scb_ampdu->max_pdu,
++				   AMPDU_SCB_MAX_RELEASE);
++
++	if (scb_ampdu->max_rx_ampdu_bytes)
++		scb_ampdu->release = min_t(u8, scb_ampdu->release,
++			scb_ampdu->max_rx_ampdu_bytes / 1600);
++
++	scb_ampdu->release = min(scb_ampdu->release,
++				 ampdu->fifo_tb[TX_AC_BE_FIFO].
++				 mcs2ampdu_table[FFPLD_MAX_MCS]);
++}
++
++static void brcms_c_scb_ampdu_update_config_all(struct ampdu_info *ampdu)
++{
++	brcms_c_scb_ampdu_update_config(ampdu, &ampdu->wlc->pri_scb);
++}
++
++static void brcms_c_ffpld_calc_mcs2ampdu_table(struct ampdu_info *ampdu, int f)
++{
++	int i;
++	u32 phy_rate, dma_rate, tmp;
++	u8 max_mpdu;
++	struct brcms_fifo_info *fifo = (ampdu->fifo_tb + f);
++
++	/* recompute the dma rate */
++	/* note : we divide/multiply by 100 to avoid integer overflows */
++	max_mpdu = min_t(u8, fifo->mcs2ampdu_table[FFPLD_MAX_MCS],
++			 AMPDU_NUM_MPDU_LEGACY);
++	phy_rate = mcs_2_rate(FFPLD_MAX_MCS, true, false);
++	dma_rate =
++	    (((phy_rate / 100) *
++	      (max_mpdu * FFPLD_MPDU_SIZE - fifo->ampdu_pld_size))
++	     / (max_mpdu * FFPLD_MPDU_SIZE)) * 100;
++	fifo->dmaxferrate = dma_rate;
++
++	/* fill up the mcs2ampdu table; do not recalc the last mcs */
++	dma_rate = dma_rate >> 7;
++	for (i = 0; i < FFPLD_MAX_MCS; i++) {
++		/* shifting to keep it within integer range */
++		phy_rate = mcs_2_rate(i, true, false) >> 7;
++		if (phy_rate > dma_rate) {
++			tmp = ((fifo->ampdu_pld_size * phy_rate) /
++			       ((phy_rate - dma_rate) * FFPLD_MPDU_SIZE)) + 1;
++			tmp = min_t(u32, tmp, 255);
++			fifo->mcs2ampdu_table[i] = (u8) tmp;
++		}
++	}
++}
++
++/* evaluate the dma transfer rate using the tx underflows as feedback.
++ * If necessary, increase tx fifo preloading. If not enough,
++ * decrease maximum ampdu size for each mcs till underflows stop
++ * Return 1 if pre-loading not active, -1 if not an underflow event,
++ * 0 if pre-loading module took care of the event.
++ */
++static int brcms_c_ffpld_check_txfunfl(struct brcms_c_info *wlc, int fid)
++{
++	struct ampdu_info *ampdu = wlc->ampdu;
++	u32 phy_rate = mcs_2_rate(FFPLD_MAX_MCS, true, false);
++	u32 txunfl_ratio;
++	u8 max_mpdu;
++	u32 current_ampdu_cnt = 0;
++	u16 max_pld_size;
++	u32 new_txunfl;
++	struct brcms_fifo_info *fifo = (ampdu->fifo_tb + fid);
++	uint xmtfifo_sz;
++	u16 cur_txunfl;
++
++	/* return if we got here for a different reason than underflows */
++	cur_txunfl = brcms_b_read_shm(wlc->hw,
++				      M_UCODE_MACSTAT +
++				      offsetof(struct macstat, txfunfl[fid]));
++	new_txunfl = (u16) (cur_txunfl - fifo->prev_txfunfl);
++	if (new_txunfl == 0) {
++		BCMMSG(wlc->wiphy, "TX status FRAG set but no tx underflows\n");
++		return -1;
++	}
++	fifo->prev_txfunfl = cur_txunfl;
++
++	if (!ampdu->tx_max_funl)
++		return 1;
++
++	/* check if fifo is big enough */
++	if (brcms_b_xmtfifo_sz_get(wlc->hw, fid, &xmtfifo_sz))
++		return -1;
++
++	if ((TXFIFO_SIZE_UNIT * (u32) xmtfifo_sz) <= ampdu->ffpld_rsvd)
++		return 1;
++
++	max_pld_size = TXFIFO_SIZE_UNIT * xmtfifo_sz - ampdu->ffpld_rsvd;
++	fifo->accum_txfunfl += new_txunfl;
++
++	/* we need to wait for at least 10 underflows */
++	if (fifo->accum_txfunfl < 10)
++		return 0;
++
++	BCMMSG(wlc->wiphy, "ampdu_count %d  tx_underflows %d\n",
++		current_ampdu_cnt, fifo->accum_txfunfl);
++
++	/*
++	   compute the current ratio of tx unfl per ampdu.
++	   When the current ampdu count becomes too
++	   big while the ratio remains small, we reset
++	   the current count in order to not
++	   introduce too big of a latency in detecting a
++	   large amount of tx underflows later.
++	 */
++
++	txunfl_ratio = current_ampdu_cnt / fifo->accum_txfunfl;
++
++	if (txunfl_ratio > ampdu->tx_max_funl) {
++		if (current_ampdu_cnt >= FFPLD_MAX_AMPDU_CNT)
++			fifo->accum_txfunfl = 0;
++
++		return 0;
++	}
++	max_mpdu = min_t(u8, fifo->mcs2ampdu_table[FFPLD_MAX_MCS],
++			 AMPDU_NUM_MPDU_LEGACY);
++
++	/* In case max value max_pdu is already lower than
++	   the fifo depth, there is nothing more we can do.
++	 */
++
++	if (fifo->ampdu_pld_size >= max_mpdu * FFPLD_MPDU_SIZE) {
++		fifo->accum_txfunfl = 0;
++		return 0;
++	}
++
++	if (fifo->ampdu_pld_size < max_pld_size) {
++
++		/* increment by TX_FIFO_PLD_INC bytes */
++		fifo->ampdu_pld_size += FFPLD_PLD_INCR;
++		if (fifo->ampdu_pld_size > max_pld_size)
++			fifo->ampdu_pld_size = max_pld_size;
++
++		/* update scb release size */
++		brcms_c_scb_ampdu_update_config_all(ampdu);
++
++		/*
++		 * compute a new dma xfer rate for max_mpdu @ max mcs.
++		 * This is the minimum dma rate that can achieve no
++		 * underflow condition for the current mpdu size.
++		 *
++		 * note : we divide/multiply by 100 to avoid integer overflows
++		 */
++		fifo->dmaxferrate =
++		    (((phy_rate / 100) *
++		      (max_mpdu * FFPLD_MPDU_SIZE - fifo->ampdu_pld_size))
++		     / (max_mpdu * FFPLD_MPDU_SIZE)) * 100;
++
++		BCMMSG(wlc->wiphy, "DMA estimated transfer rate %d; "
++			"pre-load size %d\n",
++			fifo->dmaxferrate, fifo->ampdu_pld_size);
++	} else {
++
++		/* decrease ampdu size */
++		if (fifo->mcs2ampdu_table[FFPLD_MAX_MCS] > 1) {
++			if (fifo->mcs2ampdu_table[FFPLD_MAX_MCS] == 255)
++				fifo->mcs2ampdu_table[FFPLD_MAX_MCS] =
++				    AMPDU_NUM_MPDU_LEGACY - 1;
++			else
++				fifo->mcs2ampdu_table[FFPLD_MAX_MCS] -= 1;
++
++			/* recompute the table */
++			brcms_c_ffpld_calc_mcs2ampdu_table(ampdu, fid);
++
++			/* update scb release size */
++			brcms_c_scb_ampdu_update_config_all(ampdu);
++		}
++	}
++	fifo->accum_txfunfl = 0;
++	return 0;
++}
++
++void
++brcms_c_ampdu_tx_operational(struct brcms_c_info *wlc, u8 tid,
++	u8 ba_wsize,		/* negotiated ba window size (in pdu) */
++	uint max_rx_ampdu_bytes) /* from ht_cap in beacon */
++{
++	struct scb_ampdu *scb_ampdu;
++	struct scb_ampdu_tid_ini *ini;
++	struct ampdu_info *ampdu = wlc->ampdu;
++	struct scb *scb = &wlc->pri_scb;
++	scb_ampdu = &scb->scb_ampdu;
++
++	if (!ampdu->ini_enable[tid]) {
++		wiphy_err(ampdu->wlc->wiphy, "%s: Rejecting tid %d\n",
++			  __func__, tid);
++		return;
++	}
++
++	ini = &scb_ampdu->ini[tid];
++	ini->tid = tid;
++	ini->scb = scb_ampdu->scb;
++	ini->ba_wsize = ba_wsize;
++	scb_ampdu->max_rx_ampdu_bytes = max_rx_ampdu_bytes;
++}
++
++int
++brcms_c_sendampdu(struct ampdu_info *ampdu, struct brcms_txq_info *qi,
++	      struct sk_buff **pdu, int prec)
++{
++	struct brcms_c_info *wlc;
++	struct sk_buff *p, *pkt[AMPDU_MAX_MPDU];
++	u8 tid, ndelim;
++	int err = 0;
++	u8 preamble_type = BRCMS_GF_PREAMBLE;
++	u8 fbr_preamble_type = BRCMS_GF_PREAMBLE;
++	u8 rts_preamble_type = BRCMS_LONG_PREAMBLE;
++	u8 rts_fbr_preamble_type = BRCMS_LONG_PREAMBLE;
++
++	bool rr = true, fbr = false;
++	uint i, count = 0, fifo, seg_cnt = 0;
++	u16 plen, len, seq = 0, mcl, mch, index, frameid, dma_len = 0;
++	u32 ampdu_len, max_ampdu_bytes = 0;
++	struct d11txh *txh = NULL;
++	u8 *plcp;
++	struct ieee80211_hdr *h;
++	struct scb *scb;
++	struct scb_ampdu *scb_ampdu;
++	struct scb_ampdu_tid_ini *ini;
++	u8 mcs = 0;
++	bool use_rts = false, use_cts = false;
++	u32 rspec = 0, rspec_fallback = 0;
++	u32 rts_rspec = 0, rts_rspec_fallback = 0;
++	u16 mimo_ctlchbw = PHY_TXC1_BW_20MHZ;
++	struct ieee80211_rts *rts;
++	u8 rr_retry_limit;
++	struct brcms_fifo_info *f;
++	bool fbr_iscck;
++	struct ieee80211_tx_info *tx_info;
++	u16 qlen;
++	struct wiphy *wiphy;
++
++	wlc = ampdu->wlc;
++	wiphy = wlc->wiphy;
++	p = *pdu;
++
++	tid = (u8) (p->priority);
++
++	f = ampdu->fifo_tb + prio2fifo[tid];
++
++	scb = &wlc->pri_scb;
++	scb_ampdu = &scb->scb_ampdu;
++	ini = &scb_ampdu->ini[tid];
++
++	/* Let pressure continue to build ... */
++	qlen = pktq_plen(&qi->q, prec);
++	if (ini->tx_in_transit > 0 &&
++	    qlen < min(scb_ampdu->max_pdu, ini->ba_wsize))
++		/* Collect multiple MPDU's to be sent in the next AMPDU */
++		return -EBUSY;
++
++	/* at this point we intend to transmit an AMPDU */
++	rr_retry_limit = ampdu->rr_retry_limit_tid[tid];
++	ampdu_len = 0;
++	dma_len = 0;
++	while (p) {
++		struct ieee80211_tx_rate *txrate;
++
++		tx_info = IEEE80211_SKB_CB(p);
++		txrate = tx_info->status.rates;
++
++		if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
++			err = brcms_c_prep_pdu(wlc, p, &fifo);
++		} else {
++			wiphy_err(wiphy, "%s: AMPDU flag is off!\n", __func__);
++			*pdu = NULL;
++			err = 0;
++			break;
++		}
++
++		if (err) {
++			if (err == -EBUSY) {
++				wiphy_err(wiphy, "wl%d: sendampdu: "
++					  "prep_xdu retry; seq 0x%x\n",
++					  wlc->pub->unit, seq);
++				*pdu = p;
++				break;
++			}
++
++			/* error in the packet; reject it */
++			wiphy_err(wiphy, "wl%d: sendampdu: prep_xdu "
++				  "rejected; seq 0x%x\n", wlc->pub->unit, seq);
++			*pdu = NULL;
++			break;
++		}
++
++		/* pkt is good to be aggregated */
++		txh = (struct d11txh *) p->data;
++		plcp = (u8 *) (txh + 1);
++		h = (struct ieee80211_hdr *)(plcp + D11_PHY_HDR_LEN);
++		seq = le16_to_cpu(h->seq_ctrl) >> SEQNUM_SHIFT;
++		index = TX_SEQ_TO_INDEX(seq);
++
++		/* check mcl fields and test whether it can be agg'd */
++		mcl = le16_to_cpu(txh->MacTxControlLow);
++		mcl &= ~TXC_AMPDU_MASK;
++		fbr_iscck = !(le16_to_cpu(txh->XtraFrameTypes) & 0x3);
++		txh->PreloadSize = 0;	/* always default to 0 */
++
++		/*  Handle retry limits */
++		if (txrate[0].count <= rr_retry_limit) {
++			txrate[0].count++;
++			rr = true;
++			fbr = false;
++		} else {
++			fbr = true;
++			rr = false;
++			txrate[1].count++;
++		}
++
++		/* extract the length info */
++		len = fbr_iscck ? BRCMS_GET_CCK_PLCP_LEN(txh->FragPLCPFallback)
++		    : BRCMS_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback);
++
++		/* retrieve null delimiter count */
++		ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM];
++		seg_cnt += 1;
++
++		BCMMSG(wlc->wiphy, "wl%d: mpdu %d plcp_len %d\n",
++			wlc->pub->unit, count, len);
++
++		/*
++		 * aggregateable mpdu. For ucode/hw agg,
++		 * test whether need to break or change the epoch
++		 */
++		if (count == 0) {
++			mcl |= (TXC_AMPDU_FIRST << TXC_AMPDU_SHIFT);
++			/* refill the bits since might be a retx mpdu */
++			mcl |= TXC_STARTMSDU;
++			rts = (struct ieee80211_rts *)&txh->rts_frame;
++
++			if (ieee80211_is_rts(rts->frame_control)) {
++				mcl |= TXC_SENDRTS;
++				use_rts = true;
++			}
++			if (ieee80211_is_cts(rts->frame_control)) {
++				mcl |= TXC_SENDCTS;
++				use_cts = true;
++			}
++		} else {
++			mcl |= (TXC_AMPDU_MIDDLE << TXC_AMPDU_SHIFT);
++			mcl &= ~(TXC_STARTMSDU | TXC_SENDRTS | TXC_SENDCTS);
++		}
++
++		len = roundup(len, 4);
++		ampdu_len += (len + (ndelim + 1) * AMPDU_DELIMITER_LEN);
++
++		dma_len += (u16) p->len;
++
++		BCMMSG(wlc->wiphy, "wl%d: ampdu_len %d"
++			" seg_cnt %d null delim %d\n",
++			wlc->pub->unit, ampdu_len, seg_cnt, ndelim);
++
++		txh->MacTxControlLow = cpu_to_le16(mcl);
++
++		/* this packet is added */
++		pkt[count++] = p;
++
++		/* patch the first MPDU */
++		if (count == 1) {
++			u8 plcp0, plcp3, is40, sgi;
++			struct ieee80211_sta *sta;
++
++			sta = tx_info->control.sta;
++
++			if (rr) {
++				plcp0 = plcp[0];
++				plcp3 = plcp[3];
++			} else {
++				plcp0 = txh->FragPLCPFallback[0];
++				plcp3 = txh->FragPLCPFallback[3];
++
++			}
++			is40 = (plcp0 & MIMO_PLCP_40MHZ) ? 1 : 0;
++			sgi = plcp3_issgi(plcp3) ? 1 : 0;
++			mcs = plcp0 & ~MIMO_PLCP_40MHZ;
++			max_ampdu_bytes =
++			    min(scb_ampdu->max_rx_ampdu_bytes,
++				ampdu->max_txlen[mcs][is40][sgi]);
++
++			if (is40)
++				mimo_ctlchbw =
++				   CHSPEC_SB_UPPER(wlc_phy_chanspec_get(
++								 wlc->band->pi))
++				   ? PHY_TXC1_BW_20MHZ_UP : PHY_TXC1_BW_20MHZ;
++
++			/* rebuild the rspec and rspec_fallback */
++			rspec = RSPEC_MIMORATE;
++			rspec |= plcp[0] & ~MIMO_PLCP_40MHZ;
++			if (plcp[0] & MIMO_PLCP_40MHZ)
++				rspec |= (PHY_TXC1_BW_40MHZ << RSPEC_BW_SHIFT);
++
++			if (fbr_iscck)	/* CCK */
++				rspec_fallback = cck_rspec(cck_phy2mac_rate
++						    (txh->FragPLCPFallback[0]));
++			else {	/* MIMO */
++				rspec_fallback = RSPEC_MIMORATE;
++				rspec_fallback |=
++				    txh->FragPLCPFallback[0] & ~MIMO_PLCP_40MHZ;
++				if (txh->FragPLCPFallback[0] & MIMO_PLCP_40MHZ)
++					rspec_fallback |=
++					    (PHY_TXC1_BW_40MHZ <<
++					     RSPEC_BW_SHIFT);
++			}
++
++			if (use_rts || use_cts) {
++				rts_rspec =
++				    brcms_c_rspec_to_rts_rspec(wlc,
++					rspec, false, mimo_ctlchbw);
++				rts_rspec_fallback =
++				    brcms_c_rspec_to_rts_rspec(wlc,
++					rspec_fallback, false, mimo_ctlchbw);
++			}
++		}
++
++		/* if (first mpdu for host agg) */
++		/* test whether to add more */
++		if ((mcs_2_rate(mcs, true, false) >= f->dmaxferrate) &&
++		    (count == f->mcs2ampdu_table[mcs])) {
++			BCMMSG(wlc->wiphy, "wl%d: PR 37644: stopping"
++				" ampdu at %d for mcs %d\n",
++				wlc->pub->unit, count, mcs);
++			break;
++		}
++
++		if (count == scb_ampdu->max_pdu)
++			break;
++
++		/*
++		 * check to see if the next pkt is
++		 * a candidate for aggregation
++		 */
++		p = pktq_ppeek(&qi->q, prec);
++		/* tx_info must be checked with current p */
++		tx_info = IEEE80211_SKB_CB(p);
++
++		if (p) {
++			if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) &&
++			    ((u8) (p->priority) == tid)) {
++				plen = p->len + AMPDU_MAX_MPDU_OVERHEAD;
++				plen = max(scb_ampdu->min_len, plen);
++
++				if ((plen + ampdu_len) > max_ampdu_bytes) {
++					p = NULL;
++					continue;
++				}
++
++				/*
++				 * check if there are enough
++				 * descriptors available
++				 */
++				if (*wlc->core->txavail[fifo] <= seg_cnt + 1) {
++					wiphy_err(wiphy, "%s: No fifo space  "
++						  "!!\n", __func__);
++					p = NULL;
++					continue;
++				}
++				p = brcmu_pktq_pdeq(&qi->q, prec);
++			} else {
++				p = NULL;
++			}
++		}
++	}			/* end while(p) */
++
++	ini->tx_in_transit += count;
++
++	if (count) {
++		/* patch up the last txh */
++		txh = (struct d11txh *) pkt[count - 1]->data;
++		mcl = le16_to_cpu(txh->MacTxControlLow);
++		mcl &= ~TXC_AMPDU_MASK;
++		mcl |= (TXC_AMPDU_LAST << TXC_AMPDU_SHIFT);
++		txh->MacTxControlLow = cpu_to_le16(mcl);
++
++		/* remove the null delimiter after last mpdu */
++		ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM];
++		txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM] = 0;
++		ampdu_len -= ndelim * AMPDU_DELIMITER_LEN;
++
++		/* remove the pad len from last mpdu */
++		fbr_iscck = ((le16_to_cpu(txh->XtraFrameTypes) & 0x3) == 0);
++		len = fbr_iscck ? BRCMS_GET_CCK_PLCP_LEN(txh->FragPLCPFallback)
++		    : BRCMS_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback);
++		ampdu_len -= roundup(len, 4) - len;
++
++		/* patch up the first txh & plcp */
++		txh = (struct d11txh *) pkt[0]->data;
++		plcp = (u8 *) (txh + 1);
++
++		BRCMS_SET_MIMO_PLCP_LEN(plcp, ampdu_len);
++		/* mark plcp to indicate ampdu */
++		BRCMS_SET_MIMO_PLCP_AMPDU(plcp);
++
++		/* reset the mixed mode header durations */
++		if (txh->MModeLen) {
++			u16 mmodelen =
++			    brcms_c_calc_lsig_len(wlc, rspec, ampdu_len);
++			txh->MModeLen = cpu_to_le16(mmodelen);
++			preamble_type = BRCMS_MM_PREAMBLE;
++		}
++		if (txh->MModeFbrLen) {
++			u16 mmfbrlen =
++			    brcms_c_calc_lsig_len(wlc, rspec_fallback,
++						  ampdu_len);
++			txh->MModeFbrLen = cpu_to_le16(mmfbrlen);
++			fbr_preamble_type = BRCMS_MM_PREAMBLE;
++		}
++
++		/* set the preload length */
++		if (mcs_2_rate(mcs, true, false) >= f->dmaxferrate) {
++			dma_len = min(dma_len, f->ampdu_pld_size);
++			txh->PreloadSize = cpu_to_le16(dma_len);
++		} else
++			txh->PreloadSize = 0;
++
++		mch = le16_to_cpu(txh->MacTxControlHigh);
++
++		/* update RTS dur fields */
++		if (use_rts || use_cts) {
++			u16 durid;
++			rts = (struct ieee80211_rts *)&txh->rts_frame;
++			if ((mch & TXC_PREAMBLE_RTS_MAIN_SHORT) ==
++			    TXC_PREAMBLE_RTS_MAIN_SHORT)
++				rts_preamble_type = BRCMS_SHORT_PREAMBLE;
++
++			if ((mch & TXC_PREAMBLE_RTS_FB_SHORT) ==
++			    TXC_PREAMBLE_RTS_FB_SHORT)
++				rts_fbr_preamble_type = BRCMS_SHORT_PREAMBLE;
++
++			durid =
++			    brcms_c_compute_rtscts_dur(wlc, use_cts, rts_rspec,
++						   rspec, rts_preamble_type,
++						   preamble_type, ampdu_len,
++						   true);
++			rts->duration = cpu_to_le16(durid);
++			durid = brcms_c_compute_rtscts_dur(wlc, use_cts,
++						       rts_rspec_fallback,
++						       rspec_fallback,
++						       rts_fbr_preamble_type,
++						       fbr_preamble_type,
++						       ampdu_len, true);
++			txh->RTSDurFallback = cpu_to_le16(durid);
++			/* set TxFesTimeNormal */
++			txh->TxFesTimeNormal = rts->duration;
++			/* set fallback rate version of TxFesTimeNormal */
++			txh->TxFesTimeFallback = txh->RTSDurFallback;
++		}
++
++		/* set flag and plcp for fallback rate */
++		if (fbr) {
++			mch |= TXC_AMPDU_FBR;
++			txh->MacTxControlHigh = cpu_to_le16(mch);
++			BRCMS_SET_MIMO_PLCP_AMPDU(plcp);
++			BRCMS_SET_MIMO_PLCP_AMPDU(txh->FragPLCPFallback);
++		}
++
++		BCMMSG(wlc->wiphy, "wl%d: count %d ampdu_len %d\n",
++			wlc->pub->unit, count, ampdu_len);
++
++		/* inform rate_sel if it this is a rate probe pkt */
++		frameid = le16_to_cpu(txh->TxFrameID);
++		if (frameid & TXFID_RATE_PROBE_MASK)
++			wiphy_err(wiphy, "%s: XXX what to do with "
++				  "TXFID_RATE_PROBE_MASK!?\n", __func__);
++
++		for (i = 0; i < count; i++)
++			brcms_c_txfifo(wlc, fifo, pkt[i], i == (count - 1),
++				   ampdu->txpkt_weight);
++
++	}
++	/* endif (count) */
++	return err;
++}
++
++static void
++brcms_c_ampdu_rate_status(struct brcms_c_info *wlc,
++			  struct ieee80211_tx_info *tx_info,
++			  struct tx_status *txs, u8 mcs)
++{
++	struct ieee80211_tx_rate *txrate = tx_info->status.rates;
++	int i;
++
++	/* clear the rest of the rates */
++	for (i = 2; i < IEEE80211_TX_MAX_RATES; i++) {
++		txrate[i].idx = -1;
++		txrate[i].count = 0;
++	}
++}
++
++static void
++brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
++			      struct sk_buff *p, struct tx_status *txs,
++			      u32 s1, u32 s2)
++{
++	struct scb_ampdu *scb_ampdu;
++	struct brcms_c_info *wlc = ampdu->wlc;
++	struct scb_ampdu_tid_ini *ini;
++	u8 bitmap[8], queue, tid;
++	struct d11txh *txh;
++	u8 *plcp;
++	struct ieee80211_hdr *h;
++	u16 seq, start_seq = 0, bindex, index, mcl;
++	u8 mcs = 0;
++	bool ba_recd = false, ack_recd = false;
++	u8 suc_mpdu = 0, tot_mpdu = 0;
++	uint supr_status;
++	bool update_rate = true, retry = true, tx_error = false;
++	u16 mimoantsel = 0;
++	u8 antselid = 0;
++	u8 retry_limit, rr_retry_limit;
++	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(p);
++	struct wiphy *wiphy = wlc->wiphy;
++
++#ifdef DEBUG
++	u8 hole[AMPDU_MAX_MPDU];
++	memset(hole, 0, sizeof(hole));
++#endif
++
++	scb_ampdu = &scb->scb_ampdu;
++	tid = (u8) (p->priority);
++
++	ini = &scb_ampdu->ini[tid];
++	retry_limit = ampdu->retry_limit_tid[tid];
++	rr_retry_limit = ampdu->rr_retry_limit_tid[tid];
++	memset(bitmap, 0, sizeof(bitmap));
++	queue = txs->frameid & TXFID_QUEUE_MASK;
++	supr_status = txs->status & TX_STATUS_SUPR_MASK;
++
++	if (txs->status & TX_STATUS_ACK_RCV) {
++		if (TX_STATUS_SUPR_UF == supr_status)
++			update_rate = false;
++
++		WARN_ON(!(txs->status & TX_STATUS_INTERMEDIATE));
++		start_seq = txs->sequence >> SEQNUM_SHIFT;
++		bitmap[0] = (txs->status & TX_STATUS_BA_BMAP03_MASK) >>
++		    TX_STATUS_BA_BMAP03_SHIFT;
++
++		WARN_ON(s1 & TX_STATUS_INTERMEDIATE);
++		WARN_ON(!(s1 & TX_STATUS_AMPDU));
++
++		bitmap[0] |=
++		    (s1 & TX_STATUS_BA_BMAP47_MASK) <<
++		    TX_STATUS_BA_BMAP47_SHIFT;
++		bitmap[1] = (s1 >> 8) & 0xff;
++		bitmap[2] = (s1 >> 16) & 0xff;
++		bitmap[3] = (s1 >> 24) & 0xff;
++
++		bitmap[4] = s2 & 0xff;
++		bitmap[5] = (s2 >> 8) & 0xff;
++		bitmap[6] = (s2 >> 16) & 0xff;
++		bitmap[7] = (s2 >> 24) & 0xff;
++
++		ba_recd = true;
++	} else {
++		if (supr_status) {
++			update_rate = false;
++			if (supr_status == TX_STATUS_SUPR_BADCH) {
++				wiphy_err(wiphy,
++					  "%s: Pkt tx suppressed, illegal channel possibly %d\n",
++					  __func__, CHSPEC_CHANNEL(
++					  wlc->default_bss->chanspec));
++			} else {
++				if (supr_status != TX_STATUS_SUPR_FRAG)
++					wiphy_err(wiphy, "%s: supr_status 0x%x\n",
++						  __func__, supr_status);
++			}
++			/* no need to retry for badch; will fail again */
++			if (supr_status == TX_STATUS_SUPR_BADCH ||
++			    supr_status == TX_STATUS_SUPR_EXPTIME) {
++				retry = false;
++			} else if (supr_status == TX_STATUS_SUPR_EXPTIME) {
++				/* TX underflow:
++				 *   try tuning pre-loading or ampdu size
++				 */
++			} else if (supr_status == TX_STATUS_SUPR_FRAG) {
++				/*
++				 * if there were underflows, but pre-loading
++				 * is not active, notify rate adaptation.
++				 */
++				if (brcms_c_ffpld_check_txfunfl(wlc,
++					prio2fifo[tid]) > 0)
++					tx_error = true;
++			}
++		} else if (txs->phyerr) {
++			update_rate = false;
++			wiphy_err(wiphy, "%s: ampdu tx phy error (0x%x)\n",
++				  __func__, txs->phyerr);
++
++			if (brcm_msg_level & LOG_ERROR_VAL) {
++				brcmu_prpkt("txpkt (AMPDU)", p);
++				brcms_c_print_txdesc((struct d11txh *) p->data);
++			}
++			brcms_c_print_txstatus(txs);
++		}
++	}
++
++	/* loop through all pkts and retry if not acked */
++	while (p) {
++		tx_info = IEEE80211_SKB_CB(p);
++		txh = (struct d11txh *) p->data;
++		mcl = le16_to_cpu(txh->MacTxControlLow);
++		plcp = (u8 *) (txh + 1);
++		h = (struct ieee80211_hdr *)(plcp + D11_PHY_HDR_LEN);
++		seq = le16_to_cpu(h->seq_ctrl) >> SEQNUM_SHIFT;
++
++		if (tot_mpdu == 0) {
++			mcs = plcp[0] & MIMO_PLCP_MCS_MASK;
++			mimoantsel = le16_to_cpu(txh->ABI_MimoAntSel);
++		}
++
++		index = TX_SEQ_TO_INDEX(seq);
++		ack_recd = false;
++		if (ba_recd) {
++			bindex = MODSUB_POW2(seq, start_seq, SEQNUM_MAX);
++			BCMMSG(wiphy,
++			       "tid %d seq %d, start_seq %d, bindex %d set %d, index %d\n",
++			       tid, seq, start_seq, bindex,
++			       isset(bitmap, bindex), index);
++			/* if acked then clear bit and free packet */
++			if ((bindex < AMPDU_TX_BA_MAX_WSIZE)
++			    && isset(bitmap, bindex)) {
++				ini->tx_in_transit--;
++				ini->txretry[index] = 0;
++
++				/*
++				 * ampdu_ack_len:
++				 *   number of acked aggregated frames
++				 */
++				/* ampdu_len: number of aggregated frames */
++				brcms_c_ampdu_rate_status(wlc, tx_info, txs,
++							  mcs);
++				tx_info->flags |= IEEE80211_TX_STAT_ACK;
++				tx_info->flags |= IEEE80211_TX_STAT_AMPDU;
++				tx_info->status.ampdu_ack_len =
++					tx_info->status.ampdu_len = 1;
++
++				skb_pull(p, D11_PHY_HDR_LEN);
++				skb_pull(p, D11_TXH_LEN);
++
++				ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw,
++							    p);
++				ack_recd = true;
++				suc_mpdu++;
++			}
++		}
++		/* either retransmit or send bar if ack not recd */
++		if (!ack_recd) {
++			if (retry && (ini->txretry[index] < (int)retry_limit)) {
++				ini->txretry[index]++;
++				ini->tx_in_transit--;
++				/*
++				 * Use high prededence for retransmit to
++				 * give some punch
++				 */
++				brcms_c_txq_enq(wlc, scb, p,
++						BRCMS_PRIO_TO_HI_PREC(tid));
++			} else {
++				/* Retry timeout */
++				ini->tx_in_transit--;
++				ieee80211_tx_info_clear_status(tx_info);
++				tx_info->status.ampdu_ack_len = 0;
++				tx_info->status.ampdu_len = 1;
++				tx_info->flags |=
++				    IEEE80211_TX_STAT_AMPDU_NO_BACK;
++				skb_pull(p, D11_PHY_HDR_LEN);
++				skb_pull(p, D11_TXH_LEN);
++				BCMMSG(wiphy,
++				       "BA Timeout, seq %d, in_transit %d\n",
++				       seq, ini->tx_in_transit);
++				ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw,
++							    p);
++			}
++		}
++		tot_mpdu++;
++
++		/* break out if last packet of ampdu */
++		if (((mcl & TXC_AMPDU_MASK) >> TXC_AMPDU_SHIFT) ==
++		    TXC_AMPDU_LAST)
++			break;
++
++		p = dma_getnexttxp(wlc->hw->di[queue], DMA_RANGE_TRANSMITTED);
++	}
++	brcms_c_send_q(wlc);
++
++	/* update rate state */
++	antselid = brcms_c_antsel_antsel2id(wlc->asi, mimoantsel);
++
++	brcms_c_txfifo_complete(wlc, queue, ampdu->txpkt_weight);
++}
++
++void
++brcms_c_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb,
++		     struct sk_buff *p, struct tx_status *txs)
++{
++	struct scb_ampdu *scb_ampdu;
++	struct brcms_c_info *wlc = ampdu->wlc;
++	struct scb_ampdu_tid_ini *ini;
++	u32 s1 = 0, s2 = 0;
++	struct ieee80211_tx_info *tx_info;
++
++	tx_info = IEEE80211_SKB_CB(p);
++
++	/* BMAC_NOTE: For the split driver, second level txstatus comes later
++	 * So if the ACK was received then wait for the second level else just
++	 * call the first one
++	 */
++	if (txs->status & TX_STATUS_ACK_RCV) {
++		u8 status_delay = 0;
++
++		/* wait till the next 8 bytes of txstatus is available */
++		s1 = bcma_read32(wlc->hw->d11core, D11REGOFFS(frmtxstatus));
++		while ((s1 & TXS_V) == 0) {
++			udelay(1);
++			status_delay++;
++			if (status_delay > 10)
++				return; /* error condition */
++			s1 = bcma_read32(wlc->hw->d11core,
++					 D11REGOFFS(frmtxstatus));
++		}
++
++		s2 = bcma_read32(wlc->hw->d11core, D11REGOFFS(frmtxstatus2));
++	}
++
++	if (scb) {
++		scb_ampdu = &scb->scb_ampdu;
++		ini = &scb_ampdu->ini[p->priority];
++		brcms_c_ampdu_dotxstatus_complete(ampdu, scb, p, txs, s1, s2);
++	} else {
++		/* loop through all pkts and free */
++		u8 queue = txs->frameid & TXFID_QUEUE_MASK;
++		struct d11txh *txh;
++		u16 mcl;
++		while (p) {
++			tx_info = IEEE80211_SKB_CB(p);
++			txh = (struct d11txh *) p->data;
++			mcl = le16_to_cpu(txh->MacTxControlLow);
++			brcmu_pkt_buf_free_skb(p);
++			/* break out if last packet of ampdu */
++			if (((mcl & TXC_AMPDU_MASK) >> TXC_AMPDU_SHIFT) ==
++			    TXC_AMPDU_LAST)
++				break;
++			p = dma_getnexttxp(wlc->hw->di[queue],
++					   DMA_RANGE_TRANSMITTED);
++		}
++		brcms_c_txfifo_complete(wlc, queue, ampdu->txpkt_weight);
++	}
++}
++
++void brcms_c_ampdu_macaddr_upd(struct brcms_c_info *wlc)
++{
++	char template[T_RAM_ACCESS_SZ * 2];
++
++	/* driver needs to write the ta in the template; ta is at offset 16 */
++	memset(template, 0, sizeof(template));
++	memcpy(template, wlc->pub->cur_etheraddr, ETH_ALEN);
++	brcms_b_write_template_ram(wlc->hw, (T_BA_TPL_BASE + 16),
++				  (T_RAM_ACCESS_SZ * 2),
++				  template);
++}
++
++bool brcms_c_aggregatable(struct brcms_c_info *wlc, u8 tid)
++{
++	return wlc->ampdu->ini_enable[tid];
++}
++
++void brcms_c_ampdu_shm_upd(struct ampdu_info *ampdu)
++{
++	struct brcms_c_info *wlc = ampdu->wlc;
++
++	/*
++	 * Extend ucode internal watchdog timer to
++	 * match larger received frames
++	 */
++	if ((ampdu->rx_factor & IEEE80211_HT_AMPDU_PARM_FACTOR) ==
++	    IEEE80211_HT_MAX_AMPDU_64K) {
++		brcms_b_write_shm(wlc->hw, M_MIMO_MAXSYM, MIMO_MAXSYM_MAX);
++		brcms_b_write_shm(wlc->hw, M_WATCHDOG_8TU, WATCHDOG_8TU_MAX);
++	} else {
++		brcms_b_write_shm(wlc->hw, M_MIMO_MAXSYM, MIMO_MAXSYM_DEF);
++		brcms_b_write_shm(wlc->hw, M_WATCHDOG_8TU, WATCHDOG_8TU_DEF);
++	}
++}
++
++/*
++ * callback function that helps flushing ampdu packets from a priority queue
++ */
++static bool cb_del_ampdu_pkt(struct sk_buff *mpdu, void *arg_a)
++{
++	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(mpdu);
++	struct cb_del_ampdu_pars *ampdu_pars =
++				 (struct cb_del_ampdu_pars *)arg_a;
++	bool rc;
++
++	rc = tx_info->flags & IEEE80211_TX_CTL_AMPDU ? true : false;
++	rc = rc && (tx_info->control.sta == NULL || ampdu_pars->sta == NULL ||
++		    tx_info->control.sta == ampdu_pars->sta);
++	rc = rc && ((u8)(mpdu->priority) == ampdu_pars->tid);
++	return rc;
++}
++
++/*
++ * callback function that helps invalidating ampdu packets in a DMA queue
++ */
++static void dma_cb_fn_ampdu(void *txi, void *arg_a)
++{
++	struct ieee80211_sta *sta = arg_a;
++	struct ieee80211_tx_info *tx_info = (struct ieee80211_tx_info *)txi;
++
++	if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) &&
++	    (tx_info->control.sta == sta || sta == NULL))
++		tx_info->control.sta = NULL;
++}
++
++/*
++ * When a remote party is no longer available for ampdu communication, any
++ * pending tx ampdu packets in the driver have to be flushed.
++ */
++void brcms_c_ampdu_flush(struct brcms_c_info *wlc,
++		     struct ieee80211_sta *sta, u16 tid)
++{
++	struct brcms_txq_info *qi = wlc->pkt_queue;
++	struct pktq *pq = &qi->q;
++	int prec;
++	struct cb_del_ampdu_pars ampdu_pars;
++
++	ampdu_pars.sta = sta;
++	ampdu_pars.tid = tid;
++	for (prec = 0; prec < pq->num_prec; prec++)
++		brcmu_pktq_pflush(pq, prec, true, cb_del_ampdu_pkt,
++			    (void *)&ampdu_pars);
++	brcms_c_inval_dma_pkts(wlc->hw, sta, dma_cb_fn_ampdu);
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.h b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.h
+new file mode 100644
+index 0000000..421f4ba
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.h
+@@ -0,0 +1,30 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef _BRCM_AMPDU_H_
++#define _BRCM_AMPDU_H_
++
++extern struct ampdu_info *brcms_c_ampdu_attach(struct brcms_c_info *wlc);
++extern void brcms_c_ampdu_detach(struct ampdu_info *ampdu);
++extern int brcms_c_sendampdu(struct ampdu_info *ampdu,
++			     struct brcms_txq_info *qi,
++			     struct sk_buff **aggp, int prec);
++extern void brcms_c_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb,
++				 struct sk_buff *p, struct tx_status *txs);
++extern void brcms_c_ampdu_macaddr_upd(struct brcms_c_info *wlc);
++extern void brcms_c_ampdu_shm_upd(struct ampdu_info *ampdu);
++
++#endif				/* _BRCM_AMPDU_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/antsel.c b/drivers/net/wireless/brcm80211/brcmsmac/antsel.c
+new file mode 100644
+index 0000000..55e12c3
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/antsel.c
+@@ -0,0 +1,307 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#include <linux/slab.h>
++#include <net/mac80211.h>
++
++#include "types.h"
++#include "main.h"
++#include "phy_shim.h"
++#include "antsel.h"
++
++#define ANT_SELCFG_AUTO		0x80	/* bit indicates antenna sel AUTO */
++#define ANT_SELCFG_MASK		0x33	/* antenna configuration mask */
++#define ANT_SELCFG_TX_UNICAST	0	/* unicast tx antenna configuration */
++#define ANT_SELCFG_RX_UNICAST	1	/* unicast rx antenna configuration */
++#define ANT_SELCFG_TX_DEF	2	/* default tx antenna configuration */
++#define ANT_SELCFG_RX_DEF	3	/* default rx antenna configuration */
++
++/* useful macros */
++#define BRCMS_ANTSEL_11N_0(ant)	((((ant) & ANT_SELCFG_MASK) >> 4) & 0xf)
++#define BRCMS_ANTSEL_11N_1(ant)	(((ant) & ANT_SELCFG_MASK) & 0xf)
++#define BRCMS_ANTIDX_11N(ant)	(((BRCMS_ANTSEL_11N_0(ant)) << 2) +\
++				(BRCMS_ANTSEL_11N_1(ant)))
++#define BRCMS_ANT_ISAUTO_11N(ant) (((ant) & ANT_SELCFG_AUTO) == ANT_SELCFG_AUTO)
++#define BRCMS_ANTSEL_11N(ant)	((ant) & ANT_SELCFG_MASK)
++
++/* antenna switch */
++/* defines for no boardlevel antenna diversity */
++#define ANT_SELCFG_DEF_2x2	0x01	/* default antenna configuration */
++
++/* 2x3 antdiv defines and tables for GPIO communication */
++#define ANT_SELCFG_NUM_2x3	3
++#define ANT_SELCFG_DEF_2x3	0x01	/* default antenna configuration */
++
++/* 2x4 antdiv rev4 defines and tables for GPIO communication */
++#define ANT_SELCFG_NUM_2x4	4
++#define ANT_SELCFG_DEF_2x4	0x02	/* default antenna configuration */
++
++static const u16 mimo_2x4_div_antselpat_tbl[] = {
++	0, 0, 0x9, 0xa,		/* ant0: 0 ant1: 2,3 */
++	0, 0, 0x5, 0x6,		/* ant0: 1 ant1: 2,3 */
++	0, 0, 0, 0,		/* n.a.              */
++	0, 0, 0, 0		/* n.a.              */
++};
++
++static const u8 mimo_2x4_div_antselid_tbl[16] = {
++	0, 0, 0, 0, 0, 2, 3, 0,
++	0, 0, 1, 0, 0, 0, 0, 0	/* pat to antselid */
++};
++
++static const u16 mimo_2x3_div_antselpat_tbl[] = {
++	16, 0, 1, 16,		/* ant0: 0 ant1: 1,2 */
++	16, 16, 16, 16,		/* n.a.              */
++	16, 2, 16, 16,		/* ant0: 2 ant1: 1   */
++	16, 16, 16, 16		/* n.a.              */
++};
++
++static const u8 mimo_2x3_div_antselid_tbl[16] = {
++	0, 1, 2, 0, 0, 0, 0, 0,
++	0, 0, 0, 0, 0, 0, 0, 0	/* pat to antselid */
++};
++
++/* boardlevel antenna selection: init antenna selection structure */
++static void
++brcms_c_antsel_init_cfg(struct antsel_info *asi, struct brcms_antselcfg *antsel,
++		    bool auto_sel)
++{
++	if (asi->antsel_type == ANTSEL_2x3) {
++		u8 antcfg_def = ANT_SELCFG_DEF_2x3 |
++		    ((asi->antsel_avail && auto_sel) ? ANT_SELCFG_AUTO : 0);
++		antsel->ant_config[ANT_SELCFG_TX_DEF] = antcfg_def;
++		antsel->ant_config[ANT_SELCFG_TX_UNICAST] = antcfg_def;
++		antsel->ant_config[ANT_SELCFG_RX_DEF] = antcfg_def;
++		antsel->ant_config[ANT_SELCFG_RX_UNICAST] = antcfg_def;
++		antsel->num_antcfg = ANT_SELCFG_NUM_2x3;
++
++	} else if (asi->antsel_type == ANTSEL_2x4) {
++
++		antsel->ant_config[ANT_SELCFG_TX_DEF] = ANT_SELCFG_DEF_2x4;
++		antsel->ant_config[ANT_SELCFG_TX_UNICAST] = ANT_SELCFG_DEF_2x4;
++		antsel->ant_config[ANT_SELCFG_RX_DEF] = ANT_SELCFG_DEF_2x4;
++		antsel->ant_config[ANT_SELCFG_RX_UNICAST] = ANT_SELCFG_DEF_2x4;
++		antsel->num_antcfg = ANT_SELCFG_NUM_2x4;
++
++	} else {		/* no antenna selection available */
++
++		antsel->ant_config[ANT_SELCFG_TX_DEF] = ANT_SELCFG_DEF_2x2;
++		antsel->ant_config[ANT_SELCFG_TX_UNICAST] = ANT_SELCFG_DEF_2x2;
++		antsel->ant_config[ANT_SELCFG_RX_DEF] = ANT_SELCFG_DEF_2x2;
++		antsel->ant_config[ANT_SELCFG_RX_UNICAST] = ANT_SELCFG_DEF_2x2;
++		antsel->num_antcfg = 0;
++	}
++}
++
++struct antsel_info *brcms_c_antsel_attach(struct brcms_c_info *wlc)
++{
++	struct antsel_info *asi;
++	struct ssb_sprom *sprom = &wlc->hw->d11core->bus->sprom;
++
++	asi = kzalloc(sizeof(struct antsel_info), GFP_ATOMIC);
++	if (!asi)
++		return NULL;
++
++	asi->wlc = wlc;
++	asi->pub = wlc->pub;
++	asi->antsel_type = ANTSEL_NA;
++	asi->antsel_avail = false;
++	asi->antsel_antswitch = sprom->antswitch;
++
++	if ((asi->pub->sromrev >= 4) && (asi->antsel_antswitch != 0)) {
++		switch (asi->antsel_antswitch) {
++		case ANTSWITCH_TYPE_1:
++		case ANTSWITCH_TYPE_2:
++		case ANTSWITCH_TYPE_3:
++			/* 4321/2 board with 2x3 switch logic */
++			asi->antsel_type = ANTSEL_2x3;
++			/* Antenna selection availability */
++			if ((sprom->ant_available_bg == 7) ||
++			    (sprom->ant_available_a == 7)) {
++				asi->antsel_avail = true;
++			} else if (
++				sprom->ant_available_bg == 3 ||
++				sprom->ant_available_a == 3) {
++				asi->antsel_avail = false;
++			} else {
++				asi->antsel_avail = false;
++				wiphy_err(wlc->wiphy, "antsel_attach: 2o3 "
++					  "board cfg invalid\n");
++			}
++
++			break;
++		default:
++			break;
++		}
++	} else if ((asi->pub->sromrev == 4) &&
++		   (sprom->ant_available_bg == 7) &&
++		   (sprom->ant_available_a == 0)) {
++		/* hack to match old 4321CB2 cards with 2of3 antenna switch */
++		asi->antsel_type = ANTSEL_2x3;
++		asi->antsel_avail = true;
++	} else if (asi->pub->boardflags2 & BFL2_2X4_DIV) {
++		asi->antsel_type = ANTSEL_2x4;
++		asi->antsel_avail = true;
++	}
++
++	/* Set the antenna selection type for the low driver */
++	brcms_b_antsel_type_set(wlc->hw, asi->antsel_type);
++
++	/* Init (auto/manual) antenna selection */
++	brcms_c_antsel_init_cfg(asi, &asi->antcfg_11n, true);
++	brcms_c_antsel_init_cfg(asi, &asi->antcfg_cur, true);
++
++	return asi;
++}
++
++void brcms_c_antsel_detach(struct antsel_info *asi)
++{
++	kfree(asi);
++}
++
++/*
++ * boardlevel antenna selection:
++ *   convert ant_cfg to mimo_antsel (ucode interface)
++ */
++static u16 brcms_c_antsel_antcfg2antsel(struct antsel_info *asi, u8 ant_cfg)
++{
++	u8 idx = BRCMS_ANTIDX_11N(BRCMS_ANTSEL_11N(ant_cfg));
++	u16 mimo_antsel = 0;
++
++	if (asi->antsel_type == ANTSEL_2x4) {
++		/* 2x4 antenna diversity board, 4 cfgs: 0-2 0-3 1-2 1-3 */
++		mimo_antsel = (mimo_2x4_div_antselpat_tbl[idx] & 0xf);
++		return mimo_antsel;
++
++	} else if (asi->antsel_type == ANTSEL_2x3) {
++		/* 2x3 antenna selection, 3 cfgs: 0-1 0-2 2-1 */
++		mimo_antsel = (mimo_2x3_div_antselpat_tbl[idx] & 0xf);
++		return mimo_antsel;
++	}
++
++	return mimo_antsel;
++}
++
++/* boardlevel antenna selection: ucode interface control */
++static int brcms_c_antsel_cfgupd(struct antsel_info *asi,
++				 struct brcms_antselcfg *antsel)
++{
++	struct brcms_c_info *wlc = asi->wlc;
++	u8 ant_cfg;
++	u16 mimo_antsel;
++
++	/* 1) Update TX antconfig for all frames that are not unicast data
++	 *    (aka default TX)
++	 */
++	ant_cfg = antsel->ant_config[ANT_SELCFG_TX_DEF];
++	mimo_antsel = brcms_c_antsel_antcfg2antsel(asi, ant_cfg);
++	brcms_b_write_shm(wlc->hw, M_MIMO_ANTSEL_TXDFLT, mimo_antsel);
++	/*
++	 * Update driver stats for currently selected
++	 * default tx/rx antenna config
++	 */
++	asi->antcfg_cur.ant_config[ANT_SELCFG_TX_DEF] = ant_cfg;
++
++	/* 2) Update RX antconfig for all frames that are not unicast data
++	 *    (aka default RX)
++	 */
++	ant_cfg = antsel->ant_config[ANT_SELCFG_RX_DEF];
++	mimo_antsel = brcms_c_antsel_antcfg2antsel(asi, ant_cfg);
++	brcms_b_write_shm(wlc->hw, M_MIMO_ANTSEL_RXDFLT, mimo_antsel);
++	/*
++	 * Update driver stats for currently selected
++	 * default tx/rx antenna config
++	 */
++	asi->antcfg_cur.ant_config[ANT_SELCFG_RX_DEF] = ant_cfg;
++
++	return 0;
++}
++
++void brcms_c_antsel_init(struct antsel_info *asi)
++{
++	if ((asi->antsel_type == ANTSEL_2x3) ||
++	    (asi->antsel_type == ANTSEL_2x4))
++		brcms_c_antsel_cfgupd(asi, &asi->antcfg_11n);
++}
++
++/* boardlevel antenna selection: convert id to ant_cfg */
++static u8 brcms_c_antsel_id2antcfg(struct antsel_info *asi, u8 id)
++{
++	u8 antcfg = ANT_SELCFG_DEF_2x2;
++
++	if (asi->antsel_type == ANTSEL_2x4) {
++		/* 2x4 antenna diversity board, 4 cfgs: 0-2 0-3 1-2 1-3 */
++		antcfg = (((id & 0x2) << 3) | ((id & 0x1) + 2));
++		return antcfg;
++
++	} else if (asi->antsel_type == ANTSEL_2x3) {
++		/* 2x3 antenna selection, 3 cfgs: 0-1 0-2 2-1 */
++		antcfg = (((id & 0x02) << 4) | ((id & 0x1) + 1));
++		return antcfg;
++	}
++
++	return antcfg;
++}
++
++void
++brcms_c_antsel_antcfg_get(struct antsel_info *asi, bool usedef, bool sel,
++		      u8 antselid, u8 fbantselid, u8 *antcfg,
++		      u8 *fbantcfg)
++{
++	u8 ant;
++
++	/* if use default, assign it and return */
++	if (usedef) {
++		*antcfg = asi->antcfg_11n.ant_config[ANT_SELCFG_TX_DEF];
++		*fbantcfg = *antcfg;
++		return;
++	}
++
++	if (!sel) {
++		*antcfg = asi->antcfg_11n.ant_config[ANT_SELCFG_TX_UNICAST];
++		*fbantcfg = *antcfg;
++
++	} else {
++		ant = asi->antcfg_11n.ant_config[ANT_SELCFG_TX_UNICAST];
++		if ((ant & ANT_SELCFG_AUTO) == ANT_SELCFG_AUTO) {
++			*antcfg = brcms_c_antsel_id2antcfg(asi, antselid);
++			*fbantcfg = brcms_c_antsel_id2antcfg(asi, fbantselid);
++		} else {
++			*antcfg =
++			    asi->antcfg_11n.ant_config[ANT_SELCFG_TX_UNICAST];
++			*fbantcfg = *antcfg;
++		}
++	}
++	return;
++}
++
++/* boardlevel antenna selection: convert mimo_antsel (ucode interface) to id */
++u8 brcms_c_antsel_antsel2id(struct antsel_info *asi, u16 antsel)
++{
++	u8 antselid = 0;
++
++	if (asi->antsel_type == ANTSEL_2x4) {
++		/* 2x4 antenna diversity board, 4 cfgs: 0-2 0-3 1-2 1-3 */
++		antselid = mimo_2x4_div_antselid_tbl[(antsel & 0xf)];
++		return antselid;
++
++	} else if (asi->antsel_type == ANTSEL_2x3) {
++		/* 2x3 antenna selection, 3 cfgs: 0-1 0-2 2-1 */
++		antselid = mimo_2x3_div_antselid_tbl[(antsel & 0xf)];
++		return antselid;
++	}
++
++	return antselid;
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/antsel.h b/drivers/net/wireless/brcm80211/brcmsmac/antsel.h
+new file mode 100644
+index 0000000..97ea388
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/antsel.h
+@@ -0,0 +1,29 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef _BRCM_ANTSEL_H_
++#define _BRCM_ANTSEL_H_
++
++extern struct antsel_info *brcms_c_antsel_attach(struct brcms_c_info *wlc);
++extern void brcms_c_antsel_detach(struct antsel_info *asi);
++extern void brcms_c_antsel_init(struct antsel_info *asi);
++extern void brcms_c_antsel_antcfg_get(struct antsel_info *asi, bool usedef,
++				  bool sel,
++				  u8 id, u8 fbid, u8 *antcfg,
++				  u8 *fbantcfg);
++extern u8 brcms_c_antsel_antsel2id(struct antsel_info *asi, u16 antsel);
++
++#endif /* _BRCM_ANTSEL_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.c b/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.c
+new file mode 100644
+index 0000000..52fc9ee
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.c
+@@ -0,0 +1,23 @@
++/*
++ * Copyright (c) 2011 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#include <linux/module.h> /* bug in tracepoint.h, it should include this */
++
++#ifndef __CHECKER__
++#include "mac80211_if.h"
++#define CREATE_TRACE_POINTS
++#include "brcms_trace_events.h"
++#endif
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h b/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h
+new file mode 100644
+index 0000000..27dd73e
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h
+@@ -0,0 +1,92 @@
++/*
++ * Copyright (c) 2011 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#undef TRACE_SYSTEM
++#define TRACE_SYSTEM brcmsmac
++
++#if !defined(__TRACE_BRCMSMAC_H) || defined(TRACE_HEADER_MULTI_READ)
++
++#define __TRACE_BRCMSMAC_H
++
++#include <linux/tracepoint.h>
++#include "mac80211_if.h"
++
++#ifndef CONFIG_BRCMDBG
++#undef TRACE_EVENT
++#define TRACE_EVENT(name, proto, ...) \
++static inline void trace_ ## name(proto) {}
++#endif
++
++/*
++ * We define a tracepoint, its arguments, its printk format and its
++ * 'fast binary record' layout.
++ */
++TRACE_EVENT(brcms_timer,
++	/* TPPROTO is the prototype of the function called by this tracepoint */
++	TP_PROTO(struct brcms_timer *t),
++	/*
++	 * TPARGS(firstarg, p) are the parameters names, same as found in the
++	 * prototype.
++	 */
++	TP_ARGS(t),
++	/*
++	 * Fast binary tracing: define the trace record via TP_STRUCT__entry().
++	 * You can think about it like a regular C structure local variable
++	 * definition.
++	 */
++	TP_STRUCT__entry(
++		__field(uint, ms)
++		__field(uint, set)
++		__field(uint, periodic)
++	),
++	TP_fast_assign(
++		__entry->ms = t->ms;
++		__entry->set = t->set;
++		__entry->periodic = t->periodic;
++	),
++	TP_printk(
++		"ms=%u set=%u periodic=%u",
++		__entry->ms, __entry->set, __entry->periodic
++	)
++);
++
++TRACE_EVENT(brcms_dpc,
++	TP_PROTO(unsigned long data),
++	TP_ARGS(data),
++	TP_STRUCT__entry(
++		__field(unsigned long, data)
++	),
++	TP_fast_assign(
++		__entry->data = data;
++	),
++	TP_printk(
++		"data=%p",
++		(void *)__entry->data
++	)
++);
++
++#endif /* __TRACE_BRCMSMAC_H */
++
++#ifdef CONFIG_BRCMDBG
++
++#undef TRACE_INCLUDE_PATH
++#define TRACE_INCLUDE_PATH .
++#undef TRACE_INCLUDE_FILE
++#define TRACE_INCLUDE_FILE brcms_trace_events
++
++#include <trace/define_trace.h>
++
++#endif /* CONFIG_BRCMDBG */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/channel.c b/drivers/net/wireless/brcm80211/brcmsmac/channel.c
+new file mode 100644
+index 0000000..eb77ac3
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/channel.c
+@@ -0,0 +1,1506 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#include <linux/types.h>
++#include <net/mac80211.h>
++
++#include <defs.h>
++#include "pub.h"
++#include "phy/phy_hal.h"
++#include "main.h"
++#include "stf.h"
++#include "channel.h"
++
++/* QDB() macro takes a dB value and converts to a quarter dB value */
++#define QDB(n) ((n) * BRCMS_TXPWR_DB_FACTOR)
++
++#define  LOCALE_CHAN_01_11	 (1<<0)
++#define  LOCALE_CHAN_12_13	 (1<<1)
++#define  LOCALE_CHAN_14		 (1<<2)
++#define  LOCALE_SET_5G_LOW_JP1   (1<<3)	/* 34-48, step 2 */
++#define  LOCALE_SET_5G_LOW_JP2   (1<<4)	/* 34-46, step 4 */
++#define  LOCALE_SET_5G_LOW1      (1<<5)	/* 36-48, step 4 */
++#define  LOCALE_SET_5G_LOW2      (1<<6)	/* 52 */
++#define  LOCALE_SET_5G_LOW3      (1<<7)	/* 56-64, step 4 */
++#define  LOCALE_SET_5G_MID1      (1<<8)	/* 100-116, step 4 */
++#define  LOCALE_SET_5G_MID2	 (1<<9)	/* 120-124, step 4 */
++#define  LOCALE_SET_5G_MID3      (1<<10)	/* 128 */
++#define  LOCALE_SET_5G_HIGH1     (1<<11)	/* 132-140, step 4 */
++#define  LOCALE_SET_5G_HIGH2     (1<<12)	/* 149-161, step 4 */
++#define  LOCALE_SET_5G_HIGH3     (1<<13)	/* 165 */
++#define  LOCALE_CHAN_52_140_ALL  (1<<14)
++#define  LOCALE_SET_5G_HIGH4     (1<<15)	/* 184-216 */
++
++#define  LOCALE_CHAN_36_64	(LOCALE_SET_5G_LOW1 | \
++				 LOCALE_SET_5G_LOW2 | \
++				 LOCALE_SET_5G_LOW3)
++#define  LOCALE_CHAN_52_64	(LOCALE_SET_5G_LOW2 | LOCALE_SET_5G_LOW3)
++#define  LOCALE_CHAN_100_124	(LOCALE_SET_5G_MID1 | LOCALE_SET_5G_MID2)
++#define  LOCALE_CHAN_100_140	(LOCALE_SET_5G_MID1 | LOCALE_SET_5G_MID2 | \
++				  LOCALE_SET_5G_MID3 | LOCALE_SET_5G_HIGH1)
++#define  LOCALE_CHAN_149_165	(LOCALE_SET_5G_HIGH2 | LOCALE_SET_5G_HIGH3)
++#define  LOCALE_CHAN_184_216	LOCALE_SET_5G_HIGH4
++
++#define  LOCALE_CHAN_01_14	(LOCALE_CHAN_01_11 | \
++				 LOCALE_CHAN_12_13 | \
++				 LOCALE_CHAN_14)
++
++#define  LOCALE_RADAR_SET_NONE		  0
++#define  LOCALE_RADAR_SET_1		  1
++
++#define  LOCALE_RESTRICTED_NONE		  0
++#define  LOCALE_RESTRICTED_SET_2G_SHORT   1
++#define  LOCALE_RESTRICTED_CHAN_165       2
++#define  LOCALE_CHAN_ALL_5G		  3
++#define  LOCALE_RESTRICTED_JAPAN_LEGACY   4
++#define  LOCALE_RESTRICTED_11D_2G	  5
++#define  LOCALE_RESTRICTED_11D_5G	  6
++#define  LOCALE_RESTRICTED_LOW_HI	  7
++#define  LOCALE_RESTRICTED_12_13_14	  8
++
++#define LOCALE_2G_IDX_i			0
++#define LOCALE_5G_IDX_11		0
++#define LOCALE_MIMO_IDX_bn		0
++#define LOCALE_MIMO_IDX_11n		0
++
++/* max of BAND_5G_PWR_LVLS and 6 for 2.4 GHz */
++#define BRCMS_MAXPWR_TBL_SIZE		6
++/* max of BAND_5G_PWR_LVLS and 14 for 2.4 GHz */
++#define BRCMS_MAXPWR_MIMO_TBL_SIZE	14
++
++/* power level in group of 2.4GHz band channels:
++ * maxpwr[0] - CCK  channels [1]
++ * maxpwr[1] - CCK  channels [2-10]
++ * maxpwr[2] - CCK  channels [11-14]
++ * maxpwr[3] - OFDM channels [1]
++ * maxpwr[4] - OFDM channels [2-10]
++ * maxpwr[5] - OFDM channels [11-14]
++ */
++
++/* maxpwr mapping to 5GHz band channels:
++ * maxpwr[0] - channels [34-48]
++ * maxpwr[1] - channels [52-60]
++ * maxpwr[2] - channels [62-64]
++ * maxpwr[3] - channels [100-140]
++ * maxpwr[4] - channels [149-165]
++ */
++#define BAND_5G_PWR_LVLS	5	/* 5 power levels for 5G */
++
++#define LC(id)	LOCALE_MIMO_IDX_ ## id
++
++#define LC_2G(id)	LOCALE_2G_IDX_ ## id
++
++#define LC_5G(id)	LOCALE_5G_IDX_ ## id
++
++#define LOCALES(band2, band5, mimo2, mimo5) \
++		{LC_2G(band2), LC_5G(band5), LC(mimo2), LC(mimo5)}
++
++/* macro to get 2.4 GHz channel group index for tx power */
++#define CHANNEL_POWER_IDX_2G_CCK(c) (((c) < 2) ? 0 : (((c) < 11) ? 1 : 2))
++#define CHANNEL_POWER_IDX_2G_OFDM(c) (((c) < 2) ? 3 : (((c) < 11) ? 4 : 5))
++
++/* macro to get 5 GHz channel group index for tx power */
++#define CHANNEL_POWER_IDX_5G(c) (((c) < 52) ? 0 : \
++				 (((c) < 62) ? 1 : \
++				 (((c) < 100) ? 2 : \
++				 (((c) < 149) ? 3 : 4))))
++
++#define ISDFS_EU(fl)		(((fl) & BRCMS_DFS_EU) == BRCMS_DFS_EU)
++
++struct brcms_cm_band {
++	/* struct locale_info flags */
++	u8 locale_flags;
++	/* List of valid channels in the country */
++	struct brcms_chanvec valid_channels;
++	/* List of restricted use channels */
++	const struct brcms_chanvec *restricted_channels;
++	/* List of radar sensitive channels */
++	const struct brcms_chanvec *radar_channels;
++	u8 PAD[8];
++};
++
++ /* locale per-channel tx power limits for MIMO frames
++  * maxpwr arrays are index by channel for 2.4 GHz limits, and
++  * by sub-band for 5 GHz limits using CHANNEL_POWER_IDX_5G(channel)
++  */
++struct locale_mimo_info {
++	/* tx 20 MHz power limits, qdBm units */
++	s8 maxpwr20[BRCMS_MAXPWR_MIMO_TBL_SIZE];
++	/* tx 40 MHz power limits, qdBm units */
++	s8 maxpwr40[BRCMS_MAXPWR_MIMO_TBL_SIZE];
++	u8 flags;
++};
++
++/* Country names and abbreviations with locale defined from ISO 3166 */
++struct country_info {
++	const u8 locale_2G;	/* 2.4G band locale */
++	const u8 locale_5G;	/* 5G band locale */
++	const u8 locale_mimo_2G;	/* 2.4G mimo info */
++	const u8 locale_mimo_5G;	/* 5G mimo info */
++};
++
++struct brcms_cm_info {
++	struct brcms_pub *pub;
++	struct brcms_c_info *wlc;
++	char srom_ccode[BRCM_CNTRY_BUF_SZ];	/* Country Code in SROM */
++	uint srom_regrev;	/* Regulatory Rev for the SROM ccode */
++	const struct country_info *country;	/* current country def */
++	char ccode[BRCM_CNTRY_BUF_SZ];	/* current internal Country Code */
++	uint regrev;		/* current Regulatory Revision */
++	char country_abbrev[BRCM_CNTRY_BUF_SZ];	/* current advertised ccode */
++	/* per-band state (one per phy/radio) */
++	struct brcms_cm_band bandstate[MAXBANDS];
++	/* quiet channels currently for radar sensitivity or 11h support */
++	/* channels on which we cannot transmit */
++	struct brcms_chanvec quiet_channels;
++};
++
++/* locale channel and power info. */
++struct locale_info {
++	u32 valid_channels;
++	/* List of radar sensitive channels */
++	u8 radar_channels;
++	/* List of channels used only if APs are detected */
++	u8 restricted_channels;
++	/* Max tx pwr in qdBm for each sub-band */
++	s8 maxpwr[BRCMS_MAXPWR_TBL_SIZE];
++	/* Country IE advertised max tx pwr in dBm per sub-band */
++	s8 pub_maxpwr[BAND_5G_PWR_LVLS];
++	u8 flags;
++};
++
++/* Regulatory Matrix Spreadsheet (CLM) MIMO v3.7.9 */
++
++/*
++ * Some common channel sets
++ */
++
++/* No channels */
++static const struct brcms_chanvec chanvec_none = {
++	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++/* All 2.4 GHz HW channels */
++static const struct brcms_chanvec chanvec_all_2G = {
++	{0xfe, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++/* All 5 GHz HW channels */
++static const struct brcms_chanvec chanvec_all_5G = {
++	{0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0x11, 0x11,
++	 0x01, 0x00, 0x00, 0x00, 0x10, 0x11, 0x11, 0x11,
++	 0x11, 0x11, 0x20, 0x22, 0x22, 0x00, 0x00, 0x11,
++	 0x11, 0x11, 0x11, 0x01}
++};
++
++/*
++ * Radar channel sets
++ */
++
++/* Channels 52 - 64, 100 - 140 */
++static const struct brcms_chanvec radar_set1 = {
++	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x11,  /* 52 - 60 */
++	 0x01, 0x00, 0x00, 0x00, 0x10, 0x11, 0x11, 0x11,  /* 64, 100 - 124 */
++	 0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 128 - 140 */
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++/*
++ * Restricted channel sets
++ */
++
++/* Channels 34, 38, 42, 46 */
++static const struct brcms_chanvec restricted_set_japan_legacy = {
++	{0x00, 0x00, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++/* Channels 12, 13 */
++static const struct brcms_chanvec restricted_set_2g_short = {
++	{0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++/* Channel 165 */
++static const struct brcms_chanvec restricted_chan_165 = {
++	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++/* Channels 36 - 48 & 149 - 165 */
++static const struct brcms_chanvec restricted_low_hi = {
++	{0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x01, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x20, 0x22, 0x22, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++/* Channels 12 - 14 */
++static const struct brcms_chanvec restricted_set_12_13_14 = {
++	{0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++/* global memory to provide working buffer for expanded locale */
++
++static const struct brcms_chanvec *g_table_radar_set[] = {
++	&chanvec_none,
++	&radar_set1
++};
++
++static const struct brcms_chanvec *g_table_restricted_chan[] = {
++	&chanvec_none,		/* restricted_set_none */
++	&restricted_set_2g_short,
++	&restricted_chan_165,
++	&chanvec_all_5G,
++	&restricted_set_japan_legacy,
++	&chanvec_all_2G,	/* restricted_set_11d_2G */
++	&chanvec_all_5G,	/* restricted_set_11d_5G */
++	&restricted_low_hi,
++	&restricted_set_12_13_14
++};
++
++static const struct brcms_chanvec locale_2g_01_11 = {
++	{0xfe, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++static const struct brcms_chanvec locale_2g_12_13 = {
++	{0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++static const struct brcms_chanvec locale_2g_14 = {
++	{0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++static const struct brcms_chanvec locale_5g_LOW_JP1 = {
++	{0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0x01, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++static const struct brcms_chanvec locale_5g_LOW_JP2 = {
++	{0x00, 0x00, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++static const struct brcms_chanvec locale_5g_LOW1 = {
++	{0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x01, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++static const struct brcms_chanvec locale_5g_LOW2 = {
++	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++static const struct brcms_chanvec locale_5g_LOW3 = {
++	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
++	 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++static const struct brcms_chanvec locale_5g_MID1 = {
++	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x11, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++static const struct brcms_chanvec locale_5g_MID2 = {
++	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++static const struct brcms_chanvec locale_5g_MID3 = {
++	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++static const struct brcms_chanvec locale_5g_HIGH1 = {
++	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++static const struct brcms_chanvec locale_5g_HIGH2 = {
++	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x20, 0x22, 0x02, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++static const struct brcms_chanvec locale_5g_HIGH3 = {
++	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++static const struct brcms_chanvec locale_5g_52_140_ALL = {
++	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x11,
++	 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
++	 0x11, 0x11, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++static const struct brcms_chanvec locale_5g_HIGH4 = {
++	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
++	 0x11, 0x11, 0x11, 0x11}
++};
++
++static const struct brcms_chanvec *g_table_locale_base[] = {
++	&locale_2g_01_11,
++	&locale_2g_12_13,
++	&locale_2g_14,
++	&locale_5g_LOW_JP1,
++	&locale_5g_LOW_JP2,
++	&locale_5g_LOW1,
++	&locale_5g_LOW2,
++	&locale_5g_LOW3,
++	&locale_5g_MID1,
++	&locale_5g_MID2,
++	&locale_5g_MID3,
++	&locale_5g_HIGH1,
++	&locale_5g_HIGH2,
++	&locale_5g_HIGH3,
++	&locale_5g_52_140_ALL,
++	&locale_5g_HIGH4
++};
++
++static void brcms_c_locale_add_channels(struct brcms_chanvec *target,
++				    const struct brcms_chanvec *channels)
++{
++	u8 i;
++	for (i = 0; i < sizeof(struct brcms_chanvec); i++)
++		target->vec[i] |= channels->vec[i];
++}
++
++static void brcms_c_locale_get_channels(const struct locale_info *locale,
++				    struct brcms_chanvec *channels)
++{
++	u8 i;
++
++	memset(channels, 0, sizeof(struct brcms_chanvec));
++
++	for (i = 0; i < ARRAY_SIZE(g_table_locale_base); i++) {
++		if (locale->valid_channels & (1 << i))
++			brcms_c_locale_add_channels(channels,
++						g_table_locale_base[i]);
++	}
++}
++
++/*
++ * Locale Definitions - 2.4 GHz
++ */
++static const struct locale_info locale_i = {	/* locale i. channel 1 - 13 */
++	LOCALE_CHAN_01_11 | LOCALE_CHAN_12_13,
++	LOCALE_RADAR_SET_NONE,
++	LOCALE_RESTRICTED_SET_2G_SHORT,
++	{QDB(19), QDB(19), QDB(19),
++	 QDB(19), QDB(19), QDB(19)},
++	{20, 20, 20, 0},
++	BRCMS_EIRP
++};
++
++/*
++ * Locale Definitions - 5 GHz
++ */
++static const struct locale_info locale_11 = {
++	/* locale 11. channel 36 - 48, 52 - 64, 100 - 140, 149 - 165 */
++	LOCALE_CHAN_36_64 | LOCALE_CHAN_100_140 | LOCALE_CHAN_149_165,
++	LOCALE_RADAR_SET_1,
++	LOCALE_RESTRICTED_NONE,
++	{QDB(21), QDB(21), QDB(21), QDB(21), QDB(21)},
++	{23, 23, 23, 30, 30},
++	BRCMS_EIRP | BRCMS_DFS_EU
++};
++
++static const struct locale_info *g_locale_2g_table[] = {
++	&locale_i
++};
++
++static const struct locale_info *g_locale_5g_table[] = {
++	&locale_11
++};
++
++/*
++ * MIMO Locale Definitions - 2.4 GHz
++ */
++static const struct locale_mimo_info locale_bn = {
++	{QDB(13), QDB(13), QDB(13), QDB(13), QDB(13),
++	 QDB(13), QDB(13), QDB(13), QDB(13), QDB(13),
++	 QDB(13), QDB(13), QDB(13)},
++	{0, 0, QDB(13), QDB(13), QDB(13),
++	 QDB(13), QDB(13), QDB(13), QDB(13), QDB(13),
++	 QDB(13), 0, 0},
++	0
++};
++
++static const struct locale_mimo_info *g_mimo_2g_table[] = {
++	&locale_bn
++};
++
++/*
++ * MIMO Locale Definitions - 5 GHz
++ */
++static const struct locale_mimo_info locale_11n = {
++	{ /* 12.5 dBm */ 50, 50, 50, QDB(15), QDB(15)},
++	{QDB(14), QDB(15), QDB(15), QDB(15), QDB(15)},
++	0
++};
++
++static const struct locale_mimo_info *g_mimo_5g_table[] = {
++	&locale_11n
++};
++
++static const struct {
++	char abbrev[BRCM_CNTRY_BUF_SZ];	/* country abbreviation */
++	struct country_info country;
++} cntry_locales[] = {
++	{
++	"X2", LOCALES(i, 11, bn, 11n)},	/* Worldwide RoW 2 */
++};
++
++#ifdef SUPPORT_40MHZ
++/* 20MHz channel info for 40MHz pairing support */
++struct chan20_info {
++	u8 sb;
++	u8 adj_sbs;
++};
++
++/* indicates adjacent channels that are allowed for a 40 Mhz channel and
++ * those that permitted by the HT
++ */
++struct chan20_info chan20_info[] = {
++	/* 11b/11g */
++/* 0 */ {1, (CH_UPPER_SB | CH_EWA_VALID)},
++/* 1 */ {2, (CH_UPPER_SB | CH_EWA_VALID)},
++/* 2 */ {3, (CH_UPPER_SB | CH_EWA_VALID)},
++/* 3 */ {4, (CH_UPPER_SB | CH_EWA_VALID)},
++/* 4 */ {5, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)},
++/* 5 */ {6, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)},
++/* 6 */ {7, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)},
++/* 7 */ {8, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)},
++/* 8 */ {9, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)},
++/* 9 */ {10, (CH_LOWER_SB | CH_EWA_VALID)},
++/* 10 */ {11, (CH_LOWER_SB | CH_EWA_VALID)},
++/* 11 */ {12, (CH_LOWER_SB)},
++/* 12 */ {13, (CH_LOWER_SB)},
++/* 13 */ {14, (CH_LOWER_SB)},
++
++/* 11a japan high */
++/* 14 */ {34, (CH_UPPER_SB)},
++/* 15 */ {38, (CH_LOWER_SB)},
++/* 16 */ {42, (CH_LOWER_SB)},
++/* 17 */ {46, (CH_LOWER_SB)},
++
++/* 11a usa low */
++/* 18 */ {36, (CH_UPPER_SB | CH_EWA_VALID)},
++/* 19 */ {40, (CH_LOWER_SB | CH_EWA_VALID)},
++/* 20 */ {44, (CH_UPPER_SB | CH_EWA_VALID)},
++/* 21 */ {48, (CH_LOWER_SB | CH_EWA_VALID)},
++/* 22 */ {52, (CH_UPPER_SB | CH_EWA_VALID)},
++/* 23 */ {56, (CH_LOWER_SB | CH_EWA_VALID)},
++/* 24 */ {60, (CH_UPPER_SB | CH_EWA_VALID)},
++/* 25 */ {64, (CH_LOWER_SB | CH_EWA_VALID)},
++
++/* 11a Europe */
++/* 26 */ {100, (CH_UPPER_SB | CH_EWA_VALID)},
++/* 27 */ {104, (CH_LOWER_SB | CH_EWA_VALID)},
++/* 28 */ {108, (CH_UPPER_SB | CH_EWA_VALID)},
++/* 29 */ {112, (CH_LOWER_SB | CH_EWA_VALID)},
++/* 30 */ {116, (CH_UPPER_SB | CH_EWA_VALID)},
++/* 31 */ {120, (CH_LOWER_SB | CH_EWA_VALID)},
++/* 32 */ {124, (CH_UPPER_SB | CH_EWA_VALID)},
++/* 33 */ {128, (CH_LOWER_SB | CH_EWA_VALID)},
++/* 34 */ {132, (CH_UPPER_SB | CH_EWA_VALID)},
++/* 35 */ {136, (CH_LOWER_SB | CH_EWA_VALID)},
++/* 36 */ {140, (CH_LOWER_SB)},
++
++/* 11a usa high, ref5 only */
++/* The 0x80 bit in pdiv means these are REF5, other entries are REF20 */
++/* 37 */ {149, (CH_UPPER_SB | CH_EWA_VALID)},
++/* 38 */ {153, (CH_LOWER_SB | CH_EWA_VALID)},
++/* 39 */ {157, (CH_UPPER_SB | CH_EWA_VALID)},
++/* 40 */ {161, (CH_LOWER_SB | CH_EWA_VALID)},
++/* 41 */ {165, (CH_LOWER_SB)},
++
++/* 11a japan */
++/* 42 */ {184, (CH_UPPER_SB)},
++/* 43 */ {188, (CH_LOWER_SB)},
++/* 44 */ {192, (CH_UPPER_SB)},
++/* 45 */ {196, (CH_LOWER_SB)},
++/* 46 */ {200, (CH_UPPER_SB)},
++/* 47 */ {204, (CH_LOWER_SB)},
++/* 48 */ {208, (CH_UPPER_SB)},
++/* 49 */ {212, (CH_LOWER_SB)},
++/* 50 */ {216, (CH_LOWER_SB)}
++};
++#endif				/* SUPPORT_40MHZ */
++
++static const struct locale_info *brcms_c_get_locale_2g(u8 locale_idx)
++{
++	if (locale_idx >= ARRAY_SIZE(g_locale_2g_table))
++		return NULL; /* error condition */
++
++	return g_locale_2g_table[locale_idx];
++}
++
++static const struct locale_info *brcms_c_get_locale_5g(u8 locale_idx)
++{
++	if (locale_idx >= ARRAY_SIZE(g_locale_5g_table))
++		return NULL; /* error condition */
++
++	return g_locale_5g_table[locale_idx];
++}
++
++static const struct locale_mimo_info *brcms_c_get_mimo_2g(u8 locale_idx)
++{
++	if (locale_idx >= ARRAY_SIZE(g_mimo_2g_table))
++		return NULL;
++
++	return g_mimo_2g_table[locale_idx];
++}
++
++static const struct locale_mimo_info *brcms_c_get_mimo_5g(u8 locale_idx)
++{
++	if (locale_idx >= ARRAY_SIZE(g_mimo_5g_table))
++		return NULL;
++
++	return g_mimo_5g_table[locale_idx];
++}
++
++static int
++brcms_c_country_aggregate_map(struct brcms_cm_info *wlc_cm, const char *ccode,
++			  char *mapped_ccode, uint *mapped_regrev)
++{
++	return false;
++}
++
++/*
++ * Indicates whether the country provided is valid to pass
++ * to cfg80211 or not.
++ *
++ * returns true if valid; false if not.
++ */
++static bool brcms_c_country_valid(const char *ccode)
++{
++	/*
++	 * only allow ascii alpha uppercase for the first 2
++	 * chars.
++	 */
++	if (!((0x80 & ccode[0]) == 0 && ccode[0] >= 0x41 && ccode[0] <= 0x5A &&
++	      (0x80 & ccode[1]) == 0 && ccode[1] >= 0x41 && ccode[1] <= 0x5A &&
++	      ccode[2] == '\0'))
++		return false;
++
++	/*
++	 * do not match ISO 3166-1 user assigned country codes
++	 * that may be in the driver table
++	 */
++	if (!strcmp("AA", ccode) ||        /* AA */
++	    !strcmp("ZZ", ccode) ||        /* ZZ */
++	    ccode[0] == 'X' ||             /* XA - XZ */
++	    (ccode[0] == 'Q' &&            /* QM - QZ */
++	     (ccode[1] >= 'M' && ccode[1] <= 'Z')))
++		return false;
++
++	if (!strcmp("NA", ccode))
++		return false;
++
++	return true;
++}
++
++/* Lookup a country info structure from a null terminated country
++ * abbreviation and regrev directly with no translation.
++ */
++static const struct country_info *
++brcms_c_country_lookup_direct(const char *ccode, uint regrev)
++{
++	uint size, i;
++
++	/* Should just return 0 for single locale driver. */
++	/* Keep it this way in case we add more locales. (for now anyway) */
++
++	/*
++	 * all other country def arrays are for regrev == 0, so if
++	 * regrev is non-zero, fail
++	 */
++	if (regrev > 0)
++		return NULL;
++
++	/* find matched table entry from country code */
++	size = ARRAY_SIZE(cntry_locales);
++	for (i = 0; i < size; i++) {
++		if (strcmp(ccode, cntry_locales[i].abbrev) == 0)
++			return &cntry_locales[i].country;
++	}
++	return NULL;
++}
++
++static const struct country_info *
++brcms_c_countrycode_map(struct brcms_cm_info *wlc_cm, const char *ccode,
++			char *mapped_ccode, uint *mapped_regrev)
++{
++	struct brcms_c_info *wlc = wlc_cm->wlc;
++	const struct country_info *country;
++	uint srom_regrev = wlc_cm->srom_regrev;
++	const char *srom_ccode = wlc_cm->srom_ccode;
++	int mapped;
++
++	/* check for currently supported ccode size */
++	if (strlen(ccode) > (BRCM_CNTRY_BUF_SZ - 1)) {
++		wiphy_err(wlc->wiphy, "wl%d: %s: ccode \"%s\" too long for "
++			  "match\n", wlc->pub->unit, __func__, ccode);
++		return NULL;
++	}
++
++	/* default mapping is the given ccode and regrev 0 */
++	strncpy(mapped_ccode, ccode, BRCM_CNTRY_BUF_SZ);
++	*mapped_regrev = 0;
++
++	/* If the desired country code matches the srom country code,
++	 * then the mapped country is the srom regulatory rev.
++	 * Otherwise look for an aggregate mapping.
++	 */
++	if (!strcmp(srom_ccode, ccode)) {
++		*mapped_regrev = srom_regrev;
++		mapped = 0;
++		wiphy_err(wlc->wiphy, "srom_code == ccode %s\n", __func__);
++	} else {
++		mapped =
++		    brcms_c_country_aggregate_map(wlc_cm, ccode, mapped_ccode,
++					      mapped_regrev);
++	}
++
++	/* find the matching built-in country definition */
++	country = brcms_c_country_lookup_direct(mapped_ccode, *mapped_regrev);
++
++	/* if there is not an exact rev match, default to rev zero */
++	if (country == NULL && *mapped_regrev != 0) {
++		*mapped_regrev = 0;
++		country =
++		    brcms_c_country_lookup_direct(mapped_ccode, *mapped_regrev);
++	}
++
++	return country;
++}
++
++/* Lookup a country info structure from a null terminated country code
++ * The lookup is case sensitive.
++ */
++static const struct country_info *
++brcms_c_country_lookup(struct brcms_c_info *wlc, const char *ccode)
++{
++	const struct country_info *country;
++	char mapped_ccode[BRCM_CNTRY_BUF_SZ];
++	uint mapped_regrev;
++
++	/*
++	 * map the country code to a built-in country code, regrev, and
++	 * country_info struct
++	 */
++	country = brcms_c_countrycode_map(wlc->cmi, ccode, mapped_ccode,
++					  &mapped_regrev);
++
++	return country;
++}
++
++/*
++ * reset the quiet channels vector to the union
++ * of the restricted and radar channel sets
++ */
++static void brcms_c_quiet_channels_reset(struct brcms_cm_info *wlc_cm)
++{
++	struct brcms_c_info *wlc = wlc_cm->wlc;
++	uint i, j;
++	struct brcms_band *band;
++	const struct brcms_chanvec *chanvec;
++
++	memset(&wlc_cm->quiet_channels, 0, sizeof(struct brcms_chanvec));
++
++	band = wlc->band;
++	for (i = 0; i < wlc->pub->_nbands;
++	     i++, band = wlc->bandstate[OTHERBANDUNIT(wlc)]) {
++
++		/* initialize quiet channels for restricted channels */
++		chanvec = wlc_cm->bandstate[band->bandunit].restricted_channels;
++		for (j = 0; j < sizeof(struct brcms_chanvec); j++)
++			wlc_cm->quiet_channels.vec[j] |= chanvec->vec[j];
++
++	}
++}
++
++/* Is the channel valid for the current locale and current band? */
++static bool brcms_c_valid_channel20(struct brcms_cm_info *wlc_cm, uint val)
++{
++	struct brcms_c_info *wlc = wlc_cm->wlc;
++
++	return ((val < MAXCHANNEL) &&
++		isset(wlc_cm->bandstate[wlc->band->bandunit].valid_channels.vec,
++		      val));
++}
++
++/* Is the channel valid for the current locale and specified band? */
++static bool brcms_c_valid_channel20_in_band(struct brcms_cm_info *wlc_cm,
++					    uint bandunit, uint val)
++{
++	return ((val < MAXCHANNEL)
++		&& isset(wlc_cm->bandstate[bandunit].valid_channels.vec, val));
++}
++
++/* Is the channel valid for the current locale? (but don't consider channels not
++ *   available due to bandlocking)
++ */
++static bool brcms_c_valid_channel20_db(struct brcms_cm_info *wlc_cm, uint val)
++{
++	struct brcms_c_info *wlc = wlc_cm->wlc;
++
++	return brcms_c_valid_channel20(wlc->cmi, val) ||
++		(!wlc->bandlocked
++		 && brcms_c_valid_channel20_in_band(wlc->cmi,
++						    OTHERBANDUNIT(wlc), val));
++}
++
++/* JP, J1 - J10 are Japan ccodes */
++static bool brcms_c_japan_ccode(const char *ccode)
++{
++	return (ccode[0] == 'J' &&
++		(ccode[1] == 'P' || (ccode[1] >= '1' && ccode[1] <= '9')));
++}
++
++/* Returns true if currently set country is Japan or variant */
++static bool brcms_c_japan(struct brcms_c_info *wlc)
++{
++	return brcms_c_japan_ccode(wlc->cmi->country_abbrev);
++}
++
++static void
++brcms_c_channel_min_txpower_limits_with_local_constraint(
++		struct brcms_cm_info *wlc_cm, struct txpwr_limits *txpwr,
++		u8 local_constraint_qdbm)
++{
++	int j;
++
++	/* CCK Rates */
++	for (j = 0; j < WL_TX_POWER_CCK_NUM; j++)
++		txpwr->cck[j] = min(txpwr->cck[j], local_constraint_qdbm);
++
++	/* 20 MHz Legacy OFDM SISO */
++	for (j = 0; j < WL_TX_POWER_OFDM_NUM; j++)
++		txpwr->ofdm[j] = min(txpwr->ofdm[j], local_constraint_qdbm);
++
++	/* 20 MHz Legacy OFDM CDD */
++	for (j = 0; j < BRCMS_NUM_RATES_OFDM; j++)
++		txpwr->ofdm_cdd[j] =
++		    min(txpwr->ofdm_cdd[j], local_constraint_qdbm);
++
++	/* 40 MHz Legacy OFDM SISO */
++	for (j = 0; j < BRCMS_NUM_RATES_OFDM; j++)
++		txpwr->ofdm_40_siso[j] =
++		    min(txpwr->ofdm_40_siso[j], local_constraint_qdbm);
++
++	/* 40 MHz Legacy OFDM CDD */
++	for (j = 0; j < BRCMS_NUM_RATES_OFDM; j++)
++		txpwr->ofdm_40_cdd[j] =
++		    min(txpwr->ofdm_40_cdd[j], local_constraint_qdbm);
++
++	/* 20MHz MCS 0-7 SISO */
++	for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++)
++		txpwr->mcs_20_siso[j] =
++		    min(txpwr->mcs_20_siso[j], local_constraint_qdbm);
++
++	/* 20MHz MCS 0-7 CDD */
++	for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++)
++		txpwr->mcs_20_cdd[j] =
++		    min(txpwr->mcs_20_cdd[j], local_constraint_qdbm);
++
++	/* 20MHz MCS 0-7 STBC */
++	for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++)
++		txpwr->mcs_20_stbc[j] =
++		    min(txpwr->mcs_20_stbc[j], local_constraint_qdbm);
++
++	/* 20MHz MCS 8-15 MIMO */
++	for (j = 0; j < BRCMS_NUM_RATES_MCS_2_STREAM; j++)
++		txpwr->mcs_20_mimo[j] =
++		    min(txpwr->mcs_20_mimo[j], local_constraint_qdbm);
++
++	/* 40MHz MCS 0-7 SISO */
++	for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++)
++		txpwr->mcs_40_siso[j] =
++		    min(txpwr->mcs_40_siso[j], local_constraint_qdbm);
++
++	/* 40MHz MCS 0-7 CDD */
++	for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++)
++		txpwr->mcs_40_cdd[j] =
++		    min(txpwr->mcs_40_cdd[j], local_constraint_qdbm);
++
++	/* 40MHz MCS 0-7 STBC */
++	for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++)
++		txpwr->mcs_40_stbc[j] =
++		    min(txpwr->mcs_40_stbc[j], local_constraint_qdbm);
++
++	/* 40MHz MCS 8-15 MIMO */
++	for (j = 0; j < BRCMS_NUM_RATES_MCS_2_STREAM; j++)
++		txpwr->mcs_40_mimo[j] =
++		    min(txpwr->mcs_40_mimo[j], local_constraint_qdbm);
++
++	/* 40MHz MCS 32 */
++	txpwr->mcs32 = min(txpwr->mcs32, local_constraint_qdbm);
++
++}
++
++/* Update the radio state (enable/disable) and tx power targets
++ * based on a new set of channel/regulatory information
++ */
++static void brcms_c_channels_commit(struct brcms_cm_info *wlc_cm)
++{
++	struct brcms_c_info *wlc = wlc_cm->wlc;
++	uint chan;
++	struct txpwr_limits txpwr;
++
++	/* search for the existence of any valid channel */
++	for (chan = 0; chan < MAXCHANNEL; chan++) {
++		if (brcms_c_valid_channel20_db(wlc->cmi, chan))
++			break;
++	}
++	if (chan == MAXCHANNEL)
++		chan = INVCHANNEL;
++
++	/*
++	 * based on the channel search above, set or
++	 * clear WL_RADIO_COUNTRY_DISABLE.
++	 */
++	if (chan == INVCHANNEL) {
++		/*
++		 * country/locale with no valid channels, set
++		 * the radio disable bit
++		 */
++		mboolset(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE);
++		wiphy_err(wlc->wiphy, "wl%d: %s: no valid channel for \"%s\" "
++			  "nbands %d bandlocked %d\n", wlc->pub->unit,
++			  __func__, wlc_cm->country_abbrev, wlc->pub->_nbands,
++			  wlc->bandlocked);
++	} else if (mboolisset(wlc->pub->radio_disabled,
++			      WL_RADIO_COUNTRY_DISABLE)) {
++		/*
++		 * country/locale with valid channel, clear
++		 * the radio disable bit
++		 */
++		mboolclr(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE);
++	}
++
++	/*
++	 * Now that the country abbreviation is set, if the radio supports 2G,
++	 * then set channel 14 restrictions based on the new locale.
++	 */
++	if (wlc->pub->_nbands > 1 || wlc->band->bandtype == BRCM_BAND_2G)
++		wlc_phy_chanspec_ch14_widefilter_set(wlc->band->pi,
++						     brcms_c_japan(wlc) ? true :
++						     false);
++
++	if (wlc->pub->up && chan != INVCHANNEL) {
++		brcms_c_channel_reg_limits(wlc_cm, wlc->chanspec, &txpwr);
++		brcms_c_channel_min_txpower_limits_with_local_constraint(wlc_cm,
++			&txpwr, BRCMS_TXPWR_MAX);
++		wlc_phy_txpower_limit_set(wlc->band->pi, &txpwr, wlc->chanspec);
++	}
++}
++
++static int
++brcms_c_channels_init(struct brcms_cm_info *wlc_cm,
++		      const struct country_info *country)
++{
++	struct brcms_c_info *wlc = wlc_cm->wlc;
++	uint i, j;
++	struct brcms_band *band;
++	const struct locale_info *li;
++	struct brcms_chanvec sup_chan;
++	const struct locale_mimo_info *li_mimo;
++
++	band = wlc->band;
++	for (i = 0; i < wlc->pub->_nbands;
++	     i++, band = wlc->bandstate[OTHERBANDUNIT(wlc)]) {
++
++		li = (band->bandtype == BRCM_BAND_5G) ?
++		    brcms_c_get_locale_5g(country->locale_5G) :
++		    brcms_c_get_locale_2g(country->locale_2G);
++		wlc_cm->bandstate[band->bandunit].locale_flags = li->flags;
++		li_mimo = (band->bandtype == BRCM_BAND_5G) ?
++		    brcms_c_get_mimo_5g(country->locale_mimo_5G) :
++		    brcms_c_get_mimo_2g(country->locale_mimo_2G);
++
++		/* merge the mimo non-mimo locale flags */
++		wlc_cm->bandstate[band->bandunit].locale_flags |=
++		    li_mimo->flags;
++
++		wlc_cm->bandstate[band->bandunit].restricted_channels =
++		    g_table_restricted_chan[li->restricted_channels];
++		wlc_cm->bandstate[band->bandunit].radar_channels =
++		    g_table_radar_set[li->radar_channels];
++
++		/*
++		 * set the channel availability, masking out the channels
++		 * that may not be supported on this phy.
++		 */
++		wlc_phy_chanspec_band_validch(band->pi, band->bandtype,
++					      &sup_chan);
++		brcms_c_locale_get_channels(li,
++					&wlc_cm->bandstate[band->bandunit].
++					valid_channels);
++		for (j = 0; j < sizeof(struct brcms_chanvec); j++)
++			wlc_cm->bandstate[band->bandunit].valid_channels.
++			    vec[j] &= sup_chan.vec[j];
++	}
++
++	brcms_c_quiet_channels_reset(wlc_cm);
++	brcms_c_channels_commit(wlc_cm);
++
++	return 0;
++}
++
++/*
++ * set the driver's current country and regulatory information
++ * using a country code as the source. Look up built in country
++ * information found with the country code.
++ */
++static void
++brcms_c_set_country_common(struct brcms_cm_info *wlc_cm,
++		       const char *country_abbrev,
++		       const char *ccode, uint regrev,
++		       const struct country_info *country)
++{
++	const struct locale_info *locale;
++	struct brcms_c_info *wlc = wlc_cm->wlc;
++	char prev_country_abbrev[BRCM_CNTRY_BUF_SZ];
++
++	/* save current country state */
++	wlc_cm->country = country;
++
++	memset(&prev_country_abbrev, 0, BRCM_CNTRY_BUF_SZ);
++	strncpy(prev_country_abbrev, wlc_cm->country_abbrev,
++		BRCM_CNTRY_BUF_SZ - 1);
++
++	strncpy(wlc_cm->country_abbrev, country_abbrev, BRCM_CNTRY_BUF_SZ - 1);
++	strncpy(wlc_cm->ccode, ccode, BRCM_CNTRY_BUF_SZ - 1);
++	wlc_cm->regrev = regrev;
++
++	if ((wlc->pub->_n_enab & SUPPORT_11N) !=
++	    wlc->protection->nmode_user)
++		brcms_c_set_nmode(wlc);
++
++	brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_2G_INDEX]);
++	brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]);
++	/* set or restore gmode as required by regulatory */
++	locale = brcms_c_get_locale_2g(country->locale_2G);
++	if (locale && (locale->flags & BRCMS_NO_OFDM))
++		brcms_c_set_gmode(wlc, GMODE_LEGACY_B, false);
++	else
++		brcms_c_set_gmode(wlc, wlc->protection->gmode_user, false);
++
++	brcms_c_channels_init(wlc_cm, country);
++
++	return;
++}
++
++static int
++brcms_c_set_countrycode_rev(struct brcms_cm_info *wlc_cm,
++			const char *country_abbrev,
++			const char *ccode, int regrev)
++{
++	const struct country_info *country;
++	char mapped_ccode[BRCM_CNTRY_BUF_SZ];
++	uint mapped_regrev;
++
++	/* if regrev is -1, lookup the mapped country code,
++	 * otherwise use the ccode and regrev directly
++	 */
++	if (regrev == -1) {
++		/*
++		 * map the country code to a built-in country
++		 * code, regrev, and country_info
++		 */
++		country =
++		    brcms_c_countrycode_map(wlc_cm, ccode, mapped_ccode,
++					&mapped_regrev);
++	} else {
++		/* find the matching built-in country definition */
++		country = brcms_c_country_lookup_direct(ccode, regrev);
++		strncpy(mapped_ccode, ccode, BRCM_CNTRY_BUF_SZ);
++		mapped_regrev = regrev;
++	}
++
++	if (country == NULL)
++		return -EINVAL;
++
++	/* set the driver state for the country */
++	brcms_c_set_country_common(wlc_cm, country_abbrev, mapped_ccode,
++			       mapped_regrev, country);
++
++	return 0;
++}
++
++/*
++ * set the driver's current country and regulatory information using
++ * a country code as the source. Lookup built in country information
++ * found with the country code.
++ */
++static int
++brcms_c_set_countrycode(struct brcms_cm_info *wlc_cm, const char *ccode)
++{
++	char country_abbrev[BRCM_CNTRY_BUF_SZ];
++	strncpy(country_abbrev, ccode, BRCM_CNTRY_BUF_SZ);
++	return brcms_c_set_countrycode_rev(wlc_cm, country_abbrev, ccode, -1);
++}
++
++struct brcms_cm_info *brcms_c_channel_mgr_attach(struct brcms_c_info *wlc)
++{
++	struct brcms_cm_info *wlc_cm;
++	char country_abbrev[BRCM_CNTRY_BUF_SZ];
++	const struct country_info *country;
++	struct brcms_pub *pub = wlc->pub;
++	struct ssb_sprom *sprom = &wlc->hw->d11core->bus->sprom;
++
++	BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
++
++	wlc_cm = kzalloc(sizeof(struct brcms_cm_info), GFP_ATOMIC);
++	if (wlc_cm == NULL)
++		return NULL;
++	wlc_cm->pub = pub;
++	wlc_cm->wlc = wlc;
++	wlc->cmi = wlc_cm;
++
++	/* store the country code for passing up as a regulatory hint */
++	if (sprom->alpha2 && brcms_c_country_valid(sprom->alpha2))
++		strncpy(wlc->pub->srom_ccode, sprom->alpha2, sizeof(sprom->alpha2));
++
++	/*
++	 * internal country information which must match
++	 * regulatory constraints in firmware
++	 */
++	memset(country_abbrev, 0, BRCM_CNTRY_BUF_SZ);
++	strncpy(country_abbrev, "X2", sizeof(country_abbrev) - 1);
++	country = brcms_c_country_lookup(wlc, country_abbrev);
++
++	/* save default country for exiting 11d regulatory mode */
++	strncpy(wlc->country_default, country_abbrev, BRCM_CNTRY_BUF_SZ - 1);
++
++	/* initialize autocountry_default to driver default */
++	strncpy(wlc->autocountry_default, "X2", BRCM_CNTRY_BUF_SZ - 1);
++
++	brcms_c_set_countrycode(wlc_cm, country_abbrev);
++
++	return wlc_cm;
++}
++
++void brcms_c_channel_mgr_detach(struct brcms_cm_info *wlc_cm)
++{
++	kfree(wlc_cm);
++}
++
++u8
++brcms_c_channel_locale_flags_in_band(struct brcms_cm_info *wlc_cm,
++				     uint bandunit)
++{
++	return wlc_cm->bandstate[bandunit].locale_flags;
++}
++
++static bool
++brcms_c_quiet_chanspec(struct brcms_cm_info *wlc_cm, u16 chspec)
++{
++	return (wlc_cm->wlc->pub->_n_enab & SUPPORT_11N) &&
++		CHSPEC_IS40(chspec) ?
++		(isset(wlc_cm->quiet_channels.vec,
++		       lower_20_sb(CHSPEC_CHANNEL(chspec))) ||
++		 isset(wlc_cm->quiet_channels.vec,
++		       upper_20_sb(CHSPEC_CHANNEL(chspec)))) :
++		isset(wlc_cm->quiet_channels.vec, CHSPEC_CHANNEL(chspec));
++}
++
++void
++brcms_c_channel_set_chanspec(struct brcms_cm_info *wlc_cm, u16 chanspec,
++			 u8 local_constraint_qdbm)
++{
++	struct brcms_c_info *wlc = wlc_cm->wlc;
++	struct txpwr_limits txpwr;
++
++	brcms_c_channel_reg_limits(wlc_cm, chanspec, &txpwr);
++
++	brcms_c_channel_min_txpower_limits_with_local_constraint(
++		wlc_cm, &txpwr, local_constraint_qdbm
++	);
++
++	brcms_b_set_chanspec(wlc->hw, chanspec,
++			      (brcms_c_quiet_chanspec(wlc_cm, chanspec) != 0),
++			      &txpwr);
++}
++
++void
++brcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm, u16 chanspec,
++		       struct txpwr_limits *txpwr)
++{
++	struct brcms_c_info *wlc = wlc_cm->wlc;
++	uint i;
++	uint chan;
++	int maxpwr;
++	int delta;
++	const struct country_info *country;
++	struct brcms_band *band;
++	const struct locale_info *li;
++	int conducted_max = BRCMS_TXPWR_MAX;
++	int conducted_ofdm_max = BRCMS_TXPWR_MAX;
++	const struct locale_mimo_info *li_mimo;
++	int maxpwr20, maxpwr40;
++	int maxpwr_idx;
++	uint j;
++
++	memset(txpwr, 0, sizeof(struct txpwr_limits));
++
++	if (!brcms_c_valid_chanspec_db(wlc_cm, chanspec)) {
++		country = brcms_c_country_lookup(wlc, wlc->autocountry_default);
++		if (country == NULL)
++			return;
++	} else {
++		country = wlc_cm->country;
++	}
++
++	chan = CHSPEC_CHANNEL(chanspec);
++	band = wlc->bandstate[chspec_bandunit(chanspec)];
++	li = (band->bandtype == BRCM_BAND_5G) ?
++	    brcms_c_get_locale_5g(country->locale_5G) :
++	    brcms_c_get_locale_2g(country->locale_2G);
++
++	li_mimo = (band->bandtype == BRCM_BAND_5G) ?
++	    brcms_c_get_mimo_5g(country->locale_mimo_5G) :
++	    brcms_c_get_mimo_2g(country->locale_mimo_2G);
++
++	if (li->flags & BRCMS_EIRP) {
++		delta = band->antgain;
++	} else {
++		delta = 0;
++		if (band->antgain > QDB(6))
++			delta = band->antgain - QDB(6);	/* Excess over 6 dB */
++	}
++
++	if (li == &locale_i) {
++		conducted_max = QDB(22);
++		conducted_ofdm_max = QDB(22);
++	}
++
++	/* CCK txpwr limits for 2.4G band */
++	if (band->bandtype == BRCM_BAND_2G) {
++		maxpwr = li->maxpwr[CHANNEL_POWER_IDX_2G_CCK(chan)];
++
++		maxpwr = maxpwr - delta;
++		maxpwr = max(maxpwr, 0);
++		maxpwr = min(maxpwr, conducted_max);
++
++		for (i = 0; i < BRCMS_NUM_RATES_CCK; i++)
++			txpwr->cck[i] = (u8) maxpwr;
++	}
++
++	/* OFDM txpwr limits for 2.4G or 5G bands */
++	if (band->bandtype == BRCM_BAND_2G)
++		maxpwr = li->maxpwr[CHANNEL_POWER_IDX_2G_OFDM(chan)];
++	else
++		maxpwr = li->maxpwr[CHANNEL_POWER_IDX_5G(chan)];
++
++	maxpwr = maxpwr - delta;
++	maxpwr = max(maxpwr, 0);
++	maxpwr = min(maxpwr, conducted_ofdm_max);
++
++	/* Keep OFDM lmit below CCK limit */
++	if (band->bandtype == BRCM_BAND_2G)
++		maxpwr = min_t(int, maxpwr, txpwr->cck[0]);
++
++	for (i = 0; i < BRCMS_NUM_RATES_OFDM; i++)
++		txpwr->ofdm[i] = (u8) maxpwr;
++
++	for (i = 0; i < BRCMS_NUM_RATES_OFDM; i++) {
++		/*
++		 * OFDM 40 MHz SISO has the same power as the corresponding
++		 * MCS0-7 rate unless overriden by the locale specific code.
++		 * We set this value to 0 as a flag (presumably 0 dBm isn't
++		 * a possibility) and then copy the MCS0-7 value to the 40 MHz
++		 * value if it wasn't explicitly set.
++		 */
++		txpwr->ofdm_40_siso[i] = 0;
++
++		txpwr->ofdm_cdd[i] = (u8) maxpwr;
++
++		txpwr->ofdm_40_cdd[i] = 0;
++	}
++
++	/* MIMO/HT specific limits */
++	if (li_mimo->flags & BRCMS_EIRP) {
++		delta = band->antgain;
++	} else {
++		delta = 0;
++		if (band->antgain > QDB(6))
++			delta = band->antgain - QDB(6);	/* Excess over 6 dB */
++	}
++
++	if (band->bandtype == BRCM_BAND_2G)
++		maxpwr_idx = (chan - 1);
++	else
++		maxpwr_idx = CHANNEL_POWER_IDX_5G(chan);
++
++	maxpwr20 = li_mimo->maxpwr20[maxpwr_idx];
++	maxpwr40 = li_mimo->maxpwr40[maxpwr_idx];
++
++	maxpwr20 = maxpwr20 - delta;
++	maxpwr20 = max(maxpwr20, 0);
++	maxpwr40 = maxpwr40 - delta;
++	maxpwr40 = max(maxpwr40, 0);
++
++	/* Fill in the MCS 0-7 (SISO) rates */
++	for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) {
++
++		/*
++		 * 20 MHz has the same power as the corresponding OFDM rate
++		 * unless overriden by the locale specific code.
++		 */
++		txpwr->mcs_20_siso[i] = txpwr->ofdm[i];
++		txpwr->mcs_40_siso[i] = 0;
++	}
++
++	/* Fill in the MCS 0-7 CDD rates */
++	for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) {
++		txpwr->mcs_20_cdd[i] = (u8) maxpwr20;
++		txpwr->mcs_40_cdd[i] = (u8) maxpwr40;
++	}
++
++	/*
++	 * These locales have SISO expressed in the
++	 * table and override CDD later
++	 */
++	if (li_mimo == &locale_bn) {
++		if (li_mimo == &locale_bn) {
++			maxpwr20 = QDB(16);
++			maxpwr40 = 0;
++
++			if (chan >= 3 && chan <= 11)
++				maxpwr40 = QDB(16);
++		}
++
++		for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) {
++			txpwr->mcs_20_siso[i] = (u8) maxpwr20;
++			txpwr->mcs_40_siso[i] = (u8) maxpwr40;
++		}
++	}
++
++	/* Fill in the MCS 0-7 STBC rates */
++	for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) {
++		txpwr->mcs_20_stbc[i] = 0;
++		txpwr->mcs_40_stbc[i] = 0;
++	}
++
++	/* Fill in the MCS 8-15 SDM rates */
++	for (i = 0; i < BRCMS_NUM_RATES_MCS_2_STREAM; i++) {
++		txpwr->mcs_20_mimo[i] = (u8) maxpwr20;
++		txpwr->mcs_40_mimo[i] = (u8) maxpwr40;
++	}
++
++	/* Fill in MCS32 */
++	txpwr->mcs32 = (u8) maxpwr40;
++
++	for (i = 0, j = 0; i < BRCMS_NUM_RATES_OFDM; i++, j++) {
++		if (txpwr->ofdm_40_cdd[i] == 0)
++			txpwr->ofdm_40_cdd[i] = txpwr->mcs_40_cdd[j];
++		if (i == 0) {
++			i = i + 1;
++			if (txpwr->ofdm_40_cdd[i] == 0)
++				txpwr->ofdm_40_cdd[i] = txpwr->mcs_40_cdd[j];
++		}
++	}
++
++	/*
++	 * Copy the 40 MHZ MCS 0-7 CDD value to the 40 MHZ MCS 0-7 SISO
++	 * value if it wasn't provided explicitly.
++	 */
++	for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) {
++		if (txpwr->mcs_40_siso[i] == 0)
++			txpwr->mcs_40_siso[i] = txpwr->mcs_40_cdd[i];
++	}
++
++	for (i = 0, j = 0; i < BRCMS_NUM_RATES_OFDM; i++, j++) {
++		if (txpwr->ofdm_40_siso[i] == 0)
++			txpwr->ofdm_40_siso[i] = txpwr->mcs_40_siso[j];
++		if (i == 0) {
++			i = i + 1;
++			if (txpwr->ofdm_40_siso[i] == 0)
++				txpwr->ofdm_40_siso[i] = txpwr->mcs_40_siso[j];
++		}
++	}
++
++	/*
++	 * Copy the 20 and 40 MHz MCS0-7 CDD values to the corresponding
++	 * STBC values if they weren't provided explicitly.
++	 */
++	for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) {
++		if (txpwr->mcs_20_stbc[i] == 0)
++			txpwr->mcs_20_stbc[i] = txpwr->mcs_20_cdd[i];
++
++		if (txpwr->mcs_40_stbc[i] == 0)
++			txpwr->mcs_40_stbc[i] = txpwr->mcs_40_cdd[i];
++	}
++
++	return;
++}
++
++/*
++ * Verify the chanspec is using a legal set of parameters, i.e. that the
++ * chanspec specified a band, bw, ctl_sb and channel and that the
++ * combination could be legal given any set of circumstances.
++ * RETURNS: true is the chanspec is malformed, false if it looks good.
++ */
++static bool brcms_c_chspec_malformed(u16 chanspec)
++{
++	/* must be 2G or 5G band */
++	if (!CHSPEC_IS5G(chanspec) && !CHSPEC_IS2G(chanspec))
++		return true;
++	/* must be 20 or 40 bandwidth */
++	if (!CHSPEC_IS40(chanspec) && !CHSPEC_IS20(chanspec))
++		return true;
++
++	/* 20MHZ b/w must have no ctl sb, 40 must have a ctl sb */
++	if (CHSPEC_IS20(chanspec)) {
++		if (!CHSPEC_SB_NONE(chanspec))
++			return true;
++	} else if (!CHSPEC_SB_UPPER(chanspec) && !CHSPEC_SB_LOWER(chanspec)) {
++		return true;
++	}
++
++	return false;
++}
++
++/*
++ * Validate the chanspec for this locale, for 40MHZ we need to also
++ * check that the sidebands are valid 20MZH channels in this locale
++ * and they are also a legal HT combination
++ */
++static bool
++brcms_c_valid_chanspec_ext(struct brcms_cm_info *wlc_cm, u16 chspec,
++			   bool dualband)
++{
++	struct brcms_c_info *wlc = wlc_cm->wlc;
++	u8 channel = CHSPEC_CHANNEL(chspec);
++
++	/* check the chanspec */
++	if (brcms_c_chspec_malformed(chspec)) {
++		wiphy_err(wlc->wiphy, "wl%d: malformed chanspec 0x%x\n",
++			wlc->pub->unit, chspec);
++		return false;
++	}
++
++	if (CHANNEL_BANDUNIT(wlc_cm->wlc, channel) !=
++	    chspec_bandunit(chspec))
++		return false;
++
++	/* Check a 20Mhz channel */
++	if (CHSPEC_IS20(chspec)) {
++		if (dualband)
++			return brcms_c_valid_channel20_db(wlc_cm->wlc->cmi,
++							  channel);
++		else
++			return brcms_c_valid_channel20(wlc_cm->wlc->cmi,
++						       channel);
++	}
++#ifdef SUPPORT_40MHZ
++	/*
++	 * We know we are now checking a 40MHZ channel, so we should
++	 * only be here for NPHYS
++	 */
++	if (BRCMS_ISNPHY(wlc->band) || BRCMS_ISSSLPNPHY(wlc->band)) {
++		u8 upper_sideband = 0, idx;
++		u8 num_ch20_entries =
++		    sizeof(chan20_info) / sizeof(struct chan20_info);
++
++		if (!VALID_40CHANSPEC_IN_BAND(wlc, chspec_bandunit(chspec)))
++			return false;
++
++		if (dualband) {
++			if (!brcms_c_valid_channel20_db(wlc->cmi,
++							lower_20_sb(channel)) ||
++			    !brcms_c_valid_channel20_db(wlc->cmi,
++							upper_20_sb(channel)))
++				return false;
++		} else {
++			if (!brcms_c_valid_channel20(wlc->cmi,
++						     lower_20_sb(channel)) ||
++			    !brcms_c_valid_channel20(wlc->cmi,
++						     upper_20_sb(channel)))
++				return false;
++		}
++
++		/* find the lower sideband info in the sideband array */
++		for (idx = 0; idx < num_ch20_entries; idx++) {
++			if (chan20_info[idx].sb == lower_20_sb(channel))
++				upper_sideband = chan20_info[idx].adj_sbs;
++		}
++		/* check that the lower sideband allows an upper sideband */
++		if ((upper_sideband & (CH_UPPER_SB | CH_EWA_VALID)) ==
++		    (CH_UPPER_SB | CH_EWA_VALID))
++			return true;
++		return false;
++	}
++#endif				/* 40 MHZ */
++
++	return false;
++}
++
++bool brcms_c_valid_chanspec_db(struct brcms_cm_info *wlc_cm, u16 chspec)
++{
++	return brcms_c_valid_chanspec_ext(wlc_cm, chspec, true);
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/channel.h b/drivers/net/wireless/brcm80211/brcmsmac/channel.h
+new file mode 100644
+index 0000000..808cb4f
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/channel.h
+@@ -0,0 +1,53 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef _BRCM_CHANNEL_H_
++#define _BRCM_CHANNEL_H_
++
++/* conversion for phy txpwr calculations that use .25 dB units */
++#define BRCMS_TXPWR_DB_FACTOR 4
++
++/* bits for locale_info flags */
++#define BRCMS_PEAK_CONDUCTED	0x00	/* Peak for locals */
++#define BRCMS_EIRP		0x01	/* Flag for EIRP */
++#define BRCMS_DFS_TPC		0x02	/* Flag for DFS TPC */
++#define BRCMS_NO_OFDM		0x04	/* Flag for No OFDM */
++#define BRCMS_NO_40MHZ		0x08	/* Flag for No MIMO 40MHz */
++#define BRCMS_NO_MIMO		0x10	/* Flag for No MIMO, 20 or 40 MHz */
++#define BRCMS_RADAR_TYPE_EU       0x20	/* Flag for EU */
++#define BRCMS_DFS_FCC             BRCMS_DFS_TPC	/* Flag for DFS FCC */
++
++#define BRCMS_DFS_EU (BRCMS_DFS_TPC | BRCMS_RADAR_TYPE_EU) /* Flag for DFS EU */
++
++extern struct brcms_cm_info *
++brcms_c_channel_mgr_attach(struct brcms_c_info *wlc);
++
++extern void brcms_c_channel_mgr_detach(struct brcms_cm_info *wlc_cm);
++
++extern u8 brcms_c_channel_locale_flags_in_band(struct brcms_cm_info *wlc_cm,
++					   uint bandunit);
++
++extern bool brcms_c_valid_chanspec_db(struct brcms_cm_info *wlc_cm,
++				      u16 chspec);
++
++extern void brcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm,
++				   u16 chanspec,
++				   struct txpwr_limits *txpwr);
++extern void brcms_c_channel_set_chanspec(struct brcms_cm_info *wlc_cm,
++				     u16 chanspec,
++				     u8 local_constraint_qdbm);
++
++#endif				/* _WLC_CHANNEL_H */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/d11.h b/drivers/net/wireless/brcm80211/brcmsmac/d11.h
+new file mode 100644
+index 0000000..3f659e0
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/d11.h
+@@ -0,0 +1,1901 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef	_BRCM_D11_H_
++#define	_BRCM_D11_H_
++
++#include <linux/ieee80211.h>
++
++#include <defs.h>
++#include "pub.h"
++#include "dma.h"
++
++/* RX FIFO numbers */
++#define	RX_FIFO			0	/* data and ctl frames */
++#define	RX_TXSTATUS_FIFO	3	/* RX fifo for tx status packages */
++
++/* TX FIFO numbers using WME Access Category */
++#define	TX_AC_BK_FIFO		0	/* Background TX FIFO */
++#define	TX_AC_BE_FIFO		1	/* Best-Effort TX FIFO */
++#define	TX_AC_VI_FIFO		2	/* Video TX FIFO */
++#define	TX_AC_VO_FIFO		3	/* Voice TX FIFO */
++#define	TX_BCMC_FIFO		4	/* Broadcast/Multicast TX FIFO */
++#define	TX_ATIM_FIFO		5	/* TX fifo for ATIM window info */
++
++/* Addr is byte address used by SW; offset is word offset used by uCode */
++
++/* Per AC TX limit settings */
++#define M_AC_TXLMT_BASE_ADDR         (0x180 * 2)
++#define M_AC_TXLMT_ADDR(_ac)         (M_AC_TXLMT_BASE_ADDR + (2 * (_ac)))
++
++/* Legacy TX FIFO numbers */
++#define	TX_DATA_FIFO		TX_AC_BE_FIFO
++#define	TX_CTL_FIFO		TX_AC_VO_FIFO
++
++#define WL_RSSI_ANT_MAX		4	/* max possible rx antennas */
++
++struct intctrlregs {
++	u32 intstatus;
++	u32 intmask;
++};
++
++/* PIO structure,
++ *  support two PIO format: 2 bytes access and 4 bytes access
++ *  basic FIFO register set is per channel(transmit or receive)
++ *  a pair of channels is defined for convenience
++ */
++/* 2byte-wide pio register set per channel(xmt or rcv) */
++struct pio2regs {
++	u16 fifocontrol;
++	u16 fifodata;
++	u16 fifofree;	/* only valid in xmt channel, not in rcv channel */
++	u16 PAD;
++};
++
++/* a pair of pio channels(tx and rx) */
++struct pio2regp {
++	struct pio2regs tx;
++	struct pio2regs rx;
++};
++
++/* 4byte-wide pio register set per channel(xmt or rcv) */
++struct pio4regs {
++	u32 fifocontrol;
++	u32 fifodata;
++};
++
++/* a pair of pio channels(tx and rx) */
++struct pio4regp {
++	struct pio4regs tx;
++	struct pio4regs rx;
++};
++
++/* read: 32-bit register that can be read as 32-bit or as 2 16-bit
++ * write: only low 16b-it half can be written
++ */
++union pmqreg {
++	u32 pmqhostdata;	/* read only! */
++	struct {
++		u16 pmqctrlstatus;	/* read/write */
++		u16 PAD;
++	} w;
++};
++
++struct fifo64 {
++	struct dma64regs dmaxmt;	/* dma tx */
++	struct pio4regs piotx;	/* pio tx */
++	struct dma64regs dmarcv;	/* dma rx */
++	struct pio4regs piorx;	/* pio rx */
++};
++
++/*
++ * Host Interface Registers
++ */
++struct d11regs {
++	/* Device Control ("semi-standard host registers") */
++	u32 PAD[3];		/* 0x0 - 0x8 */
++	u32 biststatus;	/* 0xC */
++	u32 biststatus2;	/* 0x10 */
++	u32 PAD;		/* 0x14 */
++	u32 gptimer;		/* 0x18 */
++	u32 usectimer;	/* 0x1c *//* for corerev >= 26 */
++
++	/* Interrupt Control *//* 0x20 */
++	struct intctrlregs intctrlregs[8];
++
++	u32 PAD[40];		/* 0x60 - 0xFC */
++
++	u32 intrcvlazy[4];	/* 0x100 - 0x10C */
++
++	u32 PAD[4];		/* 0x110 - 0x11c */
++
++	u32 maccontrol;	/* 0x120 */
++	u32 maccommand;	/* 0x124 */
++	u32 macintstatus;	/* 0x128 */
++	u32 macintmask;	/* 0x12C */
++
++	/* Transmit Template Access */
++	u32 tplatewrptr;	/* 0x130 */
++	u32 tplatewrdata;	/* 0x134 */
++	u32 PAD[2];		/* 0x138 - 0x13C */
++
++	/* PMQ registers */
++	union pmqreg pmqreg;	/* 0x140 */
++	u32 pmqpatl;		/* 0x144 */
++	u32 pmqpath;		/* 0x148 */
++	u32 PAD;		/* 0x14C */
++
++	u32 chnstatus;	/* 0x150 */
++	u32 psmdebug;	/* 0x154 */
++	u32 phydebug;	/* 0x158 */
++	u32 machwcap;	/* 0x15C */
++
++	/* Extended Internal Objects */
++	u32 objaddr;		/* 0x160 */
++	u32 objdata;		/* 0x164 */
++	u32 PAD[2];		/* 0x168 - 0x16c */
++
++	u32 frmtxstatus;	/* 0x170 */
++	u32 frmtxstatus2;	/* 0x174 */
++	u32 PAD[2];		/* 0x178 - 0x17c */
++
++	/* TSF host access */
++	u32 tsf_timerlow;	/* 0x180 */
++	u32 tsf_timerhigh;	/* 0x184 */
++	u32 tsf_cfprep;	/* 0x188 */
++	u32 tsf_cfpstart;	/* 0x18c */
++	u32 tsf_cfpmaxdur32;	/* 0x190 */
++	u32 PAD[3];		/* 0x194 - 0x19c */
++
++	u32 maccontrol1;	/* 0x1a0 */
++	u32 machwcap1;	/* 0x1a4 */
++	u32 PAD[14];		/* 0x1a8 - 0x1dc */
++
++	/* Clock control and hardware workarounds*/
++	u32 clk_ctl_st;	/* 0x1e0 */
++	u32 hw_war;
++	u32 d11_phypllctl;	/* the phypll request/avail bits are
++				 * moved to clk_ctl_st
++				 */
++	u32 PAD[5];		/* 0x1ec - 0x1fc */
++
++	/* 0x200-0x37F dma/pio registers */
++	struct fifo64 fifo64regs[6];
++
++	/* FIFO diagnostic port access */
++	struct dma32diag dmafifo;	/* 0x380 - 0x38C */
++
++	u32 aggfifocnt;	/* 0x390 */
++	u32 aggfifodata;	/* 0x394 */
++	u32 PAD[16];		/* 0x398 - 0x3d4 */
++	u16 radioregaddr;	/* 0x3d8 */
++	u16 radioregdata;	/* 0x3da */
++
++	/*
++	 * time delay between the change on rf disable input and
++	 * radio shutdown
++	 */
++	u32 rfdisabledly;	/* 0x3DC */
++
++	/* PHY register access */
++	u16 phyversion;	/* 0x3e0 - 0x0 */
++	u16 phybbconfig;	/* 0x3e2 - 0x1 */
++	u16 phyadcbias;	/* 0x3e4 - 0x2  Bphy only */
++	u16 phyanacore;	/* 0x3e6 - 0x3  pwwrdwn on aphy */
++	u16 phyrxstatus0;	/* 0x3e8 - 0x4 */
++	u16 phyrxstatus1;	/* 0x3ea - 0x5 */
++	u16 phycrsth;	/* 0x3ec - 0x6 */
++	u16 phytxerror;	/* 0x3ee - 0x7 */
++	u16 phychannel;	/* 0x3f0 - 0x8 */
++	u16 PAD[1];		/* 0x3f2 - 0x9 */
++	u16 phytest;		/* 0x3f4 - 0xa */
++	u16 phy4waddr;	/* 0x3f6 - 0xb */
++	u16 phy4wdatahi;	/* 0x3f8 - 0xc */
++	u16 phy4wdatalo;	/* 0x3fa - 0xd */
++	u16 phyregaddr;	/* 0x3fc - 0xe */
++	u16 phyregdata;	/* 0x3fe - 0xf */
++
++	/* IHR *//* 0x400 - 0x7FE */
++
++	/* RXE Block */
++	u16 PAD[3];		/* 0x400 - 0x406 */
++	u16 rcv_fifo_ctl;	/* 0x406 */
++	u16 PAD;		/* 0x408 - 0x40a */
++	u16 rcv_frm_cnt;	/* 0x40a */
++	u16 PAD[4];		/* 0x40a - 0x414 */
++	u16 rssi;		/* 0x414 */
++	u16 PAD[5];		/* 0x414 - 0x420 */
++	u16 rcm_ctl;		/* 0x420 */
++	u16 rcm_mat_data;	/* 0x422 */
++	u16 rcm_mat_mask;	/* 0x424 */
++	u16 rcm_mat_dly;	/* 0x426 */
++	u16 rcm_cond_mask_l;	/* 0x428 */
++	u16 rcm_cond_mask_h;	/* 0x42A */
++	u16 rcm_cond_dly;	/* 0x42C */
++	u16 PAD[1];		/* 0x42E */
++	u16 ext_ihr_addr;	/* 0x430 */
++	u16 ext_ihr_data;	/* 0x432 */
++	u16 rxe_phyrs_2;	/* 0x434 */
++	u16 rxe_phyrs_3;	/* 0x436 */
++	u16 phy_mode;	/* 0x438 */
++	u16 rcmta_ctl;	/* 0x43a */
++	u16 rcmta_size;	/* 0x43c */
++	u16 rcmta_addr0;	/* 0x43e */
++	u16 rcmta_addr1;	/* 0x440 */
++	u16 rcmta_addr2;	/* 0x442 */
++	u16 PAD[30];		/* 0x444 - 0x480 */
++
++	/* PSM Block *//* 0x480 - 0x500 */
++
++	u16 PAD;		/* 0x480 */
++	u16 psm_maccontrol_h;	/* 0x482 */
++	u16 psm_macintstatus_l;	/* 0x484 */
++	u16 psm_macintstatus_h;	/* 0x486 */
++	u16 psm_macintmask_l;	/* 0x488 */
++	u16 psm_macintmask_h;	/* 0x48A */
++	u16 PAD;		/* 0x48C */
++	u16 psm_maccommand;	/* 0x48E */
++	u16 psm_brc;		/* 0x490 */
++	u16 psm_phy_hdr_param;	/* 0x492 */
++	u16 psm_postcard;	/* 0x494 */
++	u16 psm_pcard_loc_l;	/* 0x496 */
++	u16 psm_pcard_loc_h;	/* 0x498 */
++	u16 psm_gpio_in;	/* 0x49A */
++	u16 psm_gpio_out;	/* 0x49C */
++	u16 psm_gpio_oe;	/* 0x49E */
++
++	u16 psm_bred_0;	/* 0x4A0 */
++	u16 psm_bred_1;	/* 0x4A2 */
++	u16 psm_bred_2;	/* 0x4A4 */
++	u16 psm_bred_3;	/* 0x4A6 */
++	u16 psm_brcl_0;	/* 0x4A8 */
++	u16 psm_brcl_1;	/* 0x4AA */
++	u16 psm_brcl_2;	/* 0x4AC */
++	u16 psm_brcl_3;	/* 0x4AE */
++	u16 psm_brpo_0;	/* 0x4B0 */
++	u16 psm_brpo_1;	/* 0x4B2 */
++	u16 psm_brpo_2;	/* 0x4B4 */
++	u16 psm_brpo_3;	/* 0x4B6 */
++	u16 psm_brwk_0;	/* 0x4B8 */
++	u16 psm_brwk_1;	/* 0x4BA */
++	u16 psm_brwk_2;	/* 0x4BC */
++	u16 psm_brwk_3;	/* 0x4BE */
++
++	u16 psm_base_0;	/* 0x4C0 */
++	u16 psm_base_1;	/* 0x4C2 */
++	u16 psm_base_2;	/* 0x4C4 */
++	u16 psm_base_3;	/* 0x4C6 */
++	u16 psm_base_4;	/* 0x4C8 */
++	u16 psm_base_5;	/* 0x4CA */
++	u16 psm_base_6;	/* 0x4CC */
++	u16 psm_pc_reg_0;	/* 0x4CE */
++	u16 psm_pc_reg_1;	/* 0x4D0 */
++	u16 psm_pc_reg_2;	/* 0x4D2 */
++	u16 psm_pc_reg_3;	/* 0x4D4 */
++	u16 PAD[0xD];	/* 0x4D6 - 0x4DE */
++	u16 psm_corectlsts;	/* 0x4f0 *//* Corerev >= 13 */
++	u16 PAD[0x7];	/* 0x4f2 - 0x4fE */
++
++	/* TXE0 Block *//* 0x500 - 0x580 */
++	u16 txe_ctl;		/* 0x500 */
++	u16 txe_aux;		/* 0x502 */
++	u16 txe_ts_loc;	/* 0x504 */
++	u16 txe_time_out;	/* 0x506 */
++	u16 txe_wm_0;	/* 0x508 */
++	u16 txe_wm_1;	/* 0x50A */
++	u16 txe_phyctl;	/* 0x50C */
++	u16 txe_status;	/* 0x50E */
++	u16 txe_mmplcp0;	/* 0x510 */
++	u16 txe_mmplcp1;	/* 0x512 */
++	u16 txe_phyctl1;	/* 0x514 */
++
++	u16 PAD[0x05];	/* 0x510 - 0x51E */
++
++	/* Transmit control */
++	u16 xmtfifodef;	/* 0x520 */
++	u16 xmtfifo_frame_cnt;	/* 0x522 *//* Corerev >= 16 */
++	u16 xmtfifo_byte_cnt;	/* 0x524 *//* Corerev >= 16 */
++	u16 xmtfifo_head;	/* 0x526 *//* Corerev >= 16 */
++	u16 xmtfifo_rd_ptr;	/* 0x528 *//* Corerev >= 16 */
++	u16 xmtfifo_wr_ptr;	/* 0x52A *//* Corerev >= 16 */
++	u16 xmtfifodef1;	/* 0x52C *//* Corerev >= 16 */
++
++	u16 PAD[0x09];	/* 0x52E - 0x53E */
++
++	u16 xmtfifocmd;	/* 0x540 */
++	u16 xmtfifoflush;	/* 0x542 */
++	u16 xmtfifothresh;	/* 0x544 */
++	u16 xmtfifordy;	/* 0x546 */
++	u16 xmtfifoprirdy;	/* 0x548 */
++	u16 xmtfiforqpri;	/* 0x54A */
++	u16 xmttplatetxptr;	/* 0x54C */
++	u16 PAD;		/* 0x54E */
++	u16 xmttplateptr;	/* 0x550 */
++	u16 smpl_clct_strptr;	/* 0x552 *//* Corerev >= 22 */
++	u16 smpl_clct_stpptr;	/* 0x554 *//* Corerev >= 22 */
++	u16 smpl_clct_curptr;	/* 0x556 *//* Corerev >= 22 */
++	u16 PAD[0x04];	/* 0x558 - 0x55E */
++	u16 xmttplatedatalo;	/* 0x560 */
++	u16 xmttplatedatahi;	/* 0x562 */
++
++	u16 PAD[2];		/* 0x564 - 0x566 */
++
++	u16 xmtsel;		/* 0x568 */
++	u16 xmttxcnt;	/* 0x56A */
++	u16 xmttxshmaddr;	/* 0x56C */
++
++	u16 PAD[0x09];	/* 0x56E - 0x57E */
++
++	/* TXE1 Block */
++	u16 PAD[0x40];	/* 0x580 - 0x5FE */
++
++	/* TSF Block */
++	u16 PAD[0X02];	/* 0x600 - 0x602 */
++	u16 tsf_cfpstrt_l;	/* 0x604 */
++	u16 tsf_cfpstrt_h;	/* 0x606 */
++	u16 PAD[0X05];	/* 0x608 - 0x610 */
++	u16 tsf_cfppretbtt;	/* 0x612 */
++	u16 PAD[0XD];	/* 0x614 - 0x62C */
++	u16 tsf_clk_frac_l;	/* 0x62E */
++	u16 tsf_clk_frac_h;	/* 0x630 */
++	u16 PAD[0X14];	/* 0x632 - 0x658 */
++	u16 tsf_random;	/* 0x65A */
++	u16 PAD[0x05];	/* 0x65C - 0x664 */
++	/* GPTimer 2 registers */
++	u16 tsf_gpt2_stat;	/* 0x666 */
++	u16 tsf_gpt2_ctr_l;	/* 0x668 */
++	u16 tsf_gpt2_ctr_h;	/* 0x66A */
++	u16 tsf_gpt2_val_l;	/* 0x66C */
++	u16 tsf_gpt2_val_h;	/* 0x66E */
++	u16 tsf_gptall_stat;	/* 0x670 */
++	u16 PAD[0x07];	/* 0x672 - 0x67E */
++
++	/* IFS Block */
++	u16 ifs_sifs_rx_tx_tx;	/* 0x680 */
++	u16 ifs_sifs_nav_tx;	/* 0x682 */
++	u16 ifs_slot;	/* 0x684 */
++	u16 PAD;		/* 0x686 */
++	u16 ifs_ctl;		/* 0x688 */
++	u16 PAD[0x3];	/* 0x68a - 0x68F */
++	u16 ifsstat;		/* 0x690 */
++	u16 ifsmedbusyctl;	/* 0x692 */
++	u16 iftxdur;		/* 0x694 */
++	u16 PAD[0x3];	/* 0x696 - 0x69b */
++	/* EDCF support in dot11macs */
++	u16 ifs_aifsn;	/* 0x69c */
++	u16 ifs_ctl1;	/* 0x69e */
++
++	/* slow clock registers */
++	u16 scc_ctl;		/* 0x6a0 */
++	u16 scc_timer_l;	/* 0x6a2 */
++	u16 scc_timer_h;	/* 0x6a4 */
++	u16 scc_frac;	/* 0x6a6 */
++	u16 scc_fastpwrup_dly;	/* 0x6a8 */
++	u16 scc_per;		/* 0x6aa */
++	u16 scc_per_frac;	/* 0x6ac */
++	u16 scc_cal_timer_l;	/* 0x6ae */
++	u16 scc_cal_timer_h;	/* 0x6b0 */
++	u16 PAD;		/* 0x6b2 */
++
++	u16 PAD[0x26];
++
++	/* NAV Block */
++	u16 nav_ctl;		/* 0x700 */
++	u16 navstat;		/* 0x702 */
++	u16 PAD[0x3e];	/* 0x702 - 0x77E */
++
++	/* WEP/PMQ Block *//* 0x780 - 0x7FE */
++	u16 PAD[0x20];	/* 0x780 - 0x7BE */
++
++	u16 wepctl;		/* 0x7C0 */
++	u16 wepivloc;	/* 0x7C2 */
++	u16 wepivkey;	/* 0x7C4 */
++	u16 wepwkey;		/* 0x7C6 */
++
++	u16 PAD[4];		/* 0x7C8 - 0x7CE */
++	u16 pcmctl;		/* 0X7D0 */
++	u16 pcmstat;		/* 0X7D2 */
++	u16 PAD[6];		/* 0x7D4 - 0x7DE */
++
++	u16 pmqctl;		/* 0x7E0 */
++	u16 pmqstatus;	/* 0x7E2 */
++	u16 pmqpat0;		/* 0x7E4 */
++	u16 pmqpat1;		/* 0x7E6 */
++	u16 pmqpat2;		/* 0x7E8 */
++
++	u16 pmqdat;		/* 0x7EA */
++	u16 pmqdator;	/* 0x7EC */
++	u16 pmqhst;		/* 0x7EE */
++	u16 pmqpath0;	/* 0x7F0 */
++	u16 pmqpath1;	/* 0x7F2 */
++	u16 pmqpath2;	/* 0x7F4 */
++	u16 pmqdath;		/* 0x7F6 */
++
++	u16 PAD[0x04];	/* 0x7F8 - 0x7FE */
++
++	/* SHM *//* 0x800 - 0xEFE */
++	u16 PAD[0x380];	/* 0x800 - 0xEFE */
++};
++
++/* d11 register field offset */
++#define D11REGOFFS(field)	offsetof(struct d11regs, field)
++
++#define	PIHR_BASE	0x0400	/* byte address of packed IHR region */
++
++/* biststatus */
++#define	BT_DONE		(1U << 31)	/* bist done */
++#define	BT_B2S		(1 << 30)	/* bist2 ram summary bit */
++
++/* intstatus and intmask */
++#define	I_PC		(1 << 10)	/* pci descriptor error */
++#define	I_PD		(1 << 11)	/* pci data error */
++#define	I_DE		(1 << 12)	/* descriptor protocol error */
++#define	I_RU		(1 << 13)	/* receive descriptor underflow */
++#define	I_RO		(1 << 14)	/* receive fifo overflow */
++#define	I_XU		(1 << 15)	/* transmit fifo underflow */
++#define	I_RI		(1 << 16)	/* receive interrupt */
++#define	I_XI		(1 << 24)	/* transmit interrupt */
++
++/* interrupt receive lazy */
++#define	IRL_TO_MASK		0x00ffffff	/* timeout */
++#define	IRL_FC_MASK		0xff000000	/* frame count */
++#define	IRL_FC_SHIFT		24	/* frame count */
++
++/*== maccontrol register ==*/
++#define	MCTL_GMODE		(1U << 31)
++#define	MCTL_DISCARD_PMQ	(1 << 30)
++#define	MCTL_WAKE		(1 << 26)
++#define	MCTL_HPS		(1 << 25)
++#define	MCTL_PROMISC		(1 << 24)
++#define	MCTL_KEEPBADFCS		(1 << 23)
++#define	MCTL_KEEPCONTROL	(1 << 22)
++#define	MCTL_PHYLOCK		(1 << 21)
++#define	MCTL_BCNS_PROMISC	(1 << 20)
++#define	MCTL_LOCK_RADIO		(1 << 19)
++#define	MCTL_AP			(1 << 18)
++#define	MCTL_INFRA		(1 << 17)
++#define	MCTL_BIGEND		(1 << 16)
++#define	MCTL_GPOUT_SEL_MASK	(3 << 14)
++#define	MCTL_GPOUT_SEL_SHIFT	14
++#define	MCTL_EN_PSMDBG		(1 << 13)
++#define	MCTL_IHR_EN		(1 << 10)
++#define	MCTL_SHM_UPPER		(1 <<  9)
++#define	MCTL_SHM_EN		(1 <<  8)
++#define	MCTL_PSM_JMP_0		(1 <<  2)
++#define	MCTL_PSM_RUN		(1 <<  1)
++#define	MCTL_EN_MAC		(1 <<  0)
++
++/*== maccommand register ==*/
++#define	MCMD_BCN0VLD		(1 <<  0)
++#define	MCMD_BCN1VLD		(1 <<  1)
++#define	MCMD_DIRFRMQVAL		(1 <<  2)
++#define	MCMD_CCA		(1 <<  3)
++#define	MCMD_BG_NOISE		(1 <<  4)
++#define	MCMD_SKIP_SHMINIT	(1 <<  5)	/* only used for simulation */
++#define MCMD_SAMPLECOLL		MCMD_SKIP_SHMINIT /* reuse for sample collect */
++
++/*== macintstatus/macintmask ==*/
++/* gracefully suspended */
++#define	MI_MACSSPNDD		(1 <<  0)
++/* beacon template available */
++#define	MI_BCNTPL		(1 <<  1)
++/* TBTT indication */
++#define	MI_TBTT			(1 <<  2)
++/* beacon successfully tx'd */
++#define	MI_BCNSUCCESS		(1 <<  3)
++/* beacon canceled (IBSS) */
++#define	MI_BCNCANCLD		(1 <<  4)
++/* end of ATIM-window (IBSS) */
++#define	MI_ATIMWINEND		(1 <<  5)
++/* PMQ entries available */
++#define	MI_PMQ			(1 <<  6)
++/* non-specific gen-stat bits that are set by PSM */
++#define	MI_NSPECGEN_0		(1 <<  7)
++/* non-specific gen-stat bits that are set by PSM */
++#define	MI_NSPECGEN_1		(1 <<  8)
++/* MAC level Tx error */
++#define	MI_MACTXERR		(1 <<  9)
++/* non-specific gen-stat bits that are set by PSM */
++#define	MI_NSPECGEN_3		(1 << 10)
++/* PHY Tx error */
++#define	MI_PHYTXERR		(1 << 11)
++/* Power Management Event */
++#define	MI_PME			(1 << 12)
++/* General-purpose timer0 */
++#define	MI_GP0			(1 << 13)
++/* General-purpose timer1 */
++#define	MI_GP1			(1 << 14)
++/* (ORed) DMA-interrupts */
++#define	MI_DMAINT		(1 << 15)
++/* MAC has completed a TX FIFO Suspend/Flush */
++#define	MI_TXSTOP		(1 << 16)
++/* MAC has completed a CCA measurement */
++#define	MI_CCA			(1 << 17)
++/* MAC has collected background noise samples */
++#define	MI_BG_NOISE		(1 << 18)
++/* MBSS DTIM TBTT indication */
++#define	MI_DTIM_TBTT		(1 << 19)
++/* Probe response queue needs attention */
++#define MI_PRQ			(1 << 20)
++/* Radio/PHY has been powered back up. */
++#define	MI_PWRUP		(1 << 21)
++#define	MI_RESERVED3		(1 << 22)
++#define	MI_RESERVED2		(1 << 23)
++#define MI_RESERVED1		(1 << 25)
++/* MAC detected change on RF Disable input*/
++#define MI_RFDISABLE		(1 << 28)
++/* MAC has completed a TX */
++#define	MI_TFS			(1 << 29)
++/* A phy status change wrt G mode */
++#define	MI_PHYCHANGED		(1 << 30)
++/* general purpose timeout */
++#define	MI_TO			(1U << 31)
++
++/* Mac capabilities registers */
++/*== machwcap ==*/
++#define	MCAP_TKIPMIC		0x80000000	/* TKIP MIC hardware present */
++
++/*== pmqhost data ==*/
++/* data entry of head pmq entry */
++#define	PMQH_DATA_MASK		0xffff0000
++/* PM entry for BSS config */
++#define	PMQH_BSSCFG		0x00100000
++/* PM Mode OFF: power save off */
++#define	PMQH_PMOFF		0x00010000
++/* PM Mode ON: power save on */
++#define	PMQH_PMON		0x00020000
++/* Dis-associated or De-authenticated */
++#define	PMQH_DASAT		0x00040000
++/* ATIM not acknowledged */
++#define	PMQH_ATIMFAIL		0x00080000
++/* delete head entry */
++#define	PMQH_DEL_ENTRY		0x00000001
++/* delete head entry to cur read pointer -1 */
++#define	PMQH_DEL_MULT		0x00000002
++/* pmq overflow indication */
++#define	PMQH_OFLO		0x00000004
++/* entries are present in pmq */
++#define	PMQH_NOT_EMPTY		0x00000008
++
++/*== phydebug ==*/
++/* phy is asserting carrier sense */
++#define	PDBG_CRS		(1 << 0)
++/* phy is taking xmit byte from mac this cycle */
++#define	PDBG_TXA		(1 << 1)
++/* mac is instructing the phy to transmit a frame */
++#define	PDBG_TXF		(1 << 2)
++/* phy is signalling a transmit Error to the mac */
++#define	PDBG_TXE		(1 << 3)
++/* phy detected the end of a valid frame preamble */
++#define	PDBG_RXF		(1 << 4)
++/* phy detected the end of a valid PLCP header */
++#define	PDBG_RXS		(1 << 5)
++/* rx start not asserted */
++#define	PDBG_RXFRG		(1 << 6)
++/* mac is taking receive byte from phy this cycle */
++#define	PDBG_RXV		(1 << 7)
++/* RF portion of the radio is disabled */
++#define	PDBG_RFD		(1 << 16)
++
++/*== objaddr register ==*/
++#define	OBJADDR_SEL_MASK	0x000F0000
++#define	OBJADDR_UCM_SEL		0x00000000
++#define	OBJADDR_SHM_SEL		0x00010000
++#define	OBJADDR_SCR_SEL		0x00020000
++#define	OBJADDR_IHR_SEL		0x00030000
++#define	OBJADDR_RCMTA_SEL	0x00040000
++#define	OBJADDR_SRCHM_SEL	0x00060000
++#define	OBJADDR_WINC		0x01000000
++#define	OBJADDR_RINC		0x02000000
++#define	OBJADDR_AUTO_INC	0x03000000
++
++#define	WEP_PCMADDR		0x07d4
++#define	WEP_PCMDATA		0x07d6
++
++/*== frmtxstatus ==*/
++#define	TXS_V			(1 << 0)	/* valid bit */
++#define	TXS_STATUS_MASK		0xffff
++#define	TXS_FID_MASK		0xffff0000
++#define	TXS_FID_SHIFT		16
++
++/*== frmtxstatus2 ==*/
++#define	TXS_SEQ_MASK		0xffff
++#define	TXS_PTX_MASK		0xff0000
++#define	TXS_PTX_SHIFT		16
++#define	TXS_MU_MASK		0x01000000
++#define	TXS_MU_SHIFT		24
++
++/*== clk_ctl_st ==*/
++#define CCS_ERSRC_REQ_D11PLL	0x00000100	/* d11 core pll request */
++#define CCS_ERSRC_REQ_PHYPLL	0x00000200	/* PHY pll request */
++#define CCS_ERSRC_AVAIL_D11PLL	0x01000000	/* d11 core pll available */
++#define CCS_ERSRC_AVAIL_PHYPLL	0x02000000	/* PHY pll available */
++
++/* HT Cloclk Ctrl and Clock Avail for 4313 */
++#define CCS_ERSRC_REQ_HT    0x00000010	/* HT avail request */
++#define CCS_ERSRC_AVAIL_HT  0x00020000	/* HT clock available */
++
++/* tsf_cfprep register */
++#define	CFPREP_CBI_MASK		0xffffffc0
++#define	CFPREP_CBI_SHIFT	6
++#define	CFPREP_CFPP		0x00000001
++
++/* tx fifo sizes values are in terms of 256 byte blocks */
++#define TXFIFOCMD_RESET_MASK	(1 << 15)	/* reset */
++#define TXFIFOCMD_FIFOSEL_SHIFT	8	/* fifo */
++#define TXFIFO_FIFOTOP_SHIFT	8	/* fifo start */
++
++#define TXFIFO_START_BLK16	 65	/* Base address + 32 * 512 B/P */
++#define TXFIFO_START_BLK	 6	/* Base address + 6 * 256 B */
++#define TXFIFO_SIZE_UNIT	256	/* one unit corresponds to 256 bytes */
++#define MBSS16_TEMPLMEM_MINBLKS	65	/* one unit corresponds to 256 bytes */
++
++/*== phy versions (PhyVersion:Revision field) ==*/
++/* analog block version */
++#define	PV_AV_MASK		0xf000
++/* analog block version bitfield offset */
++#define	PV_AV_SHIFT		12
++/* phy type */
++#define	PV_PT_MASK		0x0f00
++/* phy type bitfield offset */
++#define	PV_PT_SHIFT		8
++/* phy version */
++#define	PV_PV_MASK		0x000f
++#define	PHY_TYPE(v)		((v & PV_PT_MASK) >> PV_PT_SHIFT)
++
++/*== phy types (PhyVersion:PhyType field) ==*/
++#define	PHY_TYPE_N		4	/* N-Phy value */
++#define	PHY_TYPE_SSN		6	/* SSLPN-Phy value */
++#define	PHY_TYPE_LCN		8	/* LCN-Phy value */
++#define	PHY_TYPE_LCNXN		9	/* LCNXN-Phy value */
++#define	PHY_TYPE_NULL		0xf	/* Invalid Phy value */
++
++/*== analog types (PhyVersion:AnalogType field) ==*/
++#define	ANA_11N_013		5
++
++/* 802.11a PLCP header def */
++struct ofdm_phy_hdr {
++	u8 rlpt[3];		/* rate, length, parity, tail */
++	u16 service;
++	u8 pad;
++} __packed;
++
++#define	D11A_PHY_HDR_GRATE(phdr)	((phdr)->rlpt[0] & 0x0f)
++#define	D11A_PHY_HDR_GRES(phdr)		(((phdr)->rlpt[0] >> 4) & 0x01)
++#define	D11A_PHY_HDR_GLENGTH(phdr)	(((u32 *)((phdr)->rlpt) >> 5) & 0x0fff)
++#define	D11A_PHY_HDR_GPARITY(phdr)	(((phdr)->rlpt[3] >> 1) & 0x01)
++#define	D11A_PHY_HDR_GTAIL(phdr)	(((phdr)->rlpt[3] >> 2) & 0x3f)
++
++/* rate encoded per 802.11a-1999 sec 17.3.4.1 */
++#define	D11A_PHY_HDR_SRATE(phdr, rate)		\
++	((phdr)->rlpt[0] = ((phdr)->rlpt[0] & 0xf0) | ((rate) & 0xf))
++/* set reserved field to zero */
++#define	D11A_PHY_HDR_SRES(phdr)		((phdr)->rlpt[0] &= 0xef)
++/* length is number of octets in PSDU */
++#define	D11A_PHY_HDR_SLENGTH(phdr, length)	\
++	(*(u32 *)((phdr)->rlpt) = *(u32 *)((phdr)->rlpt) | \
++	(((length) & 0x0fff) << 5))
++/* set the tail to all zeros */
++#define	D11A_PHY_HDR_STAIL(phdr)	((phdr)->rlpt[3] &= 0x03)
++
++#define	D11A_PHY_HDR_LEN_L	3	/* low-rate part of PLCP header */
++#define	D11A_PHY_HDR_LEN_R	2	/* high-rate part of PLCP header */
++
++#define	D11A_PHY_TX_DELAY	(2)	/* 2.1 usec */
++
++#define	D11A_PHY_HDR_TIME	(4)	/* low-rate part of PLCP header */
++#define	D11A_PHY_PRE_TIME	(16)
++#define	D11A_PHY_PREHDR_TIME	(D11A_PHY_PRE_TIME + D11A_PHY_HDR_TIME)
++
++/* 802.11b PLCP header def */
++struct cck_phy_hdr {
++	u8 signal;
++	u8 service;
++	u16 length;
++	u16 crc;
++} __packed;
++
++#define	D11B_PHY_HDR_LEN	6
++
++#define	D11B_PHY_TX_DELAY	(3)	/* 3.4 usec */
++
++#define	D11B_PHY_LHDR_TIME	(D11B_PHY_HDR_LEN << 3)
++#define	D11B_PHY_LPRE_TIME	(144)
++#define	D11B_PHY_LPREHDR_TIME	(D11B_PHY_LPRE_TIME + D11B_PHY_LHDR_TIME)
++
++#define	D11B_PHY_SHDR_TIME	(D11B_PHY_LHDR_TIME >> 1)
++#define	D11B_PHY_SPRE_TIME	(D11B_PHY_LPRE_TIME >> 1)
++#define	D11B_PHY_SPREHDR_TIME	(D11B_PHY_SPRE_TIME + D11B_PHY_SHDR_TIME)
++
++#define	D11B_PLCP_SIGNAL_LOCKED	(1 << 2)
++#define	D11B_PLCP_SIGNAL_LE	(1 << 7)
++
++#define MIMO_PLCP_MCS_MASK	0x7f	/* mcs index */
++#define MIMO_PLCP_40MHZ		0x80	/* 40 Hz frame */
++#define MIMO_PLCP_AMPDU		0x08	/* ampdu */
++
++#define BRCMS_GET_CCK_PLCP_LEN(plcp) (plcp[4] + (plcp[5] << 8))
++#define BRCMS_GET_MIMO_PLCP_LEN(plcp) (plcp[1] + (plcp[2] << 8))
++#define BRCMS_SET_MIMO_PLCP_LEN(plcp, len) \
++	do { \
++		plcp[1] = len & 0xff; \
++		plcp[2] = ((len >> 8) & 0xff); \
++	} while (0)
++
++#define BRCMS_SET_MIMO_PLCP_AMPDU(plcp) (plcp[3] |= MIMO_PLCP_AMPDU)
++#define BRCMS_CLR_MIMO_PLCP_AMPDU(plcp) (plcp[3] &= ~MIMO_PLCP_AMPDU)
++#define BRCMS_IS_MIMO_PLCP_AMPDU(plcp) (plcp[3] & MIMO_PLCP_AMPDU)
++
++/*
++ * The dot11a PLCP header is 5 bytes.  To simplify the software (so that we
++ * don't need e.g. different tx DMA headers for 11a and 11b), the PLCP header
++ * has padding added in the ucode.
++ */
++#define	D11_PHY_HDR_LEN	6
++
++/* TX DMA buffer header */
++struct d11txh {
++	__le16 MacTxControlLow;	/* 0x0 */
++	__le16 MacTxControlHigh;	/* 0x1 */
++	__le16 MacFrameControl;	/* 0x2 */
++	__le16 TxFesTimeNormal;	/* 0x3 */
++	__le16 PhyTxControlWord;	/* 0x4 */
++	__le16 PhyTxControlWord_1;	/* 0x5 */
++	__le16 PhyTxControlWord_1_Fbr;	/* 0x6 */
++	__le16 PhyTxControlWord_1_Rts;	/* 0x7 */
++	__le16 PhyTxControlWord_1_FbrRts;	/* 0x8 */
++	__le16 MainRates;	/* 0x9 */
++	__le16 XtraFrameTypes;	/* 0xa */
++	u8 IV[16];		/* 0x0b - 0x12 */
++	u8 TxFrameRA[6];	/* 0x13 - 0x15 */
++	__le16 TxFesTimeFallback;	/* 0x16 */
++	u8 RTSPLCPFallback[6];	/* 0x17 - 0x19 */
++	__le16 RTSDurFallback;	/* 0x1a */
++	u8 FragPLCPFallback[6];	/* 0x1b - 1d */
++	__le16 FragDurFallback;	/* 0x1e */
++	__le16 MModeLen;	/* 0x1f */
++	__le16 MModeFbrLen;	/* 0x20 */
++	__le16 TstampLow;	/* 0x21 */
++	__le16 TstampHigh;	/* 0x22 */
++	__le16 ABI_MimoAntSel;	/* 0x23 */
++	__le16 PreloadSize;	/* 0x24 */
++	__le16 AmpduSeqCtl;	/* 0x25 */
++	__le16 TxFrameID;	/* 0x26 */
++	__le16 TxStatus;	/* 0x27 */
++	__le16 MaxNMpdus;	/* 0x28 */
++	__le16 MaxABytes_MRT;	/* 0x29 */
++	__le16 MaxABytes_FBR;	/* 0x2a */
++	__le16 MinMBytes;	/* 0x2b */
++	u8 RTSPhyHeader[D11_PHY_HDR_LEN];	/* 0x2c - 0x2e */
++	struct ieee80211_rts rts_frame;	/* 0x2f - 0x36 */
++	u16 PAD;		/* 0x37 */
++} __packed;
++
++#define	D11_TXH_LEN		112	/* bytes */
++
++/* Frame Types */
++#define FT_CCK	0
++#define FT_OFDM	1
++#define FT_HT	2
++#define FT_N	3
++
++/*
++ * Position of MPDU inside A-MPDU; indicated with bits 10:9
++ * of MacTxControlLow
++ */
++#define TXC_AMPDU_SHIFT		9	/* shift for ampdu settings */
++#define TXC_AMPDU_NONE		0	/* Regular MPDU, not an A-MPDU */
++#define TXC_AMPDU_FIRST		1	/* first MPDU of an A-MPDU */
++#define TXC_AMPDU_MIDDLE	2	/* intermediate MPDU of an A-MPDU */
++#define TXC_AMPDU_LAST		3	/* last (or single) MPDU of an A-MPDU */
++
++/*== MacTxControlLow ==*/
++#define TXC_AMIC		0x8000
++#define	TXC_SENDCTS		0x0800
++#define TXC_AMPDU_MASK		0x0600
++#define TXC_BW_40		0x0100
++#define TXC_FREQBAND_5G		0x0080
++#define	TXC_DFCS		0x0040
++#define	TXC_IGNOREPMQ		0x0020
++#define	TXC_HWSEQ		0x0010
++#define	TXC_STARTMSDU		0x0008
++#define	TXC_SENDRTS		0x0004
++#define	TXC_LONGFRAME		0x0002
++#define	TXC_IMMEDACK		0x0001
++
++/*== MacTxControlHigh ==*/
++/* RTS fallback preamble type 1 = SHORT 0 = LONG */
++#define TXC_PREAMBLE_RTS_FB_SHORT	0x8000
++/* RTS main rate preamble type 1 = SHORT 0 = LONG */
++#define TXC_PREAMBLE_RTS_MAIN_SHORT	0x4000
++/*
++ * Main fallback rate preamble type
++ *   1 = SHORT for OFDM/GF for MIMO
++ *   0 = LONG for CCK/MM for MIMO
++ */
++#define TXC_PREAMBLE_DATA_FB_SHORT	0x2000
++
++/* TXC_PREAMBLE_DATA_MAIN is in PhyTxControl bit 5 */
++/* use fallback rate for this AMPDU */
++#define	TXC_AMPDU_FBR		0x1000
++#define	TXC_SECKEY_MASK		0x0FF0
++#define	TXC_SECKEY_SHIFT	4
++/* Use alternate txpwr defined at loc. M_ALT_TXPWR_IDX */
++#define	TXC_ALT_TXPWR		0x0008
++#define	TXC_SECTYPE_MASK	0x0007
++#define	TXC_SECTYPE_SHIFT	0
++
++/* Null delimiter for Fallback rate */
++#define AMPDU_FBR_NULL_DELIM  5	/* Location of Null delimiter count for AMPDU */
++
++/* PhyTxControl for Mimophy */
++#define	PHY_TXC_PWR_MASK	0xFC00
++#define	PHY_TXC_PWR_SHIFT	10
++#define	PHY_TXC_ANT_MASK	0x03C0	/* bit 6, 7, 8, 9 */
++#define	PHY_TXC_ANT_SHIFT	6
++#define	PHY_TXC_ANT_0_1		0x00C0	/* auto, last rx */
++#define	PHY_TXC_LCNPHY_ANT_LAST	0x0000
++#define	PHY_TXC_ANT_3		0x0200	/* virtual antenna 3 */
++#define	PHY_TXC_ANT_2		0x0100	/* virtual antenna 2 */
++#define	PHY_TXC_ANT_1		0x0080	/* virtual antenna 1 */
++#define	PHY_TXC_ANT_0		0x0040	/* virtual antenna 0 */
++#define	PHY_TXC_SHORT_HDR	0x0010
++
++#define	PHY_TXC_OLD_ANT_0	0x0000
++#define	PHY_TXC_OLD_ANT_1	0x0100
++#define	PHY_TXC_OLD_ANT_LAST	0x0300
++
++/* PhyTxControl_1 for Mimophy */
++#define PHY_TXC1_BW_MASK		0x0007
++#define PHY_TXC1_BW_10MHZ		0
++#define PHY_TXC1_BW_10MHZ_UP		1
++#define PHY_TXC1_BW_20MHZ		2
++#define PHY_TXC1_BW_20MHZ_UP		3
++#define PHY_TXC1_BW_40MHZ		4
++#define PHY_TXC1_BW_40MHZ_DUP		5
++#define PHY_TXC1_MODE_SHIFT		3
++#define PHY_TXC1_MODE_MASK		0x0038
++#define PHY_TXC1_MODE_SISO		0
++#define PHY_TXC1_MODE_CDD		1
++#define PHY_TXC1_MODE_STBC		2
++#define PHY_TXC1_MODE_SDM		3
++
++/* PhyTxControl for HTphy that are different from Mimophy */
++#define	PHY_TXC_HTANT_MASK		0x3fC0	/* bits 6-13 */
++
++/* XtraFrameTypes */
++#define XFTS_RTS_FT_SHIFT	2
++#define XFTS_FBRRTS_FT_SHIFT	4
++#define XFTS_CHANNEL_SHIFT	8
++
++/* Antenna diversity bit in ant_wr_settle */
++#define	PHY_AWS_ANTDIV		0x2000
++
++/* IFS ctl */
++#define IFS_USEEDCF	(1 << 2)
++
++/* IFS ctl1 */
++#define IFS_CTL1_EDCRS	(1 << 3)
++#define IFS_CTL1_EDCRS_20L (1 << 4)
++#define IFS_CTL1_EDCRS_40 (1 << 5)
++
++/* ABI_MimoAntSel */
++#define ABI_MAS_ADDR_BMP_IDX_MASK	0x0f00
++#define ABI_MAS_ADDR_BMP_IDX_SHIFT	8
++#define ABI_MAS_FBR_ANT_PTN_MASK	0x00f0
++#define ABI_MAS_FBR_ANT_PTN_SHIFT	4
++#define ABI_MAS_MRT_ANT_PTN_MASK	0x000f
++
++/* tx status packet */
++struct tx_status {
++	u16 framelen;
++	u16 PAD;
++	u16 frameid;
++	u16 status;
++	u16 lasttxtime;
++	u16 sequence;
++	u16 phyerr;
++	u16 ackphyrxsh;
++} __packed;
++
++#define	TXSTATUS_LEN	16
++
++/* status field bit definitions */
++#define	TX_STATUS_FRM_RTX_MASK	0xF000
++#define	TX_STATUS_FRM_RTX_SHIFT	12
++#define	TX_STATUS_RTS_RTX_MASK	0x0F00
++#define	TX_STATUS_RTS_RTX_SHIFT	8
++#define TX_STATUS_MASK		0x00FE
++#define	TX_STATUS_PMINDCTD	(1 << 7) /* PM mode indicated to AP */
++#define	TX_STATUS_INTERMEDIATE	(1 << 6) /* intermediate or 1st ampdu pkg */
++#define	TX_STATUS_AMPDU		(1 << 5) /* AMPDU status */
++#define TX_STATUS_SUPR_MASK	0x1C	 /* suppress status bits (4:2) */
++#define TX_STATUS_SUPR_SHIFT	2
++#define	TX_STATUS_ACK_RCV	(1 << 1) /* ACK received */
++#define	TX_STATUS_VALID		(1 << 0) /* Tx status valid */
++#define	TX_STATUS_NO_ACK	0
++
++/* suppress status reason codes */
++#define	TX_STATUS_SUPR_PMQ	(1 << 2) /* PMQ entry */
++#define	TX_STATUS_SUPR_FLUSH	(2 << 2) /* flush request */
++#define	TX_STATUS_SUPR_FRAG	(3 << 2) /* previous frag failure */
++#define	TX_STATUS_SUPR_TBTT	(3 << 2) /* SHARED: Probe resp supr for TBTT */
++#define	TX_STATUS_SUPR_BADCH	(4 << 2) /* channel mismatch */
++#define	TX_STATUS_SUPR_EXPTIME	(5 << 2) /* lifetime expiry */
++#define	TX_STATUS_SUPR_UF	(6 << 2) /* underflow */
++
++/* Unexpected tx status for rate update */
++#define TX_STATUS_UNEXP(status) \
++	((((status) & TX_STATUS_INTERMEDIATE) != 0) && \
++	 TX_STATUS_UNEXP_AMPDU(status))
++
++/* Unexpected tx status for A-MPDU rate update */
++#define TX_STATUS_UNEXP_AMPDU(status) \
++	((((status) & TX_STATUS_SUPR_MASK) != 0) && \
++	 (((status) & TX_STATUS_SUPR_MASK) != TX_STATUS_SUPR_EXPTIME))
++
++#define TX_STATUS_BA_BMAP03_MASK	0xF000	/* ba bitmap 0:3 in 1st pkg */
++#define TX_STATUS_BA_BMAP03_SHIFT	12	/* ba bitmap 0:3 in 1st pkg */
++#define TX_STATUS_BA_BMAP47_MASK	0x001E	/* ba bitmap 4:7 in 2nd pkg */
++#define TX_STATUS_BA_BMAP47_SHIFT	3	/* ba bitmap 4:7 in 2nd pkg */
++
++/* RXE (Receive Engine) */
++
++/* RCM_CTL */
++#define	RCM_INC_MASK_H		0x0080
++#define	RCM_INC_MASK_L		0x0040
++#define	RCM_INC_DATA		0x0020
++#define	RCM_INDEX_MASK		0x001F
++#define	RCM_SIZE		15
++
++#define	RCM_MAC_OFFSET		0	/* current MAC address */
++#define	RCM_BSSID_OFFSET	3	/* current BSSID address */
++#define	RCM_F_BSSID_0_OFFSET	6	/* foreign BSS CFP tracking */
++#define	RCM_F_BSSID_1_OFFSET	9	/* foreign BSS CFP tracking */
++#define	RCM_F_BSSID_2_OFFSET	12	/* foreign BSS CFP tracking */
++
++#define RCM_WEP_TA0_OFFSET	16
++#define RCM_WEP_TA1_OFFSET	19
++#define RCM_WEP_TA2_OFFSET	22
++#define RCM_WEP_TA3_OFFSET	25
++
++/* PSM Block */
++
++/* psm_phy_hdr_param bits */
++#define MAC_PHY_RESET		1
++#define MAC_PHY_CLOCK_EN	2
++#define MAC_PHY_FORCE_CLK	4
++
++/* WEP Block */
++
++/* WEP_WKEY */
++#define	WKEY_START		(1 << 8)
++#define	WKEY_SEL_MASK		0x1F
++
++/* WEP data formats */
++
++/* the number of RCMTA entries */
++#define RCMTA_SIZE 50
++
++#define M_ADDR_BMP_BLK		(0x37e * 2)
++#define M_ADDR_BMP_BLK_SZ	12
++
++#define ADDR_BMP_RA		(1 << 0)	/* Receiver Address (RA) */
++#define ADDR_BMP_TA		(1 << 1)	/* Transmitter Address (TA) */
++#define ADDR_BMP_BSSID		(1 << 2)	/* BSSID */
++#define ADDR_BMP_AP		(1 << 3)	/* Infra-BSS Access Point */
++#define ADDR_BMP_STA		(1 << 4)	/* Infra-BSS Station */
++#define ADDR_BMP_RESERVED1	(1 << 5)
++#define ADDR_BMP_RESERVED2	(1 << 6)
++#define ADDR_BMP_RESERVED3	(1 << 7)
++#define ADDR_BMP_BSS_IDX_MASK	(3 << 8)	/* BSS control block index */
++#define ADDR_BMP_BSS_IDX_SHIFT	8
++
++#define	WSEC_MAX_RCMTA_KEYS	54
++
++/* max keys in M_TKMICKEYS_BLK */
++#define	WSEC_MAX_TKMIC_ENGINE_KEYS		12	/* 8 + 4 default */
++
++/* max RXE match registers */
++#define WSEC_MAX_RXE_KEYS	4
++
++/* SECKINDXALGO (Security Key Index & Algorithm Block) word format */
++/* SKL (Security Key Lookup) */
++#define	SKL_ALGO_MASK		0x0007
++#define	SKL_ALGO_SHIFT		0
++#define	SKL_KEYID_MASK		0x0008
++#define	SKL_KEYID_SHIFT		3
++#define	SKL_INDEX_MASK		0x03F0
++#define	SKL_INDEX_SHIFT		4
++#define	SKL_GRP_ALGO_MASK	0x1c00
++#define	SKL_GRP_ALGO_SHIFT	10
++
++/* additional bits defined for IBSS group key support */
++#define	SKL_IBSS_INDEX_MASK	0x01F0
++#define	SKL_IBSS_INDEX_SHIFT	4
++#define	SKL_IBSS_KEYID1_MASK	0x0600
++#define	SKL_IBSS_KEYID1_SHIFT	9
++#define	SKL_IBSS_KEYID2_MASK	0x1800
++#define	SKL_IBSS_KEYID2_SHIFT	11
++#define	SKL_IBSS_KEYALGO_MASK	0xE000
++#define	SKL_IBSS_KEYALGO_SHIFT	13
++
++#define	WSEC_MODE_OFF		0
++#define	WSEC_MODE_HW		1
++#define	WSEC_MODE_SW		2
++
++#define	WSEC_ALGO_OFF		0
++#define	WSEC_ALGO_WEP1		1
++#define	WSEC_ALGO_TKIP		2
++#define	WSEC_ALGO_AES		3
++#define	WSEC_ALGO_WEP128	4
++#define	WSEC_ALGO_AES_LEGACY	5
++#define	WSEC_ALGO_NALG		6
++
++#define	AES_MODE_NONE		0
++#define	AES_MODE_CCM		1
++
++/* WEP_CTL (Rev 0) */
++#define	WECR0_KEYREG_SHIFT	0
++#define	WECR0_KEYREG_MASK	0x7
++#define	WECR0_DECRYPT		(1 << 3)
++#define	WECR0_IVINLINE		(1 << 4)
++#define	WECR0_WEPALG_SHIFT	5
++#define	WECR0_WEPALG_MASK	(0x7 << 5)
++#define	WECR0_WKEYSEL_SHIFT	8
++#define	WECR0_WKEYSEL_MASK	(0x7 << 8)
++#define	WECR0_WKEYSTART		(1 << 11)
++#define	WECR0_WEPINIT		(1 << 14)
++#define	WECR0_ICVERR		(1 << 15)
++
++/* Frame template map byte offsets */
++#define	T_ACTS_TPL_BASE		(0)
++#define	T_NULL_TPL_BASE		(0xc * 2)
++#define	T_QNULL_TPL_BASE	(0x1c * 2)
++#define	T_RR_TPL_BASE		(0x2c * 2)
++#define	T_BCN0_TPL_BASE		(0x34 * 2)
++#define	T_PRS_TPL_BASE		(0x134 * 2)
++#define	T_BCN1_TPL_BASE		(0x234 * 2)
++#define T_TX_FIFO_TXRAM_BASE	(T_ACTS_TPL_BASE + \
++				 (TXFIFO_START_BLK * TXFIFO_SIZE_UNIT))
++
++#define T_BA_TPL_BASE		T_QNULL_TPL_BASE /* template area for BA */
++
++#define T_RAM_ACCESS_SZ		4	/* template ram is 4 byte access only */
++
++/* Shared Mem byte offsets */
++
++/* Location where the ucode expects the corerev */
++#define	M_MACHW_VER		(0x00b * 2)
++
++/* Location where the ucode expects the MAC capabilities */
++#define	M_MACHW_CAP_L		(0x060 * 2)
++#define	M_MACHW_CAP_H	(0x061 * 2)
++
++/* WME shared memory */
++#define M_EDCF_STATUS_OFF	(0x007 * 2)
++#define M_TXF_CUR_INDEX		(0x018 * 2)
++#define M_EDCF_QINFO		(0x120 * 2)
++
++/* PS-mode related parameters */
++#define	M_DOT11_SLOT		(0x008 * 2)
++#define	M_DOT11_DTIMPERIOD	(0x009 * 2)
++#define	M_NOSLPZNATDTIM		(0x026 * 2)
++
++/* Beacon-related parameters */
++#define	M_BCN0_FRM_BYTESZ	(0x00c * 2)	/* Bcn 0 template length */
++#define	M_BCN1_FRM_BYTESZ	(0x00d * 2)	/* Bcn 1 template length */
++#define	M_BCN_TXTSF_OFFSET	(0x00e * 2)
++#define	M_TIMBPOS_INBEACON	(0x00f * 2)
++#define	M_SFRMTXCNTFBRTHSD	(0x022 * 2)
++#define	M_LFRMTXCNTFBRTHSD	(0x023 * 2)
++#define	M_BCN_PCTLWD		(0x02a * 2)
++#define M_BCN_LI		(0x05b * 2)	/* beacon listen interval */
++
++/* MAX Rx Frame len */
++#define M_MAXRXFRM_LEN		(0x010 * 2)
++
++/* ACK/CTS related params */
++#define	M_RSP_PCTLWD		(0x011 * 2)
++
++/* Hardware Power Control */
++#define M_TXPWR_N		(0x012 * 2)
++#define M_TXPWR_TARGET		(0x013 * 2)
++#define M_TXPWR_MAX		(0x014 * 2)
++#define M_TXPWR_CUR		(0x019 * 2)
++
++/* Rx-related parameters */
++#define	M_RX_PAD_DATA_OFFSET	(0x01a * 2)
++
++/* WEP Shared mem data */
++#define	M_SEC_DEFIVLOC		(0x01e * 2)
++#define	M_SEC_VALNUMSOFTMCHTA	(0x01f * 2)
++#define	M_PHYVER		(0x028 * 2)
++#define	M_PHYTYPE		(0x029 * 2)
++#define	M_SECRXKEYS_PTR		(0x02b * 2)
++#define	M_TKMICKEYS_PTR		(0x059 * 2)
++#define	M_SECKINDXALGO_BLK	(0x2ea * 2)
++#define M_SECKINDXALGO_BLK_SZ	54
++#define	M_SECPSMRXTAMCH_BLK	(0x2fa * 2)
++#define	M_TKIP_TSC_TTAK		(0x18c * 2)
++#define	D11_MAX_KEY_SIZE	16
++
++#define	M_MAX_ANTCNT		(0x02e * 2)	/* antenna swap threshold */
++
++/* Probe response related parameters */
++#define	M_SSIDLEN		(0x024 * 2)
++#define	M_PRB_RESP_FRM_LEN	(0x025 * 2)
++#define	M_PRS_MAXTIME		(0x03a * 2)
++#define	M_SSID			(0xb0 * 2)
++#define	M_CTXPRS_BLK		(0xc0 * 2)
++#define	C_CTX_PCTLWD_POS	(0x4 * 2)
++
++/* Delta between OFDM and CCK power in CCK power boost mode */
++#define M_OFDM_OFFSET		(0x027 * 2)
++
++/* TSSI for last 4 11b/g CCK packets transmitted */
++#define	M_B_TSSI_0		(0x02c * 2)
++#define	M_B_TSSI_1		(0x02d * 2)
++
++/* Host flags to turn on ucode options */
++#define	M_HOST_FLAGS1		(0x02f * 2)
++#define	M_HOST_FLAGS2		(0x030 * 2)
++#define	M_HOST_FLAGS3		(0x031 * 2)
++#define	M_HOST_FLAGS4		(0x03c * 2)
++#define	M_HOST_FLAGS5		(0x06a * 2)
++#define	M_HOST_FLAGS_SZ		16
++
++#define M_RADAR_REG		(0x033 * 2)
++
++/* TSSI for last 4 11a OFDM packets transmitted */
++#define	M_A_TSSI_0		(0x034 * 2)
++#define	M_A_TSSI_1		(0x035 * 2)
++
++/* noise interference measurement */
++#define M_NOISE_IF_COUNT	(0x034 * 2)
++#define M_NOISE_IF_TIMEOUT	(0x035 * 2)
++
++#define	M_RF_RX_SP_REG1		(0x036 * 2)
++
++/* TSSI for last 4 11g OFDM packets transmitted */
++#define	M_G_TSSI_0		(0x038 * 2)
++#define	M_G_TSSI_1		(0x039 * 2)
++
++/* Background noise measure */
++#define	M_JSSI_0		(0x44 * 2)
++#define	M_JSSI_1		(0x45 * 2)
++#define	M_JSSI_AUX		(0x46 * 2)
++
++#define	M_CUR_2050_RADIOCODE	(0x47 * 2)
++
++/* TX fifo sizes */
++#define M_FIFOSIZE0		(0x4c * 2)
++#define M_FIFOSIZE1		(0x4d * 2)
++#define M_FIFOSIZE2		(0x4e * 2)
++#define M_FIFOSIZE3		(0x4f * 2)
++#define D11_MAX_TX_FRMS		32	/* max frames allowed in tx fifo */
++
++/* Current channel number plus upper bits */
++#define M_CURCHANNEL		(0x50 * 2)
++#define D11_CURCHANNEL_5G	0x0100;
++#define D11_CURCHANNEL_40	0x0200;
++#define D11_CURCHANNEL_MAX	0x00FF;
++
++/* last posted frameid on the bcmc fifo */
++#define M_BCMC_FID		(0x54 * 2)
++#define INVALIDFID		0xffff
++
++/* extended beacon phyctl bytes for 11N */
++#define	M_BCN_PCTL1WD		(0x058 * 2)
++
++/* idle busy ratio to duty_cycle requirement  */
++#define M_TX_IDLE_BUSY_RATIO_X_16_CCK  (0x52 * 2)
++#define M_TX_IDLE_BUSY_RATIO_X_16_OFDM (0x5A * 2)
++
++/* CW RSSI for LCNPHY */
++#define M_LCN_RSSI_0		0x1332
++#define M_LCN_RSSI_1		0x1338
++#define M_LCN_RSSI_2		0x133e
++#define M_LCN_RSSI_3		0x1344
++
++/* SNR for LCNPHY */
++#define M_LCN_SNR_A_0	0x1334
++#define M_LCN_SNR_B_0	0x1336
++
++#define M_LCN_SNR_A_1	0x133a
++#define M_LCN_SNR_B_1	0x133c
++
++#define M_LCN_SNR_A_2	0x1340
++#define M_LCN_SNR_B_2	0x1342
++
++#define M_LCN_SNR_A_3	0x1346
++#define M_LCN_SNR_B_3	0x1348
++
++#define M_LCN_LAST_RESET	(81*2)
++#define M_LCN_LAST_LOC	(63*2)
++#define M_LCNPHY_RESET_STATUS (4902)
++#define M_LCNPHY_DSC_TIME	(0x98d*2)
++#define M_LCNPHY_RESET_CNT_DSC (0x98b*2)
++#define M_LCNPHY_RESET_CNT	(0x98c*2)
++
++/* Rate table offsets */
++#define	M_RT_DIRMAP_A		(0xe0 * 2)
++#define	M_RT_BBRSMAP_A		(0xf0 * 2)
++#define	M_RT_DIRMAP_B		(0x100 * 2)
++#define	M_RT_BBRSMAP_B		(0x110 * 2)
++
++/* Rate table entry offsets */
++#define	M_RT_PRS_PLCP_POS	10
++#define	M_RT_PRS_DUR_POS	16
++#define	M_RT_OFDM_PCTL1_POS	18
++
++#define M_20IN40_IQ			(0x380 * 2)
++
++/* SHM locations where ucode stores the current power index */
++#define M_CURR_IDX1		(0x384 * 2)
++#define M_CURR_IDX2		(0x387 * 2)
++
++#define M_BSCALE_ANT0	(0x5e * 2)
++#define M_BSCALE_ANT1	(0x5f * 2)
++
++/* Antenna Diversity Testing */
++#define M_MIMO_ANTSEL_RXDFLT	(0x63 * 2)
++#define M_ANTSEL_CLKDIV	(0x61 * 2)
++#define M_MIMO_ANTSEL_TXDFLT	(0x64 * 2)
++
++#define M_MIMO_MAXSYM	(0x5d * 2)
++#define MIMO_MAXSYM_DEF		0x8000	/* 32k */
++#define MIMO_MAXSYM_MAX		0xffff	/* 64k */
++
++#define M_WATCHDOG_8TU		(0x1e * 2)
++#define WATCHDOG_8TU_DEF	5
++#define WATCHDOG_8TU_MAX	10
++
++/* Manufacturing Test Variables */
++/* PER test mode */
++#define M_PKTENG_CTRL		(0x6c * 2)
++/* IFS for TX mode */
++#define M_PKTENG_IFS		(0x6d * 2)
++/* Lower word of tx frmcnt/rx lostcnt */
++#define M_PKTENG_FRMCNT_LO	(0x6e * 2)
++/* Upper word of tx frmcnt/rx lostcnt */
++#define M_PKTENG_FRMCNT_HI	(0x6f * 2)
++
++/* Index variation in vbat ripple */
++#define M_LCN_PWR_IDX_MAX	(0x67 * 2) /* highest index read by ucode */
++#define M_LCN_PWR_IDX_MIN	(0x66 * 2) /* lowest index read by ucode */
++
++/* M_PKTENG_CTRL bit definitions */
++#define M_PKTENG_MODE_TX		0x0001
++#define M_PKTENG_MODE_TX_RIFS	        0x0004
++#define M_PKTENG_MODE_TX_CTS            0x0008
++#define M_PKTENG_MODE_RX		0x0002
++#define M_PKTENG_MODE_RX_WITH_ACK	0x0402
++#define M_PKTENG_MODE_MASK		0x0003
++/* TX frames indicated in the frmcnt reg */
++#define M_PKTENG_FRMCNT_VLD		0x0100
++
++/* Sample Collect parameters (bitmap and type) */
++/* Trigger bitmap for sample collect */
++#define M_SMPL_COL_BMP		(0x37d * 2)
++/* Sample collect type */
++#define M_SMPL_COL_CTL		(0x3b2 * 2)
++
++#define ANTSEL_CLKDIV_4MHZ	6
++#define MIMO_ANTSEL_BUSY	0x4000	/* bit 14 (busy) */
++#define MIMO_ANTSEL_SEL		0x8000	/* bit 15 write the value */
++#define MIMO_ANTSEL_WAIT	50	/* 50us wait */
++#define MIMO_ANTSEL_OVERRIDE	0x8000	/* flag */
++
++struct shm_acparams {
++	u16 txop;
++	u16 cwmin;
++	u16 cwmax;
++	u16 cwcur;
++	u16 aifs;
++	u16 bslots;
++	u16 reggap;
++	u16 status;
++	u16 rsvd[8];
++} __packed;
++#define M_EDCF_QLEN	(16 * 2)
++
++#define WME_STATUS_NEWAC	(1 << 8)
++
++/* M_HOST_FLAGS */
++#define MHFMAX		5	/* Number of valid hostflag half-word (u16) */
++#define MHF1		0	/* Hostflag 1 index */
++#define MHF2		1	/* Hostflag 2 index */
++#define MHF3		2	/* Hostflag 3 index */
++#define MHF4		3	/* Hostflag 4 index */
++#define MHF5		4	/* Hostflag 5 index */
++
++/* Flags in M_HOST_FLAGS */
++/* Enable ucode antenna diversity help */
++#define	MHF1_ANTDIV		0x0001
++/* Enable EDCF access control */
++#define	MHF1_EDCF		0x0100
++#define MHF1_IQSWAP_WAR		0x0200
++/* Disable Slow clock request, for corerev < 11 */
++#define	MHF1_FORCEFASTCLK	0x0400
++
++/* Flags in M_HOST_FLAGS2 */
++
++/* Flush BCMC FIFO immediately */
++#define MHF2_TXBCMC_NOW		0x0040
++/* Enable ucode/hw power control */
++#define MHF2_HWPWRCTL		0x0080
++#define MHF2_NPHY40MHZ_WAR	0x0800
++
++/* Flags in M_HOST_FLAGS3 */
++/* enabled mimo antenna selection */
++#define MHF3_ANTSEL_EN		0x0001
++/* antenna selection mode: 0: 2x3, 1: 2x4 */
++#define MHF3_ANTSEL_MODE	0x0002
++#define MHF3_RESERVED1		0x0004
++#define MHF3_RESERVED2		0x0008
++#define MHF3_NPHY_MLADV_WAR	0x0010
++
++/* Flags in M_HOST_FLAGS4 */
++/* force bphy Tx on core 0 (board level WAR) */
++#define MHF4_BPHY_TXCORE0	0x0080
++/* for 4313A0 FEM boards */
++#define MHF4_EXTPA_ENABLE	0x4000
++
++/* Flags in M_HOST_FLAGS5 */
++#define MHF5_4313_GPIOCTRL	0x0001
++#define MHF5_RESERVED1		0x0002
++#define MHF5_RESERVED2		0x0004
++/* Radio power setting for ucode */
++#define	M_RADIO_PWR		(0x32 * 2)
++
++/* phy noise recorded by ucode right after tx */
++#define	M_PHY_NOISE		(0x037 * 2)
++#define	PHY_NOISE_MASK		0x00ff
++
++/*
++ * Receive Frame Data Header for 802.11b DCF-only frames
++ *
++ * RxFrameSize: Actual byte length of the frame data received
++ * PAD: padding (not used)
++ * PhyRxStatus_0: PhyRxStatus 15:0
++ * PhyRxStatus_1: PhyRxStatus 31:16
++ * PhyRxStatus_2: PhyRxStatus 47:32
++ * PhyRxStatus_3: PhyRxStatus 63:48
++ * PhyRxStatus_4: PhyRxStatus 79:64
++ * PhyRxStatus_5: PhyRxStatus 95:80
++ * RxStatus1: MAC Rx Status
++ * RxStatus2: extended MAC Rx status
++ * RxTSFTime: RxTSFTime time of first MAC symbol + M_PHY_PLCPRX_DLY
++ * RxChan: gain code, channel radio code, and phy type
++ */
++struct d11rxhdr_le {
++	__le16 RxFrameSize;
++	u16 PAD;
++	__le16 PhyRxStatus_0;
++	__le16 PhyRxStatus_1;
++	__le16 PhyRxStatus_2;
++	__le16 PhyRxStatus_3;
++	__le16 PhyRxStatus_4;
++	__le16 PhyRxStatus_5;
++	__le16 RxStatus1;
++	__le16 RxStatus2;
++	__le16 RxTSFTime;
++	__le16 RxChan;
++} __packed;
++
++struct d11rxhdr {
++	u16 RxFrameSize;
++	u16 PAD;
++	u16 PhyRxStatus_0;
++	u16 PhyRxStatus_1;
++	u16 PhyRxStatus_2;
++	u16 PhyRxStatus_3;
++	u16 PhyRxStatus_4;
++	u16 PhyRxStatus_5;
++	u16 RxStatus1;
++	u16 RxStatus2;
++	u16 RxTSFTime;
++	u16 RxChan;
++} __packed;
++
++/* PhyRxStatus_0: */
++/* NPHY only: CCK, OFDM, preN, N */
++#define	PRXS0_FT_MASK		0x0003
++/* NPHY only: clip count adjustment steps by AGC */
++#define	PRXS0_CLIP_MASK		0x000C
++#define	PRXS0_CLIP_SHIFT	2
++/* PHY received a frame with unsupported rate */
++#define	PRXS0_UNSRATE		0x0010
++/* GPHY: rx ant, NPHY: upper sideband */
++#define	PRXS0_RXANT_UPSUBBAND	0x0020
++/* CCK frame only: lost crs during cck frame reception */
++#define	PRXS0_LCRS		0x0040
++/* Short Preamble */
++#define	PRXS0_SHORTH		0x0080
++/* PLCP violation */
++#define	PRXS0_PLCPFV		0x0100
++/* PLCP header integrity check failed */
++#define	PRXS0_PLCPHCF		0x0200
++/* legacy PHY gain control */
++#define	PRXS0_GAIN_CTL		0x4000
++/* NPHY: Antennas used for received frame, bitmask */
++#define PRXS0_ANTSEL_MASK	0xF000
++#define PRXS0_ANTSEL_SHIFT	0x12
++
++/* subfield PRXS0_FT_MASK */
++#define	PRXS0_CCK		0x0000
++/* valid only for G phy, use rxh->RxChan for A phy */
++#define	PRXS0_OFDM		0x0001
++#define	PRXS0_PREN		0x0002
++#define	PRXS0_STDN		0x0003
++
++/* subfield PRXS0_ANTSEL_MASK */
++#define PRXS0_ANTSEL_0		0x0	/* antenna 0 is used */
++#define PRXS0_ANTSEL_1		0x2	/* antenna 1 is used */
++#define PRXS0_ANTSEL_2		0x4	/* antenna 2 is used */
++#define PRXS0_ANTSEL_3		0x8	/* antenna 3 is used */
++
++/* PhyRxStatus_1: */
++#define	PRXS1_JSSI_MASK		0x00FF
++#define	PRXS1_JSSI_SHIFT	0
++#define	PRXS1_SQ_MASK		0xFF00
++#define	PRXS1_SQ_SHIFT		8
++
++/* nphy PhyRxStatus_1: */
++#define PRXS1_nphy_PWR0_MASK	0x00FF
++#define PRXS1_nphy_PWR1_MASK	0xFF00
++
++/* HTPHY Rx Status defines */
++/* htphy PhyRxStatus_0: those bit are overlapped with PhyRxStatus_0 */
++#define PRXS0_BAND	        0x0400	/* 0 = 2.4G, 1 = 5G */
++#define PRXS0_RSVD	        0x0800	/* reserved; set to 0 */
++#define PRXS0_UNUSED	        0xF000	/* unused and not defined; set to 0 */
++
++/* htphy PhyRxStatus_1: */
++/* core enables for {3..0}, 0=disabled, 1=enabled */
++#define PRXS1_HTPHY_CORE_MASK	0x000F
++/* antenna configation */
++#define PRXS1_HTPHY_ANTCFG_MASK	0x00F0
++/* Mixmode PLCP Length low byte mask */
++#define PRXS1_HTPHY_MMPLCPLenL_MASK	0xFF00
++
++/* htphy PhyRxStatus_2: */
++/* Mixmode PLCP Length high byte maskw */
++#define PRXS2_HTPHY_MMPLCPLenH_MASK	0x000F
++/* Mixmode PLCP rate mask */
++#define PRXS2_HTPHY_MMPLCH_RATE_MASK	0x00F0
++/* Rx power on core 0 */
++#define PRXS2_HTPHY_RXPWR_ANT0	0xFF00
++
++/* htphy PhyRxStatus_3: */
++/* Rx power on core 1 */
++#define PRXS3_HTPHY_RXPWR_ANT1	0x00FF
++/* Rx power on core 2 */
++#define PRXS3_HTPHY_RXPWR_ANT2	0xFF00
++
++/* htphy PhyRxStatus_4: */
++/* Rx power on core 3 */
++#define PRXS4_HTPHY_RXPWR_ANT3	0x00FF
++/* Coarse frequency offset */
++#define PRXS4_HTPHY_CFO		0xFF00
++
++/* htphy PhyRxStatus_5: */
++/* Fine frequency offset */
++#define PRXS5_HTPHY_FFO	        0x00FF
++/* Advance Retard */
++#define PRXS5_HTPHY_AR	        0xFF00
++
++#define HTPHY_MMPLCPLen(rxs) \
++	((((rxs)->PhyRxStatus_1 & PRXS1_HTPHY_MMPLCPLenL_MASK) >> 8) | \
++	(((rxs)->PhyRxStatus_2 & PRXS2_HTPHY_MMPLCPLenH_MASK) << 8))
++/* Get Rx power on core 0 */
++#define HTPHY_RXPWR_ANT0(rxs) \
++	((((rxs)->PhyRxStatus_2) & PRXS2_HTPHY_RXPWR_ANT0) >> 8)
++/* Get Rx power on core 1 */
++#define HTPHY_RXPWR_ANT1(rxs) \
++	(((rxs)->PhyRxStatus_3) & PRXS3_HTPHY_RXPWR_ANT1)
++/* Get Rx power on core 2 */
++#define HTPHY_RXPWR_ANT2(rxs) \
++	((((rxs)->PhyRxStatus_3) & PRXS3_HTPHY_RXPWR_ANT2) >> 8)
++
++/* ucode RxStatus1: */
++#define	RXS_BCNSENT		0x8000
++#define	RXS_SECKINDX_MASK	0x07e0
++#define	RXS_SECKINDX_SHIFT	5
++#define	RXS_DECERR		(1 << 4)
++#define	RXS_DECATMPT		(1 << 3)
++/* PAD bytes to make IP data 4 bytes aligned */
++#define	RXS_PBPRES		(1 << 2)
++#define	RXS_RESPFRAMETX		(1 << 1)
++#define	RXS_FCSERR		(1 << 0)
++
++/* ucode RxStatus2: */
++#define RXS_AMSDU_MASK		1
++#define	RXS_AGGTYPE_MASK	0x6
++#define	RXS_AGGTYPE_SHIFT	1
++#define	RXS_PHYRXST_VALID	(1 << 8)
++#define RXS_RXANT_MASK		0x3
++#define RXS_RXANT_SHIFT		12
++
++/* RxChan */
++#define RXS_CHAN_40		0x1000
++#define RXS_CHAN_5G		0x0800
++#define	RXS_CHAN_ID_MASK	0x07f8
++#define	RXS_CHAN_ID_SHIFT	3
++#define	RXS_CHAN_PHYTYPE_MASK	0x0007
++#define	RXS_CHAN_PHYTYPE_SHIFT	0
++
++/* Index of attenuations used during ucode power control. */
++#define M_PWRIND_BLKS	(0x184 * 2)
++#define M_PWRIND_MAP0	(M_PWRIND_BLKS + 0x0)
++#define M_PWRIND_MAP1	(M_PWRIND_BLKS + 0x2)
++#define M_PWRIND_MAP2	(M_PWRIND_BLKS + 0x4)
++#define M_PWRIND_MAP3	(M_PWRIND_BLKS + 0x6)
++/* M_PWRIND_MAP(core) macro */
++#define M_PWRIND_MAP(core)  (M_PWRIND_BLKS + ((core)<<1))
++
++/* PSM SHM variable offsets */
++#define	M_PSM_SOFT_REGS	0x0
++#define	M_BOM_REV_MAJOR	(M_PSM_SOFT_REGS + 0x0)
++#define	M_BOM_REV_MINOR	(M_PSM_SOFT_REGS + 0x2)
++#define	M_UCODE_DBGST	(M_PSM_SOFT_REGS + 0x40) /* ucode debug status code */
++#define	M_UCODE_MACSTAT	(M_PSM_SOFT_REGS + 0xE0) /* macstat counters */
++
++#define M_AGING_THRSH	(0x3e * 2) /* max time waiting for medium before tx */
++#define	M_MBURST_SIZE	(0x40 * 2) /* max frames in a frameburst */
++#define	M_MBURST_TXOP	(0x41 * 2) /* max frameburst TXOP in unit of us */
++#define M_SYNTHPU_DLY	(0x4a * 2) /* pre-wakeup for synthpu, default: 500 */
++#define	M_PRETBTT	(0x4b * 2)
++
++/* offset to the target txpwr */
++#define M_ALT_TXPWR_IDX		(M_PSM_SOFT_REGS + (0x3b * 2))
++#define M_PHY_TX_FLT_PTR	(M_PSM_SOFT_REGS + (0x3d * 2))
++#define M_CTS_DURATION		(M_PSM_SOFT_REGS + (0x5c * 2))
++#define M_LP_RCCAL_OVR		(M_PSM_SOFT_REGS + (0x6b * 2))
++
++/* PKTENG Rx Stats Block */
++#define M_RXSTATS_BLK_PTR	(M_PSM_SOFT_REGS + (0x65 * 2))
++
++/* ucode debug status codes */
++/* not valid really */
++#define	DBGST_INACTIVE		0
++/* after zeroing SHM, before suspending at init */
++#define	DBGST_INIT		1
++/* "normal" state */
++#define	DBGST_ACTIVE		2
++/* suspended */
++#define	DBGST_SUSPENDED		3
++/* asleep (PS mode) */
++#define	DBGST_ASLEEP		4
++
++/* Scratch Reg defs */
++enum _ePsmScratchPadRegDefinitions {
++	S_RSV0 = 0,
++	S_RSV1,
++	S_RSV2,
++
++	/* offset 0x03: scratch registers for Dot11-contants */
++	S_DOT11_CWMIN,		/* CW-minimum */
++	S_DOT11_CWMAX,		/* CW-maximum */
++	S_DOT11_CWCUR,		/* CW-current */
++	S_DOT11_SRC_LMT,	/* short retry count limit */
++	S_DOT11_LRC_LMT,	/* long retry count limit */
++	S_DOT11_DTIMCOUNT,	/* DTIM-count */
++
++	/* offset 0x09: Tx-side scratch registers */
++	S_SEQ_NUM,		/* hardware sequence number reg */
++	S_SEQ_NUM_FRAG,		/* seq num for frags (at the start of MSDU) */
++	S_FRMRETX_CNT,		/* frame retx count */
++	S_SSRC,			/* Station short retry count */
++	S_SLRC,			/* Station long retry count */
++	S_EXP_RSP,		/* Expected response frame */
++	S_OLD_BREM,		/* Remaining backoff ctr */
++	S_OLD_CWWIN,		/* saved-off CW-cur */
++	S_TXECTL,		/* TXE-Ctl word constructed in scr-pad */
++	S_CTXTST,		/* frm type-subtype as read from Tx-descr */
++
++	/* offset 0x13: Rx-side scratch registers */
++	S_RXTST,		/* Type and subtype in Rxframe */
++
++	/* Global state register */
++	S_STREG,		/* state storage actual bit maps below */
++
++	S_TXPWR_SUM,		/* Tx power control: accumulator */
++	S_TXPWR_ITER,		/* Tx power control: iteration */
++	S_RX_FRMTYPE,		/* Rate and PHY type for frames */
++	S_THIS_AGG,		/* Size of this AGG (A-MSDU) */
++
++	S_KEYINDX,
++	S_RXFRMLEN,		/* Receive MPDU length in bytes */
++
++	/* offset 0x1B: Receive TSF time stored in SCR */
++	S_RXTSFTMRVAL_WD3,	/* TSF value at the start of rx */
++	S_RXTSFTMRVAL_WD2,	/* TSF value at the start of rx */
++	S_RXTSFTMRVAL_WD1,	/* TSF value at the start of rx */
++	S_RXTSFTMRVAL_WD0,	/* TSF value at the start of rx */
++	S_RXSSN,		/* Received start seq number for A-MPDU BA */
++	S_RXQOSFLD,		/* Rx-QoS field (if present) */
++
++	/* offset 0x21: Scratch pad regs used in microcode as temp storage */
++	S_TMP0,			/* stmp0 */
++	S_TMP1,			/* stmp1 */
++	S_TMP2,			/* stmp2 */
++	S_TMP3,			/* stmp3 */
++	S_TMP4,			/* stmp4 */
++	S_TMP5,			/* stmp5 */
++	S_PRQPENALTY_CTR,	/* Probe response queue penalty counter */
++	S_ANTCNT,		/* unsuccessful attempts on current ant. */
++	S_SYMBOL,		/* flag for possible symbol ctl frames */
++	S_RXTP,			/* rx frame type */
++	S_STREG2,		/* extra state storage */
++	S_STREG3,		/* even more extra state storage */
++	S_STREG4,		/* ... */
++	S_STREG5,		/* remember to initialize it to zero */
++
++	S_ADJPWR_IDX,
++	S_CUR_PTR,		/* Temp pointer for A-MPDU re-Tx SHM table */
++	S_REVID4,		/* 0x33 */
++	S_INDX,			/* 0x34 */
++	S_ADDR0,		/* 0x35 */
++	S_ADDR1,		/* 0x36 */
++	S_ADDR2,		/* 0x37 */
++	S_ADDR3,		/* 0x38 */
++	S_ADDR4,		/* 0x39 */
++	S_ADDR5,		/* 0x3A */
++	S_TMP6,			/* 0x3B */
++	S_KEYINDX_BU,		/* Backup for Key index */
++	S_MFGTEST_TMP0,		/* Temp regs used for RX test calculations */
++	S_RXESN,		/* Received end sequence number for A-MPDU BA */
++	S_STREG6,		/* 0x3F */
++};
++
++#define S_BEACON_INDX	S_OLD_BREM
++#define S_PRS_INDX	S_OLD_CWWIN
++#define S_PHYTYPE	S_SSRC
++#define S_PHYVER	S_SLRC
++
++/* IHR SLOW_CTRL values */
++#define SLOW_CTRL_PDE		(1 << 0)
++#define SLOW_CTRL_FD		(1 << 8)
++
++/* ucode mac statistic counters in shared memory */
++struct macstat {
++	u16 txallfrm;	/* 0x80 */
++	u16 txrtsfrm;	/* 0x82 */
++	u16 txctsfrm;	/* 0x84 */
++	u16 txackfrm;	/* 0x86 */
++	u16 txdnlfrm;	/* 0x88 */
++	u16 txbcnfrm;	/* 0x8a */
++	u16 txfunfl[8];	/* 0x8c - 0x9b */
++	u16 txtplunfl;	/* 0x9c */
++	u16 txphyerr;	/* 0x9e */
++	u16 pktengrxducast;	/* 0xa0 */
++	u16 pktengrxdmcast;	/* 0xa2 */
++	u16 rxfrmtoolong;	/* 0xa4 */
++	u16 rxfrmtooshrt;	/* 0xa6 */
++	u16 rxinvmachdr;	/* 0xa8 */
++	u16 rxbadfcs;	/* 0xaa */
++	u16 rxbadplcp;	/* 0xac */
++	u16 rxcrsglitch;	/* 0xae */
++	u16 rxstrt;		/* 0xb0 */
++	u16 rxdfrmucastmbss;	/* 0xb2 */
++	u16 rxmfrmucastmbss;	/* 0xb4 */
++	u16 rxcfrmucast;	/* 0xb6 */
++	u16 rxrtsucast;	/* 0xb8 */
++	u16 rxctsucast;	/* 0xba */
++	u16 rxackucast;	/* 0xbc */
++	u16 rxdfrmocast;	/* 0xbe */
++	u16 rxmfrmocast;	/* 0xc0 */
++	u16 rxcfrmocast;	/* 0xc2 */
++	u16 rxrtsocast;	/* 0xc4 */
++	u16 rxctsocast;	/* 0xc6 */
++	u16 rxdfrmmcast;	/* 0xc8 */
++	u16 rxmfrmmcast;	/* 0xca */
++	u16 rxcfrmmcast;	/* 0xcc */
++	u16 rxbeaconmbss;	/* 0xce */
++	u16 rxdfrmucastobss;	/* 0xd0 */
++	u16 rxbeaconobss;	/* 0xd2 */
++	u16 rxrsptmout;	/* 0xd4 */
++	u16 bcntxcancl;	/* 0xd6 */
++	u16 PAD;
++	u16 rxf0ovfl;	/* 0xda */
++	u16 rxf1ovfl;	/* 0xdc */
++	u16 rxf2ovfl;	/* 0xde */
++	u16 txsfovfl;	/* 0xe0 */
++	u16 pmqovfl;		/* 0xe2 */
++	u16 rxcgprqfrm;	/* 0xe4 */
++	u16 rxcgprsqovfl;	/* 0xe6 */
++	u16 txcgprsfail;	/* 0xe8 */
++	u16 txcgprssuc;	/* 0xea */
++	u16 prs_timeout;	/* 0xec */
++	u16 rxnack;
++	u16 frmscons;
++	u16 txnack;
++	u16 txglitch_nack;
++	u16 txburst;		/* 0xf6 # tx bursts */
++	u16 bphy_rxcrsglitch;	/* bphy rx crs glitch */
++	u16 phywatchdog;	/* 0xfa # of phy watchdog events */
++	u16 PAD;
++	u16 bphy_badplcp;	/* bphy bad plcp */
++};
++
++/* dot11 core-specific control flags */
++#define	SICF_PCLKE		0x0004	/* PHY clock enable */
++#define	SICF_PRST		0x0008	/* PHY reset */
++#define	SICF_MPCLKE		0x0010	/* MAC PHY clockcontrol enable */
++#define	SICF_FREF		0x0020	/* PLL FreqRefSelect */
++/* NOTE: the following bw bits only apply when the core is attached
++ * to a NPHY
++ */
++#define	SICF_BWMASK		0x00c0	/* phy clock mask (b6 & b7) */
++#define	SICF_BW40		0x0080	/* 40MHz BW (160MHz phyclk) */
++#define	SICF_BW20		0x0040	/* 20MHz BW (80MHz phyclk) */
++#define	SICF_BW10		0x0000	/* 10MHz BW (40MHz phyclk) */
++#define	SICF_GMODE		0x2000	/* gmode enable */
++
++/* dot11 core-specific status flags */
++#define	SISF_2G_PHY		0x0001	/* 2.4G capable phy */
++#define	SISF_5G_PHY		0x0002	/* 5G capable phy */
++#define	SISF_FCLKA		0x0004	/* FastClkAvailable */
++#define	SISF_DB_PHY		0x0008	/* Dualband phy */
++
++/* === End of MAC reg, Beginning of PHY(b/a/g/n) reg === */
++/* radio and LPPHY regs are separated */
++
++#define	BPHY_REG_OFT_BASE	0x0
++/* offsets for indirect access to bphy registers */
++#define	BPHY_BB_CONFIG		0x01
++#define	BPHY_ADCBIAS		0x02
++#define	BPHY_ANACORE		0x03
++#define	BPHY_PHYCRSTH		0x06
++#define	BPHY_TEST		0x0a
++#define	BPHY_PA_TX_TO		0x10
++#define	BPHY_SYNTH_DC_TO	0x11
++#define	BPHY_PA_TX_TIME_UP	0x12
++#define	BPHY_RX_FLTR_TIME_UP	0x13
++#define	BPHY_TX_POWER_OVERRIDE	0x14
++#define	BPHY_RF_OVERRIDE	0x15
++#define	BPHY_RF_TR_LOOKUP1	0x16
++#define	BPHY_RF_TR_LOOKUP2	0x17
++#define	BPHY_COEFFS		0x18
++#define	BPHY_PLL_OUT		0x19
++#define	BPHY_REFRESH_MAIN	0x1a
++#define	BPHY_REFRESH_TO0	0x1b
++#define	BPHY_REFRESH_TO1	0x1c
++#define	BPHY_RSSI_TRESH		0x20
++#define	BPHY_IQ_TRESH_HH	0x21
++#define	BPHY_IQ_TRESH_H		0x22
++#define	BPHY_IQ_TRESH_L		0x23
++#define	BPHY_IQ_TRESH_LL	0x24
++#define	BPHY_GAIN		0x25
++#define	BPHY_LNA_GAIN_RANGE	0x26
++#define	BPHY_JSSI		0x27
++#define	BPHY_TSSI_CTL		0x28
++#define	BPHY_TSSI		0x29
++#define	BPHY_TR_LOSS_CTL	0x2a
++#define	BPHY_LO_LEAKAGE		0x2b
++#define	BPHY_LO_RSSI_ACC	0x2c
++#define	BPHY_LO_IQMAG_ACC	0x2d
++#define	BPHY_TX_DC_OFF1		0x2e
++#define	BPHY_TX_DC_OFF2		0x2f
++#define	BPHY_PEAK_CNT_THRESH	0x30
++#define	BPHY_FREQ_OFFSET	0x31
++#define	BPHY_DIVERSITY_CTL	0x32
++#define	BPHY_PEAK_ENERGY_LO	0x33
++#define	BPHY_PEAK_ENERGY_HI	0x34
++#define	BPHY_SYNC_CTL		0x35
++#define	BPHY_TX_PWR_CTRL	0x36
++#define BPHY_TX_EST_PWR		0x37
++#define	BPHY_STEP		0x38
++#define	BPHY_WARMUP		0x39
++#define	BPHY_LMS_CFF_READ	0x3a
++#define	BPHY_LMS_COEFF_I	0x3b
++#define	BPHY_LMS_COEFF_Q	0x3c
++#define	BPHY_SIG_POW		0x3d
++#define	BPHY_RFDC_CANCEL_CTL	0x3e
++#define	BPHY_HDR_TYPE		0x40
++#define	BPHY_SFD_TO		0x41
++#define	BPHY_SFD_CTL		0x42
++#define	BPHY_DEBUG		0x43
++#define	BPHY_RX_DELAY_COMP	0x44
++#define	BPHY_CRS_DROP_TO	0x45
++#define	BPHY_SHORT_SFD_NZEROS	0x46
++#define	BPHY_DSSS_COEFF1	0x48
++#define	BPHY_DSSS_COEFF2	0x49
++#define	BPHY_CCK_COEFF1		0x4a
++#define	BPHY_CCK_COEFF2		0x4b
++#define	BPHY_TR_CORR		0x4c
++#define	BPHY_ANGLE_SCALE	0x4d
++#define	BPHY_TX_PWR_BASE_IDX	0x4e
++#define	BPHY_OPTIONAL_MODES2	0x4f
++#define	BPHY_CCK_LMS_STEP	0x50
++#define	BPHY_BYPASS		0x51
++#define	BPHY_CCK_DELAY_LONG	0x52
++#define	BPHY_CCK_DELAY_SHORT	0x53
++#define	BPHY_PPROC_CHAN_DELAY	0x54
++#define	BPHY_DDFS_ENABLE	0x58
++#define	BPHY_PHASE_SCALE	0x59
++#define	BPHY_FREQ_CONTROL	0x5a
++#define	BPHY_LNA_GAIN_RANGE_10	0x5b
++#define	BPHY_LNA_GAIN_RANGE_32	0x5c
++#define	BPHY_OPTIONAL_MODES	0x5d
++#define	BPHY_RX_STATUS2		0x5e
++#define	BPHY_RX_STATUS3		0x5f
++#define	BPHY_DAC_CONTROL	0x60
++#define	BPHY_ANA11G_FILT_CTRL	0x62
++#define	BPHY_REFRESH_CTRL	0x64
++#define	BPHY_RF_OVERRIDE2	0x65
++#define	BPHY_SPUR_CANCEL_CTRL	0x66
++#define	BPHY_FINE_DIGIGAIN_CTRL	0x67
++#define	BPHY_RSSI_LUT		0x88
++#define	BPHY_RSSI_LUT_END	0xa7
++#define	BPHY_TSSI_LUT		0xa8
++#define	BPHY_TSSI_LUT_END	0xc7
++#define	BPHY_TSSI2PWR_LUT	0x380
++#define	BPHY_TSSI2PWR_LUT_END	0x39f
++#define	BPHY_LOCOMP_LUT		0x3a0
++#define	BPHY_LOCOMP_LUT_END	0x3bf
++#define	BPHY_TXGAIN_LUT		0x3c0
++#define	BPHY_TXGAIN_LUT_END	0x3ff
++
++/* Bits in BB_CONFIG: */
++#define	PHY_BBC_ANT_MASK	0x0180
++#define	PHY_BBC_ANT_SHIFT	7
++#define	BB_DARWIN		0x1000
++#define BBCFG_RESETCCA		0x4000
++#define BBCFG_RESETRX		0x8000
++
++/* Bits in phytest(0x0a): */
++#define	TST_DDFS		0x2000
++#define	TST_TXFILT1		0x0800
++#define	TST_UNSCRAM		0x0400
++#define	TST_CARR_SUPP		0x0200
++#define	TST_DC_COMP_LOOP	0x0100
++#define	TST_LOOPBACK		0x0080
++#define	TST_TXFILT0		0x0040
++#define	TST_TXTEST_ENABLE	0x0020
++#define	TST_TXTEST_RATE		0x0018
++#define	TST_TXTEST_PHASE	0x0007
++
++/* phytest txTestRate values */
++#define	TST_TXTEST_RATE_1MBPS	0
++#define	TST_TXTEST_RATE_2MBPS	1
++#define	TST_TXTEST_RATE_5_5MBPS	2
++#define	TST_TXTEST_RATE_11MBPS	3
++#define	TST_TXTEST_RATE_SHIFT	3
++
++#define SHM_BYT_CNT	0x2	/* IHR location */
++#define MAX_BYT_CNT	0x600	/* Maximum frame len */
++
++struct d11cnt {
++	u32 txfrag;
++	u32 txmulti;
++	u32 txfail;
++	u32 txretry;
++	u32 txretrie;
++	u32 rxdup;
++	u32 txrts;
++	u32 txnocts;
++	u32 txnoack;
++	u32 rxfrag;
++	u32 rxmulti;
++	u32 rxcrc;
++	u32 txfrmsnt;
++	u32 rxundec;
++};
++
++#endif				/* _BRCM_D11_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/dma.c b/drivers/net/wireless/brcm80211/brcmsmac/dma.c
+new file mode 100644
+index 0000000..e898266
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/dma.c
+@@ -0,0 +1,1444 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++#undef pr_fmt
++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
++
++#include <linux/printk.h>
++#include <linux/slab.h>
++#include <linux/delay.h>
++#include <linux/pci.h>
++
++#include <brcmu_utils.h>
++#include <aiutils.h>
++#include "types.h"
++#include "dma.h"
++#include "soc.h"
++
++/*
++ * dma register field offset calculation
++ */
++#define DMA64REGOFFS(field)		offsetof(struct dma64regs, field)
++#define DMA64TXREGOFFS(di, field)	(di->d64txregbase + DMA64REGOFFS(field))
++#define DMA64RXREGOFFS(di, field)	(di->d64rxregbase + DMA64REGOFFS(field))
++
++/*
++ * DMA hardware requires each descriptor ring to be 8kB aligned, and fit within
++ * a contiguous 8kB physical address.
++ */
++#define D64RINGALIGN_BITS	13
++#define	D64MAXRINGSZ		(1 << D64RINGALIGN_BITS)
++#define	D64RINGALIGN		(1 << D64RINGALIGN_BITS)
++
++#define	D64MAXDD	(D64MAXRINGSZ / sizeof(struct dma64desc))
++
++/* transmit channel control */
++#define	D64_XC_XE		0x00000001	/* transmit enable */
++#define	D64_XC_SE		0x00000002	/* transmit suspend request */
++#define	D64_XC_LE		0x00000004	/* loopback enable */
++#define	D64_XC_FL		0x00000010	/* flush request */
++#define	D64_XC_PD		0x00000800	/* parity check disable */
++#define	D64_XC_AE		0x00030000	/* address extension bits */
++#define	D64_XC_AE_SHIFT		16
++
++/* transmit descriptor table pointer */
++#define	D64_XP_LD_MASK		0x00000fff	/* last valid descriptor */
++
++/* transmit channel status */
++#define	D64_XS0_CD_MASK		0x00001fff	/* current descriptor pointer */
++#define	D64_XS0_XS_MASK		0xf0000000	/* transmit state */
++#define	D64_XS0_XS_SHIFT		28
++#define	D64_XS0_XS_DISABLED	0x00000000	/* disabled */
++#define	D64_XS0_XS_ACTIVE	0x10000000	/* active */
++#define	D64_XS0_XS_IDLE		0x20000000	/* idle wait */
++#define	D64_XS0_XS_STOPPED	0x30000000	/* stopped */
++#define	D64_XS0_XS_SUSP		0x40000000	/* suspend pending */
++
++#define	D64_XS1_AD_MASK		0x00001fff	/* active descriptor */
++#define	D64_XS1_XE_MASK		0xf0000000	/* transmit errors */
++#define	D64_XS1_XE_SHIFT		28
++#define	D64_XS1_XE_NOERR	0x00000000	/* no error */
++#define	D64_XS1_XE_DPE		0x10000000	/* descriptor protocol error */
++#define	D64_XS1_XE_DFU		0x20000000	/* data fifo underrun */
++#define	D64_XS1_XE_DTE		0x30000000	/* data transfer error */
++#define	D64_XS1_XE_DESRE	0x40000000	/* descriptor read error */
++#define	D64_XS1_XE_COREE	0x50000000	/* core error */
++
++/* receive channel control */
++/* receive enable */
++#define	D64_RC_RE		0x00000001
++/* receive frame offset */
++#define	D64_RC_RO_MASK		0x000000fe
++#define	D64_RC_RO_SHIFT		1
++/* direct fifo receive (pio) mode */
++#define	D64_RC_FM		0x00000100
++/* separate rx header descriptor enable */
++#define	D64_RC_SH		0x00000200
++/* overflow continue */
++#define	D64_RC_OC		0x00000400
++/* parity check disable */
++#define	D64_RC_PD		0x00000800
++/* address extension bits */
++#define	D64_RC_AE		0x00030000
++#define	D64_RC_AE_SHIFT		16
++
++/* flags for dma controller */
++/* partity enable */
++#define DMA_CTRL_PEN		(1 << 0)
++/* rx overflow continue */
++#define DMA_CTRL_ROC		(1 << 1)
++/* allow rx scatter to multiple descriptors */
++#define DMA_CTRL_RXMULTI	(1 << 2)
++/* Unframed Rx/Tx data */
++#define DMA_CTRL_UNFRAMED	(1 << 3)
++
++/* receive descriptor table pointer */
++#define	D64_RP_LD_MASK		0x00000fff	/* last valid descriptor */
++
++/* receive channel status */
++#define	D64_RS0_CD_MASK		0x00001fff	/* current descriptor pointer */
++#define	D64_RS0_RS_MASK		0xf0000000	/* receive state */
++#define	D64_RS0_RS_SHIFT		28
++#define	D64_RS0_RS_DISABLED	0x00000000	/* disabled */
++#define	D64_RS0_RS_ACTIVE	0x10000000	/* active */
++#define	D64_RS0_RS_IDLE		0x20000000	/* idle wait */
++#define	D64_RS0_RS_STOPPED	0x30000000	/* stopped */
++#define	D64_RS0_RS_SUSP		0x40000000	/* suspend pending */
++
++#define	D64_RS1_AD_MASK		0x0001ffff	/* active descriptor */
++#define	D64_RS1_RE_MASK		0xf0000000	/* receive errors */
++#define	D64_RS1_RE_SHIFT		28
++#define	D64_RS1_RE_NOERR	0x00000000	/* no error */
++#define	D64_RS1_RE_DPO		0x10000000	/* descriptor protocol error */
++#define	D64_RS1_RE_DFU		0x20000000	/* data fifo overflow */
++#define	D64_RS1_RE_DTE		0x30000000	/* data transfer error */
++#define	D64_RS1_RE_DESRE	0x40000000	/* descriptor read error */
++#define	D64_RS1_RE_COREE	0x50000000	/* core error */
++
++/* fifoaddr */
++#define	D64_FA_OFF_MASK		0xffff	/* offset */
++#define	D64_FA_SEL_MASK		0xf0000	/* select */
++#define	D64_FA_SEL_SHIFT	16
++#define	D64_FA_SEL_XDD		0x00000	/* transmit dma data */
++#define	D64_FA_SEL_XDP		0x10000	/* transmit dma pointers */
++#define	D64_FA_SEL_RDD		0x40000	/* receive dma data */
++#define	D64_FA_SEL_RDP		0x50000	/* receive dma pointers */
++#define	D64_FA_SEL_XFD		0x80000	/* transmit fifo data */
++#define	D64_FA_SEL_XFP		0x90000	/* transmit fifo pointers */
++#define	D64_FA_SEL_RFD		0xc0000	/* receive fifo data */
++#define	D64_FA_SEL_RFP		0xd0000	/* receive fifo pointers */
++#define	D64_FA_SEL_RSD		0xe0000	/* receive frame status data */
++#define	D64_FA_SEL_RSP		0xf0000	/* receive frame status pointers */
++
++/* descriptor control flags 1 */
++#define D64_CTRL_COREFLAGS	0x0ff00000	/* core specific flags */
++#define	D64_CTRL1_EOT		((u32)1 << 28)	/* end of descriptor table */
++#define	D64_CTRL1_IOC		((u32)1 << 29)	/* interrupt on completion */
++#define	D64_CTRL1_EOF		((u32)1 << 30)	/* end of frame */
++#define	D64_CTRL1_SOF		((u32)1 << 31)	/* start of frame */
++
++/* descriptor control flags 2 */
++/* buffer byte count. real data len must <= 16KB */
++#define	D64_CTRL2_BC_MASK	0x00007fff
++/* address extension bits */
++#define	D64_CTRL2_AE		0x00030000
++#define	D64_CTRL2_AE_SHIFT	16
++/* parity bit */
++#define D64_CTRL2_PARITY	0x00040000
++
++/* control flags in the range [27:20] are core-specific and not defined here */
++#define	D64_CTRL_CORE_MASK	0x0ff00000
++
++#define D64_RX_FRM_STS_LEN	0x0000ffff	/* frame length mask */
++#define D64_RX_FRM_STS_OVFL	0x00800000	/* RxOverFlow */
++#define D64_RX_FRM_STS_DSCRCNT	0x0f000000  /* no. of descriptors used - 1 */
++#define D64_RX_FRM_STS_DATATYPE	0xf0000000	/* core-dependent data type */
++
++/*
++ * packet headroom necessary to accommodate the largest header
++ * in the system, (i.e TXOFF). By doing, we avoid the need to
++ * allocate an extra buffer for the header when bridging to WL.
++ * There is a compile time check in wlc.c which ensure that this
++ * value is at least as big as TXOFF. This value is used in
++ * dma_rxfill().
++ */
++
++#define BCMEXTRAHDROOM 172
++
++/* debug/trace */
++#ifdef DEBUG
++#define	DMA_ERROR(fmt, ...)					\
++do {								\
++	if (*di->msg_level & 1)					\
++		pr_debug("%s: " fmt, __func__, ##__VA_ARGS__);	\
++} while (0)
++#define	DMA_TRACE(fmt, ...)					\
++do {								\
++	if (*di->msg_level & 2)					\
++		pr_debug("%s: " fmt, __func__, ##__VA_ARGS__);	\
++} while (0)
++#else
++#define	DMA_ERROR(fmt, ...)			\
++	no_printk(fmt, ##__VA_ARGS__)
++#define	DMA_TRACE(fmt, ...)			\
++	no_printk(fmt, ##__VA_ARGS__)
++#endif				/* DEBUG */
++
++#define	DMA_NONE(fmt, ...)			\
++	no_printk(fmt, ##__VA_ARGS__)
++
++#define	MAXNAMEL	8	/* 8 char names */
++
++/* macros to convert between byte offsets and indexes */
++#define	B2I(bytes, type)	((bytes) / sizeof(type))
++#define	I2B(index, type)	((index) * sizeof(type))
++
++#define	PCI32ADDR_HIGH		0xc0000000	/* address[31:30] */
++#define	PCI32ADDR_HIGH_SHIFT	30	/* address[31:30] */
++
++#define	PCI64ADDR_HIGH		0x80000000	/* address[63] */
++#define	PCI64ADDR_HIGH_SHIFT	31	/* address[63] */
++
++/*
++ * DMA Descriptor
++ * Descriptors are only read by the hardware, never written back.
++ */
++struct dma64desc {
++	__le32 ctrl1;	/* misc control bits & bufcount */
++	__le32 ctrl2;	/* buffer count and address extension */
++	__le32 addrlow;	/* memory address of the date buffer, bits 31:0 */
++	__le32 addrhigh; /* memory address of the date buffer, bits 63:32 */
++};
++
++/* dma engine software state */
++struct dma_info {
++	struct dma_pub dma; /* exported structure */
++	uint *msg_level;	/* message level pointer */
++	char name[MAXNAMEL];	/* callers name for diag msgs */
++
++	struct bcma_device *core;
++	struct device *dmadev;
++
++	bool dma64;	/* this dma engine is operating in 64-bit mode */
++	bool addrext;	/* this dma engine supports DmaExtendedAddrChanges */
++
++	/* 64-bit dma tx engine registers */
++	uint d64txregbase;
++	/* 64-bit dma rx engine registers */
++	uint d64rxregbase;
++	/* pointer to dma64 tx descriptor ring */
++	struct dma64desc *txd64;
++	/* pointer to dma64 rx descriptor ring */
++	struct dma64desc *rxd64;
++
++	u16 dmadesc_align;	/* alignment requirement for dma descriptors */
++
++	u16 ntxd;		/* # tx descriptors tunable */
++	u16 txin;		/* index of next descriptor to reclaim */
++	u16 txout;		/* index of next descriptor to post */
++	/* pointer to parallel array of pointers to packets */
++	struct sk_buff **txp;
++	/* Aligned physical address of descriptor ring */
++	dma_addr_t txdpa;
++	/* Original physical address of descriptor ring */
++	dma_addr_t txdpaorig;
++	u16 txdalign;	/* #bytes added to alloc'd mem to align txd */
++	u32 txdalloc;	/* #bytes allocated for the ring */
++	u32 xmtptrbase;	/* When using unaligned descriptors, the ptr register
++			 * is not just an index, it needs all 13 bits to be
++			 * an offset from the addr register.
++			 */
++
++	u16 nrxd;	/* # rx descriptors tunable */
++	u16 rxin;	/* index of next descriptor to reclaim */
++	u16 rxout;	/* index of next descriptor to post */
++	/* pointer to parallel array of pointers to packets */
++	struct sk_buff **rxp;
++	/* Aligned physical address of descriptor ring */
++	dma_addr_t rxdpa;
++	/* Original physical address of descriptor ring */
++	dma_addr_t rxdpaorig;
++	u16 rxdalign;	/* #bytes added to alloc'd mem to align rxd */
++	u32 rxdalloc;	/* #bytes allocated for the ring */
++	u32 rcvptrbase;	/* Base for ptr reg when using unaligned descriptors */
++
++	/* tunables */
++	unsigned int rxbufsize;	/* rx buffer size in bytes, not including
++				 * the extra headroom
++				 */
++	uint rxextrahdrroom;	/* extra rx headroom, reverseved to assist upper
++				 * stack, e.g. some rx pkt buffers will be
++				 * bridged to tx side without byte copying.
++				 * The extra headroom needs to be large enough
++				 * to fit txheader needs. Some dongle driver may
++				 * not need it.
++				 */
++	uint nrxpost;		/* # rx buffers to keep posted */
++	unsigned int rxoffset;	/* rxcontrol offset */
++	/* add to get dma address of descriptor ring, low 32 bits */
++	uint ddoffsetlow;
++	/*   high 32 bits */
++	uint ddoffsethigh;
++	/* add to get dma address of data buffer, low 32 bits */
++	uint dataoffsetlow;
++	/*   high 32 bits */
++	uint dataoffsethigh;
++	/* descriptor base need to be aligned or not */
++	bool aligndesc_4k;
++};
++
++/*
++ * default dma message level (if input msg_level
++ * pointer is null in dma_attach())
++ */
++static uint dma_msg_level;
++
++/* Check for odd number of 1's */
++static u32 parity32(__le32 data)
++{
++	/* no swap needed for counting 1's */
++	u32 par_data = *(u32 *)&data;
++
++	par_data ^= par_data >> 16;
++	par_data ^= par_data >> 8;
++	par_data ^= par_data >> 4;
++	par_data ^= par_data >> 2;
++	par_data ^= par_data >> 1;
++
++	return par_data & 1;
++}
++
++static bool dma64_dd_parity(struct dma64desc *dd)
++{
++	return parity32(dd->addrlow ^ dd->addrhigh ^ dd->ctrl1 ^ dd->ctrl2);
++}
++
++/* descriptor bumping functions */
++
++static uint xxd(uint x, uint n)
++{
++	return x & (n - 1); /* faster than %, but n must be power of 2 */
++}
++
++static uint txd(struct dma_info *di, uint x)
++{
++	return xxd(x, di->ntxd);
++}
++
++static uint rxd(struct dma_info *di, uint x)
++{
++	return xxd(x, di->nrxd);
++}
++
++static uint nexttxd(struct dma_info *di, uint i)
++{
++	return txd(di, i + 1);
++}
++
++static uint prevtxd(struct dma_info *di, uint i)
++{
++	return txd(di, i - 1);
++}
++
++static uint nextrxd(struct dma_info *di, uint i)
++{
++	return txd(di, i + 1);
++}
++
++static uint ntxdactive(struct dma_info *di, uint h, uint t)
++{
++	return txd(di, t-h);
++}
++
++static uint nrxdactive(struct dma_info *di, uint h, uint t)
++{
++	return rxd(di, t-h);
++}
++
++static uint _dma_ctrlflags(struct dma_info *di, uint mask, uint flags)
++{
++	uint dmactrlflags;
++
++	if (di == NULL) {
++		DMA_ERROR("NULL dma handle\n");
++		return 0;
++	}
++
++	dmactrlflags = di->dma.dmactrlflags;
++	dmactrlflags &= ~mask;
++	dmactrlflags |= flags;
++
++	/* If trying to enable parity, check if parity is actually supported */
++	if (dmactrlflags & DMA_CTRL_PEN) {
++		u32 control;
++
++		control = bcma_read32(di->core, DMA64TXREGOFFS(di, control));
++		bcma_write32(di->core, DMA64TXREGOFFS(di, control),
++		      control | D64_XC_PD);
++		if (bcma_read32(di->core, DMA64TXREGOFFS(di, control)) &
++		    D64_XC_PD)
++			/* We *can* disable it so it is supported,
++			 * restore control register
++			 */
++			bcma_write32(di->core, DMA64TXREGOFFS(di, control),
++				     control);
++		else
++			/* Not supported, don't allow it to be enabled */
++			dmactrlflags &= ~DMA_CTRL_PEN;
++	}
++
++	di->dma.dmactrlflags = dmactrlflags;
++
++	return dmactrlflags;
++}
++
++static bool _dma64_addrext(struct dma_info *di, uint ctrl_offset)
++{
++	u32 w;
++	bcma_set32(di->core, ctrl_offset, D64_XC_AE);
++	w = bcma_read32(di->core, ctrl_offset);
++	bcma_mask32(di->core, ctrl_offset, ~D64_XC_AE);
++	return (w & D64_XC_AE) == D64_XC_AE;
++}
++
++/*
++ * return true if this dma engine supports DmaExtendedAddrChanges,
++ * otherwise false
++ */
++static bool _dma_isaddrext(struct dma_info *di)
++{
++	/* DMA64 supports full 32- or 64-bit operation. AE is always valid */
++
++	/* not all tx or rx channel are available */
++	if (di->d64txregbase != 0) {
++		if (!_dma64_addrext(di, DMA64TXREGOFFS(di, control)))
++			DMA_ERROR("%s: DMA64 tx doesn't have AE set\n",
++				  di->name);
++		return true;
++	} else if (di->d64rxregbase != 0) {
++		if (!_dma64_addrext(di, DMA64RXREGOFFS(di, control)))
++			DMA_ERROR("%s: DMA64 rx doesn't have AE set\n",
++				  di->name);
++		return true;
++	}
++
++	return false;
++}
++
++static bool _dma_descriptor_align(struct dma_info *di)
++{
++	u32 addrl;
++
++	/* Check to see if the descriptors need to be aligned on 4K/8K or not */
++	if (di->d64txregbase != 0) {
++		bcma_write32(di->core, DMA64TXREGOFFS(di, addrlow), 0xff0);
++		addrl = bcma_read32(di->core, DMA64TXREGOFFS(di, addrlow));
++		if (addrl != 0)
++			return false;
++	} else if (di->d64rxregbase != 0) {
++		bcma_write32(di->core, DMA64RXREGOFFS(di, addrlow), 0xff0);
++		addrl = bcma_read32(di->core, DMA64RXREGOFFS(di, addrlow));
++		if (addrl != 0)
++			return false;
++	}
++	return true;
++}
++
++/*
++ * Descriptor table must start at the DMA hardware dictated alignment, so
++ * allocated memory must be large enough to support this requirement.
++ */
++static void *dma_alloc_consistent(struct dma_info *di, uint size,
++				  u16 align_bits, uint *alloced,
++				  dma_addr_t *pap)
++{
++	if (align_bits) {
++		u16 align = (1 << align_bits);
++		if (!IS_ALIGNED(PAGE_SIZE, align))
++			size += align;
++		*alloced = size;
++	}
++	return dma_alloc_coherent(di->dmadev, size, pap, GFP_ATOMIC);
++}
++
++static
++u8 dma_align_sizetobits(uint size)
++{
++	u8 bitpos = 0;
++	while (size >>= 1)
++		bitpos++;
++	return bitpos;
++}
++
++/* This function ensures that the DMA descriptor ring will not get allocated
++ * across Page boundary. If the allocation is done across the page boundary
++ * at the first time, then it is freed and the allocation is done at
++ * descriptor ring size aligned location. This will ensure that the ring will
++ * not cross page boundary
++ */
++static void *dma_ringalloc(struct dma_info *di, u32 boundary, uint size,
++			   u16 *alignbits, uint *alloced,
++			   dma_addr_t *descpa)
++{
++	void *va;
++	u32 desc_strtaddr;
++	u32 alignbytes = 1 << *alignbits;
++
++	va = dma_alloc_consistent(di, size, *alignbits, alloced, descpa);
++
++	if (NULL == va)
++		return NULL;
++
++	desc_strtaddr = (u32) roundup((unsigned long)va, alignbytes);
++	if (((desc_strtaddr + size - 1) & boundary) != (desc_strtaddr
++							& boundary)) {
++		*alignbits = dma_align_sizetobits(size);
++		dma_free_coherent(di->dmadev, size, va, *descpa);
++		va = dma_alloc_consistent(di, size, *alignbits,
++			alloced, descpa);
++	}
++	return va;
++}
++
++static bool dma64_alloc(struct dma_info *di, uint direction)
++{
++	u16 size;
++	uint ddlen;
++	void *va;
++	uint alloced = 0;
++	u16 align;
++	u16 align_bits;
++
++	ddlen = sizeof(struct dma64desc);
++
++	size = (direction == DMA_TX) ? (di->ntxd * ddlen) : (di->nrxd * ddlen);
++	align_bits = di->dmadesc_align;
++	align = (1 << align_bits);
++
++	if (direction == DMA_TX) {
++		va = dma_ringalloc(di, D64RINGALIGN, size, &align_bits,
++			&alloced, &di->txdpaorig);
++		if (va == NULL) {
++			DMA_ERROR("%s: DMA_ALLOC_CONSISTENT(ntxd) failed\n",
++				  di->name);
++			return false;
++		}
++		align = (1 << align_bits);
++		di->txd64 = (struct dma64desc *)
++					roundup((unsigned long)va, align);
++		di->txdalign = (uint) ((s8 *)di->txd64 - (s8 *) va);
++		di->txdpa = di->txdpaorig + di->txdalign;
++		di->txdalloc = alloced;
++	} else {
++		va = dma_ringalloc(di, D64RINGALIGN, size, &align_bits,
++			&alloced, &di->rxdpaorig);
++		if (va == NULL) {
++			DMA_ERROR("%s: DMA_ALLOC_CONSISTENT(nrxd) failed\n",
++				  di->name);
++			return false;
++		}
++		align = (1 << align_bits);
++		di->rxd64 = (struct dma64desc *)
++					roundup((unsigned long)va, align);
++		di->rxdalign = (uint) ((s8 *)di->rxd64 - (s8 *) va);
++		di->rxdpa = di->rxdpaorig + di->rxdalign;
++		di->rxdalloc = alloced;
++	}
++
++	return true;
++}
++
++static bool _dma_alloc(struct dma_info *di, uint direction)
++{
++	return dma64_alloc(di, direction);
++}
++
++struct dma_pub *dma_attach(char *name, struct si_pub *sih,
++			   struct bcma_device *core,
++			   uint txregbase, uint rxregbase, uint ntxd, uint nrxd,
++			   uint rxbufsize, int rxextheadroom,
++			   uint nrxpost, uint rxoffset, uint *msg_level)
++{
++	struct dma_info *di;
++	u8 rev = core->id.rev;
++	uint size;
++
++	/* allocate private info structure */
++	di = kzalloc(sizeof(struct dma_info), GFP_ATOMIC);
++	if (di == NULL)
++		return NULL;
++
++	di->msg_level = msg_level ? msg_level : &dma_msg_level;
++
++
++	di->dma64 =
++		((bcma_aread32(core, BCMA_IOST) & SISF_DMA64) == SISF_DMA64);
++
++	/* init dma reg info */
++	di->core = core;
++	di->d64txregbase = txregbase;
++	di->d64rxregbase = rxregbase;
++
++	/*
++	 * Default flags (which can be changed by the driver calling
++	 * dma_ctrlflags before enable): For backwards compatibility
++	 * both Rx Overflow Continue and Parity are DISABLED.
++	 */
++	_dma_ctrlflags(di, DMA_CTRL_ROC | DMA_CTRL_PEN, 0);
++
++	DMA_TRACE("%s: %s flags 0x%x ntxd %d nrxd %d "
++		  "rxbufsize %d rxextheadroom %d nrxpost %d rxoffset %d "
++		  "txregbase %u rxregbase %u\n", name, "DMA64",
++		  di->dma.dmactrlflags, ntxd, nrxd, rxbufsize,
++		  rxextheadroom, nrxpost, rxoffset, txregbase, rxregbase);
++
++	/* make a private copy of our callers name */
++	strncpy(di->name, name, MAXNAMEL);
++	di->name[MAXNAMEL - 1] = '\0';
++
++	di->dmadev = core->dma_dev;
++
++	/* save tunables */
++	di->ntxd = (u16) ntxd;
++	di->nrxd = (u16) nrxd;
++
++	/* the actual dma size doesn't include the extra headroom */
++	di->rxextrahdrroom =
++	    (rxextheadroom == -1) ? BCMEXTRAHDROOM : rxextheadroom;
++	if (rxbufsize > BCMEXTRAHDROOM)
++		di->rxbufsize = (u16) (rxbufsize - di->rxextrahdrroom);
++	else
++		di->rxbufsize = (u16) rxbufsize;
++
++	di->nrxpost = (u16) nrxpost;
++	di->rxoffset = (u8) rxoffset;
++
++	/*
++	 * figure out the DMA physical address offset for dd and data
++	 *     PCI/PCIE: they map silicon backplace address to zero
++	 *     based memory, need offset
++	 *     Other bus: use zero SI_BUS BIGENDIAN kludge: use sdram
++	 *     swapped region for data buffer, not descriptor
++	 */
++	di->ddoffsetlow = 0;
++	di->dataoffsetlow = 0;
++	/* add offset for pcie with DMA64 bus */
++	di->ddoffsetlow = 0;
++	di->ddoffsethigh = SI_PCIE_DMA_H32;
++	di->dataoffsetlow = di->ddoffsetlow;
++	di->dataoffsethigh = di->ddoffsethigh;
++	/* WAR64450 : DMACtl.Addr ext fields are not supported in SDIOD core. */
++	if ((core->id.id == SDIOD_CORE_ID)
++	    && ((rev > 0) && (rev <= 2)))
++		di->addrext = false;
++	else if ((core->id.id == I2S_CORE_ID) &&
++		 ((rev == 0) || (rev == 1)))
++		di->addrext = false;
++	else
++		di->addrext = _dma_isaddrext(di);
++
++	/* does the descriptor need to be aligned and if yes, on 4K/8K or not */
++	di->aligndesc_4k = _dma_descriptor_align(di);
++	if (di->aligndesc_4k) {
++		di->dmadesc_align = D64RINGALIGN_BITS;
++		if ((ntxd < D64MAXDD / 2) && (nrxd < D64MAXDD / 2))
++			/* for smaller dd table, HW relax alignment reqmnt */
++			di->dmadesc_align = D64RINGALIGN_BITS - 1;
++	} else {
++		di->dmadesc_align = 4;	/* 16 byte alignment */
++	}
++
++	DMA_NONE("DMA descriptor align_needed %d, align %d\n",
++		 di->aligndesc_4k, di->dmadesc_align);
++
++	/* allocate tx packet pointer vector */
++	if (ntxd) {
++		size = ntxd * sizeof(void *);
++		di->txp = kzalloc(size, GFP_ATOMIC);
++		if (di->txp == NULL)
++			goto fail;
++	}
++
++	/* allocate rx packet pointer vector */
++	if (nrxd) {
++		size = nrxd * sizeof(void *);
++		di->rxp = kzalloc(size, GFP_ATOMIC);
++		if (di->rxp == NULL)
++			goto fail;
++	}
++
++	/*
++	 * allocate transmit descriptor ring, only need ntxd descriptors
++	 * but it must be aligned
++	 */
++	if (ntxd) {
++		if (!_dma_alloc(di, DMA_TX))
++			goto fail;
++	}
++
++	/*
++	 * allocate receive descriptor ring, only need nrxd descriptors
++	 * but it must be aligned
++	 */
++	if (nrxd) {
++		if (!_dma_alloc(di, DMA_RX))
++			goto fail;
++	}
++
++	if ((di->ddoffsetlow != 0) && !di->addrext) {
++		if (di->txdpa > SI_PCI_DMA_SZ) {
++			DMA_ERROR("%s: txdpa 0x%x: addrext not supported\n",
++				  di->name, (u32)di->txdpa);
++			goto fail;
++		}
++		if (di->rxdpa > SI_PCI_DMA_SZ) {
++			DMA_ERROR("%s: rxdpa 0x%x: addrext not supported\n",
++				  di->name, (u32)di->rxdpa);
++			goto fail;
++		}
++	}
++
++	DMA_TRACE("ddoffsetlow 0x%x ddoffsethigh 0x%x dataoffsetlow 0x%x dataoffsethigh 0x%x addrext %d\n",
++		  di->ddoffsetlow, di->ddoffsethigh,
++		  di->dataoffsetlow, di->dataoffsethigh,
++		  di->addrext);
++
++	return (struct dma_pub *) di;
++
++ fail:
++	dma_detach((struct dma_pub *)di);
++	return NULL;
++}
++
++static inline void
++dma64_dd_upd(struct dma_info *di, struct dma64desc *ddring,
++	     dma_addr_t pa, uint outidx, u32 *flags, u32 bufcount)
++{
++	u32 ctrl2 = bufcount & D64_CTRL2_BC_MASK;
++
++	/* PCI bus with big(>1G) physical address, use address extension */
++	if ((di->dataoffsetlow == 0) || !(pa & PCI32ADDR_HIGH)) {
++		ddring[outidx].addrlow = cpu_to_le32(pa + di->dataoffsetlow);
++		ddring[outidx].addrhigh = cpu_to_le32(di->dataoffsethigh);
++		ddring[outidx].ctrl1 = cpu_to_le32(*flags);
++		ddring[outidx].ctrl2 = cpu_to_le32(ctrl2);
++	} else {
++		/* address extension for 32-bit PCI */
++		u32 ae;
++
++		ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT;
++		pa &= ~PCI32ADDR_HIGH;
++
++		ctrl2 |= (ae << D64_CTRL2_AE_SHIFT) & D64_CTRL2_AE;
++		ddring[outidx].addrlow = cpu_to_le32(pa + di->dataoffsetlow);
++		ddring[outidx].addrhigh = cpu_to_le32(di->dataoffsethigh);
++		ddring[outidx].ctrl1 = cpu_to_le32(*flags);
++		ddring[outidx].ctrl2 = cpu_to_le32(ctrl2);
++	}
++	if (di->dma.dmactrlflags & DMA_CTRL_PEN) {
++		if (dma64_dd_parity(&ddring[outidx]))
++			ddring[outidx].ctrl2 =
++			     cpu_to_le32(ctrl2 | D64_CTRL2_PARITY);
++	}
++}
++
++/* !! may be called with core in reset */
++void dma_detach(struct dma_pub *pub)
++{
++	struct dma_info *di = (struct dma_info *)pub;
++
++	DMA_TRACE("%s:\n", di->name);
++
++	/* free dma descriptor rings */
++	if (di->txd64)
++		dma_free_coherent(di->dmadev, di->txdalloc,
++				  ((s8 *)di->txd64 - di->txdalign),
++				  (di->txdpaorig));
++	if (di->rxd64)
++		dma_free_coherent(di->dmadev, di->rxdalloc,
++				  ((s8 *)di->rxd64 - di->rxdalign),
++				  (di->rxdpaorig));
++
++	/* free packet pointer vectors */
++	kfree(di->txp);
++	kfree(di->rxp);
++
++	/* free our private info structure */
++	kfree(di);
++
++}
++
++/* initialize descriptor table base address */
++static void
++_dma_ddtable_init(struct dma_info *di, uint direction, dma_addr_t pa)
++{
++	if (!di->aligndesc_4k) {
++		if (direction == DMA_TX)
++			di->xmtptrbase = pa;
++		else
++			di->rcvptrbase = pa;
++	}
++
++	if ((di->ddoffsetlow == 0)
++	    || !(pa & PCI32ADDR_HIGH)) {
++		if (direction == DMA_TX) {
++			bcma_write32(di->core, DMA64TXREGOFFS(di, addrlow),
++				     pa + di->ddoffsetlow);
++			bcma_write32(di->core, DMA64TXREGOFFS(di, addrhigh),
++				     di->ddoffsethigh);
++		} else {
++			bcma_write32(di->core, DMA64RXREGOFFS(di, addrlow),
++				     pa + di->ddoffsetlow);
++			bcma_write32(di->core, DMA64RXREGOFFS(di, addrhigh),
++				     di->ddoffsethigh);
++		}
++	} else {
++		/* DMA64 32bits address extension */
++		u32 ae;
++
++		/* shift the high bit(s) from pa to ae */
++		ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT;
++		pa &= ~PCI32ADDR_HIGH;
++
++		if (direction == DMA_TX) {
++			bcma_write32(di->core, DMA64TXREGOFFS(di, addrlow),
++				     pa + di->ddoffsetlow);
++			bcma_write32(di->core, DMA64TXREGOFFS(di, addrhigh),
++				     di->ddoffsethigh);
++			bcma_maskset32(di->core, DMA64TXREGOFFS(di, control),
++				       D64_XC_AE, (ae << D64_XC_AE_SHIFT));
++		} else {
++			bcma_write32(di->core, DMA64RXREGOFFS(di, addrlow),
++				     pa + di->ddoffsetlow);
++			bcma_write32(di->core, DMA64RXREGOFFS(di, addrhigh),
++				     di->ddoffsethigh);
++			bcma_maskset32(di->core, DMA64RXREGOFFS(di, control),
++				       D64_RC_AE, (ae << D64_RC_AE_SHIFT));
++		}
++	}
++}
++
++static void _dma_rxenable(struct dma_info *di)
++{
++	uint dmactrlflags = di->dma.dmactrlflags;
++	u32 control;
++
++	DMA_TRACE("%s:\n", di->name);
++
++	control = D64_RC_RE | (bcma_read32(di->core,
++					   DMA64RXREGOFFS(di, control)) &
++			       D64_RC_AE);
++
++	if ((dmactrlflags & DMA_CTRL_PEN) == 0)
++		control |= D64_RC_PD;
++
++	if (dmactrlflags & DMA_CTRL_ROC)
++		control |= D64_RC_OC;
++
++	bcma_write32(di->core, DMA64RXREGOFFS(di, control),
++		((di->rxoffset << D64_RC_RO_SHIFT) | control));
++}
++
++void dma_rxinit(struct dma_pub *pub)
++{
++	struct dma_info *di = (struct dma_info *)pub;
++
++	DMA_TRACE("%s:\n", di->name);
++
++	if (di->nrxd == 0)
++		return;
++
++	di->rxin = di->rxout = 0;
++
++	/* clear rx descriptor ring */
++	memset(di->rxd64, '\0', di->nrxd * sizeof(struct dma64desc));
++
++	/* DMA engine with out alignment requirement requires table to be inited
++	 * before enabling the engine
++	 */
++	if (!di->aligndesc_4k)
++		_dma_ddtable_init(di, DMA_RX, di->rxdpa);
++
++	_dma_rxenable(di);
++
++	if (di->aligndesc_4k)
++		_dma_ddtable_init(di, DMA_RX, di->rxdpa);
++}
++
++static struct sk_buff *dma64_getnextrxp(struct dma_info *di, bool forceall)
++{
++	uint i, curr;
++	struct sk_buff *rxp;
++	dma_addr_t pa;
++
++	i = di->rxin;
++
++	/* return if no packets posted */
++	if (i == di->rxout)
++		return NULL;
++
++	curr =
++	    B2I(((bcma_read32(di->core,
++			      DMA64RXREGOFFS(di, status0)) & D64_RS0_CD_MASK) -
++		 di->rcvptrbase) & D64_RS0_CD_MASK, struct dma64desc);
++
++	/* ignore curr if forceall */
++	if (!forceall && (i == curr))
++		return NULL;
++
++	/* get the packet pointer that corresponds to the rx descriptor */
++	rxp = di->rxp[i];
++	di->rxp[i] = NULL;
++
++	pa = le32_to_cpu(di->rxd64[i].addrlow) - di->dataoffsetlow;
++
++	/* clear this packet from the descriptor ring */
++	dma_unmap_single(di->dmadev, pa, di->rxbufsize, DMA_FROM_DEVICE);
++
++	di->rxd64[i].addrlow = cpu_to_le32(0xdeadbeef);
++	di->rxd64[i].addrhigh = cpu_to_le32(0xdeadbeef);
++
++	di->rxin = nextrxd(di, i);
++
++	return rxp;
++}
++
++static struct sk_buff *_dma_getnextrxp(struct dma_info *di, bool forceall)
++{
++	if (di->nrxd == 0)
++		return NULL;
++
++	return dma64_getnextrxp(di, forceall);
++}
++
++/*
++ * !! rx entry routine
++ * returns the number packages in the next frame, or 0 if there are no more
++ *   if DMA_CTRL_RXMULTI is defined, DMA scattering(multiple buffers) is
++ *   supported with pkts chain
++ *   otherwise, it's treated as giant pkt and will be tossed.
++ *   The DMA scattering starts with normal DMA header, followed by first
++ *   buffer data. After it reaches the max size of buffer, the data continues
++ *   in next DMA descriptor buffer WITHOUT DMA header
++ */
++int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list)
++{
++	struct dma_info *di = (struct dma_info *)pub;
++	struct sk_buff_head dma_frames;
++	struct sk_buff *p, *next;
++	uint len;
++	uint pkt_len;
++	int resid = 0;
++	int pktcnt = 1;
++
++	skb_queue_head_init(&dma_frames);
++ next_frame:
++	p = _dma_getnextrxp(di, false);
++	if (p == NULL)
++		return 0;
++
++	len = le16_to_cpu(*(__le16 *) (p->data));
++	DMA_TRACE("%s: dma_rx len %d\n", di->name, len);
++	dma_spin_for_len(len, p);
++
++	/* set actual length */
++	pkt_len = min((di->rxoffset + len), di->rxbufsize);
++	__skb_trim(p, pkt_len);
++	skb_queue_tail(&dma_frames, p);
++	resid = len - (di->rxbufsize - di->rxoffset);
++
++	/* check for single or multi-buffer rx */
++	if (resid > 0) {
++		while ((resid > 0) && (p = _dma_getnextrxp(di, false))) {
++			pkt_len = min_t(uint, resid, di->rxbufsize);
++			__skb_trim(p, pkt_len);
++			skb_queue_tail(&dma_frames, p);
++			resid -= di->rxbufsize;
++			pktcnt++;
++		}
++
++#ifdef DEBUG
++		if (resid > 0) {
++			uint cur;
++			cur =
++			    B2I(((bcma_read32(di->core,
++					      DMA64RXREGOFFS(di, status0)) &
++				  D64_RS0_CD_MASK) - di->rcvptrbase) &
++				D64_RS0_CD_MASK, struct dma64desc);
++			DMA_ERROR("rxin %d rxout %d, hw_curr %d\n",
++				   di->rxin, di->rxout, cur);
++		}
++#endif				/* DEBUG */
++
++		if ((di->dma.dmactrlflags & DMA_CTRL_RXMULTI) == 0) {
++			DMA_ERROR("%s: bad frame length (%d)\n",
++				  di->name, len);
++			skb_queue_walk_safe(&dma_frames, p, next) {
++				skb_unlink(p, &dma_frames);
++				brcmu_pkt_buf_free_skb(p);
++			}
++			di->dma.rxgiants++;
++			pktcnt = 1;
++			goto next_frame;
++		}
++	}
++
++	skb_queue_splice_tail(&dma_frames, skb_list);
++	return pktcnt;
++}
++
++static bool dma64_rxidle(struct dma_info *di)
++{
++	DMA_TRACE("%s:\n", di->name);
++
++	if (di->nrxd == 0)
++		return true;
++
++	return ((bcma_read32(di->core,
++			     DMA64RXREGOFFS(di, status0)) & D64_RS0_CD_MASK) ==
++		(bcma_read32(di->core, DMA64RXREGOFFS(di, ptr)) &
++		 D64_RS0_CD_MASK));
++}
++
++/*
++ * post receive buffers
++ *  return false is refill failed completely and ring is empty this will stall
++ *  the rx dma and user might want to call rxfill again asap. This unlikely
++ *  happens on memory-rich NIC, but often on memory-constrained dongle
++ */
++bool dma_rxfill(struct dma_pub *pub)
++{
++	struct dma_info *di = (struct dma_info *)pub;
++	struct sk_buff *p;
++	u16 rxin, rxout;
++	u32 flags = 0;
++	uint n;
++	uint i;
++	dma_addr_t pa;
++	uint extra_offset = 0;
++	bool ring_empty;
++
++	ring_empty = false;
++
++	/*
++	 * Determine how many receive buffers we're lacking
++	 * from the full complement, allocate, initialize,
++	 * and post them, then update the chip rx lastdscr.
++	 */
++
++	rxin = di->rxin;
++	rxout = di->rxout;
++
++	n = di->nrxpost - nrxdactive(di, rxin, rxout);
++
++	DMA_TRACE("%s: post %d\n", di->name, n);
++
++	if (di->rxbufsize > BCMEXTRAHDROOM)
++		extra_offset = di->rxextrahdrroom;
++
++	for (i = 0; i < n; i++) {
++		/*
++		 * the di->rxbufsize doesn't include the extra headroom,
++		 * we need to add it to the size to be allocated
++		 */
++		p = brcmu_pkt_buf_get_skb(di->rxbufsize + extra_offset);
++
++		if (p == NULL) {
++			DMA_ERROR("%s: out of rxbufs\n", di->name);
++			if (i == 0 && dma64_rxidle(di)) {
++				DMA_ERROR("%s: ring is empty !\n", di->name);
++				ring_empty = true;
++			}
++			di->dma.rxnobuf++;
++			break;
++		}
++		/* reserve an extra headroom, if applicable */
++		if (extra_offset)
++			skb_pull(p, extra_offset);
++
++		/* Do a cached write instead of uncached write since DMA_MAP
++		 * will flush the cache.
++		 */
++		*(u32 *) (p->data) = 0;
++
++		pa = dma_map_single(di->dmadev, p->data, di->rxbufsize,
++				    DMA_FROM_DEVICE);
++
++		/* save the free packet pointer */
++		di->rxp[rxout] = p;
++
++		/* reset flags for each descriptor */
++		flags = 0;
++		if (rxout == (di->nrxd - 1))
++			flags = D64_CTRL1_EOT;
++
++		dma64_dd_upd(di, di->rxd64, pa, rxout, &flags,
++			     di->rxbufsize);
++		rxout = nextrxd(di, rxout);
++	}
++
++	di->rxout = rxout;
++
++	/* update the chip lastdscr pointer */
++	bcma_write32(di->core, DMA64RXREGOFFS(di, ptr),
++	      di->rcvptrbase + I2B(rxout, struct dma64desc));
++
++	return ring_empty;
++}
++
++void dma_rxreclaim(struct dma_pub *pub)
++{
++	struct dma_info *di = (struct dma_info *)pub;
++	struct sk_buff *p;
++
++	DMA_TRACE("%s:\n", di->name);
++
++	while ((p = _dma_getnextrxp(di, true)))
++		brcmu_pkt_buf_free_skb(p);
++}
++
++void dma_counterreset(struct dma_pub *pub)
++{
++	/* reset all software counters */
++	pub->rxgiants = 0;
++	pub->rxnobuf = 0;
++	pub->txnobuf = 0;
++}
++
++/* get the address of the var in order to change later */
++unsigned long dma_getvar(struct dma_pub *pub, const char *name)
++{
++	struct dma_info *di = (struct dma_info *)pub;
++
++	if (!strcmp(name, "&txavail"))
++		return (unsigned long)&(di->dma.txavail);
++	return 0;
++}
++
++/* 64-bit DMA functions */
++
++void dma_txinit(struct dma_pub *pub)
++{
++	struct dma_info *di = (struct dma_info *)pub;
++	u32 control = D64_XC_XE;
++
++	DMA_TRACE("%s:\n", di->name);
++
++	if (di->ntxd == 0)
++		return;
++
++	di->txin = di->txout = 0;
++	di->dma.txavail = di->ntxd - 1;
++
++	/* clear tx descriptor ring */
++	memset(di->txd64, '\0', (di->ntxd * sizeof(struct dma64desc)));
++
++	/* DMA engine with out alignment requirement requires table to be inited
++	 * before enabling the engine
++	 */
++	if (!di->aligndesc_4k)
++		_dma_ddtable_init(di, DMA_TX, di->txdpa);
++
++	if ((di->dma.dmactrlflags & DMA_CTRL_PEN) == 0)
++		control |= D64_XC_PD;
++	bcma_set32(di->core, DMA64TXREGOFFS(di, control), control);
++
++	/* DMA engine with alignment requirement requires table to be inited
++	 * before enabling the engine
++	 */
++	if (di->aligndesc_4k)
++		_dma_ddtable_init(di, DMA_TX, di->txdpa);
++}
++
++void dma_txsuspend(struct dma_pub *pub)
++{
++	struct dma_info *di = (struct dma_info *)pub;
++
++	DMA_TRACE("%s:\n", di->name);
++
++	if (di->ntxd == 0)
++		return;
++
++	bcma_set32(di->core, DMA64TXREGOFFS(di, control), D64_XC_SE);
++}
++
++void dma_txresume(struct dma_pub *pub)
++{
++	struct dma_info *di = (struct dma_info *)pub;
++
++	DMA_TRACE("%s:\n", di->name);
++
++	if (di->ntxd == 0)
++		return;
++
++	bcma_mask32(di->core, DMA64TXREGOFFS(di, control), ~D64_XC_SE);
++}
++
++bool dma_txsuspended(struct dma_pub *pub)
++{
++	struct dma_info *di = (struct dma_info *)pub;
++
++	return (di->ntxd == 0) ||
++	       ((bcma_read32(di->core,
++			     DMA64TXREGOFFS(di, control)) & D64_XC_SE) ==
++		D64_XC_SE);
++}
++
++void dma_txreclaim(struct dma_pub *pub, enum txd_range range)
++{
++	struct dma_info *di = (struct dma_info *)pub;
++	struct sk_buff *p;
++
++	DMA_TRACE("%s: %s\n",
++		  di->name,
++		  range == DMA_RANGE_ALL ? "all" :
++		  range == DMA_RANGE_TRANSMITTED ? "transmitted" :
++		  "transferred");
++
++	if (di->txin == di->txout)
++		return;
++
++	while ((p = dma_getnexttxp(pub, range))) {
++		/* For unframed data, we don't have any packets to free */
++		if (!(di->dma.dmactrlflags & DMA_CTRL_UNFRAMED))
++			brcmu_pkt_buf_free_skb(p);
++	}
++}
++
++bool dma_txreset(struct dma_pub *pub)
++{
++	struct dma_info *di = (struct dma_info *)pub;
++	u32 status;
++
++	if (di->ntxd == 0)
++		return true;
++
++	/* suspend tx DMA first */
++	bcma_write32(di->core, DMA64TXREGOFFS(di, control), D64_XC_SE);
++	SPINWAIT(((status =
++		   (bcma_read32(di->core, DMA64TXREGOFFS(di, status0)) &
++		    D64_XS0_XS_MASK)) != D64_XS0_XS_DISABLED) &&
++		  (status != D64_XS0_XS_IDLE) && (status != D64_XS0_XS_STOPPED),
++		 10000);
++
++	bcma_write32(di->core, DMA64TXREGOFFS(di, control), 0);
++	SPINWAIT(((status =
++		   (bcma_read32(di->core, DMA64TXREGOFFS(di, status0)) &
++		    D64_XS0_XS_MASK)) != D64_XS0_XS_DISABLED), 10000);
++
++	/* wait for the last transaction to complete */
++	udelay(300);
++
++	return status == D64_XS0_XS_DISABLED;
++}
++
++bool dma_rxreset(struct dma_pub *pub)
++{
++	struct dma_info *di = (struct dma_info *)pub;
++	u32 status;
++
++	if (di->nrxd == 0)
++		return true;
++
++	bcma_write32(di->core, DMA64RXREGOFFS(di, control), 0);
++	SPINWAIT(((status =
++		   (bcma_read32(di->core, DMA64RXREGOFFS(di, status0)) &
++		    D64_RS0_RS_MASK)) != D64_RS0_RS_DISABLED), 10000);
++
++	return status == D64_RS0_RS_DISABLED;
++}
++
++/*
++ * !! tx entry routine
++ * WARNING: call must check the return value for error.
++ *   the error(toss frames) could be fatal and cause many subsequent hard
++ *   to debug problems
++ */
++int dma_txfast(struct dma_pub *pub, struct sk_buff *p, bool commit)
++{
++	struct dma_info *di = (struct dma_info *)pub;
++	unsigned char *data;
++	uint len;
++	u16 txout;
++	u32 flags = 0;
++	dma_addr_t pa;
++
++	DMA_TRACE("%s:\n", di->name);
++
++	txout = di->txout;
++
++	/*
++	 * obtain and initialize transmit descriptor entry.
++	 */
++	data = p->data;
++	len = p->len;
++
++	/* no use to transmit a zero length packet */
++	if (len == 0)
++		return 0;
++
++	/* return nonzero if out of tx descriptors */
++	if (nexttxd(di, txout) == di->txin)
++		goto outoftxd;
++
++	/* get physical address of buffer start */
++	pa = dma_map_single(di->dmadev, data, len, DMA_TO_DEVICE);
++
++	/* With a DMA segment list, Descriptor table is filled
++	 * using the segment list instead of looping over
++	 * buffers in multi-chain DMA. Therefore, EOF for SGLIST
++	 * is when end of segment list is reached.
++	 */
++	flags = D64_CTRL1_SOF | D64_CTRL1_IOC | D64_CTRL1_EOF;
++	if (txout == (di->ntxd - 1))
++		flags |= D64_CTRL1_EOT;
++
++	dma64_dd_upd(di, di->txd64, pa, txout, &flags, len);
++
++	txout = nexttxd(di, txout);
++
++	/* save the packet */
++	di->txp[prevtxd(di, txout)] = p;
++
++	/* bump the tx descriptor index */
++	di->txout = txout;
++
++	/* kick the chip */
++	if (commit)
++		bcma_write32(di->core, DMA64TXREGOFFS(di, ptr),
++		      di->xmtptrbase + I2B(txout, struct dma64desc));
++
++	/* tx flow control */
++	di->dma.txavail = di->ntxd - ntxdactive(di, di->txin, di->txout) - 1;
++
++	return 0;
++
++ outoftxd:
++	DMA_ERROR("%s: out of txds !!!\n", di->name);
++	brcmu_pkt_buf_free_skb(p);
++	di->dma.txavail = 0;
++	di->dma.txnobuf++;
++	return -1;
++}
++
++/*
++ * Reclaim next completed txd (txds if using chained buffers) in the range
++ * specified and return associated packet.
++ * If range is DMA_RANGE_TRANSMITTED, reclaim descriptors that have be
++ * transmitted as noted by the hardware "CurrDescr" pointer.
++ * If range is DMA_RANGE_TRANSFERED, reclaim descriptors that have be
++ * transferred by the DMA as noted by the hardware "ActiveDescr" pointer.
++ * If range is DMA_RANGE_ALL, reclaim all txd(s) posted to the ring and
++ * return associated packet regardless of the value of hardware pointers.
++ */
++struct sk_buff *dma_getnexttxp(struct dma_pub *pub, enum txd_range range)
++{
++	struct dma_info *di = (struct dma_info *)pub;
++	u16 start, end, i;
++	u16 active_desc;
++	struct sk_buff *txp;
++
++	DMA_TRACE("%s: %s\n",
++		  di->name,
++		  range == DMA_RANGE_ALL ? "all" :
++		  range == DMA_RANGE_TRANSMITTED ? "transmitted" :
++		  "transferred");
++
++	if (di->ntxd == 0)
++		return NULL;
++
++	txp = NULL;
++
++	start = di->txin;
++	if (range == DMA_RANGE_ALL)
++		end = di->txout;
++	else {
++		end = (u16) (B2I(((bcma_read32(di->core,
++					       DMA64TXREGOFFS(di, status0)) &
++				   D64_XS0_CD_MASK) - di->xmtptrbase) &
++				 D64_XS0_CD_MASK, struct dma64desc));
++
++		if (range == DMA_RANGE_TRANSFERED) {
++			active_desc =
++				(u16)(bcma_read32(di->core,
++						  DMA64TXREGOFFS(di, status1)) &
++				      D64_XS1_AD_MASK);
++			active_desc =
++			    (active_desc - di->xmtptrbase) & D64_XS0_CD_MASK;
++			active_desc = B2I(active_desc, struct dma64desc);
++			if (end != active_desc)
++				end = prevtxd(di, active_desc);
++		}
++	}
++
++	if ((start == 0) && (end > di->txout))
++		goto bogus;
++
++	for (i = start; i != end && !txp; i = nexttxd(di, i)) {
++		dma_addr_t pa;
++		uint size;
++
++		pa = le32_to_cpu(di->txd64[i].addrlow) - di->dataoffsetlow;
++
++		size =
++		    (le32_to_cpu(di->txd64[i].ctrl2) &
++		     D64_CTRL2_BC_MASK);
++
++		di->txd64[i].addrlow = cpu_to_le32(0xdeadbeef);
++		di->txd64[i].addrhigh = cpu_to_le32(0xdeadbeef);
++
++		txp = di->txp[i];
++		di->txp[i] = NULL;
++
++		dma_unmap_single(di->dmadev, pa, size, DMA_TO_DEVICE);
++	}
++
++	di->txin = i;
++
++	/* tx flow control */
++	di->dma.txavail = di->ntxd - ntxdactive(di, di->txin, di->txout) - 1;
++
++	return txp;
++
++ bogus:
++	DMA_NONE("bogus curr: start %d end %d txout %d\n",
++		 start, end, di->txout);
++	return NULL;
++}
++
++/*
++ * Mac80211 initiated actions sometimes require packets in the DMA queue to be
++ * modified. The modified portion of the packet is not under control of the DMA
++ * engine. This function calls a caller-supplied function for each packet in
++ * the caller specified dma chain.
++ */
++void dma_walk_packets(struct dma_pub *dmah, void (*callback_fnc)
++		      (void *pkt, void *arg_a), void *arg_a)
++{
++	struct dma_info *di = (struct dma_info *) dmah;
++	uint i =   di->txin;
++	uint end = di->txout;
++	struct sk_buff *skb;
++	struct ieee80211_tx_info *tx_info;
++
++	while (i != end) {
++		skb = (struct sk_buff *)di->txp[i];
++		if (skb != NULL) {
++			tx_info = (struct ieee80211_tx_info *)skb->cb;
++			(callback_fnc)(tx_info, arg_a);
++		}
++		i = nexttxd(di, i);
++	}
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/dma.h b/drivers/net/wireless/brcm80211/brcmsmac/dma.h
+new file mode 100644
+index 0000000..cc269ee
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/dma.h
+@@ -0,0 +1,122 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef	_BRCM_DMA_H_
++#define	_BRCM_DMA_H_
++
++#include <linux/delay.h>
++#include <linux/skbuff.h>
++#include "types.h"		/* forward structure declarations */
++
++/* map/unmap direction */
++#define	DMA_TX	1		/* TX direction for DMA */
++#define	DMA_RX	2		/* RX direction for DMA */
++
++/* DMA structure:
++ *  support two DMA engines: 32 bits address or 64 bit addressing
++ *  basic DMA register set is per channel(transmit or receive)
++ *  a pair of channels is defined for convenience
++ */
++
++/* 32 bits addressing */
++
++struct dma32diag {	/* diag access */
++	u32 fifoaddr;	/* diag address */
++	u32 fifodatalow;	/* low 32bits of data */
++	u32 fifodatahigh;	/* high 32bits of data */
++	u32 pad;		/* reserved */
++};
++
++/* 64 bits addressing */
++
++/* dma registers per channel(xmt or rcv) */
++struct dma64regs {
++	u32 control;	/* enable, et al */
++	u32 ptr;	/* last descriptor posted to chip */
++	u32 addrlow;	/* desc ring base address low 32-bits (8K aligned) */
++	u32 addrhigh;	/* desc ring base address bits 63:32 (8K aligned) */
++	u32 status0;	/* current descriptor, xmt state */
++	u32 status1;	/* active descriptor, xmt error */
++};
++
++/* range param for dma_getnexttxp() and dma_txreclaim */
++enum txd_range {
++	DMA_RANGE_ALL = 1,
++	DMA_RANGE_TRANSMITTED,
++	DMA_RANGE_TRANSFERED
++};
++
++/*
++ * Exported data structure (read-only)
++ */
++/* export structure */
++struct dma_pub {
++	uint txavail;		/* # free tx descriptors */
++	uint dmactrlflags;	/* dma control flags */
++
++	/* rx error counters */
++	uint rxgiants;		/* rx giant frames */
++	uint rxnobuf;		/* rx out of dma descriptors */
++	/* tx error counters */
++	uint txnobuf;		/* tx out of dma descriptors */
++};
++
++extern struct dma_pub *dma_attach(char *name, struct si_pub *sih,
++				  struct bcma_device *d11core,
++				  uint txregbase, uint rxregbase,
++				  uint ntxd, uint nrxd,
++				  uint rxbufsize, int rxextheadroom,
++				  uint nrxpost, uint rxoffset, uint *msg_level);
++
++void dma_rxinit(struct dma_pub *pub);
++int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list);
++bool dma_rxfill(struct dma_pub *pub);
++bool dma_rxreset(struct dma_pub *pub);
++bool dma_txreset(struct dma_pub *pub);
++void dma_txinit(struct dma_pub *pub);
++int dma_txfast(struct dma_pub *pub, struct sk_buff *p0, bool commit);
++void dma_txsuspend(struct dma_pub *pub);
++bool dma_txsuspended(struct dma_pub *pub);
++void dma_txresume(struct dma_pub *pub);
++void dma_txreclaim(struct dma_pub *pub, enum txd_range range);
++void dma_rxreclaim(struct dma_pub *pub);
++void dma_detach(struct dma_pub *pub);
++unsigned long dma_getvar(struct dma_pub *pub, const char *name);
++struct sk_buff *dma_getnexttxp(struct dma_pub *pub, enum txd_range range);
++void dma_counterreset(struct dma_pub *pub);
++
++void dma_walk_packets(struct dma_pub *dmah, void (*callback_fnc)
++		      (void *pkt, void *arg_a), void *arg_a);
++
++/*
++ * DMA(Bug) on bcm47xx chips seems to declare that the packet is ready, but
++ * the packet length is not updated yet (by DMA) on the expected time.
++ * Workaround is to hold processor till DMA updates the length, and stay off
++ * the bus to allow DMA update the length in buffer
++ */
++static inline void dma_spin_for_len(uint len, struct sk_buff *head)
++{
++#if defined(CONFIG_BCM47XX)
++	if (!len) {
++		while (!(len = *(u16 *) KSEG1ADDR(head->data)))
++			udelay(1);
++
++		*(u16 *) (head->data) = cpu_to_le16((u16) len);
++	}
++#endif				/* defined(CONFIG_BCM47XX) */
++}
++
++#endif				/* _BRCM_DMA_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
+new file mode 100644
+index 0000000..21f7939
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
+@@ -0,0 +1,1609 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#define __UNDEF_NO_VERSION__
++#undef pr_fmt
++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
++
++#include <linux/printk.h>
++#include <linux/etherdevice.h>
++#include <linux/sched.h>
++#include <linux/firmware.h>
++#include <linux/interrupt.h>
++#include <linux/module.h>
++#include <linux/bcma/bcma.h>
++#include <net/mac80211.h>
++#include <defs.h>
++#include "phy/phy_int.h"
++#include "d11.h"
++#include "channel.h"
++#include "scb.h"
++#include "pub.h"
++#include "ucode_loader.h"
++#include "mac80211_if.h"
++#include "main.h"
++
++#define N_TX_QUEUES	4 /* #tx queues on mac80211<->driver interface */
++
++/* Flags we support */
++#define MAC_FILTERS (FIF_PROMISC_IN_BSS | \
++	FIF_ALLMULTI | \
++	FIF_FCSFAIL | \
++	FIF_CONTROL | \
++	FIF_OTHER_BSS | \
++	FIF_BCN_PRBRESP_PROMISC | \
++	FIF_PSPOLL)
++
++#define CHAN2GHZ(channel, freqency, chflags)  { \
++	.band = IEEE80211_BAND_2GHZ, \
++	.center_freq = (freqency), \
++	.hw_value = (channel), \
++	.flags = chflags, \
++	.max_antenna_gain = 0, \
++	.max_power = 19, \
++}
++
++#define CHAN5GHZ(channel, chflags)  { \
++	.band = IEEE80211_BAND_5GHZ, \
++	.center_freq = 5000 + 5*(channel), \
++	.hw_value = (channel), \
++	.flags = chflags, \
++	.max_antenna_gain = 0, \
++	.max_power = 21, \
++}
++
++#define RATE(rate100m, _flags) { \
++	.bitrate = (rate100m), \
++	.flags = (_flags), \
++	.hw_value = (rate100m / 5), \
++}
++
++struct firmware_hdr {
++	__le32 offset;
++	__le32 len;
++	__le32 idx;
++};
++
++static const char * const brcms_firmwares[MAX_FW_IMAGES] = {
++	"brcm/bcm43xx",
++	NULL
++};
++
++static int n_adapters_found;
++
++MODULE_AUTHOR("Broadcom Corporation");
++MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN driver.");
++MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN cards");
++MODULE_LICENSE("Dual BSD/GPL");
++
++
++/* recognized BCMA Core IDs */
++static struct bcma_device_id brcms_coreid_table[] = {
++	BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 23, BCMA_ANY_CLASS),
++	BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 24, BCMA_ANY_CLASS),
++	BCMA_CORETABLE_END
++};
++MODULE_DEVICE_TABLE(bcma, brcms_coreid_table);
++
++#ifdef DEBUG
++static int msglevel = 0xdeadbeef;
++module_param(msglevel, int, 0);
++#endif				/* DEBUG */
++
++static struct ieee80211_channel brcms_2ghz_chantable[] = {
++	CHAN2GHZ(1, 2412, IEEE80211_CHAN_NO_HT40MINUS),
++	CHAN2GHZ(2, 2417, IEEE80211_CHAN_NO_HT40MINUS),
++	CHAN2GHZ(3, 2422, IEEE80211_CHAN_NO_HT40MINUS),
++	CHAN2GHZ(4, 2427, IEEE80211_CHAN_NO_HT40MINUS),
++	CHAN2GHZ(5, 2432, 0),
++	CHAN2GHZ(6, 2437, 0),
++	CHAN2GHZ(7, 2442, 0),
++	CHAN2GHZ(8, 2447, IEEE80211_CHAN_NO_HT40PLUS),
++	CHAN2GHZ(9, 2452, IEEE80211_CHAN_NO_HT40PLUS),
++	CHAN2GHZ(10, 2457, IEEE80211_CHAN_NO_HT40PLUS),
++	CHAN2GHZ(11, 2462, IEEE80211_CHAN_NO_HT40PLUS),
++	CHAN2GHZ(12, 2467,
++		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS |
++		 IEEE80211_CHAN_NO_HT40PLUS),
++	CHAN2GHZ(13, 2472,
++		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS |
++		 IEEE80211_CHAN_NO_HT40PLUS),
++	CHAN2GHZ(14, 2484,
++		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS |
++		 IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS)
++};
++
++static struct ieee80211_channel brcms_5ghz_nphy_chantable[] = {
++	/* UNII-1 */
++	CHAN5GHZ(36, IEEE80211_CHAN_NO_HT40MINUS),
++	CHAN5GHZ(40, IEEE80211_CHAN_NO_HT40PLUS),
++	CHAN5GHZ(44, IEEE80211_CHAN_NO_HT40MINUS),
++	CHAN5GHZ(48, IEEE80211_CHAN_NO_HT40PLUS),
++	/* UNII-2 */
++	CHAN5GHZ(52,
++		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
++		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
++	CHAN5GHZ(56,
++		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
++		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
++	CHAN5GHZ(60,
++		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
++		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
++	CHAN5GHZ(64,
++		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
++		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
++	/* MID */
++	CHAN5GHZ(100,
++		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
++		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
++	CHAN5GHZ(104,
++		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
++		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
++	CHAN5GHZ(108,
++		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
++		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
++	CHAN5GHZ(112,
++		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
++		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
++	CHAN5GHZ(116,
++		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
++		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
++	CHAN5GHZ(120,
++		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
++		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
++	CHAN5GHZ(124,
++		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
++		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
++	CHAN5GHZ(128,
++		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
++		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
++	CHAN5GHZ(132,
++		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
++		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
++	CHAN5GHZ(136,
++		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
++		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
++	CHAN5GHZ(140,
++		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
++		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS |
++		 IEEE80211_CHAN_NO_HT40MINUS),
++	/* UNII-3 */
++	CHAN5GHZ(149, IEEE80211_CHAN_NO_HT40MINUS),
++	CHAN5GHZ(153, IEEE80211_CHAN_NO_HT40PLUS),
++	CHAN5GHZ(157, IEEE80211_CHAN_NO_HT40MINUS),
++	CHAN5GHZ(161, IEEE80211_CHAN_NO_HT40PLUS),
++	CHAN5GHZ(165, IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS)
++};
++
++/*
++ * The rate table is used for both 2.4G and 5G rates. The
++ * latter being a subset as it does not support CCK rates.
++ */
++static struct ieee80211_rate legacy_ratetable[] = {
++	RATE(10, 0),
++	RATE(20, IEEE80211_RATE_SHORT_PREAMBLE),
++	RATE(55, IEEE80211_RATE_SHORT_PREAMBLE),
++	RATE(110, IEEE80211_RATE_SHORT_PREAMBLE),
++	RATE(60, 0),
++	RATE(90, 0),
++	RATE(120, 0),
++	RATE(180, 0),
++	RATE(240, 0),
++	RATE(360, 0),
++	RATE(480, 0),
++	RATE(540, 0),
++};
++
++static const struct ieee80211_supported_band brcms_band_2GHz_nphy_template = {
++	.band = IEEE80211_BAND_2GHZ,
++	.channels = brcms_2ghz_chantable,
++	.n_channels = ARRAY_SIZE(brcms_2ghz_chantable),
++	.bitrates = legacy_ratetable,
++	.n_bitrates = ARRAY_SIZE(legacy_ratetable),
++	.ht_cap = {
++		   /* from include/linux/ieee80211.h */
++		   .cap = IEEE80211_HT_CAP_GRN_FLD |
++			  IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40,
++		   .ht_supported = true,
++		   .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
++		   .ampdu_density = AMPDU_DEF_MPDU_DENSITY,
++		   .mcs = {
++			   /* placeholders for now */
++			   .rx_mask = {0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0},
++			   .rx_highest = cpu_to_le16(500),
++			   .tx_params = IEEE80211_HT_MCS_TX_DEFINED}
++		   }
++};
++
++static const struct ieee80211_supported_band brcms_band_5GHz_nphy_template = {
++	.band = IEEE80211_BAND_5GHZ,
++	.channels = brcms_5ghz_nphy_chantable,
++	.n_channels = ARRAY_SIZE(brcms_5ghz_nphy_chantable),
++	.bitrates = legacy_ratetable + BRCMS_LEGACY_5G_RATE_OFFSET,
++	.n_bitrates = ARRAY_SIZE(legacy_ratetable) -
++			BRCMS_LEGACY_5G_RATE_OFFSET,
++	.ht_cap = {
++		   .cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20 |
++			  IEEE80211_HT_CAP_SGI_40,
++		   .ht_supported = true,
++		   .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
++		   .ampdu_density = AMPDU_DEF_MPDU_DENSITY,
++		   .mcs = {
++			   /* placeholders for now */
++			   .rx_mask = {0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0},
++			   .rx_highest = cpu_to_le16(500),
++			   .tx_params = IEEE80211_HT_MCS_TX_DEFINED}
++		   }
++};
++
++/* flags the given rate in rateset as requested */
++static void brcms_set_basic_rate(struct brcm_rateset *rs, u16 rate, bool is_br)
++{
++	u32 i;
++
++	for (i = 0; i < rs->count; i++) {
++		if (rate != (rs->rates[i] & 0x7f))
++			continue;
++
++		if (is_br)
++			rs->rates[i] |= BRCMS_RATE_FLAG;
++		else
++			rs->rates[i] &= BRCMS_RATE_MASK;
++		return;
++	}
++}
++
++static void brcms_ops_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
++{
++	struct brcms_info *wl = hw->priv;
++
++	spin_lock_bh(&wl->lock);
++	if (!wl->pub->up) {
++		wiphy_err(wl->wiphy, "ops->tx called while down\n");
++		kfree_skb(skb);
++		goto done;
++	}
++	brcms_c_sendpkt_mac80211(wl->wlc, skb, hw);
++ done:
++	spin_unlock_bh(&wl->lock);
++}
++
++static int brcms_ops_start(struct ieee80211_hw *hw)
++{
++	struct brcms_info *wl = hw->priv;
++	bool blocked;
++	int err;
++
++	ieee80211_wake_queues(hw);
++	spin_lock_bh(&wl->lock);
++	blocked = brcms_rfkill_set_hw_state(wl);
++	spin_unlock_bh(&wl->lock);
++	if (!blocked)
++		wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy);
++
++	spin_lock_bh(&wl->lock);
++	/* avoid acknowledging frames before a non-monitor device is added */
++	wl->mute_tx = true;
++
++	if (!wl->pub->up)
++		err = brcms_up(wl);
++	else
++		err = -ENODEV;
++	spin_unlock_bh(&wl->lock);
++
++	if (err != 0)
++		wiphy_err(hw->wiphy, "%s: brcms_up() returned %d\n", __func__,
++			  err);
++	return err;
++}
++
++static void brcms_ops_stop(struct ieee80211_hw *hw)
++{
++	struct brcms_info *wl = hw->priv;
++	int status;
++
++	ieee80211_stop_queues(hw);
++
++	if (wl->wlc == NULL)
++		return;
++
++	spin_lock_bh(&wl->lock);
++	status = brcms_c_chipmatch(wl->wlc->hw->vendorid,
++				   wl->wlc->hw->deviceid);
++	spin_unlock_bh(&wl->lock);
++	if (!status) {
++		wiphy_err(wl->wiphy,
++			  "wl: brcms_ops_stop: chipmatch failed\n");
++		return;
++	}
++
++	/* put driver in down state */
++	spin_lock_bh(&wl->lock);
++	brcms_down(wl);
++	spin_unlock_bh(&wl->lock);
++}
++
++static int
++brcms_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
++{
++	struct brcms_info *wl = hw->priv;
++
++	/* Just STA for now */
++	if (vif->type != NL80211_IFTYPE_STATION) {
++		wiphy_err(hw->wiphy, "%s: Attempt to add type %d, only"
++			  " STA for now\n", __func__, vif->type);
++		return -EOPNOTSUPP;
++	}
++
++	wl->mute_tx = false;
++	brcms_c_mute(wl->wlc, false);
++
++	return 0;
++}
++
++static void
++brcms_ops_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
++{
++}
++
++static int brcms_ops_config(struct ieee80211_hw *hw, u32 changed)
++{
++	struct ieee80211_conf *conf = &hw->conf;
++	struct brcms_info *wl = hw->priv;
++	int err = 0;
++	int new_int;
++	struct wiphy *wiphy = hw->wiphy;
++
++	spin_lock_bh(&wl->lock);
++	if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) {
++		brcms_c_set_beacon_listen_interval(wl->wlc,
++						   conf->listen_interval);
++	}
++	if (changed & IEEE80211_CONF_CHANGE_MONITOR)
++		wiphy_dbg(wiphy, "%s: change monitor mode: %s\n",
++			  __func__, conf->flags & IEEE80211_CONF_MONITOR ?
++			  "true" : "false");
++	if (changed & IEEE80211_CONF_CHANGE_PS)
++		wiphy_err(wiphy, "%s: change power-save mode: %s (implement)\n",
++			  __func__, conf->flags & IEEE80211_CONF_PS ?
++			  "true" : "false");
++
++	if (changed & IEEE80211_CONF_CHANGE_POWER) {
++		err = brcms_c_set_tx_power(wl->wlc, conf->power_level);
++		if (err < 0) {
++			wiphy_err(wiphy, "%s: Error setting power_level\n",
++				  __func__);
++			goto config_out;
++		}
++		new_int = brcms_c_get_tx_power(wl->wlc);
++		if (new_int != conf->power_level)
++			wiphy_err(wiphy, "%s: Power level req != actual, %d %d"
++				  "\n", __func__, conf->power_level,
++				  new_int);
++	}
++	if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
++		if (conf->channel_type == NL80211_CHAN_HT20 ||
++		    conf->channel_type == NL80211_CHAN_NO_HT)
++			err = brcms_c_set_channel(wl->wlc,
++						  conf->channel->hw_value);
++		else
++			err = -ENOTSUPP;
++	}
++	if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
++		err = brcms_c_set_rate_limit(wl->wlc,
++					     conf->short_frame_max_tx_count,
++					     conf->long_frame_max_tx_count);
++
++ config_out:
++	spin_unlock_bh(&wl->lock);
++	return err;
++}
++
++static void
++brcms_ops_bss_info_changed(struct ieee80211_hw *hw,
++			struct ieee80211_vif *vif,
++			struct ieee80211_bss_conf *info, u32 changed)
++{
++	struct brcms_info *wl = hw->priv;
++	struct wiphy *wiphy = hw->wiphy;
++
++	if (changed & BSS_CHANGED_ASSOC) {
++		/* association status changed (associated/disassociated)
++		 * also implies a change in the AID.
++		 */
++		wiphy_err(wiphy, "%s: %s: %sassociated\n", KBUILD_MODNAME,
++			  __func__, info->assoc ? "" : "dis");
++		spin_lock_bh(&wl->lock);
++		brcms_c_associate_upd(wl->wlc, info->assoc);
++		spin_unlock_bh(&wl->lock);
++	}
++	if (changed & BSS_CHANGED_ERP_SLOT) {
++		s8 val;
++
++		/* slot timing changed */
++		if (info->use_short_slot)
++			val = 1;
++		else
++			val = 0;
++		spin_lock_bh(&wl->lock);
++		brcms_c_set_shortslot_override(wl->wlc, val);
++		spin_unlock_bh(&wl->lock);
++	}
++
++	if (changed & BSS_CHANGED_HT) {
++		/* 802.11n parameters changed */
++		u16 mode = info->ht_operation_mode;
++
++		spin_lock_bh(&wl->lock);
++		brcms_c_protection_upd(wl->wlc, BRCMS_PROT_N_CFG,
++			mode & IEEE80211_HT_OP_MODE_PROTECTION);
++		brcms_c_protection_upd(wl->wlc, BRCMS_PROT_N_NONGF,
++			mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
++		brcms_c_protection_upd(wl->wlc, BRCMS_PROT_N_OBSS,
++			mode & IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT);
++		spin_unlock_bh(&wl->lock);
++	}
++	if (changed & BSS_CHANGED_BASIC_RATES) {
++		struct ieee80211_supported_band *bi;
++		u32 br_mask, i;
++		u16 rate;
++		struct brcm_rateset rs;
++		int error;
++
++		/* retrieve the current rates */
++		spin_lock_bh(&wl->lock);
++		brcms_c_get_current_rateset(wl->wlc, &rs);
++		spin_unlock_bh(&wl->lock);
++
++		br_mask = info->basic_rates;
++		bi = hw->wiphy->bands[brcms_c_get_curband(wl->wlc)];
++		for (i = 0; i < bi->n_bitrates; i++) {
++			/* convert to internal rate value */
++			rate = (bi->bitrates[i].bitrate << 1) / 10;
++
++			/* set/clear basic rate flag */
++			brcms_set_basic_rate(&rs, rate, br_mask & 1);
++			br_mask >>= 1;
++		}
++
++		/* update the rate set */
++		spin_lock_bh(&wl->lock);
++		error = brcms_c_set_rateset(wl->wlc, &rs);
++		spin_unlock_bh(&wl->lock);
++		if (error)
++			wiphy_err(wiphy, "changing basic rates failed: %d\n",
++				  error);
++	}
++	if (changed & BSS_CHANGED_BEACON_INT) {
++		/* Beacon interval changed */
++		spin_lock_bh(&wl->lock);
++		brcms_c_set_beacon_period(wl->wlc, info->beacon_int);
++		spin_unlock_bh(&wl->lock);
++	}
++	if (changed & BSS_CHANGED_BSSID) {
++		/* BSSID changed, for whatever reason (IBSS and managed mode) */
++		spin_lock_bh(&wl->lock);
++		brcms_c_set_addrmatch(wl->wlc, RCM_BSSID_OFFSET, info->bssid);
++		spin_unlock_bh(&wl->lock);
++	}
++	if (changed & BSS_CHANGED_BEACON)
++		/* Beacon data changed, retrieve new beacon (beaconing modes) */
++		wiphy_err(wiphy, "%s: beacon changed\n", __func__);
++
++	if (changed & BSS_CHANGED_BEACON_ENABLED) {
++		/* Beaconing should be enabled/disabled (beaconing modes) */
++		wiphy_err(wiphy, "%s: Beacon enabled: %s\n", __func__,
++			  info->enable_beacon ? "true" : "false");
++	}
++
++	if (changed & BSS_CHANGED_CQM) {
++		/* Connection quality monitor config changed */
++		wiphy_err(wiphy, "%s: cqm change: threshold %d, hys %d "
++			  " (implement)\n", __func__, info->cqm_rssi_thold,
++			  info->cqm_rssi_hyst);
++	}
++
++	if (changed & BSS_CHANGED_IBSS) {
++		/* IBSS join status changed */
++		wiphy_err(wiphy, "%s: IBSS joined: %s (implement)\n", __func__,
++			  info->ibss_joined ? "true" : "false");
++	}
++
++	if (changed & BSS_CHANGED_ARP_FILTER) {
++		/* Hardware ARP filter address list or state changed */
++		wiphy_err(wiphy, "%s: arp filtering: enabled %s, count %d"
++			  " (implement)\n", __func__, info->arp_filter_enabled ?
++			  "true" : "false", info->arp_addr_cnt);
++	}
++
++	if (changed & BSS_CHANGED_QOS) {
++		/*
++		 * QoS for this association was enabled/disabled.
++		 * Note that it is only ever disabled for station mode.
++		 */
++		wiphy_err(wiphy, "%s: qos enabled: %s (implement)\n", __func__,
++			  info->qos ? "true" : "false");
++	}
++	return;
++}
++
++static void
++brcms_ops_configure_filter(struct ieee80211_hw *hw,
++			unsigned int changed_flags,
++			unsigned int *total_flags, u64 multicast)
++{
++	struct brcms_info *wl = hw->priv;
++	struct wiphy *wiphy = hw->wiphy;
++
++	changed_flags &= MAC_FILTERS;
++	*total_flags &= MAC_FILTERS;
++
++	if (changed_flags & FIF_PROMISC_IN_BSS)
++		wiphy_dbg(wiphy, "FIF_PROMISC_IN_BSS\n");
++	if (changed_flags & FIF_ALLMULTI)
++		wiphy_dbg(wiphy, "FIF_ALLMULTI\n");
++	if (changed_flags & FIF_FCSFAIL)
++		wiphy_dbg(wiphy, "FIF_FCSFAIL\n");
++	if (changed_flags & FIF_CONTROL)
++		wiphy_dbg(wiphy, "FIF_CONTROL\n");
++	if (changed_flags & FIF_OTHER_BSS)
++		wiphy_dbg(wiphy, "FIF_OTHER_BSS\n");
++	if (changed_flags & FIF_PSPOLL)
++		wiphy_dbg(wiphy, "FIF_PSPOLL\n");
++	if (changed_flags & FIF_BCN_PRBRESP_PROMISC)
++		wiphy_dbg(wiphy, "FIF_BCN_PRBRESP_PROMISC\n");
++
++	spin_lock_bh(&wl->lock);
++	brcms_c_mac_promisc(wl->wlc, *total_flags);
++	spin_unlock_bh(&wl->lock);
++	return;
++}
++
++static void brcms_ops_sw_scan_start(struct ieee80211_hw *hw)
++{
++	struct brcms_info *wl = hw->priv;
++	spin_lock_bh(&wl->lock);
++	brcms_c_scan_start(wl->wlc);
++	spin_unlock_bh(&wl->lock);
++	return;
++}
++
++static void brcms_ops_sw_scan_complete(struct ieee80211_hw *hw)
++{
++	struct brcms_info *wl = hw->priv;
++	spin_lock_bh(&wl->lock);
++	brcms_c_scan_stop(wl->wlc);
++	spin_unlock_bh(&wl->lock);
++	return;
++}
++
++static int
++brcms_ops_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 queue,
++		  const struct ieee80211_tx_queue_params *params)
++{
++	struct brcms_info *wl = hw->priv;
++
++	spin_lock_bh(&wl->lock);
++	brcms_c_wme_setparams(wl->wlc, queue, params, true);
++	spin_unlock_bh(&wl->lock);
++
++	return 0;
++}
++
++static int
++brcms_ops_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
++	       struct ieee80211_sta *sta)
++{
++	struct brcms_info *wl = hw->priv;
++	struct scb *scb = &wl->wlc->pri_scb;
++
++	brcms_c_init_scb(scb);
++
++	wl->pub->global_ampdu = &(scb->scb_ampdu);
++	wl->pub->global_ampdu->scb = scb;
++	wl->pub->global_ampdu->max_pdu = 16;
++
++	/*
++	 * minstrel_ht initiates addBA on our behalf by calling
++	 * ieee80211_start_tx_ba_session()
++	 */
++	return 0;
++}
++
++static int
++brcms_ops_ampdu_action(struct ieee80211_hw *hw,
++		    struct ieee80211_vif *vif,
++		    enum ieee80211_ampdu_mlme_action action,
++		    struct ieee80211_sta *sta, u16 tid, u16 *ssn,
++		    u8 buf_size)
++{
++	struct brcms_info *wl = hw->priv;
++	struct scb *scb = &wl->wlc->pri_scb;
++	int status;
++
++	if (WARN_ON(scb->magic != SCB_MAGIC))
++		return -EIDRM;
++	switch (action) {
++	case IEEE80211_AMPDU_RX_START:
++		break;
++	case IEEE80211_AMPDU_RX_STOP:
++		break;
++	case IEEE80211_AMPDU_TX_START:
++		spin_lock_bh(&wl->lock);
++		status = brcms_c_aggregatable(wl->wlc, tid);
++		spin_unlock_bh(&wl->lock);
++		if (!status) {
++			wiphy_err(wl->wiphy, "START: tid %d is not agg\'able\n",
++				  tid);
++			return -EINVAL;
++		}
++		ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
++		break;
++
++	case IEEE80211_AMPDU_TX_STOP:
++		spin_lock_bh(&wl->lock);
++		brcms_c_ampdu_flush(wl->wlc, sta, tid);
++		spin_unlock_bh(&wl->lock);
++		ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
++		break;
++	case IEEE80211_AMPDU_TX_OPERATIONAL:
++		/*
++		 * BA window size from ADDBA response ('buf_size') defines how
++		 * many outstanding MPDUs are allowed for the BA stream by
++		 * recipient and traffic class. 'ampdu_factor' gives maximum
++		 * AMPDU size.
++		 */
++		spin_lock_bh(&wl->lock);
++		brcms_c_ampdu_tx_operational(wl->wlc, tid, buf_size,
++			(1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
++			 sta->ht_cap.ampdu_factor)) - 1);
++		spin_unlock_bh(&wl->lock);
++		/* Power save wakeup */
++		break;
++	default:
++		wiphy_err(wl->wiphy, "%s: Invalid command, ignoring\n",
++			  __func__);
++	}
++
++	return 0;
++}
++
++static void brcms_ops_rfkill_poll(struct ieee80211_hw *hw)
++{
++	struct brcms_info *wl = hw->priv;
++	bool blocked;
++
++	spin_lock_bh(&wl->lock);
++	blocked = brcms_c_check_radio_disabled(wl->wlc);
++	spin_unlock_bh(&wl->lock);
++
++	wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, blocked);
++}
++
++static void brcms_ops_flush(struct ieee80211_hw *hw, bool drop)
++{
++	struct brcms_info *wl = hw->priv;
++
++	no_printk("%s: drop = %s\n", __func__, drop ? "true" : "false");
++
++	/* wait for packet queue and dma fifos to run empty */
++	spin_lock_bh(&wl->lock);
++	brcms_c_wait_for_tx_completion(wl->wlc, drop);
++	spin_unlock_bh(&wl->lock);
++}
++
++static const struct ieee80211_ops brcms_ops = {
++	.tx = brcms_ops_tx,
++	.start = brcms_ops_start,
++	.stop = brcms_ops_stop,
++	.add_interface = brcms_ops_add_interface,
++	.remove_interface = brcms_ops_remove_interface,
++	.config = brcms_ops_config,
++	.bss_info_changed = brcms_ops_bss_info_changed,
++	.configure_filter = brcms_ops_configure_filter,
++	.sw_scan_start = brcms_ops_sw_scan_start,
++	.sw_scan_complete = brcms_ops_sw_scan_complete,
++	.conf_tx = brcms_ops_conf_tx,
++	.sta_add = brcms_ops_sta_add,
++	.ampdu_action = brcms_ops_ampdu_action,
++	.rfkill_poll = brcms_ops_rfkill_poll,
++	.flush = brcms_ops_flush,
++};
++
++/*
++ * is called in brcms_bcma_probe() context, therefore no locking required.
++ */
++static int brcms_set_hint(struct brcms_info *wl, char *abbrev)
++{
++	return regulatory_hint(wl->pub->ieee_hw->wiphy, abbrev);
++}
++
++void brcms_dpc(unsigned long data)
++{
++	struct brcms_info *wl;
++
++	wl = (struct brcms_info *) data;
++
++	spin_lock_bh(&wl->lock);
++
++	/* call the common second level interrupt handler */
++	if (wl->pub->up) {
++		if (wl->resched) {
++			unsigned long flags;
++
++			spin_lock_irqsave(&wl->isr_lock, flags);
++			brcms_c_intrsupd(wl->wlc);
++			spin_unlock_irqrestore(&wl->isr_lock, flags);
++		}
++
++		wl->resched = brcms_c_dpc(wl->wlc, true);
++	}
++
++	/* brcms_c_dpc() may bring the driver down */
++	if (!wl->pub->up)
++		goto done;
++
++	/* re-schedule dpc */
++	if (wl->resched)
++		tasklet_schedule(&wl->tasklet);
++	else
++		/* re-enable interrupts */
++		brcms_intrson(wl);
++
++ done:
++	spin_unlock_bh(&wl->lock);
++}
++
++/*
++ * Precondition: Since this function is called in brcms_pci_probe() context,
++ * no locking is required.
++ */
++static int brcms_request_fw(struct brcms_info *wl, struct bcma_device *pdev)
++{
++	int status;
++	struct device *device = &pdev->dev;
++	char fw_name[100];
++	int i;
++
++	memset(&wl->fw, 0, sizeof(struct brcms_firmware));
++	for (i = 0; i < MAX_FW_IMAGES; i++) {
++		if (brcms_firmwares[i] == NULL)
++			break;
++		sprintf(fw_name, "%s-%d.fw", brcms_firmwares[i],
++			UCODE_LOADER_API_VER);
++		status = request_firmware(&wl->fw.fw_bin[i], fw_name, device);
++		if (status) {
++			wiphy_err(wl->wiphy, "%s: fail to load firmware %s\n",
++				  KBUILD_MODNAME, fw_name);
++			return status;
++		}
++		sprintf(fw_name, "%s_hdr-%d.fw", brcms_firmwares[i],
++			UCODE_LOADER_API_VER);
++		status = request_firmware(&wl->fw.fw_hdr[i], fw_name, device);
++		if (status) {
++			wiphy_err(wl->wiphy, "%s: fail to load firmware %s\n",
++				  KBUILD_MODNAME, fw_name);
++			return status;
++		}
++		wl->fw.hdr_num_entries[i] =
++		    wl->fw.fw_hdr[i]->size / (sizeof(struct firmware_hdr));
++	}
++	wl->fw.fw_cnt = i;
++	return brcms_ucode_data_init(wl, &wl->ucode);
++}
++
++/*
++ * Precondition: Since this function is called in brcms_pci_probe() context,
++ * no locking is required.
++ */
++static void brcms_release_fw(struct brcms_info *wl)
++{
++	int i;
++	for (i = 0; i < MAX_FW_IMAGES; i++) {
++		release_firmware(wl->fw.fw_bin[i]);
++		release_firmware(wl->fw.fw_hdr[i]);
++	}
++}
++
++/**
++ * This function frees the WL per-device resources.
++ *
++ * This function frees resources owned by the WL device pointed to
++ * by the wl parameter.
++ *
++ * precondition: can both be called locked and unlocked
++ *
++ */
++static void brcms_free(struct brcms_info *wl)
++{
++	struct brcms_timer *t, *next;
++
++	/* free ucode data */
++	if (wl->fw.fw_cnt)
++		brcms_ucode_data_free(&wl->ucode);
++	if (wl->irq)
++		free_irq(wl->irq, wl);
++
++	/* kill dpc */
++	tasklet_kill(&wl->tasklet);
++
++	if (wl->pub)
++		brcms_c_module_unregister(wl->pub, "linux", wl);
++
++	/* free common resources */
++	if (wl->wlc) {
++		brcms_c_detach(wl->wlc);
++		wl->wlc = NULL;
++		wl->pub = NULL;
++	}
++
++	/* virtual interface deletion is deferred so we cannot spinwait */
++
++	/* wait for all pending callbacks to complete */
++	while (atomic_read(&wl->callbacks) > 0)
++		schedule();
++
++	/* free timers */
++	for (t = wl->timers; t; t = next) {
++		next = t->next;
++#ifdef DEBUG
++		kfree(t->name);
++#endif
++		kfree(t);
++	}
++}
++
++/*
++* called from both kernel as from this kernel module (error flow on attach)
++* precondition: perimeter lock is not acquired.
++*/
++static void brcms_remove(struct bcma_device *pdev)
++{
++	struct ieee80211_hw *hw = bcma_get_drvdata(pdev);
++	struct brcms_info *wl = hw->priv;
++
++	if (wl->wlc) {
++		wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, false);
++		wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy);
++		ieee80211_unregister_hw(hw);
++	}
++
++	brcms_free(wl);
++
++	bcma_set_drvdata(pdev, NULL);
++	ieee80211_free_hw(hw);
++}
++
++static irqreturn_t brcms_isr(int irq, void *dev_id)
++{
++	struct brcms_info *wl;
++	bool ours, wantdpc;
++
++	wl = (struct brcms_info *) dev_id;
++
++	spin_lock(&wl->isr_lock);
++
++	/* call common first level interrupt handler */
++	ours = brcms_c_isr(wl->wlc, &wantdpc);
++	if (ours) {
++		/* if more to do... */
++		if (wantdpc) {
++
++			/* ...and call the second level interrupt handler */
++			/* schedule dpc */
++			tasklet_schedule(&wl->tasklet);
++		}
++	}
++
++	spin_unlock(&wl->isr_lock);
++
++	return IRQ_RETVAL(ours);
++}
++
++/*
++ * is called in brcms_pci_probe() context, therefore no locking required.
++ */
++static int ieee_hw_rate_init(struct ieee80211_hw *hw)
++{
++	struct brcms_info *wl = hw->priv;
++	struct brcms_c_info *wlc = wl->wlc;
++	struct ieee80211_supported_band *band;
++	int has_5g = 0;
++	u16 phy_type;
++
++	hw->wiphy->bands[IEEE80211_BAND_2GHZ] = NULL;
++	hw->wiphy->bands[IEEE80211_BAND_5GHZ] = NULL;
++
++	phy_type = brcms_c_get_phy_type(wl->wlc, 0);
++	if (phy_type == PHY_TYPE_N || phy_type == PHY_TYPE_LCN) {
++		band = &wlc->bandstate[BAND_2G_INDEX]->band;
++		*band = brcms_band_2GHz_nphy_template;
++		if (phy_type == PHY_TYPE_LCN) {
++			/* Single stream */
++			band->ht_cap.mcs.rx_mask[1] = 0;
++			band->ht_cap.mcs.rx_highest = cpu_to_le16(72);
++		}
++		hw->wiphy->bands[IEEE80211_BAND_2GHZ] = band;
++	} else {
++		return -EPERM;
++	}
++
++	/* Assume all bands use the same phy.  True for 11n devices. */
++	if (wl->pub->_nbands > 1) {
++		has_5g++;
++		if (phy_type == PHY_TYPE_N || phy_type == PHY_TYPE_LCN) {
++			band = &wlc->bandstate[BAND_5G_INDEX]->band;
++			*band = brcms_band_5GHz_nphy_template;
++			hw->wiphy->bands[IEEE80211_BAND_5GHZ] = band;
++		} else {
++			return -EPERM;
++		}
++	}
++	return 0;
++}
++
++/*
++ * is called in brcms_pci_probe() context, therefore no locking required.
++ */
++static int ieee_hw_init(struct ieee80211_hw *hw)
++{
++	hw->flags = IEEE80211_HW_SIGNAL_DBM
++	    /* | IEEE80211_HW_CONNECTION_MONITOR  What is this? */
++	    | IEEE80211_HW_REPORTS_TX_ACK_STATUS
++	    | IEEE80211_HW_AMPDU_AGGREGATION;
++
++	hw->extra_tx_headroom = brcms_c_get_header_len();
++	hw->queues = N_TX_QUEUES;
++	hw->max_rates = 2;	/* Primary rate and 1 fallback rate */
++
++	/* channel change time is dependent on chip and band  */
++	hw->channel_change_time = 7 * 1000;
++	hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
++
++	hw->rate_control_algorithm = "minstrel_ht";
++
++	hw->sta_data_size = 0;
++	return ieee_hw_rate_init(hw);
++}
++
++/**
++ * attach to the WL device.
++ *
++ * Attach to the WL device identified by vendor and device parameters.
++ * regs is a host accessible memory address pointing to WL device registers.
++ *
++ * brcms_attach is not defined as static because in the case where no bus
++ * is defined, wl_attach will never be called, and thus, gcc will issue
++ * a warning that this function is defined but not used if we declare
++ * it as static.
++ *
++ *
++ * is called in brcms_bcma_probe() context, therefore no locking required.
++ */
++static struct brcms_info *brcms_attach(struct bcma_device *pdev)
++{
++	struct brcms_info *wl = NULL;
++	int unit, err;
++	struct ieee80211_hw *hw;
++	u8 perm[ETH_ALEN];
++
++	unit = n_adapters_found;
++	err = 0;
++
++	if (unit < 0)
++		return NULL;
++
++	/* allocate private info */
++	hw = bcma_get_drvdata(pdev);
++	if (hw != NULL)
++		wl = hw->priv;
++	if (WARN_ON(hw == NULL) || WARN_ON(wl == NULL))
++		return NULL;
++	wl->wiphy = hw->wiphy;
++
++	atomic_set(&wl->callbacks, 0);
++
++	/* setup the bottom half handler */
++	tasklet_init(&wl->tasklet, brcms_dpc, (unsigned long) wl);
++
++	spin_lock_init(&wl->lock);
++	spin_lock_init(&wl->isr_lock);
++
++	/* prepare ucode */
++	if (brcms_request_fw(wl, pdev) < 0) {
++		wiphy_err(wl->wiphy, "%s: Failed to find firmware usually in "
++			  "%s\n", KBUILD_MODNAME, "/lib/firmware/brcm");
++		brcms_release_fw(wl);
++		brcms_remove(pdev);
++		return NULL;
++	}
++
++	/* common load-time initialization */
++	wl->wlc = brcms_c_attach((void *)wl, pdev, unit, false, &err);
++	brcms_release_fw(wl);
++	if (!wl->wlc) {
++		wiphy_err(wl->wiphy, "%s: attach() failed with code %d\n",
++			  KBUILD_MODNAME, err);
++		goto fail;
++	}
++	wl->pub = brcms_c_pub(wl->wlc);
++
++	wl->pub->ieee_hw = hw;
++
++	/* register our interrupt handler */
++	if (request_irq(pdev->irq, brcms_isr,
++			IRQF_SHARED, KBUILD_MODNAME, wl)) {
++		wiphy_err(wl->wiphy, "wl%d: request_irq() failed\n", unit);
++		goto fail;
++	}
++	wl->irq = pdev->irq;
++
++	/* register module */
++	brcms_c_module_register(wl->pub, "linux", wl, NULL);
++
++	if (ieee_hw_init(hw)) {
++		wiphy_err(wl->wiphy, "wl%d: %s: ieee_hw_init failed!\n", unit,
++			  __func__);
++		goto fail;
++	}
++
++	memcpy(perm, &wl->pub->cur_etheraddr, ETH_ALEN);
++	if (WARN_ON(!is_valid_ether_addr(perm)))
++		goto fail;
++	SET_IEEE80211_PERM_ADDR(hw, perm);
++
++	err = ieee80211_register_hw(hw);
++	if (err)
++		wiphy_err(wl->wiphy, "%s: ieee80211_register_hw failed, status"
++			  "%d\n", __func__, err);
++
++	if (wl->pub->srom_ccode[0] && brcms_set_hint(wl, wl->pub->srom_ccode))
++		wiphy_err(wl->wiphy, "%s: regulatory_hint failed, status %d\n",
++			  __func__, err);
++
++	n_adapters_found++;
++	return wl;
++
++fail:
++	brcms_free(wl);
++	return NULL;
++}
++
++
++
++/**
++ * determines if a device is a WL device, and if so, attaches it.
++ *
++ * This function determines if a device pointed to by pdev is a WL device,
++ * and if so, performs a brcms_attach() on it.
++ *
++ * Perimeter lock is initialized in the course of this function.
++ */
++static int __devinit brcms_bcma_probe(struct bcma_device *pdev)
++{
++	struct brcms_info *wl;
++	struct ieee80211_hw *hw;
++
++	dev_info(&pdev->dev, "mfg %x core %x rev %d class %d irq %d\n",
++		 pdev->id.manuf, pdev->id.id, pdev->id.rev, pdev->id.class,
++		 pdev->irq);
++
++	if ((pdev->id.manuf != BCMA_MANUF_BCM) ||
++	    (pdev->id.id != BCMA_CORE_80211))
++		return -ENODEV;
++
++	hw = ieee80211_alloc_hw(sizeof(struct brcms_info), &brcms_ops);
++	if (!hw) {
++		pr_err("%s: ieee80211_alloc_hw failed\n", __func__);
++		return -ENOMEM;
++	}
++
++	SET_IEEE80211_DEV(hw, &pdev->dev);
++
++	bcma_set_drvdata(pdev, hw);
++
++	memset(hw->priv, 0, sizeof(*wl));
++
++	wl = brcms_attach(pdev);
++	if (!wl) {
++		pr_err("%s: brcms_attach failed!\n", __func__);
++		return -ENODEV;
++	}
++	return 0;
++}
++
++static int brcms_suspend(struct bcma_device *pdev)
++{
++	struct brcms_info *wl;
++	struct ieee80211_hw *hw;
++
++	hw = bcma_get_drvdata(pdev);
++	wl = hw->priv;
++	if (!wl) {
++		pr_err("%s: %s: no driver private struct!\n", KBUILD_MODNAME,
++		       __func__);
++		return -ENODEV;
++	}
++
++	/* only need to flag hw is down for proper resume */
++	spin_lock_bh(&wl->lock);
++	wl->pub->hw_up = false;
++	spin_unlock_bh(&wl->lock);
++
++	pr_debug("brcms_suspend ok\n");
++
++	return 0;
++}
++
++static int brcms_resume(struct bcma_device *pdev)
++{
++	pr_debug("brcms_resume ok\n");
++	return 0;
++}
++
++static struct bcma_driver brcms_bcma_driver = {
++	.name     = KBUILD_MODNAME,
++	.probe    = brcms_bcma_probe,
++	.suspend  = brcms_suspend,
++	.resume   = brcms_resume,
++	.remove   = __devexit_p(brcms_remove),
++	.id_table = brcms_coreid_table,
++};
++
++/**
++ * This is the main entry point for the brcmsmac driver.
++ *
++ * This function is scheduled upon module initialization and
++ * does the driver registration, which result in brcms_bcma_probe()
++ * call resulting in the driver bringup.
++ */
++static void brcms_driver_init(struct work_struct *work)
++{
++	int error;
++
++	error = bcma_driver_register(&brcms_bcma_driver);
++	if (error)
++		pr_err("%s: register returned %d\n", __func__, error);
++}
++
++static DECLARE_WORK(brcms_driver_work, brcms_driver_init);
++
++static int __init brcms_module_init(void)
++{
++#ifdef DEBUG
++	if (msglevel != 0xdeadbeef)
++		brcm_msg_level = msglevel;
++#endif
++	if (!schedule_work(&brcms_driver_work))
++		return -EBUSY;
++
++	return 0;
++}
++
++/**
++ * This function unloads the brcmsmac driver from the system.
++ *
++ * This function unconditionally unloads the brcmsmac driver module from the
++ * system.
++ *
++ */
++static void __exit brcms_module_exit(void)
++{
++	cancel_work_sync(&brcms_driver_work);
++	bcma_driver_unregister(&brcms_bcma_driver);
++}
++
++module_init(brcms_module_init);
++module_exit(brcms_module_exit);
++
++/*
++ * precondition: perimeter lock has been acquired
++ */
++void brcms_txflowcontrol(struct brcms_info *wl, struct brcms_if *wlif,
++			 bool state, int prio)
++{
++	wiphy_err(wl->wiphy, "Shouldn't be here %s\n", __func__);
++}
++
++/*
++ * precondition: perimeter lock has been acquired
++ */
++void brcms_init(struct brcms_info *wl)
++{
++	BCMMSG(wl->pub->ieee_hw->wiphy, "wl%d\n", wl->pub->unit);
++	brcms_reset(wl);
++	brcms_c_init(wl->wlc, wl->mute_tx);
++}
++
++/*
++ * precondition: perimeter lock has been acquired
++ */
++uint brcms_reset(struct brcms_info *wl)
++{
++	BCMMSG(wl->pub->ieee_hw->wiphy, "wl%d\n", wl->pub->unit);
++	brcms_c_reset(wl->wlc);
++
++	/* dpc will not be rescheduled */
++	wl->resched = false;
++
++	return 0;
++}
++
++void brcms_fatal_error(struct brcms_info *wl)
++{
++	wiphy_err(wl->wlc->wiphy, "wl%d: fatal error, reinitializing\n",
++		  wl->wlc->pub->unit);
++	brcms_reset(wl);
++	ieee80211_restart_hw(wl->pub->ieee_hw);
++}
++
++/*
++ * These are interrupt on/off entry points. Disable interrupts
++ * during interrupt state transition.
++ */
++void brcms_intrson(struct brcms_info *wl)
++{
++	unsigned long flags;
++
++	spin_lock_irqsave(&wl->isr_lock, flags);
++	brcms_c_intrson(wl->wlc);
++	spin_unlock_irqrestore(&wl->isr_lock, flags);
++}
++
++u32 brcms_intrsoff(struct brcms_info *wl)
++{
++	unsigned long flags;
++	u32 status;
++
++	spin_lock_irqsave(&wl->isr_lock, flags);
++	status = brcms_c_intrsoff(wl->wlc);
++	spin_unlock_irqrestore(&wl->isr_lock, flags);
++	return status;
++}
++
++void brcms_intrsrestore(struct brcms_info *wl, u32 macintmask)
++{
++	unsigned long flags;
++
++	spin_lock_irqsave(&wl->isr_lock, flags);
++	brcms_c_intrsrestore(wl->wlc, macintmask);
++	spin_unlock_irqrestore(&wl->isr_lock, flags);
++}
++
++/*
++ * precondition: perimeter lock has been acquired
++ */
++int brcms_up(struct brcms_info *wl)
++{
++	int error = 0;
++
++	if (wl->pub->up)
++		return 0;
++
++	error = brcms_c_up(wl->wlc);
++
++	return error;
++}
++
++/*
++ * precondition: perimeter lock has been acquired
++ */
++void brcms_down(struct brcms_info *wl)
++{
++	uint callbacks, ret_val = 0;
++
++	/* call common down function */
++	ret_val = brcms_c_down(wl->wlc);
++	callbacks = atomic_read(&wl->callbacks) - ret_val;
++
++	/* wait for down callbacks to complete */
++	spin_unlock_bh(&wl->lock);
++
++	/* For HIGH_only driver, it's important to actually schedule other work,
++	 * not just spin wait since everything runs at schedule level
++	 */
++	SPINWAIT((atomic_read(&wl->callbacks) > callbacks), 100 * 1000);
++
++	spin_lock_bh(&wl->lock);
++}
++
++/*
++* precondition: perimeter lock is not acquired
++ */
++static void _brcms_timer(struct work_struct *work)
++{
++	struct brcms_timer *t = container_of(work, struct brcms_timer,
++					     dly_wrk.work);
++
++	spin_lock_bh(&t->wl->lock);
++
++	if (t->set) {
++		if (t->periodic) {
++			atomic_inc(&t->wl->callbacks);
++			ieee80211_queue_delayed_work(t->wl->pub->ieee_hw,
++						     &t->dly_wrk,
++						     msecs_to_jiffies(t->ms));
++		} else {
++			t->set = false;
++		}
++
++		t->fn(t->arg);
++	}
++
++	atomic_dec(&t->wl->callbacks);
++
++	spin_unlock_bh(&t->wl->lock);
++}
++
++/*
++ * Adds a timer to the list. Caller supplies a timer function.
++ * Is called from wlc.
++ *
++ * precondition: perimeter lock has been acquired
++ */
++struct brcms_timer *brcms_init_timer(struct brcms_info *wl,
++				     void (*fn) (void *arg),
++				     void *arg, const char *name)
++{
++	struct brcms_timer *t;
++
++	t = kzalloc(sizeof(struct brcms_timer), GFP_ATOMIC);
++	if (!t)
++		return NULL;
++
++	INIT_DELAYED_WORK(&t->dly_wrk, _brcms_timer);
++	t->wl = wl;
++	t->fn = fn;
++	t->arg = arg;
++	t->next = wl->timers;
++	wl->timers = t;
++
++#ifdef DEBUG
++	t->name = kmalloc(strlen(name) + 1, GFP_ATOMIC);
++	if (t->name)
++		strcpy(t->name, name);
++#endif
++
++	return t;
++}
++
++/*
++ * adds only the kernel timer since it's going to be more accurate
++ * as well as it's easier to make it periodic
++ *
++ * precondition: perimeter lock has been acquired
++ */
++void brcms_add_timer(struct brcms_timer *t, uint ms, int periodic)
++{
++	struct ieee80211_hw *hw = t->wl->pub->ieee_hw;
++
++#ifdef DEBUG
++	if (t->set)
++		wiphy_err(hw->wiphy, "%s: Already set. Name: %s, per %d\n",
++			  __func__, t->name, periodic);
++#endif
++	t->ms = ms;
++	t->periodic = (bool) periodic;
++	t->set = true;
++
++	atomic_inc(&t->wl->callbacks);
++
++	ieee80211_queue_delayed_work(hw, &t->dly_wrk, msecs_to_jiffies(ms));
++}
++
++/*
++ * return true if timer successfully deleted, false if still pending
++ *
++ * precondition: perimeter lock has been acquired
++ */
++bool brcms_del_timer(struct brcms_timer *t)
++{
++	if (t->set) {
++		t->set = false;
++		if (!cancel_delayed_work(&t->dly_wrk))
++			return false;
++
++		atomic_dec(&t->wl->callbacks);
++	}
++
++	return true;
++}
++
++/*
++ * precondition: perimeter lock has been acquired
++ */
++void brcms_free_timer(struct brcms_timer *t)
++{
++	struct brcms_info *wl = t->wl;
++	struct brcms_timer *tmp;
++
++	/* delete the timer in case it is active */
++	brcms_del_timer(t);
++
++	if (wl->timers == t) {
++		wl->timers = wl->timers->next;
++#ifdef DEBUG
++		kfree(t->name);
++#endif
++		kfree(t);
++		return;
++
++	}
++
++	tmp = wl->timers;
++	while (tmp) {
++		if (tmp->next == t) {
++			tmp->next = t->next;
++#ifdef DEBUG
++			kfree(t->name);
++#endif
++			kfree(t);
++			return;
++		}
++		tmp = tmp->next;
++	}
++
++}
++
++/*
++ * precondition: perimeter lock has been acquired
++ */
++int brcms_ucode_init_buf(struct brcms_info *wl, void **pbuf, u32 idx)
++{
++	int i, entry;
++	const u8 *pdata;
++	struct firmware_hdr *hdr;
++	for (i = 0; i < wl->fw.fw_cnt; i++) {
++		hdr = (struct firmware_hdr *)wl->fw.fw_hdr[i]->data;
++		for (entry = 0; entry < wl->fw.hdr_num_entries[i];
++		     entry++, hdr++) {
++			u32 len = le32_to_cpu(hdr->len);
++			if (le32_to_cpu(hdr->idx) == idx) {
++				pdata = wl->fw.fw_bin[i]->data +
++					le32_to_cpu(hdr->offset);
++				*pbuf = kmemdup(pdata, len, GFP_ATOMIC);
++				if (*pbuf == NULL)
++					goto fail;
++
++				return 0;
++			}
++		}
++	}
++	wiphy_err(wl->wiphy, "ERROR: ucode buf tag:%d can not be found!\n",
++		  idx);
++	*pbuf = NULL;
++fail:
++	return -ENODATA;
++}
++
++/*
++ * Precondition: Since this function is called in brcms_bcma_probe() context,
++ * no locking is required.
++ */
++int brcms_ucode_init_uint(struct brcms_info *wl, size_t *n_bytes, u32 idx)
++{
++	int i, entry;
++	const u8 *pdata;
++	struct firmware_hdr *hdr;
++	for (i = 0; i < wl->fw.fw_cnt; i++) {
++		hdr = (struct firmware_hdr *)wl->fw.fw_hdr[i]->data;
++		for (entry = 0; entry < wl->fw.hdr_num_entries[i];
++		     entry++, hdr++) {
++			if (le32_to_cpu(hdr->idx) == idx) {
++				pdata = wl->fw.fw_bin[i]->data +
++					le32_to_cpu(hdr->offset);
++				if (le32_to_cpu(hdr->len) != 4) {
++					wiphy_err(wl->wiphy,
++						  "ERROR: fw hdr len\n");
++					return -ENOMSG;
++				}
++				*n_bytes = le32_to_cpu(*((__le32 *) pdata));
++				return 0;
++			}
++		}
++	}
++	wiphy_err(wl->wiphy, "ERROR: ucode tag:%d can not be found!\n", idx);
++	return -ENOMSG;
++}
++
++/*
++ * precondition: can both be called locked and unlocked
++ */
++void brcms_ucode_free_buf(void *p)
++{
++	kfree(p);
++}
++
++/*
++ * checks validity of all firmware images loaded from user space
++ *
++ * Precondition: Since this function is called in brcms_bcma_probe() context,
++ * no locking is required.
++ */
++int brcms_check_firmwares(struct brcms_info *wl)
++{
++	int i;
++	int entry;
++	int rc = 0;
++	const struct firmware *fw;
++	const struct firmware *fw_hdr;
++	struct firmware_hdr *ucode_hdr;
++	for (i = 0; i < MAX_FW_IMAGES && rc == 0; i++) {
++		fw =  wl->fw.fw_bin[i];
++		fw_hdr = wl->fw.fw_hdr[i];
++		if (fw == NULL && fw_hdr == NULL) {
++			break;
++		} else if (fw == NULL || fw_hdr == NULL) {
++			wiphy_err(wl->wiphy, "%s: invalid bin/hdr fw\n",
++				  __func__);
++			rc = -EBADF;
++		} else if (fw_hdr->size % sizeof(struct firmware_hdr)) {
++			wiphy_err(wl->wiphy, "%s: non integral fw hdr file "
++				"size %zu/%zu\n", __func__, fw_hdr->size,
++				sizeof(struct firmware_hdr));
++			rc = -EBADF;
++		} else if (fw->size < MIN_FW_SIZE || fw->size > MAX_FW_SIZE) {
++			wiphy_err(wl->wiphy, "%s: out of bounds fw file size "
++				  "%zu\n", __func__, fw->size);
++			rc = -EBADF;
++		} else {
++			/* check if ucode section overruns firmware image */
++			ucode_hdr = (struct firmware_hdr *)fw_hdr->data;
++			for (entry = 0; entry < wl->fw.hdr_num_entries[i] &&
++			     !rc; entry++, ucode_hdr++) {
++				if (le32_to_cpu(ucode_hdr->offset) +
++				    le32_to_cpu(ucode_hdr->len) >
++				    fw->size) {
++					wiphy_err(wl->wiphy,
++						  "%s: conflicting bin/hdr\n",
++						  __func__);
++					rc = -EBADF;
++				}
++			}
++		}
++	}
++	if (rc == 0 && wl->fw.fw_cnt != i) {
++		wiphy_err(wl->wiphy, "%s: invalid fw_cnt=%d\n", __func__,
++			wl->fw.fw_cnt);
++		rc = -EBADF;
++	}
++	return rc;
++}
++
++/*
++ * precondition: perimeter lock has been acquired
++ */
++bool brcms_rfkill_set_hw_state(struct brcms_info *wl)
++{
++	bool blocked = brcms_c_check_radio_disabled(wl->wlc);
++
++	spin_unlock_bh(&wl->lock);
++	wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, blocked);
++	if (blocked)
++		wiphy_rfkill_start_polling(wl->pub->ieee_hw->wiphy);
++	spin_lock_bh(&wl->lock);
++	return blocked;
++}
++
++/*
++ * precondition: perimeter lock has been acquired
++ */
++void brcms_msleep(struct brcms_info *wl, uint ms)
++{
++	spin_unlock_bh(&wl->lock);
++	msleep(ms);
++	spin_lock_bh(&wl->lock);
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h
+new file mode 100644
+index 0000000..9358bd5
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h
+@@ -0,0 +1,108 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef _BRCM_MAC80211_IF_H_
++#define _BRCM_MAC80211_IF_H_
++
++#include <linux/timer.h>
++#include <linux/interrupt.h>
++#include <linux/workqueue.h>
++
++#include "ucode_loader.h"
++/*
++ * Starting index for 5G rates in the
++ * legacy rate table.
++ */
++#define BRCMS_LEGACY_5G_RATE_OFFSET	4
++
++/* softmac ioctl definitions */
++#define BRCMS_SET_SHORTSLOT_OVERRIDE		146
++
++struct brcms_timer {
++	struct delayed_work dly_wrk;
++	struct brcms_info *wl;
++	void (*fn) (void *);	/* function called upon expiration */
++	void *arg;		/* fixed argument provided to called function */
++	uint ms;
++	bool periodic;
++	bool set;		/* indicates if timer is active */
++	struct brcms_timer *next;	/* for freeing on unload */
++#ifdef DEBUG
++	char *name;		/* Description of the timer */
++#endif
++};
++
++struct brcms_if {
++	uint subunit;		/* WDS/BSS unit */
++	struct pci_dev *pci_dev;
++};
++
++#define MAX_FW_IMAGES		4
++struct brcms_firmware {
++	u32 fw_cnt;
++	const struct firmware *fw_bin[MAX_FW_IMAGES];
++	const struct firmware *fw_hdr[MAX_FW_IMAGES];
++	u32 hdr_num_entries[MAX_FW_IMAGES];
++};
++
++struct brcms_info {
++	struct brcms_pub *pub;		/* pointer to public wlc state */
++	struct brcms_c_info *wlc;	/* pointer to private common data */
++	u32 magic;
++
++	int irq;
++
++	spinlock_t lock;	/* per-device perimeter lock */
++	spinlock_t isr_lock;	/* per-device ISR synchronization lock */
++
++
++	/* timer related fields */
++	atomic_t callbacks;	/* # outstanding callback functions */
++	struct brcms_timer *timers;	/* timer cleanup queue */
++
++	struct tasklet_struct tasklet;	/* dpc tasklet */
++	bool resched;		/* dpc needs to be and is rescheduled */
++	struct brcms_firmware fw;
++	struct wiphy *wiphy;
++	struct brcms_ucode ucode;
++	bool mute_tx;
++};
++
++/* misc callbacks */
++extern void brcms_init(struct brcms_info *wl);
++extern uint brcms_reset(struct brcms_info *wl);
++extern void brcms_intrson(struct brcms_info *wl);
++extern u32 brcms_intrsoff(struct brcms_info *wl);
++extern void brcms_intrsrestore(struct brcms_info *wl, u32 macintmask);
++extern int brcms_up(struct brcms_info *wl);
++extern void brcms_down(struct brcms_info *wl);
++extern void brcms_txflowcontrol(struct brcms_info *wl, struct brcms_if *wlif,
++				bool state, int prio);
++extern bool brcms_rfkill_set_hw_state(struct brcms_info *wl);
++
++/* timer functions */
++extern struct brcms_timer *brcms_init_timer(struct brcms_info *wl,
++				      void (*fn) (void *arg), void *arg,
++				      const char *name);
++extern void brcms_free_timer(struct brcms_timer *timer);
++extern void brcms_add_timer(struct brcms_timer *timer, uint ms, int periodic);
++extern bool brcms_del_timer(struct brcms_timer *timer);
++extern void brcms_msleep(struct brcms_info *wl, uint ms);
++extern void brcms_dpc(unsigned long data);
++extern void brcms_timer(struct brcms_timer *t);
++extern void brcms_fatal_error(struct brcms_info *wl);
++
++#endif				/* _BRCM_MAC80211_IF_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
+new file mode 100644
+index 0000000..d7d4a33
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
+@@ -0,0 +1,8495 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#undef pr_fmt
++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
++
++#include <linux/printk.h>
++#include <linux/pci_ids.h>
++#include <linux/if_ether.h>
++#include <net/mac80211.h>
++#include <brcm_hw_ids.h>
++#include <aiutils.h>
++#include <chipcommon.h>
++#include "rate.h"
++#include "scb.h"
++#include "phy/phy_hal.h"
++#include "channel.h"
++#include "antsel.h"
++#include "stf.h"
++#include "ampdu.h"
++#include "mac80211_if.h"
++#include "ucode_loader.h"
++#include "main.h"
++#include "soc.h"
++
++/*
++ * Indication for txflowcontrol that all priority bits in
++ * TXQ_STOP_FOR_PRIOFC_MASK are to be considered.
++ */
++#define ALLPRIO				-1
++
++/* watchdog timer, in unit of ms */
++#define TIMER_INTERVAL_WATCHDOG		1000
++/* radio monitor timer, in unit of ms */
++#define TIMER_INTERVAL_RADIOCHK		800
++
++/* beacon interval, in unit of 1024TU */
++#define BEACON_INTERVAL_DEFAULT		100
++
++/* n-mode support capability */
++/* 2x2 includes both 1x1 & 2x2 devices
++ * reserved #define 2 for future when we want to separate 1x1 & 2x2 and
++ * control it independently
++ */
++#define WL_11N_2x2			1
++#define WL_11N_3x3			3
++#define WL_11N_4x4			4
++
++#define EDCF_ACI_MASK			0x60
++#define EDCF_ACI_SHIFT			5
++#define EDCF_ECWMIN_MASK		0x0f
++#define EDCF_ECWMAX_SHIFT		4
++#define EDCF_AIFSN_MASK			0x0f
++#define EDCF_AIFSN_MAX			15
++#define EDCF_ECWMAX_MASK		0xf0
++
++#define EDCF_AC_BE_TXOP_STA		0x0000
++#define EDCF_AC_BK_TXOP_STA		0x0000
++#define EDCF_AC_VO_ACI_STA		0x62
++#define EDCF_AC_VO_ECW_STA		0x32
++#define EDCF_AC_VI_ACI_STA		0x42
++#define EDCF_AC_VI_ECW_STA		0x43
++#define EDCF_AC_BK_ECW_STA		0xA4
++#define EDCF_AC_VI_TXOP_STA		0x005e
++#define EDCF_AC_VO_TXOP_STA		0x002f
++#define EDCF_AC_BE_ACI_STA		0x03
++#define EDCF_AC_BE_ECW_STA		0xA4
++#define EDCF_AC_BK_ACI_STA		0x27
++#define EDCF_AC_VO_TXOP_AP		0x002f
++
++#define EDCF_TXOP2USEC(txop)		((txop) << 5)
++#define EDCF_ECW2CW(exp)		((1 << (exp)) - 1)
++
++#define APHY_SYMBOL_TIME		4
++#define APHY_PREAMBLE_TIME		16
++#define APHY_SIGNAL_TIME		4
++#define APHY_SIFS_TIME			16
++#define APHY_SERVICE_NBITS		16
++#define APHY_TAIL_NBITS			6
++#define BPHY_SIFS_TIME			10
++#define BPHY_PLCP_SHORT_TIME		96
++
++#define PREN_PREAMBLE			24
++#define PREN_MM_EXT			12
++#define PREN_PREAMBLE_EXT		4
++
++#define DOT11_MAC_HDR_LEN		24
++#define DOT11_ACK_LEN			10
++#define DOT11_BA_LEN			4
++#define DOT11_OFDM_SIGNAL_EXTENSION	6
++#define DOT11_MIN_FRAG_LEN		256
++#define DOT11_RTS_LEN			16
++#define DOT11_CTS_LEN			10
++#define DOT11_BA_BITMAP_LEN		128
++#define DOT11_MIN_BEACON_PERIOD		1
++#define DOT11_MAX_BEACON_PERIOD		0xFFFF
++#define DOT11_MAXNUMFRAGS		16
++#define DOT11_MAX_FRAG_LEN		2346
++
++#define BPHY_PLCP_TIME			192
++#define RIFS_11N_TIME			2
++
++/* length of the BCN template area */
++#define BCN_TMPL_LEN			512
++
++/* brcms_bss_info flag bit values */
++#define BRCMS_BSS_HT			0x0020	/* BSS is HT (MIMO) capable */
++
++/* chip rx buffer offset */
++#define BRCMS_HWRXOFF			38
++
++/* rfdisable delay timer 500 ms, runs of ALP clock */
++#define RFDISABLE_DEFAULT		10000000
++
++#define BRCMS_TEMPSENSE_PERIOD		10	/* 10 second timeout */
++
++/* precedences numbers for wlc queues. These are twice as may levels as
++ * 802.1D priorities.
++ * Odd numbers are used for HI priority traffic at same precedence levels
++ * These constants are used ONLY by wlc_prio2prec_map.  Do not use them
++ * elsewhere.
++ */
++#define _BRCMS_PREC_NONE		0	/* None = - */
++#define _BRCMS_PREC_BK			2	/* BK - Background */
++#define _BRCMS_PREC_BE			4	/* BE - Best-effort */
++#define _BRCMS_PREC_EE			6	/* EE - Excellent-effort */
++#define _BRCMS_PREC_CL			8	/* CL - Controlled Load */
++#define _BRCMS_PREC_VI			10	/* Vi - Video */
++#define _BRCMS_PREC_VO			12	/* Vo - Voice */
++#define _BRCMS_PREC_NC			14	/* NC - Network Control */
++
++/* synthpu_dly times in us */
++#define SYNTHPU_DLY_APHY_US		3700
++#define SYNTHPU_DLY_BPHY_US		1050
++#define SYNTHPU_DLY_NPHY_US		2048
++#define SYNTHPU_DLY_LPPHY_US		300
++
++#define ANTCNT				10	/* vanilla M_MAX_ANTCNT val */
++
++/* Per-AC retry limit register definitions; uses defs.h bitfield macros */
++#define EDCF_SHORT_S			0
++#define EDCF_SFB_S			4
++#define EDCF_LONG_S			8
++#define EDCF_LFB_S			12
++#define EDCF_SHORT_M			BITFIELD_MASK(4)
++#define EDCF_SFB_M			BITFIELD_MASK(4)
++#define EDCF_LONG_M			BITFIELD_MASK(4)
++#define EDCF_LFB_M			BITFIELD_MASK(4)
++
++#define RETRY_SHORT_DEF			7	/* Default Short retry Limit */
++#define RETRY_SHORT_MAX			255	/* Maximum Short retry Limit */
++#define RETRY_LONG_DEF			4	/* Default Long retry count */
++#define RETRY_SHORT_FB			3	/* Short count for fb rate */
++#define RETRY_LONG_FB			2	/* Long count for fb rate */
++
++#define APHY_CWMIN			15
++#define PHY_CWMAX			1023
++
++#define EDCF_AIFSN_MIN			1
++
++#define FRAGNUM_MASK			0xF
++
++#define APHY_SLOT_TIME			9
++#define BPHY_SLOT_TIME			20
++
++#define WL_SPURAVOID_OFF		0
++#define WL_SPURAVOID_ON1		1
++#define WL_SPURAVOID_ON2		2
++
++/* invalid core flags, use the saved coreflags */
++#define BRCMS_USE_COREFLAGS		0xffffffff
++
++/* values for PLCPHdr_override */
++#define BRCMS_PLCP_AUTO			-1
++#define BRCMS_PLCP_SHORT		0
++#define BRCMS_PLCP_LONG			1
++
++/* values for g_protection_override and n_protection_override */
++#define BRCMS_PROTECTION_AUTO		-1
++#define BRCMS_PROTECTION_OFF		0
++#define BRCMS_PROTECTION_ON		1
++#define BRCMS_PROTECTION_MMHDR_ONLY	2
++#define BRCMS_PROTECTION_CTS_ONLY	3
++
++/* values for g_protection_control and n_protection_control */
++#define BRCMS_PROTECTION_CTL_OFF	0
++#define BRCMS_PROTECTION_CTL_LOCAL	1
++#define BRCMS_PROTECTION_CTL_OVERLAP	2
++
++/* values for n_protection */
++#define BRCMS_N_PROTECTION_OFF		0
++#define BRCMS_N_PROTECTION_OPTIONAL	1
++#define BRCMS_N_PROTECTION_20IN40	2
++#define BRCMS_N_PROTECTION_MIXEDMODE	3
++
++/* values for band specific 40MHz capabilities */
++#define BRCMS_N_BW_20ALL		0
++#define BRCMS_N_BW_40ALL		1
++#define BRCMS_N_BW_20IN2G_40IN5G	2
++
++/* bitflags for SGI support (sgi_rx iovar) */
++#define BRCMS_N_SGI_20			0x01
++#define BRCMS_N_SGI_40			0x02
++
++/* defines used by the nrate iovar */
++/* MSC in use,indicates b0-6 holds an mcs */
++#define NRATE_MCS_INUSE			0x00000080
++/* rate/mcs value */
++#define NRATE_RATE_MASK			0x0000007f
++/* stf mode mask: siso, cdd, stbc, sdm */
++#define NRATE_STF_MASK			0x0000ff00
++/* stf mode shift */
++#define NRATE_STF_SHIFT			8
++/* bit indicate to override mcs only */
++#define NRATE_OVERRIDE_MCS_ONLY		0x40000000
++#define NRATE_SGI_MASK			0x00800000	/* sgi mode */
++#define NRATE_SGI_SHIFT			23		/* sgi mode */
++#define NRATE_LDPC_CODING		0x00400000	/* adv coding in use */
++#define NRATE_LDPC_SHIFT		22		/* ldpc shift */
++
++#define NRATE_STF_SISO			0		/* stf mode SISO */
++#define NRATE_STF_CDD			1		/* stf mode CDD */
++#define NRATE_STF_STBC			2		/* stf mode STBC */
++#define NRATE_STF_SDM			3		/* stf mode SDM */
++
++#define MAX_DMA_SEGS			4
++
++/* Max # of entries in Tx FIFO based on 4kb page size */
++#define NTXD				256
++/* Max # of entries in Rx FIFO based on 4kb page size */
++#define NRXD				256
++
++/* try to keep this # rbufs posted to the chip */
++#define NRXBUFPOST			32
++
++/* data msg txq hiwat mark */
++#define BRCMS_DATAHIWAT			50
++
++/* max # frames to process in brcms_c_recv() */
++#define RXBND				8
++/* max # tx status to process in wlc_txstatus() */
++#define TXSBND				8
++
++/* brcmu_format_flags() bit description structure */
++struct brcms_c_bit_desc {
++	u32 bit;
++	const char *name;
++};
++
++/*
++ * The following table lists the buffer memory allocated to xmt fifos in HW.
++ * the size is in units of 256bytes(one block), total size is HW dependent
++ * ucode has default fifo partition, sw can overwrite if necessary
++ *
++ * This is documented in twiki under the topic UcodeTxFifo. Please ensure
++ * the twiki is updated before making changes.
++ */
++
++/* Starting corerev for the fifo size table */
++#define XMTFIFOTBL_STARTREV	20
++
++struct d11init {
++	__le16 addr;
++	__le16 size;
++	__le32 value;
++};
++
++struct edcf_acparam {
++	u8 ACI;
++	u8 ECW;
++	u16 TXOP;
++} __packed;
++
++const u8 prio2fifo[NUMPRIO] = {
++	TX_AC_BE_FIFO,		/* 0    BE      AC_BE   Best Effort */
++	TX_AC_BK_FIFO,		/* 1    BK      AC_BK   Background */
++	TX_AC_BK_FIFO,		/* 2    --      AC_BK   Background */
++	TX_AC_BE_FIFO,		/* 3    EE      AC_BE   Best Effort */
++	TX_AC_VI_FIFO,		/* 4    CL      AC_VI   Video */
++	TX_AC_VI_FIFO,		/* 5    VI      AC_VI   Video */
++	TX_AC_VO_FIFO,		/* 6    VO      AC_VO   Voice */
++	TX_AC_VO_FIFO		/* 7    NC      AC_VO   Voice */
++};
++
++/* debug/trace */
++uint brcm_msg_level =
++#if defined(DEBUG)
++	LOG_ERROR_VAL;
++#else
++	0;
++#endif				/* DEBUG */
++
++/* TX FIFO number to WME/802.1E Access Category */
++static const u8 wme_fifo2ac[] = {
++	IEEE80211_AC_BK,
++	IEEE80211_AC_BE,
++	IEEE80211_AC_VI,
++	IEEE80211_AC_VO,
++	IEEE80211_AC_BE,
++	IEEE80211_AC_BE
++};
++
++/* ieee80211 Access Category to TX FIFO number */
++static const u8 wme_ac2fifo[] = {
++	TX_AC_VO_FIFO,
++	TX_AC_VI_FIFO,
++	TX_AC_BE_FIFO,
++	TX_AC_BK_FIFO
++};
++
++/* 802.1D Priority to precedence queue mapping */
++const u8 wlc_prio2prec_map[] = {
++	_BRCMS_PREC_BE,		/* 0 BE - Best-effort */
++	_BRCMS_PREC_BK,		/* 1 BK - Background */
++	_BRCMS_PREC_NONE,		/* 2 None = - */
++	_BRCMS_PREC_EE,		/* 3 EE - Excellent-effort */
++	_BRCMS_PREC_CL,		/* 4 CL - Controlled Load */
++	_BRCMS_PREC_VI,		/* 5 Vi - Video */
++	_BRCMS_PREC_VO,		/* 6 Vo - Voice */
++	_BRCMS_PREC_NC,		/* 7 NC - Network Control */
++};
++
++static const u16 xmtfifo_sz[][NFIFO] = {
++	/* corerev 20: 5120, 49152, 49152, 5376, 4352, 1280 */
++	{20, 192, 192, 21, 17, 5},
++	/* corerev 21: 2304, 14848, 5632, 3584, 3584, 1280 */
++	{9, 58, 22, 14, 14, 5},
++	/* corerev 22: 5120, 49152, 49152, 5376, 4352, 1280 */
++	{20, 192, 192, 21, 17, 5},
++	/* corerev 23: 5120, 49152, 49152, 5376, 4352, 1280 */
++	{20, 192, 192, 21, 17, 5},
++	/* corerev 24: 2304, 14848, 5632, 3584, 3584, 1280 */
++	{9, 58, 22, 14, 14, 5},
++};
++
++#ifdef DEBUG
++static const char * const fifo_names[] = {
++	"AC_BK", "AC_BE", "AC_VI", "AC_VO", "BCMC", "ATIM" };
++#else
++static const char fifo_names[6][0];
++#endif
++
++#ifdef DEBUG
++/* pointer to most recently allocated wl/wlc */
++static struct brcms_c_info *wlc_info_dbg = (struct brcms_c_info *) (NULL);
++#endif
++
++/* Find basic rate for a given rate */
++static u8 brcms_basic_rate(struct brcms_c_info *wlc, u32 rspec)
++{
++	if (is_mcs_rate(rspec))
++		return wlc->band->basic_rate[mcs_table[rspec & RSPEC_RATE_MASK]
++		       .leg_ofdm];
++	return wlc->band->basic_rate[rspec & RSPEC_RATE_MASK];
++}
++
++static u16 frametype(u32 rspec, u8 mimoframe)
++{
++	if (is_mcs_rate(rspec))
++		return mimoframe;
++	return is_cck_rate(rspec) ? FT_CCK : FT_OFDM;
++}
++
++/* currently the best mechanism for determining SIFS is the band in use */
++static u16 get_sifs(struct brcms_band *band)
++{
++	return band->bandtype == BRCM_BAND_5G ? APHY_SIFS_TIME :
++				 BPHY_SIFS_TIME;
++}
++
++/*
++ * Detect Card removed.
++ * Even checking an sbconfig register read will not false trigger when the core
++ * is in reset it breaks CF address mechanism. Accessing gphy phyversion will
++ * cause SB error if aphy is in reset on 4306B0-DB. Need a simple accessible
++ * reg with fixed 0/1 pattern (some platforms return all 0).
++ * If clocks are present, call the sb routine which will figure out if the
++ * device is removed.
++ */
++static bool brcms_deviceremoved(struct brcms_c_info *wlc)
++{
++	u32 macctrl;
++
++	if (!wlc->hw->clk)
++		return ai_deviceremoved(wlc->hw->sih);
++	macctrl = bcma_read32(wlc->hw->d11core,
++			      D11REGOFFS(maccontrol));
++	return (macctrl & (MCTL_PSM_JMP_0 | MCTL_IHR_EN)) != MCTL_IHR_EN;
++}
++
++/* sum the individual fifo tx pending packet counts */
++static s16 brcms_txpktpendtot(struct brcms_c_info *wlc)
++{
++	return wlc->core->txpktpend[0] + wlc->core->txpktpend[1] +
++	       wlc->core->txpktpend[2] + wlc->core->txpktpend[3];
++}
++
++static bool brcms_is_mband_unlocked(struct brcms_c_info *wlc)
++{
++	return wlc->pub->_nbands > 1 && !wlc->bandlocked;
++}
++
++static int brcms_chspec_bw(u16 chanspec)
++{
++	if (CHSPEC_IS40(chanspec))
++		return BRCMS_40_MHZ;
++	if (CHSPEC_IS20(chanspec))
++		return BRCMS_20_MHZ;
++
++	return BRCMS_10_MHZ;
++}
++
++static void brcms_c_bsscfg_mfree(struct brcms_bss_cfg *cfg)
++{
++	if (cfg == NULL)
++		return;
++
++	kfree(cfg->current_bss);
++	kfree(cfg);
++}
++
++static void brcms_c_detach_mfree(struct brcms_c_info *wlc)
++{
++	if (wlc == NULL)
++		return;
++
++	brcms_c_bsscfg_mfree(wlc->bsscfg);
++	kfree(wlc->pub);
++	kfree(wlc->modulecb);
++	kfree(wlc->default_bss);
++	kfree(wlc->protection);
++	kfree(wlc->stf);
++	kfree(wlc->bandstate[0]);
++	kfree(wlc->corestate->macstat_snapshot);
++	kfree(wlc->corestate);
++	kfree(wlc->hw->bandstate[0]);
++	kfree(wlc->hw);
++
++	/* free the wlc */
++	kfree(wlc);
++	wlc = NULL;
++}
++
++static struct brcms_bss_cfg *brcms_c_bsscfg_malloc(uint unit)
++{
++	struct brcms_bss_cfg *cfg;
++
++	cfg = kzalloc(sizeof(struct brcms_bss_cfg), GFP_ATOMIC);
++	if (cfg == NULL)
++		goto fail;
++
++	cfg->current_bss = kzalloc(sizeof(struct brcms_bss_info), GFP_ATOMIC);
++	if (cfg->current_bss == NULL)
++		goto fail;
++
++	return cfg;
++
++ fail:
++	brcms_c_bsscfg_mfree(cfg);
++	return NULL;
++}
++
++static struct brcms_c_info *
++brcms_c_attach_malloc(uint unit, uint *err, uint devid)
++{
++	struct brcms_c_info *wlc;
++
++	wlc = kzalloc(sizeof(struct brcms_c_info), GFP_ATOMIC);
++	if (wlc == NULL) {
++		*err = 1002;
++		goto fail;
++	}
++
++	/* allocate struct brcms_c_pub state structure */
++	wlc->pub = kzalloc(sizeof(struct brcms_pub), GFP_ATOMIC);
++	if (wlc->pub == NULL) {
++		*err = 1003;
++		goto fail;
++	}
++	wlc->pub->wlc = wlc;
++
++	/* allocate struct brcms_hardware state structure */
++
++	wlc->hw = kzalloc(sizeof(struct brcms_hardware), GFP_ATOMIC);
++	if (wlc->hw == NULL) {
++		*err = 1005;
++		goto fail;
++	}
++	wlc->hw->wlc = wlc;
++
++	wlc->hw->bandstate[0] =
++		kzalloc(sizeof(struct brcms_hw_band) * MAXBANDS, GFP_ATOMIC);
++	if (wlc->hw->bandstate[0] == NULL) {
++		*err = 1006;
++		goto fail;
++	} else {
++		int i;
++
++		for (i = 1; i < MAXBANDS; i++)
++			wlc->hw->bandstate[i] = (struct brcms_hw_band *)
++			    ((unsigned long)wlc->hw->bandstate[0] +
++			     (sizeof(struct brcms_hw_band) * i));
++	}
++
++	wlc->modulecb =
++		kzalloc(sizeof(struct modulecb) * BRCMS_MAXMODULES, GFP_ATOMIC);
++	if (wlc->modulecb == NULL) {
++		*err = 1009;
++		goto fail;
++	}
++
++	wlc->default_bss = kzalloc(sizeof(struct brcms_bss_info), GFP_ATOMIC);
++	if (wlc->default_bss == NULL) {
++		*err = 1010;
++		goto fail;
++	}
++
++	wlc->bsscfg = brcms_c_bsscfg_malloc(unit);
++	if (wlc->bsscfg == NULL) {
++		*err = 1011;
++		goto fail;
++	}
++
++	wlc->protection = kzalloc(sizeof(struct brcms_protection),
++				  GFP_ATOMIC);
++	if (wlc->protection == NULL) {
++		*err = 1016;
++		goto fail;
++	}
++
++	wlc->stf = kzalloc(sizeof(struct brcms_stf), GFP_ATOMIC);
++	if (wlc->stf == NULL) {
++		*err = 1017;
++		goto fail;
++	}
++
++	wlc->bandstate[0] =
++		kzalloc(sizeof(struct brcms_band)*MAXBANDS, GFP_ATOMIC);
++	if (wlc->bandstate[0] == NULL) {
++		*err = 1025;
++		goto fail;
++	} else {
++		int i;
++
++		for (i = 1; i < MAXBANDS; i++)
++			wlc->bandstate[i] = (struct brcms_band *)
++				((unsigned long)wlc->bandstate[0]
++				+ (sizeof(struct brcms_band)*i));
++	}
++
++	wlc->corestate = kzalloc(sizeof(struct brcms_core), GFP_ATOMIC);
++	if (wlc->corestate == NULL) {
++		*err = 1026;
++		goto fail;
++	}
++
++	wlc->corestate->macstat_snapshot =
++		kzalloc(sizeof(struct macstat), GFP_ATOMIC);
++	if (wlc->corestate->macstat_snapshot == NULL) {
++		*err = 1027;
++		goto fail;
++	}
++
++	return wlc;
++
++ fail:
++	brcms_c_detach_mfree(wlc);
++	return NULL;
++}
++
++/*
++ * Update the slot timing for standard 11b/g (20us slots)
++ * or shortslot 11g (9us slots)
++ * The PSM needs to be suspended for this call.
++ */
++static void brcms_b_update_slot_timing(struct brcms_hardware *wlc_hw,
++					bool shortslot)
++{
++	struct bcma_device *core = wlc_hw->d11core;
++
++	if (shortslot) {
++		/* 11g short slot: 11a timing */
++		bcma_write16(core, D11REGOFFS(ifs_slot), 0x0207);
++		brcms_b_write_shm(wlc_hw, M_DOT11_SLOT, APHY_SLOT_TIME);
++	} else {
++		/* 11g long slot: 11b timing */
++		bcma_write16(core, D11REGOFFS(ifs_slot), 0x0212);
++		brcms_b_write_shm(wlc_hw, M_DOT11_SLOT, BPHY_SLOT_TIME);
++	}
++}
++
++/*
++ * calculate frame duration of a given rate and length, return
++ * time in usec unit
++ */
++static uint brcms_c_calc_frame_time(struct brcms_c_info *wlc, u32 ratespec,
++				    u8 preamble_type, uint mac_len)
++{
++	uint nsyms, dur = 0, Ndps, kNdps;
++	uint rate = rspec2rate(ratespec);
++
++	if (rate == 0) {
++		wiphy_err(wlc->wiphy, "wl%d: WAR: using rate of 1 mbps\n",
++			  wlc->pub->unit);
++		rate = BRCM_RATE_1M;
++	}
++
++	BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, preamble_type %d, len%d\n",
++		 wlc->pub->unit, ratespec, preamble_type, mac_len);
++
++	if (is_mcs_rate(ratespec)) {
++		uint mcs = ratespec & RSPEC_RATE_MASK;
++		int tot_streams = mcs_2_txstreams(mcs) + rspec_stc(ratespec);
++
++		dur = PREN_PREAMBLE + (tot_streams * PREN_PREAMBLE_EXT);
++		if (preamble_type == BRCMS_MM_PREAMBLE)
++			dur += PREN_MM_EXT;
++		/* 1000Ndbps = kbps * 4 */
++		kNdps = mcs_2_rate(mcs, rspec_is40mhz(ratespec),
++				   rspec_issgi(ratespec)) * 4;
++
++		if (rspec_stc(ratespec) == 0)
++			nsyms =
++			    CEIL((APHY_SERVICE_NBITS + 8 * mac_len +
++				  APHY_TAIL_NBITS) * 1000, kNdps);
++		else
++			/* STBC needs to have even number of symbols */
++			nsyms =
++			    2 *
++			    CEIL((APHY_SERVICE_NBITS + 8 * mac_len +
++				  APHY_TAIL_NBITS) * 1000, 2 * kNdps);
++
++		dur += APHY_SYMBOL_TIME * nsyms;
++		if (wlc->band->bandtype == BRCM_BAND_2G)
++			dur += DOT11_OFDM_SIGNAL_EXTENSION;
++	} else if (is_ofdm_rate(rate)) {
++		dur = APHY_PREAMBLE_TIME;
++		dur += APHY_SIGNAL_TIME;
++		/* Ndbps = Mbps * 4 = rate(500Kbps) * 2 */
++		Ndps = rate * 2;
++		/* NSyms = CEILING((SERVICE + 8*NBytes + TAIL) / Ndbps) */
++		nsyms =
++		    CEIL((APHY_SERVICE_NBITS + 8 * mac_len + APHY_TAIL_NBITS),
++			 Ndps);
++		dur += APHY_SYMBOL_TIME * nsyms;
++		if (wlc->band->bandtype == BRCM_BAND_2G)
++			dur += DOT11_OFDM_SIGNAL_EXTENSION;
++	} else {
++		/*
++		 * calc # bits * 2 so factor of 2 in rate (1/2 mbps)
++		 * will divide out
++		 */
++		mac_len = mac_len * 8 * 2;
++		/* calc ceiling of bits/rate = microseconds of air time */
++		dur = (mac_len + rate - 1) / rate;
++		if (preamble_type & BRCMS_SHORT_PREAMBLE)
++			dur += BPHY_PLCP_SHORT_TIME;
++		else
++			dur += BPHY_PLCP_TIME;
++	}
++	return dur;
++}
++
++static void brcms_c_write_inits(struct brcms_hardware *wlc_hw,
++				const struct d11init *inits)
++{
++	struct bcma_device *core = wlc_hw->d11core;
++	int i;
++	uint offset;
++	u16 size;
++	u32 value;
++
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
++
++	for (i = 0; inits[i].addr != cpu_to_le16(0xffff); i++) {
++		size = le16_to_cpu(inits[i].size);
++		offset = le16_to_cpu(inits[i].addr);
++		value = le32_to_cpu(inits[i].value);
++		if (size == 2)
++			bcma_write16(core, offset, value);
++		else if (size == 4)
++			bcma_write32(core, offset, value);
++		else
++			break;
++	}
++}
++
++static void brcms_c_write_mhf(struct brcms_hardware *wlc_hw, u16 *mhfs)
++{
++	u8 idx;
++	u16 addr[] = {
++		M_HOST_FLAGS1, M_HOST_FLAGS2, M_HOST_FLAGS3, M_HOST_FLAGS4,
++		M_HOST_FLAGS5
++	};
++
++	for (idx = 0; idx < MHFMAX; idx++)
++		brcms_b_write_shm(wlc_hw, addr[idx], mhfs[idx]);
++}
++
++static void brcms_c_ucode_bsinit(struct brcms_hardware *wlc_hw)
++{
++	struct wiphy *wiphy = wlc_hw->wlc->wiphy;
++	struct brcms_ucode *ucode = &wlc_hw->wlc->wl->ucode;
++
++	/* init microcode host flags */
++	brcms_c_write_mhf(wlc_hw, wlc_hw->band->mhfs);
++
++	/* do band-specific ucode IHR, SHM, and SCR inits */
++	if (D11REV_IS(wlc_hw->corerev, 23)) {
++		if (BRCMS_ISNPHY(wlc_hw->band))
++			brcms_c_write_inits(wlc_hw, ucode->d11n0bsinitvals16);
++		else
++			wiphy_err(wiphy, "%s: wl%d: unsupported phy in corerev"
++				  " %d\n", __func__, wlc_hw->unit,
++				  wlc_hw->corerev);
++	} else {
++		if (D11REV_IS(wlc_hw->corerev, 24)) {
++			if (BRCMS_ISLCNPHY(wlc_hw->band))
++				brcms_c_write_inits(wlc_hw,
++						    ucode->d11lcn0bsinitvals24);
++			else
++				wiphy_err(wiphy, "%s: wl%d: unsupported phy in"
++					  " core rev %d\n", __func__,
++					  wlc_hw->unit, wlc_hw->corerev);
++		} else {
++			wiphy_err(wiphy, "%s: wl%d: unsupported corerev %d\n",
++				__func__, wlc_hw->unit, wlc_hw->corerev);
++		}
++	}
++}
++
++static void brcms_b_core_ioctl(struct brcms_hardware *wlc_hw, u32 m, u32 v)
++{
++	struct bcma_device *core = wlc_hw->d11core;
++	u32 ioctl = bcma_aread32(core, BCMA_IOCTL) & ~m;
++
++	bcma_awrite32(core, BCMA_IOCTL, ioctl | v);
++}
++
++static void brcms_b_core_phy_clk(struct brcms_hardware *wlc_hw, bool clk)
++{
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d: clk %d\n", wlc_hw->unit, clk);
++
++	wlc_hw->phyclk = clk;
++
++	if (OFF == clk) {	/* clear gmode bit, put phy into reset */
++
++		brcms_b_core_ioctl(wlc_hw, (SICF_PRST | SICF_FGC | SICF_GMODE),
++				   (SICF_PRST | SICF_FGC));
++		udelay(1);
++		brcms_b_core_ioctl(wlc_hw, (SICF_PRST | SICF_FGC), SICF_PRST);
++		udelay(1);
++
++	} else {		/* take phy out of reset */
++
++		brcms_b_core_ioctl(wlc_hw, (SICF_PRST | SICF_FGC), SICF_FGC);
++		udelay(1);
++		brcms_b_core_ioctl(wlc_hw, SICF_FGC, 0);
++		udelay(1);
++
++	}
++}
++
++/* low-level band switch utility routine */
++static void brcms_c_setxband(struct brcms_hardware *wlc_hw, uint bandunit)
++{
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit,
++		bandunit);
++
++	wlc_hw->band = wlc_hw->bandstate[bandunit];
++
++	/*
++	 * BMAC_NOTE:
++	 *   until we eliminate need for wlc->band refs in low level code
++	 */
++	wlc_hw->wlc->band = wlc_hw->wlc->bandstate[bandunit];
++
++	/* set gmode core flag */
++	if (wlc_hw->sbclk && !wlc_hw->noreset) {
++		u32 gmode = 0;
++
++		if (bandunit == 0)
++			gmode = SICF_GMODE;
++
++		brcms_b_core_ioctl(wlc_hw, SICF_GMODE, gmode);
++	}
++}
++
++/* switch to new band but leave it inactive */
++static u32 brcms_c_setband_inact(struct brcms_c_info *wlc, uint bandunit)
++{
++	struct brcms_hardware *wlc_hw = wlc->hw;
++	u32 macintmask;
++	u32 macctrl;
++
++	BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit);
++	macctrl = bcma_read32(wlc_hw->d11core,
++			      D11REGOFFS(maccontrol));
++	WARN_ON((macctrl & MCTL_EN_MAC) != 0);
++
++	/* disable interrupts */
++	macintmask = brcms_intrsoff(wlc->wl);
++
++	/* radio off */
++	wlc_phy_switch_radio(wlc_hw->band->pi, OFF);
++
++	brcms_b_core_phy_clk(wlc_hw, OFF);
++
++	brcms_c_setxband(wlc_hw, bandunit);
++
++	return macintmask;
++}
++
++/* process an individual struct tx_status */
++static bool
++brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs)
++{
++	struct sk_buff *p;
++	uint queue;
++	struct d11txh *txh;
++	struct scb *scb = NULL;
++	bool free_pdu;
++	int tx_rts, tx_frame_count, tx_rts_count;
++	uint totlen, supr_status;
++	bool lastframe;
++	struct ieee80211_hdr *h;
++	u16 mcl;
++	struct ieee80211_tx_info *tx_info;
++	struct ieee80211_tx_rate *txrate;
++	int i;
++
++	/* discard intermediate indications for ucode with one legitimate case:
++	 *   e.g. if "useRTS" is set. ucode did a successful rts/cts exchange,
++	 *   but the subsequent tx of DATA failed. so it will start rts/cts
++	 *   from the beginning (resetting the rts transmission count)
++	 */
++	if (!(txs->status & TX_STATUS_AMPDU)
++	    && (txs->status & TX_STATUS_INTERMEDIATE)) {
++		BCMMSG(wlc->wiphy, "INTERMEDIATE but not AMPDU\n");
++		return false;
++	}
++
++	queue = txs->frameid & TXFID_QUEUE_MASK;
++	if (queue >= NFIFO) {
++		p = NULL;
++		goto fatal;
++	}
++
++	p = dma_getnexttxp(wlc->hw->di[queue], DMA_RANGE_TRANSMITTED);
++	if (p == NULL)
++		goto fatal;
++
++	txh = (struct d11txh *) (p->data);
++	mcl = le16_to_cpu(txh->MacTxControlLow);
++
++	if (txs->phyerr) {
++		if (brcm_msg_level & LOG_ERROR_VAL) {
++			wiphy_err(wlc->wiphy, "phyerr 0x%x, rate 0x%x\n",
++				  txs->phyerr, txh->MainRates);
++			brcms_c_print_txdesc(txh);
++		}
++		brcms_c_print_txstatus(txs);
++	}
++
++	if (txs->frameid != le16_to_cpu(txh->TxFrameID))
++		goto fatal;
++	tx_info = IEEE80211_SKB_CB(p);
++	h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN);
++
++	if (tx_info->control.sta)
++		scb = &wlc->pri_scb;
++
++	if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
++		brcms_c_ampdu_dotxstatus(wlc->ampdu, scb, p, txs);
++		return false;
++	}
++
++	supr_status = txs->status & TX_STATUS_SUPR_MASK;
++	if (supr_status == TX_STATUS_SUPR_BADCH)
++		BCMMSG(wlc->wiphy,
++		       "%s: Pkt tx suppressed, possibly channel %d\n",
++		       __func__, CHSPEC_CHANNEL(wlc->default_bss->chanspec));
++
++	tx_rts = le16_to_cpu(txh->MacTxControlLow) & TXC_SENDRTS;
++	tx_frame_count =
++	    (txs->status & TX_STATUS_FRM_RTX_MASK) >> TX_STATUS_FRM_RTX_SHIFT;
++	tx_rts_count =
++	    (txs->status & TX_STATUS_RTS_RTX_MASK) >> TX_STATUS_RTS_RTX_SHIFT;
++
++	lastframe = !ieee80211_has_morefrags(h->frame_control);
++
++	if (!lastframe) {
++		wiphy_err(wlc->wiphy, "Not last frame!\n");
++	} else {
++		/*
++		 * Set information to be consumed by Minstrel ht.
++		 *
++		 * The "fallback limit" is the number of tx attempts a given
++		 * MPDU is sent at the "primary" rate. Tx attempts beyond that
++		 * limit are sent at the "secondary" rate.
++		 * A 'short frame' does not exceed RTS treshold.
++		 */
++		u16 sfbl,	/* Short Frame Rate Fallback Limit */
++		    lfbl,	/* Long Frame Rate Fallback Limit */
++		    fbl;
++
++		if (queue < IEEE80211_NUM_ACS) {
++			sfbl = GFIELD(wlc->wme_retries[wme_fifo2ac[queue]],
++				      EDCF_SFB);
++			lfbl = GFIELD(wlc->wme_retries[wme_fifo2ac[queue]],
++				      EDCF_LFB);
++		} else {
++			sfbl = wlc->SFBL;
++			lfbl = wlc->LFBL;
++		}
++
++		txrate = tx_info->status.rates;
++		if (txrate[0].flags & IEEE80211_TX_RC_USE_RTS_CTS)
++			fbl = lfbl;
++		else
++			fbl = sfbl;
++
++		ieee80211_tx_info_clear_status(tx_info);
++
++		if ((tx_frame_count > fbl) && (txrate[1].idx >= 0)) {
++			/*
++			 * rate selection requested a fallback rate
++			 * and we used it
++			 */
++			txrate[0].count = fbl;
++			txrate[1].count = tx_frame_count - fbl;
++		} else {
++			/*
++			 * rate selection did not request fallback rate, or
++			 * we didn't need it
++			 */
++			txrate[0].count = tx_frame_count;
++			/*
++			 * rc80211_minstrel.c:minstrel_tx_status() expects
++			 * unused rates to be marked with idx = -1
++			 */
++			txrate[1].idx = -1;
++			txrate[1].count = 0;
++		}
++
++		/* clear the rest of the rates */
++		for (i = 2; i < IEEE80211_TX_MAX_RATES; i++) {
++			txrate[i].idx = -1;
++			txrate[i].count = 0;
++		}
++
++		if (txs->status & TX_STATUS_ACK_RCV)
++			tx_info->flags |= IEEE80211_TX_STAT_ACK;
++	}
++
++	totlen = p->len;
++	free_pdu = true;
++
++	brcms_c_txfifo_complete(wlc, queue, 1);
++
++	if (lastframe) {
++		/* remove PLCP & Broadcom tx descriptor header */
++		skb_pull(p, D11_PHY_HDR_LEN);
++		skb_pull(p, D11_TXH_LEN);
++		ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, p);
++	} else {
++		wiphy_err(wlc->wiphy, "%s: Not last frame => not calling "
++			  "tx_status\n", __func__);
++	}
++
++	return false;
++
++ fatal:
++	if (p)
++		brcmu_pkt_buf_free_skb(p);
++
++	return true;
++
++}
++
++/* process tx completion events in BMAC
++ * Return true if more tx status need to be processed. false otherwise.
++ */
++static bool
++brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal)
++{
++	bool morepending = false;
++	struct brcms_c_info *wlc = wlc_hw->wlc;
++	struct bcma_device *core;
++	struct tx_status txstatus, *txs;
++	u32 s1, s2;
++	uint n = 0;
++	/*
++	 * Param 'max_tx_num' indicates max. # tx status to process before
++	 * break out.
++	 */
++	uint max_tx_num = bound ? TXSBND : -1;
++
++	BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit);
++
++	txs = &txstatus;
++	core = wlc_hw->d11core;
++	*fatal = false;
++	s1 = bcma_read32(core, D11REGOFFS(frmtxstatus));
++	while (!(*fatal)
++	       && (s1 & TXS_V)) {
++
++		if (s1 == 0xffffffff) {
++			wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n",
++				wlc_hw->unit, __func__);
++			return morepending;
++		}
++		s2 = bcma_read32(core, D11REGOFFS(frmtxstatus2));
++
++		txs->status = s1 & TXS_STATUS_MASK;
++		txs->frameid = (s1 & TXS_FID_MASK) >> TXS_FID_SHIFT;
++		txs->sequence = s2 & TXS_SEQ_MASK;
++		txs->phyerr = (s2 & TXS_PTX_MASK) >> TXS_PTX_SHIFT;
++		txs->lasttxtime = 0;
++
++		*fatal = brcms_c_dotxstatus(wlc_hw->wlc, txs);
++
++		/* !give others some time to run! */
++		if (++n >= max_tx_num)
++			break;
++		s1 = bcma_read32(core, D11REGOFFS(frmtxstatus));
++	}
++
++	if (*fatal)
++		return 0;
++
++	if (n >= max_tx_num)
++		morepending = true;
++
++	if (!pktq_empty(&wlc->pkt_queue->q))
++		brcms_c_send_q(wlc);
++
++	return morepending;
++}
++
++static void brcms_c_tbtt(struct brcms_c_info *wlc)
++{
++	if (!wlc->bsscfg->BSS)
++		/*
++		 * DirFrmQ is now valid...defer setting until end
++		 * of ATIM window
++		 */
++		wlc->qvalid |= MCMD_DIRFRMQVAL;
++}
++
++/* set initial host flags value */
++static void
++brcms_c_mhfdef(struct brcms_c_info *wlc, u16 *mhfs, u16 mhf2_init)
++{
++	struct brcms_hardware *wlc_hw = wlc->hw;
++
++	memset(mhfs, 0, MHFMAX * sizeof(u16));
++
++	mhfs[MHF2] |= mhf2_init;
++
++	/* prohibit use of slowclock on multifunction boards */
++	if (wlc_hw->boardflags & BFL_NOPLLDOWN)
++		mhfs[MHF1] |= MHF1_FORCEFASTCLK;
++
++	if (BRCMS_ISNPHY(wlc_hw->band) && NREV_LT(wlc_hw->band->phyrev, 2)) {
++		mhfs[MHF2] |= MHF2_NPHY40MHZ_WAR;
++		mhfs[MHF1] |= MHF1_IQSWAP_WAR;
++	}
++}
++
++static uint
++dmareg(uint direction, uint fifonum)
++{
++	if (direction == DMA_TX)
++		return offsetof(struct d11regs, fifo64regs[fifonum].dmaxmt);
++	return offsetof(struct d11regs, fifo64regs[fifonum].dmarcv);
++}
++
++static bool brcms_b_attach_dmapio(struct brcms_c_info *wlc, uint j, bool wme)
++{
++	uint i;
++	char name[8];
++	/*
++	 * ucode host flag 2 needed for pio mode, independent of band and fifo
++	 */
++	u16 pio_mhf2 = 0;
++	struct brcms_hardware *wlc_hw = wlc->hw;
++	uint unit = wlc_hw->unit;
++	struct wiphy *wiphy = wlc->wiphy;
++
++	/* name and offsets for dma_attach */
++	snprintf(name, sizeof(name), "wl%d", unit);
++
++	if (wlc_hw->di[0] == NULL) {	/* Init FIFOs */
++		int dma_attach_err = 0;
++
++		/*
++		 * FIFO 0
++		 * TX: TX_AC_BK_FIFO (TX AC Background data packets)
++		 * RX: RX_FIFO (RX data packets)
++		 */
++		wlc_hw->di[0] = dma_attach(name, wlc_hw->sih, wlc_hw->d11core,
++					   (wme ? dmareg(DMA_TX, 0) : 0),
++					   dmareg(DMA_RX, 0),
++					   (wme ? NTXD : 0), NRXD,
++					   RXBUFSZ, -1, NRXBUFPOST,
++					   BRCMS_HWRXOFF, &brcm_msg_level);
++		dma_attach_err |= (NULL == wlc_hw->di[0]);
++
++		/*
++		 * FIFO 1
++		 * TX: TX_AC_BE_FIFO (TX AC Best-Effort data packets)
++		 *   (legacy) TX_DATA_FIFO (TX data packets)
++		 * RX: UNUSED
++		 */
++		wlc_hw->di[1] = dma_attach(name, wlc_hw->sih, wlc_hw->d11core,
++					   dmareg(DMA_TX, 1), 0,
++					   NTXD, 0, 0, -1, 0, 0,
++					   &brcm_msg_level);
++		dma_attach_err |= (NULL == wlc_hw->di[1]);
++
++		/*
++		 * FIFO 2
++		 * TX: TX_AC_VI_FIFO (TX AC Video data packets)
++		 * RX: UNUSED
++		 */
++		wlc_hw->di[2] = dma_attach(name, wlc_hw->sih, wlc_hw->d11core,
++					   dmareg(DMA_TX, 2), 0,
++					   NTXD, 0, 0, -1, 0, 0,
++					   &brcm_msg_level);
++		dma_attach_err |= (NULL == wlc_hw->di[2]);
++		/*
++		 * FIFO 3
++		 * TX: TX_AC_VO_FIFO (TX AC Voice data packets)
++		 *   (legacy) TX_CTL_FIFO (TX control & mgmt packets)
++		 */
++		wlc_hw->di[3] = dma_attach(name, wlc_hw->sih, wlc_hw->d11core,
++					   dmareg(DMA_TX, 3),
++					   0, NTXD, 0, 0, -1,
++					   0, 0, &brcm_msg_level);
++		dma_attach_err |= (NULL == wlc_hw->di[3]);
++/* Cleaner to leave this as if with AP defined */
++
++		if (dma_attach_err) {
++			wiphy_err(wiphy, "wl%d: wlc_attach: dma_attach failed"
++				  "\n", unit);
++			return false;
++		}
++
++		/* get pointer to dma engine tx flow control variable */
++		for (i = 0; i < NFIFO; i++)
++			if (wlc_hw->di[i])
++				wlc_hw->txavail[i] =
++				    (uint *) dma_getvar(wlc_hw->di[i],
++							"&txavail");
++	}
++
++	/* initial ucode host flags */
++	brcms_c_mhfdef(wlc, wlc_hw->band->mhfs, pio_mhf2);
++
++	return true;
++}
++
++static void brcms_b_detach_dmapio(struct brcms_hardware *wlc_hw)
++{
++	uint j;
++
++	for (j = 0; j < NFIFO; j++) {
++		if (wlc_hw->di[j]) {
++			dma_detach(wlc_hw->di[j]);
++			wlc_hw->di[j] = NULL;
++		}
++	}
++}
++
++/*
++ * Initialize brcms_c_info default values ...
++ * may get overrides later in this function
++ *  BMAC_NOTES, move low out and resolve the dangling ones
++ */
++static void brcms_b_info_init(struct brcms_hardware *wlc_hw)
++{
++	struct brcms_c_info *wlc = wlc_hw->wlc;
++
++	/* set default sw macintmask value */
++	wlc->defmacintmask = DEF_MACINTMASK;
++
++	/* various 802.11g modes */
++	wlc_hw->shortslot = false;
++
++	wlc_hw->SFBL = RETRY_SHORT_FB;
++	wlc_hw->LFBL = RETRY_LONG_FB;
++
++	/* default mac retry limits */
++	wlc_hw->SRL = RETRY_SHORT_DEF;
++	wlc_hw->LRL = RETRY_LONG_DEF;
++	wlc_hw->chanspec = ch20mhz_chspec(1);
++}
++
++static void brcms_b_wait_for_wake(struct brcms_hardware *wlc_hw)
++{
++	/* delay before first read of ucode state */
++	udelay(40);
++
++	/* wait until ucode is no longer asleep */
++	SPINWAIT((brcms_b_read_shm(wlc_hw, M_UCODE_DBGST) ==
++		  DBGST_ASLEEP), wlc_hw->wlc->fastpwrup_dly);
++}
++
++/* control chip clock to save power, enable dynamic clock or force fast clock */
++static void brcms_b_clkctl_clk(struct brcms_hardware *wlc_hw, enum bcma_clkmode mode)
++{
++	if (ai_get_cccaps(wlc_hw->sih) & CC_CAP_PMU) {
++		/* new chips with PMU, CCS_FORCEHT will distribute the HT clock
++		 * on backplane, but mac core will still run on ALP(not HT) when
++		 * it enters powersave mode, which means the FCA bit may not be
++		 * set. Should wakeup mac if driver wants it to run on HT.
++		 */
++
++		if (wlc_hw->clk) {
++			if (mode == BCMA_CLKMODE_FAST) {
++				bcma_set32(wlc_hw->d11core,
++					   D11REGOFFS(clk_ctl_st),
++					   CCS_FORCEHT);
++
++				udelay(64);
++
++				SPINWAIT(
++				    ((bcma_read32(wlc_hw->d11core,
++				      D11REGOFFS(clk_ctl_st)) &
++				      CCS_HTAVAIL) == 0),
++				      PMU_MAX_TRANSITION_DLY);
++				WARN_ON(!(bcma_read32(wlc_hw->d11core,
++					D11REGOFFS(clk_ctl_st)) &
++					CCS_HTAVAIL));
++			} else {
++				if ((ai_get_pmurev(wlc_hw->sih) == 0) &&
++				    (bcma_read32(wlc_hw->d11core,
++					D11REGOFFS(clk_ctl_st)) &
++					(CCS_FORCEHT | CCS_HTAREQ)))
++					SPINWAIT(
++					    ((bcma_read32(wlc_hw->d11core,
++					      offsetof(struct d11regs,
++						       clk_ctl_st)) &
++					      CCS_HTAVAIL) == 0),
++					      PMU_MAX_TRANSITION_DLY);
++				bcma_mask32(wlc_hw->d11core,
++					D11REGOFFS(clk_ctl_st),
++					~CCS_FORCEHT);
++			}
++		}
++		wlc_hw->forcefastclk = (mode == BCMA_CLKMODE_FAST);
++	} else {
++
++		/* old chips w/o PMU, force HT through cc,
++		 * then use FCA to verify mac is running fast clock
++		 */
++
++		wlc_hw->forcefastclk = ai_clkctl_cc(wlc_hw->sih, mode);
++
++		/* check fast clock is available (if core is not in reset) */
++		if (wlc_hw->forcefastclk && wlc_hw->clk)
++			WARN_ON(!(bcma_aread32(wlc_hw->d11core, BCMA_IOST) &
++				  SISF_FCLKA));
++
++		/*
++		 * keep the ucode wake bit on if forcefastclk is on since we
++		 * do not want ucode to put us back to slow clock when it dozes
++		 * for PM mode. Code below matches the wake override bit with
++		 * current forcefastclk state. Only setting bit in wake_override
++		 * instead of waking ucode immediately since old code had this
++		 * behavior. Older code set wlc->forcefastclk but only had the
++		 * wake happen if the wakup_ucode work (protected by an up
++		 * check) was executed just below.
++		 */
++		if (wlc_hw->forcefastclk)
++			mboolset(wlc_hw->wake_override,
++				 BRCMS_WAKE_OVERRIDE_FORCEFAST);
++		else
++			mboolclr(wlc_hw->wake_override,
++				 BRCMS_WAKE_OVERRIDE_FORCEFAST);
++	}
++}
++
++/* set or clear ucode host flag bits
++ * it has an optimization for no-change write
++ * it only writes through shared memory when the core has clock;
++ * pre-CLK changes should use wlc_write_mhf to get around the optimization
++ *
++ *
++ * bands values are: BRCM_BAND_AUTO <--- Current band only
++ *                   BRCM_BAND_5G   <--- 5G band only
++ *                   BRCM_BAND_2G   <--- 2G band only
++ *                   BRCM_BAND_ALL  <--- All bands
++ */
++void
++brcms_b_mhf(struct brcms_hardware *wlc_hw, u8 idx, u16 mask, u16 val,
++	     int bands)
++{
++	u16 save;
++	u16 addr[MHFMAX] = {
++		M_HOST_FLAGS1, M_HOST_FLAGS2, M_HOST_FLAGS3, M_HOST_FLAGS4,
++		M_HOST_FLAGS5
++	};
++	struct brcms_hw_band *band;
++
++	if ((val & ~mask) || idx >= MHFMAX)
++		return; /* error condition */
++
++	switch (bands) {
++		/* Current band only or all bands,
++		 * then set the band to current band
++		 */
++	case BRCM_BAND_AUTO:
++	case BRCM_BAND_ALL:
++		band = wlc_hw->band;
++		break;
++	case BRCM_BAND_5G:
++		band = wlc_hw->bandstate[BAND_5G_INDEX];
++		break;
++	case BRCM_BAND_2G:
++		band = wlc_hw->bandstate[BAND_2G_INDEX];
++		break;
++	default:
++		band = NULL;	/* error condition */
++	}
++
++	if (band) {
++		save = band->mhfs[idx];
++		band->mhfs[idx] = (band->mhfs[idx] & ~mask) | val;
++
++		/* optimization: only write through if changed, and
++		 * changed band is the current band
++		 */
++		if (wlc_hw->clk && (band->mhfs[idx] != save)
++		    && (band == wlc_hw->band))
++			brcms_b_write_shm(wlc_hw, addr[idx],
++					   (u16) band->mhfs[idx]);
++	}
++
++	if (bands == BRCM_BAND_ALL) {
++		wlc_hw->bandstate[0]->mhfs[idx] =
++		    (wlc_hw->bandstate[0]->mhfs[idx] & ~mask) | val;
++		wlc_hw->bandstate[1]->mhfs[idx] =
++		    (wlc_hw->bandstate[1]->mhfs[idx] & ~mask) | val;
++	}
++}
++
++/* set the maccontrol register to desired reset state and
++ * initialize the sw cache of the register
++ */
++static void brcms_c_mctrl_reset(struct brcms_hardware *wlc_hw)
++{
++	/* IHR accesses are always enabled, PSM disabled, HPS off and WAKE on */
++	wlc_hw->maccontrol = 0;
++	wlc_hw->suspended_fifos = 0;
++	wlc_hw->wake_override = 0;
++	wlc_hw->mute_override = 0;
++	brcms_b_mctrl(wlc_hw, ~0, MCTL_IHR_EN | MCTL_WAKE);
++}
++
++/*
++ * write the software state of maccontrol and
++ * overrides to the maccontrol register
++ */
++static void brcms_c_mctrl_write(struct brcms_hardware *wlc_hw)
++{
++	u32 maccontrol = wlc_hw->maccontrol;
++
++	/* OR in the wake bit if overridden */
++	if (wlc_hw->wake_override)
++		maccontrol |= MCTL_WAKE;
++
++	/* set AP and INFRA bits for mute if needed */
++	if (wlc_hw->mute_override) {
++		maccontrol &= ~(MCTL_AP);
++		maccontrol |= MCTL_INFRA;
++	}
++
++	bcma_write32(wlc_hw->d11core, D11REGOFFS(maccontrol),
++		     maccontrol);
++}
++
++/* set or clear maccontrol bits */
++void brcms_b_mctrl(struct brcms_hardware *wlc_hw, u32 mask, u32 val)
++{
++	u32 maccontrol;
++	u32 new_maccontrol;
++
++	if (val & ~mask)
++		return; /* error condition */
++	maccontrol = wlc_hw->maccontrol;
++	new_maccontrol = (maccontrol & ~mask) | val;
++
++	/* if the new maccontrol value is the same as the old, nothing to do */
++	if (new_maccontrol == maccontrol)
++		return;
++
++	/* something changed, cache the new value */
++	wlc_hw->maccontrol = new_maccontrol;
++
++	/* write the new values with overrides applied */
++	brcms_c_mctrl_write(wlc_hw);
++}
++
++void brcms_c_ucode_wake_override_set(struct brcms_hardware *wlc_hw,
++				 u32 override_bit)
++{
++	if (wlc_hw->wake_override || (wlc_hw->maccontrol & MCTL_WAKE)) {
++		mboolset(wlc_hw->wake_override, override_bit);
++		return;
++	}
++
++	mboolset(wlc_hw->wake_override, override_bit);
++
++	brcms_c_mctrl_write(wlc_hw);
++	brcms_b_wait_for_wake(wlc_hw);
++}
++
++void brcms_c_ucode_wake_override_clear(struct brcms_hardware *wlc_hw,
++				   u32 override_bit)
++{
++	mboolclr(wlc_hw->wake_override, override_bit);
++
++	if (wlc_hw->wake_override || (wlc_hw->maccontrol & MCTL_WAKE))
++		return;
++
++	brcms_c_mctrl_write(wlc_hw);
++}
++
++/* When driver needs ucode to stop beaconing, it has to make sure that
++ * MCTL_AP is clear and MCTL_INFRA is set
++ * Mode           MCTL_AP        MCTL_INFRA
++ * AP                1              1
++ * STA               0              1 <--- This will ensure no beacons
++ * IBSS              0              0
++ */
++static void brcms_c_ucode_mute_override_set(struct brcms_hardware *wlc_hw)
++{
++	wlc_hw->mute_override = 1;
++
++	/* if maccontrol already has AP == 0 and INFRA == 1 without this
++	 * override, then there is no change to write
++	 */
++	if ((wlc_hw->maccontrol & (MCTL_AP | MCTL_INFRA)) == MCTL_INFRA)
++		return;
++
++	brcms_c_mctrl_write(wlc_hw);
++}
++
++/* Clear the override on AP and INFRA bits */
++static void brcms_c_ucode_mute_override_clear(struct brcms_hardware *wlc_hw)
++{
++	if (wlc_hw->mute_override == 0)
++		return;
++
++	wlc_hw->mute_override = 0;
++
++	/* if maccontrol already has AP == 0 and INFRA == 1 without this
++	 * override, then there is no change to write
++	 */
++	if ((wlc_hw->maccontrol & (MCTL_AP | MCTL_INFRA)) == MCTL_INFRA)
++		return;
++
++	brcms_c_mctrl_write(wlc_hw);
++}
++
++/*
++ * Write a MAC address to the given match reg offset in the RXE match engine.
++ */
++static void
++brcms_b_set_addrmatch(struct brcms_hardware *wlc_hw, int match_reg_offset,
++		       const u8 *addr)
++{
++	struct bcma_device *core = wlc_hw->d11core;
++	u16 mac_l;
++	u16 mac_m;
++	u16 mac_h;
++
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d: brcms_b_set_addrmatch\n",
++		 wlc_hw->unit);
++
++	mac_l = addr[0] | (addr[1] << 8);
++	mac_m = addr[2] | (addr[3] << 8);
++	mac_h = addr[4] | (addr[5] << 8);
++
++	/* enter the MAC addr into the RXE match registers */
++	bcma_write16(core, D11REGOFFS(rcm_ctl),
++		     RCM_INC_DATA | match_reg_offset);
++	bcma_write16(core, D11REGOFFS(rcm_mat_data), mac_l);
++	bcma_write16(core, D11REGOFFS(rcm_mat_data), mac_m);
++	bcma_write16(core, D11REGOFFS(rcm_mat_data), mac_h);
++}
++
++void
++brcms_b_write_template_ram(struct brcms_hardware *wlc_hw, int offset, int len,
++			    void *buf)
++{
++	struct bcma_device *core = wlc_hw->d11core;
++	u32 word;
++	__le32 word_le;
++	__be32 word_be;
++	bool be_bit;
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
++
++	bcma_write32(core, D11REGOFFS(tplatewrptr), offset);
++
++	/* if MCTL_BIGEND bit set in mac control register,
++	 * the chip swaps data in fifo, as well as data in
++	 * template ram
++	 */
++	be_bit = (bcma_read32(core, D11REGOFFS(maccontrol)) & MCTL_BIGEND) != 0;
++
++	while (len > 0) {
++		memcpy(&word, buf, sizeof(u32));
++
++		if (be_bit) {
++			word_be = cpu_to_be32(word);
++			word = *(u32 *)&word_be;
++		} else {
++			word_le = cpu_to_le32(word);
++			word = *(u32 *)&word_le;
++		}
++
++		bcma_write32(core, D11REGOFFS(tplatewrdata), word);
++
++		buf = (u8 *) buf + sizeof(u32);
++		len -= sizeof(u32);
++	}
++}
++
++static void brcms_b_set_cwmin(struct brcms_hardware *wlc_hw, u16 newmin)
++{
++	wlc_hw->band->CWmin = newmin;
++
++	bcma_write32(wlc_hw->d11core, D11REGOFFS(objaddr),
++		     OBJADDR_SCR_SEL | S_DOT11_CWMIN);
++	(void)bcma_read32(wlc_hw->d11core, D11REGOFFS(objaddr));
++	bcma_write32(wlc_hw->d11core, D11REGOFFS(objdata), newmin);
++}
++
++static void brcms_b_set_cwmax(struct brcms_hardware *wlc_hw, u16 newmax)
++{
++	wlc_hw->band->CWmax = newmax;
++
++	bcma_write32(wlc_hw->d11core, D11REGOFFS(objaddr),
++		     OBJADDR_SCR_SEL | S_DOT11_CWMAX);
++	(void)bcma_read32(wlc_hw->d11core, D11REGOFFS(objaddr));
++	bcma_write32(wlc_hw->d11core, D11REGOFFS(objdata), newmax);
++}
++
++void brcms_b_bw_set(struct brcms_hardware *wlc_hw, u16 bw)
++{
++	bool fastclk;
++
++	/* request FAST clock if not on */
++	fastclk = wlc_hw->forcefastclk;
++	if (!fastclk)
++		brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST);
++
++	wlc_phy_bw_state_set(wlc_hw->band->pi, bw);
++
++	brcms_b_phy_reset(wlc_hw);
++	wlc_phy_init(wlc_hw->band->pi, wlc_phy_chanspec_get(wlc_hw->band->pi));
++
++	/* restore the clk */
++	if (!fastclk)
++		brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_DYNAMIC);
++}
++
++static void brcms_b_upd_synthpu(struct brcms_hardware *wlc_hw)
++{
++	u16 v;
++	struct brcms_c_info *wlc = wlc_hw->wlc;
++	/* update SYNTHPU_DLY */
++
++	if (BRCMS_ISLCNPHY(wlc->band))
++		v = SYNTHPU_DLY_LPPHY_US;
++	else if (BRCMS_ISNPHY(wlc->band) && (NREV_GE(wlc->band->phyrev, 3)))
++		v = SYNTHPU_DLY_NPHY_US;
++	else
++		v = SYNTHPU_DLY_BPHY_US;
++
++	brcms_b_write_shm(wlc_hw, M_SYNTHPU_DLY, v);
++}
++
++static void brcms_c_ucode_txant_set(struct brcms_hardware *wlc_hw)
++{
++	u16 phyctl;
++	u16 phytxant = wlc_hw->bmac_phytxant;
++	u16 mask = PHY_TXC_ANT_MASK;
++
++	/* set the Probe Response frame phy control word */
++	phyctl = brcms_b_read_shm(wlc_hw, M_CTXPRS_BLK + C_CTX_PCTLWD_POS);
++	phyctl = (phyctl & ~mask) | phytxant;
++	brcms_b_write_shm(wlc_hw, M_CTXPRS_BLK + C_CTX_PCTLWD_POS, phyctl);
++
++	/* set the Response (ACK/CTS) frame phy control word */
++	phyctl = brcms_b_read_shm(wlc_hw, M_RSP_PCTLWD);
++	phyctl = (phyctl & ~mask) | phytxant;
++	brcms_b_write_shm(wlc_hw, M_RSP_PCTLWD, phyctl);
++}
++
++static u16 brcms_b_ofdm_ratetable_offset(struct brcms_hardware *wlc_hw,
++					 u8 rate)
++{
++	uint i;
++	u8 plcp_rate = 0;
++	struct plcp_signal_rate_lookup {
++		u8 rate;
++		u8 signal_rate;
++	};
++	/* OFDM RATE sub-field of PLCP SIGNAL field, per 802.11 sec 17.3.4.1 */
++	const struct plcp_signal_rate_lookup rate_lookup[] = {
++		{BRCM_RATE_6M, 0xB},
++		{BRCM_RATE_9M, 0xF},
++		{BRCM_RATE_12M, 0xA},
++		{BRCM_RATE_18M, 0xE},
++		{BRCM_RATE_24M, 0x9},
++		{BRCM_RATE_36M, 0xD},
++		{BRCM_RATE_48M, 0x8},
++		{BRCM_RATE_54M, 0xC}
++	};
++
++	for (i = 0; i < ARRAY_SIZE(rate_lookup); i++) {
++		if (rate == rate_lookup[i].rate) {
++			plcp_rate = rate_lookup[i].signal_rate;
++			break;
++		}
++	}
++
++	/* Find the SHM pointer to the rate table entry by looking in the
++	 * Direct-map Table
++	 */
++	return 2 * brcms_b_read_shm(wlc_hw, M_RT_DIRMAP_A + (plcp_rate * 2));
++}
++
++static void brcms_upd_ofdm_pctl1_table(struct brcms_hardware *wlc_hw)
++{
++	u8 rate;
++	u8 rates[8] = {
++		BRCM_RATE_6M, BRCM_RATE_9M, BRCM_RATE_12M, BRCM_RATE_18M,
++		BRCM_RATE_24M, BRCM_RATE_36M, BRCM_RATE_48M, BRCM_RATE_54M
++	};
++	u16 entry_ptr;
++	u16 pctl1;
++	uint i;
++
++	if (!BRCMS_PHY_11N_CAP(wlc_hw->band))
++		return;
++
++	/* walk the phy rate table and update the entries */
++	for (i = 0; i < ARRAY_SIZE(rates); i++) {
++		rate = rates[i];
++
++		entry_ptr = brcms_b_ofdm_ratetable_offset(wlc_hw, rate);
++
++		/* read the SHM Rate Table entry OFDM PCTL1 values */
++		pctl1 =
++		    brcms_b_read_shm(wlc_hw, entry_ptr + M_RT_OFDM_PCTL1_POS);
++
++		/* modify the value */
++		pctl1 &= ~PHY_TXC1_MODE_MASK;
++		pctl1 |= (wlc_hw->hw_stf_ss_opmode << PHY_TXC1_MODE_SHIFT);
++
++		/* Update the SHM Rate Table entry OFDM PCTL1 values */
++		brcms_b_write_shm(wlc_hw, entry_ptr + M_RT_OFDM_PCTL1_POS,
++				   pctl1);
++	}
++}
++
++/* band-specific init */
++static void brcms_b_bsinit(struct brcms_c_info *wlc, u16 chanspec)
++{
++	struct brcms_hardware *wlc_hw = wlc->hw;
++
++	BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit,
++		wlc_hw->band->bandunit);
++
++	brcms_c_ucode_bsinit(wlc_hw);
++
++	wlc_phy_init(wlc_hw->band->pi, chanspec);
++
++	brcms_c_ucode_txant_set(wlc_hw);
++
++	/*
++	 * cwmin is band-specific, update hardware
++	 * with value for current band
++	 */
++	brcms_b_set_cwmin(wlc_hw, wlc_hw->band->CWmin);
++	brcms_b_set_cwmax(wlc_hw, wlc_hw->band->CWmax);
++
++	brcms_b_update_slot_timing(wlc_hw,
++				   wlc_hw->band->bandtype == BRCM_BAND_5G ?
++				   true : wlc_hw->shortslot);
++
++	/* write phytype and phyvers */
++	brcms_b_write_shm(wlc_hw, M_PHYTYPE, (u16) wlc_hw->band->phytype);
++	brcms_b_write_shm(wlc_hw, M_PHYVER, (u16) wlc_hw->band->phyrev);
++
++	/*
++	 * initialize the txphyctl1 rate table since
++	 * shmem is shared between bands
++	 */
++	brcms_upd_ofdm_pctl1_table(wlc_hw);
++
++	brcms_b_upd_synthpu(wlc_hw);
++}
++
++/* Perform a soft reset of the PHY PLL */
++void brcms_b_core_phypll_reset(struct brcms_hardware *wlc_hw)
++{
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
++
++	ai_cc_reg(wlc_hw->sih, offsetof(struct chipcregs, chipcontrol_addr),
++		  ~0, 0);
++	udelay(1);
++	ai_cc_reg(wlc_hw->sih, offsetof(struct chipcregs, chipcontrol_data),
++		  0x4, 0);
++	udelay(1);
++	ai_cc_reg(wlc_hw->sih, offsetof(struct chipcregs, chipcontrol_data),
++		  0x4, 4);
++	udelay(1);
++	ai_cc_reg(wlc_hw->sih, offsetof(struct chipcregs, chipcontrol_data),
++		  0x4, 0);
++	udelay(1);
++}
++
++/* light way to turn on phy clock without reset for NPHY only
++ *  refer to brcms_b_core_phy_clk for full version
++ */
++void brcms_b_phyclk_fgc(struct brcms_hardware *wlc_hw, bool clk)
++{
++	/* support(necessary for NPHY and HYPHY) only */
++	if (!BRCMS_ISNPHY(wlc_hw->band))
++		return;
++
++	if (ON == clk)
++		brcms_b_core_ioctl(wlc_hw, SICF_FGC, SICF_FGC);
++	else
++		brcms_b_core_ioctl(wlc_hw, SICF_FGC, 0);
++
++}
++
++void brcms_b_macphyclk_set(struct brcms_hardware *wlc_hw, bool clk)
++{
++	if (ON == clk)
++		brcms_b_core_ioctl(wlc_hw, SICF_MPCLKE, SICF_MPCLKE);
++	else
++		brcms_b_core_ioctl(wlc_hw, SICF_MPCLKE, 0);
++}
++
++void brcms_b_phy_reset(struct brcms_hardware *wlc_hw)
++{
++	struct brcms_phy_pub *pih = wlc_hw->band->pi;
++	u32 phy_bw_clkbits;
++	bool phy_in_reset = false;
++
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
++
++	if (pih == NULL)
++		return;
++
++	phy_bw_clkbits = wlc_phy_clk_bwbits(wlc_hw->band->pi);
++
++	/* Specific reset sequence required for NPHY rev 3 and 4 */
++	if (BRCMS_ISNPHY(wlc_hw->band) && NREV_GE(wlc_hw->band->phyrev, 3) &&
++	    NREV_LE(wlc_hw->band->phyrev, 4)) {
++		/* Set the PHY bandwidth */
++		brcms_b_core_ioctl(wlc_hw, SICF_BWMASK, phy_bw_clkbits);
++
++		udelay(1);
++
++		/* Perform a soft reset of the PHY PLL */
++		brcms_b_core_phypll_reset(wlc_hw);
++
++		/* reset the PHY */
++		brcms_b_core_ioctl(wlc_hw, (SICF_PRST | SICF_PCLKE),
++				   (SICF_PRST | SICF_PCLKE));
++		phy_in_reset = true;
++	} else {
++		brcms_b_core_ioctl(wlc_hw,
++				   (SICF_PRST | SICF_PCLKE | SICF_BWMASK),
++				   (SICF_PRST | SICF_PCLKE | phy_bw_clkbits));
++	}
++
++	udelay(2);
++	brcms_b_core_phy_clk(wlc_hw, ON);
++
++	if (pih)
++		wlc_phy_anacore(pih, ON);
++}
++
++/* switch to and initialize new band */
++static void brcms_b_setband(struct brcms_hardware *wlc_hw, uint bandunit,
++			    u16 chanspec) {
++	struct brcms_c_info *wlc = wlc_hw->wlc;
++	u32 macintmask;
++
++	/* Enable the d11 core before accessing it */
++	if (!bcma_core_is_enabled(wlc_hw->d11core)) {
++		bcma_core_enable(wlc_hw->d11core, 0);
++		brcms_c_mctrl_reset(wlc_hw);
++	}
++
++	macintmask = brcms_c_setband_inact(wlc, bandunit);
++
++	if (!wlc_hw->up)
++		return;
++
++	brcms_b_core_phy_clk(wlc_hw, ON);
++
++	/* band-specific initializations */
++	brcms_b_bsinit(wlc, chanspec);
++
++	/*
++	 * If there are any pending software interrupt bits,
++	 * then replace these with a harmless nonzero value
++	 * so brcms_c_dpc() will re-enable interrupts when done.
++	 */
++	if (wlc->macintstatus)
++		wlc->macintstatus = MI_DMAINT;
++
++	/* restore macintmask */
++	brcms_intrsrestore(wlc->wl, macintmask);
++
++	/* ucode should still be suspended.. */
++	WARN_ON((bcma_read32(wlc_hw->d11core, D11REGOFFS(maccontrol)) &
++		 MCTL_EN_MAC) != 0);
++}
++
++static bool brcms_c_isgoodchip(struct brcms_hardware *wlc_hw)
++{
++
++	/* reject unsupported corerev */
++	if (!CONF_HAS(D11CONF, wlc_hw->corerev)) {
++		wiphy_err(wlc_hw->wlc->wiphy, "unsupported core rev %d\n",
++			  wlc_hw->corerev);
++		return false;
++	}
++
++	return true;
++}
++
++/* Validate some board info parameters */
++static bool brcms_c_validboardtype(struct brcms_hardware *wlc_hw)
++{
++	uint boardrev = wlc_hw->boardrev;
++
++	/* 4 bits each for board type, major, minor, and tiny version */
++	uint brt = (boardrev & 0xf000) >> 12;
++	uint b0 = (boardrev & 0xf00) >> 8;
++	uint b1 = (boardrev & 0xf0) >> 4;
++	uint b2 = boardrev & 0xf;
++
++	/* voards from other vendors are always considered valid */
++	if (ai_get_boardvendor(wlc_hw->sih) != PCI_VENDOR_ID_BROADCOM)
++		return true;
++
++	/* do some boardrev sanity checks when boardvendor is Broadcom */
++	if (boardrev == 0)
++		return false;
++
++	if (boardrev <= 0xff)
++		return true;
++
++	if ((brt > 2) || (brt == 0) || (b0 > 9) || (b0 == 0) || (b1 > 9)
++		|| (b2 > 9))
++		return false;
++
++	return true;
++}
++
++static void brcms_c_get_macaddr(struct brcms_hardware *wlc_hw, u8 etheraddr[ETH_ALEN])
++{
++	struct ssb_sprom *sprom = &wlc_hw->d11core->bus->sprom;
++
++	/* If macaddr exists, use it (Sromrev4, CIS, ...). */
++	if (!is_zero_ether_addr(sprom->il0mac)) {
++		memcpy(etheraddr, sprom->il0mac, 6);
++		return;
++	}
++
++	if (wlc_hw->_nbands > 1)
++		memcpy(etheraddr, sprom->et1mac, 6);
++	else
++		memcpy(etheraddr, sprom->il0mac, 6);
++}
++
++/* power both the pll and external oscillator on/off */
++static void brcms_b_xtal(struct brcms_hardware *wlc_hw, bool want)
++{
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d: want %d\n", wlc_hw->unit, want);
++
++	/*
++	 * dont power down if plldown is false or
++	 * we must poll hw radio disable
++	 */
++	if (!want && wlc_hw->pllreq)
++		return;
++
++	wlc_hw->sbclk = want;
++	if (!wlc_hw->sbclk) {
++		wlc_hw->clk = false;
++		if (wlc_hw->band && wlc_hw->band->pi)
++			wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, false);
++	}
++}
++
++/*
++ * Return true if radio is disabled, otherwise false.
++ * hw radio disable signal is an external pin, users activate it asynchronously
++ * this function could be called when driver is down and w/o clock
++ * it operates on different registers depending on corerev and boardflag.
++ */
++static bool brcms_b_radio_read_hwdisabled(struct brcms_hardware *wlc_hw)
++{
++	bool v, clk, xtal;
++	u32 flags = 0;
++
++	xtal = wlc_hw->sbclk;
++	if (!xtal)
++		brcms_b_xtal(wlc_hw, ON);
++
++	/* may need to take core out of reset first */
++	clk = wlc_hw->clk;
++	if (!clk) {
++		/*
++		 * mac no longer enables phyclk automatically when driver
++		 * accesses phyreg throughput mac. This can be skipped since
++		 * only mac reg is accessed below
++		 */
++		flags |= SICF_PCLKE;
++
++		/*
++		 * TODO: test suspend/resume
++		 *
++		 * AI chip doesn't restore bar0win2 on
++		 * hibernation/resume, need sw fixup
++		 */
++
++		bcma_core_enable(wlc_hw->d11core, flags);
++		brcms_c_mctrl_reset(wlc_hw);
++	}
++
++	v = ((bcma_read32(wlc_hw->d11core,
++			  D11REGOFFS(phydebug)) & PDBG_RFD) != 0);
++
++	/* put core back into reset */
++	if (!clk)
++		bcma_core_disable(wlc_hw->d11core, 0);
++
++	if (!xtal)
++		brcms_b_xtal(wlc_hw, OFF);
++
++	return v;
++}
++
++static bool wlc_dma_rxreset(struct brcms_hardware *wlc_hw, uint fifo)
++{
++	struct dma_pub *di = wlc_hw->di[fifo];
++	return dma_rxreset(di);
++}
++
++/* d11 core reset
++ *   ensure fask clock during reset
++ *   reset dma
++ *   reset d11(out of reset)
++ *   reset phy(out of reset)
++ *   clear software macintstatus for fresh new start
++ * one testing hack wlc_hw->noreset will bypass the d11/phy reset
++ */
++void brcms_b_corereset(struct brcms_hardware *wlc_hw, u32 flags)
++{
++	uint i;
++	bool fastclk;
++
++	if (flags == BRCMS_USE_COREFLAGS)
++		flags = (wlc_hw->band->pi ? wlc_hw->band->core_flags : 0);
++
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
++
++	/* request FAST clock if not on  */
++	fastclk = wlc_hw->forcefastclk;
++	if (!fastclk)
++		brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST);
++
++	/* reset the dma engines except first time thru */
++	if (bcma_core_is_enabled(wlc_hw->d11core)) {
++		for (i = 0; i < NFIFO; i++)
++			if ((wlc_hw->di[i]) && (!dma_txreset(wlc_hw->di[i])))
++				wiphy_err(wlc_hw->wlc->wiphy, "wl%d: %s: "
++					  "dma_txreset[%d]: cannot stop dma\n",
++					   wlc_hw->unit, __func__, i);
++
++		if ((wlc_hw->di[RX_FIFO])
++		    && (!wlc_dma_rxreset(wlc_hw, RX_FIFO)))
++			wiphy_err(wlc_hw->wlc->wiphy, "wl%d: %s: dma_rxreset"
++				  "[%d]: cannot stop dma\n",
++				  wlc_hw->unit, __func__, RX_FIFO);
++	}
++	/* if noreset, just stop the psm and return */
++	if (wlc_hw->noreset) {
++		wlc_hw->wlc->macintstatus = 0;	/* skip wl_dpc after down */
++		brcms_b_mctrl(wlc_hw, MCTL_PSM_RUN | MCTL_EN_MAC, 0);
++		return;
++	}
++
++	/*
++	 * mac no longer enables phyclk automatically when driver accesses
++	 * phyreg throughput mac, AND phy_reset is skipped at early stage when
++	 * band->pi is invalid. need to enable PHY CLK
++	 */
++	flags |= SICF_PCLKE;
++
++	/*
++	 * reset the core
++	 * In chips with PMU, the fastclk request goes through d11 core
++	 * reg 0x1e0, which is cleared by the core_reset. have to re-request it.
++	 *
++	 * This adds some delay and we can optimize it by also requesting
++	 * fastclk through chipcommon during this period if necessary. But
++	 * that has to work coordinate with other driver like mips/arm since
++	 * they may touch chipcommon as well.
++	 */
++	wlc_hw->clk = false;
++	bcma_core_enable(wlc_hw->d11core, flags);
++	wlc_hw->clk = true;
++	if (wlc_hw->band && wlc_hw->band->pi)
++		wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, true);
++
++	brcms_c_mctrl_reset(wlc_hw);
++
++	if (ai_get_cccaps(wlc_hw->sih) & CC_CAP_PMU)
++		brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST);
++
++	brcms_b_phy_reset(wlc_hw);
++
++	/* turn on PHY_PLL */
++	brcms_b_core_phypll_ctl(wlc_hw, true);
++
++	/* clear sw intstatus */
++	wlc_hw->wlc->macintstatus = 0;
++
++	/* restore the clk setting */
++	if (!fastclk)
++		brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_DYNAMIC);
++}
++
++/* txfifo sizes needs to be modified(increased) since the newer cores
++ * have more memory.
++ */
++static void brcms_b_corerev_fifofixup(struct brcms_hardware *wlc_hw)
++{
++	struct bcma_device *core = wlc_hw->d11core;
++	u16 fifo_nu;
++	u16 txfifo_startblk = TXFIFO_START_BLK, txfifo_endblk;
++	u16 txfifo_def, txfifo_def1;
++	u16 txfifo_cmd;
++
++	/* tx fifos start at TXFIFO_START_BLK from the Base address */
++	txfifo_startblk = TXFIFO_START_BLK;
++
++	/* sequence of operations:  reset fifo, set fifo size, reset fifo */
++	for (fifo_nu = 0; fifo_nu < NFIFO; fifo_nu++) {
++
++		txfifo_endblk = txfifo_startblk + wlc_hw->xmtfifo_sz[fifo_nu];
++		txfifo_def = (txfifo_startblk & 0xff) |
++		    (((txfifo_endblk - 1) & 0xff) << TXFIFO_FIFOTOP_SHIFT);
++		txfifo_def1 = ((txfifo_startblk >> 8) & 0x1) |
++		    ((((txfifo_endblk -
++			1) >> 8) & 0x1) << TXFIFO_FIFOTOP_SHIFT);
++		txfifo_cmd =
++		    TXFIFOCMD_RESET_MASK | (fifo_nu << TXFIFOCMD_FIFOSEL_SHIFT);
++
++		bcma_write16(core, D11REGOFFS(xmtfifocmd), txfifo_cmd);
++		bcma_write16(core, D11REGOFFS(xmtfifodef), txfifo_def);
++		bcma_write16(core, D11REGOFFS(xmtfifodef1), txfifo_def1);
++
++		bcma_write16(core, D11REGOFFS(xmtfifocmd), txfifo_cmd);
++
++		txfifo_startblk += wlc_hw->xmtfifo_sz[fifo_nu];
++	}
++	/*
++	 * need to propagate to shm location to be in sync since ucode/hw won't
++	 * do this
++	 */
++	brcms_b_write_shm(wlc_hw, M_FIFOSIZE0,
++			   wlc_hw->xmtfifo_sz[TX_AC_BE_FIFO]);
++	brcms_b_write_shm(wlc_hw, M_FIFOSIZE1,
++			   wlc_hw->xmtfifo_sz[TX_AC_VI_FIFO]);
++	brcms_b_write_shm(wlc_hw, M_FIFOSIZE2,
++			   ((wlc_hw->xmtfifo_sz[TX_AC_VO_FIFO] << 8) | wlc_hw->
++			    xmtfifo_sz[TX_AC_BK_FIFO]));
++	brcms_b_write_shm(wlc_hw, M_FIFOSIZE3,
++			   ((wlc_hw->xmtfifo_sz[TX_ATIM_FIFO] << 8) | wlc_hw->
++			    xmtfifo_sz[TX_BCMC_FIFO]));
++}
++
++/* This function is used for changing the tsf frac register
++ * If spur avoidance mode is off, the mac freq will be 80/120/160Mhz
++ * If spur avoidance mode is on1, the mac freq will be 82/123/164Mhz
++ * If spur avoidance mode is on2, the mac freq will be 84/126/168Mhz
++ * HTPHY Formula is 2^26/freq(MHz) e.g.
++ * For spuron2 - 126MHz -> 2^26/126 = 532610.0
++ *  - 532610 = 0x82082 => tsf_clk_frac_h = 0x8, tsf_clk_frac_l = 0x2082
++ * For spuron: 123MHz -> 2^26/123    = 545600.5
++ *  - 545601 = 0x85341 => tsf_clk_frac_h = 0x8, tsf_clk_frac_l = 0x5341
++ * For spur off: 120MHz -> 2^26/120    = 559240.5
++ *  - 559241 = 0x88889 => tsf_clk_frac_h = 0x8, tsf_clk_frac_l = 0x8889
++ */
++
++void brcms_b_switch_macfreq(struct brcms_hardware *wlc_hw, u8 spurmode)
++{
++	struct bcma_device *core = wlc_hw->d11core;
++
++	if ((ai_get_chip_id(wlc_hw->sih) == BCM43224_CHIP_ID) ||
++	    (ai_get_chip_id(wlc_hw->sih) == BCM43225_CHIP_ID)) {
++		if (spurmode == WL_SPURAVOID_ON2) {	/* 126Mhz */
++			bcma_write16(core, D11REGOFFS(tsf_clk_frac_l), 0x2082);
++			bcma_write16(core, D11REGOFFS(tsf_clk_frac_h), 0x8);
++		} else if (spurmode == WL_SPURAVOID_ON1) {	/* 123Mhz */
++			bcma_write16(core, D11REGOFFS(tsf_clk_frac_l), 0x5341);
++			bcma_write16(core, D11REGOFFS(tsf_clk_frac_h), 0x8);
++		} else {	/* 120Mhz */
++			bcma_write16(core, D11REGOFFS(tsf_clk_frac_l), 0x8889);
++			bcma_write16(core, D11REGOFFS(tsf_clk_frac_h), 0x8);
++		}
++	} else if (BRCMS_ISLCNPHY(wlc_hw->band)) {
++		if (spurmode == WL_SPURAVOID_ON1) {	/* 82Mhz */
++			bcma_write16(core, D11REGOFFS(tsf_clk_frac_l), 0x7CE0);
++			bcma_write16(core, D11REGOFFS(tsf_clk_frac_h), 0xC);
++		} else {	/* 80Mhz */
++			bcma_write16(core, D11REGOFFS(tsf_clk_frac_l), 0xCCCD);
++			bcma_write16(core, D11REGOFFS(tsf_clk_frac_h), 0xC);
++		}
++	}
++}
++
++/* Initialize GPIOs that are controlled by D11 core */
++static void brcms_c_gpio_init(struct brcms_c_info *wlc)
++{
++	struct brcms_hardware *wlc_hw = wlc->hw;
++	u32 gc, gm;
++
++	/* use GPIO select 0 to get all gpio signals from the gpio out reg */
++	brcms_b_mctrl(wlc_hw, MCTL_GPOUT_SEL_MASK, 0);
++
++	/*
++	 * Common GPIO setup:
++	 *      G0 = LED 0 = WLAN Activity
++	 *      G1 = LED 1 = WLAN 2.4 GHz Radio State
++	 *      G2 = LED 2 = WLAN 5 GHz Radio State
++	 *      G4 = radio disable input (HI enabled, LO disabled)
++	 */
++
++	gc = gm = 0;
++
++	/* Allocate GPIOs for mimo antenna diversity feature */
++	if (wlc_hw->antsel_type == ANTSEL_2x3) {
++		/* Enable antenna diversity, use 2x3 mode */
++		brcms_b_mhf(wlc_hw, MHF3, MHF3_ANTSEL_EN,
++			     MHF3_ANTSEL_EN, BRCM_BAND_ALL);
++		brcms_b_mhf(wlc_hw, MHF3, MHF3_ANTSEL_MODE,
++			     MHF3_ANTSEL_MODE, BRCM_BAND_ALL);
++
++		/* init superswitch control */
++		wlc_phy_antsel_init(wlc_hw->band->pi, false);
++
++	} else if (wlc_hw->antsel_type == ANTSEL_2x4) {
++		gm |= gc |= (BOARD_GPIO_12 | BOARD_GPIO_13);
++		/*
++		 * The board itself is powered by these GPIOs
++		 * (when not sending pattern) so set them high
++		 */
++		bcma_set16(wlc_hw->d11core, D11REGOFFS(psm_gpio_oe),
++			   (BOARD_GPIO_12 | BOARD_GPIO_13));
++		bcma_set16(wlc_hw->d11core, D11REGOFFS(psm_gpio_out),
++			   (BOARD_GPIO_12 | BOARD_GPIO_13));
++
++		/* Enable antenna diversity, use 2x4 mode */
++		brcms_b_mhf(wlc_hw, MHF3, MHF3_ANTSEL_EN,
++			     MHF3_ANTSEL_EN, BRCM_BAND_ALL);
++		brcms_b_mhf(wlc_hw, MHF3, MHF3_ANTSEL_MODE, 0,
++			     BRCM_BAND_ALL);
++
++		/* Configure the desired clock to be 4Mhz */
++		brcms_b_write_shm(wlc_hw, M_ANTSEL_CLKDIV,
++				   ANTSEL_CLKDIV_4MHZ);
++	}
++
++	/*
++	 * gpio 9 controls the PA. ucode is responsible
++	 * for wiggling out and oe
++	 */
++	if (wlc_hw->boardflags & BFL_PACTRL)
++		gm |= gc |= BOARD_GPIO_PACTRL;
++
++	/* apply to gpiocontrol register */
++	bcma_chipco_gpio_control(&wlc_hw->d11core->bus->drv_cc, gm, gc);
++}
++
++static void brcms_ucode_write(struct brcms_hardware *wlc_hw,
++			      const __le32 ucode[], const size_t nbytes)
++{
++	struct bcma_device *core = wlc_hw->d11core;
++	uint i;
++	uint count;
++
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
++
++	count = (nbytes / sizeof(u32));
++
++	bcma_write32(core, D11REGOFFS(objaddr),
++		     OBJADDR_AUTO_INC | OBJADDR_UCM_SEL);
++	(void)bcma_read32(core, D11REGOFFS(objaddr));
++	for (i = 0; i < count; i++)
++		bcma_write32(core, D11REGOFFS(objdata), le32_to_cpu(ucode[i]));
++
++}
++
++static void brcms_ucode_download(struct brcms_hardware *wlc_hw)
++{
++	struct brcms_c_info *wlc;
++	struct brcms_ucode *ucode = &wlc_hw->wlc->wl->ucode;
++
++	wlc = wlc_hw->wlc;
++
++	if (wlc_hw->ucode_loaded)
++		return;
++
++	if (D11REV_IS(wlc_hw->corerev, 23)) {
++		if (BRCMS_ISNPHY(wlc_hw->band)) {
++			brcms_ucode_write(wlc_hw, ucode->bcm43xx_16_mimo,
++					  ucode->bcm43xx_16_mimosz);
++			wlc_hw->ucode_loaded = true;
++		} else
++			wiphy_err(wlc->wiphy, "%s: wl%d: unsupported phy in "
++				  "corerev %d\n",
++				  __func__, wlc_hw->unit, wlc_hw->corerev);
++	} else if (D11REV_IS(wlc_hw->corerev, 24)) {
++		if (BRCMS_ISLCNPHY(wlc_hw->band)) {
++			brcms_ucode_write(wlc_hw, ucode->bcm43xx_24_lcn,
++					  ucode->bcm43xx_24_lcnsz);
++			wlc_hw->ucode_loaded = true;
++		} else {
++			wiphy_err(wlc->wiphy, "%s: wl%d: unsupported phy in "
++				  "corerev %d\n",
++				  __func__, wlc_hw->unit, wlc_hw->corerev);
++		}
++	}
++}
++
++void brcms_b_txant_set(struct brcms_hardware *wlc_hw, u16 phytxant)
++{
++	/* update sw state */
++	wlc_hw->bmac_phytxant = phytxant;
++
++	/* push to ucode if up */
++	if (!wlc_hw->up)
++		return;
++	brcms_c_ucode_txant_set(wlc_hw);
++
++}
++
++u16 brcms_b_get_txant(struct brcms_hardware *wlc_hw)
++{
++	return (u16) wlc_hw->wlc->stf->txant;
++}
++
++void brcms_b_antsel_type_set(struct brcms_hardware *wlc_hw, u8 antsel_type)
++{
++	wlc_hw->antsel_type = antsel_type;
++
++	/* Update the antsel type for phy module to use */
++	wlc_phy_antsel_type_set(wlc_hw->band->pi, antsel_type);
++}
++
++static void brcms_b_fifoerrors(struct brcms_hardware *wlc_hw)
++{
++	bool fatal = false;
++	uint unit;
++	uint intstatus, idx;
++	struct bcma_device *core = wlc_hw->d11core;
++	struct wiphy *wiphy = wlc_hw->wlc->wiphy;
++
++	unit = wlc_hw->unit;
++
++	for (idx = 0; idx < NFIFO; idx++) {
++		/* read intstatus register and ignore any non-error bits */
++		intstatus =
++			bcma_read32(core,
++				    D11REGOFFS(intctrlregs[idx].intstatus)) &
++			I_ERRORS;
++		if (!intstatus)
++			continue;
++
++		BCMMSG(wlc_hw->wlc->wiphy, "wl%d: intstatus%d 0x%x\n",
++			unit, idx, intstatus);
++
++		if (intstatus & I_RO) {
++			wiphy_err(wiphy, "wl%d: fifo %d: receive fifo "
++				  "overflow\n", unit, idx);
++			fatal = true;
++		}
++
++		if (intstatus & I_PC) {
++			wiphy_err(wiphy, "wl%d: fifo %d: descriptor error\n",
++				 unit, idx);
++			fatal = true;
++		}
++
++		if (intstatus & I_PD) {
++			wiphy_err(wiphy, "wl%d: fifo %d: data error\n", unit,
++				  idx);
++			fatal = true;
++		}
++
++		if (intstatus & I_DE) {
++			wiphy_err(wiphy, "wl%d: fifo %d: descriptor protocol "
++				  "error\n", unit, idx);
++			fatal = true;
++		}
++
++		if (intstatus & I_RU)
++			wiphy_err(wiphy, "wl%d: fifo %d: receive descriptor "
++				  "underflow\n", idx, unit);
++
++		if (intstatus & I_XU) {
++			wiphy_err(wiphy, "wl%d: fifo %d: transmit fifo "
++				  "underflow\n", idx, unit);
++			fatal = true;
++		}
++
++		if (fatal) {
++			brcms_fatal_error(wlc_hw->wlc->wl); /* big hammer */
++			break;
++		} else
++			bcma_write32(core,
++				     D11REGOFFS(intctrlregs[idx].intstatus),
++				     intstatus);
++	}
++}
++
++void brcms_c_intrson(struct brcms_c_info *wlc)
++{
++	struct brcms_hardware *wlc_hw = wlc->hw;
++	wlc->macintmask = wlc->defmacintmask;
++	bcma_write32(wlc_hw->d11core, D11REGOFFS(macintmask), wlc->macintmask);
++}
++
++u32 brcms_c_intrsoff(struct brcms_c_info *wlc)
++{
++	struct brcms_hardware *wlc_hw = wlc->hw;
++	u32 macintmask;
++
++	if (!wlc_hw->clk)
++		return 0;
++
++	macintmask = wlc->macintmask;	/* isr can still happen */
++
++	bcma_write32(wlc_hw->d11core, D11REGOFFS(macintmask), 0);
++	(void)bcma_read32(wlc_hw->d11core, D11REGOFFS(macintmask));
++	udelay(1);		/* ensure int line is no longer driven */
++	wlc->macintmask = 0;
++
++	/* return previous macintmask; resolve race between us and our isr */
++	return wlc->macintstatus ? 0 : macintmask;
++}
++
++void brcms_c_intrsrestore(struct brcms_c_info *wlc, u32 macintmask)
++{
++	struct brcms_hardware *wlc_hw = wlc->hw;
++	if (!wlc_hw->clk)
++		return;
++
++	wlc->macintmask = macintmask;
++	bcma_write32(wlc_hw->d11core, D11REGOFFS(macintmask), wlc->macintmask);
++}
++
++/* assumes that the d11 MAC is enabled */
++static void brcms_b_tx_fifo_suspend(struct brcms_hardware *wlc_hw,
++				    uint tx_fifo)
++{
++	u8 fifo = 1 << tx_fifo;
++
++	/* Two clients of this code, 11h Quiet period and scanning. */
++
++	/* only suspend if not already suspended */
++	if ((wlc_hw->suspended_fifos & fifo) == fifo)
++		return;
++
++	/* force the core awake only if not already */
++	if (wlc_hw->suspended_fifos == 0)
++		brcms_c_ucode_wake_override_set(wlc_hw,
++						BRCMS_WAKE_OVERRIDE_TXFIFO);
++
++	wlc_hw->suspended_fifos |= fifo;
++
++	if (wlc_hw->di[tx_fifo]) {
++		/*
++		 * Suspending AMPDU transmissions in the middle can cause
++		 * underflow which may result in mismatch between ucode and
++		 * driver so suspend the mac before suspending the FIFO
++		 */
++		if (BRCMS_PHY_11N_CAP(wlc_hw->band))
++			brcms_c_suspend_mac_and_wait(wlc_hw->wlc);
++
++		dma_txsuspend(wlc_hw->di[tx_fifo]);
++
++		if (BRCMS_PHY_11N_CAP(wlc_hw->band))
++			brcms_c_enable_mac(wlc_hw->wlc);
++	}
++}
++
++static void brcms_b_tx_fifo_resume(struct brcms_hardware *wlc_hw,
++				   uint tx_fifo)
++{
++	/* BMAC_NOTE: BRCMS_TX_FIFO_ENAB is done in brcms_c_dpc() for DMA case
++	 * but need to be done here for PIO otherwise the watchdog will catch
++	 * the inconsistency and fire
++	 */
++	/* Two clients of this code, 11h Quiet period and scanning. */
++	if (wlc_hw->di[tx_fifo])
++		dma_txresume(wlc_hw->di[tx_fifo]);
++
++	/* allow core to sleep again */
++	if (wlc_hw->suspended_fifos == 0)
++		return;
++	else {
++		wlc_hw->suspended_fifos &= ~(1 << tx_fifo);
++		if (wlc_hw->suspended_fifos == 0)
++			brcms_c_ucode_wake_override_clear(wlc_hw,
++						BRCMS_WAKE_OVERRIDE_TXFIFO);
++	}
++}
++
++/* precondition: requires the mac core to be enabled */
++static void brcms_b_mute(struct brcms_hardware *wlc_hw, bool mute_tx)
++{
++	static const u8 null_ether_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0};
++
++	if (mute_tx) {
++		/* suspend tx fifos */
++		brcms_b_tx_fifo_suspend(wlc_hw, TX_DATA_FIFO);
++		brcms_b_tx_fifo_suspend(wlc_hw, TX_CTL_FIFO);
++		brcms_b_tx_fifo_suspend(wlc_hw, TX_AC_BK_FIFO);
++		brcms_b_tx_fifo_suspend(wlc_hw, TX_AC_VI_FIFO);
++
++		/* zero the address match register so we do not send ACKs */
++		brcms_b_set_addrmatch(wlc_hw, RCM_MAC_OFFSET,
++				       null_ether_addr);
++	} else {
++		/* resume tx fifos */
++		brcms_b_tx_fifo_resume(wlc_hw, TX_DATA_FIFO);
++		brcms_b_tx_fifo_resume(wlc_hw, TX_CTL_FIFO);
++		brcms_b_tx_fifo_resume(wlc_hw, TX_AC_BK_FIFO);
++		brcms_b_tx_fifo_resume(wlc_hw, TX_AC_VI_FIFO);
++
++		/* Restore address */
++		brcms_b_set_addrmatch(wlc_hw, RCM_MAC_OFFSET,
++				       wlc_hw->etheraddr);
++	}
++
++	wlc_phy_mute_upd(wlc_hw->band->pi, mute_tx, 0);
++
++	if (mute_tx)
++		brcms_c_ucode_mute_override_set(wlc_hw);
++	else
++		brcms_c_ucode_mute_override_clear(wlc_hw);
++}
++
++void
++brcms_c_mute(struct brcms_c_info *wlc, bool mute_tx)
++{
++	brcms_b_mute(wlc->hw, mute_tx);
++}
++
++/*
++ * Read and clear macintmask and macintstatus and intstatus registers.
++ * This routine should be called with interrupts off
++ * Return:
++ *   -1 if brcms_deviceremoved(wlc) evaluates to true;
++ *   0 if the interrupt is not for us, or we are in some special cases;
++ *   device interrupt status bits otherwise.
++ */
++static inline u32 wlc_intstatus(struct brcms_c_info *wlc, bool in_isr)
++{
++	struct brcms_hardware *wlc_hw = wlc->hw;
++	struct bcma_device *core = wlc_hw->d11core;
++	u32 macintstatus;
++
++	/* macintstatus includes a DMA interrupt summary bit */
++	macintstatus = bcma_read32(core, D11REGOFFS(macintstatus));
++
++	BCMMSG(wlc->wiphy, "wl%d: macintstatus: 0x%x\n", wlc_hw->unit,
++		 macintstatus);
++
++	/* detect cardbus removed, in power down(suspend) and in reset */
++	if (brcms_deviceremoved(wlc))
++		return -1;
++
++	/* brcms_deviceremoved() succeeds even when the core is still resetting,
++	 * handle that case here.
++	 */
++	if (macintstatus == 0xffffffff)
++		return 0;
++
++	/* defer unsolicited interrupts */
++	macintstatus &= (in_isr ? wlc->macintmask : wlc->defmacintmask);
++
++	/* if not for us */
++	if (macintstatus == 0)
++		return 0;
++
++	/* interrupts are already turned off for CFE build
++	 * Caution: For CFE Turning off the interrupts again has some undesired
++	 * consequences
++	 */
++	/* turn off the interrupts */
++	bcma_write32(core, D11REGOFFS(macintmask), 0);
++	(void)bcma_read32(core, D11REGOFFS(macintmask));
++	wlc->macintmask = 0;
++
++	/* clear device interrupts */
++	bcma_write32(core, D11REGOFFS(macintstatus), macintstatus);
++
++	/* MI_DMAINT is indication of non-zero intstatus */
++	if (macintstatus & MI_DMAINT)
++		/*
++		 * only fifo interrupt enabled is I_RI in
++		 * RX_FIFO. If MI_DMAINT is set, assume it
++		 * is set and clear the interrupt.
++		 */
++		bcma_write32(core, D11REGOFFS(intctrlregs[RX_FIFO].intstatus),
++			     DEF_RXINTMASK);
++
++	return macintstatus;
++}
++
++/* Update wlc->macintstatus and wlc->intstatus[]. */
++/* Return true if they are updated successfully. false otherwise */
++bool brcms_c_intrsupd(struct brcms_c_info *wlc)
++{
++	u32 macintstatus;
++
++	/* read and clear macintstatus and intstatus registers */
++	macintstatus = wlc_intstatus(wlc, false);
++
++	/* device is removed */
++	if (macintstatus == 0xffffffff)
++		return false;
++
++	/* update interrupt status in software */
++	wlc->macintstatus |= macintstatus;
++
++	return true;
++}
++
++/*
++ * First-level interrupt processing.
++ * Return true if this was our interrupt, false otherwise.
++ * *wantdpc will be set to true if further brcms_c_dpc() processing is required,
++ * false otherwise.
++ */
++bool brcms_c_isr(struct brcms_c_info *wlc, bool *wantdpc)
++{
++	struct brcms_hardware *wlc_hw = wlc->hw;
++	u32 macintstatus;
++
++	*wantdpc = false;
++
++	if (!wlc_hw->up || !wlc->macintmask)
++		return false;
++
++	/* read and clear macintstatus and intstatus registers */
++	macintstatus = wlc_intstatus(wlc, true);
++
++	if (macintstatus == 0xffffffff)
++		wiphy_err(wlc->wiphy, "DEVICEREMOVED detected in the ISR code"
++			  " path\n");
++
++	/* it is not for us */
++	if (macintstatus == 0)
++		return false;
++
++	*wantdpc = true;
++
++	/* save interrupt status bits */
++	wlc->macintstatus = macintstatus;
++
++	return true;
++
++}
++
++void brcms_c_suspend_mac_and_wait(struct brcms_c_info *wlc)
++{
++	struct brcms_hardware *wlc_hw = wlc->hw;
++	struct bcma_device *core = wlc_hw->d11core;
++	u32 mc, mi;
++	struct wiphy *wiphy = wlc->wiphy;
++
++	BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit,
++		wlc_hw->band->bandunit);
++
++	/*
++	 * Track overlapping suspend requests
++	 */
++	wlc_hw->mac_suspend_depth++;
++	if (wlc_hw->mac_suspend_depth > 1)
++		return;
++
++	/* force the core awake */
++	brcms_c_ucode_wake_override_set(wlc_hw, BRCMS_WAKE_OVERRIDE_MACSUSPEND);
++
++	mc = bcma_read32(core, D11REGOFFS(maccontrol));
++
++	if (mc == 0xffffffff) {
++		wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit,
++			  __func__);
++		brcms_down(wlc->wl);
++		return;
++	}
++	WARN_ON(mc & MCTL_PSM_JMP_0);
++	WARN_ON(!(mc & MCTL_PSM_RUN));
++	WARN_ON(!(mc & MCTL_EN_MAC));
++
++	mi = bcma_read32(core, D11REGOFFS(macintstatus));
++	if (mi == 0xffffffff) {
++		wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit,
++			  __func__);
++		brcms_down(wlc->wl);
++		return;
++	}
++	WARN_ON(mi & MI_MACSSPNDD);
++
++	brcms_b_mctrl(wlc_hw, MCTL_EN_MAC, 0);
++
++	SPINWAIT(!(bcma_read32(core, D11REGOFFS(macintstatus)) & MI_MACSSPNDD),
++		 BRCMS_MAX_MAC_SUSPEND);
++
++	if (!(bcma_read32(core, D11REGOFFS(macintstatus)) & MI_MACSSPNDD)) {
++		wiphy_err(wiphy, "wl%d: wlc_suspend_mac_and_wait: waited %d uS"
++			  " and MI_MACSSPNDD is still not on.\n",
++			  wlc_hw->unit, BRCMS_MAX_MAC_SUSPEND);
++		wiphy_err(wiphy, "wl%d: psmdebug 0x%08x, phydebug 0x%08x, "
++			  "psm_brc 0x%04x\n", wlc_hw->unit,
++			  bcma_read32(core, D11REGOFFS(psmdebug)),
++			  bcma_read32(core, D11REGOFFS(phydebug)),
++			  bcma_read16(core, D11REGOFFS(psm_brc)));
++	}
++
++	mc = bcma_read32(core, D11REGOFFS(maccontrol));
++	if (mc == 0xffffffff) {
++		wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit,
++			  __func__);
++		brcms_down(wlc->wl);
++		return;
++	}
++	WARN_ON(mc & MCTL_PSM_JMP_0);
++	WARN_ON(!(mc & MCTL_PSM_RUN));
++	WARN_ON(mc & MCTL_EN_MAC);
++}
++
++void brcms_c_enable_mac(struct brcms_c_info *wlc)
++{
++	struct brcms_hardware *wlc_hw = wlc->hw;
++	struct bcma_device *core = wlc_hw->d11core;
++	u32 mc, mi;
++
++	BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit,
++		wlc->band->bandunit);
++
++	/*
++	 * Track overlapping suspend requests
++	 */
++	wlc_hw->mac_suspend_depth--;
++	if (wlc_hw->mac_suspend_depth > 0)
++		return;
++
++	mc = bcma_read32(core, D11REGOFFS(maccontrol));
++	WARN_ON(mc & MCTL_PSM_JMP_0);
++	WARN_ON(mc & MCTL_EN_MAC);
++	WARN_ON(!(mc & MCTL_PSM_RUN));
++
++	brcms_b_mctrl(wlc_hw, MCTL_EN_MAC, MCTL_EN_MAC);
++	bcma_write32(core, D11REGOFFS(macintstatus), MI_MACSSPNDD);
++
++	mc = bcma_read32(core, D11REGOFFS(maccontrol));
++	WARN_ON(mc & MCTL_PSM_JMP_0);
++	WARN_ON(!(mc & MCTL_EN_MAC));
++	WARN_ON(!(mc & MCTL_PSM_RUN));
++
++	mi = bcma_read32(core, D11REGOFFS(macintstatus));
++	WARN_ON(mi & MI_MACSSPNDD);
++
++	brcms_c_ucode_wake_override_clear(wlc_hw,
++					  BRCMS_WAKE_OVERRIDE_MACSUSPEND);
++}
++
++void brcms_b_band_stf_ss_set(struct brcms_hardware *wlc_hw, u8 stf_mode)
++{
++	wlc_hw->hw_stf_ss_opmode = stf_mode;
++
++	if (wlc_hw->clk)
++		brcms_upd_ofdm_pctl1_table(wlc_hw);
++}
++
++static bool brcms_b_validate_chip_access(struct brcms_hardware *wlc_hw)
++{
++	struct bcma_device *core = wlc_hw->d11core;
++	u32 w, val;
++	struct wiphy *wiphy = wlc_hw->wlc->wiphy;
++
++	BCMMSG(wiphy, "wl%d\n", wlc_hw->unit);
++
++	/* Validate dchip register access */
++
++	bcma_write32(core, D11REGOFFS(objaddr), OBJADDR_SHM_SEL | 0);
++	(void)bcma_read32(core, D11REGOFFS(objaddr));
++	w = bcma_read32(core, D11REGOFFS(objdata));
++
++	/* Can we write and read back a 32bit register? */
++	bcma_write32(core, D11REGOFFS(objaddr), OBJADDR_SHM_SEL | 0);
++	(void)bcma_read32(core, D11REGOFFS(objaddr));
++	bcma_write32(core, D11REGOFFS(objdata), (u32) 0xaa5555aa);
++
++	bcma_write32(core, D11REGOFFS(objaddr), OBJADDR_SHM_SEL | 0);
++	(void)bcma_read32(core, D11REGOFFS(objaddr));
++	val = bcma_read32(core, D11REGOFFS(objdata));
++	if (val != (u32) 0xaa5555aa) {
++		wiphy_err(wiphy, "wl%d: validate_chip_access: SHM = 0x%x, "
++			  "expected 0xaa5555aa\n", wlc_hw->unit, val);
++		return false;
++	}
++
++	bcma_write32(core, D11REGOFFS(objaddr), OBJADDR_SHM_SEL | 0);
++	(void)bcma_read32(core, D11REGOFFS(objaddr));
++	bcma_write32(core, D11REGOFFS(objdata), (u32) 0x55aaaa55);
++
++	bcma_write32(core, D11REGOFFS(objaddr), OBJADDR_SHM_SEL | 0);
++	(void)bcma_read32(core, D11REGOFFS(objaddr));
++	val = bcma_read32(core, D11REGOFFS(objdata));
++	if (val != (u32) 0x55aaaa55) {
++		wiphy_err(wiphy, "wl%d: validate_chip_access: SHM = 0x%x, "
++			  "expected 0x55aaaa55\n", wlc_hw->unit, val);
++		return false;
++	}
++
++	bcma_write32(core, D11REGOFFS(objaddr), OBJADDR_SHM_SEL | 0);
++	(void)bcma_read32(core, D11REGOFFS(objaddr));
++	bcma_write32(core, D11REGOFFS(objdata), w);
++
++	/* clear CFPStart */
++	bcma_write32(core, D11REGOFFS(tsf_cfpstart), 0);
++
++	w = bcma_read32(core, D11REGOFFS(maccontrol));
++	if ((w != (MCTL_IHR_EN | MCTL_WAKE)) &&
++	    (w != (MCTL_IHR_EN | MCTL_GMODE | MCTL_WAKE))) {
++		wiphy_err(wiphy, "wl%d: validate_chip_access: maccontrol = "
++			  "0x%x, expected 0x%x or 0x%x\n", wlc_hw->unit, w,
++			  (MCTL_IHR_EN | MCTL_WAKE),
++			  (MCTL_IHR_EN | MCTL_GMODE | MCTL_WAKE));
++		return false;
++	}
++
++	return true;
++}
++
++#define PHYPLL_WAIT_US	100000
++
++void brcms_b_core_phypll_ctl(struct brcms_hardware *wlc_hw, bool on)
++{
++	struct bcma_device *core = wlc_hw->d11core;
++	u32 tmp;
++
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
++
++	tmp = 0;
++
++	if (on) {
++		if ((ai_get_chip_id(wlc_hw->sih) == BCM4313_CHIP_ID)) {
++			bcma_set32(core, D11REGOFFS(clk_ctl_st),
++				   CCS_ERSRC_REQ_HT |
++				   CCS_ERSRC_REQ_D11PLL |
++				   CCS_ERSRC_REQ_PHYPLL);
++			SPINWAIT((bcma_read32(core, D11REGOFFS(clk_ctl_st)) &
++				  CCS_ERSRC_AVAIL_HT) != CCS_ERSRC_AVAIL_HT,
++				 PHYPLL_WAIT_US);
++
++			tmp = bcma_read32(core, D11REGOFFS(clk_ctl_st));
++			if ((tmp & CCS_ERSRC_AVAIL_HT) != CCS_ERSRC_AVAIL_HT)
++				wiphy_err(wlc_hw->wlc->wiphy, "%s: turn on PHY"
++					  " PLL failed\n", __func__);
++		} else {
++			bcma_set32(core, D11REGOFFS(clk_ctl_st),
++				   tmp | CCS_ERSRC_REQ_D11PLL |
++				   CCS_ERSRC_REQ_PHYPLL);
++			SPINWAIT((bcma_read32(core, D11REGOFFS(clk_ctl_st)) &
++				  (CCS_ERSRC_AVAIL_D11PLL |
++				   CCS_ERSRC_AVAIL_PHYPLL)) !=
++				 (CCS_ERSRC_AVAIL_D11PLL |
++				  CCS_ERSRC_AVAIL_PHYPLL), PHYPLL_WAIT_US);
++
++			tmp = bcma_read32(core, D11REGOFFS(clk_ctl_st));
++			if ((tmp &
++			     (CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL))
++			    !=
++			    (CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL))
++				wiphy_err(wlc_hw->wlc->wiphy, "%s: turn on "
++					  "PHY PLL failed\n", __func__);
++		}
++	} else {
++		/*
++		 * Since the PLL may be shared, other cores can still
++		 * be requesting it; so we'll deassert the request but
++		 * not wait for status to comply.
++		 */
++		bcma_mask32(core, D11REGOFFS(clk_ctl_st),
++			    ~CCS_ERSRC_REQ_PHYPLL);
++		(void)bcma_read32(core, D11REGOFFS(clk_ctl_st));
++	}
++}
++
++static void brcms_c_coredisable(struct brcms_hardware *wlc_hw)
++{
++	bool dev_gone;
++
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
++
++	dev_gone = brcms_deviceremoved(wlc_hw->wlc);
++
++	if (dev_gone)
++		return;
++
++	if (wlc_hw->noreset)
++		return;
++
++	/* radio off */
++	wlc_phy_switch_radio(wlc_hw->band->pi, OFF);
++
++	/* turn off analog core */
++	wlc_phy_anacore(wlc_hw->band->pi, OFF);
++
++	/* turn off PHYPLL to save power */
++	brcms_b_core_phypll_ctl(wlc_hw, false);
++
++	wlc_hw->clk = false;
++	bcma_core_disable(wlc_hw->d11core, 0);
++	wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, false);
++}
++
++static void brcms_c_flushqueues(struct brcms_c_info *wlc)
++{
++	struct brcms_hardware *wlc_hw = wlc->hw;
++	uint i;
++
++	/* free any posted tx packets */
++	for (i = 0; i < NFIFO; i++)
++		if (wlc_hw->di[i]) {
++			dma_txreclaim(wlc_hw->di[i], DMA_RANGE_ALL);
++			wlc->core->txpktpend[i] = 0;
++			BCMMSG(wlc->wiphy, "pktpend fifo %d clrd\n", i);
++		}
++
++	/* free any posted rx packets */
++	dma_rxreclaim(wlc_hw->di[RX_FIFO]);
++}
++
++static u16
++brcms_b_read_objmem(struct brcms_hardware *wlc_hw, uint offset, u32 sel)
++{
++	struct bcma_device *core = wlc_hw->d11core;
++	u16 objoff = D11REGOFFS(objdata);
++
++	bcma_write32(core, D11REGOFFS(objaddr), sel | (offset >> 2));
++	(void)bcma_read32(core, D11REGOFFS(objaddr));
++	if (offset & 2)
++		objoff += 2;
++
++	return bcma_read16(core, objoff);
++}
++
++static void
++brcms_b_write_objmem(struct brcms_hardware *wlc_hw, uint offset, u16 v,
++		     u32 sel)
++{
++	struct bcma_device *core = wlc_hw->d11core;
++	u16 objoff = D11REGOFFS(objdata);
++
++	bcma_write32(core, D11REGOFFS(objaddr), sel | (offset >> 2));
++	(void)bcma_read32(core, D11REGOFFS(objaddr));
++	if (offset & 2)
++		objoff += 2;
++
++	bcma_write16(core, objoff, v);
++}
++
++/*
++ * Read a single u16 from shared memory.
++ * SHM 'offset' needs to be an even address
++ */
++u16 brcms_b_read_shm(struct brcms_hardware *wlc_hw, uint offset)
++{
++	return brcms_b_read_objmem(wlc_hw, offset, OBJADDR_SHM_SEL);
++}
++
++/*
++ * Write a single u16 to shared memory.
++ * SHM 'offset' needs to be an even address
++ */
++void brcms_b_write_shm(struct brcms_hardware *wlc_hw, uint offset, u16 v)
++{
++	brcms_b_write_objmem(wlc_hw, offset, v, OBJADDR_SHM_SEL);
++}
++
++/*
++ * Copy a buffer to shared memory of specified type .
++ * SHM 'offset' needs to be an even address and
++ * Buffer length 'len' must be an even number of bytes
++ * 'sel' selects the type of memory
++ */
++void
++brcms_b_copyto_objmem(struct brcms_hardware *wlc_hw, uint offset,
++		      const void *buf, int len, u32 sel)
++{
++	u16 v;
++	const u8 *p = (const u8 *)buf;
++	int i;
++
++	if (len <= 0 || (offset & 1) || (len & 1))
++		return;
++
++	for (i = 0; i < len; i += 2) {
++		v = p[i] | (p[i + 1] << 8);
++		brcms_b_write_objmem(wlc_hw, offset + i, v, sel);
++	}
++}
++
++/*
++ * Copy a piece of shared memory of specified type to a buffer .
++ * SHM 'offset' needs to be an even address and
++ * Buffer length 'len' must be an even number of bytes
++ * 'sel' selects the type of memory
++ */
++void
++brcms_b_copyfrom_objmem(struct brcms_hardware *wlc_hw, uint offset, void *buf,
++			 int len, u32 sel)
++{
++	u16 v;
++	u8 *p = (u8 *) buf;
++	int i;
++
++	if (len <= 0 || (offset & 1) || (len & 1))
++		return;
++
++	for (i = 0; i < len; i += 2) {
++		v = brcms_b_read_objmem(wlc_hw, offset + i, sel);
++		p[i] = v & 0xFF;
++		p[i + 1] = (v >> 8) & 0xFF;
++	}
++}
++
++/* Copy a buffer to shared memory.
++ * SHM 'offset' needs to be an even address and
++ * Buffer length 'len' must be an even number of bytes
++ */
++static void brcms_c_copyto_shm(struct brcms_c_info *wlc, uint offset,
++			const void *buf, int len)
++{
++	brcms_b_copyto_objmem(wlc->hw, offset, buf, len, OBJADDR_SHM_SEL);
++}
++
++static void brcms_b_retrylimit_upd(struct brcms_hardware *wlc_hw,
++				   u16 SRL, u16 LRL)
++{
++	wlc_hw->SRL = SRL;
++	wlc_hw->LRL = LRL;
++
++	/* write retry limit to SCR, shouldn't need to suspend */
++	if (wlc_hw->up) {
++		bcma_write32(wlc_hw->d11core, D11REGOFFS(objaddr),
++			     OBJADDR_SCR_SEL | S_DOT11_SRC_LMT);
++		(void)bcma_read32(wlc_hw->d11core, D11REGOFFS(objaddr));
++		bcma_write32(wlc_hw->d11core, D11REGOFFS(objdata), wlc_hw->SRL);
++		bcma_write32(wlc_hw->d11core, D11REGOFFS(objaddr),
++			     OBJADDR_SCR_SEL | S_DOT11_LRC_LMT);
++		(void)bcma_read32(wlc_hw->d11core, D11REGOFFS(objaddr));
++		bcma_write32(wlc_hw->d11core, D11REGOFFS(objdata), wlc_hw->LRL);
++	}
++}
++
++static void brcms_b_pllreq(struct brcms_hardware *wlc_hw, bool set, u32 req_bit)
++{
++	if (set) {
++		if (mboolisset(wlc_hw->pllreq, req_bit))
++			return;
++
++		mboolset(wlc_hw->pllreq, req_bit);
++
++		if (mboolisset(wlc_hw->pllreq, BRCMS_PLLREQ_FLIP)) {
++			if (!wlc_hw->sbclk)
++				brcms_b_xtal(wlc_hw, ON);
++		}
++	} else {
++		if (!mboolisset(wlc_hw->pllreq, req_bit))
++			return;
++
++		mboolclr(wlc_hw->pllreq, req_bit);
++
++		if (mboolisset(wlc_hw->pllreq, BRCMS_PLLREQ_FLIP)) {
++			if (wlc_hw->sbclk)
++				brcms_b_xtal(wlc_hw, OFF);
++		}
++	}
++}
++
++static void brcms_b_antsel_set(struct brcms_hardware *wlc_hw, u32 antsel_avail)
++{
++	wlc_hw->antsel_avail = antsel_avail;
++}
++
++/*
++ * conditions under which the PM bit should be set in outgoing frames
++ * and STAY_AWAKE is meaningful
++ */
++static bool brcms_c_ps_allowed(struct brcms_c_info *wlc)
++{
++	struct brcms_bss_cfg *cfg = wlc->bsscfg;
++
++	/* disallow PS when one of the following global conditions meets */
++	if (!wlc->pub->associated)
++		return false;
++
++	/* disallow PS when one of these meets when not scanning */
++	if (wlc->filter_flags & FIF_PROMISC_IN_BSS)
++		return false;
++
++	if (cfg->associated) {
++		/*
++		 * disallow PS when one of the following
++		 * bsscfg specific conditions meets
++		 */
++		if (!cfg->BSS)
++			return false;
++
++		return false;
++	}
++
++	return true;
++}
++
++static void brcms_c_statsupd(struct brcms_c_info *wlc)
++{
++	int i;
++	struct macstat macstats;
++#ifdef DEBUG
++	u16 delta;
++	u16 rxf0ovfl;
++	u16 txfunfl[NFIFO];
++#endif				/* DEBUG */
++
++	/* if driver down, make no sense to update stats */
++	if (!wlc->pub->up)
++		return;
++
++#ifdef DEBUG
++	/* save last rx fifo 0 overflow count */
++	rxf0ovfl = wlc->core->macstat_snapshot->rxf0ovfl;
++
++	/* save last tx fifo  underflow count */
++	for (i = 0; i < NFIFO; i++)
++		txfunfl[i] = wlc->core->macstat_snapshot->txfunfl[i];
++#endif				/* DEBUG */
++
++	/* Read mac stats from contiguous shared memory */
++	brcms_b_copyfrom_objmem(wlc->hw, M_UCODE_MACSTAT, &macstats,
++				sizeof(struct macstat), OBJADDR_SHM_SEL);
++
++#ifdef DEBUG
++	/* check for rx fifo 0 overflow */
++	delta = (u16) (wlc->core->macstat_snapshot->rxf0ovfl - rxf0ovfl);
++	if (delta)
++		wiphy_err(wlc->wiphy, "wl%d: %u rx fifo 0 overflows!\n",
++			  wlc->pub->unit, delta);
++
++	/* check for tx fifo underflows */
++	for (i = 0; i < NFIFO; i++) {
++		delta =
++		    (u16) (wlc->core->macstat_snapshot->txfunfl[i] -
++			      txfunfl[i]);
++		if (delta)
++			wiphy_err(wlc->wiphy, "wl%d: %u tx fifo %d underflows!"
++				  "\n", wlc->pub->unit, delta, i);
++	}
++#endif				/* DEBUG */
++
++	/* merge counters from dma module */
++	for (i = 0; i < NFIFO; i++) {
++		if (wlc->hw->di[i])
++			dma_counterreset(wlc->hw->di[i]);
++	}
++}
++
++static void brcms_b_reset(struct brcms_hardware *wlc_hw)
++{
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
++
++	/* reset the core */
++	if (!brcms_deviceremoved(wlc_hw->wlc))
++		brcms_b_corereset(wlc_hw, BRCMS_USE_COREFLAGS);
++
++	/* purge the dma rings */
++	brcms_c_flushqueues(wlc_hw->wlc);
++}
++
++void brcms_c_reset(struct brcms_c_info *wlc)
++{
++	BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
++
++	/* slurp up hw mac counters before core reset */
++	brcms_c_statsupd(wlc);
++
++	/* reset our snapshot of macstat counters */
++	memset((char *)wlc->core->macstat_snapshot, 0,
++		sizeof(struct macstat));
++
++	brcms_b_reset(wlc->hw);
++}
++
++/* Return the channel the driver should initialize during brcms_c_init.
++ * the channel may have to be changed from the currently configured channel
++ * if other configurations are in conflict (bandlocked, 11n mode disabled,
++ * invalid channel for current country, etc.)
++ */
++static u16 brcms_c_init_chanspec(struct brcms_c_info *wlc)
++{
++	u16 chanspec =
++	    1 | WL_CHANSPEC_BW_20 | WL_CHANSPEC_CTL_SB_NONE |
++	    WL_CHANSPEC_BAND_2G;
++
++	return chanspec;
++}
++
++void brcms_c_init_scb(struct scb *scb)
++{
++	int i;
++
++	memset(scb, 0, sizeof(struct scb));
++	scb->flags = SCB_WMECAP | SCB_HTCAP;
++	for (i = 0; i < NUMPRIO; i++) {
++		scb->seqnum[i] = 0;
++		scb->seqctl[i] = 0xFFFF;
++	}
++
++	scb->seqctl_nonqos = 0xFFFF;
++	scb->magic = SCB_MAGIC;
++}
++
++/* d11 core init
++ *   reset PSM
++ *   download ucode/PCM
++ *   let ucode run to suspended
++ *   download ucode inits
++ *   config other core registers
++ *   init dma
++ */
++static void brcms_b_coreinit(struct brcms_c_info *wlc)
++{
++	struct brcms_hardware *wlc_hw = wlc->hw;
++	struct bcma_device *core = wlc_hw->d11core;
++	u32 sflags;
++	u32 bcnint_us;
++	uint i = 0;
++	bool fifosz_fixup = false;
++	int err = 0;
++	u16 buf[NFIFO];
++	struct wiphy *wiphy = wlc->wiphy;
++	struct brcms_ucode *ucode = &wlc_hw->wlc->wl->ucode;
++
++	BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit);
++
++	/* reset PSM */
++	brcms_b_mctrl(wlc_hw, ~0, (MCTL_IHR_EN | MCTL_PSM_JMP_0 | MCTL_WAKE));
++
++	brcms_ucode_download(wlc_hw);
++	/*
++	 * FIFOSZ fixup. driver wants to controls the fifo allocation.
++	 */
++	fifosz_fixup = true;
++
++	/* let the PSM run to the suspended state, set mode to BSS STA */
++	bcma_write32(core, D11REGOFFS(macintstatus), -1);
++	brcms_b_mctrl(wlc_hw, ~0,
++		       (MCTL_IHR_EN | MCTL_INFRA | MCTL_PSM_RUN | MCTL_WAKE));
++
++	/* wait for ucode to self-suspend after auto-init */
++	SPINWAIT(((bcma_read32(core, D11REGOFFS(macintstatus)) &
++		   MI_MACSSPNDD) == 0), 1000 * 1000);
++	if ((bcma_read32(core, D11REGOFFS(macintstatus)) & MI_MACSSPNDD) == 0)
++		wiphy_err(wiphy, "wl%d: wlc_coreinit: ucode did not self-"
++			  "suspend!\n", wlc_hw->unit);
++
++	brcms_c_gpio_init(wlc);
++
++	sflags = bcma_aread32(core, BCMA_IOST);
++
++	if (D11REV_IS(wlc_hw->corerev, 23)) {
++		if (BRCMS_ISNPHY(wlc_hw->band))
++			brcms_c_write_inits(wlc_hw, ucode->d11n0initvals16);
++		else
++			wiphy_err(wiphy, "%s: wl%d: unsupported phy in corerev"
++				  " %d\n", __func__, wlc_hw->unit,
++				  wlc_hw->corerev);
++	} else if (D11REV_IS(wlc_hw->corerev, 24)) {
++		if (BRCMS_ISLCNPHY(wlc_hw->band))
++			brcms_c_write_inits(wlc_hw, ucode->d11lcn0initvals24);
++		else
++			wiphy_err(wiphy, "%s: wl%d: unsupported phy in corerev"
++				  " %d\n", __func__, wlc_hw->unit,
++				  wlc_hw->corerev);
++	} else {
++		wiphy_err(wiphy, "%s: wl%d: unsupported corerev %d\n",
++			  __func__, wlc_hw->unit, wlc_hw->corerev);
++	}
++
++	/* For old ucode, txfifo sizes needs to be modified(increased) */
++	if (fifosz_fixup)
++		brcms_b_corerev_fifofixup(wlc_hw);
++
++	/* check txfifo allocations match between ucode and driver */
++	buf[TX_AC_BE_FIFO] = brcms_b_read_shm(wlc_hw, M_FIFOSIZE0);
++	if (buf[TX_AC_BE_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_BE_FIFO]) {
++		i = TX_AC_BE_FIFO;
++		err = -1;
++	}
++	buf[TX_AC_VI_FIFO] = brcms_b_read_shm(wlc_hw, M_FIFOSIZE1);
++	if (buf[TX_AC_VI_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_VI_FIFO]) {
++		i = TX_AC_VI_FIFO;
++		err = -1;
++	}
++	buf[TX_AC_BK_FIFO] = brcms_b_read_shm(wlc_hw, M_FIFOSIZE2);
++	buf[TX_AC_VO_FIFO] = (buf[TX_AC_BK_FIFO] >> 8) & 0xff;
++	buf[TX_AC_BK_FIFO] &= 0xff;
++	if (buf[TX_AC_BK_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_BK_FIFO]) {
++		i = TX_AC_BK_FIFO;
++		err = -1;
++	}
++	if (buf[TX_AC_VO_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_VO_FIFO]) {
++		i = TX_AC_VO_FIFO;
++		err = -1;
++	}
++	buf[TX_BCMC_FIFO] = brcms_b_read_shm(wlc_hw, M_FIFOSIZE3);
++	buf[TX_ATIM_FIFO] = (buf[TX_BCMC_FIFO] >> 8) & 0xff;
++	buf[TX_BCMC_FIFO] &= 0xff;
++	if (buf[TX_BCMC_FIFO] != wlc_hw->xmtfifo_sz[TX_BCMC_FIFO]) {
++		i = TX_BCMC_FIFO;
++		err = -1;
++	}
++	if (buf[TX_ATIM_FIFO] != wlc_hw->xmtfifo_sz[TX_ATIM_FIFO]) {
++		i = TX_ATIM_FIFO;
++		err = -1;
++	}
++	if (err != 0)
++		wiphy_err(wiphy, "wlc_coreinit: txfifo mismatch: ucode size %d"
++			  " driver size %d index %d\n", buf[i],
++			  wlc_hw->xmtfifo_sz[i], i);
++
++	/* make sure we can still talk to the mac */
++	WARN_ON(bcma_read32(core, D11REGOFFS(maccontrol)) == 0xffffffff);
++
++	/* band-specific inits done by wlc_bsinit() */
++
++	/* Set up frame burst size and antenna swap threshold init values */
++	brcms_b_write_shm(wlc_hw, M_MBURST_SIZE, MAXTXFRAMEBURST);
++	brcms_b_write_shm(wlc_hw, M_MAX_ANTCNT, ANTCNT);
++
++	/* enable one rx interrupt per received frame */
++	bcma_write32(core, D11REGOFFS(intrcvlazy[0]), (1 << IRL_FC_SHIFT));
++
++	/* set the station mode (BSS STA) */
++	brcms_b_mctrl(wlc_hw,
++		       (MCTL_INFRA | MCTL_DISCARD_PMQ | MCTL_AP),
++		       (MCTL_INFRA | MCTL_DISCARD_PMQ));
++
++	/* set up Beacon interval */
++	bcnint_us = 0x8000 << 10;
++	bcma_write32(core, D11REGOFFS(tsf_cfprep),
++		     (bcnint_us << CFPREP_CBI_SHIFT));
++	bcma_write32(core, D11REGOFFS(tsf_cfpstart), bcnint_us);
++	bcma_write32(core, D11REGOFFS(macintstatus), MI_GP1);
++
++	/* write interrupt mask */
++	bcma_write32(core, D11REGOFFS(intctrlregs[RX_FIFO].intmask),
++		     DEF_RXINTMASK);
++
++	/* allow the MAC to control the PHY clock (dynamic on/off) */
++	brcms_b_macphyclk_set(wlc_hw, ON);
++
++	/* program dynamic clock control fast powerup delay register */
++	wlc->fastpwrup_dly = ai_clkctl_fast_pwrup_delay(wlc_hw->sih);
++	bcma_write16(core, D11REGOFFS(scc_fastpwrup_dly), wlc->fastpwrup_dly);
++
++	/* tell the ucode the corerev */
++	brcms_b_write_shm(wlc_hw, M_MACHW_VER, (u16) wlc_hw->corerev);
++
++	/* tell the ucode MAC capabilities */
++	brcms_b_write_shm(wlc_hw, M_MACHW_CAP_L,
++			   (u16) (wlc_hw->machwcap & 0xffff));
++	brcms_b_write_shm(wlc_hw, M_MACHW_CAP_H,
++			   (u16) ((wlc_hw->
++				      machwcap >> 16) & 0xffff));
++
++	/* write retry limits to SCR, this done after PSM init */
++	bcma_write32(core, D11REGOFFS(objaddr),
++		     OBJADDR_SCR_SEL | S_DOT11_SRC_LMT);
++	(void)bcma_read32(core, D11REGOFFS(objaddr));
++	bcma_write32(core, D11REGOFFS(objdata), wlc_hw->SRL);
++	bcma_write32(core, D11REGOFFS(objaddr),
++		     OBJADDR_SCR_SEL | S_DOT11_LRC_LMT);
++	(void)bcma_read32(core, D11REGOFFS(objaddr));
++	bcma_write32(core, D11REGOFFS(objdata), wlc_hw->LRL);
++
++	/* write rate fallback retry limits */
++	brcms_b_write_shm(wlc_hw, M_SFRMTXCNTFBRTHSD, wlc_hw->SFBL);
++	brcms_b_write_shm(wlc_hw, M_LFRMTXCNTFBRTHSD, wlc_hw->LFBL);
++
++	bcma_mask16(core, D11REGOFFS(ifs_ctl), 0x0FFF);
++	bcma_write16(core, D11REGOFFS(ifs_aifsn), EDCF_AIFSN_MIN);
++
++	/* init the tx dma engines */
++	for (i = 0; i < NFIFO; i++) {
++		if (wlc_hw->di[i])
++			dma_txinit(wlc_hw->di[i]);
++	}
++
++	/* init the rx dma engine(s) and post receive buffers */
++	dma_rxinit(wlc_hw->di[RX_FIFO]);
++	dma_rxfill(wlc_hw->di[RX_FIFO]);
++}
++
++void
++static brcms_b_init(struct brcms_hardware *wlc_hw, u16 chanspec) {
++	u32 macintmask;
++	bool fastclk;
++	struct brcms_c_info *wlc = wlc_hw->wlc;
++
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
++
++	/* request FAST clock if not on */
++	fastclk = wlc_hw->forcefastclk;
++	if (!fastclk)
++		brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST);
++
++	/* disable interrupts */
++	macintmask = brcms_intrsoff(wlc->wl);
++
++	/* set up the specified band and chanspec */
++	brcms_c_setxband(wlc_hw, chspec_bandunit(chanspec));
++	wlc_phy_chanspec_radio_set(wlc_hw->band->pi, chanspec);
++
++	/* do one-time phy inits and calibration */
++	wlc_phy_cal_init(wlc_hw->band->pi);
++
++	/* core-specific initialization */
++	brcms_b_coreinit(wlc);
++
++	/* band-specific inits */
++	brcms_b_bsinit(wlc, chanspec);
++
++	/* restore macintmask */
++	brcms_intrsrestore(wlc->wl, macintmask);
++
++	/* seed wake_override with BRCMS_WAKE_OVERRIDE_MACSUSPEND since the mac
++	 * is suspended and brcms_c_enable_mac() will clear this override bit.
++	 */
++	mboolset(wlc_hw->wake_override, BRCMS_WAKE_OVERRIDE_MACSUSPEND);
++
++	/*
++	 * initialize mac_suspend_depth to 1 to match ucode
++	 * initial suspended state
++	 */
++	wlc_hw->mac_suspend_depth = 1;
++
++	/* restore the clk */
++	if (!fastclk)
++		brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_DYNAMIC);
++}
++
++static void brcms_c_set_phy_chanspec(struct brcms_c_info *wlc,
++				     u16 chanspec)
++{
++	/* Save our copy of the chanspec */
++	wlc->chanspec = chanspec;
++
++	/* Set the chanspec and power limits for this locale */
++	brcms_c_channel_set_chanspec(wlc->cmi, chanspec, BRCMS_TXPWR_MAX);
++
++	if (wlc->stf->ss_algosel_auto)
++		brcms_c_stf_ss_algo_channel_get(wlc, &wlc->stf->ss_algo_channel,
++					    chanspec);
++
++	brcms_c_stf_ss_update(wlc, wlc->band);
++}
++
++static void
++brcms_default_rateset(struct brcms_c_info *wlc, struct brcms_c_rateset *rs)
++{
++	brcms_c_rateset_default(rs, NULL, wlc->band->phytype,
++		wlc->band->bandtype, false, BRCMS_RATE_MASK_FULL,
++		(bool) (wlc->pub->_n_enab & SUPPORT_11N),
++		brcms_chspec_bw(wlc->default_bss->chanspec),
++		wlc->stf->txstreams);
++}
++
++/* derive wlc->band->basic_rate[] table from 'rateset' */
++static void brcms_c_rate_lookup_init(struct brcms_c_info *wlc,
++			      struct brcms_c_rateset *rateset)
++{
++	u8 rate;
++	u8 mandatory;
++	u8 cck_basic = 0;
++	u8 ofdm_basic = 0;
++	u8 *br = wlc->band->basic_rate;
++	uint i;
++
++	/* incoming rates are in 500kbps units as in 802.11 Supported Rates */
++	memset(br, 0, BRCM_MAXRATE + 1);
++
++	/* For each basic rate in the rates list, make an entry in the
++	 * best basic lookup.
++	 */
++	for (i = 0; i < rateset->count; i++) {
++		/* only make an entry for a basic rate */
++		if (!(rateset->rates[i] & BRCMS_RATE_FLAG))
++			continue;
++
++		/* mask off basic bit */
++		rate = (rateset->rates[i] & BRCMS_RATE_MASK);
++
++		if (rate > BRCM_MAXRATE) {
++			wiphy_err(wlc->wiphy, "brcms_c_rate_lookup_init: "
++				  "invalid rate 0x%X in rate set\n",
++				  rateset->rates[i]);
++			continue;
++		}
++
++		br[rate] = rate;
++	}
++
++	/* The rate lookup table now has non-zero entries for each
++	 * basic rate, equal to the basic rate: br[basicN] = basicN
++	 *
++	 * To look up the best basic rate corresponding to any
++	 * particular rate, code can use the basic_rate table
++	 * like this
++	 *
++	 * basic_rate = wlc->band->basic_rate[tx_rate]
++	 *
++	 * Make sure there is a best basic rate entry for
++	 * every rate by walking up the table from low rates
++	 * to high, filling in holes in the lookup table
++	 */
++
++	for (i = 0; i < wlc->band->hw_rateset.count; i++) {
++		rate = wlc->band->hw_rateset.rates[i];
++
++		if (br[rate] != 0) {
++			/* This rate is a basic rate.
++			 * Keep track of the best basic rate so far by
++			 * modulation type.
++			 */
++			if (is_ofdm_rate(rate))
++				ofdm_basic = rate;
++			else
++				cck_basic = rate;
++
++			continue;
++		}
++
++		/* This rate is not a basic rate so figure out the
++		 * best basic rate less than this rate and fill in
++		 * the hole in the table
++		 */
++
++		br[rate] = is_ofdm_rate(rate) ? ofdm_basic : cck_basic;
++
++		if (br[rate] != 0)
++			continue;
++
++		if (is_ofdm_rate(rate)) {
++			/*
++			 * In 11g and 11a, the OFDM mandatory rates
++			 * are 6, 12, and 24 Mbps
++			 */
++			if (rate >= BRCM_RATE_24M)
++				mandatory = BRCM_RATE_24M;
++			else if (rate >= BRCM_RATE_12M)
++				mandatory = BRCM_RATE_12M;
++			else
++				mandatory = BRCM_RATE_6M;
++		} else {
++			/* In 11b, all CCK rates are mandatory 1 - 11 Mbps */
++			mandatory = rate;
++		}
++
++		br[rate] = mandatory;
++	}
++}
++
++static void brcms_c_bandinit_ordered(struct brcms_c_info *wlc,
++				     u16 chanspec)
++{
++	struct brcms_c_rateset default_rateset;
++	uint parkband;
++	uint i, band_order[2];
++
++	BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
++	/*
++	 * We might have been bandlocked during down and the chip
++	 * power-cycled (hibernate). Figure out the right band to park on
++	 */
++	if (wlc->bandlocked || wlc->pub->_nbands == 1) {
++		/* updated in brcms_c_bandlock() */
++		parkband = wlc->band->bandunit;
++		band_order[0] = band_order[1] = parkband;
++	} else {
++		/* park on the band of the specified chanspec */
++		parkband = chspec_bandunit(chanspec);
++
++		/* order so that parkband initialize last */
++		band_order[0] = parkband ^ 1;
++		band_order[1] = parkband;
++	}
++
++	/* make each band operational, software state init */
++	for (i = 0; i < wlc->pub->_nbands; i++) {
++		uint j = band_order[i];
++
++		wlc->band = wlc->bandstate[j];
++
++		brcms_default_rateset(wlc, &default_rateset);
++
++		/* fill in hw_rate */
++		brcms_c_rateset_filter(&default_rateset, &wlc->band->hw_rateset,
++				   false, BRCMS_RATES_CCK_OFDM, BRCMS_RATE_MASK,
++				   (bool) (wlc->pub->_n_enab & SUPPORT_11N));
++
++		/* init basic rate lookup */
++		brcms_c_rate_lookup_init(wlc, &default_rateset);
++	}
++
++	/* sync up phy/radio chanspec */
++	brcms_c_set_phy_chanspec(wlc, chanspec);
++}
++
++/*
++ * Set or clear filtering related maccontrol bits based on
++ * specified filter flags
++ */
++void brcms_c_mac_promisc(struct brcms_c_info *wlc, uint filter_flags)
++{
++	u32 promisc_bits = 0;
++
++	wlc->filter_flags = filter_flags;
++
++	if (filter_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS))
++		promisc_bits |= MCTL_PROMISC;
++
++	if (filter_flags & FIF_BCN_PRBRESP_PROMISC)
++		promisc_bits |= MCTL_BCNS_PROMISC;
++
++	if (filter_flags & FIF_FCSFAIL)
++		promisc_bits |= MCTL_KEEPBADFCS;
++
++	if (filter_flags & (FIF_CONTROL | FIF_PSPOLL))
++		promisc_bits |= MCTL_KEEPCONTROL;
++
++	brcms_b_mctrl(wlc->hw,
++		MCTL_PROMISC | MCTL_BCNS_PROMISC |
++		MCTL_KEEPCONTROL | MCTL_KEEPBADFCS,
++		promisc_bits);
++}
++
++/*
++ * ucode, hwmac update
++ *    Channel dependent updates for ucode and hw
++ */
++static void brcms_c_ucode_mac_upd(struct brcms_c_info *wlc)
++{
++	/* enable or disable any active IBSSs depending on whether or not
++	 * we are on the home channel
++	 */
++	if (wlc->home_chanspec == wlc_phy_chanspec_get(wlc->band->pi)) {
++		if (wlc->pub->associated) {
++			/*
++			 * BMAC_NOTE: This is something that should be fixed
++			 * in ucode inits. I think that the ucode inits set
++			 * up the bcn templates and shm values with a bogus
++			 * beacon. This should not be done in the inits. If
++			 * ucode needs to set up a beacon for testing, the
++			 * test routines should write it down, not expect the
++			 * inits to populate a bogus beacon.
++			 */
++			if (BRCMS_PHY_11N_CAP(wlc->band))
++				brcms_b_write_shm(wlc->hw,
++						M_BCN_TXTSF_OFFSET, 0);
++		}
++	} else {
++		/* disable an active IBSS if we are not on the home channel */
++	}
++}
++
++static void brcms_c_write_rate_shm(struct brcms_c_info *wlc, u8 rate,
++				   u8 basic_rate)
++{
++	u8 phy_rate, index;
++	u8 basic_phy_rate, basic_index;
++	u16 dir_table, basic_table;
++	u16 basic_ptr;
++
++	/* Shared memory address for the table we are reading */
++	dir_table = is_ofdm_rate(basic_rate) ? M_RT_DIRMAP_A : M_RT_DIRMAP_B;
++
++	/* Shared memory address for the table we are writing */
++	basic_table = is_ofdm_rate(rate) ? M_RT_BBRSMAP_A : M_RT_BBRSMAP_B;
++
++	/*
++	 * for a given rate, the LS-nibble of the PLCP SIGNAL field is
++	 * the index into the rate table.
++	 */
++	phy_rate = rate_info[rate] & BRCMS_RATE_MASK;
++	basic_phy_rate = rate_info[basic_rate] & BRCMS_RATE_MASK;
++	index = phy_rate & 0xf;
++	basic_index = basic_phy_rate & 0xf;
++
++	/* Find the SHM pointer to the ACK rate entry by looking in the
++	 * Direct-map Table
++	 */
++	basic_ptr = brcms_b_read_shm(wlc->hw, (dir_table + basic_index * 2));
++
++	/* Update the SHM BSS-basic-rate-set mapping table with the pointer
++	 * to the correct basic rate for the given incoming rate
++	 */
++	brcms_b_write_shm(wlc->hw, (basic_table + index * 2), basic_ptr);
++}
++
++static const struct brcms_c_rateset *
++brcms_c_rateset_get_hwrs(struct brcms_c_info *wlc)
++{
++	const struct brcms_c_rateset *rs_dflt;
++
++	if (BRCMS_PHY_11N_CAP(wlc->band)) {
++		if (wlc->band->bandtype == BRCM_BAND_5G)
++			rs_dflt = &ofdm_mimo_rates;
++		else
++			rs_dflt = &cck_ofdm_mimo_rates;
++	} else if (wlc->band->gmode)
++		rs_dflt = &cck_ofdm_rates;
++	else
++		rs_dflt = &cck_rates;
++
++	return rs_dflt;
++}
++
++static void brcms_c_set_ratetable(struct brcms_c_info *wlc)
++{
++	const struct brcms_c_rateset *rs_dflt;
++	struct brcms_c_rateset rs;
++	u8 rate, basic_rate;
++	uint i;
++
++	rs_dflt = brcms_c_rateset_get_hwrs(wlc);
++
++	brcms_c_rateset_copy(rs_dflt, &rs);
++	brcms_c_rateset_mcs_upd(&rs, wlc->stf->txstreams);
++
++	/* walk the phy rate table and update SHM basic rate lookup table */
++	for (i = 0; i < rs.count; i++) {
++		rate = rs.rates[i] & BRCMS_RATE_MASK;
++
++		/* for a given rate brcms_basic_rate returns the rate at
++		 * which a response ACK/CTS should be sent.
++		 */
++		basic_rate = brcms_basic_rate(wlc, rate);
++		if (basic_rate == 0)
++			/* This should only happen if we are using a
++			 * restricted rateset.
++			 */
++			basic_rate = rs.rates[0] & BRCMS_RATE_MASK;
++
++		brcms_c_write_rate_shm(wlc, rate, basic_rate);
++	}
++}
++
++/* band-specific init */
++static void brcms_c_bsinit(struct brcms_c_info *wlc)
++{
++	BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n",
++		 wlc->pub->unit, wlc->band->bandunit);
++
++	/* write ucode ACK/CTS rate table */
++	brcms_c_set_ratetable(wlc);
++
++	/* update some band specific mac configuration */
++	brcms_c_ucode_mac_upd(wlc);
++
++	/* init antenna selection */
++	brcms_c_antsel_init(wlc->asi);
++
++}
++
++/* formula:  IDLE_BUSY_RATIO_X_16 = (100-duty_cycle)/duty_cycle*16 */
++static int
++brcms_c_duty_cycle_set(struct brcms_c_info *wlc, int duty_cycle, bool isOFDM,
++		   bool writeToShm)
++{
++	int idle_busy_ratio_x_16 = 0;
++	uint offset =
++	    isOFDM ? M_TX_IDLE_BUSY_RATIO_X_16_OFDM :
++	    M_TX_IDLE_BUSY_RATIO_X_16_CCK;
++	if (duty_cycle > 100 || duty_cycle < 0) {
++		wiphy_err(wlc->wiphy, "wl%d:  duty cycle value off limit\n",
++			  wlc->pub->unit);
++		return -EINVAL;
++	}
++	if (duty_cycle)
++		idle_busy_ratio_x_16 = (100 - duty_cycle) * 16 / duty_cycle;
++	/* Only write to shared memory  when wl is up */
++	if (writeToShm)
++		brcms_b_write_shm(wlc->hw, offset, (u16) idle_busy_ratio_x_16);
++
++	if (isOFDM)
++		wlc->tx_duty_cycle_ofdm = (u16) duty_cycle;
++	else
++		wlc->tx_duty_cycle_cck = (u16) duty_cycle;
++
++	return 0;
++}
++
++/*
++ * Initialize the base precedence map for dequeueing
++ * from txq based on WME settings
++ */
++static void brcms_c_tx_prec_map_init(struct brcms_c_info *wlc)
++{
++	wlc->tx_prec_map = BRCMS_PREC_BMP_ALL;
++	memset(wlc->fifo2prec_map, 0, NFIFO * sizeof(u16));
++
++	wlc->fifo2prec_map[TX_AC_BK_FIFO] = BRCMS_PREC_BMP_AC_BK;
++	wlc->fifo2prec_map[TX_AC_BE_FIFO] = BRCMS_PREC_BMP_AC_BE;
++	wlc->fifo2prec_map[TX_AC_VI_FIFO] = BRCMS_PREC_BMP_AC_VI;
++	wlc->fifo2prec_map[TX_AC_VO_FIFO] = BRCMS_PREC_BMP_AC_VO;
++}
++
++static void
++brcms_c_txflowcontrol_signal(struct brcms_c_info *wlc,
++			     struct brcms_txq_info *qi, bool on, int prio)
++{
++	/* transmit flowcontrol is not yet implemented */
++}
++
++static void brcms_c_txflowcontrol_reset(struct brcms_c_info *wlc)
++{
++	struct brcms_txq_info *qi;
++
++	for (qi = wlc->tx_queues; qi != NULL; qi = qi->next) {
++		if (qi->stopped) {
++			brcms_c_txflowcontrol_signal(wlc, qi, OFF, ALLPRIO);
++			qi->stopped = 0;
++		}
++	}
++}
++
++/* push sw hps and wake state through hardware */
++static void brcms_c_set_ps_ctrl(struct brcms_c_info *wlc)
++{
++	u32 v1, v2;
++	bool hps;
++	bool awake_before;
++
++	hps = brcms_c_ps_allowed(wlc);
++
++	BCMMSG(wlc->wiphy, "wl%d: hps %d\n", wlc->pub->unit, hps);
++
++	v1 = bcma_read32(wlc->hw->d11core, D11REGOFFS(maccontrol));
++	v2 = MCTL_WAKE;
++	if (hps)
++		v2 |= MCTL_HPS;
++
++	brcms_b_mctrl(wlc->hw, MCTL_WAKE | MCTL_HPS, v2);
++
++	awake_before = ((v1 & MCTL_WAKE) || ((v1 & MCTL_HPS) == 0));
++
++	if (!awake_before)
++		brcms_b_wait_for_wake(wlc->hw);
++}
++
++/*
++ * Write this BSS config's MAC address to core.
++ * Updates RXE match engine.
++ */
++static int brcms_c_set_mac(struct brcms_bss_cfg *bsscfg)
++{
++	int err = 0;
++	struct brcms_c_info *wlc = bsscfg->wlc;
++
++	/* enter the MAC addr into the RXE match registers */
++	brcms_c_set_addrmatch(wlc, RCM_MAC_OFFSET, bsscfg->cur_etheraddr);
++
++	brcms_c_ampdu_macaddr_upd(wlc);
++
++	return err;
++}
++
++/* Write the BSS config's BSSID address to core (set_bssid in d11procs.tcl).
++ * Updates RXE match engine.
++ */
++static void brcms_c_set_bssid(struct brcms_bss_cfg *bsscfg)
++{
++	/* we need to update BSSID in RXE match registers */
++	brcms_c_set_addrmatch(bsscfg->wlc, RCM_BSSID_OFFSET, bsscfg->BSSID);
++}
++
++static void brcms_b_set_shortslot(struct brcms_hardware *wlc_hw, bool shortslot)
++{
++	wlc_hw->shortslot = shortslot;
++
++	if (wlc_hw->band->bandtype == BRCM_BAND_2G && wlc_hw->up) {
++		brcms_c_suspend_mac_and_wait(wlc_hw->wlc);
++		brcms_b_update_slot_timing(wlc_hw, shortslot);
++		brcms_c_enable_mac(wlc_hw->wlc);
++	}
++}
++
++/*
++ * Suspend the the MAC and update the slot timing
++ * for standard 11b/g (20us slots) or shortslot 11g (9us slots).
++ */
++static void brcms_c_switch_shortslot(struct brcms_c_info *wlc, bool shortslot)
++{
++	/* use the override if it is set */
++	if (wlc->shortslot_override != BRCMS_SHORTSLOT_AUTO)
++		shortslot = (wlc->shortslot_override == BRCMS_SHORTSLOT_ON);
++
++	if (wlc->shortslot == shortslot)
++		return;
++
++	wlc->shortslot = shortslot;
++
++	brcms_b_set_shortslot(wlc->hw, shortslot);
++}
++
++static void brcms_c_set_home_chanspec(struct brcms_c_info *wlc, u16 chanspec)
++{
++	if (wlc->home_chanspec != chanspec) {
++		wlc->home_chanspec = chanspec;
++
++		if (wlc->bsscfg->associated)
++			wlc->bsscfg->current_bss->chanspec = chanspec;
++	}
++}
++
++void
++brcms_b_set_chanspec(struct brcms_hardware *wlc_hw, u16 chanspec,
++		      bool mute_tx, struct txpwr_limits *txpwr)
++{
++	uint bandunit;
++
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d: 0x%x\n", wlc_hw->unit, chanspec);
++
++	wlc_hw->chanspec = chanspec;
++
++	/* Switch bands if necessary */
++	if (wlc_hw->_nbands > 1) {
++		bandunit = chspec_bandunit(chanspec);
++		if (wlc_hw->band->bandunit != bandunit) {
++			/* brcms_b_setband disables other bandunit,
++			 *  use light band switch if not up yet
++			 */
++			if (wlc_hw->up) {
++				wlc_phy_chanspec_radio_set(wlc_hw->
++							   bandstate[bandunit]->
++							   pi, chanspec);
++				brcms_b_setband(wlc_hw, bandunit, chanspec);
++			} else {
++				brcms_c_setxband(wlc_hw, bandunit);
++			}
++		}
++	}
++
++	wlc_phy_initcal_enable(wlc_hw->band->pi, !mute_tx);
++
++	if (!wlc_hw->up) {
++		if (wlc_hw->clk)
++			wlc_phy_txpower_limit_set(wlc_hw->band->pi, txpwr,
++						  chanspec);
++		wlc_phy_chanspec_radio_set(wlc_hw->band->pi, chanspec);
++	} else {
++		wlc_phy_chanspec_set(wlc_hw->band->pi, chanspec);
++		wlc_phy_txpower_limit_set(wlc_hw->band->pi, txpwr, chanspec);
++
++		/* Update muting of the channel */
++		brcms_b_mute(wlc_hw, mute_tx);
++	}
++}
++
++/* switch to and initialize new band */
++static void brcms_c_setband(struct brcms_c_info *wlc,
++					   uint bandunit)
++{
++	wlc->band = wlc->bandstate[bandunit];
++
++	if (!wlc->pub->up)
++		return;
++
++	/* wait for at least one beacon before entering sleeping state */
++	brcms_c_set_ps_ctrl(wlc);
++
++	/* band-specific initializations */
++	brcms_c_bsinit(wlc);
++}
++
++static void brcms_c_set_chanspec(struct brcms_c_info *wlc, u16 chanspec)
++{
++	uint bandunit;
++	bool switchband = false;
++	u16 old_chanspec = wlc->chanspec;
++
++	if (!brcms_c_valid_chanspec_db(wlc->cmi, chanspec)) {
++		wiphy_err(wlc->wiphy, "wl%d: %s: Bad channel %d\n",
++			  wlc->pub->unit, __func__, CHSPEC_CHANNEL(chanspec));
++		return;
++	}
++
++	/* Switch bands if necessary */
++	if (wlc->pub->_nbands > 1) {
++		bandunit = chspec_bandunit(chanspec);
++		if (wlc->band->bandunit != bandunit || wlc->bandinit_pending) {
++			switchband = true;
++			if (wlc->bandlocked) {
++				wiphy_err(wlc->wiphy, "wl%d: %s: chspec %d "
++					  "band is locked!\n",
++					  wlc->pub->unit, __func__,
++					  CHSPEC_CHANNEL(chanspec));
++				return;
++			}
++			/*
++			 * should the setband call come after the
++			 * brcms_b_chanspec() ? if the setband updates
++			 * (brcms_c_bsinit) use low level calls to inspect and
++			 * set state, the state inspected may be from the wrong
++			 * band, or the following brcms_b_set_chanspec() may
++			 * undo the work.
++			 */
++			brcms_c_setband(wlc, bandunit);
++		}
++	}
++
++	/* sync up phy/radio chanspec */
++	brcms_c_set_phy_chanspec(wlc, chanspec);
++
++	/* init antenna selection */
++	if (brcms_chspec_bw(old_chanspec) != brcms_chspec_bw(chanspec)) {
++		brcms_c_antsel_init(wlc->asi);
++
++		/* Fix the hardware rateset based on bw.
++		 * Mainly add MCS32 for 40Mhz, remove MCS 32 for 20Mhz
++		 */
++		brcms_c_rateset_bw_mcs_filter(&wlc->band->hw_rateset,
++			wlc->band->mimo_cap_40 ? brcms_chspec_bw(chanspec) : 0);
++	}
++
++	/* update some mac configuration since chanspec changed */
++	brcms_c_ucode_mac_upd(wlc);
++}
++
++/*
++ * This function changes the phytxctl for beacon based on current
++ * beacon ratespec AND txant setting as per this table:
++ *  ratespec     CCK		ant = wlc->stf->txant
++ *		OFDM		ant = 3
++ */
++void brcms_c_beacon_phytxctl_txant_upd(struct brcms_c_info *wlc,
++				       u32 bcn_rspec)
++{
++	u16 phyctl;
++	u16 phytxant = wlc->stf->phytxant;
++	u16 mask = PHY_TXC_ANT_MASK;
++
++	/* for non-siso rates or default setting, use the available chains */
++	if (BRCMS_PHY_11N_CAP(wlc->band))
++		phytxant = brcms_c_stf_phytxchain_sel(wlc, bcn_rspec);
++
++	phyctl = brcms_b_read_shm(wlc->hw, M_BCN_PCTLWD);
++	phyctl = (phyctl & ~mask) | phytxant;
++	brcms_b_write_shm(wlc->hw, M_BCN_PCTLWD, phyctl);
++}
++
++/*
++ * centralized protection config change function to simplify debugging, no
++ * consistency checking this should be called only on changes to avoid overhead
++ * in periodic function
++ */
++void brcms_c_protection_upd(struct brcms_c_info *wlc, uint idx, int val)
++{
++	BCMMSG(wlc->wiphy, "idx %d, val %d\n", idx, val);
++
++	switch (idx) {
++	case BRCMS_PROT_G_SPEC:
++		wlc->protection->_g = (bool) val;
++		break;
++	case BRCMS_PROT_G_OVR:
++		wlc->protection->g_override = (s8) val;
++		break;
++	case BRCMS_PROT_G_USER:
++		wlc->protection->gmode_user = (u8) val;
++		break;
++	case BRCMS_PROT_OVERLAP:
++		wlc->protection->overlap = (s8) val;
++		break;
++	case BRCMS_PROT_N_USER:
++		wlc->protection->nmode_user = (s8) val;
++		break;
++	case BRCMS_PROT_N_CFG:
++		wlc->protection->n_cfg = (s8) val;
++		break;
++	case BRCMS_PROT_N_CFG_OVR:
++		wlc->protection->n_cfg_override = (s8) val;
++		break;
++	case BRCMS_PROT_N_NONGF:
++		wlc->protection->nongf = (bool) val;
++		break;
++	case BRCMS_PROT_N_NONGF_OVR:
++		wlc->protection->nongf_override = (s8) val;
++		break;
++	case BRCMS_PROT_N_PAM_OVR:
++		wlc->protection->n_pam_override = (s8) val;
++		break;
++	case BRCMS_PROT_N_OBSS:
++		wlc->protection->n_obss = (bool) val;
++		break;
++
++	default:
++		break;
++	}
++
++}
++
++static void brcms_c_ht_update_sgi_rx(struct brcms_c_info *wlc, int val)
++{
++	if (wlc->pub->up) {
++		brcms_c_update_beacon(wlc);
++		brcms_c_update_probe_resp(wlc, true);
++	}
++}
++
++static void brcms_c_ht_update_ldpc(struct brcms_c_info *wlc, s8 val)
++{
++	wlc->stf->ldpc = val;
++
++	if (wlc->pub->up) {
++		brcms_c_update_beacon(wlc);
++		brcms_c_update_probe_resp(wlc, true);
++		wlc_phy_ldpc_override_set(wlc->band->pi, (val ? true : false));
++	}
++}
++
++void brcms_c_wme_setparams(struct brcms_c_info *wlc, u16 aci,
++		       const struct ieee80211_tx_queue_params *params,
++		       bool suspend)
++{
++	int i;
++	struct shm_acparams acp_shm;
++	u16 *shm_entry;
++
++	/* Only apply params if the core is out of reset and has clocks */
++	if (!wlc->clk) {
++		wiphy_err(wlc->wiphy, "wl%d: %s : no-clock\n", wlc->pub->unit,
++			  __func__);
++		return;
++	}
++
++	memset((char *)&acp_shm, 0, sizeof(struct shm_acparams));
++	/* fill in shm ac params struct */
++	acp_shm.txop = params->txop;
++	/* convert from units of 32us to us for ucode */
++	wlc->edcf_txop[aci & 0x3] = acp_shm.txop =
++	    EDCF_TXOP2USEC(acp_shm.txop);
++	acp_shm.aifs = (params->aifs & EDCF_AIFSN_MASK);
++
++	if (aci == IEEE80211_AC_VI && acp_shm.txop == 0
++	    && acp_shm.aifs < EDCF_AIFSN_MAX)
++		acp_shm.aifs++;
++
++	if (acp_shm.aifs < EDCF_AIFSN_MIN
++	    || acp_shm.aifs > EDCF_AIFSN_MAX) {
++		wiphy_err(wlc->wiphy, "wl%d: edcf_setparams: bad "
++			  "aifs %d\n", wlc->pub->unit, acp_shm.aifs);
++	} else {
++		acp_shm.cwmin = params->cw_min;
++		acp_shm.cwmax = params->cw_max;
++		acp_shm.cwcur = acp_shm.cwmin;
++		acp_shm.bslots =
++			bcma_read16(wlc->hw->d11core, D11REGOFFS(tsf_random)) &
++			acp_shm.cwcur;
++		acp_shm.reggap = acp_shm.bslots + acp_shm.aifs;
++		/* Indicate the new params to the ucode */
++		acp_shm.status = brcms_b_read_shm(wlc->hw, (M_EDCF_QINFO +
++						  wme_ac2fifo[aci] *
++						  M_EDCF_QLEN +
++						  M_EDCF_STATUS_OFF));
++		acp_shm.status |= WME_STATUS_NEWAC;
++
++		/* Fill in shm acparam table */
++		shm_entry = (u16 *) &acp_shm;
++		for (i = 0; i < (int)sizeof(struct shm_acparams); i += 2)
++			brcms_b_write_shm(wlc->hw,
++					  M_EDCF_QINFO +
++					  wme_ac2fifo[aci] * M_EDCF_QLEN + i,
++					  *shm_entry++);
++	}
++
++	if (suspend) {
++		brcms_c_suspend_mac_and_wait(wlc);
++		brcms_c_enable_mac(wlc);
++	}
++}
++
++static void brcms_c_edcf_setparams(struct brcms_c_info *wlc, bool suspend)
++{
++	u16 aci;
++	int i_ac;
++	struct ieee80211_tx_queue_params txq_pars;
++	static const struct edcf_acparam default_edcf_acparams[] = {
++		 {EDCF_AC_BE_ACI_STA, EDCF_AC_BE_ECW_STA, EDCF_AC_BE_TXOP_STA},
++		 {EDCF_AC_BK_ACI_STA, EDCF_AC_BK_ECW_STA, EDCF_AC_BK_TXOP_STA},
++		 {EDCF_AC_VI_ACI_STA, EDCF_AC_VI_ECW_STA, EDCF_AC_VI_TXOP_STA},
++		 {EDCF_AC_VO_ACI_STA, EDCF_AC_VO_ECW_STA, EDCF_AC_VO_TXOP_STA}
++	}; /* ucode needs these parameters during its initialization */
++	const struct edcf_acparam *edcf_acp = &default_edcf_acparams[0];
++
++	for (i_ac = 0; i_ac < IEEE80211_NUM_ACS; i_ac++, edcf_acp++) {
++		/* find out which ac this set of params applies to */
++		aci = (edcf_acp->ACI & EDCF_ACI_MASK) >> EDCF_ACI_SHIFT;
++
++		/* fill in shm ac params struct */
++		txq_pars.txop = edcf_acp->TXOP;
++		txq_pars.aifs = edcf_acp->ACI;
++
++		/* CWmin = 2^(ECWmin) - 1 */
++		txq_pars.cw_min = EDCF_ECW2CW(edcf_acp->ECW & EDCF_ECWMIN_MASK);
++		/* CWmax = 2^(ECWmax) - 1 */
++		txq_pars.cw_max = EDCF_ECW2CW((edcf_acp->ECW & EDCF_ECWMAX_MASK)
++					    >> EDCF_ECWMAX_SHIFT);
++		brcms_c_wme_setparams(wlc, aci, &txq_pars, suspend);
++	}
++
++	if (suspend) {
++		brcms_c_suspend_mac_and_wait(wlc);
++		brcms_c_enable_mac(wlc);
++	}
++}
++
++static void brcms_c_radio_monitor_start(struct brcms_c_info *wlc)
++{
++	/* Don't start the timer if HWRADIO feature is disabled */
++	if (wlc->radio_monitor)
++		return;
++
++	wlc->radio_monitor = true;
++	brcms_b_pllreq(wlc->hw, true, BRCMS_PLLREQ_RADIO_MON);
++	brcms_add_timer(wlc->radio_timer, TIMER_INTERVAL_RADIOCHK, true);
++}
++
++static bool brcms_c_radio_monitor_stop(struct brcms_c_info *wlc)
++{
++	if (!wlc->radio_monitor)
++		return true;
++
++	wlc->radio_monitor = false;
++	brcms_b_pllreq(wlc->hw, false, BRCMS_PLLREQ_RADIO_MON);
++	return brcms_del_timer(wlc->radio_timer);
++}
++
++/* read hwdisable state and propagate to wlc flag */
++static void brcms_c_radio_hwdisable_upd(struct brcms_c_info *wlc)
++{
++	if (wlc->pub->hw_off)
++		return;
++
++	if (brcms_b_radio_read_hwdisabled(wlc->hw))
++		mboolset(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE);
++	else
++		mboolclr(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE);
++}
++
++/* update hwradio status and return it */
++bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc)
++{
++	brcms_c_radio_hwdisable_upd(wlc);
++
++	return mboolisset(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE) ?
++			true : false;
++}
++
++/* periodical query hw radio button while driver is "down" */
++static void brcms_c_radio_timer(void *arg)
++{
++	struct brcms_c_info *wlc = (struct brcms_c_info *) arg;
++
++	if (brcms_deviceremoved(wlc)) {
++		wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n", wlc->pub->unit,
++			__func__);
++		brcms_down(wlc->wl);
++		return;
++	}
++
++	brcms_c_radio_hwdisable_upd(wlc);
++}
++
++/* common low-level watchdog code */
++static void brcms_b_watchdog(void *arg)
++{
++	struct brcms_c_info *wlc = (struct brcms_c_info *) arg;
++	struct brcms_hardware *wlc_hw = wlc->hw;
++
++	BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit);
++
++	if (!wlc_hw->up)
++		return;
++
++	/* increment second count */
++	wlc_hw->now++;
++
++	/* Check for FIFO error interrupts */
++	brcms_b_fifoerrors(wlc_hw);
++
++	/* make sure RX dma has buffers */
++	dma_rxfill(wlc->hw->di[RX_FIFO]);
++
++	wlc_phy_watchdog(wlc_hw->band->pi);
++}
++
++/* common watchdog code */
++static void brcms_c_watchdog(void *arg)
++{
++	struct brcms_c_info *wlc = (struct brcms_c_info *) arg;
++
++	BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
++
++	if (!wlc->pub->up)
++		return;
++
++	if (brcms_deviceremoved(wlc)) {
++		wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n", wlc->pub->unit,
++			  __func__);
++		brcms_down(wlc->wl);
++		return;
++	}
++
++	/* increment second count */
++	wlc->pub->now++;
++
++	brcms_c_radio_hwdisable_upd(wlc);
++	/* if radio is disable, driver may be down, quit here */
++	if (wlc->pub->radio_disabled)
++		return;
++
++	brcms_b_watchdog(wlc);
++
++	/*
++	 * occasionally sample mac stat counters to
++	 * detect 16-bit counter wrap
++	 */
++	if ((wlc->pub->now % SW_TIMER_MAC_STAT_UPD) == 0)
++		brcms_c_statsupd(wlc);
++
++	if (BRCMS_ISNPHY(wlc->band) &&
++	    ((wlc->pub->now - wlc->tempsense_lasttime) >=
++	     BRCMS_TEMPSENSE_PERIOD)) {
++		wlc->tempsense_lasttime = wlc->pub->now;
++		brcms_c_tempsense_upd(wlc);
++	}
++}
++
++static void brcms_c_watchdog_by_timer(void *arg)
++{
++	brcms_c_watchdog(arg);
++}
++
++static bool brcms_c_timers_init(struct brcms_c_info *wlc, int unit)
++{
++	wlc->wdtimer = brcms_init_timer(wlc->wl, brcms_c_watchdog_by_timer,
++		wlc, "watchdog");
++	if (!wlc->wdtimer) {
++		wiphy_err(wlc->wiphy, "wl%d:  wl_init_timer for wdtimer "
++			  "failed\n", unit);
++		goto fail;
++	}
++
++	wlc->radio_timer = brcms_init_timer(wlc->wl, brcms_c_radio_timer,
++		wlc, "radio");
++	if (!wlc->radio_timer) {
++		wiphy_err(wlc->wiphy, "wl%d:  wl_init_timer for radio_timer "
++			  "failed\n", unit);
++		goto fail;
++	}
++
++	return true;
++
++ fail:
++	return false;
++}
++
++/*
++ * Initialize brcms_c_info default values ...
++ * may get overrides later in this function
++ */
++static void brcms_c_info_init(struct brcms_c_info *wlc, int unit)
++{
++	int i;
++
++	/* Save our copy of the chanspec */
++	wlc->chanspec = ch20mhz_chspec(1);
++
++	/* various 802.11g modes */
++	wlc->shortslot = false;
++	wlc->shortslot_override = BRCMS_SHORTSLOT_AUTO;
++
++	brcms_c_protection_upd(wlc, BRCMS_PROT_G_OVR, BRCMS_PROTECTION_AUTO);
++	brcms_c_protection_upd(wlc, BRCMS_PROT_G_SPEC, false);
++
++	brcms_c_protection_upd(wlc, BRCMS_PROT_N_CFG_OVR,
++			       BRCMS_PROTECTION_AUTO);
++	brcms_c_protection_upd(wlc, BRCMS_PROT_N_CFG, BRCMS_N_PROTECTION_OFF);
++	brcms_c_protection_upd(wlc, BRCMS_PROT_N_NONGF_OVR,
++			       BRCMS_PROTECTION_AUTO);
++	brcms_c_protection_upd(wlc, BRCMS_PROT_N_NONGF, false);
++	brcms_c_protection_upd(wlc, BRCMS_PROT_N_PAM_OVR, AUTO);
++
++	brcms_c_protection_upd(wlc, BRCMS_PROT_OVERLAP,
++			       BRCMS_PROTECTION_CTL_OVERLAP);
++
++	/* 802.11g draft 4.0 NonERP elt advertisement */
++	wlc->include_legacy_erp = true;
++
++	wlc->stf->ant_rx_ovr = ANT_RX_DIV_DEF;
++	wlc->stf->txant = ANT_TX_DEF;
++
++	wlc->prb_resp_timeout = BRCMS_PRB_RESP_TIMEOUT;
++
++	wlc->usr_fragthresh = DOT11_DEFAULT_FRAG_LEN;
++	for (i = 0; i < NFIFO; i++)
++		wlc->fragthresh[i] = DOT11_DEFAULT_FRAG_LEN;
++	wlc->RTSThresh = DOT11_DEFAULT_RTS_LEN;
++
++	/* default rate fallback retry limits */
++	wlc->SFBL = RETRY_SHORT_FB;
++	wlc->LFBL = RETRY_LONG_FB;
++
++	/* default mac retry limits */
++	wlc->SRL = RETRY_SHORT_DEF;
++	wlc->LRL = RETRY_LONG_DEF;
++
++	/* WME QoS mode is Auto by default */
++	wlc->pub->_ampdu = AMPDU_AGG_HOST;
++	wlc->pub->bcmerror = 0;
++}
++
++static uint brcms_c_attach_module(struct brcms_c_info *wlc)
++{
++	uint err = 0;
++	uint unit;
++	unit = wlc->pub->unit;
++
++	wlc->asi = brcms_c_antsel_attach(wlc);
++	if (wlc->asi == NULL) {
++		wiphy_err(wlc->wiphy, "wl%d: attach: antsel_attach "
++			  "failed\n", unit);
++		err = 44;
++		goto fail;
++	}
++
++	wlc->ampdu = brcms_c_ampdu_attach(wlc);
++	if (wlc->ampdu == NULL) {
++		wiphy_err(wlc->wiphy, "wl%d: attach: ampdu_attach "
++			  "failed\n", unit);
++		err = 50;
++		goto fail;
++	}
++
++	if ((brcms_c_stf_attach(wlc) != 0)) {
++		wiphy_err(wlc->wiphy, "wl%d: attach: stf_attach "
++			  "failed\n", unit);
++		err = 68;
++		goto fail;
++	}
++ fail:
++	return err;
++}
++
++struct brcms_pub *brcms_c_pub(struct brcms_c_info *wlc)
++{
++	return wlc->pub;
++}
++
++/* low level attach
++ *    run backplane attach, init nvram
++ *    run phy attach
++ *    initialize software state for each core and band
++ *    put the whole chip in reset(driver down state), no clock
++ */
++static int brcms_b_attach(struct brcms_c_info *wlc, struct bcma_device *core,
++			  uint unit, bool piomode)
++{
++	struct brcms_hardware *wlc_hw;
++	uint err = 0;
++	uint j;
++	bool wme = false;
++	struct shared_phy_params sha_params;
++	struct wiphy *wiphy = wlc->wiphy;
++	struct pci_dev *pcidev = core->bus->host_pci;
++	struct ssb_sprom *sprom = &core->bus->sprom;
++
++	if (core->bus->hosttype == BCMA_HOSTTYPE_PCI)
++		BCMMSG(wlc->wiphy, "wl%d: vendor 0x%x device 0x%x\n", unit,
++		       pcidev->vendor,
++		       pcidev->device);
++	else
++		BCMMSG(wlc->wiphy, "wl%d: vendor 0x%x device 0x%x\n", unit,
++		       core->bus->boardinfo.vendor,
++		       core->bus->boardinfo.type);
++
++	wme = true;
++
++	wlc_hw = wlc->hw;
++	wlc_hw->wlc = wlc;
++	wlc_hw->unit = unit;
++	wlc_hw->band = wlc_hw->bandstate[0];
++	wlc_hw->_piomode = piomode;
++
++	/* populate struct brcms_hardware with default values  */
++	brcms_b_info_init(wlc_hw);
++
++	/*
++	 * Do the hardware portion of the attach. Also initialize software
++	 * state that depends on the particular hardware we are running.
++	 */
++	wlc_hw->sih = ai_attach(core->bus);
++	if (wlc_hw->sih == NULL) {
++		wiphy_err(wiphy, "wl%d: brcms_b_attach: si_attach failed\n",
++			  unit);
++		err = 11;
++		goto fail;
++	}
++
++	/* verify again the device is supported */
++	if (core->bus->hosttype == BCMA_HOSTTYPE_PCI &&
++	    !brcms_c_chipmatch(pcidev->vendor, pcidev->device)) {
++		wiphy_err(wiphy, "wl%d: brcms_b_attach: Unsupported "
++			"vendor/device (0x%x/0x%x)\n",
++			 unit, pcidev->vendor, pcidev->device);
++		err = 12;
++		goto fail;
++	}
++
++	if (core->bus->hosttype == BCMA_HOSTTYPE_PCI) {
++		wlc_hw->vendorid = pcidev->vendor;
++		wlc_hw->deviceid = pcidev->device;
++	} else {
++		wlc_hw->vendorid = core->bus->boardinfo.vendor;
++		wlc_hw->deviceid = core->bus->boardinfo.type;
++	}
++
++	wlc_hw->d11core = core;
++	wlc_hw->corerev = core->id.rev;
++
++	/* validate chip, chiprev and corerev */
++	if (!brcms_c_isgoodchip(wlc_hw)) {
++		err = 13;
++		goto fail;
++	}
++
++	/* initialize power control registers */
++	ai_clkctl_init(wlc_hw->sih);
++
++	/* request fastclock and force fastclock for the rest of attach
++	 * bring the d11 core out of reset.
++	 *   For PMU chips, the first wlc_clkctl_clk is no-op since core-clk
++	 *   is still false; But it will be called again inside wlc_corereset,
++	 *   after d11 is out of reset.
++	 */
++	brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST);
++	brcms_b_corereset(wlc_hw, BRCMS_USE_COREFLAGS);
++
++	if (!brcms_b_validate_chip_access(wlc_hw)) {
++		wiphy_err(wiphy, "wl%d: brcms_b_attach: validate_chip_access "
++			"failed\n", unit);
++		err = 14;
++		goto fail;
++	}
++
++	/* get the board rev, used just below */
++	j = sprom->board_rev;
++	/* promote srom boardrev of 0xFF to 1 */
++	if (j == BOARDREV_PROMOTABLE)
++		j = BOARDREV_PROMOTED;
++	wlc_hw->boardrev = (u16) j;
++	if (!brcms_c_validboardtype(wlc_hw)) {
++		wiphy_err(wiphy, "wl%d: brcms_b_attach: Unsupported Broadcom "
++			  "board type (0x%x)" " or revision level (0x%x)\n",
++			  unit, ai_get_boardtype(wlc_hw->sih),
++			  wlc_hw->boardrev);
++		err = 15;
++		goto fail;
++	}
++	wlc_hw->sromrev = sprom->revision;
++	wlc_hw->boardflags = sprom->boardflags_lo + (sprom->boardflags_hi << 16);
++	wlc_hw->boardflags2 = sprom->boardflags2_lo + (sprom->boardflags2_hi << 16);
++
++	if (wlc_hw->boardflags & BFL_NOPLLDOWN)
++		brcms_b_pllreq(wlc_hw, true, BRCMS_PLLREQ_SHARED);
++
++	/* check device id(srom, nvram etc.) to set bands */
++	if (wlc_hw->deviceid == BCM43224_D11N_ID ||
++	    wlc_hw->deviceid == BCM43224_D11N_ID_VEN1)
++		/* Dualband boards */
++		wlc_hw->_nbands = 2;
++	else
++		wlc_hw->_nbands = 1;
++
++	if ((ai_get_chip_id(wlc_hw->sih) == BCM43225_CHIP_ID))
++		wlc_hw->_nbands = 1;
++
++	/* BMAC_NOTE: remove init of pub values when brcms_c_attach()
++	 * unconditionally does the init of these values
++	 */
++	wlc->vendorid = wlc_hw->vendorid;
++	wlc->deviceid = wlc_hw->deviceid;
++	wlc->pub->sih = wlc_hw->sih;
++	wlc->pub->corerev = wlc_hw->corerev;
++	wlc->pub->sromrev = wlc_hw->sromrev;
++	wlc->pub->boardrev = wlc_hw->boardrev;
++	wlc->pub->boardflags = wlc_hw->boardflags;
++	wlc->pub->boardflags2 = wlc_hw->boardflags2;
++	wlc->pub->_nbands = wlc_hw->_nbands;
++
++	wlc_hw->physhim = wlc_phy_shim_attach(wlc_hw, wlc->wl, wlc);
++
++	if (wlc_hw->physhim == NULL) {
++		wiphy_err(wiphy, "wl%d: brcms_b_attach: wlc_phy_shim_attach "
++			"failed\n", unit);
++		err = 25;
++		goto fail;
++	}
++
++	/* pass all the parameters to wlc_phy_shared_attach in one struct */
++	sha_params.sih = wlc_hw->sih;
++	sha_params.physhim = wlc_hw->physhim;
++	sha_params.unit = unit;
++	sha_params.corerev = wlc_hw->corerev;
++	sha_params.vid = wlc_hw->vendorid;
++	sha_params.did = wlc_hw->deviceid;
++	sha_params.chip = ai_get_chip_id(wlc_hw->sih);
++	sha_params.chiprev = ai_get_chiprev(wlc_hw->sih);
++	sha_params.chippkg = ai_get_chippkg(wlc_hw->sih);
++	sha_params.sromrev = wlc_hw->sromrev;
++	sha_params.boardtype = ai_get_boardtype(wlc_hw->sih);
++	sha_params.boardrev = wlc_hw->boardrev;
++	sha_params.boardflags = wlc_hw->boardflags;
++	sha_params.boardflags2 = wlc_hw->boardflags2;
++
++	/* alloc and save pointer to shared phy state area */
++	wlc_hw->phy_sh = wlc_phy_shared_attach(&sha_params);
++	if (!wlc_hw->phy_sh) {
++		err = 16;
++		goto fail;
++	}
++
++	/* initialize software state for each core and band */
++	for (j = 0; j < wlc_hw->_nbands; j++) {
++		/*
++		 * band0 is always 2.4Ghz
++		 * band1, if present, is 5Ghz
++		 */
++
++		brcms_c_setxband(wlc_hw, j);
++
++		wlc_hw->band->bandunit = j;
++		wlc_hw->band->bandtype = j ? BRCM_BAND_5G : BRCM_BAND_2G;
++		wlc->band->bandunit = j;
++		wlc->band->bandtype = j ? BRCM_BAND_5G : BRCM_BAND_2G;
++		wlc->core->coreidx = core->core_index;
++
++		wlc_hw->machwcap = bcma_read32(core, D11REGOFFS(machwcap));
++		wlc_hw->machwcap_backup = wlc_hw->machwcap;
++
++		/* init tx fifo size */
++		wlc_hw->xmtfifo_sz =
++		    xmtfifo_sz[(wlc_hw->corerev - XMTFIFOTBL_STARTREV)];
++
++		/* Get a phy for this band */
++		wlc_hw->band->pi =
++			wlc_phy_attach(wlc_hw->phy_sh, core,
++				       wlc_hw->band->bandtype,
++				       wlc->wiphy);
++		if (wlc_hw->band->pi == NULL) {
++			wiphy_err(wiphy, "wl%d: brcms_b_attach: wlc_phy_"
++				  "attach failed\n", unit);
++			err = 17;
++			goto fail;
++		}
++
++		wlc_phy_machwcap_set(wlc_hw->band->pi, wlc_hw->machwcap);
++
++		wlc_phy_get_phyversion(wlc_hw->band->pi, &wlc_hw->band->phytype,
++				       &wlc_hw->band->phyrev,
++				       &wlc_hw->band->radioid,
++				       &wlc_hw->band->radiorev);
++		wlc_hw->band->abgphy_encore =
++		    wlc_phy_get_encore(wlc_hw->band->pi);
++		wlc->band->abgphy_encore = wlc_phy_get_encore(wlc_hw->band->pi);
++		wlc_hw->band->core_flags =
++		    wlc_phy_get_coreflags(wlc_hw->band->pi);
++
++		/* verify good phy_type & supported phy revision */
++		if (BRCMS_ISNPHY(wlc_hw->band)) {
++			if (NCONF_HAS(wlc_hw->band->phyrev))
++				goto good_phy;
++			else
++				goto bad_phy;
++		} else if (BRCMS_ISLCNPHY(wlc_hw->band)) {
++			if (LCNCONF_HAS(wlc_hw->band->phyrev))
++				goto good_phy;
++			else
++				goto bad_phy;
++		} else {
++ bad_phy:
++			wiphy_err(wiphy, "wl%d: brcms_b_attach: unsupported "
++				  "phy type/rev (%d/%d)\n", unit,
++				  wlc_hw->band->phytype, wlc_hw->band->phyrev);
++			err = 18;
++			goto fail;
++		}
++
++ good_phy:
++		/*
++		 * BMAC_NOTE: wlc->band->pi should not be set below and should
++		 * be done in the high level attach. However we can not make
++		 * that change until all low level access is changed to
++		 * wlc_hw->band->pi. Instead do the wlc->band->pi init below,
++		 * keeping wlc_hw->band->pi as well for incremental update of
++		 * low level fns, and cut over low only init when all fns
++		 * updated.
++		 */
++		wlc->band->pi = wlc_hw->band->pi;
++		wlc->band->phytype = wlc_hw->band->phytype;
++		wlc->band->phyrev = wlc_hw->band->phyrev;
++		wlc->band->radioid = wlc_hw->band->radioid;
++		wlc->band->radiorev = wlc_hw->band->radiorev;
++
++		/* default contention windows size limits */
++		wlc_hw->band->CWmin = APHY_CWMIN;
++		wlc_hw->band->CWmax = PHY_CWMAX;
++
++		if (!brcms_b_attach_dmapio(wlc, j, wme)) {
++			err = 19;
++			goto fail;
++		}
++	}
++
++	/* disable core to match driver "down" state */
++	brcms_c_coredisable(wlc_hw);
++
++	/* Match driver "down" state */
++	ai_pci_down(wlc_hw->sih);
++
++	/* turn off pll and xtal to match driver "down" state */
++	brcms_b_xtal(wlc_hw, OFF);
++
++	/* *******************************************************************
++	 * The hardware is in the DOWN state at this point. D11 core
++	 * or cores are in reset with clocks off, and the board PLLs
++	 * are off if possible.
++	 *
++	 * Beyond this point, wlc->sbclk == false and chip registers
++	 * should not be touched.
++	 *********************************************************************
++	 */
++
++	/* init etheraddr state variables */
++	brcms_c_get_macaddr(wlc_hw, wlc_hw->etheraddr);
++
++	if (is_broadcast_ether_addr(wlc_hw->etheraddr) ||
++	    is_zero_ether_addr(wlc_hw->etheraddr)) {
++		wiphy_err(wiphy, "wl%d: brcms_b_attach: bad macaddr\n",
++			  unit);
++		err = 22;
++		goto fail;
++	}
++
++	BCMMSG(wlc->wiphy, "deviceid 0x%x nbands %d board 0x%x\n",
++	       wlc_hw->deviceid, wlc_hw->_nbands, ai_get_boardtype(wlc_hw->sih));
++
++	return err;
++
++ fail:
++	wiphy_err(wiphy, "wl%d: brcms_b_attach: failed with err %d\n", unit,
++		  err);
++	return err;
++}
++
++static void brcms_c_attach_antgain_init(struct brcms_c_info *wlc)
++{
++	uint unit;
++	unit = wlc->pub->unit;
++
++	if ((wlc->band->antgain == -1) && (wlc->pub->sromrev == 1)) {
++		/* default antenna gain for srom rev 1 is 2 dBm (8 qdbm) */
++		wlc->band->antgain = 8;
++	} else if (wlc->band->antgain == -1) {
++		wiphy_err(wlc->wiphy, "wl%d: %s: Invalid antennas available in"
++			  " srom, using 2dB\n", unit, __func__);
++		wlc->band->antgain = 8;
++	} else {
++		s8 gain, fract;
++		/* Older sroms specified gain in whole dbm only.  In order
++		 * be able to specify qdbm granularity and remain backward
++		 * compatible the whole dbms are now encoded in only
++		 * low 6 bits and remaining qdbms are encoded in the hi 2 bits.
++		 * 6 bit signed number ranges from -32 - 31.
++		 *
++		 * Examples:
++		 * 0x1 = 1 db,
++		 * 0xc1 = 1.75 db (1 + 3 quarters),
++		 * 0x3f = -1 (-1 + 0 quarters),
++		 * 0x7f = -.75 (-1 + 1 quarters) = -3 qdbm.
++		 * 0xbf = -.50 (-1 + 2 quarters) = -2 qdbm.
++		 */
++		gain = wlc->band->antgain & 0x3f;
++		gain <<= 2;	/* Sign extend */
++		gain >>= 2;
++		fract = (wlc->band->antgain & 0xc0) >> 6;
++		wlc->band->antgain = 4 * gain + fract;
++	}
++}
++
++static bool brcms_c_attach_stf_ant_init(struct brcms_c_info *wlc)
++{
++	int aa;
++	uint unit;
++	int bandtype;
++	struct ssb_sprom *sprom = &wlc->hw->d11core->bus->sprom;
++
++	unit = wlc->pub->unit;
++	bandtype = wlc->band->bandtype;
++
++	/* get antennas available */
++	if (bandtype == BRCM_BAND_5G)
++		aa = sprom->ant_available_a;
++	else
++		aa = sprom->ant_available_bg;
++
++	if ((aa < 1) || (aa > 15)) {
++		wiphy_err(wlc->wiphy, "wl%d: %s: Invalid antennas available in"
++			  " srom (0x%x), using 3\n", unit, __func__, aa);
++		aa = 3;
++	}
++
++	/* reset the defaults if we have a single antenna */
++	if (aa == 1) {
++		wlc->stf->ant_rx_ovr = ANT_RX_DIV_FORCE_0;
++		wlc->stf->txant = ANT_TX_FORCE_0;
++	} else if (aa == 2) {
++		wlc->stf->ant_rx_ovr = ANT_RX_DIV_FORCE_1;
++		wlc->stf->txant = ANT_TX_FORCE_1;
++	} else {
++	}
++
++	/* Compute Antenna Gain */
++	if (bandtype == BRCM_BAND_5G)
++		wlc->band->antgain = sprom->antenna_gain.a1;
++	else
++		wlc->band->antgain = sprom->antenna_gain.a0;
++
++	brcms_c_attach_antgain_init(wlc);
++
++	return true;
++}
++
++static void brcms_c_bss_default_init(struct brcms_c_info *wlc)
++{
++	u16 chanspec;
++	struct brcms_band *band;
++	struct brcms_bss_info *bi = wlc->default_bss;
++
++	/* init default and target BSS with some sane initial values */
++	memset((char *)(bi), 0, sizeof(struct brcms_bss_info));
++	bi->beacon_period = BEACON_INTERVAL_DEFAULT;
++
++	/* fill the default channel as the first valid channel
++	 * starting from the 2G channels
++	 */
++	chanspec = ch20mhz_chspec(1);
++	wlc->home_chanspec = bi->chanspec = chanspec;
++
++	/* find the band of our default channel */
++	band = wlc->band;
++	if (wlc->pub->_nbands > 1 &&
++	    band->bandunit != chspec_bandunit(chanspec))
++		band = wlc->bandstate[OTHERBANDUNIT(wlc)];
++
++	/* init bss rates to the band specific default rate set */
++	brcms_c_rateset_default(&bi->rateset, NULL, band->phytype,
++		band->bandtype, false, BRCMS_RATE_MASK_FULL,
++		(bool) (wlc->pub->_n_enab & SUPPORT_11N),
++		brcms_chspec_bw(chanspec), wlc->stf->txstreams);
++
++	if (wlc->pub->_n_enab & SUPPORT_11N)
++		bi->flags |= BRCMS_BSS_HT;
++}
++
++static struct brcms_txq_info *brcms_c_txq_alloc(struct brcms_c_info *wlc)
++{
++	struct brcms_txq_info *qi, *p;
++
++	qi = kzalloc(sizeof(struct brcms_txq_info), GFP_ATOMIC);
++	if (qi != NULL) {
++		/*
++		 * Have enough room for control packets along with HI watermark
++		 * Also, add room to txq for total psq packets if all the SCBs
++		 * leave PS mode. The watermark for flowcontrol to OS packets
++		 * will remain the same
++		 */
++		brcmu_pktq_init(&qi->q, BRCMS_PREC_COUNT,
++			  2 * BRCMS_DATAHIWAT + PKTQ_LEN_DEFAULT);
++
++		/* add this queue to the the global list */
++		p = wlc->tx_queues;
++		if (p == NULL) {
++			wlc->tx_queues = qi;
++		} else {
++			while (p->next != NULL)
++				p = p->next;
++			p->next = qi;
++		}
++	}
++	return qi;
++}
++
++static void brcms_c_txq_free(struct brcms_c_info *wlc,
++			     struct brcms_txq_info *qi)
++{
++	struct brcms_txq_info *p;
++
++	if (qi == NULL)
++		return;
++
++	/* remove the queue from the linked list */
++	p = wlc->tx_queues;
++	if (p == qi)
++		wlc->tx_queues = p->next;
++	else {
++		while (p != NULL && p->next != qi)
++			p = p->next;
++		if (p != NULL)
++			p->next = p->next->next;
++	}
++
++	kfree(qi);
++}
++
++static void brcms_c_update_mimo_band_bwcap(struct brcms_c_info *wlc, u8 bwcap)
++{
++	uint i;
++	struct brcms_band *band;
++
++	for (i = 0; i < wlc->pub->_nbands; i++) {
++		band = wlc->bandstate[i];
++		if (band->bandtype == BRCM_BAND_5G) {
++			if ((bwcap == BRCMS_N_BW_40ALL)
++			    || (bwcap == BRCMS_N_BW_20IN2G_40IN5G))
++				band->mimo_cap_40 = true;
++			else
++				band->mimo_cap_40 = false;
++		} else {
++			if (bwcap == BRCMS_N_BW_40ALL)
++				band->mimo_cap_40 = true;
++			else
++				band->mimo_cap_40 = false;
++		}
++	}
++}
++
++static void brcms_c_timers_deinit(struct brcms_c_info *wlc)
++{
++	/* free timer state */
++	if (wlc->wdtimer) {
++		brcms_free_timer(wlc->wdtimer);
++		wlc->wdtimer = NULL;
++	}
++	if (wlc->radio_timer) {
++		brcms_free_timer(wlc->radio_timer);
++		wlc->radio_timer = NULL;
++	}
++}
++
++static void brcms_c_detach_module(struct brcms_c_info *wlc)
++{
++	if (wlc->asi) {
++		brcms_c_antsel_detach(wlc->asi);
++		wlc->asi = NULL;
++	}
++
++	if (wlc->ampdu) {
++		brcms_c_ampdu_detach(wlc->ampdu);
++		wlc->ampdu = NULL;
++	}
++
++	brcms_c_stf_detach(wlc);
++}
++
++/*
++ * low level detach
++ */
++static int brcms_b_detach(struct brcms_c_info *wlc)
++{
++	uint i;
++	struct brcms_hw_band *band;
++	struct brcms_hardware *wlc_hw = wlc->hw;
++	int callbacks;
++
++	callbacks = 0;
++
++	brcms_b_detach_dmapio(wlc_hw);
++
++	band = wlc_hw->band;
++	for (i = 0; i < wlc_hw->_nbands; i++) {
++		if (band->pi) {
++			/* Detach this band's phy */
++			wlc_phy_detach(band->pi);
++			band->pi = NULL;
++		}
++		band = wlc_hw->bandstate[OTHERBANDUNIT(wlc)];
++	}
++
++	/* Free shared phy state */
++	kfree(wlc_hw->phy_sh);
++
++	wlc_phy_shim_detach(wlc_hw->physhim);
++
++	if (wlc_hw->sih) {
++		ai_detach(wlc_hw->sih);
++		wlc_hw->sih = NULL;
++	}
++
++	return callbacks;
++
++}
++
++/*
++ * Return a count of the number of driver callbacks still pending.
++ *
++ * General policy is that brcms_c_detach can only dealloc/free software states.
++ * It can NOT touch hardware registers since the d11core may be in reset and
++ * clock may not be available.
++ * One exception is sb register access, which is possible if crystal is turned
++ * on after "down" state, driver should avoid software timer with the exception
++ * of radio_monitor.
++ */
++uint brcms_c_detach(struct brcms_c_info *wlc)
++{
++	uint callbacks = 0;
++
++	if (wlc == NULL)
++		return 0;
++
++	BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
++
++	callbacks += brcms_b_detach(wlc);
++
++	/* delete software timers */
++	if (!brcms_c_radio_monitor_stop(wlc))
++		callbacks++;
++
++	brcms_c_channel_mgr_detach(wlc->cmi);
++
++	brcms_c_timers_deinit(wlc);
++
++	brcms_c_detach_module(wlc);
++
++
++	while (wlc->tx_queues != NULL)
++		brcms_c_txq_free(wlc, wlc->tx_queues);
++
++	brcms_c_detach_mfree(wlc);
++	return callbacks;
++}
++
++/* update state that depends on the current value of "ap" */
++static void brcms_c_ap_upd(struct brcms_c_info *wlc)
++{
++	/* STA-BSS; short capable */
++	wlc->PLCPHdr_override = BRCMS_PLCP_SHORT;
++}
++
++/* Initialize just the hardware when coming out of POR or S3/S5 system states */
++static void brcms_b_hw_up(struct brcms_hardware *wlc_hw)
++{
++	if (wlc_hw->wlc->pub->hw_up)
++		return;
++
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
++
++	/*
++	 * Enable pll and xtal, initialize the power control registers,
++	 * and force fastclock for the remainder of brcms_c_up().
++	 */
++	brcms_b_xtal(wlc_hw, ON);
++	ai_clkctl_init(wlc_hw->sih);
++	brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST);
++
++	/*
++	 * TODO: test suspend/resume
++	 *
++	 * AI chip doesn't restore bar0win2 on
++	 * hibernation/resume, need sw fixup
++	 */
++
++	/*
++	 * Inform phy that a POR reset has occurred so
++	 * it does a complete phy init
++	 */
++	wlc_phy_por_inform(wlc_hw->band->pi);
++
++	wlc_hw->ucode_loaded = false;
++	wlc_hw->wlc->pub->hw_up = true;
++
++	if ((wlc_hw->boardflags & BFL_FEM)
++	    && (ai_get_chip_id(wlc_hw->sih) == BCM4313_CHIP_ID)) {
++		if (!
++		    (wlc_hw->boardrev >= 0x1250
++		     && (wlc_hw->boardflags & BFL_FEM_BT)))
++			ai_epa_4313war(wlc_hw->sih);
++	}
++}
++
++static int brcms_b_up_prep(struct brcms_hardware *wlc_hw)
++{
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
++
++	/*
++	 * Enable pll and xtal, initialize the power control registers,
++	 * and force fastclock for the remainder of brcms_c_up().
++	 */
++	brcms_b_xtal(wlc_hw, ON);
++	ai_clkctl_init(wlc_hw->sih);
++	brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST);
++
++	/*
++	 * Configure pci/pcmcia here instead of in brcms_c_attach()
++	 * to allow mfg hotswap:  down, hotswap (chip power cycle), up.
++	 */
++	bcma_core_pci_irq_ctl(&wlc_hw->d11core->bus->drv_pci, wlc_hw->d11core,
++			      true);
++
++	/*
++	 * Need to read the hwradio status here to cover the case where the
++	 * system is loaded with the hw radio disabled. We do not want to
++	 * bring the driver up in this case.
++	 */
++	if (brcms_b_radio_read_hwdisabled(wlc_hw)) {
++		/* put SB PCI in down state again */
++		ai_pci_down(wlc_hw->sih);
++		brcms_b_xtal(wlc_hw, OFF);
++		return -ENOMEDIUM;
++	}
++
++	ai_pci_up(wlc_hw->sih);
++
++	/* reset the d11 core */
++	brcms_b_corereset(wlc_hw, BRCMS_USE_COREFLAGS);
++
++	return 0;
++}
++
++static int brcms_b_up_finish(struct brcms_hardware *wlc_hw)
++{
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
++
++	wlc_hw->up = true;
++	wlc_phy_hw_state_upd(wlc_hw->band->pi, true);
++
++	/* FULLY enable dynamic power control and d11 core interrupt */
++	brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_DYNAMIC);
++	brcms_intrson(wlc_hw->wlc->wl);
++	return 0;
++}
++
++/*
++ * Write WME tunable parameters for retransmit/max rate
++ * from wlc struct to ucode
++ */
++static void brcms_c_wme_retries_write(struct brcms_c_info *wlc)
++{
++	int ac;
++
++	/* Need clock to do this */
++	if (!wlc->clk)
++		return;
++
++	for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
++		brcms_b_write_shm(wlc->hw, M_AC_TXLMT_ADDR(ac),
++				  wlc->wme_retries[ac]);
++}
++
++/* make interface operational */
++int brcms_c_up(struct brcms_c_info *wlc)
++{
++	BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
++
++	/* HW is turned off so don't try to access it */
++	if (wlc->pub->hw_off || brcms_deviceremoved(wlc))
++		return -ENOMEDIUM;
++
++	if (!wlc->pub->hw_up) {
++		brcms_b_hw_up(wlc->hw);
++		wlc->pub->hw_up = true;
++	}
++
++	if ((wlc->pub->boardflags & BFL_FEM)
++	    && (ai_get_chip_id(wlc->hw->sih) == BCM4313_CHIP_ID)) {
++		if (wlc->pub->boardrev >= 0x1250
++		    && (wlc->pub->boardflags & BFL_FEM_BT))
++			brcms_b_mhf(wlc->hw, MHF5, MHF5_4313_GPIOCTRL,
++				MHF5_4313_GPIOCTRL, BRCM_BAND_ALL);
++		else
++			brcms_b_mhf(wlc->hw, MHF4, MHF4_EXTPA_ENABLE,
++				    MHF4_EXTPA_ENABLE, BRCM_BAND_ALL);
++	}
++
++	/*
++	 * Need to read the hwradio status here to cover the case where the
++	 * system is loaded with the hw radio disabled. We do not want to bring
++	 * the driver up in this case. If radio is disabled, abort up, lower
++	 * power, start radio timer and return 0(for NDIS) don't call
++	 * radio_update to avoid looping brcms_c_up.
++	 *
++	 * brcms_b_up_prep() returns either 0 or -BCME_RADIOOFF only
++	 */
++	if (!wlc->pub->radio_disabled) {
++		int status = brcms_b_up_prep(wlc->hw);
++		if (status == -ENOMEDIUM) {
++			if (!mboolisset
++			    (wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE)) {
++				struct brcms_bss_cfg *bsscfg = wlc->bsscfg;
++				mboolset(wlc->pub->radio_disabled,
++					 WL_RADIO_HW_DISABLE);
++
++				if (bsscfg->enable && bsscfg->BSS)
++					wiphy_err(wlc->wiphy, "wl%d: up"
++						  ": rfdisable -> "
++						  "bsscfg_disable()\n",
++						   wlc->pub->unit);
++			}
++		}
++	}
++
++	if (wlc->pub->radio_disabled) {
++		brcms_c_radio_monitor_start(wlc);
++		return 0;
++	}
++
++	/* brcms_b_up_prep has done brcms_c_corereset(). so clk is on, set it */
++	wlc->clk = true;
++
++	brcms_c_radio_monitor_stop(wlc);
++
++	/* Set EDCF hostflags */
++	brcms_b_mhf(wlc->hw, MHF1, MHF1_EDCF, MHF1_EDCF, BRCM_BAND_ALL);
++
++	brcms_init(wlc->wl);
++	wlc->pub->up = true;
++
++	if (wlc->bandinit_pending) {
++		brcms_c_suspend_mac_and_wait(wlc);
++		brcms_c_set_chanspec(wlc, wlc->default_bss->chanspec);
++		wlc->bandinit_pending = false;
++		brcms_c_enable_mac(wlc);
++	}
++
++	brcms_b_up_finish(wlc->hw);
++
++	/* Program the TX wme params with the current settings */
++	brcms_c_wme_retries_write(wlc);
++
++	/* start one second watchdog timer */
++	brcms_add_timer(wlc->wdtimer, TIMER_INTERVAL_WATCHDOG, true);
++	wlc->WDarmed = true;
++
++	/* ensure antenna config is up to date */
++	brcms_c_stf_phy_txant_upd(wlc);
++	/* ensure LDPC config is in sync */
++	brcms_c_ht_update_ldpc(wlc, wlc->stf->ldpc);
++
++	return 0;
++}
++
++static uint brcms_c_down_del_timer(struct brcms_c_info *wlc)
++{
++	uint callbacks = 0;
++
++	return callbacks;
++}
++
++static int brcms_b_bmac_down_prep(struct brcms_hardware *wlc_hw)
++{
++	bool dev_gone;
++	uint callbacks = 0;
++
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
++
++	if (!wlc_hw->up)
++		return callbacks;
++
++	dev_gone = brcms_deviceremoved(wlc_hw->wlc);
++
++	/* disable interrupts */
++	if (dev_gone)
++		wlc_hw->wlc->macintmask = 0;
++	else {
++		/* now disable interrupts */
++		brcms_intrsoff(wlc_hw->wlc->wl);
++
++		/* ensure we're running on the pll clock again */
++		brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST);
++	}
++	/* down phy at the last of this stage */
++	callbacks += wlc_phy_down(wlc_hw->band->pi);
++
++	return callbacks;
++}
++
++static int brcms_b_down_finish(struct brcms_hardware *wlc_hw)
++{
++	uint callbacks = 0;
++	bool dev_gone;
++
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
++
++	if (!wlc_hw->up)
++		return callbacks;
++
++	wlc_hw->up = false;
++	wlc_phy_hw_state_upd(wlc_hw->band->pi, false);
++
++	dev_gone = brcms_deviceremoved(wlc_hw->wlc);
++
++	if (dev_gone) {
++		wlc_hw->sbclk = false;
++		wlc_hw->clk = false;
++		wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, false);
++
++		/* reclaim any posted packets */
++		brcms_c_flushqueues(wlc_hw->wlc);
++	} else {
++
++		/* Reset and disable the core */
++		if (bcma_core_is_enabled(wlc_hw->d11core)) {
++			if (bcma_read32(wlc_hw->d11core,
++					D11REGOFFS(maccontrol)) & MCTL_EN_MAC)
++				brcms_c_suspend_mac_and_wait(wlc_hw->wlc);
++			callbacks += brcms_reset(wlc_hw->wlc->wl);
++			brcms_c_coredisable(wlc_hw);
++		}
++
++		/* turn off primary xtal and pll */
++		if (!wlc_hw->noreset) {
++			ai_pci_down(wlc_hw->sih);
++			brcms_b_xtal(wlc_hw, OFF);
++		}
++	}
++
++	return callbacks;
++}
++
++/*
++ * Mark the interface nonoperational, stop the software mechanisms,
++ * disable the hardware, free any transient buffer state.
++ * Return a count of the number of driver callbacks still pending.
++ */
++uint brcms_c_down(struct brcms_c_info *wlc)
++{
++
++	uint callbacks = 0;
++	int i;
++	bool dev_gone = false;
++	struct brcms_txq_info *qi;
++
++	BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
++
++	/* check if we are already in the going down path */
++	if (wlc->going_down) {
++		wiphy_err(wlc->wiphy, "wl%d: %s: Driver going down so return"
++			  "\n", wlc->pub->unit, __func__);
++		return 0;
++	}
++	if (!wlc->pub->up)
++		return callbacks;
++
++	wlc->going_down = true;
++
++	callbacks += brcms_b_bmac_down_prep(wlc->hw);
++
++	dev_gone = brcms_deviceremoved(wlc);
++
++	/* Call any registered down handlers */
++	for (i = 0; i < BRCMS_MAXMODULES; i++) {
++		if (wlc->modulecb[i].down_fn)
++			callbacks +=
++			    wlc->modulecb[i].down_fn(wlc->modulecb[i].hdl);
++	}
++
++	/* cancel the watchdog timer */
++	if (wlc->WDarmed) {
++		if (!brcms_del_timer(wlc->wdtimer))
++			callbacks++;
++		wlc->WDarmed = false;
++	}
++	/* cancel all other timers */
++	callbacks += brcms_c_down_del_timer(wlc);
++
++	wlc->pub->up = false;
++
++	wlc_phy_mute_upd(wlc->band->pi, false, PHY_MUTE_ALL);
++
++	/* clear txq flow control */
++	brcms_c_txflowcontrol_reset(wlc);
++
++	/* flush tx queues */
++	for (qi = wlc->tx_queues; qi != NULL; qi = qi->next)
++		brcmu_pktq_flush(&qi->q, true, NULL, NULL);
++
++	callbacks += brcms_b_down_finish(wlc->hw);
++
++	/* brcms_b_down_finish has done brcms_c_coredisable(). so clk is off */
++	wlc->clk = false;
++
++	wlc->going_down = false;
++	return callbacks;
++}
++
++/* Set the current gmode configuration */
++int brcms_c_set_gmode(struct brcms_c_info *wlc, u8 gmode, bool config)
++{
++	int ret = 0;
++	uint i;
++	struct brcms_c_rateset rs;
++	/* Default to 54g Auto */
++	/* Advertise and use shortslot (-1/0/1 Auto/Off/On) */
++	s8 shortslot = BRCMS_SHORTSLOT_AUTO;
++	bool shortslot_restrict = false; /* Restrict association to stations
++					  * that support shortslot
++					  */
++	bool ofdm_basic = false;	/* Make 6, 12, and 24 basic rates */
++	/* Advertise and use short preambles (-1/0/1 Auto/Off/On) */
++	int preamble = BRCMS_PLCP_LONG;
++	bool preamble_restrict = false;	/* Restrict association to stations
++					 * that support short preambles
++					 */
++	struct brcms_band *band;
++
++	/* if N-support is enabled, allow Gmode set as long as requested
++	 * Gmode is not GMODE_LEGACY_B
++	 */
++	if ((wlc->pub->_n_enab & SUPPORT_11N) && gmode == GMODE_LEGACY_B)
++		return -ENOTSUPP;
++
++	/* verify that we are dealing with 2G band and grab the band pointer */
++	if (wlc->band->bandtype == BRCM_BAND_2G)
++		band = wlc->band;
++	else if ((wlc->pub->_nbands > 1) &&
++		 (wlc->bandstate[OTHERBANDUNIT(wlc)]->bandtype == BRCM_BAND_2G))
++		band = wlc->bandstate[OTHERBANDUNIT(wlc)];
++	else
++		return -EINVAL;
++
++	/* Legacy or bust when no OFDM is supported by regulatory */
++	if ((brcms_c_channel_locale_flags_in_band(wlc->cmi, band->bandunit) &
++	     BRCMS_NO_OFDM) && (gmode != GMODE_LEGACY_B))
++		return -EINVAL;
++
++	/* update configuration value */
++	if (config)
++		brcms_c_protection_upd(wlc, BRCMS_PROT_G_USER, gmode);
++
++	/* Clear rateset override */
++	memset(&rs, 0, sizeof(struct brcms_c_rateset));
++
++	switch (gmode) {
++	case GMODE_LEGACY_B:
++		shortslot = BRCMS_SHORTSLOT_OFF;
++		brcms_c_rateset_copy(&gphy_legacy_rates, &rs);
++
++		break;
++
++	case GMODE_LRS:
++		break;
++
++	case GMODE_AUTO:
++		/* Accept defaults */
++		break;
++
++	case GMODE_ONLY:
++		ofdm_basic = true;
++		preamble = BRCMS_PLCP_SHORT;
++		preamble_restrict = true;
++		break;
++
++	case GMODE_PERFORMANCE:
++		shortslot = BRCMS_SHORTSLOT_ON;
++		shortslot_restrict = true;
++		ofdm_basic = true;
++		preamble = BRCMS_PLCP_SHORT;
++		preamble_restrict = true;
++		break;
++
++	default:
++		/* Error */
++		wiphy_err(wlc->wiphy, "wl%d: %s: invalid gmode %d\n",
++			  wlc->pub->unit, __func__, gmode);
++		return -ENOTSUPP;
++	}
++
++	band->gmode = gmode;
++
++	wlc->shortslot_override = shortslot;
++
++	/* Use the default 11g rateset */
++	if (!rs.count)
++		brcms_c_rateset_copy(&cck_ofdm_rates, &rs);
++
++	if (ofdm_basic) {
++		for (i = 0; i < rs.count; i++) {
++			if (rs.rates[i] == BRCM_RATE_6M
++			    || rs.rates[i] == BRCM_RATE_12M
++			    || rs.rates[i] == BRCM_RATE_24M)
++				rs.rates[i] |= BRCMS_RATE_FLAG;
++		}
++	}
++
++	/* Set default bss rateset */
++	wlc->default_bss->rateset.count = rs.count;
++	memcpy(wlc->default_bss->rateset.rates, rs.rates,
++	       sizeof(wlc->default_bss->rateset.rates));
++
++	return ret;
++}
++
++int brcms_c_set_nmode(struct brcms_c_info *wlc)
++{
++	uint i;
++	s32 nmode = AUTO;
++
++	if (wlc->stf->txstreams == WL_11N_3x3)
++		nmode = WL_11N_3x3;
++	else
++		nmode = WL_11N_2x2;
++
++	/* force GMODE_AUTO if NMODE is ON */
++	brcms_c_set_gmode(wlc, GMODE_AUTO, true);
++	if (nmode == WL_11N_3x3)
++		wlc->pub->_n_enab = SUPPORT_HT;
++	else
++		wlc->pub->_n_enab = SUPPORT_11N;
++	wlc->default_bss->flags |= BRCMS_BSS_HT;
++	/* add the mcs rates to the default and hw ratesets */
++	brcms_c_rateset_mcs_build(&wlc->default_bss->rateset,
++			      wlc->stf->txstreams);
++	for (i = 0; i < wlc->pub->_nbands; i++)
++		memcpy(wlc->bandstate[i]->hw_rateset.mcs,
++		       wlc->default_bss->rateset.mcs, MCSSET_LEN);
++
++	return 0;
++}
++
++static int
++brcms_c_set_internal_rateset(struct brcms_c_info *wlc,
++			     struct brcms_c_rateset *rs_arg)
++{
++	struct brcms_c_rateset rs, new;
++	uint bandunit;
++
++	memcpy(&rs, rs_arg, sizeof(struct brcms_c_rateset));
++
++	/* check for bad count value */
++	if ((rs.count == 0) || (rs.count > BRCMS_NUMRATES))
++		return -EINVAL;
++
++	/* try the current band */
++	bandunit = wlc->band->bandunit;
++	memcpy(&new, &rs, sizeof(struct brcms_c_rateset));
++	if (brcms_c_rate_hwrs_filter_sort_validate
++	    (&new, &wlc->bandstate[bandunit]->hw_rateset, true,
++	     wlc->stf->txstreams))
++		goto good;
++
++	/* try the other band */
++	if (brcms_is_mband_unlocked(wlc)) {
++		bandunit = OTHERBANDUNIT(wlc);
++		memcpy(&new, &rs, sizeof(struct brcms_c_rateset));
++		if (brcms_c_rate_hwrs_filter_sort_validate(&new,
++						       &wlc->
++						       bandstate[bandunit]->
++						       hw_rateset, true,
++						       wlc->stf->txstreams))
++			goto good;
++	}
++
++	return -EBADE;
++
++ good:
++	/* apply new rateset */
++	memcpy(&wlc->default_bss->rateset, &new,
++	       sizeof(struct brcms_c_rateset));
++	memcpy(&wlc->bandstate[bandunit]->defrateset, &new,
++	       sizeof(struct brcms_c_rateset));
++	return 0;
++}
++
++static void brcms_c_ofdm_rateset_war(struct brcms_c_info *wlc)
++{
++	u8 r;
++	bool war = false;
++
++	if (wlc->bsscfg->associated)
++		r = wlc->bsscfg->current_bss->rateset.rates[0];
++	else
++		r = wlc->default_bss->rateset.rates[0];
++
++	wlc_phy_ofdm_rateset_war(wlc->band->pi, war);
++}
++
++int brcms_c_set_channel(struct brcms_c_info *wlc, u16 channel)
++{
++	u16 chspec = ch20mhz_chspec(channel);
++
++	if (channel < 0 || channel > MAXCHANNEL)
++		return -EINVAL;
++
++	if (!brcms_c_valid_chanspec_db(wlc->cmi, chspec))
++		return -EINVAL;
++
++
++	if (!wlc->pub->up && brcms_is_mband_unlocked(wlc)) {
++		if (wlc->band->bandunit != chspec_bandunit(chspec))
++			wlc->bandinit_pending = true;
++		else
++			wlc->bandinit_pending = false;
++	}
++
++	wlc->default_bss->chanspec = chspec;
++	/* brcms_c_BSSinit() will sanitize the rateset before
++	 * using it.. */
++	if (wlc->pub->up && (wlc_phy_chanspec_get(wlc->band->pi) != chspec)) {
++		brcms_c_set_home_chanspec(wlc, chspec);
++		brcms_c_suspend_mac_and_wait(wlc);
++		brcms_c_set_chanspec(wlc, chspec);
++		brcms_c_enable_mac(wlc);
++	}
++	return 0;
++}
++
++int brcms_c_set_rate_limit(struct brcms_c_info *wlc, u16 srl, u16 lrl)
++{
++	int ac;
++
++	if (srl < 1 || srl > RETRY_SHORT_MAX ||
++	    lrl < 1 || lrl > RETRY_SHORT_MAX)
++		return -EINVAL;
++
++	wlc->SRL = srl;
++	wlc->LRL = lrl;
++
++	brcms_b_retrylimit_upd(wlc->hw, wlc->SRL, wlc->LRL);
++
++	for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
++		wlc->wme_retries[ac] =	SFIELD(wlc->wme_retries[ac],
++					       EDCF_SHORT,  wlc->SRL);
++		wlc->wme_retries[ac] =	SFIELD(wlc->wme_retries[ac],
++					       EDCF_LONG, wlc->LRL);
++	}
++	brcms_c_wme_retries_write(wlc);
++
++	return 0;
++}
++
++void brcms_c_get_current_rateset(struct brcms_c_info *wlc,
++				 struct brcm_rateset *currs)
++{
++	struct brcms_c_rateset *rs;
++
++	if (wlc->pub->associated)
++		rs = &wlc->bsscfg->current_bss->rateset;
++	else
++		rs = &wlc->default_bss->rateset;
++
++	/* Copy only legacy rateset section */
++	currs->count = rs->count;
++	memcpy(&currs->rates, &rs->rates, rs->count);
++}
++
++int brcms_c_set_rateset(struct brcms_c_info *wlc, struct brcm_rateset *rs)
++{
++	struct brcms_c_rateset internal_rs;
++	int bcmerror;
++
++	if (rs->count > BRCMS_NUMRATES)
++		return -ENOBUFS;
++
++	memset(&internal_rs, 0, sizeof(struct brcms_c_rateset));
++
++	/* Copy only legacy rateset section */
++	internal_rs.count = rs->count;
++	memcpy(&internal_rs.rates, &rs->rates, internal_rs.count);
++
++	/* merge rateset coming in with the current mcsset */
++	if (wlc->pub->_n_enab & SUPPORT_11N) {
++		struct brcms_bss_info *mcsset_bss;
++		if (wlc->bsscfg->associated)
++			mcsset_bss = wlc->bsscfg->current_bss;
++		else
++			mcsset_bss = wlc->default_bss;
++		memcpy(internal_rs.mcs, &mcsset_bss->rateset.mcs[0],
++		       MCSSET_LEN);
++	}
++
++	bcmerror = brcms_c_set_internal_rateset(wlc, &internal_rs);
++	if (!bcmerror)
++		brcms_c_ofdm_rateset_war(wlc);
++
++	return bcmerror;
++}
++
++int brcms_c_set_beacon_period(struct brcms_c_info *wlc, u16 period)
++{
++	if (period < DOT11_MIN_BEACON_PERIOD ||
++	    period > DOT11_MAX_BEACON_PERIOD)
++		return -EINVAL;
++
++	wlc->default_bss->beacon_period = period;
++	return 0;
++}
++
++u16 brcms_c_get_phy_type(struct brcms_c_info *wlc, int phyidx)
++{
++	return wlc->band->phytype;
++}
++
++void brcms_c_set_shortslot_override(struct brcms_c_info *wlc, s8 sslot_override)
++{
++	wlc->shortslot_override = sslot_override;
++
++	/*
++	 * shortslot is an 11g feature, so no more work if we are
++	 * currently on the 5G band
++	 */
++	if (wlc->band->bandtype == BRCM_BAND_5G)
++		return;
++
++	if (wlc->pub->up && wlc->pub->associated) {
++		/* let watchdog or beacon processing update shortslot */
++	} else if (wlc->pub->up) {
++		/* unassociated shortslot is off */
++		brcms_c_switch_shortslot(wlc, false);
++	} else {
++		/* driver is down, so just update the brcms_c_info
++		 * value */
++		if (wlc->shortslot_override == BRCMS_SHORTSLOT_AUTO)
++			wlc->shortslot = false;
++		else
++			wlc->shortslot =
++			    (wlc->shortslot_override ==
++			     BRCMS_SHORTSLOT_ON);
++	}
++}
++
++/*
++ * register watchdog and down handlers.
++ */
++int brcms_c_module_register(struct brcms_pub *pub,
++			    const char *name, struct brcms_info *hdl,
++			    int (*d_fn)(void *handle))
++{
++	struct brcms_c_info *wlc = (struct brcms_c_info *) pub->wlc;
++	int i;
++
++	/* find an empty entry and just add, no duplication check! */
++	for (i = 0; i < BRCMS_MAXMODULES; i++) {
++		if (wlc->modulecb[i].name[0] == '\0') {
++			strncpy(wlc->modulecb[i].name, name,
++				sizeof(wlc->modulecb[i].name) - 1);
++			wlc->modulecb[i].hdl = hdl;
++			wlc->modulecb[i].down_fn = d_fn;
++			return 0;
++		}
++	}
++
++	return -ENOSR;
++}
++
++/* unregister module callbacks */
++int brcms_c_module_unregister(struct brcms_pub *pub, const char *name,
++			      struct brcms_info *hdl)
++{
++	struct brcms_c_info *wlc = (struct brcms_c_info *) pub->wlc;
++	int i;
++
++	if (wlc == NULL)
++		return -ENODATA;
++
++	for (i = 0; i < BRCMS_MAXMODULES; i++) {
++		if (!strcmp(wlc->modulecb[i].name, name) &&
++		    (wlc->modulecb[i].hdl == hdl)) {
++			memset(&wlc->modulecb[i], 0, sizeof(struct modulecb));
++			return 0;
++		}
++	}
++
++	/* table not found! */
++	return -ENODATA;
++}
++
++void brcms_c_print_txstatus(struct tx_status *txs)
++{
++	pr_debug("\ntxpkt (MPDU) Complete\n");
++
++	pr_debug("FrameID: %04x   TxStatus: %04x\n", txs->frameid, txs->status);
++
++	pr_debug("[15:12]  %d  frame attempts\n",
++		  (txs->status & TX_STATUS_FRM_RTX_MASK) >>
++		 TX_STATUS_FRM_RTX_SHIFT);
++	pr_debug(" [11:8]  %d  rts attempts\n",
++		 (txs->status & TX_STATUS_RTS_RTX_MASK) >>
++		 TX_STATUS_RTS_RTX_SHIFT);
++	pr_debug("    [7]  %d  PM mode indicated\n",
++		 txs->status & TX_STATUS_PMINDCTD ? 1 : 0);
++	pr_debug("    [6]  %d  intermediate status\n",
++		 txs->status & TX_STATUS_INTERMEDIATE ? 1 : 0);
++	pr_debug("    [5]  %d  AMPDU\n",
++		 txs->status & TX_STATUS_AMPDU ? 1 : 0);
++	pr_debug("  [4:2]  %d  Frame Suppressed Reason (%s)\n",
++		 (txs->status & TX_STATUS_SUPR_MASK) >> TX_STATUS_SUPR_SHIFT,
++		 (const char *[]) {
++			"None",
++			"PMQ Entry",
++			"Flush request",
++			"Previous frag failure",
++			"Channel mismatch",
++			"Lifetime Expiry",
++			"Underflow"
++		 } [(txs->status & TX_STATUS_SUPR_MASK) >>
++		    TX_STATUS_SUPR_SHIFT]);
++	pr_debug("    [1]  %d  acked\n",
++		 txs->status & TX_STATUS_ACK_RCV ? 1 : 0);
++
++	pr_debug("LastTxTime: %04x Seq: %04x PHYTxStatus: %04x RxAckRSSI: %04x RxAckSQ: %04x\n",
++		 txs->lasttxtime, txs->sequence, txs->phyerr,
++		 (txs->ackphyrxsh & PRXS1_JSSI_MASK) >> PRXS1_JSSI_SHIFT,
++		 (txs->ackphyrxsh & PRXS1_SQ_MASK) >> PRXS1_SQ_SHIFT);
++}
++
++bool brcms_c_chipmatch(u16 vendor, u16 device)
++{
++	if (vendor != PCI_VENDOR_ID_BROADCOM) {
++		pr_err("unknown vendor id %04x\n", vendor);
++		return false;
++	}
++
++	if (device == BCM43224_D11N_ID_VEN1)
++		return true;
++	if ((device == BCM43224_D11N_ID) || (device == BCM43225_D11N2G_ID))
++		return true;
++	if (device == BCM4313_D11N2G_ID)
++		return true;
++	if ((device == BCM43236_D11N_ID) || (device == BCM43236_D11N2G_ID))
++		return true;
++
++	pr_err("unknown device id %04x\n", device);
++	return false;
++}
++
++#if defined(DEBUG)
++void brcms_c_print_txdesc(struct d11txh *txh)
++{
++	u16 mtcl = le16_to_cpu(txh->MacTxControlLow);
++	u16 mtch = le16_to_cpu(txh->MacTxControlHigh);
++	u16 mfc = le16_to_cpu(txh->MacFrameControl);
++	u16 tfest = le16_to_cpu(txh->TxFesTimeNormal);
++	u16 ptcw = le16_to_cpu(txh->PhyTxControlWord);
++	u16 ptcw_1 = le16_to_cpu(txh->PhyTxControlWord_1);
++	u16 ptcw_1_Fbr = le16_to_cpu(txh->PhyTxControlWord_1_Fbr);
++	u16 ptcw_1_Rts = le16_to_cpu(txh->PhyTxControlWord_1_Rts);
++	u16 ptcw_1_FbrRts = le16_to_cpu(txh->PhyTxControlWord_1_FbrRts);
++	u16 mainrates = le16_to_cpu(txh->MainRates);
++	u16 xtraft = le16_to_cpu(txh->XtraFrameTypes);
++	u8 *iv = txh->IV;
++	u8 *ra = txh->TxFrameRA;
++	u16 tfestfb = le16_to_cpu(txh->TxFesTimeFallback);
++	u8 *rtspfb = txh->RTSPLCPFallback;
++	u16 rtsdfb = le16_to_cpu(txh->RTSDurFallback);
++	u8 *fragpfb = txh->FragPLCPFallback;
++	u16 fragdfb = le16_to_cpu(txh->FragDurFallback);
++	u16 mmodelen = le16_to_cpu(txh->MModeLen);
++	u16 mmodefbrlen = le16_to_cpu(txh->MModeFbrLen);
++	u16 tfid = le16_to_cpu(txh->TxFrameID);
++	u16 txs = le16_to_cpu(txh->TxStatus);
++	u16 mnmpdu = le16_to_cpu(txh->MaxNMpdus);
++	u16 mabyte = le16_to_cpu(txh->MaxABytes_MRT);
++	u16 mabyte_f = le16_to_cpu(txh->MaxABytes_FBR);
++	u16 mmbyte = le16_to_cpu(txh->MinMBytes);
++
++	u8 *rtsph = txh->RTSPhyHeader;
++	struct ieee80211_rts rts = txh->rts_frame;
++
++	/* add plcp header along with txh descriptor */
++	brcmu_dbg_hex_dump(txh, sizeof(struct d11txh) + 48,
++			   "Raw TxDesc + plcp header:\n");
++
++	pr_debug("TxCtlLow: %04x ", mtcl);
++	pr_debug("TxCtlHigh: %04x ", mtch);
++	pr_debug("FC: %04x ", mfc);
++	pr_debug("FES Time: %04x\n", tfest);
++	pr_debug("PhyCtl: %04x%s ", ptcw,
++	       (ptcw & PHY_TXC_SHORT_HDR) ? " short" : "");
++	pr_debug("PhyCtl_1: %04x ", ptcw_1);
++	pr_debug("PhyCtl_1_Fbr: %04x\n", ptcw_1_Fbr);
++	pr_debug("PhyCtl_1_Rts: %04x ", ptcw_1_Rts);
++	pr_debug("PhyCtl_1_Fbr_Rts: %04x\n", ptcw_1_FbrRts);
++	pr_debug("MainRates: %04x ", mainrates);
++	pr_debug("XtraFrameTypes: %04x ", xtraft);
++	pr_debug("\n");
++
++	print_hex_dump_bytes("SecIV:", DUMP_PREFIX_OFFSET, iv, sizeof(txh->IV));
++	print_hex_dump_bytes("RA:", DUMP_PREFIX_OFFSET,
++			     ra, sizeof(txh->TxFrameRA));
++
++	pr_debug("Fb FES Time: %04x ", tfestfb);
++	print_hex_dump_bytes("Fb RTS PLCP:", DUMP_PREFIX_OFFSET,
++			     rtspfb, sizeof(txh->RTSPLCPFallback));
++	pr_debug("RTS DUR: %04x ", rtsdfb);
++	print_hex_dump_bytes("PLCP:", DUMP_PREFIX_OFFSET,
++			     fragpfb, sizeof(txh->FragPLCPFallback));
++	pr_debug("DUR: %04x", fragdfb);
++	pr_debug("\n");
++
++	pr_debug("MModeLen: %04x ", mmodelen);
++	pr_debug("MModeFbrLen: %04x\n", mmodefbrlen);
++
++	pr_debug("FrameID:     %04x\n", tfid);
++	pr_debug("TxStatus:    %04x\n", txs);
++
++	pr_debug("MaxNumMpdu:  %04x\n", mnmpdu);
++	pr_debug("MaxAggbyte:  %04x\n", mabyte);
++	pr_debug("MaxAggbyte_fb:  %04x\n", mabyte_f);
++	pr_debug("MinByte:     %04x\n", mmbyte);
++
++	print_hex_dump_bytes("RTS PLCP:", DUMP_PREFIX_OFFSET,
++			     rtsph, sizeof(txh->RTSPhyHeader));
++	print_hex_dump_bytes("RTS Frame:", DUMP_PREFIX_OFFSET,
++			     (u8 *)&rts, sizeof(txh->rts_frame));
++	pr_debug("\n");
++}
++#endif				/* defined(DEBUG) */
++
++#if defined(DEBUG)
++static int
++brcms_c_format_flags(const struct brcms_c_bit_desc *bd, u32 flags, char *buf,
++		     int len)
++{
++	int i;
++	char *p = buf;
++	char hexstr[16];
++	int slen = 0, nlen = 0;
++	u32 bit;
++	const char *name;
++
++	if (len < 2 || !buf)
++		return 0;
++
++	buf[0] = '\0';
++
++	for (i = 0; flags != 0; i++) {
++		bit = bd[i].bit;
++		name = bd[i].name;
++		if (bit == 0 && flags != 0) {
++			/* print any unnamed bits */
++			snprintf(hexstr, 16, "0x%X", flags);
++			name = hexstr;
++			flags = 0;	/* exit loop */
++		} else if ((flags & bit) == 0)
++			continue;
++		flags &= ~bit;
++		nlen = strlen(name);
++		slen += nlen;
++		/* count btwn flag space */
++		if (flags != 0)
++			slen += 1;
++		/* need NULL char as well */
++		if (len <= slen)
++			break;
++		/* copy NULL char but don't count it */
++		strncpy(p, name, nlen + 1);
++		p += nlen;
++		/* copy btwn flag space and NULL char */
++		if (flags != 0)
++			p += snprintf(p, 2, " ");
++		len -= slen;
++	}
++
++	/* indicate the str was too short */
++	if (flags != 0) {
++		if (len < 2)
++			p -= 2 - len;	/* overwrite last char */
++		p += snprintf(p, 2, ">");
++	}
++
++	return (int)(p - buf);
++}
++#endif				/* defined(DEBUG) */
++
++#if defined(DEBUG)
++void brcms_c_print_rxh(struct d11rxhdr *rxh)
++{
++	u16 len = rxh->RxFrameSize;
++	u16 phystatus_0 = rxh->PhyRxStatus_0;
++	u16 phystatus_1 = rxh->PhyRxStatus_1;
++	u16 phystatus_2 = rxh->PhyRxStatus_2;
++	u16 phystatus_3 = rxh->PhyRxStatus_3;
++	u16 macstatus1 = rxh->RxStatus1;
++	u16 macstatus2 = rxh->RxStatus2;
++	char flagstr[64];
++	char lenbuf[20];
++	static const struct brcms_c_bit_desc macstat_flags[] = {
++		{RXS_FCSERR, "FCSErr"},
++		{RXS_RESPFRAMETX, "Reply"},
++		{RXS_PBPRES, "PADDING"},
++		{RXS_DECATMPT, "DeCr"},
++		{RXS_DECERR, "DeCrErr"},
++		{RXS_BCNSENT, "Bcn"},
++		{0, NULL}
++	};
++
++	brcmu_dbg_hex_dump(rxh, sizeof(struct d11rxhdr), "Raw RxDesc:\n");
++
++	brcms_c_format_flags(macstat_flags, macstatus1, flagstr, 64);
++
++	snprintf(lenbuf, sizeof(lenbuf), "0x%x", len);
++
++	pr_debug("RxFrameSize:     %6s (%d)%s\n", lenbuf, len,
++	       (rxh->PhyRxStatus_0 & PRXS0_SHORTH) ? " short preamble" : "");
++	pr_debug("RxPHYStatus:     %04x %04x %04x %04x\n",
++	       phystatus_0, phystatus_1, phystatus_2, phystatus_3);
++	pr_debug("RxMACStatus:     %x %s\n", macstatus1, flagstr);
++	pr_debug("RXMACaggtype:    %x\n",
++	       (macstatus2 & RXS_AGGTYPE_MASK));
++	pr_debug("RxTSFTime:       %04x\n", rxh->RxTSFTime);
++}
++#endif				/* defined(DEBUG) */
++
++u16 brcms_b_rate_shm_offset(struct brcms_hardware *wlc_hw, u8 rate)
++{
++	u16 table_ptr;
++	u8 phy_rate, index;
++
++	/* get the phy specific rate encoding for the PLCP SIGNAL field */
++	if (is_ofdm_rate(rate))
++		table_ptr = M_RT_DIRMAP_A;
++	else
++		table_ptr = M_RT_DIRMAP_B;
++
++	/* for a given rate, the LS-nibble of the PLCP SIGNAL field is
++	 * the index into the rate table.
++	 */
++	phy_rate = rate_info[rate] & BRCMS_RATE_MASK;
++	index = phy_rate & 0xf;
++
++	/* Find the SHM pointer to the rate table entry by looking in the
++	 * Direct-map Table
++	 */
++	return 2 * brcms_b_read_shm(wlc_hw, table_ptr + (index * 2));
++}
++
++static bool
++brcms_c_prec_enq_head(struct brcms_c_info *wlc, struct pktq *q,
++		      struct sk_buff *pkt, int prec, bool head)
++{
++	struct sk_buff *p;
++	int eprec = -1;		/* precedence to evict from */
++
++	/* Determine precedence from which to evict packet, if any */
++	if (pktq_pfull(q, prec))
++		eprec = prec;
++	else if (pktq_full(q)) {
++		p = brcmu_pktq_peek_tail(q, &eprec);
++		if (eprec > prec) {
++			wiphy_err(wlc->wiphy, "%s: Failing: eprec %d > prec %d"
++				  "\n", __func__, eprec, prec);
++			return false;
++		}
++	}
++
++	/* Evict if needed */
++	if (eprec >= 0) {
++		bool discard_oldest;
++
++		discard_oldest = ac_bitmap_tst(0, eprec);
++
++		/* Refuse newer packet unless configured to discard oldest */
++		if (eprec == prec && !discard_oldest) {
++			wiphy_err(wlc->wiphy, "%s: No where to go, prec == %d"
++				  "\n", __func__, prec);
++			return false;
++		}
++
++		/* Evict packet according to discard policy */
++		p = discard_oldest ? brcmu_pktq_pdeq(q, eprec) :
++			brcmu_pktq_pdeq_tail(q, eprec);
++		brcmu_pkt_buf_free_skb(p);
++	}
++
++	/* Enqueue */
++	if (head)
++		p = brcmu_pktq_penq_head(q, prec, pkt);
++	else
++		p = brcmu_pktq_penq(q, prec, pkt);
++
++	return true;
++}
++
++/*
++ * Attempts to queue a packet onto a multiple-precedence queue,
++ * if necessary evicting a lower precedence packet from the queue.
++ *
++ * 'prec' is the precedence number that has already been mapped
++ * from the packet priority.
++ *
++ * Returns true if packet consumed (queued), false if not.
++ */
++static bool brcms_c_prec_enq(struct brcms_c_info *wlc, struct pktq *q,
++		      struct sk_buff *pkt, int prec)
++{
++	return brcms_c_prec_enq_head(wlc, q, pkt, prec, false);
++}
++
++void brcms_c_txq_enq(struct brcms_c_info *wlc, struct scb *scb,
++		     struct sk_buff *sdu, uint prec)
++{
++	struct brcms_txq_info *qi = wlc->pkt_queue;	/* Check me */
++	struct pktq *q = &qi->q;
++	int prio;
++
++	prio = sdu->priority;
++
++	if (!brcms_c_prec_enq(wlc, q, sdu, prec)) {
++		/*
++		 * we might hit this condtion in case
++		 * packet flooding from mac80211 stack
++		 */
++		brcmu_pkt_buf_free_skb(sdu);
++	}
++}
++
++/*
++ * bcmc_fid_generate:
++ * Generate frame ID for a BCMC packet.  The frag field is not used
++ * for MC frames so is used as part of the sequence number.
++ */
++static inline u16
++bcmc_fid_generate(struct brcms_c_info *wlc, struct brcms_bss_cfg *bsscfg,
++		  struct d11txh *txh)
++{
++	u16 frameid;
++
++	frameid = le16_to_cpu(txh->TxFrameID) & ~(TXFID_SEQ_MASK |
++						  TXFID_QUEUE_MASK);
++	frameid |=
++	    (((wlc->
++	       mc_fid_counter++) << TXFID_SEQ_SHIFT) & TXFID_SEQ_MASK) |
++	    TX_BCMC_FIFO;
++
++	return frameid;
++}
++
++static uint
++brcms_c_calc_ack_time(struct brcms_c_info *wlc, u32 rspec,
++		      u8 preamble_type)
++{
++	uint dur = 0;
++
++	BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, preamble_type %d\n",
++		wlc->pub->unit, rspec, preamble_type);
++	/*
++	 * Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that
++	 * is less than or equal to the rate of the immediately previous
++	 * frame in the FES
++	 */
++	rspec = brcms_basic_rate(wlc, rspec);
++	/* ACK frame len == 14 == 2(fc) + 2(dur) + 6(ra) + 4(fcs) */
++	dur =
++	    brcms_c_calc_frame_time(wlc, rspec, preamble_type,
++				(DOT11_ACK_LEN + FCS_LEN));
++	return dur;
++}
++
++static uint
++brcms_c_calc_cts_time(struct brcms_c_info *wlc, u32 rspec,
++		      u8 preamble_type)
++{
++	BCMMSG(wlc->wiphy, "wl%d: ratespec 0x%x, preamble_type %d\n",
++		wlc->pub->unit, rspec, preamble_type);
++	return brcms_c_calc_ack_time(wlc, rspec, preamble_type);
++}
++
++static uint
++brcms_c_calc_ba_time(struct brcms_c_info *wlc, u32 rspec,
++		     u8 preamble_type)
++{
++	BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, "
++		 "preamble_type %d\n", wlc->pub->unit, rspec, preamble_type);
++	/*
++	 * Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that
++	 * is less than or equal to the rate of the immediately previous
++	 * frame in the FES
++	 */
++	rspec = brcms_basic_rate(wlc, rspec);
++	/* BA len == 32 == 16(ctl hdr) + 4(ba len) + 8(bitmap) + 4(fcs) */
++	return brcms_c_calc_frame_time(wlc, rspec, preamble_type,
++				   (DOT11_BA_LEN + DOT11_BA_BITMAP_LEN +
++				    FCS_LEN));
++}
++
++/* brcms_c_compute_frame_dur()
++ *
++ * Calculate the 802.11 MAC header DUR field for MPDU
++ * DUR for a single frame = 1 SIFS + 1 ACK
++ * DUR for a frame with following frags = 3 SIFS + 2 ACK + next frag time
++ *
++ * rate			MPDU rate in unit of 500kbps
++ * next_frag_len	next MPDU length in bytes
++ * preamble_type	use short/GF or long/MM PLCP header
++ */
++static u16
++brcms_c_compute_frame_dur(struct brcms_c_info *wlc, u32 rate,
++		      u8 preamble_type, uint next_frag_len)
++{
++	u16 dur, sifs;
++
++	sifs = get_sifs(wlc->band);
++
++	dur = sifs;
++	dur += (u16) brcms_c_calc_ack_time(wlc, rate, preamble_type);
++
++	if (next_frag_len) {
++		/* Double the current DUR to get 2 SIFS + 2 ACKs */
++		dur *= 2;
++		/* add another SIFS and the frag time */
++		dur += sifs;
++		dur +=
++		    (u16) brcms_c_calc_frame_time(wlc, rate, preamble_type,
++						 next_frag_len);
++	}
++	return dur;
++}
++
++/* The opposite of brcms_c_calc_frame_time */
++static uint
++brcms_c_calc_frame_len(struct brcms_c_info *wlc, u32 ratespec,
++		   u8 preamble_type, uint dur)
++{
++	uint nsyms, mac_len, Ndps, kNdps;
++	uint rate = rspec2rate(ratespec);
++
++	BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, preamble_type %d, dur %d\n",
++		 wlc->pub->unit, ratespec, preamble_type, dur);
++
++	if (is_mcs_rate(ratespec)) {
++		uint mcs = ratespec & RSPEC_RATE_MASK;
++		int tot_streams = mcs_2_txstreams(mcs) + rspec_stc(ratespec);
++		dur -= PREN_PREAMBLE + (tot_streams * PREN_PREAMBLE_EXT);
++		/* payload calculation matches that of regular ofdm */
++		if (wlc->band->bandtype == BRCM_BAND_2G)
++			dur -= DOT11_OFDM_SIGNAL_EXTENSION;
++		/* kNdbps = kbps * 4 */
++		kNdps =	mcs_2_rate(mcs, rspec_is40mhz(ratespec),
++				   rspec_issgi(ratespec)) * 4;
++		nsyms = dur / APHY_SYMBOL_TIME;
++		mac_len =
++		    ((nsyms * kNdps) -
++		     ((APHY_SERVICE_NBITS + APHY_TAIL_NBITS) * 1000)) / 8000;
++	} else if (is_ofdm_rate(ratespec)) {
++		dur -= APHY_PREAMBLE_TIME;
++		dur -= APHY_SIGNAL_TIME;
++		/* Ndbps = Mbps * 4 = rate(500Kbps) * 2 */
++		Ndps = rate * 2;
++		nsyms = dur / APHY_SYMBOL_TIME;
++		mac_len =
++		    ((nsyms * Ndps) -
++		     (APHY_SERVICE_NBITS + APHY_TAIL_NBITS)) / 8;
++	} else {
++		if (preamble_type & BRCMS_SHORT_PREAMBLE)
++			dur -= BPHY_PLCP_SHORT_TIME;
++		else
++			dur -= BPHY_PLCP_TIME;
++		mac_len = dur * rate;
++		/* divide out factor of 2 in rate (1/2 mbps) */
++		mac_len = mac_len / 8 / 2;
++	}
++	return mac_len;
++}
++
++/*
++ * Return true if the specified rate is supported by the specified band.
++ * BRCM_BAND_AUTO indicates the current band.
++ */
++static bool brcms_c_valid_rate(struct brcms_c_info *wlc, u32 rspec, int band,
++		    bool verbose)
++{
++	struct brcms_c_rateset *hw_rateset;
++	uint i;
++
++	if ((band == BRCM_BAND_AUTO) || (band == wlc->band->bandtype))
++		hw_rateset = &wlc->band->hw_rateset;
++	else if (wlc->pub->_nbands > 1)
++		hw_rateset = &wlc->bandstate[OTHERBANDUNIT(wlc)]->hw_rateset;
++	else
++		/* other band specified and we are a single band device */
++		return false;
++
++	/* check if this is a mimo rate */
++	if (is_mcs_rate(rspec)) {
++		if ((rspec & RSPEC_RATE_MASK) >= MCS_TABLE_SIZE)
++			goto error;
++
++		return isset(hw_rateset->mcs, (rspec & RSPEC_RATE_MASK));
++	}
++
++	for (i = 0; i < hw_rateset->count; i++)
++		if (hw_rateset->rates[i] == rspec2rate(rspec))
++			return true;
++ error:
++	if (verbose)
++		wiphy_err(wlc->wiphy, "wl%d: valid_rate: rate spec 0x%x "
++			  "not in hw_rateset\n", wlc->pub->unit, rspec);
++
++	return false;
++}
++
++static u32
++mac80211_wlc_set_nrate(struct brcms_c_info *wlc, struct brcms_band *cur_band,
++		       u32 int_val)
++{
++	u8 stf = (int_val & NRATE_STF_MASK) >> NRATE_STF_SHIFT;
++	u8 rate = int_val & NRATE_RATE_MASK;
++	u32 rspec;
++	bool ismcs = ((int_val & NRATE_MCS_INUSE) == NRATE_MCS_INUSE);
++	bool issgi = ((int_val & NRATE_SGI_MASK) >> NRATE_SGI_SHIFT);
++	bool override_mcs_only = ((int_val & NRATE_OVERRIDE_MCS_ONLY)
++				  == NRATE_OVERRIDE_MCS_ONLY);
++	int bcmerror = 0;
++
++	if (!ismcs)
++		return (u32) rate;
++
++	/* validate the combination of rate/mcs/stf is allowed */
++	if ((wlc->pub->_n_enab & SUPPORT_11N) && ismcs) {
++		/* mcs only allowed when nmode */
++		if (stf > PHY_TXC1_MODE_SDM) {
++			wiphy_err(wlc->wiphy, "wl%d: %s: Invalid stf\n",
++				  wlc->pub->unit, __func__);
++			bcmerror = -EINVAL;
++			goto done;
++		}
++
++		/* mcs 32 is a special case, DUP mode 40 only */
++		if (rate == 32) {
++			if (!CHSPEC_IS40(wlc->home_chanspec) ||
++			    ((stf != PHY_TXC1_MODE_SISO)
++			     && (stf != PHY_TXC1_MODE_CDD))) {
++				wiphy_err(wlc->wiphy, "wl%d: %s: Invalid mcs "
++					  "32\n", wlc->pub->unit, __func__);
++				bcmerror = -EINVAL;
++				goto done;
++			}
++			/* mcs > 7 must use stf SDM */
++		} else if (rate > HIGHEST_SINGLE_STREAM_MCS) {
++			/* mcs > 7 must use stf SDM */
++			if (stf != PHY_TXC1_MODE_SDM) {
++				BCMMSG(wlc->wiphy, "wl%d: enabling "
++				       "SDM mode for mcs %d\n",
++				       wlc->pub->unit, rate);
++				stf = PHY_TXC1_MODE_SDM;
++			}
++		} else {
++			/*
++			 * MCS 0-7 may use SISO, CDD, and for
++			 * phy_rev >= 3 STBC
++			 */
++			if ((stf > PHY_TXC1_MODE_STBC) ||
++			    (!BRCMS_STBC_CAP_PHY(wlc)
++			     && (stf == PHY_TXC1_MODE_STBC))) {
++				wiphy_err(wlc->wiphy, "wl%d: %s: Invalid STBC"
++					  "\n", wlc->pub->unit, __func__);
++				bcmerror = -EINVAL;
++				goto done;
++			}
++		}
++	} else if (is_ofdm_rate(rate)) {
++		if ((stf != PHY_TXC1_MODE_CDD) && (stf != PHY_TXC1_MODE_SISO)) {
++			wiphy_err(wlc->wiphy, "wl%d: %s: Invalid OFDM\n",
++				  wlc->pub->unit, __func__);
++			bcmerror = -EINVAL;
++			goto done;
++		}
++	} else if (is_cck_rate(rate)) {
++		if ((cur_band->bandtype != BRCM_BAND_2G)
++		    || (stf != PHY_TXC1_MODE_SISO)) {
++			wiphy_err(wlc->wiphy, "wl%d: %s: Invalid CCK\n",
++				  wlc->pub->unit, __func__);
++			bcmerror = -EINVAL;
++			goto done;
++		}
++	} else {
++		wiphy_err(wlc->wiphy, "wl%d: %s: Unknown rate type\n",
++			  wlc->pub->unit, __func__);
++		bcmerror = -EINVAL;
++		goto done;
++	}
++	/* make sure multiple antennae are available for non-siso rates */
++	if ((stf != PHY_TXC1_MODE_SISO) && (wlc->stf->txstreams == 1)) {
++		wiphy_err(wlc->wiphy, "wl%d: %s: SISO antenna but !SISO "
++			  "request\n", wlc->pub->unit, __func__);
++		bcmerror = -EINVAL;
++		goto done;
++	}
++
++	rspec = rate;
++	if (ismcs) {
++		rspec |= RSPEC_MIMORATE;
++		/* For STBC populate the STC field of the ratespec */
++		if (stf == PHY_TXC1_MODE_STBC) {
++			u8 stc;
++			stc = 1;	/* Nss for single stream is always 1 */
++			rspec |= (stc << RSPEC_STC_SHIFT);
++		}
++	}
++
++	rspec |= (stf << RSPEC_STF_SHIFT);
++
++	if (override_mcs_only)
++		rspec |= RSPEC_OVERRIDE_MCS_ONLY;
++
++	if (issgi)
++		rspec |= RSPEC_SHORT_GI;
++
++	if ((rate != 0)
++	    && !brcms_c_valid_rate(wlc, rspec, cur_band->bandtype, true))
++		return rate;
++
++	return rspec;
++done:
++	return rate;
++}
++
++/*
++ * Compute PLCP, but only requires actual rate and length of pkt.
++ * Rate is given in the driver standard multiple of 500 kbps.
++ * le is set for 11 Mbps rate if necessary.
++ * Broken out for PRQ.
++ */
++
++static void brcms_c_cck_plcp_set(struct brcms_c_info *wlc, int rate_500,
++			     uint length, u8 *plcp)
++{
++	u16 usec = 0;
++	u8 le = 0;
++
++	switch (rate_500) {
++	case BRCM_RATE_1M:
++		usec = length << 3;
++		break;
++	case BRCM_RATE_2M:
++		usec = length << 2;
++		break;
++	case BRCM_RATE_5M5:
++		usec = (length << 4) / 11;
++		if ((length << 4) - (usec * 11) > 0)
++			usec++;
++		break;
++	case BRCM_RATE_11M:
++		usec = (length << 3) / 11;
++		if ((length << 3) - (usec * 11) > 0) {
++			usec++;
++			if ((usec * 11) - (length << 3) >= 8)
++				le = D11B_PLCP_SIGNAL_LE;
++		}
++		break;
++
++	default:
++		wiphy_err(wlc->wiphy,
++			  "brcms_c_cck_plcp_set: unsupported rate %d\n",
++			  rate_500);
++		rate_500 = BRCM_RATE_1M;
++		usec = length << 3;
++		break;
++	}
++	/* PLCP signal byte */
++	plcp[0] = rate_500 * 5;	/* r (500kbps) * 5 == r (100kbps) */
++	/* PLCP service byte */
++	plcp[1] = (u8) (le | D11B_PLCP_SIGNAL_LOCKED);
++	/* PLCP length u16, little endian */
++	plcp[2] = usec & 0xff;
++	plcp[3] = (usec >> 8) & 0xff;
++	/* PLCP CRC16 */
++	plcp[4] = 0;
++	plcp[5] = 0;
++}
++
++/* Rate: 802.11 rate code, length: PSDU length in octets */
++static void brcms_c_compute_mimo_plcp(u32 rspec, uint length, u8 *plcp)
++{
++	u8 mcs = (u8) (rspec & RSPEC_RATE_MASK);
++	plcp[0] = mcs;
++	if (rspec_is40mhz(rspec) || (mcs == 32))
++		plcp[0] |= MIMO_PLCP_40MHZ;
++	BRCMS_SET_MIMO_PLCP_LEN(plcp, length);
++	plcp[3] = rspec_mimoplcp3(rspec); /* rspec already holds this byte */
++	plcp[3] |= 0x7; /* set smoothing, not sounding ppdu & reserved */
++	plcp[4] = 0; /* number of extension spatial streams bit 0 & 1 */
++	plcp[5] = 0;
++}
++
++/* Rate: 802.11 rate code, length: PSDU length in octets */
++static void
++brcms_c_compute_ofdm_plcp(u32 rspec, u32 length, u8 *plcp)
++{
++	u8 rate_signal;
++	u32 tmp = 0;
++	int rate = rspec2rate(rspec);
++
++	/*
++	 * encode rate per 802.11a-1999 sec 17.3.4.1, with lsb
++	 * transmitted first
++	 */
++	rate_signal = rate_info[rate] & BRCMS_RATE_MASK;
++	memset(plcp, 0, D11_PHY_HDR_LEN);
++	D11A_PHY_HDR_SRATE((struct ofdm_phy_hdr *) plcp, rate_signal);
++
++	tmp = (length & 0xfff) << 5;
++	plcp[2] |= (tmp >> 16) & 0xff;
++	plcp[1] |= (tmp >> 8) & 0xff;
++	plcp[0] |= tmp & 0xff;
++}
++
++/* Rate: 802.11 rate code, length: PSDU length in octets */
++static void brcms_c_compute_cck_plcp(struct brcms_c_info *wlc, u32 rspec,
++				 uint length, u8 *plcp)
++{
++	int rate = rspec2rate(rspec);
++
++	brcms_c_cck_plcp_set(wlc, rate, length, plcp);
++}
++
++static void
++brcms_c_compute_plcp(struct brcms_c_info *wlc, u32 rspec,
++		     uint length, u8 *plcp)
++{
++	if (is_mcs_rate(rspec))
++		brcms_c_compute_mimo_plcp(rspec, length, plcp);
++	else if (is_ofdm_rate(rspec))
++		brcms_c_compute_ofdm_plcp(rspec, length, plcp);
++	else
++		brcms_c_compute_cck_plcp(wlc, rspec, length, plcp);
++}
++
++/* brcms_c_compute_rtscts_dur()
++ *
++ * Calculate the 802.11 MAC header DUR field for an RTS or CTS frame
++ * DUR for normal RTS/CTS w/ frame = 3 SIFS + 1 CTS + next frame time + 1 ACK
++ * DUR for CTS-TO-SELF w/ frame    = 2 SIFS         + next frame time + 1 ACK
++ *
++ * cts			cts-to-self or rts/cts
++ * rts_rate		rts or cts rate in unit of 500kbps
++ * rate			next MPDU rate in unit of 500kbps
++ * frame_len		next MPDU frame length in bytes
++ */
++u16
++brcms_c_compute_rtscts_dur(struct brcms_c_info *wlc, bool cts_only,
++			   u32 rts_rate,
++			   u32 frame_rate, u8 rts_preamble_type,
++			   u8 frame_preamble_type, uint frame_len, bool ba)
++{
++	u16 dur, sifs;
++
++	sifs = get_sifs(wlc->band);
++
++	if (!cts_only) {
++		/* RTS/CTS */
++		dur = 3 * sifs;
++		dur +=
++		    (u16) brcms_c_calc_cts_time(wlc, rts_rate,
++					       rts_preamble_type);
++	} else {
++		/* CTS-TO-SELF */
++		dur = 2 * sifs;
++	}
++
++	dur +=
++	    (u16) brcms_c_calc_frame_time(wlc, frame_rate, frame_preamble_type,
++					 frame_len);
++	if (ba)
++		dur +=
++		    (u16) brcms_c_calc_ba_time(wlc, frame_rate,
++					      BRCMS_SHORT_PREAMBLE);
++	else
++		dur +=
++		    (u16) brcms_c_calc_ack_time(wlc, frame_rate,
++					       frame_preamble_type);
++	return dur;
++}
++
++static u16 brcms_c_phytxctl1_calc(struct brcms_c_info *wlc, u32 rspec)
++{
++	u16 phyctl1 = 0;
++	u16 bw;
++
++	if (BRCMS_ISLCNPHY(wlc->band)) {
++		bw = PHY_TXC1_BW_20MHZ;
++	} else {
++		bw = rspec_get_bw(rspec);
++		/* 10Mhz is not supported yet */
++		if (bw < PHY_TXC1_BW_20MHZ) {
++			wiphy_err(wlc->wiphy, "phytxctl1_calc: bw %d is "
++				  "not supported yet, set to 20L\n", bw);
++			bw = PHY_TXC1_BW_20MHZ;
++		}
++	}
++
++	if (is_mcs_rate(rspec)) {
++		uint mcs = rspec & RSPEC_RATE_MASK;
++
++		/* bw, stf, coding-type is part of rspec_phytxbyte2 returns */
++		phyctl1 = rspec_phytxbyte2(rspec);
++		/* set the upper byte of phyctl1 */
++		phyctl1 |= (mcs_table[mcs].tx_phy_ctl3 << 8);
++	} else if (is_cck_rate(rspec) && !BRCMS_ISLCNPHY(wlc->band)
++		   && !BRCMS_ISSSLPNPHY(wlc->band)) {
++		/*
++		 * In CCK mode LPPHY overloads OFDM Modulation bits with CCK
++		 * Data Rate. Eventually MIMOPHY would also be converted to
++		 * this format
++		 */
++		/* 0 = 1Mbps; 1 = 2Mbps; 2 = 5.5Mbps; 3 = 11Mbps */
++		phyctl1 = (bw | (rspec_stf(rspec) << PHY_TXC1_MODE_SHIFT));
++	} else {		/* legacy OFDM/CCK */
++		s16 phycfg;
++		/* get the phyctl byte from rate phycfg table */
++		phycfg = brcms_c_rate_legacy_phyctl(rspec2rate(rspec));
++		if (phycfg == -1) {
++			wiphy_err(wlc->wiphy, "phytxctl1_calc: wrong "
++				  "legacy OFDM/CCK rate\n");
++			phycfg = 0;
++		}
++		/* set the upper byte of phyctl1 */
++		phyctl1 =
++		    (bw | (phycfg << 8) |
++		     (rspec_stf(rspec) << PHY_TXC1_MODE_SHIFT));
++	}
++	return phyctl1;
++}
++
++/*
++ * Add struct d11txh, struct cck_phy_hdr.
++ *
++ * 'p' data must start with 802.11 MAC header
++ * 'p' must allow enough bytes of local headers to be "pushed" onto the packet
++ *
++ * headroom == D11_PHY_HDR_LEN + D11_TXH_LEN (D11_TXH_LEN is now 104 bytes)
++ *
++ */
++static u16
++brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw,
++		     struct sk_buff *p, struct scb *scb, uint frag,
++		     uint nfrags, uint queue, uint next_frag_len)
++{
++	struct ieee80211_hdr *h;
++	struct d11txh *txh;
++	u8 *plcp, plcp_fallback[D11_PHY_HDR_LEN];
++	int len, phylen, rts_phylen;
++	u16 mch, phyctl, xfts, mainrates;
++	u16 seq = 0, mcl = 0, status = 0, frameid = 0;
++	u32 rspec[2] = { BRCM_RATE_1M, BRCM_RATE_1M };
++	u32 rts_rspec[2] = { BRCM_RATE_1M, BRCM_RATE_1M };
++	bool use_rts = false;
++	bool use_cts = false;
++	bool use_rifs = false;
++	bool short_preamble[2] = { false, false };
++	u8 preamble_type[2] = { BRCMS_LONG_PREAMBLE, BRCMS_LONG_PREAMBLE };
++	u8 rts_preamble_type[2] = { BRCMS_LONG_PREAMBLE, BRCMS_LONG_PREAMBLE };
++	u8 *rts_plcp, rts_plcp_fallback[D11_PHY_HDR_LEN];
++	struct ieee80211_rts *rts = NULL;
++	bool qos;
++	uint ac;
++	bool hwtkmic = false;
++	u16 mimo_ctlchbw = PHY_TXC1_BW_20MHZ;
++#define ANTCFG_NONE 0xFF
++	u8 antcfg = ANTCFG_NONE;
++	u8 fbantcfg = ANTCFG_NONE;
++	uint phyctl1_stf = 0;
++	u16 durid = 0;
++	struct ieee80211_tx_rate *txrate[2];
++	int k;
++	struct ieee80211_tx_info *tx_info;
++	bool is_mcs;
++	u16 mimo_txbw;
++	u8 mimo_preamble_type;
++
++	/* locate 802.11 MAC header */
++	h = (struct ieee80211_hdr *)(p->data);
++	qos = ieee80211_is_data_qos(h->frame_control);
++
++	/* compute length of frame in bytes for use in PLCP computations */
++	len = p->len;
++	phylen = len + FCS_LEN;
++
++	/* Get tx_info */
++	tx_info = IEEE80211_SKB_CB(p);
++
++	/* add PLCP */
++	plcp = skb_push(p, D11_PHY_HDR_LEN);
++
++	/* add Broadcom tx descriptor header */
++	txh = (struct d11txh *) skb_push(p, D11_TXH_LEN);
++	memset(txh, 0, D11_TXH_LEN);
++
++	/* setup frameid */
++	if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
++		/* non-AP STA should never use BCMC queue */
++		if (queue == TX_BCMC_FIFO) {
++			wiphy_err(wlc->wiphy, "wl%d: %s: ASSERT queue == "
++				  "TX_BCMC!\n", wlc->pub->unit, __func__);
++			frameid = bcmc_fid_generate(wlc, NULL, txh);
++		} else {
++			/* Increment the counter for first fragment */
++			if (tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
++				scb->seqnum[p->priority]++;
++
++			/* extract fragment number from frame first */
++			seq = le16_to_cpu(h->seq_ctrl) & FRAGNUM_MASK;
++			seq |= (scb->seqnum[p->priority] << SEQNUM_SHIFT);
++			h->seq_ctrl = cpu_to_le16(seq);
++
++			frameid = ((seq << TXFID_SEQ_SHIFT) & TXFID_SEQ_MASK) |
++			    (queue & TXFID_QUEUE_MASK);
++		}
++	}
++	frameid |= queue & TXFID_QUEUE_MASK;
++
++	/* set the ignpmq bit for all pkts tx'd in PS mode and for beacons */
++	if (ieee80211_is_beacon(h->frame_control))
++		mcl |= TXC_IGNOREPMQ;
++
++	txrate[0] = tx_info->control.rates;
++	txrate[1] = txrate[0] + 1;
++
++	/*
++	 * if rate control algorithm didn't give us a fallback
++	 * rate, use the primary rate
++	 */
++	if (txrate[1]->idx < 0)
++		txrate[1] = txrate[0];
++
++	for (k = 0; k < hw->max_rates; k++) {
++		is_mcs = txrate[k]->flags & IEEE80211_TX_RC_MCS ? true : false;
++		if (!is_mcs) {
++			if ((txrate[k]->idx >= 0)
++			    && (txrate[k]->idx <
++				hw->wiphy->bands[tx_info->band]->n_bitrates)) {
++				rspec[k] =
++				    hw->wiphy->bands[tx_info->band]->
++				    bitrates[txrate[k]->idx].hw_value;
++				short_preamble[k] =
++				    txrate[k]->
++				    flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE ?
++				    true : false;
++			} else {
++				rspec[k] = BRCM_RATE_1M;
++			}
++		} else {
++			rspec[k] = mac80211_wlc_set_nrate(wlc, wlc->band,
++					NRATE_MCS_INUSE | txrate[k]->idx);
++		}
++
++		/*
++		 * Currently only support same setting for primay and
++		 * fallback rates. Unify flags for each rate into a
++		 * single value for the frame
++		 */
++		use_rts |=
++		    txrate[k]->
++		    flags & IEEE80211_TX_RC_USE_RTS_CTS ? true : false;
++		use_cts |=
++		    txrate[k]->
++		    flags & IEEE80211_TX_RC_USE_CTS_PROTECT ? true : false;
++
++
++		/*
++		 * (1) RATE:
++		 *   determine and validate primary rate
++		 *   and fallback rates
++		 */
++		if (!rspec_active(rspec[k])) {
++			rspec[k] = BRCM_RATE_1M;
++		} else {
++			if (!is_multicast_ether_addr(h->addr1)) {
++				/* set tx antenna config */
++				brcms_c_antsel_antcfg_get(wlc->asi, false,
++					false, 0, 0, &antcfg, &fbantcfg);
++			}
++		}
++	}
++
++	phyctl1_stf = wlc->stf->ss_opmode;
++
++	if (wlc->pub->_n_enab & SUPPORT_11N) {
++		for (k = 0; k < hw->max_rates; k++) {
++			/*
++			 * apply siso/cdd to single stream mcs's or ofdm
++			 * if rspec is auto selected
++			 */
++			if (((is_mcs_rate(rspec[k]) &&
++			      is_single_stream(rspec[k] & RSPEC_RATE_MASK)) ||
++			     is_ofdm_rate(rspec[k]))
++			    && ((rspec[k] & RSPEC_OVERRIDE_MCS_ONLY)
++				|| !(rspec[k] & RSPEC_OVERRIDE))) {
++				rspec[k] &= ~(RSPEC_STF_MASK | RSPEC_STC_MASK);
++
++				/* For SISO MCS use STBC if possible */
++				if (is_mcs_rate(rspec[k])
++				    && BRCMS_STF_SS_STBC_TX(wlc, scb)) {
++					u8 stc;
++
++					/* Nss for single stream is always 1 */
++					stc = 1;
++					rspec[k] |= (PHY_TXC1_MODE_STBC <<
++							RSPEC_STF_SHIFT) |
++						    (stc << RSPEC_STC_SHIFT);
++				} else
++					rspec[k] |=
++					    (phyctl1_stf << RSPEC_STF_SHIFT);
++			}
++
++			/*
++			 * Is the phy configured to use 40MHZ frames? If
++			 * so then pick the desired txbw
++			 */
++			if (brcms_chspec_bw(wlc->chanspec) == BRCMS_40_MHZ) {
++				/* default txbw is 20in40 SB */
++				mimo_ctlchbw = mimo_txbw =
++				   CHSPEC_SB_UPPER(wlc_phy_chanspec_get(
++								 wlc->band->pi))
++				   ? PHY_TXC1_BW_20MHZ_UP : PHY_TXC1_BW_20MHZ;
++
++				if (is_mcs_rate(rspec[k])) {
++					/* mcs 32 must be 40b/w DUP */
++					if ((rspec[k] & RSPEC_RATE_MASK)
++					    == 32) {
++						mimo_txbw =
++						    PHY_TXC1_BW_40MHZ_DUP;
++						/* use override */
++					} else if (wlc->mimo_40txbw != AUTO)
++						mimo_txbw = wlc->mimo_40txbw;
++					/* else check if dst is using 40 Mhz */
++					else if (scb->flags & SCB_IS40)
++						mimo_txbw = PHY_TXC1_BW_40MHZ;
++				} else if (is_ofdm_rate(rspec[k])) {
++					if (wlc->ofdm_40txbw != AUTO)
++						mimo_txbw = wlc->ofdm_40txbw;
++				} else if (wlc->cck_40txbw != AUTO) {
++					mimo_txbw = wlc->cck_40txbw;
++				}
++			} else {
++				/*
++				 * mcs32 is 40 b/w only.
++				 * This is possible for probe packets on
++				 * a STA during SCAN
++				 */
++				if ((rspec[k] & RSPEC_RATE_MASK) == 32)
++					/* mcs 0 */
++					rspec[k] = RSPEC_MIMORATE;
++
++				mimo_txbw = PHY_TXC1_BW_20MHZ;
++			}
++
++			/* Set channel width */
++			rspec[k] &= ~RSPEC_BW_MASK;
++			if ((k == 0) || ((k > 0) && is_mcs_rate(rspec[k])))
++				rspec[k] |= (mimo_txbw << RSPEC_BW_SHIFT);
++			else
++				rspec[k] |= (mimo_ctlchbw << RSPEC_BW_SHIFT);
++
++			/* Disable short GI, not supported yet */
++			rspec[k] &= ~RSPEC_SHORT_GI;
++
++			mimo_preamble_type = BRCMS_MM_PREAMBLE;
++			if (txrate[k]->flags & IEEE80211_TX_RC_GREEN_FIELD)
++				mimo_preamble_type = BRCMS_GF_PREAMBLE;
++
++			if ((txrate[k]->flags & IEEE80211_TX_RC_MCS)
++			    && (!is_mcs_rate(rspec[k]))) {
++				wiphy_err(wlc->wiphy, "wl%d: %s: IEEE80211_TX_"
++					  "RC_MCS != is_mcs_rate(rspec)\n",
++					  wlc->pub->unit, __func__);
++			}
++
++			if (is_mcs_rate(rspec[k])) {
++				preamble_type[k] = mimo_preamble_type;
++
++				/*
++				 * if SGI is selected, then forced mm
++				 * for single stream
++				 */
++				if ((rspec[k] & RSPEC_SHORT_GI)
++				    && is_single_stream(rspec[k] &
++							RSPEC_RATE_MASK))
++					preamble_type[k] = BRCMS_MM_PREAMBLE;
++			}
++
++			/* should be better conditionalized */
++			if (!is_mcs_rate(rspec[0])
++			    && (tx_info->control.rates[0].
++				flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE))
++				preamble_type[k] = BRCMS_SHORT_PREAMBLE;
++		}
++	} else {
++		for (k = 0; k < hw->max_rates; k++) {
++			/* Set ctrlchbw as 20Mhz */
++			rspec[k] &= ~RSPEC_BW_MASK;
++			rspec[k] |= (PHY_TXC1_BW_20MHZ << RSPEC_BW_SHIFT);
++
++			/* for nphy, stf of ofdm frames must follow policies */
++			if (BRCMS_ISNPHY(wlc->band) && is_ofdm_rate(rspec[k])) {
++				rspec[k] &= ~RSPEC_STF_MASK;
++				rspec[k] |= phyctl1_stf << RSPEC_STF_SHIFT;
++			}
++		}
++	}
++
++	/* Reset these for use with AMPDU's */
++	txrate[0]->count = 0;
++	txrate[1]->count = 0;
++
++	/* (2) PROTECTION, may change rspec */
++	if ((ieee80211_is_data(h->frame_control) ||
++	    ieee80211_is_mgmt(h->frame_control)) &&
++	    (phylen > wlc->RTSThresh) && !is_multicast_ether_addr(h->addr1))
++		use_rts = true;
++
++	/* (3) PLCP: determine PLCP header and MAC duration,
++	 * fill struct d11txh */
++	brcms_c_compute_plcp(wlc, rspec[0], phylen, plcp);
++	brcms_c_compute_plcp(wlc, rspec[1], phylen, plcp_fallback);
++	memcpy(&txh->FragPLCPFallback,
++	       plcp_fallback, sizeof(txh->FragPLCPFallback));
++
++	/* Length field now put in CCK FBR CRC field */
++	if (is_cck_rate(rspec[1])) {
++		txh->FragPLCPFallback[4] = phylen & 0xff;
++		txh->FragPLCPFallback[5] = (phylen & 0xff00) >> 8;
++	}
++
++	/* MIMO-RATE: need validation ?? */
++	mainrates = is_ofdm_rate(rspec[0]) ?
++			D11A_PHY_HDR_GRATE((struct ofdm_phy_hdr *) plcp) :
++			plcp[0];
++
++	/* DUR field for main rate */
++	if (!ieee80211_is_pspoll(h->frame_control) &&
++	    !is_multicast_ether_addr(h->addr1) && !use_rifs) {
++		durid =
++		    brcms_c_compute_frame_dur(wlc, rspec[0], preamble_type[0],
++					  next_frag_len);
++		h->duration_id = cpu_to_le16(durid);
++	} else if (use_rifs) {
++		/* NAV protect to end of next max packet size */
++		durid =
++		    (u16) brcms_c_calc_frame_time(wlc, rspec[0],
++						 preamble_type[0],
++						 DOT11_MAX_FRAG_LEN);
++		durid += RIFS_11N_TIME;
++		h->duration_id = cpu_to_le16(durid);
++	}
++
++	/* DUR field for fallback rate */
++	if (ieee80211_is_pspoll(h->frame_control))
++		txh->FragDurFallback = h->duration_id;
++	else if (is_multicast_ether_addr(h->addr1) || use_rifs)
++		txh->FragDurFallback = 0;
++	else {
++		durid = brcms_c_compute_frame_dur(wlc, rspec[1],
++					      preamble_type[1], next_frag_len);
++		txh->FragDurFallback = cpu_to_le16(durid);
++	}
++
++	/* (4) MAC-HDR: MacTxControlLow */
++	if (frag == 0)
++		mcl |= TXC_STARTMSDU;
++
++	if (!is_multicast_ether_addr(h->addr1))
++		mcl |= TXC_IMMEDACK;
++
++	if (wlc->band->bandtype == BRCM_BAND_5G)
++		mcl |= TXC_FREQBAND_5G;
++
++	if (CHSPEC_IS40(wlc_phy_chanspec_get(wlc->band->pi)))
++		mcl |= TXC_BW_40;
++
++	/* set AMIC bit if using hardware TKIP MIC */
++	if (hwtkmic)
++		mcl |= TXC_AMIC;
++
++	txh->MacTxControlLow = cpu_to_le16(mcl);
++
++	/* MacTxControlHigh */
++	mch = 0;
++
++	/* Set fallback rate preamble type */
++	if ((preamble_type[1] == BRCMS_SHORT_PREAMBLE) ||
++	    (preamble_type[1] == BRCMS_GF_PREAMBLE)) {
++		if (rspec2rate(rspec[1]) != BRCM_RATE_1M)
++			mch |= TXC_PREAMBLE_DATA_FB_SHORT;
++	}
++
++	/* MacFrameControl */
++	memcpy(&txh->MacFrameControl, &h->frame_control, sizeof(u16));
++	txh->TxFesTimeNormal = cpu_to_le16(0);
++
++	txh->TxFesTimeFallback = cpu_to_le16(0);
++
++	/* TxFrameRA */
++	memcpy(&txh->TxFrameRA, &h->addr1, ETH_ALEN);
++
++	/* TxFrameID */
++	txh->TxFrameID = cpu_to_le16(frameid);
++
++	/*
++	 * TxStatus, Note the case of recreating the first frag of a suppressed
++	 * frame then we may need to reset the retry cnt's via the status reg
++	 */
++	txh->TxStatus = cpu_to_le16(status);
++
++	/*
++	 * extra fields for ucode AMPDU aggregation, the new fields are added to
++	 * the END of previous structure so that it's compatible in driver.
++	 */
++	txh->MaxNMpdus = cpu_to_le16(0);
++	txh->MaxABytes_MRT = cpu_to_le16(0);
++	txh->MaxABytes_FBR = cpu_to_le16(0);
++	txh->MinMBytes = cpu_to_le16(0);
++
++	/* (5) RTS/CTS: determine RTS/CTS PLCP header and MAC duration,
++	 * furnish struct d11txh */
++	/* RTS PLCP header and RTS frame */
++	if (use_rts || use_cts) {
++		if (use_rts && use_cts)
++			use_cts = false;
++
++		for (k = 0; k < 2; k++) {
++			rts_rspec[k] = brcms_c_rspec_to_rts_rspec(wlc, rspec[k],
++							      false,
++							      mimo_ctlchbw);
++		}
++
++		if (!is_ofdm_rate(rts_rspec[0]) &&
++		    !((rspec2rate(rts_rspec[0]) == BRCM_RATE_1M) ||
++		      (wlc->PLCPHdr_override == BRCMS_PLCP_LONG))) {
++			rts_preamble_type[0] = BRCMS_SHORT_PREAMBLE;
++			mch |= TXC_PREAMBLE_RTS_MAIN_SHORT;
++		}
++
++		if (!is_ofdm_rate(rts_rspec[1]) &&
++		    !((rspec2rate(rts_rspec[1]) == BRCM_RATE_1M) ||
++		      (wlc->PLCPHdr_override == BRCMS_PLCP_LONG))) {
++			rts_preamble_type[1] = BRCMS_SHORT_PREAMBLE;
++			mch |= TXC_PREAMBLE_RTS_FB_SHORT;
++		}
++
++		/* RTS/CTS additions to MacTxControlLow */
++		if (use_cts) {
++			txh->MacTxControlLow |= cpu_to_le16(TXC_SENDCTS);
++		} else {
++			txh->MacTxControlLow |= cpu_to_le16(TXC_SENDRTS);
++			txh->MacTxControlLow |= cpu_to_le16(TXC_LONGFRAME);
++		}
++
++		/* RTS PLCP header */
++		rts_plcp = txh->RTSPhyHeader;
++		if (use_cts)
++			rts_phylen = DOT11_CTS_LEN + FCS_LEN;
++		else
++			rts_phylen = DOT11_RTS_LEN + FCS_LEN;
++
++		brcms_c_compute_plcp(wlc, rts_rspec[0], rts_phylen, rts_plcp);
++
++		/* fallback rate version of RTS PLCP header */
++		brcms_c_compute_plcp(wlc, rts_rspec[1], rts_phylen,
++				 rts_plcp_fallback);
++		memcpy(&txh->RTSPLCPFallback, rts_plcp_fallback,
++		       sizeof(txh->RTSPLCPFallback));
++
++		/* RTS frame fields... */
++		rts = (struct ieee80211_rts *)&txh->rts_frame;
++
++		durid = brcms_c_compute_rtscts_dur(wlc, use_cts, rts_rspec[0],
++					       rspec[0], rts_preamble_type[0],
++					       preamble_type[0], phylen, false);
++		rts->duration = cpu_to_le16(durid);
++		/* fallback rate version of RTS DUR field */
++		durid = brcms_c_compute_rtscts_dur(wlc, use_cts,
++					       rts_rspec[1], rspec[1],
++					       rts_preamble_type[1],
++					       preamble_type[1], phylen, false);
++		txh->RTSDurFallback = cpu_to_le16(durid);
++
++		if (use_cts) {
++			rts->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL |
++							 IEEE80211_STYPE_CTS);
++
++			memcpy(&rts->ra, &h->addr2, ETH_ALEN);
++		} else {
++			rts->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL |
++							 IEEE80211_STYPE_RTS);
++
++			memcpy(&rts->ra, &h->addr1, 2 * ETH_ALEN);
++		}
++
++		/* mainrate
++		 *    low 8 bits: main frag rate/mcs,
++		 *    high 8 bits: rts/cts rate/mcs
++		 */
++		mainrates |= (is_ofdm_rate(rts_rspec[0]) ?
++				D11A_PHY_HDR_GRATE(
++					(struct ofdm_phy_hdr *) rts_plcp) :
++				rts_plcp[0]) << 8;
++	} else {
++		memset((char *)txh->RTSPhyHeader, 0, D11_PHY_HDR_LEN);
++		memset((char *)&txh->rts_frame, 0,
++			sizeof(struct ieee80211_rts));
++		memset((char *)txh->RTSPLCPFallback, 0,
++		      sizeof(txh->RTSPLCPFallback));
++		txh->RTSDurFallback = 0;
++	}
++
++#ifdef SUPPORT_40MHZ
++	/* add null delimiter count */
++	if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && is_mcs_rate(rspec))
++		txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM] =
++		   brcm_c_ampdu_null_delim_cnt(wlc->ampdu, scb, rspec, phylen);
++
++#endif
++
++	/*
++	 * Now that RTS/RTS FB preamble types are updated, write
++	 * the final value
++	 */
++	txh->MacTxControlHigh = cpu_to_le16(mch);
++
++	/*
++	 * MainRates (both the rts and frag plcp rates have
++	 * been calculated now)
++	 */
++	txh->MainRates = cpu_to_le16(mainrates);
++
++	/* XtraFrameTypes */
++	xfts = frametype(rspec[1], wlc->mimoft);
++	xfts |= (frametype(rts_rspec[0], wlc->mimoft) << XFTS_RTS_FT_SHIFT);
++	xfts |= (frametype(rts_rspec[1], wlc->mimoft) << XFTS_FBRRTS_FT_SHIFT);
++	xfts |= CHSPEC_CHANNEL(wlc_phy_chanspec_get(wlc->band->pi)) <<
++							     XFTS_CHANNEL_SHIFT;
++	txh->XtraFrameTypes = cpu_to_le16(xfts);
++
++	/* PhyTxControlWord */
++	phyctl = frametype(rspec[0], wlc->mimoft);
++	if ((preamble_type[0] == BRCMS_SHORT_PREAMBLE) ||
++	    (preamble_type[0] == BRCMS_GF_PREAMBLE)) {
++		if (rspec2rate(rspec[0]) != BRCM_RATE_1M)
++			phyctl |= PHY_TXC_SHORT_HDR;
++	}
++
++	/* phytxant is properly bit shifted */
++	phyctl |= brcms_c_stf_d11hdrs_phyctl_txant(wlc, rspec[0]);
++	txh->PhyTxControlWord = cpu_to_le16(phyctl);
++
++	/* PhyTxControlWord_1 */
++	if (BRCMS_PHY_11N_CAP(wlc->band)) {
++		u16 phyctl1 = 0;
++
++		phyctl1 = brcms_c_phytxctl1_calc(wlc, rspec[0]);
++		txh->PhyTxControlWord_1 = cpu_to_le16(phyctl1);
++		phyctl1 = brcms_c_phytxctl1_calc(wlc, rspec[1]);
++		txh->PhyTxControlWord_1_Fbr = cpu_to_le16(phyctl1);
++
++		if (use_rts || use_cts) {
++			phyctl1 = brcms_c_phytxctl1_calc(wlc, rts_rspec[0]);
++			txh->PhyTxControlWord_1_Rts = cpu_to_le16(phyctl1);
++			phyctl1 = brcms_c_phytxctl1_calc(wlc, rts_rspec[1]);
++			txh->PhyTxControlWord_1_FbrRts = cpu_to_le16(phyctl1);
++		}
++
++		/*
++		 * For mcs frames, if mixedmode(overloaded with long preamble)
++		 * is going to be set, fill in non-zero MModeLen and/or
++		 * MModeFbrLen it will be unnecessary if they are separated
++		 */
++		if (is_mcs_rate(rspec[0]) &&
++		    (preamble_type[0] == BRCMS_MM_PREAMBLE)) {
++			u16 mmodelen =
++			    brcms_c_calc_lsig_len(wlc, rspec[0], phylen);
++			txh->MModeLen = cpu_to_le16(mmodelen);
++		}
++
++		if (is_mcs_rate(rspec[1]) &&
++		    (preamble_type[1] == BRCMS_MM_PREAMBLE)) {
++			u16 mmodefbrlen =
++			    brcms_c_calc_lsig_len(wlc, rspec[1], phylen);
++			txh->MModeFbrLen = cpu_to_le16(mmodefbrlen);
++		}
++	}
++
++	ac = skb_get_queue_mapping(p);
++	if ((scb->flags & SCB_WMECAP) && qos && wlc->edcf_txop[ac]) {
++		uint frag_dur, dur, dur_fallback;
++
++		/* WME: Update TXOP threshold */
++		if (!(tx_info->flags & IEEE80211_TX_CTL_AMPDU) && frag == 0) {
++			frag_dur =
++			    brcms_c_calc_frame_time(wlc, rspec[0],
++					preamble_type[0], phylen);
++
++			if (rts) {
++				/* 1 RTS or CTS-to-self frame */
++				dur =
++				    brcms_c_calc_cts_time(wlc, rts_rspec[0],
++						      rts_preamble_type[0]);
++				dur_fallback =
++				    brcms_c_calc_cts_time(wlc, rts_rspec[1],
++						      rts_preamble_type[1]);
++				/* (SIFS + CTS) + SIFS + frame + SIFS + ACK */
++				dur += le16_to_cpu(rts->duration);
++				dur_fallback +=
++					le16_to_cpu(txh->RTSDurFallback);
++			} else if (use_rifs) {
++				dur = frag_dur;
++				dur_fallback = 0;
++			} else {
++				/* frame + SIFS + ACK */
++				dur = frag_dur;
++				dur +=
++				    brcms_c_compute_frame_dur(wlc, rspec[0],
++							  preamble_type[0], 0);
++
++				dur_fallback =
++				    brcms_c_calc_frame_time(wlc, rspec[1],
++							preamble_type[1],
++							phylen);
++				dur_fallback +=
++				    brcms_c_compute_frame_dur(wlc, rspec[1],
++							  preamble_type[1], 0);
++			}
++			/* NEED to set TxFesTimeNormal (hard) */
++			txh->TxFesTimeNormal = cpu_to_le16((u16) dur);
++			/*
++			 * NEED to set fallback rate version of
++			 * TxFesTimeNormal (hard)
++			 */
++			txh->TxFesTimeFallback =
++				cpu_to_le16((u16) dur_fallback);
++
++			/*
++			 * update txop byte threshold (txop minus intraframe
++			 * overhead)
++			 */
++			if (wlc->edcf_txop[ac] >= (dur - frag_dur)) {
++				uint newfragthresh;
++
++				newfragthresh =
++				    brcms_c_calc_frame_len(wlc,
++					rspec[0], preamble_type[0],
++					(wlc->edcf_txop[ac] -
++						(dur - frag_dur)));
++				/* range bound the fragthreshold */
++				if (newfragthresh < DOT11_MIN_FRAG_LEN)
++					newfragthresh =
++					    DOT11_MIN_FRAG_LEN;
++				else if (newfragthresh >
++					 wlc->usr_fragthresh)
++					newfragthresh =
++					    wlc->usr_fragthresh;
++				/* update the fragthresh and do txc update */
++				if (wlc->fragthresh[queue] !=
++				    (u16) newfragthresh)
++					wlc->fragthresh[queue] =
++					    (u16) newfragthresh;
++			} else {
++				wiphy_err(wlc->wiphy, "wl%d: %s txop invalid "
++					  "for rate %d\n",
++					  wlc->pub->unit, fifo_names[queue],
++					  rspec2rate(rspec[0]));
++			}
++
++			if (dur > wlc->edcf_txop[ac])
++				wiphy_err(wlc->wiphy, "wl%d: %s: %s txop "
++					  "exceeded phylen %d/%d dur %d/%d\n",
++					  wlc->pub->unit, __func__,
++					  fifo_names[queue],
++					  phylen, wlc->fragthresh[queue],
++					  dur, wlc->edcf_txop[ac]);
++		}
++	}
++
++	return 0;
++}
++
++void brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc, struct sk_buff *sdu,
++			      struct ieee80211_hw *hw)
++{
++	u8 prio;
++	uint fifo;
++	struct scb *scb = &wlc->pri_scb;
++	struct ieee80211_hdr *d11_header = (struct ieee80211_hdr *)(sdu->data);
++
++	/*
++	 * 802.11 standard requires management traffic
++	 * to go at highest priority
++	 */
++	prio = ieee80211_is_data(d11_header->frame_control) ? sdu->priority :
++		MAXPRIO;
++	fifo = prio2fifo[prio];
++	if (brcms_c_d11hdrs_mac80211(wlc, hw, sdu, scb, 0, 1, fifo, 0))
++		return;
++	brcms_c_txq_enq(wlc, scb, sdu, BRCMS_PRIO_TO_PREC(prio));
++	brcms_c_send_q(wlc);
++}
++
++void brcms_c_send_q(struct brcms_c_info *wlc)
++{
++	struct sk_buff *pkt[DOT11_MAXNUMFRAGS];
++	int prec;
++	u16 prec_map;
++	int err = 0, i, count;
++	uint fifo;
++	struct brcms_txq_info *qi = wlc->pkt_queue;
++	struct pktq *q = &qi->q;
++	struct ieee80211_tx_info *tx_info;
++
++	prec_map = wlc->tx_prec_map;
++
++	/* Send all the enq'd pkts that we can.
++	 * Dequeue packets with precedence with empty HW fifo only
++	 */
++	while (prec_map && (pkt[0] = brcmu_pktq_mdeq(q, prec_map, &prec))) {
++		tx_info = IEEE80211_SKB_CB(pkt[0]);
++		if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
++			err = brcms_c_sendampdu(wlc->ampdu, qi, pkt, prec);
++		} else {
++			count = 1;
++			err = brcms_c_prep_pdu(wlc, pkt[0], &fifo);
++			if (!err) {
++				for (i = 0; i < count; i++)
++					brcms_c_txfifo(wlc, fifo, pkt[i], true,
++						       1);
++			}
++		}
++
++		if (err == -EBUSY) {
++			brcmu_pktq_penq_head(q, prec, pkt[0]);
++			/*
++			 * If send failed due to any other reason than a
++			 * change in HW FIFO condition, quit. Otherwise,
++			 * read the new prec_map!
++			 */
++			if (prec_map == wlc->tx_prec_map)
++				break;
++			prec_map = wlc->tx_prec_map;
++		}
++	}
++}
++
++void
++brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo, struct sk_buff *p,
++	       bool commit, s8 txpktpend)
++{
++	u16 frameid = INVALIDFID;
++	struct d11txh *txh;
++
++	txh = (struct d11txh *) (p->data);
++
++	/* When a BC/MC frame is being committed to the BCMC fifo
++	 * via DMA (NOT PIO), update ucode or BSS info as appropriate.
++	 */
++	if (fifo == TX_BCMC_FIFO)
++		frameid = le16_to_cpu(txh->TxFrameID);
++
++	/*
++	 * Bump up pending count for if not using rpc. If rpc is
++	 * used, this will be handled in brcms_b_txfifo()
++	 */
++	if (commit) {
++		wlc->core->txpktpend[fifo] += txpktpend;
++		BCMMSG(wlc->wiphy, "pktpend inc %d to %d\n",
++			 txpktpend, wlc->core->txpktpend[fifo]);
++	}
++
++	/* Commit BCMC sequence number in the SHM frame ID location */
++	if (frameid != INVALIDFID) {
++		/*
++		 * To inform the ucode of the last mcast frame posted
++		 * so that it can clear moredata bit
++		 */
++		brcms_b_write_shm(wlc->hw, M_BCMC_FID, frameid);
++	}
++
++	if (dma_txfast(wlc->hw->di[fifo], p, commit) < 0)
++		wiphy_err(wlc->wiphy, "txfifo: fatal, toss frames !!!\n");
++}
++
++u32
++brcms_c_rspec_to_rts_rspec(struct brcms_c_info *wlc, u32 rspec,
++			   bool use_rspec, u16 mimo_ctlchbw)
++{
++	u32 rts_rspec = 0;
++
++	if (use_rspec)
++		/* use frame rate as rts rate */
++		rts_rspec = rspec;
++	else if (wlc->band->gmode && wlc->protection->_g && !is_cck_rate(rspec))
++		/* Use 11Mbps as the g protection RTS target rate and fallback.
++		 * Use the brcms_basic_rate() lookup to find the best basic rate
++		 * under the target in case 11 Mbps is not Basic.
++		 * 6 and 9 Mbps are not usually selected by rate selection, but
++		 * even if the OFDM rate we are protecting is 6 or 9 Mbps, 11
++		 * is more robust.
++		 */
++		rts_rspec = brcms_basic_rate(wlc, BRCM_RATE_11M);
++	else
++		/* calculate RTS rate and fallback rate based on the frame rate
++		 * RTS must be sent at a basic rate since it is a
++		 * control frame, sec 9.6 of 802.11 spec
++		 */
++		rts_rspec = brcms_basic_rate(wlc, rspec);
++
++	if (BRCMS_PHY_11N_CAP(wlc->band)) {
++		/* set rts txbw to correct side band */
++		rts_rspec &= ~RSPEC_BW_MASK;
++
++		/*
++		 * if rspec/rspec_fallback is 40MHz, then send RTS on both
++		 * 20MHz channel (DUP), otherwise send RTS on control channel
++		 */
++		if (rspec_is40mhz(rspec) && !is_cck_rate(rts_rspec))
++			rts_rspec |= (PHY_TXC1_BW_40MHZ_DUP << RSPEC_BW_SHIFT);
++		else
++			rts_rspec |= (mimo_ctlchbw << RSPEC_BW_SHIFT);
++
++		/* pick siso/cdd as default for ofdm */
++		if (is_ofdm_rate(rts_rspec)) {
++			rts_rspec &= ~RSPEC_STF_MASK;
++			rts_rspec |= (wlc->stf->ss_opmode << RSPEC_STF_SHIFT);
++		}
++	}
++	return rts_rspec;
++}
++
++void
++brcms_c_txfifo_complete(struct brcms_c_info *wlc, uint fifo, s8 txpktpend)
++{
++	wlc->core->txpktpend[fifo] -= txpktpend;
++	BCMMSG(wlc->wiphy, "pktpend dec %d to %d\n", txpktpend,
++	       wlc->core->txpktpend[fifo]);
++
++	/* There is more room; mark precedences related to this FIFO sendable */
++	wlc->tx_prec_map |= wlc->fifo2prec_map[fifo];
++
++	/* figure out which bsscfg is being worked on... */
++}
++
++/* Update beacon listen interval in shared memory */
++static void brcms_c_bcn_li_upd(struct brcms_c_info *wlc)
++{
++	/* wake up every DTIM is the default */
++	if (wlc->bcn_li_dtim == 1)
++		brcms_b_write_shm(wlc->hw, M_BCN_LI, 0);
++	else
++		brcms_b_write_shm(wlc->hw, M_BCN_LI,
++			      (wlc->bcn_li_dtim << 8) | wlc->bcn_li_bcn);
++}
++
++static void
++brcms_b_read_tsf(struct brcms_hardware *wlc_hw, u32 *tsf_l_ptr,
++		  u32 *tsf_h_ptr)
++{
++	struct bcma_device *core = wlc_hw->d11core;
++
++	/* read the tsf timer low, then high to get an atomic read */
++	*tsf_l_ptr = bcma_read32(core, D11REGOFFS(tsf_timerlow));
++	*tsf_h_ptr = bcma_read32(core, D11REGOFFS(tsf_timerhigh));
++}
++
++/*
++ * recover 64bit TSF value from the 16bit TSF value in the rx header
++ * given the assumption that the TSF passed in header is within 65ms
++ * of the current tsf.
++ *
++ * 6       5       4       4       3       2       1
++ * 3.......6.......8.......0.......2.......4.......6.......8......0
++ * |<---------- tsf_h ----------->||<--- tsf_l -->||<-RxTSFTime ->|
++ *
++ * The RxTSFTime are the lowest 16 bits and provided by the ucode. The
++ * tsf_l is filled in by brcms_b_recv, which is done earlier in the
++ * receive call sequence after rx interrupt. Only the higher 16 bits
++ * are used. Finally, the tsf_h is read from the tsf register.
++ */
++static u64 brcms_c_recover_tsf64(struct brcms_c_info *wlc,
++				 struct d11rxhdr *rxh)
++{
++	u32 tsf_h, tsf_l;
++	u16 rx_tsf_0_15, rx_tsf_16_31;
++
++	brcms_b_read_tsf(wlc->hw, &tsf_l, &tsf_h);
++
++	rx_tsf_16_31 = (u16)(tsf_l >> 16);
++	rx_tsf_0_15 = rxh->RxTSFTime;
++
++	/*
++	 * a greater tsf time indicates the low 16 bits of
++	 * tsf_l wrapped, so decrement the high 16 bits.
++	 */
++	if ((u16)tsf_l < rx_tsf_0_15) {
++		rx_tsf_16_31 -= 1;
++		if (rx_tsf_16_31 == 0xffff)
++			tsf_h -= 1;
++	}
++
++	return ((u64)tsf_h << 32) | (((u32)rx_tsf_16_31 << 16) + rx_tsf_0_15);
++}
++
++static void
++prep_mac80211_status(struct brcms_c_info *wlc, struct d11rxhdr *rxh,
++		     struct sk_buff *p,
++		     struct ieee80211_rx_status *rx_status)
++{
++	int preamble;
++	int channel;
++	u32 rspec;
++	unsigned char *plcp;
++
++	/* fill in TSF and flag its presence */
++	rx_status->mactime = brcms_c_recover_tsf64(wlc, rxh);
++	rx_status->flag |= RX_FLAG_MACTIME_MPDU;
++
++	channel = BRCMS_CHAN_CHANNEL(rxh->RxChan);
++
++	if (channel > 14) {
++		rx_status->band = IEEE80211_BAND_5GHZ;
++		rx_status->freq = ieee80211_ofdm_chan_to_freq(
++					WF_CHAN_FACTOR_5_G/2, channel);
++
++	} else {
++		rx_status->band = IEEE80211_BAND_2GHZ;
++		rx_status->freq = ieee80211_dsss_chan_to_freq(channel);
++	}
++
++	rx_status->signal = wlc_phy_rssi_compute(wlc->hw->band->pi, rxh);
++
++	/* noise */
++	/* qual */
++	rx_status->antenna =
++		(rxh->PhyRxStatus_0 & PRXS0_RXANT_UPSUBBAND) ? 1 : 0;
++
++	plcp = p->data;
++
++	rspec = brcms_c_compute_rspec(rxh, plcp);
++	if (is_mcs_rate(rspec)) {
++		rx_status->rate_idx = rspec & RSPEC_RATE_MASK;
++		rx_status->flag |= RX_FLAG_HT;
++		if (rspec_is40mhz(rspec))
++			rx_status->flag |= RX_FLAG_40MHZ;
++	} else {
++		switch (rspec2rate(rspec)) {
++		case BRCM_RATE_1M:
++			rx_status->rate_idx = 0;
++			break;
++		case BRCM_RATE_2M:
++			rx_status->rate_idx = 1;
++			break;
++		case BRCM_RATE_5M5:
++			rx_status->rate_idx = 2;
++			break;
++		case BRCM_RATE_11M:
++			rx_status->rate_idx = 3;
++			break;
++		case BRCM_RATE_6M:
++			rx_status->rate_idx = 4;
++			break;
++		case BRCM_RATE_9M:
++			rx_status->rate_idx = 5;
++			break;
++		case BRCM_RATE_12M:
++			rx_status->rate_idx = 6;
++			break;
++		case BRCM_RATE_18M:
++			rx_status->rate_idx = 7;
++			break;
++		case BRCM_RATE_24M:
++			rx_status->rate_idx = 8;
++			break;
++		case BRCM_RATE_36M:
++			rx_status->rate_idx = 9;
++			break;
++		case BRCM_RATE_48M:
++			rx_status->rate_idx = 10;
++			break;
++		case BRCM_RATE_54M:
++			rx_status->rate_idx = 11;
++			break;
++		default:
++			wiphy_err(wlc->wiphy, "%s: Unknown rate\n", __func__);
++		}
++
++		/*
++		 * For 5GHz, we should decrease the index as it is
++		 * a subset of the 2.4G rates. See bitrates field
++		 * of brcms_band_5GHz_nphy (in mac80211_if.c).
++		 */
++		if (rx_status->band == IEEE80211_BAND_5GHZ)
++			rx_status->rate_idx -= BRCMS_LEGACY_5G_RATE_OFFSET;
++
++		/* Determine short preamble and rate_idx */
++		preamble = 0;
++		if (is_cck_rate(rspec)) {
++			if (rxh->PhyRxStatus_0 & PRXS0_SHORTH)
++				rx_status->flag |= RX_FLAG_SHORTPRE;
++		} else if (is_ofdm_rate(rspec)) {
++			rx_status->flag |= RX_FLAG_SHORTPRE;
++		} else {
++			wiphy_err(wlc->wiphy, "%s: Unknown modulation\n",
++				  __func__);
++		}
++	}
++
++	if (plcp3_issgi(plcp[3]))
++		rx_status->flag |= RX_FLAG_SHORT_GI;
++
++	if (rxh->RxStatus1 & RXS_DECERR) {
++		rx_status->flag |= RX_FLAG_FAILED_PLCP_CRC;
++		wiphy_err(wlc->wiphy, "%s:  RX_FLAG_FAILED_PLCP_CRC\n",
++			  __func__);
++	}
++	if (rxh->RxStatus1 & RXS_FCSERR) {
++		rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
++		wiphy_err(wlc->wiphy, "%s:  RX_FLAG_FAILED_FCS_CRC\n",
++			  __func__);
++	}
++}
++
++static void
++brcms_c_recvctl(struct brcms_c_info *wlc, struct d11rxhdr *rxh,
++		struct sk_buff *p)
++{
++	int len_mpdu;
++	struct ieee80211_rx_status rx_status;
++	struct ieee80211_hdr *hdr;
++
++	memset(&rx_status, 0, sizeof(rx_status));
++	prep_mac80211_status(wlc, rxh, p, &rx_status);
++
++	/* mac header+body length, exclude CRC and plcp header */
++	len_mpdu = p->len - D11_PHY_HDR_LEN - FCS_LEN;
++	skb_pull(p, D11_PHY_HDR_LEN);
++	__skb_trim(p, len_mpdu);
++
++	/* unmute transmit */
++	if (wlc->hw->suspended_fifos) {
++		hdr = (struct ieee80211_hdr *)p->data;
++		if (ieee80211_is_beacon(hdr->frame_control))
++			brcms_b_mute(wlc->hw, false);
++	}
++
++	memcpy(IEEE80211_SKB_RXCB(p), &rx_status, sizeof(rx_status));
++	ieee80211_rx_irqsafe(wlc->pub->ieee_hw, p);
++}
++
++/* calculate frame duration for Mixed-mode L-SIG spoofing, return
++ * number of bytes goes in the length field
++ *
++ * Formula given by HT PHY Spec v 1.13
++ *   len = 3(nsyms + nstream + 3) - 3
++ */
++u16
++brcms_c_calc_lsig_len(struct brcms_c_info *wlc, u32 ratespec,
++		      uint mac_len)
++{
++	uint nsyms, len = 0, kNdps;
++
++	BCMMSG(wlc->wiphy, "wl%d: rate %d, len%d\n",
++		 wlc->pub->unit, rspec2rate(ratespec), mac_len);
++
++	if (is_mcs_rate(ratespec)) {
++		uint mcs = ratespec & RSPEC_RATE_MASK;
++		int tot_streams = (mcs_2_txstreams(mcs) + 1) +
++				  rspec_stc(ratespec);
++
++		/*
++		 * the payload duration calculation matches that
++		 * of regular ofdm
++		 */
++		/* 1000Ndbps = kbps * 4 */
++		kNdps = mcs_2_rate(mcs, rspec_is40mhz(ratespec),
++				   rspec_issgi(ratespec)) * 4;
++
++		if (rspec_stc(ratespec) == 0)
++			nsyms =
++			    CEIL((APHY_SERVICE_NBITS + 8 * mac_len +
++				  APHY_TAIL_NBITS) * 1000, kNdps);
++		else
++			/* STBC needs to have even number of symbols */
++			nsyms =
++			    2 *
++			    CEIL((APHY_SERVICE_NBITS + 8 * mac_len +
++				  APHY_TAIL_NBITS) * 1000, 2 * kNdps);
++
++		/* (+3) account for HT-SIG(2) and HT-STF(1) */
++		nsyms += (tot_streams + 3);
++		/*
++		 * 3 bytes/symbol @ legacy 6Mbps rate
++		 * (-3) excluding service bits and tail bits
++		 */
++		len = (3 * nsyms) - 3;
++	}
++
++	return (u16) len;
++}
++
++static void
++brcms_c_mod_prb_rsp_rate_table(struct brcms_c_info *wlc, uint frame_len)
++{
++	const struct brcms_c_rateset *rs_dflt;
++	struct brcms_c_rateset rs;
++	u8 rate;
++	u16 entry_ptr;
++	u8 plcp[D11_PHY_HDR_LEN];
++	u16 dur, sifs;
++	uint i;
++
++	sifs = get_sifs(wlc->band);
++
++	rs_dflt = brcms_c_rateset_get_hwrs(wlc);
++
++	brcms_c_rateset_copy(rs_dflt, &rs);
++	brcms_c_rateset_mcs_upd(&rs, wlc->stf->txstreams);
++
++	/*
++	 * walk the phy rate table and update MAC core SHM
++	 * basic rate table entries
++	 */
++	for (i = 0; i < rs.count; i++) {
++		rate = rs.rates[i] & BRCMS_RATE_MASK;
++
++		entry_ptr = brcms_b_rate_shm_offset(wlc->hw, rate);
++
++		/* Calculate the Probe Response PLCP for the given rate */
++		brcms_c_compute_plcp(wlc, rate, frame_len, plcp);
++
++		/*
++		 * Calculate the duration of the Probe Response
++		 * frame plus SIFS for the MAC
++		 */
++		dur = (u16) brcms_c_calc_frame_time(wlc, rate,
++						BRCMS_LONG_PREAMBLE, frame_len);
++		dur += sifs;
++
++		/* Update the SHM Rate Table entry Probe Response values */
++		brcms_b_write_shm(wlc->hw, entry_ptr + M_RT_PRS_PLCP_POS,
++			      (u16) (plcp[0] + (plcp[1] << 8)));
++		brcms_b_write_shm(wlc->hw, entry_ptr + M_RT_PRS_PLCP_POS + 2,
++			      (u16) (plcp[2] + (plcp[3] << 8)));
++		brcms_b_write_shm(wlc->hw, entry_ptr + M_RT_PRS_DUR_POS, dur);
++	}
++}
++
++/*	Max buffering needed for beacon template/prb resp template is 142 bytes.
++ *
++ *	PLCP header is 6 bytes.
++ *	802.11 A3 header is 24 bytes.
++ *	Max beacon frame body template length is 112 bytes.
++ *	Max probe resp frame body template length is 110 bytes.
++ *
++ *      *len on input contains the max length of the packet available.
++ *
++ *	The *len value is set to the number of bytes in buf used, and starts
++ *	with the PLCP and included up to, but not including, the 4 byte FCS.
++ */
++static void
++brcms_c_bcn_prb_template(struct brcms_c_info *wlc, u16 type,
++			 u32 bcn_rspec,
++			 struct brcms_bss_cfg *cfg, u16 *buf, int *len)
++{
++	static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255};
++	struct cck_phy_hdr *plcp;
++	struct ieee80211_mgmt *h;
++	int hdr_len, body_len;
++
++	hdr_len = D11_PHY_HDR_LEN + DOT11_MAC_HDR_LEN;
++
++	/* calc buffer size provided for frame body */
++	body_len = *len - hdr_len;
++	/* return actual size */
++	*len = hdr_len + body_len;
++
++	/* format PHY and MAC headers */
++	memset((char *)buf, 0, hdr_len);
++
++	plcp = (struct cck_phy_hdr *) buf;
++
++	/*
++	 * PLCP for Probe Response frames are filled in from
++	 * core's rate table
++	 */
++	if (type == IEEE80211_STYPE_BEACON)
++		/* fill in PLCP */
++		brcms_c_compute_plcp(wlc, bcn_rspec,
++				 (DOT11_MAC_HDR_LEN + body_len + FCS_LEN),
++				 (u8 *) plcp);
++
++	/* "Regular" and 16 MBSS but not for 4 MBSS */
++	/* Update the phytxctl for the beacon based on the rspec */
++	brcms_c_beacon_phytxctl_txant_upd(wlc, bcn_rspec);
++
++	h = (struct ieee80211_mgmt *)&plcp[1];
++
++	/* fill in 802.11 header */
++	h->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | type);
++
++	/* DUR is 0 for multicast bcn, or filled in by MAC for prb resp */
++	/* A1 filled in by MAC for prb resp, broadcast for bcn */
++	if (type == IEEE80211_STYPE_BEACON)
++		memcpy(&h->da, &ether_bcast, ETH_ALEN);
++	memcpy(&h->sa, &cfg->cur_etheraddr, ETH_ALEN);
++	memcpy(&h->bssid, &cfg->BSSID, ETH_ALEN);
++
++	/* SEQ filled in by MAC */
++}
++
++int brcms_c_get_header_len(void)
++{
++	return TXOFF;
++}
++
++/*
++ * Update all beacons for the system.
++ */
++void brcms_c_update_beacon(struct brcms_c_info *wlc)
++{
++	struct brcms_bss_cfg *bsscfg = wlc->bsscfg;
++
++	if (bsscfg->up && !bsscfg->BSS)
++		/* Clear the soft intmask */
++		wlc->defmacintmask &= ~MI_BCNTPL;
++}
++
++/* Write ssid into shared memory */
++static void
++brcms_c_shm_ssid_upd(struct brcms_c_info *wlc, struct brcms_bss_cfg *cfg)
++{
++	u8 *ssidptr = cfg->SSID;
++	u16 base = M_SSID;
++	u8 ssidbuf[IEEE80211_MAX_SSID_LEN];
++
++	/* padding the ssid with zero and copy it into shm */
++	memset(ssidbuf, 0, IEEE80211_MAX_SSID_LEN);
++	memcpy(ssidbuf, ssidptr, cfg->SSID_len);
++
++	brcms_c_copyto_shm(wlc, base, ssidbuf, IEEE80211_MAX_SSID_LEN);
++	brcms_b_write_shm(wlc->hw, M_SSIDLEN, (u16) cfg->SSID_len);
++}
++
++static void
++brcms_c_bss_update_probe_resp(struct brcms_c_info *wlc,
++			      struct brcms_bss_cfg *cfg,
++			      bool suspend)
++{
++	u16 prb_resp[BCN_TMPL_LEN / 2];
++	int len = BCN_TMPL_LEN;
++
++	/*
++	 * write the probe response to hardware, or save in
++	 * the config structure
++	 */
++
++	/* create the probe response template */
++	brcms_c_bcn_prb_template(wlc, IEEE80211_STYPE_PROBE_RESP, 0,
++				 cfg, prb_resp, &len);
++
++	if (suspend)
++		brcms_c_suspend_mac_and_wait(wlc);
++
++	/* write the probe response into the template region */
++	brcms_b_write_template_ram(wlc->hw, T_PRS_TPL_BASE,
++				    (len + 3) & ~3, prb_resp);
++
++	/* write the length of the probe response frame (+PLCP/-FCS) */
++	brcms_b_write_shm(wlc->hw, M_PRB_RESP_FRM_LEN, (u16) len);
++
++	/* write the SSID and SSID length */
++	brcms_c_shm_ssid_upd(wlc, cfg);
++
++	/*
++	 * Write PLCP headers and durations for probe response frames
++	 * at all rates. Use the actual frame length covered by the
++	 * PLCP header for the call to brcms_c_mod_prb_rsp_rate_table()
++	 * by subtracting the PLCP len and adding the FCS.
++	 */
++	len += (-D11_PHY_HDR_LEN + FCS_LEN);
++	brcms_c_mod_prb_rsp_rate_table(wlc, (u16) len);
++
++	if (suspend)
++		brcms_c_enable_mac(wlc);
++}
++
++void brcms_c_update_probe_resp(struct brcms_c_info *wlc, bool suspend)
++{
++	struct brcms_bss_cfg *bsscfg = wlc->bsscfg;
++
++	/* update AP or IBSS probe responses */
++	if (bsscfg->up && !bsscfg->BSS)
++		brcms_c_bss_update_probe_resp(wlc, bsscfg, suspend);
++}
++
++/* prepares pdu for transmission. returns BCM error codes */
++int brcms_c_prep_pdu(struct brcms_c_info *wlc, struct sk_buff *pdu, uint *fifop)
++{
++	uint fifo;
++	struct d11txh *txh;
++	struct ieee80211_hdr *h;
++	struct scb *scb;
++
++	txh = (struct d11txh *) (pdu->data);
++	h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN);
++
++	/* get the pkt queue info. This was put at brcms_c_sendctl or
++	 * brcms_c_send for PDU */
++	fifo = le16_to_cpu(txh->TxFrameID) & TXFID_QUEUE_MASK;
++
++	scb = NULL;
++
++	*fifop = fifo;
++
++	/* return if insufficient dma resources */
++	if (*wlc->core->txavail[fifo] < MAX_DMA_SEGS) {
++		/* Mark precedences related to this FIFO, unsendable */
++		/* A fifo is full. Clear precedences related to that FIFO */
++		wlc->tx_prec_map &= ~(wlc->fifo2prec_map[fifo]);
++		return -EBUSY;
++	}
++	return 0;
++}
++
++int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo,
++			   uint *blocks)
++{
++	if (fifo >= NFIFO)
++		return -EINVAL;
++
++	*blocks = wlc_hw->xmtfifo_sz[fifo];
++
++	return 0;
++}
++
++void
++brcms_c_set_addrmatch(struct brcms_c_info *wlc, int match_reg_offset,
++		  const u8 *addr)
++{
++	brcms_b_set_addrmatch(wlc->hw, match_reg_offset, addr);
++	if (match_reg_offset == RCM_BSSID_OFFSET)
++		memcpy(wlc->bsscfg->BSSID, addr, ETH_ALEN);
++}
++
++/*
++ * Flag 'scan in progress' to withhold dynamic phy calibration
++ */
++void brcms_c_scan_start(struct brcms_c_info *wlc)
++{
++	wlc_phy_hold_upd(wlc->band->pi, PHY_HOLD_FOR_SCAN, true);
++}
++
++void brcms_c_scan_stop(struct brcms_c_info *wlc)
++{
++	wlc_phy_hold_upd(wlc->band->pi, PHY_HOLD_FOR_SCAN, false);
++}
++
++void brcms_c_associate_upd(struct brcms_c_info *wlc, bool state)
++{
++	wlc->pub->associated = state;
++	wlc->bsscfg->associated = state;
++}
++
++/*
++ * When a remote STA/AP is removed by Mac80211, or when it can no longer accept
++ * AMPDU traffic, packets pending in hardware have to be invalidated so that
++ * when later on hardware releases them, they can be handled appropriately.
++ */
++void brcms_c_inval_dma_pkts(struct brcms_hardware *hw,
++			       struct ieee80211_sta *sta,
++			       void (*dma_callback_fn))
++{
++	struct dma_pub *dmah;
++	int i;
++	for (i = 0; i < NFIFO; i++) {
++		dmah = hw->di[i];
++		if (dmah != NULL)
++			dma_walk_packets(dmah, dma_callback_fn, sta);
++	}
++}
++
++int brcms_c_get_curband(struct brcms_c_info *wlc)
++{
++	return wlc->band->bandunit;
++}
++
++void brcms_c_wait_for_tx_completion(struct brcms_c_info *wlc, bool drop)
++{
++	int timeout = 20;
++
++	/* flush packet queue when requested */
++	if (drop)
++		brcmu_pktq_flush(&wlc->pkt_queue->q, false, NULL, NULL);
++
++	/* wait for queue and DMA fifos to run dry */
++	while (!pktq_empty(&wlc->pkt_queue->q) || brcms_txpktpendtot(wlc) > 0) {
++		brcms_msleep(wlc->wl, 1);
++
++		if (--timeout == 0)
++			break;
++	}
++
++	WARN_ON_ONCE(timeout == 0);
++}
++
++void brcms_c_set_beacon_listen_interval(struct brcms_c_info *wlc, u8 interval)
++{
++	wlc->bcn_li_bcn = interval;
++	if (wlc->pub->up)
++		brcms_c_bcn_li_upd(wlc);
++}
++
++int brcms_c_set_tx_power(struct brcms_c_info *wlc, int txpwr)
++{
++	uint qdbm;
++
++	/* Remove override bit and clip to max qdbm value */
++	qdbm = min_t(uint, txpwr * BRCMS_TXPWR_DB_FACTOR, 0xff);
++	return wlc_phy_txpower_set(wlc->band->pi, qdbm, false);
++}
++
++int brcms_c_get_tx_power(struct brcms_c_info *wlc)
++{
++	uint qdbm;
++	bool override;
++
++	wlc_phy_txpower_get(wlc->band->pi, &qdbm, &override);
++
++	/* Return qdbm units */
++	return (int)(qdbm / BRCMS_TXPWR_DB_FACTOR);
++}
++
++/* Process received frames */
++/*
++ * Return true if more frames need to be processed. false otherwise.
++ * Param 'bound' indicates max. # frames to process before break out.
++ */
++static void brcms_c_recv(struct brcms_c_info *wlc, struct sk_buff *p)
++{
++	struct d11rxhdr *rxh;
++	struct ieee80211_hdr *h;
++	uint len;
++	bool is_amsdu;
++
++	BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
++
++	/* frame starts with rxhdr */
++	rxh = (struct d11rxhdr *) (p->data);
++
++	/* strip off rxhdr */
++	skb_pull(p, BRCMS_HWRXOFF);
++
++	/* MAC inserts 2 pad bytes for a4 headers or QoS or A-MSDU subframes */
++	if (rxh->RxStatus1 & RXS_PBPRES) {
++		if (p->len < 2) {
++			wiphy_err(wlc->wiphy, "wl%d: recv: rcvd runt of "
++				  "len %d\n", wlc->pub->unit, p->len);
++			goto toss;
++		}
++		skb_pull(p, 2);
++	}
++
++	h = (struct ieee80211_hdr *)(p->data + D11_PHY_HDR_LEN);
++	len = p->len;
++
++	if (rxh->RxStatus1 & RXS_FCSERR) {
++		if (!(wlc->filter_flags & FIF_FCSFAIL))
++			goto toss;
++	}
++
++	/* check received pkt has at least frame control field */
++	if (len < D11_PHY_HDR_LEN + sizeof(h->frame_control))
++		goto toss;
++
++	/* not supporting A-MSDU */
++	is_amsdu = rxh->RxStatus2 & RXS_AMSDU_MASK;
++	if (is_amsdu)
++		goto toss;
++
++	brcms_c_recvctl(wlc, rxh, p);
++	return;
++
++ toss:
++	brcmu_pkt_buf_free_skb(p);
++}
++
++/* Process received frames */
++/*
++ * Return true if more frames need to be processed. false otherwise.
++ * Param 'bound' indicates max. # frames to process before break out.
++ */
++static bool
++brcms_b_recv(struct brcms_hardware *wlc_hw, uint fifo, bool bound)
++{
++	struct sk_buff *p;
++	struct sk_buff *next = NULL;
++	struct sk_buff_head recv_frames;
++
++	uint n = 0;
++	uint bound_limit = bound ? RXBND : -1;
++
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
++	skb_queue_head_init(&recv_frames);
++
++	/* gather received frames */
++	while (dma_rx(wlc_hw->di[fifo], &recv_frames)) {
++
++		/* !give others some time to run! */
++		if (++n >= bound_limit)
++			break;
++	}
++
++	/* post more rbufs */
++	dma_rxfill(wlc_hw->di[fifo]);
++
++	/* process each frame */
++	skb_queue_walk_safe(&recv_frames, p, next) {
++		struct d11rxhdr_le *rxh_le;
++		struct d11rxhdr *rxh;
++
++		skb_unlink(p, &recv_frames);
++		rxh_le = (struct d11rxhdr_le *)p->data;
++		rxh = (struct d11rxhdr *)p->data;
++
++		/* fixup rx header endianness */
++		rxh->RxFrameSize = le16_to_cpu(rxh_le->RxFrameSize);
++		rxh->PhyRxStatus_0 = le16_to_cpu(rxh_le->PhyRxStatus_0);
++		rxh->PhyRxStatus_1 = le16_to_cpu(rxh_le->PhyRxStatus_1);
++		rxh->PhyRxStatus_2 = le16_to_cpu(rxh_le->PhyRxStatus_2);
++		rxh->PhyRxStatus_3 = le16_to_cpu(rxh_le->PhyRxStatus_3);
++		rxh->PhyRxStatus_4 = le16_to_cpu(rxh_le->PhyRxStatus_4);
++		rxh->PhyRxStatus_5 = le16_to_cpu(rxh_le->PhyRxStatus_5);
++		rxh->RxStatus1 = le16_to_cpu(rxh_le->RxStatus1);
++		rxh->RxStatus2 = le16_to_cpu(rxh_le->RxStatus2);
++		rxh->RxTSFTime = le16_to_cpu(rxh_le->RxTSFTime);
++		rxh->RxChan = le16_to_cpu(rxh_le->RxChan);
++
++		brcms_c_recv(wlc_hw->wlc, p);
++	}
++
++	return n >= bound_limit;
++}
++
++/* second-level interrupt processing
++ *   Return true if another dpc needs to be re-scheduled. false otherwise.
++ *   Param 'bounded' indicates if applicable loops should be bounded.
++ */
++bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded)
++{
++	u32 macintstatus;
++	struct brcms_hardware *wlc_hw = wlc->hw;
++	struct bcma_device *core = wlc_hw->d11core;
++	struct wiphy *wiphy = wlc->wiphy;
++
++	if (brcms_deviceremoved(wlc)) {
++		wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit,
++			  __func__);
++		brcms_down(wlc->wl);
++		return false;
++	}
++
++	/* grab and clear the saved software intstatus bits */
++	macintstatus = wlc->macintstatus;
++	wlc->macintstatus = 0;
++
++	BCMMSG(wlc->wiphy, "wl%d: macintstatus 0x%x\n",
++	       wlc_hw->unit, macintstatus);
++
++	WARN_ON(macintstatus & MI_PRQ); /* PRQ Interrupt in non-MBSS */
++
++	/* tx status */
++	if (macintstatus & MI_TFS) {
++		bool fatal;
++		if (brcms_b_txstatus(wlc->hw, bounded, &fatal))
++			wlc->macintstatus |= MI_TFS;
++		if (fatal) {
++			wiphy_err(wiphy, "MI_TFS: fatal\n");
++			goto fatal;
++		}
++	}
++
++	if (macintstatus & (MI_TBTT | MI_DTIM_TBTT))
++		brcms_c_tbtt(wlc);
++
++	/* ATIM window end */
++	if (macintstatus & MI_ATIMWINEND) {
++		BCMMSG(wlc->wiphy, "end of ATIM window\n");
++		bcma_set32(core, D11REGOFFS(maccommand), wlc->qvalid);
++		wlc->qvalid = 0;
++	}
++
++	/*
++	 * received data or control frame, MI_DMAINT is
++	 * indication of RX_FIFO interrupt
++	 */
++	if (macintstatus & MI_DMAINT)
++		if (brcms_b_recv(wlc_hw, RX_FIFO, bounded))
++			wlc->macintstatus |= MI_DMAINT;
++
++	/* noise sample collected */
++	if (macintstatus & MI_BG_NOISE)
++		wlc_phy_noise_sample_intr(wlc_hw->band->pi);
++
++	if (macintstatus & MI_GP0) {
++		wiphy_err(wiphy, "wl%d: PSM microcode watchdog fired at %d "
++			  "(seconds). Resetting.\n", wlc_hw->unit, wlc_hw->now);
++
++		printk_once("%s : PSM Watchdog, chipid 0x%x, chiprev 0x%x\n",
++			    __func__, ai_get_chip_id(wlc_hw->sih),
++			    ai_get_chiprev(wlc_hw->sih));
++		brcms_fatal_error(wlc_hw->wlc->wl);
++	}
++
++	/* gptimer timeout */
++	if (macintstatus & MI_TO)
++		bcma_write32(core, D11REGOFFS(gptimer), 0);
++
++	if (macintstatus & MI_RFDISABLE) {
++		BCMMSG(wlc->wiphy, "wl%d: BMAC Detected a change on the"
++		       " RF Disable Input\n", wlc_hw->unit);
++		brcms_rfkill_set_hw_state(wlc->wl);
++	}
++
++	/* send any enq'd tx packets. Just makes sure to jump start tx */
++	if (!pktq_empty(&wlc->pkt_queue->q))
++		brcms_c_send_q(wlc);
++
++	/* it isn't done and needs to be resched if macintstatus is non-zero */
++	return wlc->macintstatus != 0;
++
++ fatal:
++	brcms_fatal_error(wlc_hw->wlc->wl);
++	return wlc->macintstatus != 0;
++}
++
++void brcms_c_init(struct brcms_c_info *wlc, bool mute_tx)
++{
++	struct bcma_device *core = wlc->hw->d11core;
++	u16 chanspec;
++
++	BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
++
++	/*
++	 * This will happen if a big-hammer was executed. In
++	 * that case, we want to go back to the channel that
++	 * we were on and not new channel
++	 */
++	if (wlc->pub->associated)
++		chanspec = wlc->home_chanspec;
++	else
++		chanspec = brcms_c_init_chanspec(wlc);
++
++	brcms_b_init(wlc->hw, chanspec);
++
++	/* update beacon listen interval */
++	brcms_c_bcn_li_upd(wlc);
++
++	/* write ethernet address to core */
++	brcms_c_set_mac(wlc->bsscfg);
++	brcms_c_set_bssid(wlc->bsscfg);
++
++	/* Update tsf_cfprep if associated and up */
++	if (wlc->pub->associated && wlc->bsscfg->up) {
++		u32 bi;
++
++		/* get beacon period and convert to uS */
++		bi = wlc->bsscfg->current_bss->beacon_period << 10;
++		/*
++		 * update since init path would reset
++		 * to default value
++		 */
++		bcma_write32(core, D11REGOFFS(tsf_cfprep),
++			     bi << CFPREP_CBI_SHIFT);
++
++		/* Update maccontrol PM related bits */
++		brcms_c_set_ps_ctrl(wlc);
++	}
++
++	brcms_c_bandinit_ordered(wlc, chanspec);
++
++	/* init probe response timeout */
++	brcms_b_write_shm(wlc->hw, M_PRS_MAXTIME, wlc->prb_resp_timeout);
++
++	/* init max burst txop (framebursting) */
++	brcms_b_write_shm(wlc->hw, M_MBURST_TXOP,
++		      (wlc->
++		       _rifs ? (EDCF_AC_VO_TXOP_AP << 5) : MAXFRAMEBURST_TXOP));
++
++	/* initialize maximum allowed duty cycle */
++	brcms_c_duty_cycle_set(wlc, wlc->tx_duty_cycle_ofdm, true, true);
++	brcms_c_duty_cycle_set(wlc, wlc->tx_duty_cycle_cck, false, true);
++
++	/*
++	 * Update some shared memory locations related to
++	 * max AMPDU size allowed to received
++	 */
++	brcms_c_ampdu_shm_upd(wlc->ampdu);
++
++	/* band-specific inits */
++	brcms_c_bsinit(wlc);
++
++	/* Enable EDCF mode (while the MAC is suspended) */
++	bcma_set16(core, D11REGOFFS(ifs_ctl), IFS_USEEDCF);
++	brcms_c_edcf_setparams(wlc, false);
++
++	/* Init precedence maps for empty FIFOs */
++	brcms_c_tx_prec_map_init(wlc);
++
++	/* read the ucode version if we have not yet done so */
++	if (wlc->ucode_rev == 0) {
++		wlc->ucode_rev =
++		    brcms_b_read_shm(wlc->hw, M_BOM_REV_MAJOR) << NBITS(u16);
++		wlc->ucode_rev |= brcms_b_read_shm(wlc->hw, M_BOM_REV_MINOR);
++	}
++
++	/* ..now really unleash hell (allow the MAC out of suspend) */
++	brcms_c_enable_mac(wlc);
++
++	/* suspend the tx fifos and mute the phy for preism cac time */
++	if (mute_tx)
++		brcms_b_mute(wlc->hw, true);
++
++	/* clear tx flow control */
++	brcms_c_txflowcontrol_reset(wlc);
++
++	/* enable the RF Disable Delay timer */
++	bcma_write32(core, D11REGOFFS(rfdisabledly), RFDISABLE_DEFAULT);
++
++	/*
++	 * Initialize WME parameters; if they haven't been set by some other
++	 * mechanism (IOVar, etc) then read them from the hardware.
++	 */
++	if (GFIELD(wlc->wme_retries[0], EDCF_SHORT) == 0) {
++		/* Uninitialized; read from HW */
++		int ac;
++
++		for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
++			wlc->wme_retries[ac] =
++			    brcms_b_read_shm(wlc->hw, M_AC_TXLMT_ADDR(ac));
++	}
++}
++
++/*
++ * The common driver entry routine. Error codes should be unique
++ */
++struct brcms_c_info *
++brcms_c_attach(struct brcms_info *wl, struct bcma_device *core, uint unit,
++	       bool piomode, uint *perr)
++{
++	struct brcms_c_info *wlc;
++	uint err = 0;
++	uint i, j;
++	struct brcms_pub *pub;
++
++	/* allocate struct brcms_c_info state and its substructures */
++	wlc = (struct brcms_c_info *) brcms_c_attach_malloc(unit, &err, 0);
++	if (wlc == NULL)
++		goto fail;
++	wlc->wiphy = wl->wiphy;
++	pub = wlc->pub;
++
++#if defined(DEBUG)
++	wlc_info_dbg = wlc;
++#endif
++
++	wlc->band = wlc->bandstate[0];
++	wlc->core = wlc->corestate;
++	wlc->wl = wl;
++	pub->unit = unit;
++	pub->_piomode = piomode;
++	wlc->bandinit_pending = false;
++
++	/* populate struct brcms_c_info with default values  */
++	brcms_c_info_init(wlc, unit);
++
++	/* update sta/ap related parameters */
++	brcms_c_ap_upd(wlc);
++
++	/*
++	 * low level attach steps(all hw accesses go
++	 * inside, no more in rest of the attach)
++	 */
++	err = brcms_b_attach(wlc, core, unit, piomode);
++	if (err)
++		goto fail;
++
++	brcms_c_protection_upd(wlc, BRCMS_PROT_N_PAM_OVR, OFF);
++
++	pub->phy_11ncapable = BRCMS_PHY_11N_CAP(wlc->band);
++
++	/* disable allowed duty cycle */
++	wlc->tx_duty_cycle_ofdm = 0;
++	wlc->tx_duty_cycle_cck = 0;
++
++	brcms_c_stf_phy_chain_calc(wlc);
++
++	/* txchain 1: txant 0, txchain 2: txant 1 */
++	if (BRCMS_ISNPHY(wlc->band) && (wlc->stf->txstreams == 1))
++		wlc->stf->txant = wlc->stf->hw_txchain - 1;
++
++	/* push to BMAC driver */
++	wlc_phy_stf_chain_init(wlc->band->pi, wlc->stf->hw_txchain,
++			       wlc->stf->hw_rxchain);
++
++	/* pull up some info resulting from the low attach */
++	for (i = 0; i < NFIFO; i++)
++		wlc->core->txavail[i] = wlc->hw->txavail[i];
++
++	memcpy(&wlc->perm_etheraddr, &wlc->hw->etheraddr, ETH_ALEN);
++	memcpy(&pub->cur_etheraddr, &wlc->hw->etheraddr, ETH_ALEN);
++
++	for (j = 0; j < wlc->pub->_nbands; j++) {
++		wlc->band = wlc->bandstate[j];
++
++		if (!brcms_c_attach_stf_ant_init(wlc)) {
++			err = 24;
++			goto fail;
++		}
++
++		/* default contention windows size limits */
++		wlc->band->CWmin = APHY_CWMIN;
++		wlc->band->CWmax = PHY_CWMAX;
++
++		/* init gmode value */
++		if (wlc->band->bandtype == BRCM_BAND_2G) {
++			wlc->band->gmode = GMODE_AUTO;
++			brcms_c_protection_upd(wlc, BRCMS_PROT_G_USER,
++					   wlc->band->gmode);
++		}
++
++		/* init _n_enab supported mode */
++		if (BRCMS_PHY_11N_CAP(wlc->band)) {
++			pub->_n_enab = SUPPORT_11N;
++			brcms_c_protection_upd(wlc, BRCMS_PROT_N_USER,
++						   ((pub->_n_enab ==
++						     SUPPORT_11N) ? WL_11N_2x2 :
++						    WL_11N_3x3));
++		}
++
++		/* init per-band default rateset, depend on band->gmode */
++		brcms_default_rateset(wlc, &wlc->band->defrateset);
++
++		/* fill in hw_rateset */
++		brcms_c_rateset_filter(&wlc->band->defrateset,
++				   &wlc->band->hw_rateset, false,
++				   BRCMS_RATES_CCK_OFDM, BRCMS_RATE_MASK,
++				   (bool) (wlc->pub->_n_enab & SUPPORT_11N));
++	}
++
++	/*
++	 * update antenna config due to
++	 * wlc->stf->txant/txchain/ant_rx_ovr change
++	 */
++	brcms_c_stf_phy_txant_upd(wlc);
++
++	/* attach each modules */
++	err = brcms_c_attach_module(wlc);
++	if (err != 0)
++		goto fail;
++
++	if (!brcms_c_timers_init(wlc, unit)) {
++		wiphy_err(wl->wiphy, "wl%d: %s: init_timer failed\n", unit,
++			  __func__);
++		err = 32;
++		goto fail;
++	}
++
++	/* depend on rateset, gmode */
++	wlc->cmi = brcms_c_channel_mgr_attach(wlc);
++	if (!wlc->cmi) {
++		wiphy_err(wl->wiphy, "wl%d: %s: channel_mgr_attach failed"
++			  "\n", unit, __func__);
++		err = 33;
++		goto fail;
++	}
++
++	/* init default when all parameters are ready, i.e. ->rateset */
++	brcms_c_bss_default_init(wlc);
++
++	/*
++	 * Complete the wlc default state initializations..
++	 */
++
++	/* allocate our initial queue */
++	wlc->pkt_queue = brcms_c_txq_alloc(wlc);
++	if (wlc->pkt_queue == NULL) {
++		wiphy_err(wl->wiphy, "wl%d: %s: failed to malloc tx queue\n",
++			  unit, __func__);
++		err = 100;
++		goto fail;
++	}
++
++	wlc->bsscfg->wlc = wlc;
++
++	wlc->mimoft = FT_HT;
++	wlc->mimo_40txbw = AUTO;
++	wlc->ofdm_40txbw = AUTO;
++	wlc->cck_40txbw = AUTO;
++	brcms_c_update_mimo_band_bwcap(wlc, BRCMS_N_BW_20IN2G_40IN5G);
++
++	/* Set default values of SGI */
++	if (BRCMS_SGI_CAP_PHY(wlc)) {
++		brcms_c_ht_update_sgi_rx(wlc, (BRCMS_N_SGI_20 |
++					       BRCMS_N_SGI_40));
++	} else if (BRCMS_ISSSLPNPHY(wlc->band)) {
++		brcms_c_ht_update_sgi_rx(wlc, (BRCMS_N_SGI_20 |
++					       BRCMS_N_SGI_40));
++	} else {
++		brcms_c_ht_update_sgi_rx(wlc, 0);
++	}
++
++	brcms_b_antsel_set(wlc->hw, wlc->asi->antsel_avail);
++
++	if (perr)
++		*perr = 0;
++
++	return wlc;
++
++ fail:
++	wiphy_err(wl->wiphy, "wl%d: %s: failed with err %d\n",
++		  unit, __func__, err);
++	if (wlc)
++		brcms_c_detach(wlc);
++
++	if (perr)
++		*perr = err;
++	return NULL;
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.h b/drivers/net/wireless/brcm80211/brcmsmac/main.h
+new file mode 100644
+index 0000000..8debc74
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.h
+@@ -0,0 +1,720 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef _BRCM_MAIN_H_
++#define _BRCM_MAIN_H_
++
++#include <linux/etherdevice.h>
++
++#include <brcmu_utils.h>
++#include "types.h"
++#include "d11.h"
++#include "scb.h"
++
++#define	INVCHANNEL		255	/* invalid channel */
++
++/* max # brcms_c_module_register() calls */
++#define BRCMS_MAXMODULES	22
++
++#define SEQNUM_SHIFT		4
++#define SEQNUM_MAX		0x1000
++
++#define NTXRATE			64	/* # tx MPDUs rate is reported for */
++
++/* Maximum wait time for a MAC suspend */
++/* uS: 83mS is max packet time (64KB ampdu @ 6Mbps) */
++#define	BRCMS_MAX_MAC_SUSPEND	83000
++
++/* responses for probe requests older that this are tossed, zero to disable */
++#define BRCMS_PRB_RESP_TIMEOUT	0	/* Disable probe response timeout */
++
++/* transmit buffer max headroom for protocol headers */
++#define TXOFF (D11_TXH_LEN + D11_PHY_HDR_LEN)
++
++/* Macros for doing definition and get/set of bitfields
++ * Usage example, e.g. a three-bit field (bits 4-6):
++ *    #define <NAME>_M	BITFIELD_MASK(3)
++ *    #define <NAME>_S	4
++ * ...
++ *    regval = R_REG(osh, &regs->regfoo);
++ *    field = GFIELD(regval, <NAME>);
++ *    regval = SFIELD(regval, <NAME>, 1);
++ *    W_REG(osh, &regs->regfoo, regval);
++ */
++#define BITFIELD_MASK(width) \
++		(((unsigned)1 << (width)) - 1)
++#define GFIELD(val, field) \
++		(((val) >> field ## _S) & field ## _M)
++#define SFIELD(val, field, bits) \
++		(((val) & (~(field ## _M << field ## _S))) | \
++		 ((unsigned)(bits) << field ## _S))
++
++#define	SW_TIMER_MAC_STAT_UPD		30	/* periodic MAC stats update */
++
++/* max # supported core revisions (0 .. MAXCOREREV - 1) */
++#define	MAXCOREREV		28
++
++/* Double check that unsupported cores are not enabled */
++#if CONF_MSK(D11CONF, 0x4f) || CONF_GE(D11CONF, MAXCOREREV)
++#error "Configuration for D11CONF includes unsupported versions."
++#endif				/* Bad versions */
++
++/* values for shortslot_override */
++#define BRCMS_SHORTSLOT_AUTO	-1 /* Driver will manage Shortslot setting */
++#define BRCMS_SHORTSLOT_OFF	0  /* Turn off short slot */
++#define BRCMS_SHORTSLOT_ON	1  /* Turn on short slot */
++
++/* value for short/long and mixmode/greenfield preamble */
++#define BRCMS_LONG_PREAMBLE	(0)
++#define BRCMS_SHORT_PREAMBLE	(1 << 0)
++#define BRCMS_GF_PREAMBLE		(1 << 1)
++#define BRCMS_MM_PREAMBLE		(1 << 2)
++#define BRCMS_IS_MIMO_PREAMBLE(_pre) (((_pre) == BRCMS_GF_PREAMBLE) || \
++				      ((_pre) == BRCMS_MM_PREAMBLE))
++
++/* TxFrameID */
++/* seq and frag bits: SEQNUM_SHIFT, FRAGNUM_MASK (802.11.h) */
++/* rate epoch bits: TXFID_RATE_SHIFT, TXFID_RATE_MASK ((wlc_rate.c) */
++#define TXFID_QUEUE_MASK	0x0007	/* Bits 0-2 */
++#define TXFID_SEQ_MASK		0x7FE0	/* Bits 5-15 */
++#define TXFID_SEQ_SHIFT		5	/* Number of bit shifts */
++#define	TXFID_RATE_PROBE_MASK	0x8000	/* Bit 15 for rate probe */
++#define TXFID_RATE_MASK		0x0018	/* Mask for bits 3 and 4 */
++#define TXFID_RATE_SHIFT	3	/* Shift 3 bits for rate mask */
++
++/* promote boardrev */
++#define BOARDREV_PROMOTABLE	0xFF	/* from */
++#define BOARDREV_PROMOTED	1	/* to */
++
++#define DATA_BLOCK_TX_SUPR	(1 << 4)
++
++/* 802.1D Priority to TX FIFO number for wme */
++extern const u8 prio2fifo[];
++
++/* Ucode MCTL_WAKE override bits */
++#define BRCMS_WAKE_OVERRIDE_CLKCTL	0x01
++#define BRCMS_WAKE_OVERRIDE_PHYREG	0x02
++#define BRCMS_WAKE_OVERRIDE_MACSUSPEND	0x04
++#define BRCMS_WAKE_OVERRIDE_TXFIFO	0x08
++#define BRCMS_WAKE_OVERRIDE_FORCEFAST	0x10
++
++/* stuff pulled in from wlc.c */
++
++/* Interrupt bit error summary.  Don't include I_RU: we refill DMA at other
++ * times; and if we run out, constant I_RU interrupts may cause lockup.  We
++ * will still get error counts from rx0ovfl.
++ */
++#define	I_ERRORS	(I_PC | I_PD | I_DE | I_RO | I_XU)
++/* default software intmasks */
++#define	DEF_RXINTMASK	(I_RI)	/* enable rx int on rxfifo only */
++#define	DEF_MACINTMASK	(MI_TXSTOP | MI_TBTT | MI_ATIMWINEND | MI_PMQ | \
++			 MI_PHYTXERR | MI_DMAINT | MI_TFS | MI_BG_NOISE | \
++			 MI_CCA | MI_TO | MI_GP0 | MI_RFDISABLE | MI_PWRUP)
++
++#define	MAXTXPKTS		6	/* max # pkts pending */
++
++/* frameburst */
++#define	MAXTXFRAMEBURST		8 /* vanilla xpress mode: max frames/burst */
++#define	MAXFRAMEBURST_TXOP	10000	/* Frameburst TXOP in usec */
++
++#define	NFIFO			6	/* # tx/rx fifopairs */
++
++/* PLL requests */
++
++/* pll is shared on old chips */
++#define BRCMS_PLLREQ_SHARED	0x1
++/* hold pll for radio monitor register checking */
++#define BRCMS_PLLREQ_RADIO_MON	0x2
++/* hold/release pll for some short operation */
++#define BRCMS_PLLREQ_FLIP		0x4
++
++#define	CHANNEL_BANDUNIT(wlc, ch) \
++	(((ch) <= CH_MAX_2G_CHANNEL) ? BAND_2G_INDEX : BAND_5G_INDEX)
++
++#define	OTHERBANDUNIT(wlc) \
++	((uint)((wlc)->band->bandunit ? BAND_2G_INDEX : BAND_5G_INDEX))
++
++/*
++ * 802.11 protection information
++ *
++ * _g: use g spec protection, driver internal.
++ * g_override: override for use of g spec protection.
++ * gmode_user: user config gmode, operating band->gmode is different.
++ * overlap: Overlap BSS/IBSS protection for both 11g and 11n.
++ * nmode_user: user config nmode, operating pub->nmode is different.
++ * n_cfg: use OFDM protection on MIMO frames.
++ * n_cfg_override: override for use of N protection.
++ * nongf: non-GF present protection.
++ * nongf_override: override for use of GF protection.
++ * n_pam_override: override for preamble: MM or GF.
++ * n_obss: indicated OBSS Non-HT STA present.
++*/
++struct brcms_protection {
++	bool _g;
++	s8 g_override;
++	u8 gmode_user;
++	s8 overlap;
++	s8 nmode_user;
++	s8 n_cfg;
++	s8 n_cfg_override;
++	bool nongf;
++	s8 nongf_override;
++	s8 n_pam_override;
++	bool n_obss;
++};
++
++/*
++ * anything affecting the single/dual streams/antenna operation
++ *
++ * hw_txchain: HW txchain bitmap cfg.
++ * txchain: txchain bitmap being used.
++ * txstreams: number of txchains being used.
++ * hw_rxchain: HW rxchain bitmap cfg.
++ * rxchain: rxchain bitmap being used.
++ * rxstreams: number of rxchains being used.
++ * ant_rx_ovr: rx antenna override.
++ * txant: userTx antenna setting.
++ * phytxant: phyTx antenna setting in txheader.
++ * ss_opmode: singlestream Operational mode, 0:siso; 1:cdd.
++ * ss_algosel_auto: if true, use wlc->stf->ss_algo_channel;
++ *			else use wlc->band->stf->ss_mode_band.
++ * ss_algo_channel: ss based on per-channel algo: 0: SISO, 1: CDD 2: STBC.
++ * rxchain_restore_delay: delay time to restore default rxchain.
++ * ldpc: AUTO/ON/OFF ldpc cap supported.
++ * txcore[MAX_STREAMS_SUPPORTED + 1]: bitmap of selected core for each Nsts.
++ * spatial_policy:
++ */
++struct brcms_stf {
++	u8 hw_txchain;
++	u8 txchain;
++	u8 txstreams;
++	u8 hw_rxchain;
++	u8 rxchain;
++	u8 rxstreams;
++	u8 ant_rx_ovr;
++	s8 txant;
++	u16 phytxant;
++	u8 ss_opmode;
++	bool ss_algosel_auto;
++	u16 ss_algo_channel;
++	u8 rxchain_restore_delay;
++	s8 ldpc;
++	u8 txcore[MAX_STREAMS_SUPPORTED + 1];
++	s8 spatial_policy;
++};
++
++#define BRCMS_STF_SS_STBC_TX(wlc, scb) \
++	(((wlc)->stf->txstreams > 1) && (((wlc)->band->band_stf_stbc_tx == ON) \
++	 || (((scb)->flags & SCB_STBCCAP) && \
++	     (wlc)->band->band_stf_stbc_tx == AUTO && \
++	     isset(&((wlc)->stf->ss_algo_channel), PHY_TXC1_MODE_STBC))))
++
++#define BRCMS_STBC_CAP_PHY(wlc) (BRCMS_ISNPHY(wlc->band) && \
++				 NREV_GE(wlc->band->phyrev, 3))
++
++#define BRCMS_SGI_CAP_PHY(wlc) ((BRCMS_ISNPHY(wlc->band) && \
++				 NREV_GE(wlc->band->phyrev, 3)) || \
++				BRCMS_ISLCNPHY(wlc->band))
++
++#define BRCMS_CHAN_PHYTYPE(x)     (((x) & RXS_CHAN_PHYTYPE_MASK) \
++				   >> RXS_CHAN_PHYTYPE_SHIFT)
++#define BRCMS_CHAN_CHANNEL(x)     (((x) & RXS_CHAN_ID_MASK) \
++				   >> RXS_CHAN_ID_SHIFT)
++
++/*
++ * core state (mac)
++ */
++struct brcms_core {
++	uint coreidx;		/* # sb enumerated core */
++
++	/* fifo */
++	uint *txavail[NFIFO];	/* # tx descriptors available */
++	s16 txpktpend[NFIFO];	/* tx admission control */
++
++	struct macstat *macstat_snapshot;	/* mac hw prev read values */
++};
++
++/*
++ * band state (phy+ana+radio)
++ */
++struct brcms_band {
++	int bandtype;		/* BRCM_BAND_2G, BRCM_BAND_5G */
++	uint bandunit;		/* bandstate[] index */
++
++	u16 phytype;		/* phytype */
++	u16 phyrev;
++	u16 radioid;
++	u16 radiorev;
++	struct brcms_phy_pub *pi; /* pointer to phy specific information */
++	bool abgphy_encore;
++
++	u8 gmode;		/* currently active gmode */
++
++	struct scb *hwrs_scb;	/* permanent scb for hw rateset */
++
++	/* band-specific copy of default_bss.rateset */
++	struct brcms_c_rateset defrateset;
++
++	u8 band_stf_ss_mode;	/* Configured STF type, 0:siso; 1:cdd */
++	s8 band_stf_stbc_tx;	/* STBC TX 0:off; 1:force on; -1:auto */
++	/* rates supported by chip (phy-specific) */
++	struct brcms_c_rateset hw_rateset;
++	u8 basic_rate[BRCM_MAXRATE + 1]; /* basic rates indexed by rate */
++	bool mimo_cap_40;	/* 40 MHz cap enabled on this band */
++	s8 antgain;		/* antenna gain from srom */
++
++	u16 CWmin; /* minimum size of contention window, in unit of aSlotTime */
++	u16 CWmax; /* maximum size of contention window, in unit of aSlotTime */
++	struct ieee80211_supported_band band;
++};
++
++/* module control blocks */
++struct modulecb {
++	/* module name : NULL indicates empty array member */
++	char name[32];
++	/* handle passed when handler 'doiovar' is called */
++	struct brcms_info *hdl;
++
++	int (*down_fn)(void *handle); /* down handler. Note: the int returned
++				       * by the down function is a count of the
++				       * number of timers that could not be
++				       * freed.
++				       */
++
++};
++
++struct brcms_hw_band {
++	int bandtype;		/* BRCM_BAND_2G, BRCM_BAND_5G */
++	uint bandunit;		/* bandstate[] index */
++	u16 mhfs[MHFMAX];	/* MHF array shadow */
++	u8 bandhw_stf_ss_mode;	/* HW configured STF type, 0:siso; 1:cdd */
++	u16 CWmin;
++	u16 CWmax;
++	u32 core_flags;
++
++	u16 phytype;		/* phytype */
++	u16 phyrev;
++	u16 radioid;
++	u16 radiorev;
++	struct brcms_phy_pub *pi; /* pointer to phy specific information */
++	bool abgphy_encore;
++};
++
++struct brcms_hardware {
++	bool _piomode;		/* true if pio mode */
++	struct brcms_c_info *wlc;
++
++	/* fifo */
++	struct dma_pub *di[NFIFO];	/* dma handles, per fifo */
++
++	uint unit;		/* device instance number */
++
++	/* version info */
++	u16 vendorid;	/* PCI vendor id */
++	u16 deviceid;	/* PCI device id */
++	uint corerev;		/* core revision */
++	u8 sromrev;		/* version # of the srom */
++	u16 boardrev;	/* version # of particular board */
++	u32 boardflags;	/* Board specific flags from srom */
++	u32 boardflags2;	/* More board flags if sromrev >= 4 */
++	u32 machwcap;	/* MAC capabilities */
++	u32 machwcap_backup;	/* backup of machwcap */
++
++	struct si_pub *sih;	/* SI handle (cookie for siutils calls) */
++	struct bcma_device *d11core;	/* pointer to 802.11 core */
++	struct phy_shim_info *physhim; /* phy shim layer handler */
++	struct shared_phy *phy_sh;	/* pointer to shared phy state */
++	struct brcms_hw_band *band;/* pointer to active per-band state */
++	/* band state per phy/radio */
++	struct brcms_hw_band *bandstate[MAXBANDS];
++	u16 bmac_phytxant;	/* cache of high phytxant state */
++	bool shortslot;		/* currently using 11g ShortSlot timing */
++	u16 SRL;		/* 802.11 dot11ShortRetryLimit */
++	u16 LRL;		/* 802.11 dot11LongRetryLimit */
++	u16 SFBL;		/* Short Frame Rate Fallback Limit */
++	u16 LFBL;		/* Long Frame Rate Fallback Limit */
++
++	bool up;		/* d11 hardware up and running */
++	uint now;		/* # elapsed seconds */
++	uint _nbands;		/* # bands supported */
++	u16 chanspec;	/* bmac chanspec shadow */
++
++	uint *txavail[NFIFO];	/* # tx descriptors available */
++	const u16 *xmtfifo_sz;	/* fifo size in 256B for each xmt fifo */
++
++	u32 pllreq;		/* pll requests to keep PLL on */
++
++	u8 suspended_fifos;	/* Which TX fifo to remain awake for */
++	u32 maccontrol;	/* Cached value of maccontrol */
++	uint mac_suspend_depth;	/* current depth of mac_suspend levels */
++	u32 wake_override;	/* bit flags to force MAC to WAKE mode */
++	u32 mute_override;	/* Prevent ucode from sending beacons */
++	u8 etheraddr[ETH_ALEN];	/* currently configured ethernet address */
++	bool noreset;		/* true= do not reset hw, used by WLC_OUT */
++	bool forcefastclk;	/* true if h/w is forcing to use fast clk */
++	bool clk;		/* core is out of reset and has clock */
++	bool sbclk;		/* sb has clock */
++	bool phyclk;		/* phy is out of reset and has clock */
++
++	bool ucode_loaded;	/* true after ucode downloaded */
++
++
++	u8 hw_stf_ss_opmode;	/* STF single stream operation mode */
++	u8 antsel_type;	/* Type of boardlevel mimo antenna switch-logic
++				 * 0 = N/A, 1 = 2x4 board, 2 = 2x3 CB2 board
++				 */
++	u32 antsel_avail;	/*
++				 * put struct antsel_info here if more info is
++				 * needed
++				 */
++};
++
++/* TX Queue information
++ *
++ * Each flow of traffic out of the device has a TX Queue with independent
++ * flow control. Several interfaces may be associated with a single TX Queue
++ * if they belong to the same flow of traffic from the device. For multi-channel
++ * operation there are independent TX Queues for each channel.
++ */
++struct brcms_txq_info {
++	struct brcms_txq_info *next;
++	struct pktq q;
++	uint stopped;		/* tx flow control bits */
++};
++
++/*
++ * Principal common driver data structure.
++ *
++ * pub: pointer to driver public state.
++ * wl: pointer to specific private state.
++ * hw: HW related state.
++ * clkreq_override: setting for clkreq for PCIE : Auto, 0, 1.
++ * fastpwrup_dly: time in us needed to bring up d11 fast clock.
++ * macintstatus: bit channel between isr and dpc.
++ * macintmask: sw runtime master macintmask value.
++ * defmacintmask: default "on" macintmask value.
++ * clk: core is out of reset and has clock.
++ * core: pointer to active io core.
++ * band: pointer to active per-band state.
++ * corestate: per-core state (one per hw core).
++ * bandstate: per-band state (one per phy/radio).
++ * qvalid: DirFrmQValid and BcMcFrmQValid.
++ * ampdu: ampdu module handler.
++ * asi: antsel module handler.
++ * cmi: channel manager module handler.
++ * vendorid: PCI vendor id.
++ * deviceid: PCI device id.
++ * ucode_rev: microcode revision.
++ * machwcap: MAC capabilities, BMAC shadow.
++ * perm_etheraddr: original sprom local ethernet address.
++ * bandlocked: disable auto multi-band switching.
++ * bandinit_pending: track band init in auto band.
++ * radio_monitor: radio timer is running.
++ * going_down: down path intermediate variable.
++ * wdtimer: timer for watchdog routine.
++ * radio_timer: timer for hw radio button monitor routine.
++ * monitor: monitor (MPDU sniffing) mode.
++ * bcnmisc_monitor: bcns promisc mode override for monitor.
++ * _rifs: enable per-packet rifs.
++ * bcn_li_bcn: beacon listen interval in # beacons.
++ * bcn_li_dtim: beacon listen interval in # dtims.
++ * WDarmed: watchdog timer is armed.
++ * WDlast: last time wlc_watchdog() was called.
++ * edcf_txop[IEEE80211_NUM_ACS]: current txop for each ac.
++ * wme_retries: per-AC retry limits.
++ * tx_prec_map: Precedence map based on HW FIFO space.
++ * fifo2prec_map[NFIFO]: pointer to fifo2_prec map based on WME.
++ * bsscfg: set of BSS configurations, idx 0 is default and always valid.
++ * cfg: the primary bsscfg (can be AP or STA).
++ * tx_queues: common TX Queue list.
++ * modulecb:
++ * mimoft: SIGN or 11N.
++ * cck_40txbw: 11N, cck tx b/w override when in 40MHZ mode.
++ * ofdm_40txbw: 11N, ofdm tx b/w override when in 40MHZ mode.
++ * mimo_40txbw: 11N, mimo tx b/w override when in 40MHZ mode.
++ * default_bss: configured BSS parameters.
++ * mc_fid_counter: BC/MC FIFO frame ID counter.
++ * country_default: saved country for leaving 802.11d auto-country mode.
++ * autocountry_default: initial country for 802.11d auto-country mode.
++ * prb_resp_timeout: do not send prb resp if request older
++ *		     than this, 0 = disable.
++ * home_chanspec: shared home chanspec.
++ * chanspec: target operational channel.
++ * usr_fragthresh: user configured fragmentation threshold.
++ * fragthresh[NFIFO]: per-fifo fragmentation thresholds.
++ * RTSThresh: 802.11 dot11RTSThreshold.
++ * SRL: 802.11 dot11ShortRetryLimit.
++ * LRL: 802.11 dot11LongRetryLimit.
++ * SFBL: Short Frame Rate Fallback Limit.
++ * LFBL: Long Frame Rate Fallback Limit.
++ * shortslot: currently using 11g ShortSlot timing.
++ * shortslot_override: 11g ShortSlot override.
++ * include_legacy_erp: include Legacy ERP info elt ID 47 as well as g ID 42.
++ * PLCPHdr_override: 802.11b Preamble Type override.
++ * stf:
++ * bcn_rspec: save bcn ratespec purpose.
++ * tempsense_lasttime;
++ * tx_duty_cycle_ofdm: maximum allowed duty cycle for OFDM.
++ * tx_duty_cycle_cck: maximum allowed duty cycle for CCK.
++ * pkt_queue: txq for transmit packets.
++ * wiphy:
++ * pri_scb: primary Station Control Block
++ */
++struct brcms_c_info {
++	struct brcms_pub *pub;
++	struct brcms_info *wl;
++	struct brcms_hardware *hw;
++
++	/* clock */
++	u16 fastpwrup_dly;
++
++	/* interrupt */
++	u32 macintstatus;
++	u32 macintmask;
++	u32 defmacintmask;
++
++	bool clk;
++
++	/* multiband */
++	struct brcms_core *core;
++	struct brcms_band *band;
++	struct brcms_core *corestate;
++	struct brcms_band *bandstate[MAXBANDS];
++
++	/* packet queue */
++	uint qvalid;
++
++	struct ampdu_info *ampdu;
++	struct antsel_info *asi;
++	struct brcms_cm_info *cmi;
++
++	u16 vendorid;
++	u16 deviceid;
++	uint ucode_rev;
++
++	u8 perm_etheraddr[ETH_ALEN];
++
++	bool bandlocked;
++	bool bandinit_pending;
++
++	bool radio_monitor;
++	bool going_down;
++
++	struct brcms_timer *wdtimer;
++	struct brcms_timer *radio_timer;
++
++	/* promiscuous */
++	uint filter_flags;
++
++	/* driver feature */
++	bool _rifs;
++
++	/* AP-STA synchronization, power save */
++	u8 bcn_li_bcn;
++	u8 bcn_li_dtim;
++
++	bool WDarmed;
++	u32 WDlast;
++
++	/* WME */
++	u16 edcf_txop[IEEE80211_NUM_ACS];
++
++	u16 wme_retries[IEEE80211_NUM_ACS];
++	u16 tx_prec_map;
++	u16 fifo2prec_map[NFIFO];
++
++	struct brcms_bss_cfg *bsscfg;
++
++	/* tx queue */
++	struct brcms_txq_info *tx_queues;
++
++	struct modulecb *modulecb;
++
++	u8 mimoft;
++	s8 cck_40txbw;
++	s8 ofdm_40txbw;
++	s8 mimo_40txbw;
++
++	struct brcms_bss_info *default_bss;
++
++	u16 mc_fid_counter;
++
++	char country_default[BRCM_CNTRY_BUF_SZ];
++	char autocountry_default[BRCM_CNTRY_BUF_SZ];
++	u16 prb_resp_timeout;
++
++	u16 home_chanspec;
++
++	/* PHY parameters */
++	u16 chanspec;
++	u16 usr_fragthresh;
++	u16 fragthresh[NFIFO];
++	u16 RTSThresh;
++	u16 SRL;
++	u16 LRL;
++	u16 SFBL;
++	u16 LFBL;
++
++	/* network config */
++	bool shortslot;
++	s8 shortslot_override;
++	bool include_legacy_erp;
++
++	struct brcms_protection *protection;
++	s8 PLCPHdr_override;
++
++	struct brcms_stf *stf;
++
++	u32 bcn_rspec;
++
++	uint tempsense_lasttime;
++
++	u16 tx_duty_cycle_ofdm;
++	u16 tx_duty_cycle_cck;
++
++	struct brcms_txq_info *pkt_queue;
++	struct wiphy *wiphy;
++	struct scb pri_scb;
++};
++
++/* antsel module specific state */
++struct antsel_info {
++	struct brcms_c_info *wlc;	/* pointer to main wlc structure */
++	struct brcms_pub *pub;		/* pointer to public fn */
++	u8 antsel_type;	/* Type of boardlevel mimo antenna switch-logic
++				 * 0 = N/A, 1 = 2x4 board, 2 = 2x3 CB2 board
++				 */
++	u8 antsel_antswitch;	/* board level antenna switch type */
++	bool antsel_avail;	/* Ant selection availability (SROM based) */
++	struct brcms_antselcfg antcfg_11n; /* antenna configuration */
++	struct brcms_antselcfg antcfg_cur; /* current antenna config (auto) */
++};
++
++/*
++ * BSS configuration state
++ *
++ * wlc: wlc to which this bsscfg belongs to.
++ * up: is this configuration up operational
++ * enable: is this configuration enabled
++ * associated: is BSS in ASSOCIATED state
++ * BSS: infraustructure or adhoc
++ * SSID_len: the length of SSID
++ * SSID: SSID string
++ *
++ *
++ * BSSID: BSSID (associated)
++ * cur_etheraddr: h/w address
++ * flags: BSSCFG flags; see below
++ *
++ * current_bss: BSS parms in ASSOCIATED state
++ *
++ *
++ * ID: 'unique' ID of this bsscfg, assigned at bsscfg allocation
++ */
++struct brcms_bss_cfg {
++	struct brcms_c_info *wlc;
++	bool up;
++	bool enable;
++	bool associated;
++	bool BSS;
++	u8 SSID_len;
++	u8 SSID[IEEE80211_MAX_SSID_LEN];
++	u8 BSSID[ETH_ALEN];
++	u8 cur_etheraddr[ETH_ALEN];
++	struct brcms_bss_info *current_bss;
++};
++
++extern void brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo,
++			   struct sk_buff *p,
++			   bool commit, s8 txpktpend);
++extern void brcms_c_txfifo_complete(struct brcms_c_info *wlc, uint fifo,
++				    s8 txpktpend);
++extern void brcms_c_txq_enq(struct brcms_c_info *wlc, struct scb *scb,
++			    struct sk_buff *sdu, uint prec);
++extern void brcms_c_print_txstatus(struct tx_status *txs);
++extern int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo,
++		   uint *blocks);
++
++#if defined(DEBUG)
++extern void brcms_c_print_txdesc(struct d11txh *txh);
++#else
++static inline void brcms_c_print_txdesc(struct d11txh *txh)
++{
++}
++#endif
++
++extern int brcms_c_set_gmode(struct brcms_c_info *wlc, u8 gmode, bool config);
++extern void brcms_c_mac_promisc(struct brcms_c_info *wlc, uint filter_flags);
++extern void brcms_c_send_q(struct brcms_c_info *wlc);
++extern int brcms_c_prep_pdu(struct brcms_c_info *wlc, struct sk_buff *pdu,
++			    uint *fifo);
++extern u16 brcms_c_calc_lsig_len(struct brcms_c_info *wlc, u32 ratespec,
++				uint mac_len);
++extern u32 brcms_c_rspec_to_rts_rspec(struct brcms_c_info *wlc,
++					     u32 rspec,
++					     bool use_rspec, u16 mimo_ctlchbw);
++extern u16 brcms_c_compute_rtscts_dur(struct brcms_c_info *wlc, bool cts_only,
++				      u32 rts_rate,
++				      u32 frame_rate,
++				      u8 rts_preamble_type,
++				      u8 frame_preamble_type, uint frame_len,
++				      bool ba);
++extern void brcms_c_inval_dma_pkts(struct brcms_hardware *hw,
++			       struct ieee80211_sta *sta,
++			       void (*dma_callback_fn));
++extern void brcms_c_update_beacon(struct brcms_c_info *wlc);
++extern void brcms_c_update_probe_resp(struct brcms_c_info *wlc, bool suspend);
++extern int brcms_c_set_nmode(struct brcms_c_info *wlc);
++extern void brcms_c_beacon_phytxctl_txant_upd(struct brcms_c_info *wlc,
++					  u32 bcn_rate);
++extern void brcms_b_antsel_type_set(struct brcms_hardware *wlc_hw,
++				     u8 antsel_type);
++extern void brcms_b_set_chanspec(struct brcms_hardware *wlc_hw,
++				  u16 chanspec,
++				  bool mute, struct txpwr_limits *txpwr);
++extern void brcms_b_write_shm(struct brcms_hardware *wlc_hw, uint offset,
++			      u16 v);
++extern u16 brcms_b_read_shm(struct brcms_hardware *wlc_hw, uint offset);
++extern void brcms_b_mhf(struct brcms_hardware *wlc_hw, u8 idx, u16 mask,
++			u16 val, int bands);
++extern void brcms_b_corereset(struct brcms_hardware *wlc_hw, u32 flags);
++extern void brcms_b_mctrl(struct brcms_hardware *wlc_hw, u32 mask, u32 val);
++extern void brcms_b_phy_reset(struct brcms_hardware *wlc_hw);
++extern void brcms_b_bw_set(struct brcms_hardware *wlc_hw, u16 bw);
++extern void brcms_b_core_phypll_reset(struct brcms_hardware *wlc_hw);
++extern void brcms_c_ucode_wake_override_set(struct brcms_hardware *wlc_hw,
++					u32 override_bit);
++extern void brcms_c_ucode_wake_override_clear(struct brcms_hardware *wlc_hw,
++					  u32 override_bit);
++extern void brcms_b_write_template_ram(struct brcms_hardware *wlc_hw,
++				       int offset, int len, void *buf);
++extern u16 brcms_b_rate_shm_offset(struct brcms_hardware *wlc_hw, u8 rate);
++extern void brcms_b_copyto_objmem(struct brcms_hardware *wlc_hw,
++				   uint offset, const void *buf, int len,
++				   u32 sel);
++extern void brcms_b_copyfrom_objmem(struct brcms_hardware *wlc_hw, uint offset,
++				     void *buf, int len, u32 sel);
++extern void brcms_b_switch_macfreq(struct brcms_hardware *wlc_hw, u8 spurmode);
++extern u16 brcms_b_get_txant(struct brcms_hardware *wlc_hw);
++extern void brcms_b_phyclk_fgc(struct brcms_hardware *wlc_hw, bool clk);
++extern void brcms_b_macphyclk_set(struct brcms_hardware *wlc_hw, bool clk);
++extern void brcms_b_core_phypll_ctl(struct brcms_hardware *wlc_hw, bool on);
++extern void brcms_b_txant_set(struct brcms_hardware *wlc_hw, u16 phytxant);
++extern void brcms_b_band_stf_ss_set(struct brcms_hardware *wlc_hw,
++				    u8 stf_mode);
++extern void brcms_c_init_scb(struct scb *scb);
++
++#endif				/* _BRCM_MAIN_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c
+new file mode 100644
+index 0000000..264f8c4
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c
+@@ -0,0 +1,2961 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++#include <linux/kernel.h>
++#include <linux/delay.h>
++#include <linux/bitops.h>
++
++#include <brcm_hw_ids.h>
++#include <chipcommon.h>
++#include <aiutils.h>
++#include <d11.h>
++#include <phy_shim.h>
++#include "phy_hal.h"
++#include "phy_int.h"
++#include "phy_radio.h"
++#include "phy_lcn.h"
++#include "phyreg_n.h"
++
++#define VALID_N_RADIO(radioid) ((radioid == BCM2055_ID) || \
++				 (radioid == BCM2056_ID) || \
++				 (radioid == BCM2057_ID))
++
++#define VALID_LCN_RADIO(radioid)	(radioid == BCM2064_ID)
++
++#define VALID_RADIO(pi, radioid)        ( \
++		(ISNPHY(pi) ? VALID_N_RADIO(radioid) : false) || \
++		(ISLCNPHY(pi) ? VALID_LCN_RADIO(radioid) : false))
++
++/* basic mux operation - can be optimized on several architectures */
++#define MUX(pred, true, false) ((pred) ? (true) : (false))
++
++/* modulo inc/dec - assumes x E [0, bound - 1] */
++#define MODINC(x, bound) MUX((x) == (bound) - 1, 0, (x) + 1)
++
++/* modulo inc/dec, bound = 2^k */
++#define MODDEC_POW2(x, bound) (((x) - 1) & ((bound) - 1))
++#define MODINC_POW2(x, bound) (((x) + 1) & ((bound) - 1))
++
++struct chan_info_basic {
++	u16 chan;
++	u16 freq;
++};
++
++static const struct chan_info_basic chan_info_all[] = {
++	{1, 2412},
++	{2, 2417},
++	{3, 2422},
++	{4, 2427},
++	{5, 2432},
++	{6, 2437},
++	{7, 2442},
++	{8, 2447},
++	{9, 2452},
++	{10, 2457},
++	{11, 2462},
++	{12, 2467},
++	{13, 2472},
++	{14, 2484},
++
++	{34, 5170},
++	{38, 5190},
++	{42, 5210},
++	{46, 5230},
++
++	{36, 5180},
++	{40, 5200},
++	{44, 5220},
++	{48, 5240},
++	{52, 5260},
++	{56, 5280},
++	{60, 5300},
++	{64, 5320},
++
++	{100, 5500},
++	{104, 5520},
++	{108, 5540},
++	{112, 5560},
++	{116, 5580},
++	{120, 5600},
++	{124, 5620},
++	{128, 5640},
++	{132, 5660},
++	{136, 5680},
++	{140, 5700},
++
++	{149, 5745},
++	{153, 5765},
++	{157, 5785},
++	{161, 5805},
++	{165, 5825},
++
++	{184, 4920},
++	{188, 4940},
++	{192, 4960},
++	{196, 4980},
++	{200, 5000},
++	{204, 5020},
++	{208, 5040},
++	{212, 5060},
++	{216, 5080}
++};
++
++static const u8 ofdm_rate_lookup[] = {
++
++	BRCM_RATE_48M,
++	BRCM_RATE_24M,
++	BRCM_RATE_12M,
++	BRCM_RATE_6M,
++	BRCM_RATE_54M,
++	BRCM_RATE_36M,
++	BRCM_RATE_18M,
++	BRCM_RATE_9M
++};
++
++#define PHY_WREG_LIMIT  24
++
++void wlc_phyreg_enter(struct brcms_phy_pub *pih)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++	wlapi_bmac_ucode_wake_override_phyreg_set(pi->sh->physhim);
++}
++
++void wlc_phyreg_exit(struct brcms_phy_pub *pih)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++	wlapi_bmac_ucode_wake_override_phyreg_clear(pi->sh->physhim);
++}
++
++void wlc_radioreg_enter(struct brcms_phy_pub *pih)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++	wlapi_bmac_mctrl(pi->sh->physhim, MCTL_LOCK_RADIO, MCTL_LOCK_RADIO);
++
++	udelay(10);
++}
++
++void wlc_radioreg_exit(struct brcms_phy_pub *pih)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	(void)bcma_read16(pi->d11core, D11REGOFFS(phyversion));
++	pi->phy_wreg = 0;
++	wlapi_bmac_mctrl(pi->sh->physhim, MCTL_LOCK_RADIO, 0);
++}
++
++u16 read_radio_reg(struct brcms_phy *pi, u16 addr)
++{
++	u16 data;
++
++	if ((addr == RADIO_IDCODE))
++		return 0xffff;
++
++	switch (pi->pubpi.phy_type) {
++	case PHY_TYPE_N:
++		if (!CONF_HAS(PHYTYPE, PHY_TYPE_N))
++			break;
++		if (NREV_GE(pi->pubpi.phy_rev, 7))
++			addr |= RADIO_2057_READ_OFF;
++		else
++			addr |= RADIO_2055_READ_OFF;
++		break;
++
++	case PHY_TYPE_LCN:
++		if (!CONF_HAS(PHYTYPE, PHY_TYPE_LCN))
++			break;
++		addr |= RADIO_2064_READ_OFF;
++		break;
++
++	default:
++		break;
++	}
++
++	if ((D11REV_GE(pi->sh->corerev, 24)) ||
++	    (D11REV_IS(pi->sh->corerev, 22)
++	     && (pi->pubpi.phy_type != PHY_TYPE_SSN))) {
++		bcma_wflush16(pi->d11core, D11REGOFFS(radioregaddr), addr);
++		data = bcma_read16(pi->d11core, D11REGOFFS(radioregdata));
++	} else {
++		bcma_wflush16(pi->d11core, D11REGOFFS(phy4waddr), addr);
++		data = bcma_read16(pi->d11core, D11REGOFFS(phy4wdatalo));
++	}
++	pi->phy_wreg = 0;
++
++	return data;
++}
++
++void write_radio_reg(struct brcms_phy *pi, u16 addr, u16 val)
++{
++	if ((D11REV_GE(pi->sh->corerev, 24)) ||
++	    (D11REV_IS(pi->sh->corerev, 22)
++	     && (pi->pubpi.phy_type != PHY_TYPE_SSN))) {
++
++		bcma_wflush16(pi->d11core, D11REGOFFS(radioregaddr), addr);
++		bcma_write16(pi->d11core, D11REGOFFS(radioregdata), val);
++	} else {
++		bcma_wflush16(pi->d11core, D11REGOFFS(phy4waddr), addr);
++		bcma_write16(pi->d11core, D11REGOFFS(phy4wdatalo), val);
++	}
++
++	if (++pi->phy_wreg >= pi->phy_wreg_limit) {
++		(void)bcma_read32(pi->d11core, D11REGOFFS(maccontrol));
++		pi->phy_wreg = 0;
++	}
++}
++
++static u32 read_radio_id(struct brcms_phy *pi)
++{
++	u32 id;
++
++	if (D11REV_GE(pi->sh->corerev, 24)) {
++		u32 b0, b1, b2;
++
++		bcma_wflush16(pi->d11core, D11REGOFFS(radioregaddr), 0);
++		b0 = (u32) bcma_read16(pi->d11core, D11REGOFFS(radioregdata));
++		bcma_wflush16(pi->d11core, D11REGOFFS(radioregaddr), 1);
++		b1 = (u32) bcma_read16(pi->d11core, D11REGOFFS(radioregdata));
++		bcma_wflush16(pi->d11core, D11REGOFFS(radioregaddr), 2);
++		b2 = (u32) bcma_read16(pi->d11core, D11REGOFFS(radioregdata));
++
++		id = ((b0 & 0xf) << 28) | (((b2 << 8) | b1) << 12) | ((b0 >> 4)
++								      & 0xf);
++	} else {
++		bcma_wflush16(pi->d11core, D11REGOFFS(phy4waddr), RADIO_IDCODE);
++		id = (u32) bcma_read16(pi->d11core, D11REGOFFS(phy4wdatalo));
++		id |= (u32) bcma_read16(pi->d11core,
++					D11REGOFFS(phy4wdatahi)) << 16;
++	}
++	pi->phy_wreg = 0;
++	return id;
++}
++
++void and_radio_reg(struct brcms_phy *pi, u16 addr, u16 val)
++{
++	u16 rval;
++
++	rval = read_radio_reg(pi, addr);
++	write_radio_reg(pi, addr, (rval & val));
++}
++
++void or_radio_reg(struct brcms_phy *pi, u16 addr, u16 val)
++{
++	u16 rval;
++
++	rval = read_radio_reg(pi, addr);
++	write_radio_reg(pi, addr, (rval | val));
++}
++
++void xor_radio_reg(struct brcms_phy *pi, u16 addr, u16 mask)
++{
++	u16 rval;
++
++	rval = read_radio_reg(pi, addr);
++	write_radio_reg(pi, addr, (rval ^ mask));
++}
++
++void mod_radio_reg(struct brcms_phy *pi, u16 addr, u16 mask, u16 val)
++{
++	u16 rval;
++
++	rval = read_radio_reg(pi, addr);
++	write_radio_reg(pi, addr, (rval & ~mask) | (val & mask));
++}
++
++void write_phy_channel_reg(struct brcms_phy *pi, uint val)
++{
++	bcma_write16(pi->d11core, D11REGOFFS(phychannel), val);
++}
++
++u16 read_phy_reg(struct brcms_phy *pi, u16 addr)
++{
++	bcma_wflush16(pi->d11core, D11REGOFFS(phyregaddr), addr);
++
++	pi->phy_wreg = 0;
++	return bcma_read16(pi->d11core, D11REGOFFS(phyregdata));
++}
++
++void write_phy_reg(struct brcms_phy *pi, u16 addr, u16 val)
++{
++#ifdef CONFIG_BCM47XX
++	bcma_wflush16(pi->d11core, D11REGOFFS(phyregaddr), addr);
++	bcma_write16(pi->d11core, D11REGOFFS(phyregdata), val);
++	if (addr == 0x72)
++		(void)bcma_read16(pi->d11core, D11REGOFFS(phyversion));
++#else
++	bcma_write32(pi->d11core, D11REGOFFS(phyregaddr), addr | (val << 16));
++	if (++pi->phy_wreg >= pi->phy_wreg_limit) {
++		pi->phy_wreg = 0;
++		(void)bcma_read16(pi->d11core, D11REGOFFS(phyversion));
++	}
++#endif
++}
++
++void and_phy_reg(struct brcms_phy *pi, u16 addr, u16 val)
++{
++	bcma_wflush16(pi->d11core, D11REGOFFS(phyregaddr), addr);
++	bcma_mask16(pi->d11core, D11REGOFFS(phyregdata), val);
++	pi->phy_wreg = 0;
++}
++
++void or_phy_reg(struct brcms_phy *pi, u16 addr, u16 val)
++{
++	bcma_wflush16(pi->d11core, D11REGOFFS(phyregaddr), addr);
++	bcma_set16(pi->d11core, D11REGOFFS(phyregdata), val);
++	pi->phy_wreg = 0;
++}
++
++void mod_phy_reg(struct brcms_phy *pi, u16 addr, u16 mask, u16 val)
++{
++	val &= mask;
++	bcma_wflush16(pi->d11core, D11REGOFFS(phyregaddr), addr);
++	bcma_maskset16(pi->d11core, D11REGOFFS(phyregdata), ~mask, val);
++	pi->phy_wreg = 0;
++}
++
++static void wlc_set_phy_uninitted(struct brcms_phy *pi)
++{
++	int i, j;
++
++	pi->initialized = false;
++
++	pi->tx_vos = 0xffff;
++	pi->nrssi_table_delta = 0x7fffffff;
++	pi->rc_cal = 0xffff;
++	pi->mintxbias = 0xffff;
++	pi->txpwridx = -1;
++	if (ISNPHY(pi)) {
++		pi->phy_spuravoid = SPURAVOID_DISABLE;
++
++		if (NREV_GE(pi->pubpi.phy_rev, 3)
++		    && NREV_LT(pi->pubpi.phy_rev, 7))
++			pi->phy_spuravoid = SPURAVOID_AUTO;
++
++		pi->nphy_papd_skip = 0;
++		pi->nphy_papd_epsilon_offset[0] = 0xf588;
++		pi->nphy_papd_epsilon_offset[1] = 0xf588;
++		pi->nphy_txpwr_idx[0] = 128;
++		pi->nphy_txpwr_idx[1] = 128;
++		pi->nphy_txpwrindex[0].index_internal = 40;
++		pi->nphy_txpwrindex[1].index_internal = 40;
++		pi->phy_pabias = 0;
++	} else {
++		pi->phy_spuravoid = SPURAVOID_AUTO;
++	}
++	pi->radiopwr = 0xffff;
++	for (i = 0; i < STATIC_NUM_RF; i++) {
++		for (j = 0; j < STATIC_NUM_BB; j++)
++			pi->stats_11b_txpower[i][j] = -1;
++	}
++}
++
++struct shared_phy *wlc_phy_shared_attach(struct shared_phy_params *shp)
++{
++	struct shared_phy *sh;
++
++	sh = kzalloc(sizeof(struct shared_phy), GFP_ATOMIC);
++	if (sh == NULL)
++		return NULL;
++
++	sh->sih = shp->sih;
++	sh->physhim = shp->physhim;
++	sh->unit = shp->unit;
++	sh->corerev = shp->corerev;
++
++	sh->vid = shp->vid;
++	sh->did = shp->did;
++	sh->chip = shp->chip;
++	sh->chiprev = shp->chiprev;
++	sh->chippkg = shp->chippkg;
++	sh->sromrev = shp->sromrev;
++	sh->boardtype = shp->boardtype;
++	sh->boardrev = shp->boardrev;
++	sh->boardflags = shp->boardflags;
++	sh->boardflags2 = shp->boardflags2;
++
++	sh->fast_timer = PHY_SW_TIMER_FAST;
++	sh->slow_timer = PHY_SW_TIMER_SLOW;
++	sh->glacial_timer = PHY_SW_TIMER_GLACIAL;
++
++	sh->rssi_mode = RSSI_ANT_MERGE_MAX;
++
++	return sh;
++}
++
++static void wlc_phy_timercb_phycal(struct brcms_phy *pi)
++{
++	uint delay = 5;
++
++	if (PHY_PERICAL_MPHASE_PENDING(pi)) {
++		if (!pi->sh->up) {
++			wlc_phy_cal_perical_mphase_reset(pi);
++			return;
++		}
++
++		if (SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi)) {
++
++			delay = 1000;
++			wlc_phy_cal_perical_mphase_restart(pi);
++		} else
++			wlc_phy_cal_perical_nphy_run(pi, PHY_PERICAL_AUTO);
++		wlapi_add_timer(pi->phycal_timer, delay, 0);
++		return;
++	}
++
++}
++
++static u32 wlc_phy_get_radio_ver(struct brcms_phy *pi)
++{
++	u32 ver;
++
++	ver = read_radio_id(pi);
++
++	return ver;
++}
++
++struct brcms_phy_pub *
++wlc_phy_attach(struct shared_phy *sh, struct bcma_device *d11core,
++	       int bandtype, struct wiphy *wiphy)
++{
++	struct brcms_phy *pi;
++	u32 sflags = 0;
++	uint phyversion;
++	u32 idcode;
++	int i;
++
++	if (D11REV_IS(sh->corerev, 4))
++		sflags = SISF_2G_PHY | SISF_5G_PHY;
++	else
++		sflags = bcma_aread32(d11core, BCMA_IOST);
++
++	if (bandtype == BRCM_BAND_5G) {
++		if ((sflags & (SISF_5G_PHY | SISF_DB_PHY)) == 0)
++			return NULL;
++	}
++
++	pi = sh->phy_head;
++	if ((sflags & SISF_DB_PHY) && pi) {
++		wlapi_bmac_corereset(pi->sh->physhim, pi->pubpi.coreflags);
++		pi->refcnt++;
++		return &pi->pubpi_ro;
++	}
++
++	pi = kzalloc(sizeof(struct brcms_phy), GFP_ATOMIC);
++	if (pi == NULL)
++		return NULL;
++	pi->wiphy = wiphy;
++	pi->d11core = d11core;
++	pi->sh = sh;
++	pi->phy_init_por = true;
++	pi->phy_wreg_limit = PHY_WREG_LIMIT;
++
++	pi->txpwr_percent = 100;
++
++	pi->do_initcal = true;
++
++	pi->phycal_tempdelta = 0;
++
++	if (bandtype == BRCM_BAND_2G && (sflags & SISF_2G_PHY))
++		pi->pubpi.coreflags = SICF_GMODE;
++
++	wlapi_bmac_corereset(pi->sh->physhim, pi->pubpi.coreflags);
++	phyversion = bcma_read16(pi->d11core, D11REGOFFS(phyversion));
++
++	pi->pubpi.phy_type = PHY_TYPE(phyversion);
++	pi->pubpi.phy_rev = phyversion & PV_PV_MASK;
++
++	if (pi->pubpi.phy_type == PHY_TYPE_LCNXN) {
++		pi->pubpi.phy_type = PHY_TYPE_N;
++		pi->pubpi.phy_rev += LCNXN_BASEREV;
++	}
++	pi->pubpi.phy_corenum = PHY_CORE_NUM_2;
++	pi->pubpi.ana_rev = (phyversion & PV_AV_MASK) >> PV_AV_SHIFT;
++
++	if (pi->pubpi.phy_type != PHY_TYPE_N &&
++	    pi->pubpi.phy_type != PHY_TYPE_LCN)
++		goto err;
++
++	if (bandtype == BRCM_BAND_5G) {
++		if (!ISNPHY(pi))
++			goto err;
++	} else if (!ISNPHY(pi) && !ISLCNPHY(pi)) {
++		goto err;
++	}
++
++	wlc_phy_anacore((struct brcms_phy_pub *) pi, ON);
++
++	idcode = wlc_phy_get_radio_ver(pi);
++	pi->pubpi.radioid =
++		(idcode & IDCODE_ID_MASK) >> IDCODE_ID_SHIFT;
++	pi->pubpi.radiorev =
++		(idcode & IDCODE_REV_MASK) >> IDCODE_REV_SHIFT;
++	pi->pubpi.radiover =
++		(idcode & IDCODE_VER_MASK) >> IDCODE_VER_SHIFT;
++	if (!VALID_RADIO(pi, pi->pubpi.radioid))
++		goto err;
++
++	wlc_phy_switch_radio((struct brcms_phy_pub *) pi, OFF);
++
++	wlc_set_phy_uninitted(pi);
++
++	pi->bw = WL_CHANSPEC_BW_20;
++	pi->radio_chanspec = (bandtype == BRCM_BAND_2G) ?
++			     ch20mhz_chspec(1) : ch20mhz_chspec(36);
++
++	pi->rxiq_samps = PHY_NOISE_SAMPLE_LOG_NUM_NPHY;
++	pi->rxiq_antsel = ANT_RX_DIV_DEF;
++
++	pi->watchdog_override = true;
++
++	pi->cal_type_override = PHY_PERICAL_AUTO;
++
++	pi->nphy_saved_noisevars.bufcount = 0;
++
++	if (ISNPHY(pi))
++		pi->min_txpower = PHY_TXPWR_MIN_NPHY;
++	else
++		pi->min_txpower = PHY_TXPWR_MIN;
++
++	pi->sh->phyrxchain = 0x3;
++
++	pi->rx2tx_biasentry = -1;
++
++	pi->phy_txcore_disable_temp = PHY_CHAIN_TX_DISABLE_TEMP;
++	pi->phy_txcore_enable_temp =
++		PHY_CHAIN_TX_DISABLE_TEMP - PHY_HYSTERESIS_DELTATEMP;
++	pi->phy_tempsense_offset = 0;
++	pi->phy_txcore_heatedup = false;
++
++	pi->nphy_lastcal_temp = -50;
++
++	pi->phynoise_polling = true;
++	if (ISNPHY(pi) || ISLCNPHY(pi))
++		pi->phynoise_polling = false;
++
++	for (i = 0; i < TXP_NUM_RATES; i++) {
++		pi->txpwr_limit[i] = BRCMS_TXPWR_MAX;
++		pi->txpwr_env_limit[i] = BRCMS_TXPWR_MAX;
++		pi->tx_user_target[i] = BRCMS_TXPWR_MAX;
++	}
++
++	pi->radiopwr_override = RADIOPWR_OVERRIDE_DEF;
++
++	pi->user_txpwr_at_rfport = false;
++
++	if (ISNPHY(pi)) {
++
++		pi->phycal_timer = wlapi_init_timer(pi->sh->physhim,
++						    wlc_phy_timercb_phycal,
++						    pi, "phycal");
++		if (!pi->phycal_timer)
++			goto err;
++
++		if (!wlc_phy_attach_nphy(pi))
++			goto err;
++
++	} else if (ISLCNPHY(pi)) {
++		if (!wlc_phy_attach_lcnphy(pi))
++			goto err;
++
++	}
++
++	pi->refcnt++;
++	pi->next = pi->sh->phy_head;
++	sh->phy_head = pi;
++
++	memcpy(&pi->pubpi_ro, &pi->pubpi, sizeof(struct brcms_phy_pub));
++
++	return &pi->pubpi_ro;
++
++err:
++	kfree(pi);
++	return NULL;
++}
++
++void wlc_phy_detach(struct brcms_phy_pub *pih)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	if (pih) {
++		if (--pi->refcnt)
++			return;
++
++		if (pi->phycal_timer) {
++			wlapi_free_timer(pi->phycal_timer);
++			pi->phycal_timer = NULL;
++		}
++
++		if (pi->sh->phy_head == pi)
++			pi->sh->phy_head = pi->next;
++		else if (pi->sh->phy_head->next == pi)
++			pi->sh->phy_head->next = NULL;
++
++		if (pi->pi_fptr.detach)
++			(pi->pi_fptr.detach)(pi);
++
++		kfree(pi);
++	}
++}
++
++bool
++wlc_phy_get_phyversion(struct brcms_phy_pub *pih, u16 *phytype, u16 *phyrev,
++		       u16 *radioid, u16 *radiover)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++	*phytype = (u16) pi->pubpi.phy_type;
++	*phyrev = (u16) pi->pubpi.phy_rev;
++	*radioid = pi->pubpi.radioid;
++	*radiover = pi->pubpi.radiorev;
++
++	return true;
++}
++
++bool wlc_phy_get_encore(struct brcms_phy_pub *pih)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++	return pi->pubpi.abgphy_encore;
++}
++
++u32 wlc_phy_get_coreflags(struct brcms_phy_pub *pih)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++	return pi->pubpi.coreflags;
++}
++
++void wlc_phy_anacore(struct brcms_phy_pub *pih, bool on)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	if (ISNPHY(pi)) {
++		if (on) {
++			if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++				write_phy_reg(pi, 0xa6, 0x0d);
++				write_phy_reg(pi, 0x8f, 0x0);
++				write_phy_reg(pi, 0xa7, 0x0d);
++				write_phy_reg(pi, 0xa5, 0x0);
++			} else {
++				write_phy_reg(pi, 0xa5, 0x0);
++			}
++		} else {
++			if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++				write_phy_reg(pi, 0x8f, 0x07ff);
++				write_phy_reg(pi, 0xa6, 0x0fd);
++				write_phy_reg(pi, 0xa5, 0x07ff);
++				write_phy_reg(pi, 0xa7, 0x0fd);
++			} else {
++				write_phy_reg(pi, 0xa5, 0x7fff);
++			}
++		}
++	} else if (ISLCNPHY(pi)) {
++		if (on) {
++			and_phy_reg(pi, 0x43b,
++				    ~((0x1 << 0) | (0x1 << 1) | (0x1 << 2)));
++		} else {
++			or_phy_reg(pi, 0x43c,
++				   (0x1 << 0) | (0x1 << 1) | (0x1 << 2));
++			or_phy_reg(pi, 0x43b,
++				   (0x1 << 0) | (0x1 << 1) | (0x1 << 2));
++		}
++	}
++}
++
++u32 wlc_phy_clk_bwbits(struct brcms_phy_pub *pih)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	u32 phy_bw_clkbits = 0;
++
++	if (pi && (ISNPHY(pi) || ISLCNPHY(pi))) {
++		switch (pi->bw) {
++		case WL_CHANSPEC_BW_10:
++			phy_bw_clkbits = SICF_BW10;
++			break;
++		case WL_CHANSPEC_BW_20:
++			phy_bw_clkbits = SICF_BW20;
++			break;
++		case WL_CHANSPEC_BW_40:
++			phy_bw_clkbits = SICF_BW40;
++			break;
++		default:
++			break;
++		}
++	}
++
++	return phy_bw_clkbits;
++}
++
++void wlc_phy_por_inform(struct brcms_phy_pub *ppi)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++
++	pi->phy_init_por = true;
++}
++
++void wlc_phy_edcrs_lock(struct brcms_phy_pub *pih, bool lock)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	pi->edcrs_threshold_lock = lock;
++
++	write_phy_reg(pi, 0x22c, 0x46b);
++	write_phy_reg(pi, 0x22d, 0x46b);
++	write_phy_reg(pi, 0x22e, 0x3c0);
++	write_phy_reg(pi, 0x22f, 0x3c0);
++}
++
++void wlc_phy_initcal_enable(struct brcms_phy_pub *pih, bool initcal)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	pi->do_initcal = initcal;
++}
++
++void wlc_phy_hw_clk_state_upd(struct brcms_phy_pub *pih, bool newstate)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	if (!pi || !pi->sh)
++		return;
++
++	pi->sh->clk = newstate;
++}
++
++void wlc_phy_hw_state_upd(struct brcms_phy_pub *pih, bool newstate)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	if (!pi || !pi->sh)
++		return;
++
++	pi->sh->up = newstate;
++}
++
++void wlc_phy_init(struct brcms_phy_pub *pih, u16 chanspec)
++{
++	u32 mc;
++	void (*phy_init)(struct brcms_phy *) = NULL;
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	if (pi->init_in_progress)
++		return;
++
++	pi->init_in_progress = true;
++
++	pi->radio_chanspec = chanspec;
++
++	mc = bcma_read32(pi->d11core, D11REGOFFS(maccontrol));
++	if (WARN(mc & MCTL_EN_MAC, "HW error MAC running on init"))
++		return;
++
++	if (!(pi->measure_hold & PHY_HOLD_FOR_SCAN))
++		pi->measure_hold |= PHY_HOLD_FOR_NOT_ASSOC;
++
++	if (WARN(!(bcma_aread32(pi->d11core, BCMA_IOST) & SISF_FCLKA),
++		 "HW error SISF_FCLKA\n"))
++		return;
++
++	phy_init = pi->pi_fptr.init;
++
++	if (phy_init == NULL)
++		return;
++
++	wlc_phy_anacore(pih, ON);
++
++	if (CHSPEC_BW(pi->radio_chanspec) != pi->bw)
++		wlapi_bmac_bw_set(pi->sh->physhim,
++				  CHSPEC_BW(pi->radio_chanspec));
++
++	pi->nphy_gain_boost = true;
++
++	wlc_phy_switch_radio((struct brcms_phy_pub *) pi, ON);
++
++	(*phy_init)(pi);
++
++	pi->phy_init_por = false;
++
++	if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12))
++		wlc_phy_do_dummy_tx(pi, true, OFF);
++
++	if (!(ISNPHY(pi)))
++		wlc_phy_txpower_update_shm(pi);
++
++	wlc_phy_ant_rxdiv_set((struct brcms_phy_pub *) pi, pi->sh->rx_antdiv);
++
++	pi->init_in_progress = false;
++}
++
++void wlc_phy_cal_init(struct brcms_phy_pub *pih)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++	void (*cal_init)(struct brcms_phy *) = NULL;
++
++	if (WARN((bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) &
++		  MCTL_EN_MAC) != 0, "HW error: MAC enabled during phy cal\n"))
++		return;
++
++	if (!pi->initialized) {
++		cal_init = pi->pi_fptr.calinit;
++		if (cal_init)
++			(*cal_init)(pi);
++
++		pi->initialized = true;
++	}
++}
++
++int wlc_phy_down(struct brcms_phy_pub *pih)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++	int callbacks = 0;
++
++	if (pi->phycal_timer
++	    && !wlapi_del_timer(pi->phycal_timer))
++		callbacks++;
++
++	pi->nphy_iqcal_chanspec_2G = 0;
++	pi->nphy_iqcal_chanspec_5G = 0;
++
++	return callbacks;
++}
++
++void
++wlc_phy_table_addr(struct brcms_phy *pi, uint tbl_id, uint tbl_offset,
++		   u16 tblAddr, u16 tblDataHi, u16 tblDataLo)
++{
++	write_phy_reg(pi, tblAddr, (tbl_id << 10) | tbl_offset);
++
++	pi->tbl_data_hi = tblDataHi;
++	pi->tbl_data_lo = tblDataLo;
++
++	if (pi->sh->chip == BCM43224_CHIP_ID &&
++	    pi->sh->chiprev == 1) {
++		pi->tbl_addr = tblAddr;
++		pi->tbl_save_id = tbl_id;
++		pi->tbl_save_offset = tbl_offset;
++	}
++}
++
++void wlc_phy_table_data_write(struct brcms_phy *pi, uint width, u32 val)
++{
++	if ((pi->sh->chip == BCM43224_CHIP_ID) &&
++	    (pi->sh->chiprev == 1) &&
++	    (pi->tbl_save_id == NPHY_TBL_ID_ANTSWCTRLLUT)) {
++		read_phy_reg(pi, pi->tbl_data_lo);
++
++		write_phy_reg(pi, pi->tbl_addr,
++			      (pi->tbl_save_id << 10) | pi->tbl_save_offset);
++		pi->tbl_save_offset++;
++	}
++
++	if (width == 32) {
++		write_phy_reg(pi, pi->tbl_data_hi, (u16) (val >> 16));
++		write_phy_reg(pi, pi->tbl_data_lo, (u16) val);
++	} else {
++		write_phy_reg(pi, pi->tbl_data_lo, (u16) val);
++	}
++}
++
++void
++wlc_phy_write_table(struct brcms_phy *pi, const struct phytbl_info *ptbl_info,
++		    u16 tblAddr, u16 tblDataHi, u16 tblDataLo)
++{
++	uint idx;
++	uint tbl_id = ptbl_info->tbl_id;
++	uint tbl_offset = ptbl_info->tbl_offset;
++	uint tbl_width = ptbl_info->tbl_width;
++	const u8 *ptbl_8b = (const u8 *)ptbl_info->tbl_ptr;
++	const u16 *ptbl_16b = (const u16 *)ptbl_info->tbl_ptr;
++	const u32 *ptbl_32b = (const u32 *)ptbl_info->tbl_ptr;
++
++	write_phy_reg(pi, tblAddr, (tbl_id << 10) | tbl_offset);
++
++	for (idx = 0; idx < ptbl_info->tbl_len; idx++) {
++
++		if ((pi->sh->chip == BCM43224_CHIP_ID) &&
++		    (pi->sh->chiprev == 1) &&
++		    (tbl_id == NPHY_TBL_ID_ANTSWCTRLLUT)) {
++			read_phy_reg(pi, tblDataLo);
++
++			write_phy_reg(pi, tblAddr,
++				      (tbl_id << 10) | (tbl_offset + idx));
++		}
++
++		if (tbl_width == 32) {
++			write_phy_reg(pi, tblDataHi,
++				      (u16) (ptbl_32b[idx] >> 16));
++			write_phy_reg(pi, tblDataLo, (u16) ptbl_32b[idx]);
++		} else if (tbl_width == 16) {
++			write_phy_reg(pi, tblDataLo, ptbl_16b[idx]);
++		} else {
++			write_phy_reg(pi, tblDataLo, ptbl_8b[idx]);
++		}
++	}
++}
++
++void
++wlc_phy_read_table(struct brcms_phy *pi, const struct phytbl_info *ptbl_info,
++		   u16 tblAddr, u16 tblDataHi, u16 tblDataLo)
++{
++	uint idx;
++	uint tbl_id = ptbl_info->tbl_id;
++	uint tbl_offset = ptbl_info->tbl_offset;
++	uint tbl_width = ptbl_info->tbl_width;
++	u8 *ptbl_8b = (u8 *)ptbl_info->tbl_ptr;
++	u16 *ptbl_16b = (u16 *)ptbl_info->tbl_ptr;
++	u32 *ptbl_32b = (u32 *)ptbl_info->tbl_ptr;
++
++	write_phy_reg(pi, tblAddr, (tbl_id << 10) | tbl_offset);
++
++	for (idx = 0; idx < ptbl_info->tbl_len; idx++) {
++
++		if ((pi->sh->chip == BCM43224_CHIP_ID) &&
++		    (pi->sh->chiprev == 1)) {
++			(void)read_phy_reg(pi, tblDataLo);
++
++			write_phy_reg(pi, tblAddr,
++				      (tbl_id << 10) | (tbl_offset + idx));
++		}
++
++		if (tbl_width == 32) {
++			ptbl_32b[idx] = read_phy_reg(pi, tblDataLo);
++			ptbl_32b[idx] |= (read_phy_reg(pi, tblDataHi) << 16);
++		} else if (tbl_width == 16) {
++			ptbl_16b[idx] = read_phy_reg(pi, tblDataLo);
++		} else {
++			ptbl_8b[idx] = (u8) read_phy_reg(pi, tblDataLo);
++		}
++	}
++}
++
++uint
++wlc_phy_init_radio_regs_allbands(struct brcms_phy *pi,
++				 struct radio_20xx_regs *radioregs)
++{
++	uint i = 0;
++
++	do {
++		if (radioregs[i].do_init)
++			write_radio_reg(pi, radioregs[i].address,
++					(u16) radioregs[i].init);
++
++		i++;
++	} while (radioregs[i].address != 0xffff);
++
++	return i;
++}
++
++uint
++wlc_phy_init_radio_regs(struct brcms_phy *pi,
++			const struct radio_regs *radioregs,
++			u16 core_offset)
++{
++	uint i = 0;
++	uint count = 0;
++
++	do {
++		if (CHSPEC_IS5G(pi->radio_chanspec)) {
++			if (radioregs[i].do_init_a) {
++				write_radio_reg(pi,
++						radioregs[i].
++						address | core_offset,
++						(u16) radioregs[i].init_a);
++				if (ISNPHY(pi) && (++count % 4 == 0))
++					BRCMS_PHY_WAR_PR51571(pi);
++			}
++		} else {
++			if (radioregs[i].do_init_g) {
++				write_radio_reg(pi,
++						radioregs[i].
++						address | core_offset,
++						(u16) radioregs[i].init_g);
++				if (ISNPHY(pi) && (++count % 4 == 0))
++					BRCMS_PHY_WAR_PR51571(pi);
++			}
++		}
++
++		i++;
++	} while (radioregs[i].address != 0xffff);
++
++	return i;
++}
++
++void wlc_phy_do_dummy_tx(struct brcms_phy *pi, bool ofdm, bool pa_on)
++{
++#define DUMMY_PKT_LEN   20
++	struct bcma_device *core = pi->d11core;
++	int i, count;
++	u8 ofdmpkt[DUMMY_PKT_LEN] = {
++		0xcc, 0x01, 0x02, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00,
++		0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00
++	};
++	u8 cckpkt[DUMMY_PKT_LEN] = {
++		0x6e, 0x84, 0x0b, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00,
++		0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00
++	};
++	u32 *dummypkt;
++
++	dummypkt = (u32 *) (ofdm ? ofdmpkt : cckpkt);
++	wlapi_bmac_write_template_ram(pi->sh->physhim, 0, DUMMY_PKT_LEN,
++				      dummypkt);
++
++	bcma_write16(core, D11REGOFFS(xmtsel), 0);
++
++	if (D11REV_GE(pi->sh->corerev, 11))
++		bcma_write16(core, D11REGOFFS(wepctl), 0x100);
++	else
++		bcma_write16(core, D11REGOFFS(wepctl), 0);
++
++	bcma_write16(core, D11REGOFFS(txe_phyctl),
++		     (ofdm ? 1 : 0) | PHY_TXC_ANT_0);
++	if (ISNPHY(pi) || ISLCNPHY(pi))
++		bcma_write16(core, D11REGOFFS(txe_phyctl1), 0x1A02);
++
++	bcma_write16(core, D11REGOFFS(txe_wm_0), 0);
++	bcma_write16(core, D11REGOFFS(txe_wm_1), 0);
++
++	bcma_write16(core, D11REGOFFS(xmttplatetxptr), 0);
++	bcma_write16(core, D11REGOFFS(xmttxcnt), DUMMY_PKT_LEN);
++
++	bcma_write16(core, D11REGOFFS(xmtsel),
++		     ((8 << 8) | (1 << 5) | (1 << 2) | 2));
++
++	bcma_write16(core, D11REGOFFS(txe_ctl), 0);
++
++	if (!pa_on) {
++		if (ISNPHY(pi))
++			wlc_phy_pa_override_nphy(pi, OFF);
++	}
++
++	if (ISNPHY(pi) || ISLCNPHY(pi))
++		bcma_write16(core, D11REGOFFS(txe_aux), 0xD0);
++	else
++		bcma_write16(core, D11REGOFFS(txe_aux), ((1 << 5) | (1 << 4)));
++
++	(void)bcma_read16(core, D11REGOFFS(txe_aux));
++
++	i = 0;
++	count = ofdm ? 30 : 250;
++	while ((i++ < count)
++	       && (bcma_read16(core, D11REGOFFS(txe_status)) & (1 << 7)))
++		udelay(10);
++
++	i = 0;
++
++	while ((i++ < 10) &&
++	       ((bcma_read16(core, D11REGOFFS(txe_status)) & (1 << 10)) == 0))
++		udelay(10);
++
++	i = 0;
++
++	while ((i++ < 10) &&
++	       ((bcma_read16(core, D11REGOFFS(ifsstat)) & (1 << 8))))
++		udelay(10);
++
++	if (!pa_on) {
++		if (ISNPHY(pi))
++			wlc_phy_pa_override_nphy(pi, ON);
++	}
++}
++
++void wlc_phy_hold_upd(struct brcms_phy_pub *pih, u32 id, bool set)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	if (set)
++		mboolset(pi->measure_hold, id);
++	else
++		mboolclr(pi->measure_hold, id);
++
++	return;
++}
++
++void wlc_phy_mute_upd(struct brcms_phy_pub *pih, bool mute, u32 flags)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	if (mute)
++		mboolset(pi->measure_hold, PHY_HOLD_FOR_MUTE);
++	else
++		mboolclr(pi->measure_hold, PHY_HOLD_FOR_MUTE);
++
++	if (!mute && (flags & PHY_MUTE_FOR_PREISM))
++		pi->nphy_perical_last = pi->sh->now - pi->sh->glacial_timer;
++	return;
++}
++
++void wlc_phy_clear_tssi(struct brcms_phy_pub *pih)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	if (ISNPHY(pi)) {
++		return;
++	} else {
++		wlapi_bmac_write_shm(pi->sh->physhim, M_B_TSSI_0, NULL_TSSI_W);
++		wlapi_bmac_write_shm(pi->sh->physhim, M_B_TSSI_1, NULL_TSSI_W);
++		wlapi_bmac_write_shm(pi->sh->physhim, M_G_TSSI_0, NULL_TSSI_W);
++		wlapi_bmac_write_shm(pi->sh->physhim, M_G_TSSI_1, NULL_TSSI_W);
++	}
++}
++
++static bool wlc_phy_cal_txpower_recalc_sw(struct brcms_phy *pi)
++{
++	return false;
++}
++
++void wlc_phy_switch_radio(struct brcms_phy_pub *pih, bool on)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++	(void)bcma_read32(pi->d11core, D11REGOFFS(maccontrol));
++
++	if (ISNPHY(pi)) {
++		wlc_phy_switch_radio_nphy(pi, on);
++	} else if (ISLCNPHY(pi)) {
++		if (on) {
++			and_phy_reg(pi, 0x44c,
++				    ~((0x1 << 8) |
++				      (0x1 << 9) |
++				      (0x1 << 10) | (0x1 << 11) | (0x1 << 12)));
++			and_phy_reg(pi, 0x4b0, ~((0x1 << 3) | (0x1 << 11)));
++			and_phy_reg(pi, 0x4f9, ~(0x1 << 3));
++		} else {
++			and_phy_reg(pi, 0x44d,
++				    ~((0x1 << 10) |
++				      (0x1 << 11) |
++				      (0x1 << 12) | (0x1 << 13) | (0x1 << 14)));
++			or_phy_reg(pi, 0x44c,
++				   (0x1 << 8) |
++				   (0x1 << 9) |
++				   (0x1 << 10) | (0x1 << 11) | (0x1 << 12));
++
++			and_phy_reg(pi, 0x4b7, ~((0x7f << 8)));
++			and_phy_reg(pi, 0x4b1, ~((0x1 << 13)));
++			or_phy_reg(pi, 0x4b0, (0x1 << 3) | (0x1 << 11));
++			and_phy_reg(pi, 0x4fa, ~((0x1 << 3)));
++			or_phy_reg(pi, 0x4f9, (0x1 << 3));
++		}
++	}
++}
++
++u16 wlc_phy_bw_state_get(struct brcms_phy_pub *ppi)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++
++	return pi->bw;
++}
++
++void wlc_phy_bw_state_set(struct brcms_phy_pub *ppi, u16 bw)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++
++	pi->bw = bw;
++}
++
++void wlc_phy_chanspec_radio_set(struct brcms_phy_pub *ppi, u16 newch)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++	pi->radio_chanspec = newch;
++
++}
++
++u16 wlc_phy_chanspec_get(struct brcms_phy_pub *ppi)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++
++	return pi->radio_chanspec;
++}
++
++void wlc_phy_chanspec_set(struct brcms_phy_pub *ppi, u16 chanspec)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++	u16 m_cur_channel;
++	void (*chanspec_set)(struct brcms_phy *, u16) = NULL;
++	m_cur_channel = CHSPEC_CHANNEL(chanspec);
++	if (CHSPEC_IS5G(chanspec))
++		m_cur_channel |= D11_CURCHANNEL_5G;
++	if (CHSPEC_IS40(chanspec))
++		m_cur_channel |= D11_CURCHANNEL_40;
++	wlapi_bmac_write_shm(pi->sh->physhim, M_CURCHANNEL, m_cur_channel);
++
++	chanspec_set = pi->pi_fptr.chanset;
++	if (chanspec_set)
++		(*chanspec_set)(pi, chanspec);
++
++}
++
++int wlc_phy_chanspec_freq2bandrange_lpssn(uint freq)
++{
++	int range = -1;
++
++	if (freq < 2500)
++		range = WL_CHAN_FREQ_RANGE_2G;
++	else if (freq <= 5320)
++		range = WL_CHAN_FREQ_RANGE_5GL;
++	else if (freq <= 5700)
++		range = WL_CHAN_FREQ_RANGE_5GM;
++	else
++		range = WL_CHAN_FREQ_RANGE_5GH;
++
++	return range;
++}
++
++int wlc_phy_chanspec_bandrange_get(struct brcms_phy *pi, u16 chanspec)
++{
++	int range = -1;
++	uint channel = CHSPEC_CHANNEL(chanspec);
++	uint freq = wlc_phy_channel2freq(channel);
++
++	if (ISNPHY(pi))
++		range = wlc_phy_get_chan_freq_range_nphy(pi, channel);
++	else if (ISLCNPHY(pi))
++		range = wlc_phy_chanspec_freq2bandrange_lpssn(freq);
++
++	return range;
++}
++
++void wlc_phy_chanspec_ch14_widefilter_set(struct brcms_phy_pub *ppi,
++					  bool wide_filter)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++
++	pi->channel_14_wide_filter = wide_filter;
++
++}
++
++int wlc_phy_channel2freq(uint channel)
++{
++	uint i;
++
++	for (i = 0; i < ARRAY_SIZE(chan_info_all); i++)
++		if (chan_info_all[i].chan == channel)
++			return chan_info_all[i].freq;
++	return 0;
++}
++
++void
++wlc_phy_chanspec_band_validch(struct brcms_phy_pub *ppi, uint band,
++			      struct brcms_chanvec *channels)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++	uint i;
++	uint channel;
++
++	memset(channels, 0, sizeof(struct brcms_chanvec));
++
++	for (i = 0; i < ARRAY_SIZE(chan_info_all); i++) {
++		channel = chan_info_all[i].chan;
++
++		if ((pi->a_band_high_disable) && (channel >= FIRST_REF5_CHANNUM)
++		    && (channel <= LAST_REF5_CHANNUM))
++			continue;
++
++		if ((band == BRCM_BAND_2G && channel <= CH_MAX_2G_CHANNEL) ||
++		    (band == BRCM_BAND_5G && channel > CH_MAX_2G_CHANNEL))
++			setbit(channels->vec, channel);
++	}
++}
++
++u16 wlc_phy_chanspec_band_firstch(struct brcms_phy_pub *ppi, uint band)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++	uint i;
++	uint channel;
++	u16 chspec;
++
++	for (i = 0; i < ARRAY_SIZE(chan_info_all); i++) {
++		channel = chan_info_all[i].chan;
++
++		if (ISNPHY(pi) && pi->bw == WL_CHANSPEC_BW_40) {
++			uint j;
++
++			for (j = 0; j < ARRAY_SIZE(chan_info_all); j++) {
++				if (chan_info_all[j].chan ==
++				    channel + CH_10MHZ_APART)
++					break;
++			}
++
++			if (j == ARRAY_SIZE(chan_info_all))
++				continue;
++
++			channel = upper_20_sb(channel);
++			chspec =  channel | WL_CHANSPEC_BW_40 |
++				  WL_CHANSPEC_CTL_SB_LOWER;
++			if (band == BRCM_BAND_2G)
++				chspec |= WL_CHANSPEC_BAND_2G;
++			else
++				chspec |= WL_CHANSPEC_BAND_5G;
++		} else
++			chspec = ch20mhz_chspec(channel);
++
++		if ((pi->a_band_high_disable) && (channel >= FIRST_REF5_CHANNUM)
++		    && (channel <= LAST_REF5_CHANNUM))
++			continue;
++
++		if ((band == BRCM_BAND_2G && channel <= CH_MAX_2G_CHANNEL) ||
++		    (band == BRCM_BAND_5G && channel > CH_MAX_2G_CHANNEL))
++			return chspec;
++	}
++
++	return (u16) INVCHANSPEC;
++}
++
++int wlc_phy_txpower_get(struct brcms_phy_pub *ppi, uint *qdbm, bool *override)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++
++	*qdbm = pi->tx_user_target[0];
++	if (override != NULL)
++		*override = pi->txpwroverride;
++	return 0;
++}
++
++void wlc_phy_txpower_target_set(struct brcms_phy_pub *ppi,
++				struct txpwr_limits *txpwr)
++{
++	bool mac_enabled = false;
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++
++	memcpy(&pi->tx_user_target[TXP_FIRST_CCK],
++	       &txpwr->cck[0], BRCMS_NUM_RATES_CCK);
++
++	memcpy(&pi->tx_user_target[TXP_FIRST_OFDM],
++	       &txpwr->ofdm[0], BRCMS_NUM_RATES_OFDM);
++	memcpy(&pi->tx_user_target[TXP_FIRST_OFDM_20_CDD],
++	       &txpwr->ofdm_cdd[0], BRCMS_NUM_RATES_OFDM);
++
++	memcpy(&pi->tx_user_target[TXP_FIRST_OFDM_40_SISO],
++	       &txpwr->ofdm_40_siso[0], BRCMS_NUM_RATES_OFDM);
++	memcpy(&pi->tx_user_target[TXP_FIRST_OFDM_40_CDD],
++	       &txpwr->ofdm_40_cdd[0], BRCMS_NUM_RATES_OFDM);
++
++	memcpy(&pi->tx_user_target[TXP_FIRST_MCS_20_SISO],
++	       &txpwr->mcs_20_siso[0], BRCMS_NUM_RATES_MCS_1_STREAM);
++	memcpy(&pi->tx_user_target[TXP_FIRST_MCS_20_CDD],
++	       &txpwr->mcs_20_cdd[0], BRCMS_NUM_RATES_MCS_1_STREAM);
++	memcpy(&pi->tx_user_target[TXP_FIRST_MCS_20_STBC],
++	       &txpwr->mcs_20_stbc[0], BRCMS_NUM_RATES_MCS_1_STREAM);
++	memcpy(&pi->tx_user_target[TXP_FIRST_MCS_20_SDM],
++	       &txpwr->mcs_20_mimo[0], BRCMS_NUM_RATES_MCS_2_STREAM);
++
++	memcpy(&pi->tx_user_target[TXP_FIRST_MCS_40_SISO],
++	       &txpwr->mcs_40_siso[0], BRCMS_NUM_RATES_MCS_1_STREAM);
++	memcpy(&pi->tx_user_target[TXP_FIRST_MCS_40_CDD],
++	       &txpwr->mcs_40_cdd[0], BRCMS_NUM_RATES_MCS_1_STREAM);
++	memcpy(&pi->tx_user_target[TXP_FIRST_MCS_40_STBC],
++	       &txpwr->mcs_40_stbc[0], BRCMS_NUM_RATES_MCS_1_STREAM);
++	memcpy(&pi->tx_user_target[TXP_FIRST_MCS_40_SDM],
++	       &txpwr->mcs_40_mimo[0], BRCMS_NUM_RATES_MCS_2_STREAM);
++
++	if (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) & MCTL_EN_MAC)
++		mac_enabled = true;
++
++	if (mac_enabled)
++		wlapi_suspend_mac_and_wait(pi->sh->physhim);
++
++	wlc_phy_txpower_recalc_target(pi);
++	wlc_phy_cal_txpower_recalc_sw(pi);
++
++	if (mac_enabled)
++		wlapi_enable_mac(pi->sh->physhim);
++}
++
++int wlc_phy_txpower_set(struct brcms_phy_pub *ppi, uint qdbm, bool override)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++	int i;
++
++	if (qdbm > 127)
++		return -EINVAL;
++
++	for (i = 0; i < TXP_NUM_RATES; i++)
++		pi->tx_user_target[i] = (u8) qdbm;
++
++	pi->txpwroverride = false;
++
++	if (pi->sh->up) {
++		if (!SCAN_INPROG_PHY(pi)) {
++			bool suspend;
++
++			suspend = (0 == (bcma_read32(pi->d11core,
++						     D11REGOFFS(maccontrol)) &
++					 MCTL_EN_MAC));
++
++			if (!suspend)
++				wlapi_suspend_mac_and_wait(pi->sh->physhim);
++
++			wlc_phy_txpower_recalc_target(pi);
++			wlc_phy_cal_txpower_recalc_sw(pi);
++
++			if (!suspend)
++				wlapi_enable_mac(pi->sh->physhim);
++		}
++	}
++	return 0;
++}
++
++void
++wlc_phy_txpower_sromlimit(struct brcms_phy_pub *ppi, uint channel, u8 *min_pwr,
++			  u8 *max_pwr, int txp_rate_idx)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++	uint i;
++
++	*min_pwr = pi->min_txpower * BRCMS_TXPWR_DB_FACTOR;
++
++	if (ISNPHY(pi)) {
++		if (txp_rate_idx < 0)
++			txp_rate_idx = TXP_FIRST_CCK;
++		wlc_phy_txpower_sromlimit_get_nphy(pi, channel, max_pwr,
++						   (u8) txp_rate_idx);
++
++	} else if ((channel <= CH_MAX_2G_CHANNEL)) {
++		if (txp_rate_idx < 0)
++			txp_rate_idx = TXP_FIRST_CCK;
++		*max_pwr = pi->tx_srom_max_rate_2g[txp_rate_idx];
++	} else {
++
++		*max_pwr = BRCMS_TXPWR_MAX;
++
++		if (txp_rate_idx < 0)
++			txp_rate_idx = TXP_FIRST_OFDM;
++
++		for (i = 0; i < ARRAY_SIZE(chan_info_all); i++) {
++			if (channel == chan_info_all[i].chan)
++				break;
++		}
++
++		if (pi->hwtxpwr) {
++			*max_pwr = pi->hwtxpwr[i];
++		} else {
++
++			if ((i >= FIRST_MID_5G_CHAN) && (i <= LAST_MID_5G_CHAN))
++				*max_pwr =
++				    pi->tx_srom_max_rate_5g_mid[txp_rate_idx];
++			if ((i >= FIRST_HIGH_5G_CHAN)
++			    && (i <= LAST_HIGH_5G_CHAN))
++				*max_pwr =
++				    pi->tx_srom_max_rate_5g_hi[txp_rate_idx];
++			if ((i >= FIRST_LOW_5G_CHAN) && (i <= LAST_LOW_5G_CHAN))
++				*max_pwr =
++				    pi->tx_srom_max_rate_5g_low[txp_rate_idx];
++		}
++	}
++}
++
++void
++wlc_phy_txpower_sromlimit_max_get(struct brcms_phy_pub *ppi, uint chan,
++				  u8 *max_txpwr, u8 *min_txpwr)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++	u8 tx_pwr_max = 0;
++	u8 tx_pwr_min = 255;
++	u8 max_num_rate;
++	u8 maxtxpwr, mintxpwr, rate, pactrl;
++
++	pactrl = 0;
++
++	max_num_rate = ISNPHY(pi) ? TXP_NUM_RATES :
++		       ISLCNPHY(pi) ? (TXP_LAST_SISO_MCS_20 +
++				       1) : (TXP_LAST_OFDM + 1);
++
++	for (rate = 0; rate < max_num_rate; rate++) {
++
++		wlc_phy_txpower_sromlimit(ppi, chan, &mintxpwr, &maxtxpwr,
++					  rate);
++
++		maxtxpwr = (maxtxpwr > pactrl) ? (maxtxpwr - pactrl) : 0;
++
++		maxtxpwr = (maxtxpwr > 6) ? (maxtxpwr - 6) : 0;
++
++		tx_pwr_max = max(tx_pwr_max, maxtxpwr);
++		tx_pwr_min = min(tx_pwr_min, maxtxpwr);
++	}
++	*max_txpwr = tx_pwr_max;
++	*min_txpwr = tx_pwr_min;
++}
++
++void
++wlc_phy_txpower_boardlimit_band(struct brcms_phy_pub *ppi, uint bandunit,
++				s32 *max_pwr, s32 *min_pwr, u32 *step_pwr)
++{
++	return;
++}
++
++u8 wlc_phy_txpower_get_target_min(struct brcms_phy_pub *ppi)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++
++	return pi->tx_power_min;
++}
++
++u8 wlc_phy_txpower_get_target_max(struct brcms_phy_pub *ppi)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++
++	return pi->tx_power_max;
++}
++
++static s8 wlc_phy_env_measure_vbat(struct brcms_phy *pi)
++{
++	if (ISLCNPHY(pi))
++		return wlc_lcnphy_vbatsense(pi, 0);
++	else
++		return 0;
++}
++
++static s8 wlc_phy_env_measure_temperature(struct brcms_phy *pi)
++{
++	if (ISLCNPHY(pi))
++		return wlc_lcnphy_tempsense_degree(pi, 0);
++	else
++		return 0;
++}
++
++static void wlc_phy_upd_env_txpwr_rate_limits(struct brcms_phy *pi, u32 band)
++{
++	u8 i;
++	s8 temp, vbat;
++
++	for (i = 0; i < TXP_NUM_RATES; i++)
++		pi->txpwr_env_limit[i] = BRCMS_TXPWR_MAX;
++
++	vbat = wlc_phy_env_measure_vbat(pi);
++	temp = wlc_phy_env_measure_temperature(pi);
++
++}
++
++static s8
++wlc_user_txpwr_antport_to_rfport(struct brcms_phy *pi, uint chan, u32 band,
++				 u8 rate)
++{
++	s8 offset = 0;
++
++	if (!pi->user_txpwr_at_rfport)
++		return offset;
++	return offset;
++}
++
++void wlc_phy_txpower_recalc_target(struct brcms_phy *pi)
++{
++	u8 maxtxpwr, mintxpwr, rate, pactrl;
++	uint target_chan;
++	u8 tx_pwr_target[TXP_NUM_RATES];
++	u8 tx_pwr_max = 0;
++	u8 tx_pwr_min = 255;
++	u8 tx_pwr_max_rate_ind = 0;
++	u8 max_num_rate;
++	u8 start_rate = 0;
++	u16 chspec;
++	u32 band = CHSPEC2BAND(pi->radio_chanspec);
++	void (*txpwr_recalc_fn)(struct brcms_phy *) = NULL;
++
++	chspec = pi->radio_chanspec;
++	if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_NONE)
++		target_chan = CHSPEC_CHANNEL(chspec);
++	else if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_UPPER)
++		target_chan = upper_20_sb(CHSPEC_CHANNEL(chspec));
++	else
++		target_chan = lower_20_sb(CHSPEC_CHANNEL(chspec));
++
++	pactrl = 0;
++	if (ISLCNPHY(pi)) {
++		u32 offset_mcs, i;
++
++		if (CHSPEC_IS40(pi->radio_chanspec)) {
++			offset_mcs = pi->mcs40_po;
++			for (i = TXP_FIRST_SISO_MCS_20;
++			     i <= TXP_LAST_SISO_MCS_20; i++) {
++				pi->tx_srom_max_rate_2g[i - 8] =
++					pi->tx_srom_max_2g -
++					((offset_mcs & 0xf) * 2);
++				offset_mcs >>= 4;
++			}
++		} else {
++			offset_mcs = pi->mcs20_po;
++			for (i = TXP_FIRST_SISO_MCS_20;
++			     i <= TXP_LAST_SISO_MCS_20; i++) {
++				pi->tx_srom_max_rate_2g[i - 8] =
++					pi->tx_srom_max_2g -
++					((offset_mcs & 0xf) * 2);
++				offset_mcs >>= 4;
++			}
++		}
++	}
++
++	max_num_rate = ((ISNPHY(pi)) ? (TXP_NUM_RATES) :
++			((ISLCNPHY(pi)) ?
++			 (TXP_LAST_SISO_MCS_20 + 1) : (TXP_LAST_OFDM + 1)));
++
++	wlc_phy_upd_env_txpwr_rate_limits(pi, band);
++
++	for (rate = start_rate; rate < max_num_rate; rate++) {
++
++		tx_pwr_target[rate] = pi->tx_user_target[rate];
++
++		if (pi->user_txpwr_at_rfport)
++			tx_pwr_target[rate] +=
++				wlc_user_txpwr_antport_to_rfport(pi,
++								 target_chan,
++								 band,
++								 rate);
++
++		wlc_phy_txpower_sromlimit((struct brcms_phy_pub *) pi,
++					  target_chan,
++					  &mintxpwr, &maxtxpwr, rate);
++
++		maxtxpwr = min(maxtxpwr, pi->txpwr_limit[rate]);
++
++		maxtxpwr = (maxtxpwr > pactrl) ? (maxtxpwr - pactrl) : 0;
++
++		maxtxpwr = (maxtxpwr > 6) ? (maxtxpwr - 6) : 0;
++
++		maxtxpwr = min(maxtxpwr, tx_pwr_target[rate]);
++
++		if (pi->txpwr_percent <= 100)
++			maxtxpwr = (maxtxpwr * pi->txpwr_percent) / 100;
++
++		tx_pwr_target[rate] = max(maxtxpwr, mintxpwr);
++
++		tx_pwr_target[rate] =
++			min(tx_pwr_target[rate], pi->txpwr_env_limit[rate]);
++
++		if (tx_pwr_target[rate] > tx_pwr_max)
++			tx_pwr_max_rate_ind = rate;
++
++		tx_pwr_max = max(tx_pwr_max, tx_pwr_target[rate]);
++		tx_pwr_min = min(tx_pwr_min, tx_pwr_target[rate]);
++	}
++
++	memset(pi->tx_power_offset, 0, sizeof(pi->tx_power_offset));
++	pi->tx_power_max = tx_pwr_max;
++	pi->tx_power_min = tx_pwr_min;
++	pi->tx_power_max_rate_ind = tx_pwr_max_rate_ind;
++	for (rate = 0; rate < max_num_rate; rate++) {
++
++		pi->tx_power_target[rate] = tx_pwr_target[rate];
++
++		if (!pi->hwpwrctrl || ISNPHY(pi))
++			pi->tx_power_offset[rate] =
++				pi->tx_power_max - pi->tx_power_target[rate];
++		else
++			pi->tx_power_offset[rate] =
++				pi->tx_power_target[rate] - pi->tx_power_min;
++	}
++
++	txpwr_recalc_fn = pi->pi_fptr.txpwrrecalc;
++	if (txpwr_recalc_fn)
++		(*txpwr_recalc_fn)(pi);
++}
++
++static void
++wlc_phy_txpower_reg_limit_calc(struct brcms_phy *pi, struct txpwr_limits *txpwr,
++			       u16 chanspec)
++{
++	u8 tmp_txpwr_limit[2 * BRCMS_NUM_RATES_OFDM];
++	u8 *txpwr_ptr1 = NULL, *txpwr_ptr2 = NULL;
++	int rate_start_index = 0, rate1, rate2, k;
++
++	for (rate1 = WL_TX_POWER_CCK_FIRST, rate2 = 0;
++	     rate2 < WL_TX_POWER_CCK_NUM; rate1++, rate2++)
++		pi->txpwr_limit[rate1] = txpwr->cck[rate2];
++
++	for (rate1 = WL_TX_POWER_OFDM_FIRST, rate2 = 0;
++	     rate2 < WL_TX_POWER_OFDM_NUM; rate1++, rate2++)
++		pi->txpwr_limit[rate1] = txpwr->ofdm[rate2];
++
++	if (ISNPHY(pi)) {
++
++		for (k = 0; k < 4; k++) {
++			switch (k) {
++			case 0:
++
++				txpwr_ptr1 = txpwr->mcs_20_siso;
++				txpwr_ptr2 = txpwr->ofdm;
++				rate_start_index = WL_TX_POWER_OFDM_FIRST;
++				break;
++			case 1:
++
++				txpwr_ptr1 = txpwr->mcs_20_cdd;
++				txpwr_ptr2 = txpwr->ofdm_cdd;
++				rate_start_index = WL_TX_POWER_OFDM20_CDD_FIRST;
++				break;
++			case 2:
++
++				txpwr_ptr1 = txpwr->mcs_40_siso;
++				txpwr_ptr2 = txpwr->ofdm_40_siso;
++				rate_start_index =
++					WL_TX_POWER_OFDM40_SISO_FIRST;
++				break;
++			case 3:
++
++				txpwr_ptr1 = txpwr->mcs_40_cdd;
++				txpwr_ptr2 = txpwr->ofdm_40_cdd;
++				rate_start_index = WL_TX_POWER_OFDM40_CDD_FIRST;
++				break;
++			}
++
++			for (rate2 = 0; rate2 < BRCMS_NUM_RATES_OFDM;
++			     rate2++) {
++				tmp_txpwr_limit[rate2] = 0;
++				tmp_txpwr_limit[BRCMS_NUM_RATES_OFDM + rate2] =
++					txpwr_ptr1[rate2];
++			}
++			wlc_phy_mcs_to_ofdm_powers_nphy(
++				tmp_txpwr_limit, 0,
++				BRCMS_NUM_RATES_OFDM -
++				1, BRCMS_NUM_RATES_OFDM);
++			for (rate1 = rate_start_index, rate2 = 0;
++			     rate2 < BRCMS_NUM_RATES_OFDM; rate1++, rate2++)
++				pi->txpwr_limit[rate1] =
++					min(txpwr_ptr2[rate2],
++					    tmp_txpwr_limit[rate2]);
++		}
++
++		for (k = 0; k < 4; k++) {
++			switch (k) {
++			case 0:
++
++				txpwr_ptr1 = txpwr->ofdm;
++				txpwr_ptr2 = txpwr->mcs_20_siso;
++				rate_start_index = WL_TX_POWER_MCS20_SISO_FIRST;
++				break;
++			case 1:
++
++				txpwr_ptr1 = txpwr->ofdm_cdd;
++				txpwr_ptr2 = txpwr->mcs_20_cdd;
++				rate_start_index = WL_TX_POWER_MCS20_CDD_FIRST;
++				break;
++			case 2:
++
++				txpwr_ptr1 = txpwr->ofdm_40_siso;
++				txpwr_ptr2 = txpwr->mcs_40_siso;
++				rate_start_index = WL_TX_POWER_MCS40_SISO_FIRST;
++				break;
++			case 3:
++
++				txpwr_ptr1 = txpwr->ofdm_40_cdd;
++				txpwr_ptr2 = txpwr->mcs_40_cdd;
++				rate_start_index = WL_TX_POWER_MCS40_CDD_FIRST;
++				break;
++			}
++			for (rate2 = 0; rate2 < BRCMS_NUM_RATES_OFDM;
++			     rate2++) {
++				tmp_txpwr_limit[rate2] = 0;
++				tmp_txpwr_limit[BRCMS_NUM_RATES_OFDM + rate2] =
++					txpwr_ptr1[rate2];
++			}
++			wlc_phy_ofdm_to_mcs_powers_nphy(
++				tmp_txpwr_limit, 0,
++				BRCMS_NUM_RATES_OFDM -
++				1, BRCMS_NUM_RATES_OFDM);
++			for (rate1 = rate_start_index, rate2 = 0;
++			     rate2 < BRCMS_NUM_RATES_MCS_1_STREAM;
++			     rate1++, rate2++)
++				pi->txpwr_limit[rate1] =
++					min(txpwr_ptr2[rate2],
++					    tmp_txpwr_limit[rate2]);
++		}
++
++		for (k = 0; k < 2; k++) {
++			switch (k) {
++			case 0:
++
++				rate_start_index = WL_TX_POWER_MCS20_STBC_FIRST;
++				txpwr_ptr1 = txpwr->mcs_20_stbc;
++				break;
++			case 1:
++
++				rate_start_index = WL_TX_POWER_MCS40_STBC_FIRST;
++				txpwr_ptr1 = txpwr->mcs_40_stbc;
++				break;
++			}
++			for (rate1 = rate_start_index, rate2 = 0;
++			     rate2 < BRCMS_NUM_RATES_MCS_1_STREAM;
++			     rate1++, rate2++)
++				pi->txpwr_limit[rate1] = txpwr_ptr1[rate2];
++		}
++
++		for (k = 0; k < 2; k++) {
++			switch (k) {
++			case 0:
++
++				rate_start_index = WL_TX_POWER_MCS20_SDM_FIRST;
++				txpwr_ptr1 = txpwr->mcs_20_mimo;
++				break;
++			case 1:
++
++				rate_start_index = WL_TX_POWER_MCS40_SDM_FIRST;
++				txpwr_ptr1 = txpwr->mcs_40_mimo;
++				break;
++			}
++			for (rate1 = rate_start_index, rate2 = 0;
++			     rate2 < BRCMS_NUM_RATES_MCS_2_STREAM;
++			     rate1++, rate2++)
++				pi->txpwr_limit[rate1] = txpwr_ptr1[rate2];
++		}
++
++		pi->txpwr_limit[WL_TX_POWER_MCS_32] = txpwr->mcs32;
++
++		pi->txpwr_limit[WL_TX_POWER_MCS40_CDD_FIRST] =
++			min(pi->txpwr_limit[WL_TX_POWER_MCS40_CDD_FIRST],
++			    pi->txpwr_limit[WL_TX_POWER_MCS_32]);
++		pi->txpwr_limit[WL_TX_POWER_MCS_32] =
++			pi->txpwr_limit[WL_TX_POWER_MCS40_CDD_FIRST];
++	}
++}
++
++void wlc_phy_txpwr_percent_set(struct brcms_phy_pub *ppi, u8 txpwr_percent)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++
++	pi->txpwr_percent = txpwr_percent;
++}
++
++void wlc_phy_machwcap_set(struct brcms_phy_pub *ppi, u32 machwcap)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++
++	pi->sh->machwcap = machwcap;
++}
++
++void wlc_phy_runbist_config(struct brcms_phy_pub *ppi, bool start_end)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++	u16 rxc;
++	rxc = 0;
++
++	if (start_end == ON) {
++		if (!ISNPHY(pi))
++			return;
++
++		if (NREV_IS(pi->pubpi.phy_rev, 3)
++		    || NREV_IS(pi->pubpi.phy_rev, 4)) {
++			bcma_wflush16(pi->d11core, D11REGOFFS(phyregaddr),
++				      0xa0);
++			bcma_set16(pi->d11core, D11REGOFFS(phyregdata),
++				   0x1 << 15);
++		}
++	} else {
++		if (NREV_IS(pi->pubpi.phy_rev, 3)
++		    || NREV_IS(pi->pubpi.phy_rev, 4)) {
++			bcma_wflush16(pi->d11core, D11REGOFFS(phyregaddr),
++				      0xa0);
++			bcma_write16(pi->d11core, D11REGOFFS(phyregdata), rxc);
++		}
++
++		wlc_phy_por_inform(ppi);
++	}
++}
++
++void
++wlc_phy_txpower_limit_set(struct brcms_phy_pub *ppi, struct txpwr_limits *txpwr,
++			  u16 chanspec)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++
++	wlc_phy_txpower_reg_limit_calc(pi, txpwr, chanspec);
++
++	if (ISLCNPHY(pi)) {
++		int i, j;
++		for (i = TXP_FIRST_OFDM_20_CDD, j = 0;
++		     j < BRCMS_NUM_RATES_MCS_1_STREAM; i++, j++) {
++			if (txpwr->mcs_20_siso[j])
++				pi->txpwr_limit[i] = txpwr->mcs_20_siso[j];
++			else
++				pi->txpwr_limit[i] = txpwr->ofdm[j];
++		}
++	}
++
++	wlapi_suspend_mac_and_wait(pi->sh->physhim);
++
++	wlc_phy_txpower_recalc_target(pi);
++	wlc_phy_cal_txpower_recalc_sw(pi);
++	wlapi_enable_mac(pi->sh->physhim);
++}
++
++void wlc_phy_ofdm_rateset_war(struct brcms_phy_pub *pih, bool war)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	pi->ofdm_rateset_war = war;
++}
++
++void wlc_phy_bf_preempt_enable(struct brcms_phy_pub *pih, bool bf_preempt)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	pi->bf_preempt_4306 = bf_preempt;
++}
++
++void wlc_phy_txpower_update_shm(struct brcms_phy *pi)
++{
++	int j;
++	if (ISNPHY(pi))
++		return;
++
++	if (!pi->sh->clk)
++		return;
++
++	if (pi->hwpwrctrl) {
++		u16 offset;
++
++		wlapi_bmac_write_shm(pi->sh->physhim, M_TXPWR_MAX, 63);
++		wlapi_bmac_write_shm(pi->sh->physhim, M_TXPWR_N,
++				     1 << NUM_TSSI_FRAMES);
++
++		wlapi_bmac_write_shm(pi->sh->physhim, M_TXPWR_TARGET,
++				     pi->tx_power_min << NUM_TSSI_FRAMES);
++
++		wlapi_bmac_write_shm(pi->sh->physhim, M_TXPWR_CUR,
++				     pi->hwpwr_txcur);
++
++		for (j = TXP_FIRST_OFDM; j <= TXP_LAST_OFDM; j++) {
++			const u8 ucode_ofdm_rates[] = {
++				0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c
++			};
++			offset = wlapi_bmac_rate_shm_offset(
++				pi->sh->physhim,
++				ucode_ofdm_rates[j - TXP_FIRST_OFDM]);
++			wlapi_bmac_write_shm(pi->sh->physhim, offset + 6,
++					     pi->tx_power_offset[j]);
++			wlapi_bmac_write_shm(pi->sh->physhim, offset + 14,
++					     -(pi->tx_power_offset[j] / 2));
++		}
++
++		wlapi_bmac_mhf(pi->sh->physhim, MHF2, MHF2_HWPWRCTL,
++			       MHF2_HWPWRCTL, BRCM_BAND_ALL);
++	} else {
++		int i;
++
++		for (i = TXP_FIRST_OFDM; i <= TXP_LAST_OFDM; i++)
++			pi->tx_power_offset[i] =
++				(u8) roundup(pi->tx_power_offset[i], 8);
++		wlapi_bmac_write_shm(pi->sh->physhim, M_OFDM_OFFSET,
++				     (u16)
++				     ((pi->tx_power_offset[TXP_FIRST_OFDM]
++				       + 7) >> 3));
++	}
++}
++
++bool wlc_phy_txpower_hw_ctrl_get(struct brcms_phy_pub *ppi)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++
++	if (ISNPHY(pi))
++		return pi->nphy_txpwrctrl;
++	else
++		return pi->hwpwrctrl;
++}
++
++void wlc_phy_txpower_hw_ctrl_set(struct brcms_phy_pub *ppi, bool hwpwrctrl)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++	bool suspend;
++
++	if (!pi->hwpwrctrl_capable)
++		return;
++
++	pi->hwpwrctrl = hwpwrctrl;
++	pi->nphy_txpwrctrl = hwpwrctrl;
++	pi->txpwrctrl = hwpwrctrl;
++
++	if (ISNPHY(pi)) {
++		suspend = (0 == (bcma_read32(pi->d11core,
++					     D11REGOFFS(maccontrol)) &
++				 MCTL_EN_MAC));
++		if (!suspend)
++			wlapi_suspend_mac_and_wait(pi->sh->physhim);
++
++		wlc_phy_txpwrctrl_enable_nphy(pi, pi->nphy_txpwrctrl);
++		if (pi->nphy_txpwrctrl == PHY_TPC_HW_OFF)
++			wlc_phy_txpwr_fixpower_nphy(pi);
++		else
++			mod_phy_reg(pi, 0x1e7, (0x7f << 0),
++				    pi->saved_txpwr_idx);
++
++		if (!suspend)
++			wlapi_enable_mac(pi->sh->physhim);
++	}
++}
++
++void wlc_phy_txpower_ipa_upd(struct brcms_phy *pi)
++{
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		pi->ipa2g_on = (pi->srom_fem2g.extpagain == 2);
++		pi->ipa5g_on = (pi->srom_fem5g.extpagain == 2);
++	} else {
++		pi->ipa2g_on = false;
++		pi->ipa5g_on = false;
++	}
++}
++
++static u32 wlc_phy_txpower_est_power_nphy(struct brcms_phy *pi)
++{
++	s16 tx0_status, tx1_status;
++	u16 estPower1, estPower2;
++	u8 pwr0, pwr1, adj_pwr0, adj_pwr1;
++	u32 est_pwr;
++
++	estPower1 = read_phy_reg(pi, 0x118);
++	estPower2 = read_phy_reg(pi, 0x119);
++
++	if ((estPower1 & (0x1 << 8)) == (0x1 << 8))
++		pwr0 = (u8) (estPower1 & (0xff << 0)) >> 0;
++	else
++		pwr0 = 0x80;
++
++	if ((estPower2 & (0x1 << 8)) == (0x1 << 8))
++		pwr1 = (u8) (estPower2 & (0xff << 0)) >> 0;
++	else
++		pwr1 = 0x80;
++
++	tx0_status = read_phy_reg(pi, 0x1ed);
++	tx1_status = read_phy_reg(pi, 0x1ee);
++
++	if ((tx0_status & (0x1 << 15)) == (0x1 << 15))
++		adj_pwr0 = (u8) (tx0_status & (0xff << 0)) >> 0;
++	else
++		adj_pwr0 = 0x80;
++	if ((tx1_status & (0x1 << 15)) == (0x1 << 15))
++		adj_pwr1 = (u8) (tx1_status & (0xff << 0)) >> 0;
++	else
++		adj_pwr1 = 0x80;
++
++	est_pwr = (u32) ((pwr0 << 24) | (pwr1 << 16) | (adj_pwr0 << 8) |
++			 adj_pwr1);
++
++	return est_pwr;
++}
++
++void
++wlc_phy_txpower_get_current(struct brcms_phy_pub *ppi, struct tx_power *power,
++			    uint channel)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++	uint rate, num_rates;
++	u8 min_pwr, max_pwr;
++
++#if WL_TX_POWER_RATES != TXP_NUM_RATES
++#error "struct tx_power out of sync with this fn"
++#endif
++
++	if (ISNPHY(pi)) {
++		power->rf_cores = 2;
++		power->flags |= (WL_TX_POWER_F_MIMO);
++		if (pi->nphy_txpwrctrl == PHY_TPC_HW_ON)
++			power->flags |=
++				(WL_TX_POWER_F_ENABLED | WL_TX_POWER_F_HW);
++	} else if (ISLCNPHY(pi)) {
++		power->rf_cores = 1;
++		power->flags |= (WL_TX_POWER_F_SISO);
++		if (pi->radiopwr_override == RADIOPWR_OVERRIDE_DEF)
++			power->flags |= WL_TX_POWER_F_ENABLED;
++		if (pi->hwpwrctrl)
++			power->flags |= WL_TX_POWER_F_HW;
++	}
++
++	num_rates = ((ISNPHY(pi)) ? (TXP_NUM_RATES) :
++		     ((ISLCNPHY(pi)) ?
++		      (TXP_LAST_OFDM_20_CDD + 1) : (TXP_LAST_OFDM + 1)));
++
++	for (rate = 0; rate < num_rates; rate++) {
++		power->user_limit[rate] = pi->tx_user_target[rate];
++		wlc_phy_txpower_sromlimit(ppi, channel, &min_pwr, &max_pwr,
++					  rate);
++		power->board_limit[rate] = (u8) max_pwr;
++		power->target[rate] = pi->tx_power_target[rate];
++	}
++
++	if (ISNPHY(pi)) {
++		u32 est_pout;
++
++		wlapi_suspend_mac_and_wait(pi->sh->physhim);
++		wlc_phyreg_enter((struct brcms_phy_pub *) pi);
++		est_pout = wlc_phy_txpower_est_power_nphy(pi);
++		wlc_phyreg_exit((struct brcms_phy_pub *) pi);
++		wlapi_enable_mac(pi->sh->physhim);
++
++		power->est_Pout[0] = (est_pout >> 8) & 0xff;
++		power->est_Pout[1] = est_pout & 0xff;
++
++		power->est_Pout_act[0] = est_pout >> 24;
++		power->est_Pout_act[1] = (est_pout >> 16) & 0xff;
++
++		if (power->est_Pout[0] == 0x80)
++			power->est_Pout[0] = 0;
++		if (power->est_Pout[1] == 0x80)
++			power->est_Pout[1] = 0;
++
++		if (power->est_Pout_act[0] == 0x80)
++			power->est_Pout_act[0] = 0;
++		if (power->est_Pout_act[1] == 0x80)
++			power->est_Pout_act[1] = 0;
++
++		power->est_Pout_cck = 0;
++
++		power->tx_power_max[0] = pi->tx_power_max;
++		power->tx_power_max[1] = pi->tx_power_max;
++
++		power->tx_power_max_rate_ind[0] = pi->tx_power_max_rate_ind;
++		power->tx_power_max_rate_ind[1] = pi->tx_power_max_rate_ind;
++	} else if (pi->hwpwrctrl && pi->sh->up) {
++
++		wlc_phyreg_enter(ppi);
++		if (ISLCNPHY(pi)) {
++
++			power->tx_power_max[0] = pi->tx_power_max;
++			power->tx_power_max[1] = pi->tx_power_max;
++
++			power->tx_power_max_rate_ind[0] =
++				pi->tx_power_max_rate_ind;
++			power->tx_power_max_rate_ind[1] =
++				pi->tx_power_max_rate_ind;
++
++			if (wlc_phy_tpc_isenabled_lcnphy(pi))
++				power->flags |=
++					(WL_TX_POWER_F_HW |
++					 WL_TX_POWER_F_ENABLED);
++			else
++				power->flags &=
++					~(WL_TX_POWER_F_HW |
++					  WL_TX_POWER_F_ENABLED);
++
++			wlc_lcnphy_get_tssi(pi, (s8 *) &power->est_Pout[0],
++					    (s8 *) &power->est_Pout_cck);
++		}
++		wlc_phyreg_exit(ppi);
++	}
++}
++
++void wlc_phy_antsel_type_set(struct brcms_phy_pub *ppi, u8 antsel_type)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++
++	pi->antsel_type = antsel_type;
++}
++
++bool wlc_phy_test_ison(struct brcms_phy_pub *ppi)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++
++	return pi->phytest_on;
++}
++
++void wlc_phy_ant_rxdiv_set(struct brcms_phy_pub *ppi, u8 val)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++	bool suspend;
++
++	pi->sh->rx_antdiv = val;
++
++	if (!(ISNPHY(pi) && D11REV_IS(pi->sh->corerev, 16))) {
++		if (val > ANT_RX_DIV_FORCE_1)
++			wlapi_bmac_mhf(pi->sh->physhim, MHF1, MHF1_ANTDIV,
++				       MHF1_ANTDIV, BRCM_BAND_ALL);
++		else
++			wlapi_bmac_mhf(pi->sh->physhim, MHF1, MHF1_ANTDIV, 0,
++				       BRCM_BAND_ALL);
++	}
++
++	if (ISNPHY(pi))
++		return;
++
++	if (!pi->sh->clk)
++		return;
++
++	suspend = (0 == (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) &
++			 MCTL_EN_MAC));
++	if (!suspend)
++		wlapi_suspend_mac_and_wait(pi->sh->physhim);
++
++	if (ISLCNPHY(pi)) {
++		if (val > ANT_RX_DIV_FORCE_1) {
++			mod_phy_reg(pi, 0x410, (0x1 << 1), 0x01 << 1);
++			mod_phy_reg(pi, 0x410,
++				    (0x1 << 0),
++				    ((ANT_RX_DIV_START_1 == val) ? 1 : 0) << 0);
++		} else {
++			mod_phy_reg(pi, 0x410, (0x1 << 1), 0x00 << 1);
++			mod_phy_reg(pi, 0x410, (0x1 << 0), (u16) val << 0);
++		}
++	}
++
++	if (!suspend)
++		wlapi_enable_mac(pi->sh->physhim);
++
++	return;
++}
++
++static bool
++wlc_phy_noise_calc_phy(struct brcms_phy *pi, u32 *cmplx_pwr, s8 *pwr_ant)
++{
++	s8 cmplx_pwr_dbm[PHY_CORE_MAX];
++	u8 i;
++
++	memset((u8 *) cmplx_pwr_dbm, 0, sizeof(cmplx_pwr_dbm));
++	wlc_phy_compute_dB(cmplx_pwr, cmplx_pwr_dbm, pi->pubpi.phy_corenum);
++
++	for (i = 0; i < pi->pubpi.phy_corenum; i++) {
++		if (NREV_GE(pi->pubpi.phy_rev, 3))
++			cmplx_pwr_dbm[i] += (s8) PHY_NOISE_OFFSETFACT_4322;
++		else
++
++			cmplx_pwr_dbm[i] += (s8) (16 - (15) * 3 - 70);
++	}
++
++	for (i = 0; i < pi->pubpi.phy_corenum; i++) {
++		pi->nphy_noise_win[i][pi->nphy_noise_index] = cmplx_pwr_dbm[i];
++		pwr_ant[i] = cmplx_pwr_dbm[i];
++	}
++	pi->nphy_noise_index =
++		MODINC_POW2(pi->nphy_noise_index, PHY_NOISE_WINDOW_SZ);
++	return true;
++}
++
++static void wlc_phy_noise_cb(struct brcms_phy *pi, u8 channel, s8 noise_dbm)
++{
++	if (!pi->phynoise_state)
++		return;
++
++	if (pi->phynoise_state & PHY_NOISE_STATE_MON) {
++		if (pi->phynoise_chan_watchdog == channel) {
++			pi->sh->phy_noise_window[pi->sh->phy_noise_index] =
++				noise_dbm;
++			pi->sh->phy_noise_index =
++				MODINC(pi->sh->phy_noise_index, MA_WINDOW_SZ);
++		}
++		pi->phynoise_state &= ~PHY_NOISE_STATE_MON;
++	}
++
++	if (pi->phynoise_state & PHY_NOISE_STATE_EXTERNAL)
++		pi->phynoise_state &= ~PHY_NOISE_STATE_EXTERNAL;
++
++}
++
++static s8 wlc_phy_noise_read_shmem(struct brcms_phy *pi)
++{
++	u32 cmplx_pwr[PHY_CORE_MAX];
++	s8 noise_dbm_ant[PHY_CORE_MAX];
++	u16 lo, hi;
++	u32 cmplx_pwr_tot = 0;
++	s8 noise_dbm = PHY_NOISE_FIXED_VAL_NPHY;
++	u8 idx, core;
++
++	memset((u8 *) cmplx_pwr, 0, sizeof(cmplx_pwr));
++	memset((u8 *) noise_dbm_ant, 0, sizeof(noise_dbm_ant));
++
++	for (idx = 0, core = 0; core < pi->pubpi.phy_corenum; idx += 2,
++	     core++) {
++		lo = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP(idx));
++		hi = wlapi_bmac_read_shm(pi->sh->physhim,
++					 M_PWRIND_MAP(idx + 1));
++		cmplx_pwr[core] = (hi << 16) + lo;
++		cmplx_pwr_tot += cmplx_pwr[core];
++		if (cmplx_pwr[core] == 0)
++			noise_dbm_ant[core] = PHY_NOISE_FIXED_VAL_NPHY;
++		else
++			cmplx_pwr[core] >>= PHY_NOISE_SAMPLE_LOG_NUM_UCODE;
++	}
++
++	if (cmplx_pwr_tot != 0)
++		wlc_phy_noise_calc_phy(pi, cmplx_pwr, noise_dbm_ant);
++
++	for (core = 0; core < pi->pubpi.phy_corenum; core++) {
++		pi->nphy_noise_win[core][pi->nphy_noise_index] =
++			noise_dbm_ant[core];
++
++		if (noise_dbm_ant[core] > noise_dbm)
++			noise_dbm = noise_dbm_ant[core];
++	}
++	pi->nphy_noise_index =
++		MODINC_POW2(pi->nphy_noise_index, PHY_NOISE_WINDOW_SZ);
++
++	return noise_dbm;
++
++}
++
++void wlc_phy_noise_sample_intr(struct brcms_phy_pub *pih)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++	u16 jssi_aux;
++	u8 channel = 0;
++	s8 noise_dbm = PHY_NOISE_FIXED_VAL_NPHY;
++
++	if (ISLCNPHY(pi)) {
++		u32 cmplx_pwr, cmplx_pwr0, cmplx_pwr1;
++		u16 lo, hi;
++		s32 pwr_offset_dB, gain_dB;
++		u16 status_0, status_1;
++
++		jssi_aux = wlapi_bmac_read_shm(pi->sh->physhim, M_JSSI_AUX);
++		channel = jssi_aux & D11_CURCHANNEL_MAX;
++
++		lo = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP0);
++		hi = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP1);
++		cmplx_pwr0 = (hi << 16) + lo;
++
++		lo = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP2);
++		hi = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP3);
++		cmplx_pwr1 = (hi << 16) + lo;
++		cmplx_pwr = (cmplx_pwr0 + cmplx_pwr1) >> 6;
++
++		status_0 = 0x44;
++		status_1 = wlapi_bmac_read_shm(pi->sh->physhim, M_JSSI_0);
++		if ((cmplx_pwr > 0 && cmplx_pwr < 500)
++		    && ((status_1 & 0xc000) == 0x4000)) {
++
++			wlc_phy_compute_dB(&cmplx_pwr, &noise_dbm,
++					   pi->pubpi.phy_corenum);
++			pwr_offset_dB = (read_phy_reg(pi, 0x434) & 0xFF);
++			if (pwr_offset_dB > 127)
++				pwr_offset_dB -= 256;
++
++			noise_dbm += (s8) (pwr_offset_dB - 30);
++
++			gain_dB = (status_0 & 0x1ff);
++			noise_dbm -= (s8) (gain_dB);
++		} else {
++			noise_dbm = PHY_NOISE_FIXED_VAL_LCNPHY;
++		}
++	} else if (ISNPHY(pi)) {
++
++		jssi_aux = wlapi_bmac_read_shm(pi->sh->physhim, M_JSSI_AUX);
++		channel = jssi_aux & D11_CURCHANNEL_MAX;
++
++		noise_dbm = wlc_phy_noise_read_shmem(pi);
++	}
++
++	wlc_phy_noise_cb(pi, channel, noise_dbm);
++
++}
++
++static void
++wlc_phy_noise_sample_request(struct brcms_phy_pub *pih, u8 reason, u8 ch)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++	s8 noise_dbm = PHY_NOISE_FIXED_VAL_NPHY;
++	bool sampling_in_progress = (pi->phynoise_state != 0);
++	bool wait_for_intr = true;
++
++	switch (reason) {
++	case PHY_NOISE_SAMPLE_MON:
++		pi->phynoise_chan_watchdog = ch;
++		pi->phynoise_state |= PHY_NOISE_STATE_MON;
++		break;
++
++	case PHY_NOISE_SAMPLE_EXTERNAL:
++		pi->phynoise_state |= PHY_NOISE_STATE_EXTERNAL;
++		break;
++
++	default:
++		break;
++	}
++
++	if (sampling_in_progress)
++		return;
++
++	pi->phynoise_now = pi->sh->now;
++
++	if (pi->phy_fixed_noise) {
++		if (ISNPHY(pi)) {
++			pi->nphy_noise_win[WL_ANT_IDX_1][pi->nphy_noise_index] =
++				PHY_NOISE_FIXED_VAL_NPHY;
++			pi->nphy_noise_win[WL_ANT_IDX_2][pi->nphy_noise_index] =
++				PHY_NOISE_FIXED_VAL_NPHY;
++			pi->nphy_noise_index = MODINC_POW2(pi->nphy_noise_index,
++							   PHY_NOISE_WINDOW_SZ);
++			noise_dbm = PHY_NOISE_FIXED_VAL_NPHY;
++		} else {
++			noise_dbm = PHY_NOISE_FIXED_VAL;
++		}
++
++		wait_for_intr = false;
++		goto done;
++	}
++
++	if (ISLCNPHY(pi)) {
++		if (!pi->phynoise_polling
++		    || (reason == PHY_NOISE_SAMPLE_EXTERNAL)) {
++			wlapi_bmac_write_shm(pi->sh->physhim, M_JSSI_0, 0);
++			wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP0, 0);
++			wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP1, 0);
++			wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP2, 0);
++			wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP3, 0);
++
++			bcma_set32(pi->d11core, D11REGOFFS(maccommand),
++				   MCMD_BG_NOISE);
++		} else {
++			wlapi_suspend_mac_and_wait(pi->sh->physhim);
++			wlc_lcnphy_deaf_mode(pi, (bool) 0);
++			noise_dbm = (s8) wlc_lcnphy_rx_signal_power(pi, 20);
++			wlc_lcnphy_deaf_mode(pi, (bool) 1);
++			wlapi_enable_mac(pi->sh->physhim);
++			wait_for_intr = false;
++		}
++	} else if (ISNPHY(pi)) {
++		if (!pi->phynoise_polling
++		    || (reason == PHY_NOISE_SAMPLE_EXTERNAL)) {
++
++			wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP0, 0);
++			wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP1, 0);
++			wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP2, 0);
++			wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP3, 0);
++
++			bcma_set32(pi->d11core, D11REGOFFS(maccommand),
++				   MCMD_BG_NOISE);
++		} else {
++			struct phy_iq_est est[PHY_CORE_MAX];
++			u32 cmplx_pwr[PHY_CORE_MAX];
++			s8 noise_dbm_ant[PHY_CORE_MAX];
++			u16 log_num_samps, num_samps, classif_state = 0;
++			u8 wait_time = 32;
++			u8 wait_crs = 0;
++			u8 i;
++
++			memset((u8 *) est, 0, sizeof(est));
++			memset((u8 *) cmplx_pwr, 0, sizeof(cmplx_pwr));
++			memset((u8 *) noise_dbm_ant, 0, sizeof(noise_dbm_ant));
++
++			log_num_samps = PHY_NOISE_SAMPLE_LOG_NUM_NPHY;
++			num_samps = 1 << log_num_samps;
++
++			wlapi_suspend_mac_and_wait(pi->sh->physhim);
++			classif_state = wlc_phy_classifier_nphy(pi, 0, 0);
++			wlc_phy_classifier_nphy(pi, 3, 0);
++			wlc_phy_rx_iq_est_nphy(pi, est, num_samps, wait_time,
++					       wait_crs);
++			wlc_phy_classifier_nphy(pi, (0x7 << 0), classif_state);
++			wlapi_enable_mac(pi->sh->physhim);
++
++			for (i = 0; i < pi->pubpi.phy_corenum; i++)
++				cmplx_pwr[i] = (est[i].i_pwr + est[i].q_pwr) >>
++					       log_num_samps;
++
++			wlc_phy_noise_calc_phy(pi, cmplx_pwr, noise_dbm_ant);
++
++			for (i = 0; i < pi->pubpi.phy_corenum; i++) {
++				pi->nphy_noise_win[i][pi->nphy_noise_index] =
++					noise_dbm_ant[i];
++
++				if (noise_dbm_ant[i] > noise_dbm)
++					noise_dbm = noise_dbm_ant[i];
++			}
++			pi->nphy_noise_index = MODINC_POW2(pi->nphy_noise_index,
++							   PHY_NOISE_WINDOW_SZ);
++
++			wait_for_intr = false;
++		}
++	}
++
++done:
++
++	if (!wait_for_intr)
++		wlc_phy_noise_cb(pi, ch, noise_dbm);
++
++}
++
++void wlc_phy_noise_sample_request_external(struct brcms_phy_pub *pih)
++{
++	u8 channel;
++
++	channel = CHSPEC_CHANNEL(wlc_phy_chanspec_get(pih));
++
++	wlc_phy_noise_sample_request(pih, PHY_NOISE_SAMPLE_EXTERNAL, channel);
++}
++
++static const s8 lcnphy_gain_index_offset_for_pkt_rssi[] = {
++	8,
++	8,
++	8,
++	8,
++	8,
++	8,
++	8,
++	9,
++	10,
++	8,
++	8,
++	7,
++	7,
++	1,
++	2,
++	2,
++	2,
++	2,
++	2,
++	2,
++	2,
++	2,
++	2,
++	2,
++	2,
++	2,
++	2,
++	2,
++	2,
++	2,
++	2,
++	2,
++	1,
++	1,
++	0,
++	0,
++	0,
++	0
++};
++
++void wlc_phy_compute_dB(u32 *cmplx_pwr, s8 *p_cmplx_pwr_dB, u8 core)
++{
++	u8 msb, secondmsb, i;
++	u32 tmp;
++
++	for (i = 0; i < core; i++) {
++		secondmsb = 0;
++		tmp = cmplx_pwr[i];
++		msb = fls(tmp);
++		if (msb)
++			secondmsb = (u8) ((tmp >> (--msb - 1)) & 1);
++		p_cmplx_pwr_dB[i] = (s8) (3 * msb + 2 * secondmsb);
++	}
++}
++
++int wlc_phy_rssi_compute(struct brcms_phy_pub *pih,
++			 struct d11rxhdr *rxh)
++{
++	int rssi = rxh->PhyRxStatus_1 & PRXS1_JSSI_MASK;
++	uint radioid = pih->radioid;
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	if ((pi->sh->corerev >= 11)
++	    && !(rxh->RxStatus2 & RXS_PHYRXST_VALID)) {
++		rssi = BRCMS_RSSI_INVALID;
++		goto end;
++	}
++
++	if (ISLCNPHY(pi)) {
++		u8 gidx = (rxh->PhyRxStatus_2 & 0xFC00) >> 10;
++		struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++		if (rssi > 127)
++			rssi -= 256;
++
++		rssi = rssi + lcnphy_gain_index_offset_for_pkt_rssi[gidx];
++		if ((rssi > -46) && (gidx > 18))
++			rssi = rssi + 7;
++
++		rssi = rssi + pi_lcn->lcnphy_pkteng_rssi_slope;
++
++		rssi = rssi + 2;
++
++	}
++
++	if (ISLCNPHY(pi)) {
++		if (rssi > 127)
++			rssi -= 256;
++	} else if (radioid == BCM2055_ID || radioid == BCM2056_ID
++		   || radioid == BCM2057_ID) {
++		rssi = wlc_phy_rssi_compute_nphy(pi, rxh);
++	}
++
++end:
++	return rssi;
++}
++
++void wlc_phy_freqtrack_start(struct brcms_phy_pub *pih)
++{
++	return;
++}
++
++void wlc_phy_freqtrack_end(struct brcms_phy_pub *pih)
++{
++	return;
++}
++
++void wlc_phy_set_deaf(struct brcms_phy_pub *ppi, bool user_flag)
++{
++	struct brcms_phy *pi;
++	pi = (struct brcms_phy *) ppi;
++
++	if (ISLCNPHY(pi))
++		wlc_lcnphy_deaf_mode(pi, true);
++	else if (ISNPHY(pi))
++		wlc_nphy_deaf_mode(pi, true);
++}
++
++void wlc_phy_watchdog(struct brcms_phy_pub *pih)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++	bool delay_phy_cal = false;
++	pi->sh->now++;
++
++	if (!pi->watchdog_override)
++		return;
++
++	if (!(SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi)))
++		wlc_phy_noise_sample_request((struct brcms_phy_pub *) pi,
++					     PHY_NOISE_SAMPLE_MON,
++					     CHSPEC_CHANNEL(pi->
++							    radio_chanspec));
++
++	if (pi->phynoise_state && (pi->sh->now - pi->phynoise_now) > 5)
++		pi->phynoise_state = 0;
++
++	if ((!pi->phycal_txpower) ||
++	    ((pi->sh->now - pi->phycal_txpower) >= pi->sh->fast_timer)) {
++
++		if (!SCAN_INPROG_PHY(pi) && wlc_phy_cal_txpower_recalc_sw(pi))
++			pi->phycal_txpower = pi->sh->now;
++	}
++
++	if ((SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi)
++	     || ASSOC_INPROG_PHY(pi)))
++		return;
++
++	if (ISNPHY(pi) && !pi->disable_percal && !delay_phy_cal) {
++
++		if ((pi->nphy_perical != PHY_PERICAL_DISABLE) &&
++		    (pi->nphy_perical != PHY_PERICAL_MANUAL) &&
++		    ((pi->sh->now - pi->nphy_perical_last) >=
++		     pi->sh->glacial_timer))
++			wlc_phy_cal_perical((struct brcms_phy_pub *) pi,
++					    PHY_PERICAL_WATCHDOG);
++
++		wlc_phy_txpwr_papd_cal_nphy(pi);
++	}
++
++	if (ISLCNPHY(pi)) {
++		if (pi->phy_forcecal ||
++		    ((pi->sh->now - pi->phy_lastcal) >=
++		     pi->sh->glacial_timer)) {
++			if (!(SCAN_RM_IN_PROGRESS(pi) || ASSOC_INPROG_PHY(pi)))
++				wlc_lcnphy_calib_modes(
++					pi,
++					LCNPHY_PERICAL_TEMPBASED_TXPWRCTRL);
++			if (!
++			    (SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi)
++			     || ASSOC_INPROG_PHY(pi)
++			     || pi->carrier_suppr_disable
++			     || pi->disable_percal))
++				wlc_lcnphy_calib_modes(pi,
++						       PHY_PERICAL_WATCHDOG);
++		}
++	}
++}
++
++void wlc_phy_BSSinit(struct brcms_phy_pub *pih, bool bonlyap, int rssi)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++	uint i;
++	uint k;
++
++	for (i = 0; i < MA_WINDOW_SZ; i++)
++		pi->sh->phy_noise_window[i] = (s8) (rssi & 0xff);
++	if (ISLCNPHY(pi)) {
++		for (i = 0; i < MA_WINDOW_SZ; i++)
++			pi->sh->phy_noise_window[i] =
++				PHY_NOISE_FIXED_VAL_LCNPHY;
++	}
++	pi->sh->phy_noise_index = 0;
++
++	for (i = 0; i < PHY_NOISE_WINDOW_SZ; i++) {
++		for (k = WL_ANT_IDX_1; k < WL_ANT_RX_MAX; k++)
++			pi->nphy_noise_win[k][i] = PHY_NOISE_FIXED_VAL_NPHY;
++	}
++	pi->nphy_noise_index = 0;
++}
++
++void
++wlc_phy_papd_decode_epsilon(u32 epsilon, s32 *eps_real, s32 *eps_imag)
++{
++	*eps_imag = (epsilon >> 13);
++	if (*eps_imag > 0xfff)
++		*eps_imag -= 0x2000;
++
++	*eps_real = (epsilon & 0x1fff);
++	if (*eps_real > 0xfff)
++		*eps_real -= 0x2000;
++}
++
++void wlc_phy_cal_perical_mphase_reset(struct brcms_phy *pi)
++{
++	wlapi_del_timer(pi->phycal_timer);
++
++	pi->cal_type_override = PHY_PERICAL_AUTO;
++	pi->mphase_cal_phase_id = MPHASE_CAL_STATE_IDLE;
++	pi->mphase_txcal_cmdidx = 0;
++}
++
++static void
++wlc_phy_cal_perical_mphase_schedule(struct brcms_phy *pi, uint delay)
++{
++
++	if ((pi->nphy_perical != PHY_PERICAL_MPHASE) &&
++	    (pi->nphy_perical != PHY_PERICAL_MANUAL))
++		return;
++
++	wlapi_del_timer(pi->phycal_timer);
++
++	pi->mphase_cal_phase_id = MPHASE_CAL_STATE_INIT;
++	wlapi_add_timer(pi->phycal_timer, delay, 0);
++}
++
++void wlc_phy_cal_perical(struct brcms_phy_pub *pih, u8 reason)
++{
++	s16 nphy_currtemp = 0;
++	s16 delta_temp = 0;
++	bool do_periodic_cal = true;
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	if (!ISNPHY(pi))
++		return;
++
++	if ((pi->nphy_perical == PHY_PERICAL_DISABLE) ||
++	    (pi->nphy_perical == PHY_PERICAL_MANUAL))
++		return;
++
++	switch (reason) {
++	case PHY_PERICAL_DRIVERUP:
++		break;
++
++	case PHY_PERICAL_PHYINIT:
++		if (pi->nphy_perical == PHY_PERICAL_MPHASE) {
++			if (PHY_PERICAL_MPHASE_PENDING(pi))
++				wlc_phy_cal_perical_mphase_reset(pi);
++
++			wlc_phy_cal_perical_mphase_schedule(
++				pi,
++				PHY_PERICAL_INIT_DELAY);
++		}
++		break;
++
++	case PHY_PERICAL_JOIN_BSS:
++	case PHY_PERICAL_START_IBSS:
++	case PHY_PERICAL_UP_BSS:
++		if ((pi->nphy_perical == PHY_PERICAL_MPHASE) &&
++		    PHY_PERICAL_MPHASE_PENDING(pi))
++			wlc_phy_cal_perical_mphase_reset(pi);
++
++		pi->first_cal_after_assoc = true;
++
++		pi->cal_type_override = PHY_PERICAL_FULL;
++
++		if (pi->phycal_tempdelta)
++			pi->nphy_lastcal_temp = wlc_phy_tempsense_nphy(pi);
++
++		wlc_phy_cal_perical_nphy_run(pi, PHY_PERICAL_FULL);
++		break;
++
++	case PHY_PERICAL_WATCHDOG:
++		if (pi->phycal_tempdelta) {
++			nphy_currtemp = wlc_phy_tempsense_nphy(pi);
++			delta_temp =
++				(nphy_currtemp > pi->nphy_lastcal_temp) ?
++				nphy_currtemp - pi->nphy_lastcal_temp :
++				pi->nphy_lastcal_temp - nphy_currtemp;
++
++			if ((delta_temp < (s16) pi->phycal_tempdelta) &&
++			    (pi->nphy_txiqlocal_chanspec ==
++			     pi->radio_chanspec))
++				do_periodic_cal = false;
++			else
++				pi->nphy_lastcal_temp = nphy_currtemp;
++		}
++
++		if (do_periodic_cal) {
++			if (pi->nphy_perical == PHY_PERICAL_MPHASE) {
++				if (!PHY_PERICAL_MPHASE_PENDING(pi))
++					wlc_phy_cal_perical_mphase_schedule(
++						pi,
++						PHY_PERICAL_WDOG_DELAY);
++			} else if (pi->nphy_perical == PHY_PERICAL_SPHASE)
++				wlc_phy_cal_perical_nphy_run(pi,
++							     PHY_PERICAL_AUTO);
++		}
++		break;
++	default:
++		break;
++	}
++}
++
++void wlc_phy_cal_perical_mphase_restart(struct brcms_phy *pi)
++{
++	pi->mphase_cal_phase_id = MPHASE_CAL_STATE_INIT;
++	pi->mphase_txcal_cmdidx = 0;
++}
++
++u8 wlc_phy_nbits(s32 value)
++{
++	s32 abs_val;
++	u8 nbits = 0;
++
++	abs_val = abs(value);
++	while ((abs_val >> nbits) > 0)
++		nbits++;
++
++	return nbits;
++}
++
++void wlc_phy_stf_chain_init(struct brcms_phy_pub *pih, u8 txchain, u8 rxchain)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	pi->sh->hw_phytxchain = txchain;
++	pi->sh->hw_phyrxchain = rxchain;
++	pi->sh->phytxchain = txchain;
++	pi->sh->phyrxchain = rxchain;
++	pi->pubpi.phy_corenum = (u8)hweight8(pi->sh->phyrxchain);
++}
++
++void wlc_phy_stf_chain_set(struct brcms_phy_pub *pih, u8 txchain, u8 rxchain)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	pi->sh->phytxchain = txchain;
++
++	if (ISNPHY(pi))
++		wlc_phy_rxcore_setstate_nphy(pih, rxchain);
++
++	pi->pubpi.phy_corenum = (u8)hweight8(pi->sh->phyrxchain);
++}
++
++void wlc_phy_stf_chain_get(struct brcms_phy_pub *pih, u8 *txchain, u8 *rxchain)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	*txchain = pi->sh->phytxchain;
++	*rxchain = pi->sh->phyrxchain;
++}
++
++u8 wlc_phy_stf_chain_active_get(struct brcms_phy_pub *pih)
++{
++	s16 nphy_currtemp;
++	u8 active_bitmap;
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	active_bitmap = (pi->phy_txcore_heatedup) ? 0x31 : 0x33;
++
++	if (!pi->watchdog_override)
++		return active_bitmap;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 6)) {
++		wlapi_suspend_mac_and_wait(pi->sh->physhim);
++		nphy_currtemp = wlc_phy_tempsense_nphy(pi);
++		wlapi_enable_mac(pi->sh->physhim);
++
++		if (!pi->phy_txcore_heatedup) {
++			if (nphy_currtemp >= pi->phy_txcore_disable_temp) {
++				active_bitmap &= 0xFD;
++				pi->phy_txcore_heatedup = true;
++			}
++		} else {
++			if (nphy_currtemp <= pi->phy_txcore_enable_temp) {
++				active_bitmap |= 0x2;
++				pi->phy_txcore_heatedup = false;
++			}
++		}
++	}
++
++	return active_bitmap;
++}
++
++s8 wlc_phy_stf_ssmode_get(struct brcms_phy_pub *pih, u16 chanspec)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++	u8 siso_mcs_id, cdd_mcs_id;
++
++	siso_mcs_id =
++		(CHSPEC_IS40(chanspec)) ? TXP_FIRST_MCS_40_SISO :
++		TXP_FIRST_MCS_20_SISO;
++	cdd_mcs_id =
++		(CHSPEC_IS40(chanspec)) ? TXP_FIRST_MCS_40_CDD :
++		TXP_FIRST_MCS_20_CDD;
++
++	if (pi->tx_power_target[siso_mcs_id] >
++	    (pi->tx_power_target[cdd_mcs_id] + 12))
++		return PHY_TXC1_MODE_SISO;
++	else
++		return PHY_TXC1_MODE_CDD;
++}
++
++const u8 *wlc_phy_get_ofdm_rate_lookup(void)
++{
++	return ofdm_rate_lookup;
++}
++
++void wlc_lcnphy_epa_switch(struct brcms_phy *pi, bool mode)
++{
++	if ((pi->sh->chip == BCM4313_CHIP_ID) &&
++	    (pi->sh->boardflags & BFL_FEM)) {
++		if (mode) {
++			u16 txant = 0;
++			txant = wlapi_bmac_get_txant(pi->sh->physhim);
++			if (txant == 1) {
++				mod_phy_reg(pi, 0x44d, (0x1 << 2), (1) << 2);
++
++				mod_phy_reg(pi, 0x44c, (0x1 << 2), (1) << 2);
++
++			}
++			ai_cc_reg(pi->sh->sih,
++				  offsetof(struct chipcregs, gpiocontrol),
++				  ~0x0, 0x0);
++			ai_cc_reg(pi->sh->sih,
++				  offsetof(struct chipcregs, gpioout),
++				  0x40, 0x40);
++			ai_cc_reg(pi->sh->sih,
++				  offsetof(struct chipcregs, gpioouten),
++				  0x40, 0x40);
++		} else {
++			mod_phy_reg(pi, 0x44c, (0x1 << 2), (0) << 2);
++
++			mod_phy_reg(pi, 0x44d, (0x1 << 2), (0) << 2);
++
++			ai_cc_reg(pi->sh->sih,
++				  offsetof(struct chipcregs, gpioout),
++				  0x40, 0x00);
++			ai_cc_reg(pi->sh->sih,
++				  offsetof(struct chipcregs, gpioouten),
++				  0x40, 0x0);
++			ai_cc_reg(pi->sh->sih,
++				  offsetof(struct chipcregs, gpiocontrol),
++				  ~0x0, 0x40);
++		}
++	}
++}
++
++void wlc_phy_ldpc_override_set(struct brcms_phy_pub *ppi, bool ldpc)
++{
++	return;
++}
++
++void
++wlc_phy_get_pwrdet_offsets(struct brcms_phy *pi, s8 *cckoffset, s8 *ofdmoffset)
++{
++	*cckoffset = 0;
++	*ofdmoffset = 0;
++}
++
++s8 wlc_phy_upd_rssi_offset(struct brcms_phy *pi, s8 rssi, u16 chanspec)
++{
++
++	return rssi;
++}
++
++bool wlc_phy_txpower_ipa_ison(struct brcms_phy_pub *ppi)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++
++	if (ISNPHY(pi))
++		return wlc_phy_n_txpower_ipa_ison(pi);
++	else
++		return 0;
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_hal.h b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_hal.h
+new file mode 100644
+index 0000000..e34a71e
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_hal.h
+@@ -0,0 +1,299 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++/*
++ * phy_hal.h:  functionality exported from the phy to higher layers
++ */
++
++#ifndef _BRCM_PHY_HAL_H_
++#define _BRCM_PHY_HAL_H_
++
++#include <brcmu_utils.h>
++#include <brcmu_wifi.h>
++#include <phy_shim.h>
++
++#define	IDCODE_VER_MASK		0x0000000f
++#define	IDCODE_VER_SHIFT	0
++#define	IDCODE_MFG_MASK		0x00000fff
++#define	IDCODE_MFG_SHIFT	0
++#define	IDCODE_ID_MASK		0x0ffff000
++#define	IDCODE_ID_SHIFT		12
++#define	IDCODE_REV_MASK		0xf0000000
++#define	IDCODE_REV_SHIFT	28
++
++#define	NORADIO_ID		0xe4f5
++#define	NORADIO_IDCODE		0x4e4f5246
++
++#define BCM2055_ID		0x2055
++#define BCM2055_IDCODE		0x02055000
++#define BCM2055A0_IDCODE	0x1205517f
++
++#define BCM2056_ID		0x2056
++#define BCM2056_IDCODE		0x02056000
++#define BCM2056A0_IDCODE	0x1205617f
++
++#define BCM2057_ID		0x2057
++#define BCM2057_IDCODE		0x02057000
++#define BCM2057A0_IDCODE	0x1205717f
++
++#define BCM2064_ID		0x2064
++#define BCM2064_IDCODE		0x02064000
++#define BCM2064A0_IDCODE	0x0206417f
++
++#define PHY_TPC_HW_OFF		false
++#define PHY_TPC_HW_ON		true
++
++#define PHY_PERICAL_DRIVERUP	1
++#define PHY_PERICAL_WATCHDOG	2
++#define PHY_PERICAL_PHYINIT	3
++#define PHY_PERICAL_JOIN_BSS	4
++#define PHY_PERICAL_START_IBSS	5
++#define PHY_PERICAL_UP_BSS	6
++#define PHY_PERICAL_CHAN	7
++#define PHY_FULLCAL	8
++
++#define PHY_PERICAL_DISABLE	0
++#define PHY_PERICAL_SPHASE	1
++#define PHY_PERICAL_MPHASE	2
++#define PHY_PERICAL_MANUAL	3
++
++#define PHY_HOLD_FOR_ASSOC	1
++#define PHY_HOLD_FOR_SCAN	2
++#define PHY_HOLD_FOR_RM		4
++#define PHY_HOLD_FOR_PLT	8
++#define PHY_HOLD_FOR_MUTE	16
++#define PHY_HOLD_FOR_NOT_ASSOC 0x20
++
++#define PHY_MUTE_FOR_PREISM	1
++#define PHY_MUTE_ALL		0xffffffff
++
++#define PHY_NOISE_FIXED_VAL		(-95)
++#define PHY_NOISE_FIXED_VAL_NPHY	(-92)
++#define PHY_NOISE_FIXED_VAL_LCNPHY	(-92)
++
++#define PHY_MODE_CAL		0x0002
++#define PHY_MODE_NOISEM		0x0004
++
++#define BRCMS_TXPWR_DB_FACTOR	4
++
++/* a large TX Power as an init value to factor out of min() calculations,
++ * keep low enough to fit in an s8, units are .25 dBm
++ */
++#define BRCMS_TXPWR_MAX		(127)	/* ~32 dBm = 1,500 mW */
++
++#define BRCMS_NUM_RATES_CCK           4
++#define BRCMS_NUM_RATES_OFDM          8
++#define BRCMS_NUM_RATES_MCS_1_STREAM  8
++#define BRCMS_NUM_RATES_MCS_2_STREAM  8
++#define BRCMS_NUM_RATES_MCS_3_STREAM  8
++#define BRCMS_NUM_RATES_MCS_4_STREAM  8
++
++#define	BRCMS_RSSI_INVALID	 0	/* invalid RSSI value */
++
++struct d11regs;
++struct phy_shim_info;
++
++struct txpwr_limits {
++	u8 cck[BRCMS_NUM_RATES_CCK];
++	u8 ofdm[BRCMS_NUM_RATES_OFDM];
++
++	u8 ofdm_cdd[BRCMS_NUM_RATES_OFDM];
++
++	u8 ofdm_40_siso[BRCMS_NUM_RATES_OFDM];
++	u8 ofdm_40_cdd[BRCMS_NUM_RATES_OFDM];
++
++	u8 mcs_20_siso[BRCMS_NUM_RATES_MCS_1_STREAM];
++	u8 mcs_20_cdd[BRCMS_NUM_RATES_MCS_1_STREAM];
++	u8 mcs_20_stbc[BRCMS_NUM_RATES_MCS_1_STREAM];
++	u8 mcs_20_mimo[BRCMS_NUM_RATES_MCS_2_STREAM];
++
++	u8 mcs_40_siso[BRCMS_NUM_RATES_MCS_1_STREAM];
++	u8 mcs_40_cdd[BRCMS_NUM_RATES_MCS_1_STREAM];
++	u8 mcs_40_stbc[BRCMS_NUM_RATES_MCS_1_STREAM];
++	u8 mcs_40_mimo[BRCMS_NUM_RATES_MCS_2_STREAM];
++	u8 mcs32;
++};
++
++struct tx_power {
++	u32 flags;
++	u16 chanspec;   /* txpwr report for this channel */
++	u16 local_chanspec;     /* channel on which we are associated */
++	u8 local_max;   /* local max according to the AP */
++	u8 local_constraint;    /* local constraint according to the AP */
++	s8 antgain[2];  /* Ant gain for each band - from SROM */
++	u8 rf_cores;            /* count of RF Cores being reported */
++	u8 est_Pout[4]; /* Latest tx power out estimate per RF chain */
++	u8 est_Pout_act[4];     /* Latest tx power out estimate per RF chain
++				 * without adjustment */
++	u8 est_Pout_cck;        /* Latest CCK tx power out estimate */
++	u8 tx_power_max[4];     /* Maximum target power among all rates */
++	/* Index of the rate with the max target power */
++	u8 tx_power_max_rate_ind[4];
++	/* User limit */
++	u8 user_limit[WL_TX_POWER_RATES];
++	/* Regulatory power limit */
++	u8 reg_limit[WL_TX_POWER_RATES];
++	/* Max power board can support (SROM) */
++	u8 board_limit[WL_TX_POWER_RATES];
++	/* Latest target power */
++	u8 target[WL_TX_POWER_RATES];
++};
++
++struct tx_inst_power {
++	u8 txpwr_est_Pout[2];   /* Latest estimate for 2.4 and 5 Ghz */
++	u8 txpwr_est_Pout_gofdm;        /* Pwr estimate for 2.4 OFDM */
++};
++
++struct brcms_chanvec {
++	u8 vec[MAXCHANNEL / NBBY];
++};
++
++struct shared_phy_params {
++	struct si_pub *sih;
++	struct phy_shim_info *physhim;
++	uint unit;
++	uint corerev;
++	u16 vid;
++	u16 did;
++	uint chip;
++	uint chiprev;
++	uint chippkg;
++	uint sromrev;
++	uint boardtype;
++	uint boardrev;
++	u32 boardflags;
++	u32 boardflags2;
++};
++
++
++extern struct shared_phy *wlc_phy_shared_attach(struct shared_phy_params *shp);
++extern struct brcms_phy_pub *wlc_phy_attach(struct shared_phy *sh,
++					    struct bcma_device *d11core,
++					    int bandtype, struct wiphy *wiphy);
++extern void wlc_phy_detach(struct brcms_phy_pub *ppi);
++
++extern bool wlc_phy_get_phyversion(struct brcms_phy_pub *pih, u16 *phytype,
++				   u16 *phyrev, u16 *radioid,
++				   u16 *radiover);
++extern bool wlc_phy_get_encore(struct brcms_phy_pub *pih);
++extern u32 wlc_phy_get_coreflags(struct brcms_phy_pub *pih);
++
++extern void wlc_phy_hw_clk_state_upd(struct brcms_phy_pub *ppi, bool newstate);
++extern void wlc_phy_hw_state_upd(struct brcms_phy_pub *ppi, bool newstate);
++extern void wlc_phy_init(struct brcms_phy_pub *ppi, u16 chanspec);
++extern void wlc_phy_watchdog(struct brcms_phy_pub *ppi);
++extern int wlc_phy_down(struct brcms_phy_pub *ppi);
++extern u32 wlc_phy_clk_bwbits(struct brcms_phy_pub *pih);
++extern void wlc_phy_cal_init(struct brcms_phy_pub *ppi);
++extern void wlc_phy_antsel_init(struct brcms_phy_pub *ppi, bool lut_init);
++
++extern void wlc_phy_chanspec_set(struct brcms_phy_pub *ppi,
++				 u16 chanspec);
++extern u16 wlc_phy_chanspec_get(struct brcms_phy_pub *ppi);
++extern void wlc_phy_chanspec_radio_set(struct brcms_phy_pub *ppi,
++				       u16 newch);
++extern u16 wlc_phy_bw_state_get(struct brcms_phy_pub *ppi);
++extern void wlc_phy_bw_state_set(struct brcms_phy_pub *ppi, u16 bw);
++
++extern int wlc_phy_rssi_compute(struct brcms_phy_pub *pih,
++				struct d11rxhdr *rxh);
++extern void wlc_phy_por_inform(struct brcms_phy_pub *ppi);
++extern void wlc_phy_noise_sample_intr(struct brcms_phy_pub *ppi);
++extern bool wlc_phy_bist_check_phy(struct brcms_phy_pub *ppi);
++
++extern void wlc_phy_set_deaf(struct brcms_phy_pub *ppi, bool user_flag);
++
++extern void wlc_phy_switch_radio(struct brcms_phy_pub *ppi, bool on);
++extern void wlc_phy_anacore(struct brcms_phy_pub *ppi, bool on);
++
++
++extern void wlc_phy_BSSinit(struct brcms_phy_pub *ppi, bool bonlyap, int rssi);
++
++extern void wlc_phy_chanspec_ch14_widefilter_set(struct brcms_phy_pub *ppi,
++						 bool wide_filter);
++extern void wlc_phy_chanspec_band_validch(struct brcms_phy_pub *ppi, uint band,
++					  struct brcms_chanvec *channels);
++extern u16 wlc_phy_chanspec_band_firstch(struct brcms_phy_pub *ppi,
++					 uint band);
++
++extern void wlc_phy_txpower_sromlimit(struct brcms_phy_pub *ppi, uint chan,
++				      u8 *_min_, u8 *_max_, int rate);
++extern void wlc_phy_txpower_sromlimit_max_get(struct brcms_phy_pub *ppi,
++					      uint chan, u8 *_max_, u8 *_min_);
++extern void wlc_phy_txpower_boardlimit_band(struct brcms_phy_pub *ppi,
++					    uint band, s32 *, s32 *, u32 *);
++extern void wlc_phy_txpower_limit_set(struct brcms_phy_pub *ppi,
++				      struct txpwr_limits *,
++				      u16 chanspec);
++extern int wlc_phy_txpower_get(struct brcms_phy_pub *ppi, uint *qdbm,
++			       bool *override);
++extern int wlc_phy_txpower_set(struct brcms_phy_pub *ppi, uint qdbm,
++			       bool override);
++extern void wlc_phy_txpower_target_set(struct brcms_phy_pub *ppi,
++				       struct txpwr_limits *);
++extern bool wlc_phy_txpower_hw_ctrl_get(struct brcms_phy_pub *ppi);
++extern void wlc_phy_txpower_hw_ctrl_set(struct brcms_phy_pub *ppi,
++					bool hwpwrctrl);
++extern u8 wlc_phy_txpower_get_target_min(struct brcms_phy_pub *ppi);
++extern u8 wlc_phy_txpower_get_target_max(struct brcms_phy_pub *ppi);
++extern bool wlc_phy_txpower_ipa_ison(struct brcms_phy_pub *pih);
++
++extern void wlc_phy_stf_chain_init(struct brcms_phy_pub *pih, u8 txchain,
++				   u8 rxchain);
++extern void wlc_phy_stf_chain_set(struct brcms_phy_pub *pih, u8 txchain,
++				  u8 rxchain);
++extern void wlc_phy_stf_chain_get(struct brcms_phy_pub *pih, u8 *txchain,
++				  u8 *rxchain);
++extern u8 wlc_phy_stf_chain_active_get(struct brcms_phy_pub *pih);
++extern s8 wlc_phy_stf_ssmode_get(struct brcms_phy_pub *pih,
++				 u16 chanspec);
++extern void wlc_phy_ldpc_override_set(struct brcms_phy_pub *ppi, bool val);
++
++extern void wlc_phy_cal_perical(struct brcms_phy_pub *ppi, u8 reason);
++extern void wlc_phy_noise_sample_request_external(struct brcms_phy_pub *ppi);
++extern void wlc_phy_edcrs_lock(struct brcms_phy_pub *pih, bool lock);
++extern void wlc_phy_cal_papd_recal(struct brcms_phy_pub *ppi);
++
++extern void wlc_phy_ant_rxdiv_set(struct brcms_phy_pub *ppi, u8 val);
++extern void wlc_phy_clear_tssi(struct brcms_phy_pub *ppi);
++extern void wlc_phy_hold_upd(struct brcms_phy_pub *ppi, u32 id, bool val);
++extern void wlc_phy_mute_upd(struct brcms_phy_pub *ppi, bool val, u32 flags);
++
++extern void wlc_phy_antsel_type_set(struct brcms_phy_pub *ppi, u8 antsel_type);
++
++extern void wlc_phy_txpower_get_current(struct brcms_phy_pub *ppi,
++					struct tx_power *power, uint channel);
++
++extern void wlc_phy_initcal_enable(struct brcms_phy_pub *pih, bool initcal);
++extern bool wlc_phy_test_ison(struct brcms_phy_pub *ppi);
++extern void wlc_phy_txpwr_percent_set(struct brcms_phy_pub *ppi,
++				      u8 txpwr_percent);
++extern void wlc_phy_ofdm_rateset_war(struct brcms_phy_pub *pih, bool war);
++extern void wlc_phy_bf_preempt_enable(struct brcms_phy_pub *pih,
++				      bool bf_preempt);
++extern void wlc_phy_machwcap_set(struct brcms_phy_pub *ppi, u32 machwcap);
++
++extern void wlc_phy_runbist_config(struct brcms_phy_pub *ppi, bool start_end);
++
++extern void wlc_phy_freqtrack_start(struct brcms_phy_pub *ppi);
++extern void wlc_phy_freqtrack_end(struct brcms_phy_pub *ppi);
++
++extern const u8 *wlc_phy_get_ofdm_rate_lookup(void);
++
++extern s8 wlc_phy_get_tx_power_offset_by_mcs(struct brcms_phy_pub *ppi,
++					     u8 mcs_offset);
++extern s8 wlc_phy_get_tx_power_offset(struct brcms_phy_pub *ppi, u8 tbl_offset);
++#endif                          /* _BRCM_PHY_HAL_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_int.h b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_int.h
+new file mode 100644
+index 0000000..af00e2c
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_int.h
+@@ -0,0 +1,1162 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef _BRCM_PHY_INT_H_
++#define _BRCM_PHY_INT_H_
++
++#include <types.h>
++#include <brcmu_utils.h>
++#include <brcmu_wifi.h>
++
++#define	PHY_VERSION			{ 1, 82, 8, 0 }
++
++#define LCNXN_BASEREV		16
++
++struct phy_shim_info;
++
++struct brcms_phy_srom_fem {
++	/* TSSI positive slope, 1: positive, 0: negative */
++	u8 tssipos;
++	/* Ext PA gain-type: full-gain: 0, pa-lite: 1, no_pa: 2 */
++	u8 extpagain;
++	/* support 32 combinations of different Pdet dynamic ranges */
++	u8 pdetrange;
++	/* TR switch isolation */
++	u8 triso;
++	/* antswctrl lookup table configuration: 32 possible choices */
++	u8 antswctrllut;
++};
++
++#define ISNPHY(pi)	PHYTYPE_IS((pi)->pubpi.phy_type, PHY_TYPE_N)
++#define ISLCNPHY(pi)	PHYTYPE_IS((pi)->pubpi.phy_type, PHY_TYPE_LCN)
++
++#define PHY_GET_RFATTN(rfgain)	((rfgain) & 0x0f)
++#define PHY_GET_PADMIX(rfgain)	(((rfgain) & 0x10) >> 4)
++#define PHY_GET_RFGAINID(rfattn, padmix, width)	((rfattn) + ((padmix)*(width)))
++#define PHY_SAT(x, n)		((x) > ((1<<((n)-1))-1) ? ((1<<((n)-1))-1) : \
++				((x) < -(1<<((n)-1)) ? -(1<<((n)-1)) : (x)))
++#define PHY_SHIFT_ROUND(x, n)	((x) >= 0 ? ((x)+(1<<((n)-1)))>>(n) : (x)>>(n))
++#define PHY_HW_ROUND(x, s)		((x >> s) + ((x >> (s-1)) & (s != 0)))
++
++#define CH_5G_GROUP	3
++#define A_LOW_CHANS	0
++#define A_MID_CHANS	1
++#define A_HIGH_CHANS	2
++#define CH_2G_GROUP	1
++#define G_ALL_CHANS	0
++
++#define FIRST_REF5_CHANNUM	149
++#define LAST_REF5_CHANNUM	165
++#define	FIRST_5G_CHAN		14
++#define	LAST_5G_CHAN		50
++#define	FIRST_MID_5G_CHAN	14
++#define	LAST_MID_5G_CHAN	35
++#define	FIRST_HIGH_5G_CHAN	36
++#define	LAST_HIGH_5G_CHAN	41
++#define	FIRST_LOW_5G_CHAN	42
++#define	LAST_LOW_5G_CHAN	50
++
++#define BASE_LOW_5G_CHAN	4900
++#define BASE_MID_5G_CHAN	5100
++#define BASE_HIGH_5G_CHAN	5500
++
++#define CHAN5G_FREQ(chan)  (5000 + chan*5)
++#define CHAN2G_FREQ(chan)  (2407 + chan*5)
++
++#define TXP_FIRST_CCK		0
++#define TXP_LAST_CCK		3
++#define TXP_FIRST_OFDM		4
++#define TXP_LAST_OFDM		11
++#define TXP_FIRST_OFDM_20_CDD	12
++#define TXP_LAST_OFDM_20_CDD	19
++#define TXP_FIRST_MCS_20_SISO	20
++#define TXP_LAST_MCS_20_SISO	27
++#define TXP_FIRST_MCS_20_CDD	28
++#define TXP_LAST_MCS_20_CDD	35
++#define TXP_FIRST_MCS_20_STBC	36
++#define TXP_LAST_MCS_20_STBC	43
++#define TXP_FIRST_MCS_20_SDM	44
++#define TXP_LAST_MCS_20_SDM	51
++#define TXP_FIRST_OFDM_40_SISO	52
++#define TXP_LAST_OFDM_40_SISO	59
++#define TXP_FIRST_OFDM_40_CDD	60
++#define TXP_LAST_OFDM_40_CDD	67
++#define TXP_FIRST_MCS_40_SISO	68
++#define TXP_LAST_MCS_40_SISO	75
++#define TXP_FIRST_MCS_40_CDD	76
++#define TXP_LAST_MCS_40_CDD	83
++#define TXP_FIRST_MCS_40_STBC	84
++#define TXP_LAST_MCS_40_STBC	91
++#define TXP_FIRST_MCS_40_SDM	92
++#define TXP_LAST_MCS_40_SDM	99
++#define TXP_MCS_32	        100
++#define TXP_NUM_RATES		101
++#define ADJ_PWR_TBL_LEN		84
++
++#define TXP_FIRST_SISO_MCS_20	20
++#define TXP_LAST_SISO_MCS_20	27
++
++#define PHY_CORE_NUM_1	1
++#define PHY_CORE_NUM_2	2
++#define PHY_CORE_NUM_3	3
++#define PHY_CORE_NUM_4	4
++#define PHY_CORE_MAX	PHY_CORE_NUM_4
++#define PHY_CORE_0	0
++#define PHY_CORE_1	1
++#define PHY_CORE_2	2
++#define PHY_CORE_3	3
++
++#define MA_WINDOW_SZ		8
++
++#define PHY_NOISE_SAMPLE_MON		1
++#define PHY_NOISE_SAMPLE_EXTERNAL	2
++#define PHY_NOISE_WINDOW_SZ	16
++#define PHY_NOISE_GLITCH_INIT_MA 10
++#define PHY_NOISE_GLITCH_INIT_MA_BADPlCP 10
++#define PHY_NOISE_STATE_MON		0x1
++#define PHY_NOISE_STATE_EXTERNAL	0x2
++#define PHY_NOISE_SAMPLE_LOG_NUM_NPHY	10
++#define PHY_NOISE_SAMPLE_LOG_NUM_UCODE	9
++
++#define PHY_NOISE_OFFSETFACT_4322  (-103)
++#define PHY_NOISE_MA_WINDOW_SZ	2
++
++#define	PHY_RSSI_TABLE_SIZE	64
++#define RSSI_ANT_MERGE_MAX	0
++#define RSSI_ANT_MERGE_MIN	1
++#define RSSI_ANT_MERGE_AVG	2
++
++#define	PHY_TSSI_TABLE_SIZE	64
++#define	APHY_TSSI_TABLE_SIZE	256
++#define	TX_GAIN_TABLE_LENGTH	64
++#define	DEFAULT_11A_TXP_IDX	24
++#define NUM_TSSI_FRAMES        4
++#define	NULL_TSSI		0x7f
++#define	NULL_TSSI_W		0x7f7f
++
++#define PHY_PAPD_EPS_TBL_SIZE_LCNPHY 64
++
++#define LCNPHY_PERICAL_TEMPBASED_TXPWRCTRL 9
++
++#define PHY_TXPWR_MIN		10
++#define PHY_TXPWR_MIN_NPHY	8
++#define RADIOPWR_OVERRIDE_DEF	(-1)
++
++#define PWRTBL_NUM_COEFF	3
++
++#define SPURAVOID_DISABLE	0
++#define SPURAVOID_AUTO		1
++#define SPURAVOID_FORCEON	2
++#define SPURAVOID_FORCEON2	3
++
++#define PHY_SW_TIMER_FAST		15
++#define PHY_SW_TIMER_SLOW		60
++#define PHY_SW_TIMER_GLACIAL	120
++
++#define PHY_PERICAL_AUTO	0
++#define PHY_PERICAL_FULL	1
++#define PHY_PERICAL_PARTIAL	2
++
++#define PHY_PERICAL_NODELAY	0
++#define PHY_PERICAL_INIT_DELAY	5
++#define PHY_PERICAL_ASSOC_DELAY	5
++#define PHY_PERICAL_WDOG_DELAY	5
++
++#define MPHASE_TXCAL_NUMCMDS	2
++
++#define PHY_PERICAL_MPHASE_PENDING(pi) \
++	(pi->mphase_cal_phase_id > MPHASE_CAL_STATE_IDLE)
++
++enum {
++	MPHASE_CAL_STATE_IDLE = 0,
++	MPHASE_CAL_STATE_INIT = 1,
++	MPHASE_CAL_STATE_TXPHASE0,
++	MPHASE_CAL_STATE_TXPHASE1,
++	MPHASE_CAL_STATE_TXPHASE2,
++	MPHASE_CAL_STATE_TXPHASE3,
++	MPHASE_CAL_STATE_TXPHASE4,
++	MPHASE_CAL_STATE_TXPHASE5,
++	MPHASE_CAL_STATE_PAPDCAL,
++	MPHASE_CAL_STATE_RXCAL,
++	MPHASE_CAL_STATE_RSSICAL,
++	MPHASE_CAL_STATE_IDLETSSI
++};
++
++enum phy_cal_mode {
++	CAL_FULL,
++	CAL_RECAL,
++	CAL_CURRECAL,
++	CAL_DIGCAL,
++	CAL_GCTRL,
++	CAL_SOFT,
++	CAL_DIGLO
++};
++
++#define RDR_NTIERS  1
++#define RDR_TIER_SIZE 64
++#define RDR_LIST_SIZE (512/3)
++#define RDR_EPOCH_SIZE 40
++#define RDR_NANTENNAS 2
++#define RDR_NTIER_SIZE  RDR_LIST_SIZE
++#define RDR_LP_BUFFER_SIZE 64
++#define LP_LEN_HIS_SIZE 10
++
++#define STATIC_NUM_RF 32
++#define STATIC_NUM_BB 9
++
++#define BB_MULT_MASK		0x0000ffff
++#define BB_MULT_VALID_MASK	0x80000000
++
++#define CORDIC_AG	39797
++#define	CORDIC_NI	18
++#define	FIXED(X)	((s32)((X) << 16))
++
++#define	FLOAT(X) \
++	(((X) >= 0) ? ((((X) >> 15) + 1) >> 1) : -((((-(X)) >> 15) + 1) >> 1))
++
++#define PHY_CHAIN_TX_DISABLE_TEMP	115
++#define PHY_HYSTERESIS_DELTATEMP	5
++
++#define SCAN_INPROG_PHY(pi) \
++	(mboolisset(pi->measure_hold, PHY_HOLD_FOR_SCAN))
++
++#define PLT_INPROG_PHY(pi)      (mboolisset(pi->measure_hold, PHY_HOLD_FOR_PLT))
++
++#define ASSOC_INPROG_PHY(pi) \
++	(mboolisset(pi->measure_hold, PHY_HOLD_FOR_ASSOC))
++
++#define SCAN_RM_IN_PROGRESS(pi) \
++	(mboolisset(pi->measure_hold, PHY_HOLD_FOR_SCAN | PHY_HOLD_FOR_RM))
++
++#define PHY_MUTED(pi) \
++	(mboolisset(pi->measure_hold, PHY_HOLD_FOR_MUTE))
++
++#define PUB_NOT_ASSOC(pi) \
++	(mboolisset(pi->measure_hold, PHY_HOLD_FOR_NOT_ASSOC))
++
++struct phy_table_info {
++	uint table;
++	int q;
++	uint max;
++};
++
++struct phytbl_info {
++	const void *tbl_ptr;
++	u32 tbl_len;
++	u32 tbl_id;
++	u32 tbl_offset;
++	u32 tbl_width;
++};
++
++struct interference_info {
++	u8 curr_home_channel;
++	u16 crsminpwrthld_40_stored;
++	u16 crsminpwrthld_20L_stored;
++	u16 crsminpwrthld_20U_stored;
++	u16 init_gain_code_core1_stored;
++	u16 init_gain_code_core2_stored;
++	u16 init_gain_codeb_core1_stored;
++	u16 init_gain_codeb_core2_stored;
++	u16 init_gain_table_stored[4];
++
++	u16 clip1_hi_gain_code_core1_stored;
++	u16 clip1_hi_gain_code_core2_stored;
++	u16 clip1_hi_gain_codeb_core1_stored;
++	u16 clip1_hi_gain_codeb_core2_stored;
++	u16 nb_clip_thresh_core1_stored;
++	u16 nb_clip_thresh_core2_stored;
++	u16 init_ofdmlna2gainchange_stored[4];
++	u16 init_ccklna2gainchange_stored[4];
++	u16 clip1_lo_gain_code_core1_stored;
++	u16 clip1_lo_gain_code_core2_stored;
++	u16 clip1_lo_gain_codeb_core1_stored;
++	u16 clip1_lo_gain_codeb_core2_stored;
++	u16 w1_clip_thresh_core1_stored;
++	u16 w1_clip_thresh_core2_stored;
++	u16 radio_2056_core1_rssi_gain_stored;
++	u16 radio_2056_core2_rssi_gain_stored;
++	u16 energy_drop_timeout_len_stored;
++
++	u16 ed_crs40_assertthld0_stored;
++	u16 ed_crs40_assertthld1_stored;
++	u16 ed_crs40_deassertthld0_stored;
++	u16 ed_crs40_deassertthld1_stored;
++	u16 ed_crs20L_assertthld0_stored;
++	u16 ed_crs20L_assertthld1_stored;
++	u16 ed_crs20L_deassertthld0_stored;
++	u16 ed_crs20L_deassertthld1_stored;
++	u16 ed_crs20U_assertthld0_stored;
++	u16 ed_crs20U_assertthld1_stored;
++	u16 ed_crs20U_deassertthld0_stored;
++	u16 ed_crs20U_deassertthld1_stored;
++
++	u16 badplcp_ma;
++	u16 badplcp_ma_previous;
++	u16 badplcp_ma_total;
++	u16 badplcp_ma_list[MA_WINDOW_SZ];
++	int badplcp_ma_index;
++	s16 pre_badplcp_cnt;
++	s16 bphy_pre_badplcp_cnt;
++
++	u16 init_gain_core1;
++	u16 init_gain_core2;
++	u16 init_gainb_core1;
++	u16 init_gainb_core2;
++	u16 init_gain_rfseq[4];
++
++	u16 crsminpwr0;
++	u16 crsminpwrl0;
++	u16 crsminpwru0;
++
++	s16 crsminpwr_index;
++
++	u16 radio_2057_core1_rssi_wb1a_gc_stored;
++	u16 radio_2057_core2_rssi_wb1a_gc_stored;
++	u16 radio_2057_core1_rssi_wb1g_gc_stored;
++	u16 radio_2057_core2_rssi_wb1g_gc_stored;
++	u16 radio_2057_core1_rssi_wb2_gc_stored;
++	u16 radio_2057_core2_rssi_wb2_gc_stored;
++	u16 radio_2057_core1_rssi_nb_gc_stored;
++	u16 radio_2057_core2_rssi_nb_gc_stored;
++};
++
++struct aci_save_gphy {
++	u16 rc_cal_ovr;
++	u16 phycrsth1;
++	u16 phycrsth2;
++	u16 init_n1p1_gain;
++	u16 p1_p2_gain;
++	u16 n1_n2_gain;
++	u16 n1_p1_gain;
++	u16 div_search_gain;
++	u16 div_p1_p2_gain;
++	u16 div_search_gn_change;
++	u16 table_7_2;
++	u16 table_7_3;
++	u16 cckshbits_gnref;
++	u16 clip_thresh;
++	u16 clip2_thresh;
++	u16 clip3_thresh;
++	u16 clip_p2_thresh;
++	u16 clip_pwdn_thresh;
++	u16 clip_n1p1_thresh;
++	u16 clip_n1_pwdn_thresh;
++	u16 bbconfig;
++	u16 cthr_sthr_shdin;
++	u16 energy;
++	u16 clip_p1_p2_thresh;
++	u16 threshold;
++	u16 reg15;
++	u16 reg16;
++	u16 reg17;
++	u16 div_srch_idx;
++	u16 div_srch_p1_p2;
++	u16 div_srch_gn_back;
++	u16 ant_dwell;
++	u16 ant_wr_settle;
++};
++
++struct lo_complex_abgphy_info {
++	s8 i;
++	s8 q;
++};
++
++struct nphy_iq_comp {
++	s16 a0;
++	s16 b0;
++	s16 a1;
++	s16 b1;
++};
++
++struct nphy_txpwrindex {
++	s8 index;
++	s8 index_internal;
++	s8 index_internal_save;
++	u16 AfectrlOverride;
++	u16 AfeCtrlDacGain;
++	u16 rad_gain;
++	u8 bbmult;
++	u16 iqcomp_a;
++	u16 iqcomp_b;
++	u16 locomp;
++};
++
++struct txiqcal_cache {
++
++	u16 txcal_coeffs_2G[8];
++	u16 txcal_radio_regs_2G[8];
++	struct nphy_iq_comp rxcal_coeffs_2G;
++
++	u16 txcal_coeffs_5G[8];
++	u16 txcal_radio_regs_5G[8];
++	struct nphy_iq_comp rxcal_coeffs_5G;
++};
++
++struct nphy_pwrctrl {
++	s8 max_pwr_2g;
++	s8 idle_targ_2g;
++	s16 pwrdet_2g_a1;
++	s16 pwrdet_2g_b0;
++	s16 pwrdet_2g_b1;
++	s8 max_pwr_5gm;
++	s8 idle_targ_5gm;
++	s8 max_pwr_5gh;
++	s8 max_pwr_5gl;
++	s16 pwrdet_5gm_a1;
++	s16 pwrdet_5gm_b0;
++	s16 pwrdet_5gm_b1;
++	s16 pwrdet_5gl_a1;
++	s16 pwrdet_5gl_b0;
++	s16 pwrdet_5gl_b1;
++	s16 pwrdet_5gh_a1;
++	s16 pwrdet_5gh_b0;
++	s16 pwrdet_5gh_b1;
++	s8 idle_targ_5gl;
++	s8 idle_targ_5gh;
++	s8 idle_tssi_2g;
++	s8 idle_tssi_5g;
++	s8 idle_tssi;
++	s16 a1;
++	s16 b0;
++	s16 b1;
++};
++
++struct nphy_txgains {
++	u16 txlpf[2];
++	u16 txgm[2];
++	u16 pga[2];
++	u16 pad[2];
++	u16 ipa[2];
++};
++
++#define PHY_NOISEVAR_BUFSIZE 10
++
++struct nphy_noisevar_buf {
++	int bufcount;
++	int tone_id[PHY_NOISEVAR_BUFSIZE];
++	u32 noise_vars[PHY_NOISEVAR_BUFSIZE];
++	u32 min_noise_vars[PHY_NOISEVAR_BUFSIZE];
++};
++
++struct rssical_cache {
++	u16 rssical_radio_regs_2G[2];
++	u16 rssical_phyregs_2G[12];
++
++	u16 rssical_radio_regs_5G[2];
++	u16 rssical_phyregs_5G[12];
++};
++
++struct lcnphy_cal_results {
++
++	u16 txiqlocal_a;
++	u16 txiqlocal_b;
++	u16 txiqlocal_didq;
++	u8 txiqlocal_ei0;
++	u8 txiqlocal_eq0;
++	u8 txiqlocal_fi0;
++	u8 txiqlocal_fq0;
++
++	u16 txiqlocal_bestcoeffs[11];
++	u16 txiqlocal_bestcoeffs_valid;
++
++	u32 papd_eps_tbl[PHY_PAPD_EPS_TBL_SIZE_LCNPHY];
++	u16 analog_gain_ref;
++	u16 lut_begin;
++	u16 lut_end;
++	u16 lut_step;
++	u16 rxcompdbm;
++	u16 papdctrl;
++	u16 sslpnCalibClkEnCtrl;
++
++	u16 rxiqcal_coeff_a0;
++	u16 rxiqcal_coeff_b0;
++};
++
++struct shared_phy {
++	struct brcms_phy *phy_head;
++	uint unit;
++	struct si_pub *sih;
++	struct phy_shim_info *physhim;
++	uint corerev;
++	u32 machwcap;
++	bool up;
++	bool clk;
++	uint now;
++	u16 vid;
++	u16 did;
++	uint chip;
++	uint chiprev;
++	uint chippkg;
++	uint sromrev;
++	uint boardtype;
++	uint boardrev;
++	u32 boardflags;
++	u32 boardflags2;
++	uint fast_timer;
++	uint slow_timer;
++	uint glacial_timer;
++	u8 rx_antdiv;
++	s8 phy_noise_window[MA_WINDOW_SZ];
++	uint phy_noise_index;
++	u8 hw_phytxchain;
++	u8 hw_phyrxchain;
++	u8 phytxchain;
++	u8 phyrxchain;
++	u8 rssi_mode;
++	bool _rifs_phy;
++};
++
++struct brcms_phy_pub {
++	uint phy_type;
++	uint phy_rev;
++	u8 phy_corenum;
++	u16 radioid;
++	u8 radiorev;
++	u8 radiover;
++
++	uint coreflags;
++	uint ana_rev;
++	bool abgphy_encore;
++};
++
++struct phy_func_ptr {
++	void (*init)(struct brcms_phy *);
++	void (*calinit)(struct brcms_phy *);
++	void (*chanset)(struct brcms_phy *, u16 chanspec);
++	void (*txpwrrecalc)(struct brcms_phy *);
++	int (*longtrn)(struct brcms_phy *, int);
++	void (*txiqccget)(struct brcms_phy *, u16 *, u16 *);
++	void (*txiqccset)(struct brcms_phy *, u16, u16);
++	u16 (*txloccget)(struct brcms_phy *);
++	void (*radioloftget)(struct brcms_phy *, u8 *, u8 *, u8 *, u8 *);
++	void (*carrsuppr)(struct brcms_phy *);
++	s32 (*rxsigpwr)(struct brcms_phy *, s32);
++	void (*detach)(struct brcms_phy *);
++};
++
++struct brcms_phy {
++	struct brcms_phy_pub pubpi_ro;
++	struct shared_phy *sh;
++	struct phy_func_ptr pi_fptr;
++
++	union {
++		struct brcms_phy_lcnphy *pi_lcnphy;
++	} u;
++	bool user_txpwr_at_rfport;
++
++	struct bcma_device *d11core;
++	struct brcms_phy *next;
++	struct brcms_phy_pub pubpi;
++
++	bool do_initcal;
++	bool phytest_on;
++	bool ofdm_rateset_war;
++	bool bf_preempt_4306;
++	u16 radio_chanspec;
++	u8 antsel_type;
++	u16 bw;
++	u8 txpwr_percent;
++	bool phy_init_por;
++
++	bool init_in_progress;
++	bool initialized;
++	bool sbtml_gm;
++	uint refcnt;
++	bool watchdog_override;
++	u8 phynoise_state;
++	uint phynoise_now;
++	int phynoise_chan_watchdog;
++	bool phynoise_polling;
++	bool disable_percal;
++	u32 measure_hold;
++
++	s16 txpa_2g[PWRTBL_NUM_COEFF];
++	s16 txpa_2g_low_temp[PWRTBL_NUM_COEFF];
++	s16 txpa_2g_high_temp[PWRTBL_NUM_COEFF];
++	s16 txpa_5g_low[PWRTBL_NUM_COEFF];
++	s16 txpa_5g_mid[PWRTBL_NUM_COEFF];
++	s16 txpa_5g_hi[PWRTBL_NUM_COEFF];
++
++	u8 tx_srom_max_2g;
++	u8 tx_srom_max_5g_low;
++	u8 tx_srom_max_5g_mid;
++	u8 tx_srom_max_5g_hi;
++	u8 tx_srom_max_rate_2g[TXP_NUM_RATES];
++	u8 tx_srom_max_rate_5g_low[TXP_NUM_RATES];
++	u8 tx_srom_max_rate_5g_mid[TXP_NUM_RATES];
++	u8 tx_srom_max_rate_5g_hi[TXP_NUM_RATES];
++	u8 tx_user_target[TXP_NUM_RATES];
++	s8 tx_power_offset[TXP_NUM_RATES];
++	u8 tx_power_target[TXP_NUM_RATES];
++
++	struct brcms_phy_srom_fem srom_fem2g;
++	struct brcms_phy_srom_fem srom_fem5g;
++
++	u8 tx_power_max;
++	u8 tx_power_max_rate_ind;
++	bool hwpwrctrl;
++	u8 nphy_txpwrctrl;
++	s8 nphy_txrx_chain;
++	bool phy_5g_pwrgain;
++
++	u16 phy_wreg;
++	u16 phy_wreg_limit;
++
++	s8 n_preamble_override;
++	u8 antswitch;
++	u8 aa2g, aa5g;
++
++	s8 idle_tssi[CH_5G_GROUP];
++	s8 target_idle_tssi;
++	s8 txpwr_est_Pout;
++	u8 tx_power_min;
++	u8 txpwr_limit[TXP_NUM_RATES];
++	u8 txpwr_env_limit[TXP_NUM_RATES];
++	u8 adj_pwr_tbl_nphy[ADJ_PWR_TBL_LEN];
++
++	bool channel_14_wide_filter;
++
++	bool txpwroverride;
++	bool txpwridx_override_aphy;
++	s16 radiopwr_override;
++	u16 hwpwr_txcur;
++	u8 saved_txpwr_idx;
++
++	bool edcrs_threshold_lock;
++
++	u32 tr_R_gain_val;
++	u32 tr_T_gain_val;
++
++	s16 ofdm_analog_filt_bw_override;
++	s16 cck_analog_filt_bw_override;
++	s16 ofdm_rccal_override;
++	s16 cck_rccal_override;
++	u16 extlna_type;
++
++	uint interference_mode_crs_time;
++	u16 crsglitch_prev;
++	bool interference_mode_crs;
++
++	u32 phy_tx_tone_freq;
++	uint phy_lastcal;
++	bool phy_forcecal;
++	bool phy_fixed_noise;
++	u32 xtalfreq;
++	u8 pdiv;
++	s8 carrier_suppr_disable;
++
++	bool phy_bphy_evm;
++	bool phy_bphy_rfcs;
++	s8 phy_scraminit;
++	u8 phy_gpiosel;
++
++	s16 phy_txcore_disable_temp;
++	s16 phy_txcore_enable_temp;
++	s8 phy_tempsense_offset;
++	bool phy_txcore_heatedup;
++
++	u16 radiopwr;
++	u16 bb_atten;
++	u16 txctl1;
++
++	u16 mintxbias;
++	u16 mintxmag;
++	struct lo_complex_abgphy_info gphy_locomp_iq
++			[STATIC_NUM_RF][STATIC_NUM_BB];
++	s8 stats_11b_txpower[STATIC_NUM_RF][STATIC_NUM_BB];
++	u16 gain_table[TX_GAIN_TABLE_LENGTH];
++	bool loopback_gain;
++	s16 max_lpback_gain_hdB;
++	s16 trsw_rx_gain_hdB;
++	u8 power_vec[8];
++
++	u16 rc_cal;
++	int nrssi_table_delta;
++	int nrssi_slope_scale;
++	int nrssi_slope_offset;
++	int min_rssi;
++	int max_rssi;
++
++	s8 txpwridx;
++	u8 min_txpower;
++
++	u8 a_band_high_disable;
++
++	u16 tx_vos;
++	u16 global_tx_bb_dc_bias_loft;
++
++	int rf_max;
++	int bb_max;
++	int rf_list_size;
++	int bb_list_size;
++	u16 *rf_attn_list;
++	u16 *bb_attn_list;
++	u16 padmix_mask;
++	u16 padmix_reg;
++	u16 *txmag_list;
++	uint txmag_len;
++	bool txmag_enable;
++
++	s8 *a_tssi_to_dbm;
++	s8 *m_tssi_to_dbm;
++	s8 *l_tssi_to_dbm;
++	s8 *h_tssi_to_dbm;
++	u8 *hwtxpwr;
++
++	u16 freqtrack_saved_regs[2];
++	int cur_interference_mode;
++	bool hwpwrctrl_capable;
++	bool temppwrctrl_capable;
++
++	uint phycal_nslope;
++	uint phycal_noffset;
++	uint phycal_mlo;
++	uint phycal_txpower;
++
++	u8 phy_aa2g;
++
++	bool nphy_tableloaded;
++	s8 nphy_rssisel;
++	u32 nphy_bb_mult_save;
++	u16 nphy_txiqlocal_bestc[11];
++	bool nphy_txiqlocal_coeffsvalid;
++	struct nphy_txpwrindex nphy_txpwrindex[PHY_CORE_NUM_2];
++	struct nphy_pwrctrl nphy_pwrctrl_info[PHY_CORE_NUM_2];
++	u16 cck2gpo;
++	u32 ofdm2gpo;
++	u32 ofdm5gpo;
++	u32 ofdm5glpo;
++	u32 ofdm5ghpo;
++	u8 bw402gpo;
++	u8 bw405gpo;
++	u8 bw405glpo;
++	u8 bw405ghpo;
++	u8 cdd2gpo;
++	u8 cdd5gpo;
++	u8 cdd5glpo;
++	u8 cdd5ghpo;
++	u8 stbc2gpo;
++	u8 stbc5gpo;
++	u8 stbc5glpo;
++	u8 stbc5ghpo;
++	u8 bwdup2gpo;
++	u8 bwdup5gpo;
++	u8 bwdup5glpo;
++	u8 bwdup5ghpo;
++	u16 mcs2gpo[8];
++	u16 mcs5gpo[8];
++	u16 mcs5glpo[8];
++	u16 mcs5ghpo[8];
++	u32 nphy_rxcalparams;
++
++	u8 phy_spuravoid;
++	bool phy_isspuravoid;
++
++	u8 phy_pabias;
++	u8 nphy_papd_skip;
++	u8 nphy_tssi_slope;
++
++	s16 nphy_noise_win[PHY_CORE_MAX][PHY_NOISE_WINDOW_SZ];
++	u8 nphy_noise_index;
++
++	bool nphy_gain_boost;
++	bool nphy_elna_gain_config;
++	u16 old_bphy_test;
++	u16 old_bphy_testcontrol;
++
++	bool phyhang_avoid;
++
++	bool rssical_nphy;
++	u8 nphy_perical;
++	uint nphy_perical_last;
++	u8 cal_type_override;
++	u8 mphase_cal_phase_id;
++	u8 mphase_txcal_cmdidx;
++	u8 mphase_txcal_numcmds;
++	u16 mphase_txcal_bestcoeffs[11];
++	u16 nphy_txiqlocal_chanspec;
++	u16 nphy_iqcal_chanspec_2G;
++	u16 nphy_iqcal_chanspec_5G;
++	u16 nphy_rssical_chanspec_2G;
++	u16 nphy_rssical_chanspec_5G;
++	struct wlapi_timer *phycal_timer;
++	bool use_int_tx_iqlo_cal_nphy;
++	bool internal_tx_iqlo_cal_tapoff_intpa_nphy;
++	s16 nphy_lastcal_temp;
++
++	struct txiqcal_cache calibration_cache;
++	struct rssical_cache rssical_cache;
++
++	u8 nphy_txpwr_idx[2];
++	u8 nphy_papd_cal_type;
++	uint nphy_papd_last_cal;
++	u16 nphy_papd_tx_gain_at_last_cal[2];
++	u8 nphy_papd_cal_gain_index[2];
++	s16 nphy_papd_epsilon_offset[2];
++	bool nphy_papd_recal_enable;
++	u32 nphy_papd_recal_counter;
++	bool nphy_force_papd_cal;
++	bool nphy_papdcomp;
++	bool ipa2g_on;
++	bool ipa5g_on;
++
++	u16 classifier_state;
++	u16 clip_state[2];
++	uint nphy_deaf_count;
++	u8 rxiq_samps;
++	u8 rxiq_antsel;
++
++	u16 rfctrlIntc1_save;
++	u16 rfctrlIntc2_save;
++	bool first_cal_after_assoc;
++	u16 tx_rx_cal_radio_saveregs[22];
++	u16 tx_rx_cal_phy_saveregs[15];
++
++	u8 nphy_cal_orig_pwr_idx[2];
++	u8 nphy_txcal_pwr_idx[2];
++	u8 nphy_rxcal_pwr_idx[2];
++	u16 nphy_cal_orig_tx_gain[2];
++	struct nphy_txgains nphy_cal_target_gain;
++	u16 nphy_txcal_bbmult;
++	u16 nphy_gmval;
++
++	u16 nphy_saved_bbconf;
++
++	bool nphy_gband_spurwar_en;
++	bool nphy_gband_spurwar2_en;
++	bool nphy_aband_spurwar_en;
++	u16 nphy_rccal_value;
++	u16 nphy_crsminpwr[3];
++	struct nphy_noisevar_buf nphy_saved_noisevars;
++	bool nphy_anarxlpf_adjusted;
++	bool nphy_crsminpwr_adjusted;
++	bool nphy_noisevars_adjusted;
++
++	bool nphy_rxcal_active;
++	u16 radar_percal_mask;
++	bool dfs_lp_buffer_nphy;
++
++	u16 nphy_fineclockgatecontrol;
++
++	s8 rx2tx_biasentry;
++
++	u16 crsminpwr0;
++	u16 crsminpwrl0;
++	u16 crsminpwru0;
++	s16 noise_crsminpwr_index;
++	u16 init_gain_core1;
++	u16 init_gain_core2;
++	u16 init_gainb_core1;
++	u16 init_gainb_core2;
++	u8 aci_noise_curr_channel;
++	u16 init_gain_rfseq[4];
++
++	bool radio_is_on;
++
++	bool nphy_sample_play_lpf_bw_ctl_ovr;
++
++	u16 tbl_data_hi;
++	u16 tbl_data_lo;
++	u16 tbl_addr;
++
++	uint tbl_save_id;
++	uint tbl_save_offset;
++
++	u8 txpwrctrl;
++	s8 txpwrindex[PHY_CORE_MAX];
++
++	u8 phycal_tempdelta;
++	u32 mcs20_po;
++	u32 mcs40_po;
++	struct wiphy *wiphy;
++};
++
++struct cs32 {
++	s32 q;
++	s32 i;
++};
++
++struct radio_regs {
++	u16 address;
++	u32 init_a;
++	u32 init_g;
++	u8 do_init_a;
++	u8 do_init_g;
++};
++
++struct radio_20xx_regs {
++	u16 address;
++	u8 init;
++	u8 do_init;
++};
++
++struct lcnphy_radio_regs {
++	u16 address;
++	u8 init_a;
++	u8 init_g;
++	u8 do_init_a;
++	u8 do_init_g;
++};
++
++extern u16 read_phy_reg(struct brcms_phy *pi, u16 addr);
++extern void write_phy_reg(struct brcms_phy *pi, u16 addr, u16 val);
++extern void and_phy_reg(struct brcms_phy *pi, u16 addr, u16 val);
++extern void or_phy_reg(struct brcms_phy *pi, u16 addr, u16 val);
++extern void mod_phy_reg(struct brcms_phy *pi, u16 addr, u16 mask, u16 val);
++
++extern u16 read_radio_reg(struct brcms_phy *pi, u16 addr);
++extern void or_radio_reg(struct brcms_phy *pi, u16 addr, u16 val);
++extern void and_radio_reg(struct brcms_phy *pi, u16 addr, u16 val);
++extern void mod_radio_reg(struct brcms_phy *pi, u16 addr, u16 mask,
++			  u16 val);
++extern void xor_radio_reg(struct brcms_phy *pi, u16 addr, u16 mask);
++
++extern void write_radio_reg(struct brcms_phy *pi, u16 addr, u16 val);
++
++extern void wlc_phyreg_enter(struct brcms_phy_pub *pih);
++extern void wlc_phyreg_exit(struct brcms_phy_pub *pih);
++extern void wlc_radioreg_enter(struct brcms_phy_pub *pih);
++extern void wlc_radioreg_exit(struct brcms_phy_pub *pih);
++
++extern void wlc_phy_read_table(struct brcms_phy *pi,
++			       const struct phytbl_info *ptbl_info,
++			       u16 tblAddr, u16 tblDataHi,
++			       u16 tblDatalo);
++extern void wlc_phy_write_table(struct brcms_phy *pi,
++				const struct phytbl_info *ptbl_info,
++				u16 tblAddr, u16 tblDataHi, u16 tblDatalo);
++extern void wlc_phy_table_addr(struct brcms_phy *pi, uint tbl_id,
++			       uint tbl_offset, u16 tblAddr, u16 tblDataHi,
++			       u16 tblDataLo);
++extern void wlc_phy_table_data_write(struct brcms_phy *pi, uint width, u32 val);
++
++extern void write_phy_channel_reg(struct brcms_phy *pi, uint val);
++extern void wlc_phy_txpower_update_shm(struct brcms_phy *pi);
++
++extern u8 wlc_phy_nbits(s32 value);
++extern void wlc_phy_compute_dB(u32 *cmplx_pwr, s8 *p_dB, u8 core);
++
++extern uint wlc_phy_init_radio_regs_allbands(struct brcms_phy *pi,
++					     struct radio_20xx_regs *radioregs);
++extern uint wlc_phy_init_radio_regs(struct brcms_phy *pi,
++				    const struct radio_regs *radioregs,
++				    u16 core_offset);
++
++extern void wlc_phy_txpower_ipa_upd(struct brcms_phy *pi);
++
++extern void wlc_phy_do_dummy_tx(struct brcms_phy *pi, bool ofdm, bool pa_on);
++extern void wlc_phy_papd_decode_epsilon(u32 epsilon, s32 *eps_real,
++					s32 *eps_imag);
++
++extern void wlc_phy_cal_perical_mphase_reset(struct brcms_phy *pi);
++extern void wlc_phy_cal_perical_mphase_restart(struct brcms_phy *pi);
++
++extern bool wlc_phy_attach_nphy(struct brcms_phy *pi);
++extern bool wlc_phy_attach_lcnphy(struct brcms_phy *pi);
++
++extern void wlc_phy_detach_lcnphy(struct brcms_phy *pi);
++
++extern void wlc_phy_init_nphy(struct brcms_phy *pi);
++extern void wlc_phy_init_lcnphy(struct brcms_phy *pi);
++
++extern void wlc_phy_cal_init_nphy(struct brcms_phy *pi);
++extern void wlc_phy_cal_init_lcnphy(struct brcms_phy *pi);
++
++extern void wlc_phy_chanspec_set_nphy(struct brcms_phy *pi,
++				      u16 chanspec);
++extern void wlc_phy_chanspec_set_lcnphy(struct brcms_phy *pi,
++					u16 chanspec);
++extern void wlc_phy_chanspec_set_fixup_lcnphy(struct brcms_phy *pi,
++					      u16 chanspec);
++extern int wlc_phy_channel2freq(uint channel);
++extern int wlc_phy_chanspec_freq2bandrange_lpssn(uint);
++extern int wlc_phy_chanspec_bandrange_get(struct brcms_phy *, u16 chanspec);
++
++extern void wlc_lcnphy_set_tx_pwr_ctrl(struct brcms_phy *pi, u16 mode);
++extern s8 wlc_lcnphy_get_current_tx_pwr_idx(struct brcms_phy *pi);
++
++extern void wlc_phy_txpower_recalc_target_nphy(struct brcms_phy *pi);
++extern void wlc_lcnphy_txpower_recalc_target(struct brcms_phy *pi);
++extern void wlc_phy_txpower_recalc_target_lcnphy(struct brcms_phy *pi);
++
++extern void wlc_lcnphy_set_tx_pwr_by_index(struct brcms_phy *pi, int index);
++extern void wlc_lcnphy_tx_pu(struct brcms_phy *pi, bool bEnable);
++extern void wlc_lcnphy_stop_tx_tone(struct brcms_phy *pi);
++extern void wlc_lcnphy_start_tx_tone(struct brcms_phy *pi, s32 f_kHz,
++				     u16 max_val, bool iqcalmode);
++
++extern void wlc_phy_txpower_sromlimit_get_nphy(struct brcms_phy *pi, uint chan,
++					       u8 *max_pwr, u8 rate_id);
++extern void wlc_phy_ofdm_to_mcs_powers_nphy(u8 *power, u8 rate_mcs_start,
++					    u8 rate_mcs_end,
++					    u8 rate_ofdm_start);
++extern void wlc_phy_mcs_to_ofdm_powers_nphy(u8 *power,
++					    u8 rate_ofdm_start,
++					    u8 rate_ofdm_end,
++					    u8 rate_mcs_start);
++
++extern u16 wlc_lcnphy_tempsense(struct brcms_phy *pi, bool mode);
++extern s16 wlc_lcnphy_tempsense_new(struct brcms_phy *pi, bool mode);
++extern s8 wlc_lcnphy_tempsense_degree(struct brcms_phy *pi, bool mode);
++extern s8 wlc_lcnphy_vbatsense(struct brcms_phy *pi, bool mode);
++extern void wlc_phy_carrier_suppress_lcnphy(struct brcms_phy *pi);
++extern void wlc_lcnphy_crsuprs(struct brcms_phy *pi, int channel);
++extern void wlc_lcnphy_epa_switch(struct brcms_phy *pi, bool mode);
++extern void wlc_2064_vco_cal(struct brcms_phy *pi);
++
++extern void wlc_phy_txpower_recalc_target(struct brcms_phy *pi);
++
++#define LCNPHY_TBL_ID_PAPDCOMPDELTATBL	0x18
++#define LCNPHY_TX_POWER_TABLE_SIZE	128
++#define LCNPHY_MAX_TX_POWER_INDEX	(LCNPHY_TX_POWER_TABLE_SIZE - 1)
++#define LCNPHY_TBL_ID_TXPWRCTL	0x07
++#define LCNPHY_TX_PWR_CTRL_OFF	0
++#define LCNPHY_TX_PWR_CTRL_SW		(0x1 << 15)
++#define LCNPHY_TX_PWR_CTRL_HW         ((0x1 << 15) | \
++					(0x1 << 14) | \
++					(0x1 << 13))
++
++#define LCNPHY_TX_PWR_CTRL_TEMPBASED	0xE001
++
++extern void wlc_lcnphy_write_table(struct brcms_phy *pi,
++				   const struct phytbl_info *pti);
++extern void wlc_lcnphy_read_table(struct brcms_phy *pi,
++				  struct phytbl_info *pti);
++extern void wlc_lcnphy_set_tx_iqcc(struct brcms_phy *pi, u16 a, u16 b);
++extern void wlc_lcnphy_set_tx_locc(struct brcms_phy *pi, u16 didq);
++extern void wlc_lcnphy_get_tx_iqcc(struct brcms_phy *pi, u16 *a, u16 *b);
++extern u16 wlc_lcnphy_get_tx_locc(struct brcms_phy *pi);
++extern void wlc_lcnphy_get_radio_loft(struct brcms_phy *pi, u8 *ei0,
++				      u8 *eq0, u8 *fi0, u8 *fq0);
++extern void wlc_lcnphy_calib_modes(struct brcms_phy *pi, uint mode);
++extern void wlc_lcnphy_deaf_mode(struct brcms_phy *pi, bool mode);
++extern bool wlc_phy_tpc_isenabled_lcnphy(struct brcms_phy *pi);
++extern void wlc_lcnphy_tx_pwr_update_npt(struct brcms_phy *pi);
++extern s32 wlc_lcnphy_tssi2dbm(s32 tssi, s32 a1, s32 b0, s32 b1);
++extern void wlc_lcnphy_get_tssi(struct brcms_phy *pi, s8 *ofdm_pwr,
++				s8 *cck_pwr);
++extern void wlc_lcnphy_tx_power_adjustment(struct brcms_phy_pub *ppi);
++
++extern s32 wlc_lcnphy_rx_signal_power(struct brcms_phy *pi, s32 gain_index);
++
++#define NPHY_MAX_HPVGA1_INDEX		10
++#define NPHY_DEF_HPVGA1_INDEXLIMIT	7
++
++struct phy_iq_est {
++	s32 iq_prod;
++	u32 i_pwr;
++	u32 q_pwr;
++};
++
++extern void wlc_phy_stay_in_carriersearch_nphy(struct brcms_phy *pi,
++					       bool enable);
++extern void wlc_nphy_deaf_mode(struct brcms_phy *pi, bool mode);
++
++#define wlc_phy_write_table_nphy(pi, pti) \
++	wlc_phy_write_table(pi, pti, 0x72, 0x74, 0x73)
++
++#define wlc_phy_read_table_nphy(pi, pti) \
++	wlc_phy_read_table(pi, pti, 0x72, 0x74, 0x73)
++
++#define wlc_nphy_table_addr(pi, id, off) \
++	wlc_phy_table_addr((pi), (id), (off), 0x72, 0x74, 0x73)
++
++#define wlc_nphy_table_data_write(pi, w, v) \
++	wlc_phy_table_data_write((pi), (w), (v))
++
++extern void wlc_phy_table_read_nphy(struct brcms_phy *pi, u32, u32 l, u32 o,
++				    u32 w, void *d);
++extern void wlc_phy_table_write_nphy(struct brcms_phy *pi, u32, u32, u32,
++				     u32, const void *);
++
++#define	PHY_IPA(pi) \
++	((pi->ipa2g_on && CHSPEC_IS2G(pi->radio_chanspec)) || \
++	 (pi->ipa5g_on && CHSPEC_IS5G(pi->radio_chanspec)))
++
++#define BRCMS_PHY_WAR_PR51571(pi) \
++	if (NREV_LT((pi)->pubpi.phy_rev, 3)) \
++		(void)bcma_read32(pi->d11core, D11REGOFFS(maccontrol))
++
++extern void wlc_phy_cal_perical_nphy_run(struct brcms_phy *pi, u8 caltype);
++extern void wlc_phy_aci_reset_nphy(struct brcms_phy *pi);
++extern void wlc_phy_pa_override_nphy(struct brcms_phy *pi, bool en);
++
++extern u8 wlc_phy_get_chan_freq_range_nphy(struct brcms_phy *pi, uint chan);
++extern void wlc_phy_switch_radio_nphy(struct brcms_phy *pi, bool on);
++
++extern void wlc_phy_stf_chain_upd_nphy(struct brcms_phy *pi);
++
++extern void wlc_phy_force_rfseq_nphy(struct brcms_phy *pi, u8 cmd);
++extern s16 wlc_phy_tempsense_nphy(struct brcms_phy *pi);
++
++extern u16 wlc_phy_classifier_nphy(struct brcms_phy *pi, u16 mask, u16 val);
++
++extern void wlc_phy_rx_iq_est_nphy(struct brcms_phy *pi, struct phy_iq_est *est,
++				   u16 num_samps, u8 wait_time,
++				   u8 wait_for_crs);
++
++extern void wlc_phy_rx_iq_coeffs_nphy(struct brcms_phy *pi, u8 write,
++				      struct nphy_iq_comp *comp);
++extern void wlc_phy_aci_and_noise_reduction_nphy(struct brcms_phy *pi);
++
++extern void wlc_phy_rxcore_setstate_nphy(struct brcms_phy_pub *pih,
++					 u8 rxcore_bitmask);
++extern u8 wlc_phy_rxcore_getstate_nphy(struct brcms_phy_pub *pih);
++
++extern void wlc_phy_txpwrctrl_enable_nphy(struct brcms_phy *pi, u8 ctrl_type);
++extern void wlc_phy_txpwr_fixpower_nphy(struct brcms_phy *pi);
++extern void wlc_phy_txpwr_apply_nphy(struct brcms_phy *pi);
++extern void wlc_phy_txpwr_papd_cal_nphy(struct brcms_phy *pi);
++extern u16 wlc_phy_txpwr_idx_get_nphy(struct brcms_phy *pi);
++
++extern struct nphy_txgains wlc_phy_get_tx_gain_nphy(struct brcms_phy *pi);
++extern int wlc_phy_cal_txiqlo_nphy(struct brcms_phy *pi,
++				   struct nphy_txgains target_gain,
++				   bool full, bool m);
++extern int wlc_phy_cal_rxiq_nphy(struct brcms_phy *pi,
++				 struct nphy_txgains target_gain,
++				 u8 type, bool d);
++extern void wlc_phy_txpwr_index_nphy(struct brcms_phy *pi, u8 core_mask,
++				     s8 txpwrindex, bool res);
++extern void wlc_phy_rssisel_nphy(struct brcms_phy *pi, u8 core, u8 rssi_type);
++extern int wlc_phy_poll_rssi_nphy(struct brcms_phy *pi, u8 rssi_type,
++				  s32 *rssi_buf, u8 nsamps);
++extern void wlc_phy_rssi_cal_nphy(struct brcms_phy *pi);
++extern int wlc_phy_aci_scan_nphy(struct brcms_phy *pi);
++extern void wlc_phy_cal_txgainctrl_nphy(struct brcms_phy *pi,
++					s32 dBm_targetpower, bool debug);
++extern int wlc_phy_tx_tone_nphy(struct brcms_phy *pi, u32 f_kHz, u16 max_val,
++				u8 mode, u8, bool);
++extern void wlc_phy_stopplayback_nphy(struct brcms_phy *pi);
++extern void wlc_phy_est_tonepwr_nphy(struct brcms_phy *pi, s32 *qdBm_pwrbuf,
++				     u8 num_samps);
++extern void wlc_phy_radio205x_vcocal_nphy(struct brcms_phy *pi);
++
++extern int wlc_phy_rssi_compute_nphy(struct brcms_phy *pi,
++				     struct d11rxhdr *rxh);
++
++#define NPHY_TESTPATTERN_BPHY_EVM   0
++#define NPHY_TESTPATTERN_BPHY_RFCS  1
++
++extern void wlc_phy_nphy_tkip_rifs_war(struct brcms_phy *pi, u8 rifs);
++
++void wlc_phy_get_pwrdet_offsets(struct brcms_phy *pi, s8 *cckoffset,
++				s8 *ofdmoffset);
++extern s8 wlc_phy_upd_rssi_offset(struct brcms_phy *pi, s8 rssi,
++				  u16 chanspec);
++
++extern bool wlc_phy_n_txpower_ipa_ison(struct brcms_phy *pih);
++#endif				/* _BRCM_PHY_INT_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
+new file mode 100644
+index 0000000..abfd788
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
+@@ -0,0 +1,5137 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#include <linux/kernel.h>
++#include <linux/delay.h>
++#include <linux/cordic.h>
++
++#include <pmu.h>
++#include <d11.h>
++#include <phy_shim.h>
++#include "phy_qmath.h"
++#include "phy_hal.h"
++#include "phy_radio.h"
++#include "phytbl_lcn.h"
++#include "phy_lcn.h"
++
++#define PLL_2064_NDIV		90
++#define PLL_2064_LOW_END_VCO	3000
++#define PLL_2064_LOW_END_KVCO	27
++#define PLL_2064_HIGH_END_VCO	4200
++#define PLL_2064_HIGH_END_KVCO	68
++#define PLL_2064_LOOP_BW_DOUBLER	200
++#define PLL_2064_D30_DOUBLER		10500
++#define PLL_2064_LOOP_BW	260
++#define PLL_2064_D30		8000
++#define PLL_2064_CAL_REF_TO	8
++#define PLL_2064_MHZ		1000000
++#define PLL_2064_OPEN_LOOP_DELAY	5
++
++#define TEMPSENSE			1
++#define VBATSENSE           2
++
++#define NOISE_IF_UPD_CHK_INTERVAL	1
++#define NOISE_IF_UPD_RST_INTERVAL	60
++#define NOISE_IF_UPD_THRESHOLD_CNT	1
++#define NOISE_IF_UPD_TRHRESHOLD	50
++#define NOISE_IF_UPD_TIMEOUT		1000
++#define NOISE_IF_OFF			0
++#define NOISE_IF_CHK			1
++#define NOISE_IF_ON			2
++
++#define PAPD_BLANKING_PROFILE		3
++#define PAPD2LUT			0
++#define PAPD_CORR_NORM			0
++#define PAPD_BLANKING_THRESHOLD		0
++#define PAPD_STOP_AFTER_LAST_UPDATE	0
++
++#define LCN_TARGET_PWR  60
++
++#define LCN_VBAT_OFFSET_433X 34649679
++#define LCN_VBAT_SLOPE_433X  8258032
++
++#define LCN_VBAT_SCALE_NOM  53
++#define LCN_VBAT_SCALE_DEN  432
++
++#define LCN_TEMPSENSE_OFFSET  80812
++#define LCN_TEMPSENSE_DEN  2647
++
++#define LCN_BW_LMT	200
++#define LCN_CUR_LMT	1250
++#define LCN_MULT	1
++#define LCN_VCO_DIV	30
++#define LCN_OFFSET	680
++#define LCN_FACT	490
++#define LCN_CUR_DIV	2640
++
++#define LCNPHY_txgainctrlovrval1_pagain_ovr_val1_SHIFT \
++	(0 + 8)
++#define LCNPHY_txgainctrlovrval1_pagain_ovr_val1_MASK \
++	(0x7f << LCNPHY_txgainctrlovrval1_pagain_ovr_val1_SHIFT)
++
++#define LCNPHY_stxtxgainctrlovrval1_pagain_ovr_val1_SHIFT \
++	(0 + 8)
++#define LCNPHY_stxtxgainctrlovrval1_pagain_ovr_val1_MASK \
++	(0x7f << LCNPHY_stxtxgainctrlovrval1_pagain_ovr_val1_SHIFT)
++
++#define wlc_lcnphy_enable_tx_gain_override(pi) \
++	wlc_lcnphy_set_tx_gain_override(pi, true)
++#define wlc_lcnphy_disable_tx_gain_override(pi)	\
++	wlc_lcnphy_set_tx_gain_override(pi, false)
++
++#define wlc_lcnphy_iqcal_active(pi)	\
++	(read_phy_reg((pi), 0x451) & \
++	 ((0x1 << 15) | (0x1 << 14)))
++
++#define txpwrctrl_off(pi) (0x7 != ((read_phy_reg(pi, 0x4a4) & 0xE000) >> 13))
++#define wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)	\
++	(pi->temppwrctrl_capable)
++#define wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi) \
++	(pi->hwpwrctrl_capable)
++
++#define SWCTRL_BT_TX		0x18
++#define SWCTRL_OVR_DISABLE	0x40
++
++#define	AFE_CLK_INIT_MODE_TXRX2X	1
++#define	AFE_CLK_INIT_MODE_PAPD		0
++
++#define LCNPHY_TBL_ID_IQLOCAL			0x00
++
++#define LCNPHY_TBL_ID_RFSEQ         0x08
++#define LCNPHY_TBL_ID_GAIN_IDX		0x0d
++#define LCNPHY_TBL_ID_SW_CTRL			0x0f
++#define LCNPHY_TBL_ID_GAIN_TBL		0x12
++#define LCNPHY_TBL_ID_SPUR			0x14
++#define LCNPHY_TBL_ID_SAMPLEPLAY		0x15
++#define LCNPHY_TBL_ID_SAMPLEPLAY1		0x16
++
++#define LCNPHY_TX_PWR_CTRL_RATE_OFFSET	832
++#define LCNPHY_TX_PWR_CTRL_MAC_OFFSET	128
++#define LCNPHY_TX_PWR_CTRL_GAIN_OFFSET	192
++#define LCNPHY_TX_PWR_CTRL_IQ_OFFSET		320
++#define LCNPHY_TX_PWR_CTRL_LO_OFFSET		448
++#define LCNPHY_TX_PWR_CTRL_PWR_OFFSET		576
++
++#define LCNPHY_TX_PWR_CTRL_START_INDEX_2G_4313	140
++
++#define LCNPHY_TX_PWR_CTRL_START_NPT		1
++#define LCNPHY_TX_PWR_CTRL_MAX_NPT			7
++
++#define LCNPHY_NOISE_SAMPLES_DEFAULT 5000
++
++#define LCNPHY_ACI_DETECT_START      1
++#define LCNPHY_ACI_DETECT_PROGRESS   2
++#define LCNPHY_ACI_DETECT_STOP       3
++
++#define LCNPHY_ACI_CRSHIFRMLO_TRSH 100
++#define LCNPHY_ACI_GLITCH_TRSH 2000
++#define	LCNPHY_ACI_TMOUT 250
++#define LCNPHY_ACI_DETECT_TIMEOUT  2
++#define LCNPHY_ACI_START_DELAY 0
++
++#define wlc_lcnphy_tx_gain_override_enabled(pi)	\
++	(0 != (read_phy_reg((pi), 0x43b) & (0x1 << 6)))
++
++#define wlc_lcnphy_total_tx_frames(pi) \
++	wlapi_bmac_read_shm((pi)->sh->physhim, M_UCODE_MACSTAT + \
++			    offsetof(struct macstat, txallfrm))
++
++struct lcnphy_txgains {
++	u16 gm_gain;
++	u16 pga_gain;
++	u16 pad_gain;
++	u16 dac_gain;
++};
++
++enum lcnphy_cal_mode {
++	LCNPHY_CAL_FULL,
++	LCNPHY_CAL_RECAL,
++	LCNPHY_CAL_CURRECAL,
++	LCNPHY_CAL_DIGCAL,
++	LCNPHY_CAL_GCTRL
++};
++
++struct lcnphy_rx_iqcomp {
++	u8 chan;
++	s16 a;
++	s16 b;
++};
++
++struct lcnphy_spb_tone {
++	s16 re;
++	s16 im;
++};
++
++struct lcnphy_unsign16_struct {
++	u16 re;
++	u16 im;
++};
++
++struct lcnphy_iq_est {
++	u32 iq_prod;
++	u32 i_pwr;
++	u32 q_pwr;
++};
++
++struct lcnphy_sfo_cfg {
++	u16 ptcentreTs20;
++	u16 ptcentreFactor;
++};
++
++enum lcnphy_papd_cal_type {
++	LCNPHY_PAPD_CAL_CW,
++	LCNPHY_PAPD_CAL_OFDM
++};
++
++typedef u16 iqcal_gain_params_lcnphy[9];
++
++static const iqcal_gain_params_lcnphy tbl_iqcal_gainparams_lcnphy_2G[] = {
++	{0, 0, 0, 0, 0, 0, 0, 0, 0},
++};
++
++static const iqcal_gain_params_lcnphy *tbl_iqcal_gainparams_lcnphy[1] = {
++	tbl_iqcal_gainparams_lcnphy_2G,
++};
++
++static const u16 iqcal_gainparams_numgains_lcnphy[1] = {
++	ARRAY_SIZE(tbl_iqcal_gainparams_lcnphy_2G),
++};
++
++static const struct lcnphy_sfo_cfg lcnphy_sfo_cfg[] = {
++	{965, 1087},
++	{967, 1085},
++	{969, 1082},
++	{971, 1080},
++	{973, 1078},
++	{975, 1076},
++	{977, 1073},
++	{979, 1071},
++	{981, 1069},
++	{983, 1067},
++	{985, 1065},
++	{987, 1063},
++	{989, 1060},
++	{994, 1055}
++};
++
++static const
++u16 lcnphy_iqcal_loft_gainladder[] = {
++	((2 << 8) | 0),
++	((3 << 8) | 0),
++	((4 << 8) | 0),
++	((6 << 8) | 0),
++	((8 << 8) | 0),
++	((11 << 8) | 0),
++	((16 << 8) | 0),
++	((16 << 8) | 1),
++	((16 << 8) | 2),
++	((16 << 8) | 3),
++	((16 << 8) | 4),
++	((16 << 8) | 5),
++	((16 << 8) | 6),
++	((16 << 8) | 7),
++	((23 << 8) | 7),
++	((32 << 8) | 7),
++	((45 << 8) | 7),
++	((64 << 8) | 7),
++	((91 << 8) | 7),
++	((128 << 8) | 7)
++};
++
++static const
++u16 lcnphy_iqcal_ir_gainladder[] = {
++	((1 << 8) | 0),
++	((2 << 8) | 0),
++	((4 << 8) | 0),
++	((6 << 8) | 0),
++	((8 << 8) | 0),
++	((11 << 8) | 0),
++	((16 << 8) | 0),
++	((23 << 8) | 0),
++	((32 << 8) | 0),
++	((45 << 8) | 0),
++	((64 << 8) | 0),
++	((64 << 8) | 1),
++	((64 << 8) | 2),
++	((64 << 8) | 3),
++	((64 << 8) | 4),
++	((64 << 8) | 5),
++	((64 << 8) | 6),
++	((64 << 8) | 7),
++	((91 << 8) | 7),
++	((128 << 8) | 7)
++};
++
++static const
++struct lcnphy_spb_tone lcnphy_spb_tone_3750[] = {
++	{88, 0},
++	{73, 49},
++	{34, 81},
++	{-17, 86},
++	{-62, 62},
++	{-86, 17},
++	{-81, -34},
++	{-49, -73},
++	{0, -88},
++	{49, -73},
++	{81, -34},
++	{86, 17},
++	{62, 62},
++	{17, 86},
++	{-34, 81},
++	{-73, 49},
++	{-88, 0},
++	{-73, -49},
++	{-34, -81},
++	{17, -86},
++	{62, -62},
++	{86, -17},
++	{81, 34},
++	{49, 73},
++	{0, 88},
++	{-49, 73},
++	{-81, 34},
++	{-86, -17},
++	{-62, -62},
++	{-17, -86},
++	{34, -81},
++	{73, -49},
++};
++
++static const
++u16 iqlo_loopback_rf_regs[20] = {
++	RADIO_2064_REG036,
++	RADIO_2064_REG11A,
++	RADIO_2064_REG03A,
++	RADIO_2064_REG025,
++	RADIO_2064_REG028,
++	RADIO_2064_REG005,
++	RADIO_2064_REG112,
++	RADIO_2064_REG0FF,
++	RADIO_2064_REG11F,
++	RADIO_2064_REG00B,
++	RADIO_2064_REG113,
++	RADIO_2064_REG007,
++	RADIO_2064_REG0FC,
++	RADIO_2064_REG0FD,
++	RADIO_2064_REG012,
++	RADIO_2064_REG057,
++	RADIO_2064_REG059,
++	RADIO_2064_REG05C,
++	RADIO_2064_REG078,
++	RADIO_2064_REG092,
++};
++
++static const
++u16 tempsense_phy_regs[14] = {
++	0x503,
++	0x4a4,
++	0x4d0,
++	0x4d9,
++	0x4da,
++	0x4a6,
++	0x938,
++	0x939,
++	0x4d8,
++	0x4d0,
++	0x4d7,
++	0x4a5,
++	0x40d,
++	0x4a2,
++};
++
++static const
++u16 rxiq_cal_rf_reg[11] = {
++	RADIO_2064_REG098,
++	RADIO_2064_REG116,
++	RADIO_2064_REG12C,
++	RADIO_2064_REG06A,
++	RADIO_2064_REG00B,
++	RADIO_2064_REG01B,
++	RADIO_2064_REG113,
++	RADIO_2064_REG01D,
++	RADIO_2064_REG114,
++	RADIO_2064_REG02E,
++	RADIO_2064_REG12A,
++};
++
++static const
++struct lcnphy_rx_iqcomp lcnphy_rx_iqcomp_table_rev0[] = {
++	{1, 0, 0},
++	{2, 0, 0},
++	{3, 0, 0},
++	{4, 0, 0},
++	{5, 0, 0},
++	{6, 0, 0},
++	{7, 0, 0},
++	{8, 0, 0},
++	{9, 0, 0},
++	{10, 0, 0},
++	{11, 0, 0},
++	{12, 0, 0},
++	{13, 0, 0},
++	{14, 0, 0},
++	{34, 0, 0},
++	{38, 0, 0},
++	{42, 0, 0},
++	{46, 0, 0},
++	{36, 0, 0},
++	{40, 0, 0},
++	{44, 0, 0},
++	{48, 0, 0},
++	{52, 0, 0},
++	{56, 0, 0},
++	{60, 0, 0},
++	{64, 0, 0},
++	{100, 0, 0},
++	{104, 0, 0},
++	{108, 0, 0},
++	{112, 0, 0},
++	{116, 0, 0},
++	{120, 0, 0},
++	{124, 0, 0},
++	{128, 0, 0},
++	{132, 0, 0},
++	{136, 0, 0},
++	{140, 0, 0},
++	{149, 0, 0},
++	{153, 0, 0},
++	{157, 0, 0},
++	{161, 0, 0},
++	{165, 0, 0},
++	{184, 0, 0},
++	{188, 0, 0},
++	{192, 0, 0},
++	{196, 0, 0},
++	{200, 0, 0},
++	{204, 0, 0},
++	{208, 0, 0},
++	{212, 0, 0},
++	{216, 0, 0},
++};
++
++static const u32 lcnphy_23bitgaincode_table[] = {
++	0x200100,
++	0x200200,
++	0x200004,
++	0x200014,
++	0x200024,
++	0x200034,
++	0x200134,
++	0x200234,
++	0x200334,
++	0x200434,
++	0x200037,
++	0x200137,
++	0x200237,
++	0x200337,
++	0x200437,
++	0x000035,
++	0x000135,
++	0x000235,
++	0x000037,
++	0x000137,
++	0x000237,
++	0x000337,
++	0x00013f,
++	0x00023f,
++	0x00033f,
++	0x00034f,
++	0x00044f,
++	0x00144f,
++	0x00244f,
++	0x00254f,
++	0x00354f,
++	0x00454f,
++	0x00464f,
++	0x01464f,
++	0x02464f,
++	0x03464f,
++	0x04464f,
++};
++
++static const s8 lcnphy_gain_table[] = {
++	-16,
++	-13,
++	10,
++	7,
++	4,
++	0,
++	3,
++	6,
++	9,
++	12,
++	15,
++	18,
++	21,
++	24,
++	27,
++	30,
++	33,
++	36,
++	39,
++	42,
++	45,
++	48,
++	50,
++	53,
++	56,
++	59,
++	62,
++	65,
++	68,
++	71,
++	74,
++	77,
++	80,
++	83,
++	86,
++	89,
++	92,
++};
++
++static const s8 lcnphy_gain_index_offset_for_rssi[] = {
++	7,
++	7,
++	7,
++	7,
++	7,
++	7,
++	7,
++	8,
++	7,
++	7,
++	6,
++	7,
++	7,
++	4,
++	4,
++	4,
++	4,
++	4,
++	4,
++	4,
++	4,
++	3,
++	3,
++	3,
++	3,
++	3,
++	3,
++	4,
++	2,
++	2,
++	2,
++	2,
++	2,
++	2,
++	-1,
++	-2,
++	-2,
++	-2
++};
++
++struct chan_info_2064_lcnphy {
++	uint chan;
++	uint freq;
++	u8 logen_buftune;
++	u8 logen_rccr_tx;
++	u8 txrf_mix_tune_ctrl;
++	u8 pa_input_tune_g;
++	u8 logen_rccr_rx;
++	u8 pa_rxrf_lna1_freq_tune;
++	u8 pa_rxrf_lna2_freq_tune;
++	u8 rxrf_rxrf_spare1;
++};
++
++static const struct chan_info_2064_lcnphy chan_info_2064_lcnphy[] = {
++	{1, 2412, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
++	{2, 2417, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
++	{3, 2422, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
++	{4, 2427, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
++	{5, 2432, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
++	{6, 2437, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
++	{7, 2442, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
++	{8, 2447, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
++	{9, 2452, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
++	{10, 2457, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
++	{11, 2462, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
++	{12, 2467, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
++	{13, 2472, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
++	{14, 2484, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
++};
++
++static const struct lcnphy_radio_regs lcnphy_radio_regs_2064[] = {
++	{0x00, 0, 0, 0, 0},
++	{0x01, 0x64, 0x64, 0, 0},
++	{0x02, 0x20, 0x20, 0, 0},
++	{0x03, 0x66, 0x66, 0, 0},
++	{0x04, 0xf8, 0xf8, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0x10, 0x10, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0, 0, 0, 0},
++	{0x0A, 0x37, 0x37, 0, 0},
++	{0x0B, 0x6, 0x6, 0, 0},
++	{0x0C, 0x55, 0x55, 0, 0},
++	{0x0D, 0x8b, 0x8b, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0x5, 0x5, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0xe, 0xe, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0xb, 0xb, 0, 0},
++	{0x14, 0x2, 0x2, 0, 0},
++	{0x15, 0x12, 0x12, 0, 0},
++	{0x16, 0x12, 0x12, 0, 0},
++	{0x17, 0xc, 0xc, 0, 0},
++	{0x18, 0xc, 0xc, 0, 0},
++	{0x19, 0xc, 0xc, 0, 0},
++	{0x1A, 0x8, 0x8, 0, 0},
++	{0x1B, 0x2, 0x2, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0x1, 0x1, 0, 0},
++	{0x1E, 0x12, 0x12, 0, 0},
++	{0x1F, 0x6e, 0x6e, 0, 0},
++	{0x20, 0x2, 0x2, 0, 0},
++	{0x21, 0x23, 0x23, 0, 0},
++	{0x22, 0x8, 0x8, 0, 0},
++	{0x23, 0, 0, 0, 0},
++	{0x24, 0, 0, 0, 0},
++	{0x25, 0xc, 0xc, 0, 0},
++	{0x26, 0x33, 0x33, 0, 0},
++	{0x27, 0x55, 0x55, 0, 0},
++	{0x28, 0, 0, 0, 0},
++	{0x29, 0x30, 0x30, 0, 0},
++	{0x2A, 0xb, 0xb, 0, 0},
++	{0x2B, 0x1b, 0x1b, 0, 0},
++	{0x2C, 0x3, 0x3, 0, 0},
++	{0x2D, 0x1b, 0x1b, 0, 0},
++	{0x2E, 0, 0, 0, 0},
++	{0x2F, 0x20, 0x20, 0, 0},
++	{0x30, 0xa, 0xa, 0, 0},
++	{0x31, 0, 0, 0, 0},
++	{0x32, 0x62, 0x62, 0, 0},
++	{0x33, 0x19, 0x19, 0, 0},
++	{0x34, 0x33, 0x33, 0, 0},
++	{0x35, 0x77, 0x77, 0, 0},
++	{0x36, 0, 0, 0, 0},
++	{0x37, 0x70, 0x70, 0, 0},
++	{0x38, 0x3, 0x3, 0, 0},
++	{0x39, 0xf, 0xf, 0, 0},
++	{0x3A, 0x6, 0x6, 0, 0},
++	{0x3B, 0xcf, 0xcf, 0, 0},
++	{0x3C, 0x1a, 0x1a, 0, 0},
++	{0x3D, 0x6, 0x6, 0, 0},
++	{0x3E, 0x42, 0x42, 0, 0},
++	{0x3F, 0, 0, 0, 0},
++	{0x40, 0xfb, 0xfb, 0, 0},
++	{0x41, 0x9a, 0x9a, 0, 0},
++	{0x42, 0x7a, 0x7a, 0, 0},
++	{0x43, 0x29, 0x29, 0, 0},
++	{0x44, 0, 0, 0, 0},
++	{0x45, 0x8, 0x8, 0, 0},
++	{0x46, 0xce, 0xce, 0, 0},
++	{0x47, 0x27, 0x27, 0, 0},
++	{0x48, 0x62, 0x62, 0, 0},
++	{0x49, 0x6, 0x6, 0, 0},
++	{0x4A, 0x58, 0x58, 0, 0},
++	{0x4B, 0xf7, 0xf7, 0, 0},
++	{0x4C, 0, 0, 0, 0},
++	{0x4D, 0xb3, 0xb3, 0, 0},
++	{0x4E, 0, 0, 0, 0},
++	{0x4F, 0x2, 0x2, 0, 0},
++	{0x50, 0, 0, 0, 0},
++	{0x51, 0x9, 0x9, 0, 0},
++	{0x52, 0x5, 0x5, 0, 0},
++	{0x53, 0x17, 0x17, 0, 0},
++	{0x54, 0x38, 0x38, 0, 0},
++	{0x55, 0, 0, 0, 0},
++	{0x56, 0, 0, 0, 0},
++	{0x57, 0xb, 0xb, 0, 0},
++	{0x58, 0, 0, 0, 0},
++	{0x59, 0, 0, 0, 0},
++	{0x5A, 0, 0, 0, 0},
++	{0x5B, 0, 0, 0, 0},
++	{0x5C, 0, 0, 0, 0},
++	{0x5D, 0, 0, 0, 0},
++	{0x5E, 0x88, 0x88, 0, 0},
++	{0x5F, 0xcc, 0xcc, 0, 0},
++	{0x60, 0x74, 0x74, 0, 0},
++	{0x61, 0x74, 0x74, 0, 0},
++	{0x62, 0x74, 0x74, 0, 0},
++	{0x63, 0x44, 0x44, 0, 0},
++	{0x64, 0x77, 0x77, 0, 0},
++	{0x65, 0x44, 0x44, 0, 0},
++	{0x66, 0x77, 0x77, 0, 0},
++	{0x67, 0x55, 0x55, 0, 0},
++	{0x68, 0x77, 0x77, 0, 0},
++	{0x69, 0x77, 0x77, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0x7f, 0x7f, 0, 0},
++	{0x6C, 0x8, 0x8, 0, 0},
++	{0x6D, 0, 0, 0, 0},
++	{0x6E, 0x88, 0x88, 0, 0},
++	{0x6F, 0x66, 0x66, 0, 0},
++	{0x70, 0x66, 0x66, 0, 0},
++	{0x71, 0x28, 0x28, 0, 0},
++	{0x72, 0x55, 0x55, 0, 0},
++	{0x73, 0x4, 0x4, 0, 0},
++	{0x74, 0, 0, 0, 0},
++	{0x75, 0, 0, 0, 0},
++	{0x76, 0, 0, 0, 0},
++	{0x77, 0x1, 0x1, 0, 0},
++	{0x78, 0xd6, 0xd6, 0, 0},
++	{0x79, 0, 0, 0, 0},
++	{0x7A, 0, 0, 0, 0},
++	{0x7B, 0, 0, 0, 0},
++	{0x7C, 0, 0, 0, 0},
++	{0x7D, 0, 0, 0, 0},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0xb4, 0xb4, 0, 0},
++	{0x84, 0x1, 0x1, 0, 0},
++	{0x85, 0x20, 0x20, 0, 0},
++	{0x86, 0x5, 0x5, 0, 0},
++	{0x87, 0xff, 0xff, 0, 0},
++	{0x88, 0x7, 0x7, 0, 0},
++	{0x89, 0x77, 0x77, 0, 0},
++	{0x8A, 0x77, 0x77, 0, 0},
++	{0x8B, 0x77, 0x77, 0, 0},
++	{0x8C, 0x77, 0x77, 0, 0},
++	{0x8D, 0x8, 0x8, 0, 0},
++	{0x8E, 0xa, 0xa, 0, 0},
++	{0x8F, 0x8, 0x8, 0, 0},
++	{0x90, 0x18, 0x18, 0, 0},
++	{0x91, 0x5, 0x5, 0, 0},
++	{0x92, 0x1f, 0x1f, 0, 0},
++	{0x93, 0x10, 0x10, 0, 0},
++	{0x94, 0x3, 0x3, 0, 0},
++	{0x95, 0, 0, 0, 0},
++	{0x96, 0, 0, 0, 0},
++	{0x97, 0xaa, 0xaa, 0, 0},
++	{0x98, 0, 0, 0, 0},
++	{0x99, 0x23, 0x23, 0, 0},
++	{0x9A, 0x7, 0x7, 0, 0},
++	{0x9B, 0xf, 0xf, 0, 0},
++	{0x9C, 0x10, 0x10, 0, 0},
++	{0x9D, 0x3, 0x3, 0, 0},
++	{0x9E, 0x4, 0x4, 0, 0},
++	{0x9F, 0x20, 0x20, 0, 0},
++	{0xA0, 0, 0, 0, 0},
++	{0xA1, 0, 0, 0, 0},
++	{0xA2, 0, 0, 0, 0},
++	{0xA3, 0, 0, 0, 0},
++	{0xA4, 0x1, 0x1, 0, 0},
++	{0xA5, 0x77, 0x77, 0, 0},
++	{0xA6, 0x77, 0x77, 0, 0},
++	{0xA7, 0x77, 0x77, 0, 0},
++	{0xA8, 0x77, 0x77, 0, 0},
++	{0xA9, 0x8c, 0x8c, 0, 0},
++	{0xAA, 0x88, 0x88, 0, 0},
++	{0xAB, 0x78, 0x78, 0, 0},
++	{0xAC, 0x57, 0x57, 0, 0},
++	{0xAD, 0x88, 0x88, 0, 0},
++	{0xAE, 0, 0, 0, 0},
++	{0xAF, 0x8, 0x8, 0, 0},
++	{0xB0, 0x88, 0x88, 0, 0},
++	{0xB1, 0, 0, 0, 0},
++	{0xB2, 0x1b, 0x1b, 0, 0},
++	{0xB3, 0x3, 0x3, 0, 0},
++	{0xB4, 0x24, 0x24, 0, 0},
++	{0xB5, 0x3, 0x3, 0, 0},
++	{0xB6, 0x1b, 0x1b, 0, 0},
++	{0xB7, 0x24, 0x24, 0, 0},
++	{0xB8, 0x3, 0x3, 0, 0},
++	{0xB9, 0, 0, 0, 0},
++	{0xBA, 0xaa, 0xaa, 0, 0},
++	{0xBB, 0, 0, 0, 0},
++	{0xBC, 0x4, 0x4, 0, 0},
++	{0xBD, 0, 0, 0, 0},
++	{0xBE, 0x8, 0x8, 0, 0},
++	{0xBF, 0x11, 0x11, 0, 0},
++	{0xC0, 0, 0, 0, 0},
++	{0xC1, 0, 0, 0, 0},
++	{0xC2, 0x62, 0x62, 0, 0},
++	{0xC3, 0x1e, 0x1e, 0, 0},
++	{0xC4, 0x33, 0x33, 0, 0},
++	{0xC5, 0x37, 0x37, 0, 0},
++	{0xC6, 0, 0, 0, 0},
++	{0xC7, 0x70, 0x70, 0, 0},
++	{0xC8, 0x1e, 0x1e, 0, 0},
++	{0xC9, 0x6, 0x6, 0, 0},
++	{0xCA, 0x4, 0x4, 0, 0},
++	{0xCB, 0x2f, 0x2f, 0, 0},
++	{0xCC, 0xf, 0xf, 0, 0},
++	{0xCD, 0, 0, 0, 0},
++	{0xCE, 0xff, 0xff, 0, 0},
++	{0xCF, 0x8, 0x8, 0, 0},
++	{0xD0, 0x3f, 0x3f, 0, 0},
++	{0xD1, 0x3f, 0x3f, 0, 0},
++	{0xD2, 0x3f, 0x3f, 0, 0},
++	{0xD3, 0, 0, 0, 0},
++	{0xD4, 0, 0, 0, 0},
++	{0xD5, 0, 0, 0, 0},
++	{0xD6, 0xcc, 0xcc, 0, 0},
++	{0xD7, 0, 0, 0, 0},
++	{0xD8, 0x8, 0x8, 0, 0},
++	{0xD9, 0x8, 0x8, 0, 0},
++	{0xDA, 0x8, 0x8, 0, 0},
++	{0xDB, 0x11, 0x11, 0, 0},
++	{0xDC, 0, 0, 0, 0},
++	{0xDD, 0x87, 0x87, 0, 0},
++	{0xDE, 0x88, 0x88, 0, 0},
++	{0xDF, 0x8, 0x8, 0, 0},
++	{0xE0, 0x8, 0x8, 0, 0},
++	{0xE1, 0x8, 0x8, 0, 0},
++	{0xE2, 0, 0, 0, 0},
++	{0xE3, 0, 0, 0, 0},
++	{0xE4, 0, 0, 0, 0},
++	{0xE5, 0xf5, 0xf5, 0, 0},
++	{0xE6, 0x30, 0x30, 0, 0},
++	{0xE7, 0x1, 0x1, 0, 0},
++	{0xE8, 0, 0, 0, 0},
++	{0xE9, 0xff, 0xff, 0, 0},
++	{0xEA, 0, 0, 0, 0},
++	{0xEB, 0, 0, 0, 0},
++	{0xEC, 0x22, 0x22, 0, 0},
++	{0xED, 0, 0, 0, 0},
++	{0xEE, 0, 0, 0, 0},
++	{0xEF, 0, 0, 0, 0},
++	{0xF0, 0x3, 0x3, 0, 0},
++	{0xF1, 0x1, 0x1, 0, 0},
++	{0xF2, 0, 0, 0, 0},
++	{0xF3, 0, 0, 0, 0},
++	{0xF4, 0, 0, 0, 0},
++	{0xF5, 0, 0, 0, 0},
++	{0xF6, 0, 0, 0, 0},
++	{0xF7, 0x6, 0x6, 0, 0},
++	{0xF8, 0, 0, 0, 0},
++	{0xF9, 0, 0, 0, 0},
++	{0xFA, 0x40, 0x40, 0, 0},
++	{0xFB, 0, 0, 0, 0},
++	{0xFC, 0x1, 0x1, 0, 0},
++	{0xFD, 0x80, 0x80, 0, 0},
++	{0xFE, 0x2, 0x2, 0, 0},
++	{0xFF, 0x10, 0x10, 0, 0},
++	{0x100, 0x2, 0x2, 0, 0},
++	{0x101, 0x1e, 0x1e, 0, 0},
++	{0x102, 0x1e, 0x1e, 0, 0},
++	{0x103, 0, 0, 0, 0},
++	{0x104, 0x1f, 0x1f, 0, 0},
++	{0x105, 0, 0x8, 0, 1},
++	{0x106, 0x2a, 0x2a, 0, 0},
++	{0x107, 0xf, 0xf, 0, 0},
++	{0x108, 0, 0, 0, 0},
++	{0x109, 0, 0, 0, 0},
++	{0x10A, 0, 0, 0, 0},
++	{0x10B, 0, 0, 0, 0},
++	{0x10C, 0, 0, 0, 0},
++	{0x10D, 0, 0, 0, 0},
++	{0x10E, 0, 0, 0, 0},
++	{0x10F, 0, 0, 0, 0},
++	{0x110, 0, 0, 0, 0},
++	{0x111, 0, 0, 0, 0},
++	{0x112, 0, 0, 0, 0},
++	{0x113, 0, 0, 0, 0},
++	{0x114, 0, 0, 0, 0},
++	{0x115, 0, 0, 0, 0},
++	{0x116, 0, 0, 0, 0},
++	{0x117, 0, 0, 0, 0},
++	{0x118, 0, 0, 0, 0},
++	{0x119, 0, 0, 0, 0},
++	{0x11A, 0, 0, 0, 0},
++	{0x11B, 0, 0, 0, 0},
++	{0x11C, 0x1, 0x1, 0, 0},
++	{0x11D, 0, 0, 0, 0},
++	{0x11E, 0, 0, 0, 0},
++	{0x11F, 0, 0, 0, 0},
++	{0x120, 0, 0, 0, 0},
++	{0x121, 0, 0, 0, 0},
++	{0x122, 0x80, 0x80, 0, 0},
++	{0x123, 0, 0, 0, 0},
++	{0x124, 0xf8, 0xf8, 0, 0},
++	{0x125, 0, 0, 0, 0},
++	{0x126, 0, 0, 0, 0},
++	{0x127, 0, 0, 0, 0},
++	{0x128, 0, 0, 0, 0},
++	{0x129, 0, 0, 0, 0},
++	{0x12A, 0, 0, 0, 0},
++	{0x12B, 0, 0, 0, 0},
++	{0x12C, 0, 0, 0, 0},
++	{0x12D, 0, 0, 0, 0},
++	{0x12E, 0, 0, 0, 0},
++	{0x12F, 0, 0, 0, 0},
++	{0x130, 0, 0, 0, 0},
++	{0xFFFF, 0, 0, 0, 0}
++};
++
++#define LCNPHY_NUM_DIG_FILT_COEFFS 16
++#define LCNPHY_NUM_TX_DIG_FILTERS_CCK 13
++
++static const u16 LCNPHY_txdigfiltcoeffs_cck[LCNPHY_NUM_TX_DIG_FILTERS_CCK]
++	[LCNPHY_NUM_DIG_FILT_COEFFS + 1] = {
++	{0, 1, 415, 1874, 64, 128, 64, 792, 1656, 64, 128, 64, 778, 1582, 64,
++	 128, 64,},
++	{1, 1, 402, 1847, 259, 59, 259, 671, 1794, 68, 54, 68, 608, 1863, 93,
++	 167, 93,},
++	{2, 1, 415, 1874, 64, 128, 64, 792, 1656, 192, 384, 192, 778, 1582, 64,
++	 128, 64,},
++	{3, 1, 302, 1841, 129, 258, 129, 658, 1720, 205, 410, 205, 754, 1760,
++	 170, 340, 170,},
++	{20, 1, 360, 1884, 242, 1734, 242, 752, 1720, 205, 1845, 205, 767, 1760,
++	 256, 185, 256,},
++	{21, 1, 360, 1884, 149, 1874, 149, 752, 1720, 205, 1883, 205, 767, 1760,
++	 256, 273, 256,},
++	{22, 1, 360, 1884, 98, 1948, 98, 752, 1720, 205, 1924, 205, 767, 1760,
++	 256, 352, 256,},
++	{23, 1, 350, 1884, 116, 1966, 116, 752, 1720, 205, 2008, 205, 767, 1760,
++	 128, 233, 128,},
++	{24, 1, 325, 1884, 32, 40, 32, 756, 1720, 256, 471, 256, 766, 1760, 256,
++	 1881, 256,},
++	{25, 1, 299, 1884, 51, 64, 51, 736, 1720, 256, 471, 256, 765, 1760, 256,
++	 1881, 256,},
++	{26, 1, 277, 1943, 39, 117, 88, 637, 1838, 64, 192, 144, 614, 1864, 128,
++	 384, 288,},
++	{27, 1, 245, 1943, 49, 147, 110, 626, 1838, 256, 768, 576, 613, 1864,
++	 128, 384, 288,},
++	{30, 1, 302, 1841, 61, 122, 61, 658, 1720, 205, 410, 205, 754, 1760,
++	 170, 340, 170,},
++};
++
++#define LCNPHY_NUM_TX_DIG_FILTERS_OFDM 3
++static const u16 LCNPHY_txdigfiltcoeffs_ofdm[LCNPHY_NUM_TX_DIG_FILTERS_OFDM]
++	[LCNPHY_NUM_DIG_FILT_COEFFS + 1] = {
++	{0, 0, 0xa2, 0x0, 0x100, 0x100, 0x0, 0x0, 0x0, 0x100, 0x0, 0x0,
++	 0x278, 0xfea0, 0x80, 0x100, 0x80,},
++	{1, 0, 374, 0xFF79, 16, 32, 16, 799, 0xFE74, 50, 32, 50,
++	 750, 0xFE2B, 212, 0xFFCE, 212,},
++	{2, 0, 375, 0xFF16, 37, 76, 37, 799, 0xFE74, 32, 20, 32, 748,
++	 0xFEF2, 128, 0xFFE2, 128}
++};
++
++#define wlc_lcnphy_set_start_tx_pwr_idx(pi, idx) \
++	mod_phy_reg(pi, 0x4a4, \
++		    (0x1ff << 0), \
++		    (u16)(idx) << 0)
++
++#define wlc_lcnphy_set_tx_pwr_npt(pi, npt) \
++	mod_phy_reg(pi, 0x4a5, \
++		    (0x7 << 8),	\
++		    (u16)(npt) << 8)
++
++#define wlc_lcnphy_get_tx_pwr_ctrl(pi) \
++	(read_phy_reg((pi), 0x4a4) & \
++	 ((0x1 << 15) |	\
++	  (0x1 << 14) |	\
++	  (0x1 << 13)))
++
++#define wlc_lcnphy_get_tx_pwr_npt(pi) \
++	((read_phy_reg(pi, 0x4a5) & \
++	  (0x7 << 8)) >> \
++	 8)
++
++#define wlc_lcnphy_get_current_tx_pwr_idx_if_pwrctrl_on(pi) \
++	(read_phy_reg(pi, 0x473) & 0x1ff)
++
++#define wlc_lcnphy_get_target_tx_pwr(pi) \
++	((read_phy_reg(pi, 0x4a7) & \
++	  (0xff << 0)) >> \
++	 0)
++
++#define wlc_lcnphy_set_target_tx_pwr(pi, target) \
++	mod_phy_reg(pi, 0x4a7, \
++		    (0xff << 0), \
++		    (u16)(target) << 0)
++
++#define wlc_radio_2064_rcal_done(pi) \
++	(0 != (read_radio_reg(pi, RADIO_2064_REG05C) & 0x20))
++
++#define tempsense_done(pi) \
++	(0x8000 == (read_phy_reg(pi, 0x476) & 0x8000))
++
++#define LCNPHY_IQLOCC_READ(val) \
++	((u8)(-(s8)(((val) & 0xf0) >> 4) + (s8)((val) & 0x0f)))
++
++#define FIXED_TXPWR 78
++#define LCNPHY_TEMPSENSE(val) ((s16)((val > 255) ? (val - 512) : val))
++
++void wlc_lcnphy_write_table(struct brcms_phy *pi, const struct phytbl_info *pti)
++{
++	wlc_phy_write_table(pi, pti, 0x455, 0x457, 0x456);
++}
++
++void wlc_lcnphy_read_table(struct brcms_phy *pi, struct phytbl_info *pti)
++{
++	wlc_phy_read_table(pi, pti, 0x455, 0x457, 0x456);
++}
++
++static void
++wlc_lcnphy_common_read_table(struct brcms_phy *pi, u32 tbl_id,
++			     const u16 *tbl_ptr, u32 tbl_len,
++			     u32 tbl_width, u32 tbl_offset)
++{
++	struct phytbl_info tab;
++	tab.tbl_id = tbl_id;
++	tab.tbl_ptr = tbl_ptr;
++	tab.tbl_len = tbl_len;
++	tab.tbl_width = tbl_width;
++	tab.tbl_offset = tbl_offset;
++	wlc_lcnphy_read_table(pi, &tab);
++}
++
++static void
++wlc_lcnphy_common_write_table(struct brcms_phy *pi, u32 tbl_id,
++			      const u16 *tbl_ptr, u32 tbl_len,
++			      u32 tbl_width, u32 tbl_offset)
++{
++
++	struct phytbl_info tab;
++	tab.tbl_id = tbl_id;
++	tab.tbl_ptr = tbl_ptr;
++	tab.tbl_len = tbl_len;
++	tab.tbl_width = tbl_width;
++	tab.tbl_offset = tbl_offset;
++	wlc_lcnphy_write_table(pi, &tab);
++}
++
++static u32
++wlc_lcnphy_qdiv_roundup(u32 dividend, u32 divisor, u8 precision)
++{
++	u32 quotient, remainder, roundup, rbit;
++
++	quotient = dividend / divisor;
++	remainder = dividend % divisor;
++	rbit = divisor & 1;
++	roundup = (divisor >> 1) + rbit;
++
++	while (precision--) {
++		quotient <<= 1;
++		if (remainder >= roundup) {
++			quotient++;
++			remainder = ((remainder - roundup) << 1) + rbit;
++		} else {
++			remainder <<= 1;
++		}
++	}
++
++	if (remainder >= roundup)
++		quotient++;
++
++	return quotient;
++}
++
++static int wlc_lcnphy_calc_floor(s16 coeff_x, int type)
++{
++	int k;
++	k = 0;
++	if (type == 0) {
++		if (coeff_x < 0)
++			k = (coeff_x - 1) / 2;
++		else
++			k = coeff_x / 2;
++	}
++
++	if (type == 1) {
++		if ((coeff_x + 1) < 0)
++			k = (coeff_x) / 2;
++		else
++			k = (coeff_x + 1) / 2;
++	}
++	return k;
++}
++
++static void
++wlc_lcnphy_get_tx_gain(struct brcms_phy *pi, struct lcnphy_txgains *gains)
++{
++	u16 dac_gain, rfgain0, rfgain1;
++
++	dac_gain = read_phy_reg(pi, 0x439) >> 0;
++	gains->dac_gain = (dac_gain & 0x380) >> 7;
++
++	rfgain0 = (read_phy_reg(pi, 0x4b5) & (0xffff << 0)) >> 0;
++	rfgain1 = (read_phy_reg(pi, 0x4fb) & (0x7fff << 0)) >> 0;
++
++	gains->gm_gain = rfgain0 & 0xff;
++	gains->pga_gain = (rfgain0 >> 8) & 0xff;
++	gains->pad_gain = rfgain1 & 0xff;
++}
++
++
++static void wlc_lcnphy_set_dac_gain(struct brcms_phy *pi, u16 dac_gain)
++{
++	u16 dac_ctrl;
++
++	dac_ctrl = (read_phy_reg(pi, 0x439) >> 0);
++	dac_ctrl = dac_ctrl & 0xc7f;
++	dac_ctrl = dac_ctrl | (dac_gain << 7);
++	mod_phy_reg(pi, 0x439, (0xfff << 0), (dac_ctrl) << 0);
++
++}
++
++static void wlc_lcnphy_set_tx_gain_override(struct brcms_phy *pi, bool bEnable)
++{
++	u16 bit = bEnable ? 1 : 0;
++
++	mod_phy_reg(pi, 0x4b0, (0x1 << 7), bit << 7);
++
++	mod_phy_reg(pi, 0x4b0, (0x1 << 14), bit << 14);
++
++	mod_phy_reg(pi, 0x43b, (0x1 << 6), bit << 6);
++}
++
++static void
++wlc_lcnphy_rx_gain_override_enable(struct brcms_phy *pi, bool enable)
++{
++	u16 ebit = enable ? 1 : 0;
++
++	mod_phy_reg(pi, 0x4b0, (0x1 << 8), ebit << 8);
++
++	mod_phy_reg(pi, 0x44c, (0x1 << 0), ebit << 0);
++
++	if (LCNREV_LT(pi->pubpi.phy_rev, 2)) {
++		mod_phy_reg(pi, 0x44c, (0x1 << 4), ebit << 4);
++		mod_phy_reg(pi, 0x44c, (0x1 << 6), ebit << 6);
++		mod_phy_reg(pi, 0x4b0, (0x1 << 5), ebit << 5);
++		mod_phy_reg(pi, 0x4b0, (0x1 << 6), ebit << 6);
++	} else {
++		mod_phy_reg(pi, 0x4b0, (0x1 << 12), ebit << 12);
++		mod_phy_reg(pi, 0x4b0, (0x1 << 13), ebit << 13);
++		mod_phy_reg(pi, 0x4b0, (0x1 << 5), ebit << 5);
++	}
++
++	if (CHSPEC_IS2G(pi->radio_chanspec)) {
++		mod_phy_reg(pi, 0x4b0, (0x1 << 10), ebit << 10);
++		mod_phy_reg(pi, 0x4e5, (0x1 << 3), ebit << 3);
++	}
++}
++
++static void
++wlc_lcnphy_set_rx_gain_by_distribution(struct brcms_phy *pi,
++				       u16 trsw,
++				       u16 ext_lna,
++				       u16 biq2,
++				       u16 biq1,
++				       u16 tia, u16 lna2, u16 lna1)
++{
++	u16 gain0_15, gain16_19;
++
++	gain16_19 = biq2 & 0xf;
++	gain0_15 = ((biq1 & 0xf) << 12) |
++		   ((tia & 0xf) << 8) |
++		   ((lna2 & 0x3) << 6) |
++		   ((lna2 &
++		     0x3) << 4) | ((lna1 & 0x3) << 2) | ((lna1 & 0x3) << 0);
++
++	mod_phy_reg(pi, 0x4b6, (0xffff << 0), gain0_15 << 0);
++	mod_phy_reg(pi, 0x4b7, (0xf << 0), gain16_19 << 0);
++	mod_phy_reg(pi, 0x4b1, (0x3 << 11), lna1 << 11);
++
++	if (LCNREV_LT(pi->pubpi.phy_rev, 2)) {
++		mod_phy_reg(pi, 0x4b1, (0x1 << 9), ext_lna << 9);
++		mod_phy_reg(pi, 0x4b1, (0x1 << 10), ext_lna << 10);
++	} else {
++		mod_phy_reg(pi, 0x4b1, (0x1 << 10), 0 << 10);
++
++		mod_phy_reg(pi, 0x4b1, (0x1 << 15), 0 << 15);
++
++		mod_phy_reg(pi, 0x4b1, (0x1 << 9), ext_lna << 9);
++	}
++
++	mod_phy_reg(pi, 0x44d, (0x1 << 0), (!trsw) << 0);
++
++}
++
++static void wlc_lcnphy_set_trsw_override(struct brcms_phy *pi, bool tx, bool rx)
++{
++
++	mod_phy_reg(pi, 0x44d,
++		    (0x1 << 1) |
++		    (0x1 << 0), (tx ? (0x1 << 1) : 0) | (rx ? (0x1 << 0) : 0));
++
++	or_phy_reg(pi, 0x44c, (0x1 << 1) | (0x1 << 0));
++}
++
++static void wlc_lcnphy_clear_trsw_override(struct brcms_phy *pi)
++{
++
++	and_phy_reg(pi, 0x44c, (u16) ~((0x1 << 1) | (0x1 << 0)));
++}
++
++static void wlc_lcnphy_set_rx_iq_comp(struct brcms_phy *pi, u16 a, u16 b)
++{
++	mod_phy_reg(pi, 0x645, (0x3ff << 0), (a) << 0);
++
++	mod_phy_reg(pi, 0x646, (0x3ff << 0), (b) << 0);
++
++	mod_phy_reg(pi, 0x647, (0x3ff << 0), (a) << 0);
++
++	mod_phy_reg(pi, 0x648, (0x3ff << 0), (b) << 0);
++
++	mod_phy_reg(pi, 0x649, (0x3ff << 0), (a) << 0);
++
++	mod_phy_reg(pi, 0x64a, (0x3ff << 0), (b) << 0);
++
++}
++
++static bool
++wlc_lcnphy_rx_iq_est(struct brcms_phy *pi,
++		     u16 num_samps,
++		     u8 wait_time, struct lcnphy_iq_est *iq_est)
++{
++	int wait_count = 0;
++	bool result = true;
++	u8 phybw40;
++	phybw40 = CHSPEC_IS40(pi->radio_chanspec);
++
++	mod_phy_reg(pi, 0x6da, (0x1 << 5), (1) << 5);
++
++	mod_phy_reg(pi, 0x410, (0x1 << 3), (0) << 3);
++
++	mod_phy_reg(pi, 0x482, (0xffff << 0), (num_samps) << 0);
++
++	mod_phy_reg(pi, 0x481, (0xff << 0), ((u16) wait_time) << 0);
++
++	mod_phy_reg(pi, 0x481, (0x1 << 8), (0) << 8);
++
++	mod_phy_reg(pi, 0x481, (0x1 << 9), (1) << 9);
++
++	while (read_phy_reg(pi, 0x481) & (0x1 << 9)) {
++
++		if (wait_count > (10 * 500)) {
++			result = false;
++			goto cleanup;
++		}
++		udelay(100);
++		wait_count++;
++	}
++
++	iq_est->iq_prod = ((u32) read_phy_reg(pi, 0x483) << 16) |
++			  (u32) read_phy_reg(pi, 0x484);
++	iq_est->i_pwr = ((u32) read_phy_reg(pi, 0x485) << 16) |
++			(u32) read_phy_reg(pi, 0x486);
++	iq_est->q_pwr = ((u32) read_phy_reg(pi, 0x487) << 16) |
++			(u32) read_phy_reg(pi, 0x488);
++
++cleanup:
++	mod_phy_reg(pi, 0x410, (0x1 << 3), (1) << 3);
++
++	mod_phy_reg(pi, 0x6da, (0x1 << 5), (0) << 5);
++
++	return result;
++}
++
++static bool wlc_lcnphy_calc_rx_iq_comp(struct brcms_phy *pi, u16 num_samps)
++{
++#define LCNPHY_MIN_RXIQ_PWR 2
++	bool result;
++	u16 a0_new, b0_new;
++	struct lcnphy_iq_est iq_est = { 0, 0, 0 };
++	s32 a, b, temp;
++	s16 iq_nbits, qq_nbits, arsh, brsh;
++	s32 iq;
++	u32 ii, qq;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	a0_new = ((read_phy_reg(pi, 0x645) & (0x3ff << 0)) >> 0);
++	b0_new = ((read_phy_reg(pi, 0x646) & (0x3ff << 0)) >> 0);
++	mod_phy_reg(pi, 0x6d1, (0x1 << 2), (0) << 2);
++
++	mod_phy_reg(pi, 0x64b, (0x1 << 6), (1) << 6);
++
++	wlc_lcnphy_set_rx_iq_comp(pi, 0, 0);
++
++	result = wlc_lcnphy_rx_iq_est(pi, num_samps, 32, &iq_est);
++	if (!result)
++		goto cleanup;
++
++	iq = (s32) iq_est.iq_prod;
++	ii = iq_est.i_pwr;
++	qq = iq_est.q_pwr;
++
++	if ((ii + qq) < LCNPHY_MIN_RXIQ_PWR) {
++		result = false;
++		goto cleanup;
++	}
++
++	iq_nbits = wlc_phy_nbits(iq);
++	qq_nbits = wlc_phy_nbits(qq);
++
++	arsh = 10 - (30 - iq_nbits);
++	if (arsh >= 0) {
++		a = (-(iq << (30 - iq_nbits)) + (ii >> (1 + arsh)));
++		temp = (s32) (ii >> arsh);
++		if (temp == 0)
++			return false;
++	} else {
++		a = (-(iq << (30 - iq_nbits)) + (ii << (-1 - arsh)));
++		temp = (s32) (ii << -arsh);
++		if (temp == 0)
++			return false;
++	}
++	a /= temp;
++	brsh = qq_nbits - 31 + 20;
++	if (brsh >= 0) {
++		b = (qq << (31 - qq_nbits));
++		temp = (s32) (ii >> brsh);
++		if (temp == 0)
++			return false;
++	} else {
++		b = (qq << (31 - qq_nbits));
++		temp = (s32) (ii << -brsh);
++		if (temp == 0)
++			return false;
++	}
++	b /= temp;
++	b -= a * a;
++	b = (s32) int_sqrt((unsigned long) b);
++	b -= (1 << 10);
++	a0_new = (u16) (a & 0x3ff);
++	b0_new = (u16) (b & 0x3ff);
++cleanup:
++
++	wlc_lcnphy_set_rx_iq_comp(pi, a0_new, b0_new);
++
++	mod_phy_reg(pi, 0x64b, (0x1 << 0), (1) << 0);
++
++	mod_phy_reg(pi, 0x64b, (0x1 << 3), (1) << 3);
++
++	pi_lcn->lcnphy_cal_results.rxiqcal_coeff_a0 = a0_new;
++	pi_lcn->lcnphy_cal_results.rxiqcal_coeff_b0 = b0_new;
++
++	return result;
++}
++
++static u32 wlc_lcnphy_measure_digital_power(struct brcms_phy *pi, u16 nsamples)
++{
++	struct lcnphy_iq_est iq_est = { 0, 0, 0 };
++
++	if (!wlc_lcnphy_rx_iq_est(pi, nsamples, 32, &iq_est))
++		return 0;
++	return (iq_est.i_pwr + iq_est.q_pwr) / nsamples;
++}
++
++static bool
++wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi,
++		     const struct lcnphy_rx_iqcomp *iqcomp,
++		     int iqcomp_sz, bool tx_switch, bool rx_switch, int module,
++		     int tx_gain_idx)
++{
++	struct lcnphy_txgains old_gains;
++	u16 tx_pwr_ctrl;
++	u8 tx_gain_index_old = 0;
++	bool result = false, tx_gain_override_old = false;
++	u16 i, Core1TxControl_old, RFOverride0_old,
++	    RFOverrideVal0_old, rfoverride2_old, rfoverride2val_old,
++	    rfoverride3_old, rfoverride3val_old, rfoverride4_old,
++	    rfoverride4val_old, afectrlovr_old, afectrlovrval_old;
++	int tia_gain;
++	u32 received_power, rx_pwr_threshold;
++	u16 old_sslpnCalibClkEnCtrl, old_sslpnRxFeClkEnCtrl;
++	u16 values_to_save[11];
++	s16 *ptr;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	ptr = kmalloc(sizeof(s16) * 131, GFP_ATOMIC);
++	if (NULL == ptr)
++		return false;
++	if (module == 2) {
++		while (iqcomp_sz--) {
++			if (iqcomp[iqcomp_sz].chan ==
++			    CHSPEC_CHANNEL(pi->radio_chanspec)) {
++				wlc_lcnphy_set_rx_iq_comp(pi,
++							  (u16)
++							  iqcomp[iqcomp_sz].a,
++							  (u16)
++							  iqcomp[iqcomp_sz].b);
++				result = true;
++				break;
++			}
++		}
++		goto cal_done;
++	}
++
++	if (module == 1) {
++
++		tx_pwr_ctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
++		wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
++
++		for (i = 0; i < 11; i++)
++			values_to_save[i] =
++				read_radio_reg(pi, rxiq_cal_rf_reg[i]);
++		Core1TxControl_old = read_phy_reg(pi, 0x631);
++
++		or_phy_reg(pi, 0x631, 0x0015);
++
++		RFOverride0_old = read_phy_reg(pi, 0x44c);
++		RFOverrideVal0_old = read_phy_reg(pi, 0x44d);
++		rfoverride2_old = read_phy_reg(pi, 0x4b0);
++		rfoverride2val_old = read_phy_reg(pi, 0x4b1);
++		rfoverride3_old = read_phy_reg(pi, 0x4f9);
++		rfoverride3val_old = read_phy_reg(pi, 0x4fa);
++		rfoverride4_old = read_phy_reg(pi, 0x938);
++		rfoverride4val_old = read_phy_reg(pi, 0x939);
++		afectrlovr_old = read_phy_reg(pi, 0x43b);
++		afectrlovrval_old = read_phy_reg(pi, 0x43c);
++		old_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da);
++		old_sslpnRxFeClkEnCtrl = read_phy_reg(pi, 0x6db);
++
++		tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi);
++		if (tx_gain_override_old) {
++			wlc_lcnphy_get_tx_gain(pi, &old_gains);
++			tx_gain_index_old = pi_lcn->lcnphy_current_index;
++		}
++
++		wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_idx);
++
++		mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0);
++		mod_phy_reg(pi, 0x4fa, (0x1 << 0), 0 << 0);
++
++		mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1);
++		mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1);
++
++		write_radio_reg(pi, RADIO_2064_REG116, 0x06);
++		write_radio_reg(pi, RADIO_2064_REG12C, 0x07);
++		write_radio_reg(pi, RADIO_2064_REG06A, 0xd3);
++		write_radio_reg(pi, RADIO_2064_REG098, 0x03);
++		write_radio_reg(pi, RADIO_2064_REG00B, 0x7);
++		mod_radio_reg(pi, RADIO_2064_REG113, 1 << 4, 1 << 4);
++		write_radio_reg(pi, RADIO_2064_REG01D, 0x01);
++		write_radio_reg(pi, RADIO_2064_REG114, 0x01);
++		write_radio_reg(pi, RADIO_2064_REG02E, 0x10);
++		write_radio_reg(pi, RADIO_2064_REG12A, 0x08);
++
++		mod_phy_reg(pi, 0x938, (0x1 << 0), 1 << 0);
++		mod_phy_reg(pi, 0x939, (0x1 << 0), 0 << 0);
++		mod_phy_reg(pi, 0x938, (0x1 << 1), 1 << 1);
++		mod_phy_reg(pi, 0x939, (0x1 << 1), 1 << 1);
++		mod_phy_reg(pi, 0x938, (0x1 << 2), 1 << 2);
++		mod_phy_reg(pi, 0x939, (0x1 << 2), 1 << 2);
++		mod_phy_reg(pi, 0x938, (0x1 << 3), 1 << 3);
++		mod_phy_reg(pi, 0x939, (0x1 << 3), 1 << 3);
++		mod_phy_reg(pi, 0x938, (0x1 << 5), 1 << 5);
++		mod_phy_reg(pi, 0x939, (0x1 << 5), 0 << 5);
++
++		mod_phy_reg(pi, 0x43b, (0x1 << 0), 1 << 0);
++		mod_phy_reg(pi, 0x43c, (0x1 << 0), 0 << 0);
++
++		wlc_lcnphy_start_tx_tone(pi, 2000, 120, 0);
++		write_phy_reg(pi, 0x6da, 0xffff);
++		or_phy_reg(pi, 0x6db, 0x3);
++		wlc_lcnphy_set_trsw_override(pi, tx_switch, rx_switch);
++		wlc_lcnphy_rx_gain_override_enable(pi, true);
++
++		tia_gain = 8;
++		rx_pwr_threshold = 950;
++		while (tia_gain > 0) {
++			tia_gain -= 1;
++			wlc_lcnphy_set_rx_gain_by_distribution(pi,
++							       0, 0, 2, 2,
++							       (u16)
++							       tia_gain, 1, 0);
++			udelay(500);
++
++			received_power =
++				wlc_lcnphy_measure_digital_power(pi, 2000);
++			if (received_power < rx_pwr_threshold)
++				break;
++		}
++		result = wlc_lcnphy_calc_rx_iq_comp(pi, 0xffff);
++
++		wlc_lcnphy_stop_tx_tone(pi);
++
++		write_phy_reg(pi, 0x631, Core1TxControl_old);
++
++		write_phy_reg(pi, 0x44c, RFOverrideVal0_old);
++		write_phy_reg(pi, 0x44d, RFOverrideVal0_old);
++		write_phy_reg(pi, 0x4b0, rfoverride2_old);
++		write_phy_reg(pi, 0x4b1, rfoverride2val_old);
++		write_phy_reg(pi, 0x4f9, rfoverride3_old);
++		write_phy_reg(pi, 0x4fa, rfoverride3val_old);
++		write_phy_reg(pi, 0x938, rfoverride4_old);
++		write_phy_reg(pi, 0x939, rfoverride4val_old);
++		write_phy_reg(pi, 0x43b, afectrlovr_old);
++		write_phy_reg(pi, 0x43c, afectrlovrval_old);
++		write_phy_reg(pi, 0x6da, old_sslpnCalibClkEnCtrl);
++		write_phy_reg(pi, 0x6db, old_sslpnRxFeClkEnCtrl);
++
++		wlc_lcnphy_clear_trsw_override(pi);
++
++		mod_phy_reg(pi, 0x44c, (0x1 << 2), 0 << 2);
++
++		for (i = 0; i < 11; i++)
++			write_radio_reg(pi, rxiq_cal_rf_reg[i],
++					values_to_save[i]);
++
++		if (tx_gain_override_old)
++			wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_index_old);
++		else
++			wlc_lcnphy_disable_tx_gain_override(pi);
++
++		wlc_lcnphy_set_tx_pwr_ctrl(pi, tx_pwr_ctrl);
++		wlc_lcnphy_rx_gain_override_enable(pi, false);
++	}
++
++cal_done:
++	kfree(ptr);
++	return result;
++}
++
++s8 wlc_lcnphy_get_current_tx_pwr_idx(struct brcms_phy *pi)
++{
++	s8 index;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	if (txpwrctrl_off(pi))
++		index = pi_lcn->lcnphy_current_index;
++	else if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi))
++		index =	(s8) (wlc_lcnphy_get_current_tx_pwr_idx_if_pwrctrl_on(
++			      pi) / 2);
++	else
++		index = pi_lcn->lcnphy_current_index;
++	return index;
++}
++
++void wlc_lcnphy_crsuprs(struct brcms_phy *pi, int channel)
++{
++	u16 afectrlovr, afectrlovrval;
++	afectrlovr = read_phy_reg(pi, 0x43b);
++	afectrlovrval = read_phy_reg(pi, 0x43c);
++	if (channel != 0) {
++		mod_phy_reg(pi, 0x43b, (0x1 << 1), (1) << 1);
++
++		mod_phy_reg(pi, 0x43c, (0x1 << 1), (0) << 1);
++
++		mod_phy_reg(pi, 0x43b, (0x1 << 4), (1) << 4);
++
++		mod_phy_reg(pi, 0x43c, (0x1 << 6), (0) << 6);
++
++		write_phy_reg(pi, 0x44b, 0xffff);
++		wlc_lcnphy_tx_pu(pi, 1);
++
++		mod_phy_reg(pi, 0x634, (0xff << 8), (0) << 8);
++
++		or_phy_reg(pi, 0x6da, 0x0080);
++
++		or_phy_reg(pi, 0x00a, 0x228);
++	} else {
++		and_phy_reg(pi, 0x00a, ~(0x228));
++
++		and_phy_reg(pi, 0x6da, 0xFF7F);
++		write_phy_reg(pi, 0x43b, afectrlovr);
++		write_phy_reg(pi, 0x43c, afectrlovrval);
++	}
++}
++
++static void wlc_lcnphy_toggle_afe_pwdn(struct brcms_phy *pi)
++{
++	u16 save_AfeCtrlOvrVal, save_AfeCtrlOvr;
++
++	save_AfeCtrlOvrVal = read_phy_reg(pi, 0x43c);
++	save_AfeCtrlOvr = read_phy_reg(pi, 0x43b);
++
++	write_phy_reg(pi, 0x43c, save_AfeCtrlOvrVal | 0x1);
++	write_phy_reg(pi, 0x43b, save_AfeCtrlOvr | 0x1);
++
++	write_phy_reg(pi, 0x43c, save_AfeCtrlOvrVal & 0xfffe);
++	write_phy_reg(pi, 0x43b, save_AfeCtrlOvr & 0xfffe);
++
++	write_phy_reg(pi, 0x43c, save_AfeCtrlOvrVal);
++	write_phy_reg(pi, 0x43b, save_AfeCtrlOvr);
++}
++
++static void
++wlc_lcnphy_txrx_spur_avoidance_mode(struct brcms_phy *pi, bool enable)
++{
++	if (enable) {
++		write_phy_reg(pi, 0x942, 0x7);
++		write_phy_reg(pi, 0x93b, ((1 << 13) + 23));
++		write_phy_reg(pi, 0x93c, ((1 << 13) + 1989));
++
++		write_phy_reg(pi, 0x44a, 0x084);
++		write_phy_reg(pi, 0x44a, 0x080);
++		write_phy_reg(pi, 0x6d3, 0x2222);
++		write_phy_reg(pi, 0x6d3, 0x2220);
++	} else {
++		write_phy_reg(pi, 0x942, 0x0);
++		write_phy_reg(pi, 0x93b, ((0 << 13) + 23));
++		write_phy_reg(pi, 0x93c, ((0 << 13) + 1989));
++	}
++	wlapi_switch_macfreq(pi->sh->physhim, enable);
++}
++
++static void
++wlc_lcnphy_set_chanspec_tweaks(struct brcms_phy *pi, u16 chanspec)
++{
++	u8 channel = CHSPEC_CHANNEL(chanspec);
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	if (channel == 14)
++		mod_phy_reg(pi, 0x448, (0x3 << 8), (2) << 8);
++	else
++		mod_phy_reg(pi, 0x448, (0x3 << 8), (1) << 8);
++
++	pi_lcn->lcnphy_bandedge_corr = 2;
++	if (channel == 1)
++		pi_lcn->lcnphy_bandedge_corr = 4;
++
++	if (channel == 1 || channel == 2 || channel == 3 ||
++	    channel == 4 || channel == 9 ||
++	    channel == 10 || channel == 11 || channel == 12) {
++		si_pmu_pllcontrol(pi->sh->sih, 0x2, 0xffffffff, 0x03000c04);
++		si_pmu_pllcontrol(pi->sh->sih, 0x3, 0xffffff, 0x0);
++		si_pmu_pllcontrol(pi->sh->sih, 0x4, 0xffffffff, 0x200005c0);
++
++		si_pmu_pllupd(pi->sh->sih);
++		write_phy_reg(pi, 0x942, 0);
++		wlc_lcnphy_txrx_spur_avoidance_mode(pi, false);
++		pi_lcn->lcnphy_spurmod = false;
++		mod_phy_reg(pi, 0x424, (0xff << 8), (0x1b) << 8);
++
++		write_phy_reg(pi, 0x425, 0x5907);
++	} else {
++		si_pmu_pllcontrol(pi->sh->sih, 0x2, 0xffffffff, 0x03140c04);
++		si_pmu_pllcontrol(pi->sh->sih, 0x3, 0xffffff, 0x333333);
++		si_pmu_pllcontrol(pi->sh->sih, 0x4, 0xffffffff, 0x202c2820);
++
++		si_pmu_pllupd(pi->sh->sih);
++		write_phy_reg(pi, 0x942, 0);
++		wlc_lcnphy_txrx_spur_avoidance_mode(pi, true);
++
++		pi_lcn->lcnphy_spurmod = false;
++		mod_phy_reg(pi, 0x424, (0xff << 8), (0x1f) << 8);
++
++		write_phy_reg(pi, 0x425, 0x590a);
++	}
++
++	or_phy_reg(pi, 0x44a, 0x44);
++	write_phy_reg(pi, 0x44a, 0x80);
++}
++
++static void
++wlc_lcnphy_radio_2064_channel_tune_4313(struct brcms_phy *pi, u8 channel)
++{
++	uint i;
++	const struct chan_info_2064_lcnphy *ci;
++	u8 rfpll_doubler = 0;
++	u8 pll_pwrup, pll_pwrup_ovr;
++	s32 qFxtal, qFref, qFvco, qFcal;
++	u8 d15, d16, f16, e44, e45;
++	u32 div_int, div_frac, fvco3, fpfd, fref3, fcal_div;
++	u16 loop_bw, d30, setCount;
++
++	u8 h29, h28_ten, e30, h30_ten, cp_current;
++	u16 g30, d28;
++
++	ci = &chan_info_2064_lcnphy[0];
++	rfpll_doubler = 1;
++
++	mod_radio_reg(pi, RADIO_2064_REG09D, 0x4, 0x1 << 2);
++
++	write_radio_reg(pi, RADIO_2064_REG09E, 0xf);
++	if (!rfpll_doubler) {
++		loop_bw = PLL_2064_LOOP_BW;
++		d30 = PLL_2064_D30;
++	} else {
++		loop_bw = PLL_2064_LOOP_BW_DOUBLER;
++		d30 = PLL_2064_D30_DOUBLER;
++	}
++
++	if (CHSPEC_IS2G(pi->radio_chanspec)) {
++		for (i = 0; i < ARRAY_SIZE(chan_info_2064_lcnphy); i++)
++			if (chan_info_2064_lcnphy[i].chan == channel)
++				break;
++
++		if (i >= ARRAY_SIZE(chan_info_2064_lcnphy))
++			return;
++
++		ci = &chan_info_2064_lcnphy[i];
++	}
++
++	write_radio_reg(pi, RADIO_2064_REG02A, ci->logen_buftune);
++
++	mod_radio_reg(pi, RADIO_2064_REG030, 0x3, ci->logen_rccr_tx);
++
++	mod_radio_reg(pi, RADIO_2064_REG091, 0x3, ci->txrf_mix_tune_ctrl);
++
++	mod_radio_reg(pi, RADIO_2064_REG038, 0xf, ci->pa_input_tune_g);
++
++	mod_radio_reg(pi, RADIO_2064_REG030, 0x3 << 2,
++		      (ci->logen_rccr_rx) << 2);
++
++	mod_radio_reg(pi, RADIO_2064_REG05E, 0xf, ci->pa_rxrf_lna1_freq_tune);
++
++	mod_radio_reg(pi, RADIO_2064_REG05E, (0xf) << 4,
++		      (ci->pa_rxrf_lna2_freq_tune) << 4);
++
++	write_radio_reg(pi, RADIO_2064_REG06C, ci->rxrf_rxrf_spare1);
++
++	pll_pwrup = (u8) read_radio_reg(pi, RADIO_2064_REG044);
++	pll_pwrup_ovr = (u8) read_radio_reg(pi, RADIO_2064_REG12B);
++
++	or_radio_reg(pi, RADIO_2064_REG044, 0x07);
++
++	or_radio_reg(pi, RADIO_2064_REG12B, (0x07) << 1);
++	e44 = 0;
++	e45 = 0;
++
++	fpfd = rfpll_doubler ? (pi->xtalfreq << 1) : (pi->xtalfreq);
++	if (pi->xtalfreq > 26000000)
++		e44 = 1;
++	if (pi->xtalfreq > 52000000)
++		e45 = 1;
++	if (e44 == 0)
++		fcal_div = 1;
++	else if (e45 == 0)
++		fcal_div = 2;
++	else
++		fcal_div = 4;
++	fvco3 = (ci->freq * 3);
++	fref3 = 2 * fpfd;
++
++	qFxtal = wlc_lcnphy_qdiv_roundup(pi->xtalfreq, PLL_2064_MHZ, 16);
++	qFref = wlc_lcnphy_qdiv_roundup(fpfd, PLL_2064_MHZ, 16);
++	qFcal = pi->xtalfreq * fcal_div / PLL_2064_MHZ;
++	qFvco = wlc_lcnphy_qdiv_roundup(fvco3, 2, 16);
++
++	write_radio_reg(pi, RADIO_2064_REG04F, 0x02);
++
++	d15 = (pi->xtalfreq * fcal_div * 4 / 5) / PLL_2064_MHZ - 1;
++	write_radio_reg(pi, RADIO_2064_REG052, (0x07 & (d15 >> 2)));
++	write_radio_reg(pi, RADIO_2064_REG053, (d15 & 0x3) << 5);
++
++	d16 = (qFcal * 8 / (d15 + 1)) - 1;
++	write_radio_reg(pi, RADIO_2064_REG051, d16);
++
++	f16 = ((d16 + 1) * (d15 + 1)) / qFcal;
++	setCount = f16 * 3 * (ci->freq) / 32 - 1;
++	mod_radio_reg(pi, RADIO_2064_REG053, (0x0f << 0),
++		      (u8) (setCount >> 8));
++
++	or_radio_reg(pi, RADIO_2064_REG053, 0x10);
++	write_radio_reg(pi, RADIO_2064_REG054, (u8) (setCount & 0xff));
++
++	div_int = ((fvco3 * (PLL_2064_MHZ >> 4)) / fref3) << 4;
++
++	div_frac = ((fvco3 * (PLL_2064_MHZ >> 4)) % fref3) << 4;
++	while (div_frac >= fref3) {
++		div_int++;
++		div_frac -= fref3;
++	}
++	div_frac = wlc_lcnphy_qdiv_roundup(div_frac, fref3, 20);
++
++	mod_radio_reg(pi, RADIO_2064_REG045, (0x1f << 0),
++		      (u8) (div_int >> 4));
++	mod_radio_reg(pi, RADIO_2064_REG046, (0x1f << 4),
++		      (u8) (div_int << 4));
++	mod_radio_reg(pi, RADIO_2064_REG046, (0x0f << 0),
++		      (u8) (div_frac >> 16));
++	write_radio_reg(pi, RADIO_2064_REG047, (u8) (div_frac >> 8) & 0xff);
++	write_radio_reg(pi, RADIO_2064_REG048, (u8) div_frac & 0xff);
++
++	write_radio_reg(pi, RADIO_2064_REG040, 0xfb);
++
++	write_radio_reg(pi, RADIO_2064_REG041, 0x9A);
++	write_radio_reg(pi, RADIO_2064_REG042, 0xA3);
++	write_radio_reg(pi, RADIO_2064_REG043, 0x0C);
++
++	h29 = LCN_BW_LMT / loop_bw;
++	d28 = (((PLL_2064_HIGH_END_KVCO - PLL_2064_LOW_END_KVCO) *
++		(fvco3 / 2 - PLL_2064_LOW_END_VCO)) /
++	       (PLL_2064_HIGH_END_VCO - PLL_2064_LOW_END_VCO))
++	      + PLL_2064_LOW_END_KVCO;
++	h28_ten = (d28 * 10) / LCN_VCO_DIV;
++	e30 = (d30 - LCN_OFFSET) / LCN_FACT;
++	g30 = LCN_OFFSET + (e30 * LCN_FACT);
++	h30_ten = (g30 * 10) / LCN_CUR_DIV;
++	cp_current = ((LCN_CUR_LMT * h29 * LCN_MULT * 100) / h28_ten) / h30_ten;
++	mod_radio_reg(pi, RADIO_2064_REG03C, 0x3f, cp_current);
++
++	if (channel >= 1 && channel <= 5)
++		write_radio_reg(pi, RADIO_2064_REG03C, 0x8);
++	else
++		write_radio_reg(pi, RADIO_2064_REG03C, 0x7);
++	write_radio_reg(pi, RADIO_2064_REG03D, 0x3);
++
++	mod_radio_reg(pi, RADIO_2064_REG044, 0x0c, 0x0c);
++	udelay(1);
++
++	wlc_2064_vco_cal(pi);
++
++	write_radio_reg(pi, RADIO_2064_REG044, pll_pwrup);
++	write_radio_reg(pi, RADIO_2064_REG12B, pll_pwrup_ovr);
++	if (LCNREV_IS(pi->pubpi.phy_rev, 1)) {
++		write_radio_reg(pi, RADIO_2064_REG038, 3);
++		write_radio_reg(pi, RADIO_2064_REG091, 7);
++	}
++}
++
++static int
++wlc_lcnphy_load_tx_iir_filter(struct brcms_phy *pi, bool is_ofdm, s16 filt_type)
++{
++	s16 filt_index = -1;
++	int j;
++
++	u16 addr[] = {
++		0x910,
++		0x91e,
++		0x91f,
++		0x924,
++		0x925,
++		0x926,
++		0x920,
++		0x921,
++		0x927,
++		0x928,
++		0x929,
++		0x922,
++		0x923,
++		0x930,
++		0x931,
++		0x932
++	};
++
++	u16 addr_ofdm[] = {
++		0x90f,
++		0x900,
++		0x901,
++		0x906,
++		0x907,
++		0x908,
++		0x902,
++		0x903,
++		0x909,
++		0x90a,
++		0x90b,
++		0x904,
++		0x905,
++		0x90c,
++		0x90d,
++		0x90e
++	};
++
++	if (!is_ofdm) {
++		for (j = 0; j < LCNPHY_NUM_TX_DIG_FILTERS_CCK; j++) {
++			if (filt_type == LCNPHY_txdigfiltcoeffs_cck[j][0]) {
++				filt_index = (s16) j;
++				break;
++			}
++		}
++
++		if (filt_index != -1) {
++			for (j = 0; j < LCNPHY_NUM_DIG_FILT_COEFFS; j++)
++				write_phy_reg(pi, addr[j],
++					      LCNPHY_txdigfiltcoeffs_cck
++					      [filt_index][j + 1]);
++		}
++	} else {
++		for (j = 0; j < LCNPHY_NUM_TX_DIG_FILTERS_OFDM; j++) {
++			if (filt_type == LCNPHY_txdigfiltcoeffs_ofdm[j][0]) {
++				filt_index = (s16) j;
++				break;
++			}
++		}
++
++		if (filt_index != -1) {
++			for (j = 0; j < LCNPHY_NUM_DIG_FILT_COEFFS; j++)
++				write_phy_reg(pi, addr_ofdm[j],
++					      LCNPHY_txdigfiltcoeffs_ofdm
++					      [filt_index][j + 1]);
++		}
++	}
++
++	return (filt_index != -1) ? 0 : -1;
++}
++
++void wlc_phy_chanspec_set_lcnphy(struct brcms_phy *pi, u16 chanspec)
++{
++	u8 channel = CHSPEC_CHANNEL(chanspec);
++
++	wlc_phy_chanspec_radio_set((struct brcms_phy_pub *) pi, chanspec);
++
++	wlc_lcnphy_set_chanspec_tweaks(pi, pi->radio_chanspec);
++
++	or_phy_reg(pi, 0x44a, 0x44);
++	write_phy_reg(pi, 0x44a, 0x80);
++
++	wlc_lcnphy_radio_2064_channel_tune_4313(pi, channel);
++	udelay(1000);
++
++	wlc_lcnphy_toggle_afe_pwdn(pi);
++
++	write_phy_reg(pi, 0x657, lcnphy_sfo_cfg[channel - 1].ptcentreTs20);
++	write_phy_reg(pi, 0x658, lcnphy_sfo_cfg[channel - 1].ptcentreFactor);
++
++	if (CHSPEC_CHANNEL(pi->radio_chanspec) == 14) {
++		mod_phy_reg(pi, 0x448, (0x3 << 8), (2) << 8);
++
++		wlc_lcnphy_load_tx_iir_filter(pi, false, 3);
++	} else {
++		mod_phy_reg(pi, 0x448, (0x3 << 8), (1) << 8);
++
++		wlc_lcnphy_load_tx_iir_filter(pi, false, 2);
++	}
++
++	wlc_lcnphy_load_tx_iir_filter(pi, true, 0);
++
++	mod_phy_reg(pi, 0x4eb, (0x7 << 3), (1) << 3);
++
++}
++
++static u16 wlc_lcnphy_get_pa_gain(struct brcms_phy *pi)
++{
++	u16 pa_gain;
++
++	pa_gain = (read_phy_reg(pi, 0x4fb) &
++		   LCNPHY_txgainctrlovrval1_pagain_ovr_val1_MASK) >>
++		  LCNPHY_txgainctrlovrval1_pagain_ovr_val1_SHIFT;
++
++	return pa_gain;
++}
++
++static void wlc_lcnphy_set_tx_gain(struct brcms_phy *pi,
++				   struct lcnphy_txgains *target_gains)
++{
++	u16 pa_gain = wlc_lcnphy_get_pa_gain(pi);
++
++	mod_phy_reg(
++		pi, 0x4b5,
++		(0xffff << 0),
++		((target_gains->gm_gain) |
++		 (target_gains->pga_gain << 8)) <<
++		0);
++	mod_phy_reg(pi, 0x4fb,
++		    (0x7fff << 0),
++		    ((target_gains->pad_gain) | (pa_gain << 8)) << 0);
++
++	mod_phy_reg(
++		pi, 0x4fc,
++		(0xffff << 0),
++		((target_gains->gm_gain) |
++		 (target_gains->pga_gain << 8)) <<
++		0);
++	mod_phy_reg(pi, 0x4fd,
++		    (0x7fff << 0),
++		    ((target_gains->pad_gain) | (pa_gain << 8)) << 0);
++
++	wlc_lcnphy_set_dac_gain(pi, target_gains->dac_gain);
++
++	wlc_lcnphy_enable_tx_gain_override(pi);
++}
++
++static void wlc_lcnphy_set_bbmult(struct brcms_phy *pi, u8 m0)
++{
++	u16 m0m1 = (u16) m0 << 8;
++	struct phytbl_info tab;
++
++	tab.tbl_ptr = &m0m1;
++	tab.tbl_len = 1;
++	tab.tbl_id = LCNPHY_TBL_ID_IQLOCAL;
++	tab.tbl_offset = 87;
++	tab.tbl_width = 16;
++	wlc_lcnphy_write_table(pi, &tab);
++}
++
++static void wlc_lcnphy_clear_tx_power_offsets(struct brcms_phy *pi)
++{
++	u32 data_buf[64];
++	struct phytbl_info tab;
++
++	memset(data_buf, 0, sizeof(data_buf));
++
++	tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
++	tab.tbl_width = 32;
++	tab.tbl_ptr = data_buf;
++
++	if (!wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) {
++
++		tab.tbl_len = 30;
++		tab.tbl_offset = LCNPHY_TX_PWR_CTRL_RATE_OFFSET;
++		wlc_lcnphy_write_table(pi, &tab);
++	}
++
++	tab.tbl_len = 64;
++	tab.tbl_offset = LCNPHY_TX_PWR_CTRL_MAC_OFFSET;
++	wlc_lcnphy_write_table(pi, &tab);
++}
++
++enum lcnphy_tssi_mode {
++	LCNPHY_TSSI_PRE_PA,
++	LCNPHY_TSSI_POST_PA,
++	LCNPHY_TSSI_EXT
++};
++
++static void
++wlc_lcnphy_set_tssi_mux(struct brcms_phy *pi, enum lcnphy_tssi_mode pos)
++{
++	mod_phy_reg(pi, 0x4d7, (0x1 << 0), (0x1) << 0);
++
++	mod_phy_reg(pi, 0x4d7, (0x1 << 6), (1) << 6);
++
++	if (LCNPHY_TSSI_POST_PA == pos) {
++		mod_phy_reg(pi, 0x4d9, (0x1 << 2), (0) << 2);
++
++		mod_phy_reg(pi, 0x4d9, (0x1 << 3), (1) << 3);
++
++		if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
++			mod_radio_reg(pi, RADIO_2064_REG086, 0x4, 0x4);
++		} else {
++			mod_radio_reg(pi, RADIO_2064_REG03A, 1, 0x1);
++			mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 0x8);
++		}
++	} else {
++		mod_phy_reg(pi, 0x4d9, (0x1 << 2), (0x1) << 2);
++
++		mod_phy_reg(pi, 0x4d9, (0x1 << 3), (0) << 3);
++
++		if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
++			mod_radio_reg(pi, RADIO_2064_REG086, 0x4, 0x4);
++		} else {
++			mod_radio_reg(pi, RADIO_2064_REG03A, 1, 0);
++			mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 0x8);
++		}
++	}
++	mod_phy_reg(pi, 0x637, (0x3 << 14), (0) << 14);
++
++	if (LCNPHY_TSSI_EXT == pos) {
++		write_radio_reg(pi, RADIO_2064_REG07F, 1);
++		mod_radio_reg(pi, RADIO_2064_REG005, 0x7, 0x2);
++		mod_radio_reg(pi, RADIO_2064_REG112, 0x80, 0x1 << 7);
++		mod_radio_reg(pi, RADIO_2064_REG028, 0x1f, 0x3);
++	}
++}
++
++static u16 wlc_lcnphy_rfseq_tbl_adc_pwrup(struct brcms_phy *pi)
++{
++	u16 N1, N2, N3, N4, N5, N6, N;
++	N1 = ((read_phy_reg(pi, 0x4a5) & (0xff << 0))
++	      >> 0);
++	N2 = 1 << ((read_phy_reg(pi, 0x4a5) & (0x7 << 12))
++		   >> 12);
++	N3 = ((read_phy_reg(pi, 0x40d) & (0xff << 0))
++	      >> 0);
++	N4 = 1 << ((read_phy_reg(pi, 0x40d) & (0x7 << 8))
++		   >> 8);
++	N5 = ((read_phy_reg(pi, 0x4a2) & (0xff << 0))
++	      >> 0);
++	N6 = 1 << ((read_phy_reg(pi, 0x4a2) & (0x7 << 8))
++		   >> 8);
++	N = 2 * (N1 + N2 + N3 + N4 + 2 * (N5 + N6)) + 80;
++	if (N < 1600)
++		N = 1600;
++	return N;
++}
++
++static void wlc_lcnphy_pwrctrl_rssiparams(struct brcms_phy *pi)
++{
++	u16 auxpga_vmid, auxpga_vmid_temp, auxpga_gain_temp;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	auxpga_vmid = (2 << 8) |
++		      (pi_lcn->lcnphy_rssi_vc << 4) | pi_lcn->lcnphy_rssi_vf;
++	auxpga_vmid_temp = (2 << 8) | (8 << 4) | 4;
++	auxpga_gain_temp = 2;
++
++	mod_phy_reg(pi, 0x4d8, (0x1 << 0), (0) << 0);
++
++	mod_phy_reg(pi, 0x4d8, (0x1 << 1), (0) << 1);
++
++	mod_phy_reg(pi, 0x4d7, (0x1 << 3), (0) << 3);
++
++	mod_phy_reg(pi, 0x4db,
++		    (0x3ff << 0) |
++		    (0x7 << 12),
++		    (auxpga_vmid << 0) | (pi_lcn->lcnphy_rssi_gs << 12));
++
++	mod_phy_reg(pi, 0x4dc,
++		    (0x3ff << 0) |
++		    (0x7 << 12),
++		    (auxpga_vmid << 0) | (pi_lcn->lcnphy_rssi_gs << 12));
++
++	mod_phy_reg(pi, 0x40a,
++		    (0x3ff << 0) |
++		    (0x7 << 12),
++		    (auxpga_vmid << 0) | (pi_lcn->lcnphy_rssi_gs << 12));
++
++	mod_phy_reg(pi, 0x40b,
++		    (0x3ff << 0) |
++		    (0x7 << 12),
++		    (auxpga_vmid_temp << 0) | (auxpga_gain_temp << 12));
++
++	mod_phy_reg(pi, 0x40c,
++		    (0x3ff << 0) |
++		    (0x7 << 12),
++		    (auxpga_vmid_temp << 0) | (auxpga_gain_temp << 12));
++
++	mod_radio_reg(pi, RADIO_2064_REG082, (1 << 5), (1 << 5));
++}
++
++static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi)
++{
++	struct phytbl_info tab;
++	u32 rfseq, ind;
++
++	tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
++	tab.tbl_width = 32;
++	tab.tbl_ptr = &ind;
++	tab.tbl_len = 1;
++	tab.tbl_offset = 0;
++	for (ind = 0; ind < 128; ind++) {
++		wlc_lcnphy_write_table(pi, &tab);
++		tab.tbl_offset++;
++	}
++	tab.tbl_offset = 704;
++	for (ind = 0; ind < 128; ind++) {
++		wlc_lcnphy_write_table(pi, &tab);
++		tab.tbl_offset++;
++	}
++	mod_phy_reg(pi, 0x503, (0x1 << 0), (0) << 0);
++
++	mod_phy_reg(pi, 0x503, (0x1 << 2), (0) << 2);
++
++	mod_phy_reg(pi, 0x503, (0x1 << 4), (1) << 4);
++
++	wlc_lcnphy_set_tssi_mux(pi, LCNPHY_TSSI_EXT);
++	mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0) << 14);
++
++	mod_phy_reg(pi, 0x4a4, (0x1 << 15), (1) << 15);
++
++	mod_phy_reg(pi, 0x4d0, (0x1 << 5), (0) << 5);
++
++	mod_phy_reg(pi, 0x4a4, (0x1ff << 0), (0) << 0);
++
++	mod_phy_reg(pi, 0x4a5, (0xff << 0), (255) << 0);
++
++	mod_phy_reg(pi, 0x4a5, (0x7 << 12), (5) << 12);
++
++	mod_phy_reg(pi, 0x4a5, (0x7 << 8), (0) << 8);
++
++	mod_phy_reg(pi, 0x40d, (0xff << 0), (64) << 0);
++
++	mod_phy_reg(pi, 0x40d, (0x7 << 8), (4) << 8);
++
++	mod_phy_reg(pi, 0x4a2, (0xff << 0), (64) << 0);
++
++	mod_phy_reg(pi, 0x4a2, (0x7 << 8), (4) << 8);
++
++	mod_phy_reg(pi, 0x4d0, (0x1ff << 6), (0) << 6);
++
++	mod_phy_reg(pi, 0x4a8, (0xff << 0), (0x1) << 0);
++
++	wlc_lcnphy_clear_tx_power_offsets(pi);
++
++	mod_phy_reg(pi, 0x4a6, (0x1 << 15), (1) << 15);
++
++	mod_phy_reg(pi, 0x4a6, (0x1ff << 0), (0xff) << 0);
++
++	mod_phy_reg(pi, 0x49a, (0x1ff << 0), (0xff) << 0);
++
++	if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
++		mod_radio_reg(pi, RADIO_2064_REG028, 0xf, 0xe);
++		mod_radio_reg(pi, RADIO_2064_REG086, 0x4, 0x4);
++	} else {
++		mod_radio_reg(pi, RADIO_2064_REG03A, 0x1, 1);
++		mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 1 << 3);
++	}
++
++	write_radio_reg(pi, RADIO_2064_REG025, 0xc);
++
++	if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
++		mod_radio_reg(pi, RADIO_2064_REG03A, 0x1, 1);
++	} else {
++		if (CHSPEC_IS2G(pi->radio_chanspec))
++			mod_radio_reg(pi, RADIO_2064_REG03A, 0x2, 1 << 1);
++		else
++			mod_radio_reg(pi, RADIO_2064_REG03A, 0x2, 0 << 1);
++	}
++
++	if (LCNREV_IS(pi->pubpi.phy_rev, 2))
++		mod_radio_reg(pi, RADIO_2064_REG03A, 0x2, 1 << 1);
++	else
++		mod_radio_reg(pi, RADIO_2064_REG03A, 0x4, 1 << 2);
++
++	mod_radio_reg(pi, RADIO_2064_REG11A, 0x1, 1 << 0);
++
++	mod_radio_reg(pi, RADIO_2064_REG005, 0x8, 1 << 3);
++
++	if (!wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi))
++		mod_phy_reg(pi, 0x4d7,
++			    (0x1 << 3) | (0x7 << 12), 0 << 3 | 2 << 12);
++
++	rfseq = wlc_lcnphy_rfseq_tbl_adc_pwrup(pi);
++	tab.tbl_id = LCNPHY_TBL_ID_RFSEQ;
++	tab.tbl_width = 16;
++	tab.tbl_ptr = &rfseq;
++	tab.tbl_len = 1;
++	tab.tbl_offset = 6;
++	wlc_lcnphy_write_table(pi, &tab);
++
++	mod_phy_reg(pi, 0x938, (0x1 << 2), (1) << 2);
++
++	mod_phy_reg(pi, 0x939, (0x1 << 2), (1) << 2);
++
++	mod_phy_reg(pi, 0x4a4, (0x1 << 12), (1) << 12);
++
++	mod_phy_reg(pi, 0x4d7, (0x1 << 2), (1) << 2);
++
++	mod_phy_reg(pi, 0x4d7, (0xf << 8), (0) << 8);
++
++	wlc_lcnphy_pwrctrl_rssiparams(pi);
++}
++
++void wlc_lcnphy_tx_pwr_update_npt(struct brcms_phy *pi)
++{
++	u16 tx_cnt, tx_total, npt;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	tx_total = wlc_lcnphy_total_tx_frames(pi);
++	tx_cnt = tx_total - pi_lcn->lcnphy_tssi_tx_cnt;
++	npt = wlc_lcnphy_get_tx_pwr_npt(pi);
++
++	if (tx_cnt > (1 << npt)) {
++
++		pi_lcn->lcnphy_tssi_tx_cnt = tx_total;
++
++		pi_lcn->lcnphy_tssi_idx = wlc_lcnphy_get_current_tx_pwr_idx(pi);
++		pi_lcn->lcnphy_tssi_npt = npt;
++
++	}
++}
++
++s32 wlc_lcnphy_tssi2dbm(s32 tssi, s32 a1, s32 b0, s32 b1)
++{
++	s32 a, b, p;
++
++	a = 32768 + (a1 * tssi);
++	b = (1024 * b0) + (64 * b1 * tssi);
++	p = ((2 * b) + a) / (2 * a);
++
++	return p;
++}
++
++static void wlc_lcnphy_txpower_reset_npt(struct brcms_phy *pi)
++{
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++	if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi))
++		return;
++
++	pi_lcn->lcnphy_tssi_idx = LCNPHY_TX_PWR_CTRL_START_INDEX_2G_4313;
++	pi_lcn->lcnphy_tssi_npt = LCNPHY_TX_PWR_CTRL_START_NPT;
++}
++
++void wlc_lcnphy_txpower_recalc_target(struct brcms_phy *pi)
++{
++	struct phytbl_info tab;
++	u32 rate_table[BRCMS_NUM_RATES_CCK + BRCMS_NUM_RATES_OFDM +
++		       BRCMS_NUM_RATES_MCS_1_STREAM];
++	uint i, j;
++	if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi))
++		return;
++
++	for (i = 0, j = 0; i < ARRAY_SIZE(rate_table); i++, j++) {
++
++		if (i == BRCMS_NUM_RATES_CCK + BRCMS_NUM_RATES_OFDM)
++			j = TXP_FIRST_MCS_20_SISO;
++
++		rate_table[i] = (u32) ((s32) (-pi->tx_power_offset[j]));
++	}
++
++	tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
++	tab.tbl_width = 32;
++	tab.tbl_len = ARRAY_SIZE(rate_table);
++	tab.tbl_ptr = rate_table;
++	tab.tbl_offset = LCNPHY_TX_PWR_CTRL_RATE_OFFSET;
++	wlc_lcnphy_write_table(pi, &tab);
++
++	if (wlc_lcnphy_get_target_tx_pwr(pi) != pi->tx_power_min) {
++		wlc_lcnphy_set_target_tx_pwr(pi, pi->tx_power_min);
++
++		wlc_lcnphy_txpower_reset_npt(pi);
++	}
++}
++
++static void wlc_lcnphy_set_tx_pwr_soft_ctrl(struct brcms_phy *pi, s8 index)
++{
++	u32 cck_offset[4] = { 22, 22, 22, 22 };
++	u32 ofdm_offset, reg_offset_cck;
++	int i;
++	u16 index2;
++	struct phytbl_info tab;
++
++	if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi))
++		return;
++
++	mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0x1) << 14);
++
++	mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0x0) << 14);
++
++	or_phy_reg(pi, 0x6da, 0x0040);
++
++	reg_offset_cck = 0;
++	for (i = 0; i < 4; i++)
++		cck_offset[i] -= reg_offset_cck;
++	tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
++	tab.tbl_width = 32;
++	tab.tbl_len = 4;
++	tab.tbl_ptr = cck_offset;
++	tab.tbl_offset = LCNPHY_TX_PWR_CTRL_RATE_OFFSET;
++	wlc_lcnphy_write_table(pi, &tab);
++	ofdm_offset = 0;
++	tab.tbl_len = 1;
++	tab.tbl_ptr = &ofdm_offset;
++	for (i = 836; i < 862; i++) {
++		tab.tbl_offset = i;
++		wlc_lcnphy_write_table(pi, &tab);
++	}
++
++	mod_phy_reg(pi, 0x4a4, (0x1 << 15), (0x1) << 15);
++
++	mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0x1) << 14);
++
++	mod_phy_reg(pi, 0x4a4, (0x1 << 13), (0x1) << 13);
++
++	mod_phy_reg(pi, 0x4b0, (0x1 << 7), (0) << 7);
++
++	mod_phy_reg(pi, 0x43b, (0x1 << 6), (0) << 6);
++
++	mod_phy_reg(pi, 0x4a9, (0x1 << 15), (1) << 15);
++
++	index2 = (u16) (index * 2);
++	mod_phy_reg(pi, 0x4a9, (0x1ff << 0), (index2) << 0);
++
++	mod_phy_reg(pi, 0x6a3, (0x1 << 4), (0) << 4);
++
++}
++
++static s8 wlc_lcnphy_tempcompensated_txpwrctrl(struct brcms_phy *pi)
++{
++	s8 index, delta_brd, delta_temp, new_index, tempcorrx;
++	s16 manp, meas_temp, temp_diff;
++	bool neg = false;
++	u16 temp;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi))
++		return pi_lcn->lcnphy_current_index;
++
++	index = FIXED_TXPWR;
++
++	if (pi_lcn->lcnphy_tempsense_slope == 0)
++		return index;
++
++	temp = (u16) wlc_lcnphy_tempsense(pi, 0);
++	meas_temp = LCNPHY_TEMPSENSE(temp);
++
++	if (pi->tx_power_min != 0)
++		delta_brd = (pi_lcn->lcnphy_measPower - pi->tx_power_min);
++	else
++		delta_brd = 0;
++
++	manp = LCNPHY_TEMPSENSE(pi_lcn->lcnphy_rawtempsense);
++	temp_diff = manp - meas_temp;
++	if (temp_diff < 0) {
++		neg = true;
++		temp_diff = -temp_diff;
++	}
++
++	delta_temp = (s8) wlc_lcnphy_qdiv_roundup((u32) (temp_diff * 192),
++						  (u32) (pi_lcn->
++							 lcnphy_tempsense_slope
++							 * 10), 0);
++	if (neg)
++		delta_temp = -delta_temp;
++
++	if (pi_lcn->lcnphy_tempsense_option == 3
++	    && LCNREV_IS(pi->pubpi.phy_rev, 0))
++		delta_temp = 0;
++	if (pi_lcn->lcnphy_tempcorrx > 31)
++		tempcorrx = (s8) (pi_lcn->lcnphy_tempcorrx - 64);
++	else
++		tempcorrx = (s8) pi_lcn->lcnphy_tempcorrx;
++	if (LCNREV_IS(pi->pubpi.phy_rev, 1))
++		tempcorrx = 4;
++	new_index =
++		index + delta_brd + delta_temp - pi_lcn->lcnphy_bandedge_corr;
++	new_index += tempcorrx;
++
++	if (LCNREV_IS(pi->pubpi.phy_rev, 1))
++		index = 127;
++
++	if (new_index < 0 || new_index > 126)
++		return index;
++
++	return new_index;
++}
++
++static u16 wlc_lcnphy_set_tx_pwr_ctrl_mode(struct brcms_phy *pi, u16 mode)
++{
++
++	u16 current_mode = mode;
++	if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi) &&
++	    mode == LCNPHY_TX_PWR_CTRL_HW)
++		current_mode = LCNPHY_TX_PWR_CTRL_TEMPBASED;
++	if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi) &&
++	    mode == LCNPHY_TX_PWR_CTRL_TEMPBASED)
++		current_mode = LCNPHY_TX_PWR_CTRL_HW;
++	return current_mode;
++}
++
++void wlc_lcnphy_set_tx_pwr_ctrl(struct brcms_phy *pi, u16 mode)
++{
++	u16 old_mode = wlc_lcnphy_get_tx_pwr_ctrl(pi);
++	s8 index;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	mode = wlc_lcnphy_set_tx_pwr_ctrl_mode(pi, mode);
++	old_mode = wlc_lcnphy_set_tx_pwr_ctrl_mode(pi, old_mode);
++
++	mod_phy_reg(pi, 0x6da, (0x1 << 6),
++		    ((LCNPHY_TX_PWR_CTRL_HW == mode) ? 1 : 0) << 6);
++
++	mod_phy_reg(pi, 0x6a3, (0x1 << 4),
++		    ((LCNPHY_TX_PWR_CTRL_HW == mode) ? 0 : 1) << 4);
++
++	if (old_mode != mode) {
++		if (LCNPHY_TX_PWR_CTRL_HW == old_mode) {
++
++			wlc_lcnphy_tx_pwr_update_npt(pi);
++
++			wlc_lcnphy_clear_tx_power_offsets(pi);
++		}
++		if (LCNPHY_TX_PWR_CTRL_HW == mode) {
++
++			wlc_lcnphy_txpower_recalc_target(pi);
++
++			wlc_lcnphy_set_start_tx_pwr_idx(pi,
++							pi_lcn->
++							lcnphy_tssi_idx);
++			wlc_lcnphy_set_tx_pwr_npt(pi, pi_lcn->lcnphy_tssi_npt);
++			mod_radio_reg(pi, RADIO_2064_REG11F, 0x4, 0);
++
++			pi_lcn->lcnphy_tssi_tx_cnt =
++				wlc_lcnphy_total_tx_frames(pi);
++
++			wlc_lcnphy_disable_tx_gain_override(pi);
++			pi_lcn->lcnphy_tx_power_idx_override = -1;
++		} else
++			wlc_lcnphy_enable_tx_gain_override(pi);
++
++		mod_phy_reg(pi, 0x4a4,
++			    ((0x1 << 15) | (0x1 << 14) | (0x1 << 13)), mode);
++		if (mode == LCNPHY_TX_PWR_CTRL_TEMPBASED) {
++			index = wlc_lcnphy_tempcompensated_txpwrctrl(pi);
++			wlc_lcnphy_set_tx_pwr_soft_ctrl(pi, index);
++			pi_lcn->lcnphy_current_index = (s8)
++						       ((read_phy_reg(pi,
++								      0x4a9) &
++							 0xFF) / 2);
++		}
++	}
++}
++
++static void
++wlc_lcnphy_tx_iqlo_loopback(struct brcms_phy *pi, u16 *values_to_save)
++{
++	u16 vmid;
++	int i;
++	for (i = 0; i < 20; i++)
++		values_to_save[i] =
++			read_radio_reg(pi, iqlo_loopback_rf_regs[i]);
++
++	mod_phy_reg(pi, 0x44c, (0x1 << 12), 1 << 12);
++	mod_phy_reg(pi, 0x44d, (0x1 << 14), 1 << 14);
++
++	mod_phy_reg(pi, 0x44c, (0x1 << 11), 1 << 11);
++	mod_phy_reg(pi, 0x44d, (0x1 << 13), 0 << 13);
++
++	mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1);
++	mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1);
++
++	mod_phy_reg(pi, 0x43b, (0x1 << 0), 1 << 0);
++	mod_phy_reg(pi, 0x43c, (0x1 << 0), 0 << 0);
++
++	if (LCNREV_IS(pi->pubpi.phy_rev, 2))
++		and_radio_reg(pi, RADIO_2064_REG03A, 0xFD);
++	else
++		and_radio_reg(pi, RADIO_2064_REG03A, 0xF9);
++	or_radio_reg(pi, RADIO_2064_REG11A, 0x1);
++
++	or_radio_reg(pi, RADIO_2064_REG036, 0x01);
++	or_radio_reg(pi, RADIO_2064_REG11A, 0x18);
++	udelay(20);
++
++	if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
++		if (CHSPEC_IS5G(pi->radio_chanspec))
++			mod_radio_reg(pi, RADIO_2064_REG03A, 1, 0);
++		else
++			or_radio_reg(pi, RADIO_2064_REG03A, 1);
++	} else {
++		if (CHSPEC_IS5G(pi->radio_chanspec))
++			mod_radio_reg(pi, RADIO_2064_REG03A, 3, 1);
++		else
++			or_radio_reg(pi, RADIO_2064_REG03A, 0x3);
++	}
++
++	udelay(20);
++
++	write_radio_reg(pi, RADIO_2064_REG025, 0xF);
++	if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
++		if (CHSPEC_IS5G(pi->radio_chanspec))
++			mod_radio_reg(pi, RADIO_2064_REG028, 0xF, 0x4);
++		else
++			mod_radio_reg(pi, RADIO_2064_REG028, 0xF, 0x6);
++	} else {
++		if (CHSPEC_IS5G(pi->radio_chanspec))
++			mod_radio_reg(pi, RADIO_2064_REG028, 0x1e, 0x4 << 1);
++		else
++			mod_radio_reg(pi, RADIO_2064_REG028, 0x1e, 0x6 << 1);
++	}
++
++	udelay(20);
++
++	write_radio_reg(pi, RADIO_2064_REG005, 0x8);
++	or_radio_reg(pi, RADIO_2064_REG112, 0x80);
++	udelay(20);
++
++	or_radio_reg(pi, RADIO_2064_REG0FF, 0x10);
++	or_radio_reg(pi, RADIO_2064_REG11F, 0x44);
++	udelay(20);
++
++	or_radio_reg(pi, RADIO_2064_REG00B, 0x7);
++	or_radio_reg(pi, RADIO_2064_REG113, 0x10);
++	udelay(20);
++
++	write_radio_reg(pi, RADIO_2064_REG007, 0x1);
++	udelay(20);
++
++	vmid = 0x2A6;
++	mod_radio_reg(pi, RADIO_2064_REG0FC, 0x3 << 0, (vmid >> 8) & 0x3);
++	write_radio_reg(pi, RADIO_2064_REG0FD, (vmid & 0xff));
++	or_radio_reg(pi, RADIO_2064_REG11F, 0x44);
++	udelay(20);
++
++	or_radio_reg(pi, RADIO_2064_REG0FF, 0x10);
++	udelay(20);
++	write_radio_reg(pi, RADIO_2064_REG012, 0x02);
++	or_radio_reg(pi, RADIO_2064_REG112, 0x06);
++	write_radio_reg(pi, RADIO_2064_REG036, 0x11);
++	write_radio_reg(pi, RADIO_2064_REG059, 0xcc);
++	write_radio_reg(pi, RADIO_2064_REG05C, 0x2e);
++	write_radio_reg(pi, RADIO_2064_REG078, 0xd7);
++	write_radio_reg(pi, RADIO_2064_REG092, 0x15);
++}
++
++static bool wlc_lcnphy_iqcal_wait(struct brcms_phy *pi)
++{
++	uint delay_count = 0;
++
++	while (wlc_lcnphy_iqcal_active(pi)) {
++		udelay(100);
++		delay_count++;
++
++		if (delay_count > (10 * 500))
++			break;
++	}
++
++	return (0 == wlc_lcnphy_iqcal_active(pi));
++}
++
++static void
++wlc_lcnphy_tx_iqlo_loopback_cleanup(struct brcms_phy *pi, u16 *values_to_save)
++{
++	int i;
++
++	and_phy_reg(pi, 0x44c, 0x0 >> 11);
++
++	and_phy_reg(pi, 0x43b, 0xC);
++
++	for (i = 0; i < 20; i++)
++		write_radio_reg(pi, iqlo_loopback_rf_regs[i],
++				values_to_save[i]);
++}
++
++static void
++wlc_lcnphy_tx_iqlo_cal(struct brcms_phy *pi,
++		       struct lcnphy_txgains *target_gains,
++		       enum lcnphy_cal_mode cal_mode, bool keep_tone)
++{
++
++	struct lcnphy_txgains cal_gains, temp_gains;
++	u16 hash;
++	u8 band_idx;
++	int j;
++	u16 ncorr_override[5];
++	u16 syst_coeffs[] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
++			      0x0000, 0x0000, 0x0000, 0x0000, 0x0000};
++
++	u16 commands_fullcal[] = {
++		0x8434, 0x8334, 0x8084, 0x8267, 0x8056, 0x8234
++	};
++
++	u16 commands_recal[] = {
++		0x8434, 0x8334, 0x8084, 0x8267, 0x8056, 0x8234
++	};
++
++	u16 command_nums_fullcal[] = {
++		0x7a97, 0x7a97, 0x7a97, 0x7a87, 0x7a87, 0x7b97
++	};
++
++	u16 command_nums_recal[] = {
++		0x7a97, 0x7a97, 0x7a97, 0x7a87, 0x7a87, 0x7b97
++	};
++	u16 *command_nums = command_nums_fullcal;
++
++	u16 *start_coeffs = NULL, *cal_cmds = NULL, cal_type, diq_start;
++	u16 tx_pwr_ctrl_old, save_txpwrctrlrfctrl2;
++	u16 save_sslpnCalibClkEnCtrl, save_sslpnRxFeClkEnCtrl;
++	bool tx_gain_override_old;
++	struct lcnphy_txgains old_gains;
++	uint i, n_cal_cmds = 0, n_cal_start = 0;
++	u16 *values_to_save;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	values_to_save = kmalloc(sizeof(u16) * 20, GFP_ATOMIC);
++	if (NULL == values_to_save)
++		return;
++
++	save_sslpnRxFeClkEnCtrl = read_phy_reg(pi, 0x6db);
++	save_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da);
++
++	or_phy_reg(pi, 0x6da, 0x40);
++	or_phy_reg(pi, 0x6db, 0x3);
++
++	switch (cal_mode) {
++	case LCNPHY_CAL_FULL:
++		start_coeffs = syst_coeffs;
++		cal_cmds = commands_fullcal;
++		n_cal_cmds = ARRAY_SIZE(commands_fullcal);
++		break;
++
++	case LCNPHY_CAL_RECAL:
++		start_coeffs = syst_coeffs;
++		cal_cmds = commands_recal;
++		n_cal_cmds = ARRAY_SIZE(commands_recal);
++		command_nums = command_nums_recal;
++		break;
++
++	default:
++		break;
++	}
++
++	wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
++				      start_coeffs, 11, 16, 64);
++
++	write_phy_reg(pi, 0x6da, 0xffff);
++	mod_phy_reg(pi, 0x503, (0x1 << 3), (1) << 3);
++
++	tx_pwr_ctrl_old = wlc_lcnphy_get_tx_pwr_ctrl(pi);
++
++	mod_phy_reg(pi, 0x4a4, (0x1 << 12), (1) << 12);
++
++	wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
++
++	save_txpwrctrlrfctrl2 = read_phy_reg(pi, 0x4db);
++
++	mod_phy_reg(pi, 0x4db, (0x3ff << 0), (0x2a6) << 0);
++
++	mod_phy_reg(pi, 0x4db, (0x7 << 12), (2) << 12);
++
++	wlc_lcnphy_tx_iqlo_loopback(pi, values_to_save);
++
++	tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi);
++	if (tx_gain_override_old)
++		wlc_lcnphy_get_tx_gain(pi, &old_gains);
++
++	if (!target_gains) {
++		if (!tx_gain_override_old)
++			wlc_lcnphy_set_tx_pwr_by_index(pi,
++						       pi_lcn->lcnphy_tssi_idx);
++		wlc_lcnphy_get_tx_gain(pi, &temp_gains);
++		target_gains = &temp_gains;
++	}
++
++	hash = (target_gains->gm_gain << 8) |
++	       (target_gains->pga_gain << 4) | (target_gains->pad_gain);
++
++	band_idx = (CHSPEC_IS5G(pi->radio_chanspec) ? 1 : 0);
++
++	cal_gains = *target_gains;
++	memset(ncorr_override, 0, sizeof(ncorr_override));
++	for (j = 0; j < iqcal_gainparams_numgains_lcnphy[band_idx]; j++) {
++		if (hash == tbl_iqcal_gainparams_lcnphy[band_idx][j][0]) {
++			cal_gains.gm_gain =
++				tbl_iqcal_gainparams_lcnphy[band_idx][j][1];
++			cal_gains.pga_gain =
++				tbl_iqcal_gainparams_lcnphy[band_idx][j][2];
++			cal_gains.pad_gain =
++				tbl_iqcal_gainparams_lcnphy[band_idx][j][3];
++			memcpy(ncorr_override,
++			       &tbl_iqcal_gainparams_lcnphy[band_idx][j][3],
++			       sizeof(ncorr_override));
++			break;
++		}
++	}
++
++	wlc_lcnphy_set_tx_gain(pi, &cal_gains);
++
++	write_phy_reg(pi, 0x453, 0xaa9);
++	write_phy_reg(pi, 0x93d, 0xc0);
++
++	wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
++				      lcnphy_iqcal_loft_gainladder,
++				      ARRAY_SIZE(lcnphy_iqcal_loft_gainladder),
++				      16, 0);
++
++	wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
++				      lcnphy_iqcal_ir_gainladder,
++				      ARRAY_SIZE(
++					      lcnphy_iqcal_ir_gainladder), 16,
++				      32);
++
++	if (pi->phy_tx_tone_freq) {
++
++		wlc_lcnphy_stop_tx_tone(pi);
++		udelay(5);
++		wlc_lcnphy_start_tx_tone(pi, 3750, 88, 1);
++	} else {
++		wlc_lcnphy_start_tx_tone(pi, 3750, 88, 1);
++	}
++
++	write_phy_reg(pi, 0x6da, 0xffff);
++
++	for (i = n_cal_start; i < n_cal_cmds; i++) {
++		u16 zero_diq = 0;
++		u16 best_coeffs[11];
++		u16 command_num;
++
++		cal_type = (cal_cmds[i] & 0x0f00) >> 8;
++
++		command_num = command_nums[i];
++		if (ncorr_override[cal_type])
++			command_num =
++				ncorr_override[cal_type] << 8 | (command_num &
++								 0xff);
++
++		write_phy_reg(pi, 0x452, command_num);
++
++		if ((cal_type == 3) || (cal_type == 4)) {
++			wlc_lcnphy_common_read_table(pi, LCNPHY_TBL_ID_IQLOCAL,
++						     &diq_start, 1, 16, 69);
++
++			wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
++						      &zero_diq, 1, 16, 69);
++		}
++
++		write_phy_reg(pi, 0x451, cal_cmds[i]);
++
++		if (!wlc_lcnphy_iqcal_wait(pi))
++			goto cleanup;
++
++		wlc_lcnphy_common_read_table(pi, LCNPHY_TBL_ID_IQLOCAL,
++					     best_coeffs,
++					     ARRAY_SIZE(best_coeffs), 16, 96);
++		wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
++					      best_coeffs,
++					      ARRAY_SIZE(best_coeffs), 16, 64);
++
++		if ((cal_type == 3) || (cal_type == 4))
++			wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
++						      &diq_start, 1, 16, 69);
++		wlc_lcnphy_common_read_table(pi, LCNPHY_TBL_ID_IQLOCAL,
++					     pi_lcn->lcnphy_cal_results.
++					     txiqlocal_bestcoeffs,
++					     ARRAY_SIZE(pi_lcn->
++							lcnphy_cal_results.
++							txiqlocal_bestcoeffs),
++					     16, 96);
++	}
++
++	wlc_lcnphy_common_read_table(pi, LCNPHY_TBL_ID_IQLOCAL,
++				     pi_lcn->lcnphy_cal_results.
++				     txiqlocal_bestcoeffs,
++				     ARRAY_SIZE(pi_lcn->lcnphy_cal_results.
++						txiqlocal_bestcoeffs), 16, 96);
++	pi_lcn->lcnphy_cal_results.txiqlocal_bestcoeffs_valid = true;
++
++	wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
++				      &pi_lcn->lcnphy_cal_results.
++				      txiqlocal_bestcoeffs[0], 4, 16, 80);
++
++	wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
++				      &pi_lcn->lcnphy_cal_results.
++				      txiqlocal_bestcoeffs[5], 2, 16, 85);
++
++cleanup:
++	wlc_lcnphy_tx_iqlo_loopback_cleanup(pi, values_to_save);
++	kfree(values_to_save);
++
++	if (!keep_tone)
++		wlc_lcnphy_stop_tx_tone(pi);
++
++	write_phy_reg(pi, 0x4db, save_txpwrctrlrfctrl2);
++
++	write_phy_reg(pi, 0x453, 0);
++
++	if (tx_gain_override_old)
++		wlc_lcnphy_set_tx_gain(pi, &old_gains);
++	wlc_lcnphy_set_tx_pwr_ctrl(pi, tx_pwr_ctrl_old);
++
++	write_phy_reg(pi, 0x6da, save_sslpnCalibClkEnCtrl);
++	write_phy_reg(pi, 0x6db, save_sslpnRxFeClkEnCtrl);
++
++}
++
++static void wlc_lcnphy_idle_tssi_est(struct brcms_phy_pub *ppi)
++{
++	bool suspend, tx_gain_override_old;
++	struct lcnphy_txgains old_gains;
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++	u16 idleTssi, idleTssi0_2C, idleTssi0_OB, idleTssi0_regvalue_OB,
++	    idleTssi0_regvalue_2C;
++	u16 SAVE_txpwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
++	u16 SAVE_lpfgain = read_radio_reg(pi, RADIO_2064_REG112);
++	u16 SAVE_jtag_bb_afe_switch =
++		read_radio_reg(pi, RADIO_2064_REG007) & 1;
++	u16 SAVE_jtag_auxpga = read_radio_reg(pi, RADIO_2064_REG0FF) & 0x10;
++	u16 SAVE_iqadc_aux_en = read_radio_reg(pi, RADIO_2064_REG11F) & 4;
++	idleTssi = read_phy_reg(pi, 0x4ab);
++	suspend = (0 == (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) &
++			 MCTL_EN_MAC));
++	if (!suspend)
++		wlapi_suspend_mac_and_wait(pi->sh->physhim);
++	wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
++
++	tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi);
++	wlc_lcnphy_get_tx_gain(pi, &old_gains);
++
++	wlc_lcnphy_enable_tx_gain_override(pi);
++	wlc_lcnphy_set_tx_pwr_by_index(pi, 127);
++	write_radio_reg(pi, RADIO_2064_REG112, 0x6);
++	mod_radio_reg(pi, RADIO_2064_REG007, 0x1, 1);
++	mod_radio_reg(pi, RADIO_2064_REG0FF, 0x10, 1 << 4);
++	mod_radio_reg(pi, RADIO_2064_REG11F, 0x4, 1 << 2);
++	wlc_lcnphy_tssi_setup(pi);
++	wlc_phy_do_dummy_tx(pi, true, OFF);
++	idleTssi = ((read_phy_reg(pi, 0x4ab) & (0x1ff << 0))
++		    >> 0);
++
++	idleTssi0_2C = ((read_phy_reg(pi, 0x63e) & (0x1ff << 0))
++			>> 0);
++
++	if (idleTssi0_2C >= 256)
++		idleTssi0_OB = idleTssi0_2C - 256;
++	else
++		idleTssi0_OB = idleTssi0_2C + 256;
++
++	idleTssi0_regvalue_OB = idleTssi0_OB;
++	if (idleTssi0_regvalue_OB >= 256)
++		idleTssi0_regvalue_2C = idleTssi0_regvalue_OB - 256;
++	else
++		idleTssi0_regvalue_2C = idleTssi0_regvalue_OB + 256;
++	mod_phy_reg(pi, 0x4a6, (0x1ff << 0), (idleTssi0_regvalue_2C) << 0);
++
++	mod_phy_reg(pi, 0x44c, (0x1 << 12), (0) << 12);
++
++	wlc_lcnphy_set_tx_gain_override(pi, tx_gain_override_old);
++	wlc_lcnphy_set_tx_gain(pi, &old_gains);
++	wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_txpwrctrl);
++
++	write_radio_reg(pi, RADIO_2064_REG112, SAVE_lpfgain);
++	mod_radio_reg(pi, RADIO_2064_REG007, 0x1, SAVE_jtag_bb_afe_switch);
++	mod_radio_reg(pi, RADIO_2064_REG0FF, 0x10, SAVE_jtag_auxpga);
++	mod_radio_reg(pi, RADIO_2064_REG11F, 0x4, SAVE_iqadc_aux_en);
++	mod_radio_reg(pi, RADIO_2064_REG112, 0x80, 1 << 7);
++	if (!suspend)
++		wlapi_enable_mac(pi->sh->physhim);
++}
++
++static void wlc_lcnphy_vbat_temp_sense_setup(struct brcms_phy *pi, u8 mode)
++{
++	bool suspend;
++	u16 save_txpwrCtrlEn;
++	u8 auxpga_vmidcourse, auxpga_vmidfine, auxpga_gain;
++	u16 auxpga_vmid;
++	struct phytbl_info tab;
++	u32 val;
++	u8 save_reg007, save_reg0FF, save_reg11F, save_reg005, save_reg025,
++	   save_reg112;
++	u16 values_to_save[14];
++	s8 index;
++	int i;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++	udelay(999);
++
++	save_reg007 = (u8) read_radio_reg(pi, RADIO_2064_REG007);
++	save_reg0FF = (u8) read_radio_reg(pi, RADIO_2064_REG0FF);
++	save_reg11F = (u8) read_radio_reg(pi, RADIO_2064_REG11F);
++	save_reg005 = (u8) read_radio_reg(pi, RADIO_2064_REG005);
++	save_reg025 = (u8) read_radio_reg(pi, RADIO_2064_REG025);
++	save_reg112 = (u8) read_radio_reg(pi, RADIO_2064_REG112);
++
++	for (i = 0; i < 14; i++)
++		values_to_save[i] = read_phy_reg(pi, tempsense_phy_regs[i]);
++	suspend = (0 == (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) &
++			 MCTL_EN_MAC));
++	if (!suspend)
++		wlapi_suspend_mac_and_wait(pi->sh->physhim);
++	save_txpwrCtrlEn = read_radio_reg(pi, 0x4a4);
++
++	wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
++	index = pi_lcn->lcnphy_current_index;
++	wlc_lcnphy_set_tx_pwr_by_index(pi, 127);
++	mod_radio_reg(pi, RADIO_2064_REG007, 0x1, 0x1);
++	mod_radio_reg(pi, RADIO_2064_REG0FF, 0x10, 0x1 << 4);
++	mod_radio_reg(pi, RADIO_2064_REG11F, 0x4, 0x1 << 2);
++	mod_phy_reg(pi, 0x503, (0x1 << 0), (0) << 0);
++
++	mod_phy_reg(pi, 0x503, (0x1 << 2), (0) << 2);
++
++	mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0) << 14);
++
++	mod_phy_reg(pi, 0x4a4, (0x1 << 15), (0) << 15);
++
++	mod_phy_reg(pi, 0x4d0, (0x1 << 5), (0) << 5);
++
++	mod_phy_reg(pi, 0x4a5, (0xff << 0), (255) << 0);
++
++	mod_phy_reg(pi, 0x4a5, (0x7 << 12), (5) << 12);
++
++	mod_phy_reg(pi, 0x4a5, (0x7 << 8), (0) << 8);
++
++	mod_phy_reg(pi, 0x40d, (0xff << 0), (64) << 0);
++
++	mod_phy_reg(pi, 0x40d, (0x7 << 8), (6) << 8);
++
++	mod_phy_reg(pi, 0x4a2, (0xff << 0), (64) << 0);
++
++	mod_phy_reg(pi, 0x4a2, (0x7 << 8), (6) << 8);
++
++	mod_phy_reg(pi, 0x4d9, (0x7 << 4), (2) << 4);
++
++	mod_phy_reg(pi, 0x4d9, (0x7 << 8), (3) << 8);
++
++	mod_phy_reg(pi, 0x4d9, (0x7 << 12), (1) << 12);
++
++	mod_phy_reg(pi, 0x4da, (0x1 << 12), (0) << 12);
++
++	mod_phy_reg(pi, 0x4da, (0x1 << 13), (1) << 13);
++
++	mod_phy_reg(pi, 0x4a6, (0x1 << 15), (1) << 15);
++
++	write_radio_reg(pi, RADIO_2064_REG025, 0xC);
++
++	mod_radio_reg(pi, RADIO_2064_REG005, 0x8, 0x1 << 3);
++
++	mod_phy_reg(pi, 0x938, (0x1 << 2), (1) << 2);
++
++	mod_phy_reg(pi, 0x939, (0x1 << 2), (1) << 2);
++
++	mod_phy_reg(pi, 0x4a4, (0x1 << 12), (1) << 12);
++
++	val = wlc_lcnphy_rfseq_tbl_adc_pwrup(pi);
++	tab.tbl_id = LCNPHY_TBL_ID_RFSEQ;
++	tab.tbl_width = 16;
++	tab.tbl_len = 1;
++	tab.tbl_ptr = &val;
++	tab.tbl_offset = 6;
++	wlc_lcnphy_write_table(pi, &tab);
++	if (mode == TEMPSENSE) {
++		mod_phy_reg(pi, 0x4d7, (0x1 << 3), (1) << 3);
++
++		mod_phy_reg(pi, 0x4d7, (0x7 << 12), (1) << 12);
++
++		auxpga_vmidcourse = 8;
++		auxpga_vmidfine = 0x4;
++		auxpga_gain = 2;
++		mod_radio_reg(pi, RADIO_2064_REG082, 0x20, 1 << 5);
++	} else {
++		mod_phy_reg(pi, 0x4d7, (0x1 << 3), (1) << 3);
++
++		mod_phy_reg(pi, 0x4d7, (0x7 << 12), (3) << 12);
++
++		auxpga_vmidcourse = 7;
++		auxpga_vmidfine = 0xa;
++		auxpga_gain = 2;
++	}
++	auxpga_vmid =
++		(u16) ((2 << 8) | (auxpga_vmidcourse << 4) | auxpga_vmidfine);
++	mod_phy_reg(pi, 0x4d8, (0x1 << 0), (1) << 0);
++
++	mod_phy_reg(pi, 0x4d8, (0x3ff << 2), (auxpga_vmid) << 2);
++
++	mod_phy_reg(pi, 0x4d8, (0x1 << 1), (1) << 1);
++
++	mod_phy_reg(pi, 0x4d8, (0x7 << 12), (auxpga_gain) << 12);
++
++	mod_phy_reg(pi, 0x4d0, (0x1 << 5), (1) << 5);
++
++	write_radio_reg(pi, RADIO_2064_REG112, 0x6);
++
++	wlc_phy_do_dummy_tx(pi, true, OFF);
++	if (!tempsense_done(pi))
++		udelay(10);
++
++	write_radio_reg(pi, RADIO_2064_REG007, (u16) save_reg007);
++	write_radio_reg(pi, RADIO_2064_REG0FF, (u16) save_reg0FF);
++	write_radio_reg(pi, RADIO_2064_REG11F, (u16) save_reg11F);
++	write_radio_reg(pi, RADIO_2064_REG005, (u16) save_reg005);
++	write_radio_reg(pi, RADIO_2064_REG025, (u16) save_reg025);
++	write_radio_reg(pi, RADIO_2064_REG112, (u16) save_reg112);
++	for (i = 0; i < 14; i++)
++		write_phy_reg(pi, tempsense_phy_regs[i], values_to_save[i]);
++	wlc_lcnphy_set_tx_pwr_by_index(pi, (int)index);
++
++	write_radio_reg(pi, 0x4a4, save_txpwrCtrlEn);
++	if (!suspend)
++		wlapi_enable_mac(pi->sh->physhim);
++	udelay(999);
++}
++
++static void wlc_lcnphy_tx_pwr_ctrl_init(struct brcms_phy_pub *ppi)
++{
++	struct lcnphy_txgains tx_gains;
++	u8 bbmult;
++	struct phytbl_info tab;
++	s32 a1, b0, b1;
++	s32 tssi, pwr, maxtargetpwr, mintargetpwr;
++	bool suspend;
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++
++	suspend = (0 == (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) &
++			 MCTL_EN_MAC));
++	if (!suspend)
++		wlapi_suspend_mac_and_wait(pi->sh->physhim);
++
++	if (!pi->hwpwrctrl_capable) {
++		if (CHSPEC_IS2G(pi->radio_chanspec)) {
++			tx_gains.gm_gain = 4;
++			tx_gains.pga_gain = 12;
++			tx_gains.pad_gain = 12;
++			tx_gains.dac_gain = 0;
++
++			bbmult = 150;
++		} else {
++			tx_gains.gm_gain = 7;
++			tx_gains.pga_gain = 15;
++			tx_gains.pad_gain = 14;
++			tx_gains.dac_gain = 0;
++
++			bbmult = 150;
++		}
++		wlc_lcnphy_set_tx_gain(pi, &tx_gains);
++		wlc_lcnphy_set_bbmult(pi, bbmult);
++		wlc_lcnphy_vbat_temp_sense_setup(pi, TEMPSENSE);
++	} else {
++
++		wlc_lcnphy_idle_tssi_est(ppi);
++
++		wlc_lcnphy_clear_tx_power_offsets(pi);
++
++		b0 = pi->txpa_2g[0];
++		b1 = pi->txpa_2g[1];
++		a1 = pi->txpa_2g[2];
++		maxtargetpwr = wlc_lcnphy_tssi2dbm(10, a1, b0, b1);
++		mintargetpwr = wlc_lcnphy_tssi2dbm(125, a1, b0, b1);
++
++		tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
++		tab.tbl_width = 32;
++		tab.tbl_ptr = &pwr;
++		tab.tbl_len = 1;
++		tab.tbl_offset = 0;
++		for (tssi = 0; tssi < 128; tssi++) {
++			pwr = wlc_lcnphy_tssi2dbm(tssi, a1, b0, b1);
++
++			pwr = (pwr < mintargetpwr) ? mintargetpwr : pwr;
++			wlc_lcnphy_write_table(pi, &tab);
++			tab.tbl_offset++;
++		}
++
++		mod_phy_reg(pi, 0x410, (0x1 << 7), (0) << 7);
++
++		write_phy_reg(pi, 0x4a8, 10);
++
++		wlc_lcnphy_set_target_tx_pwr(pi, LCN_TARGET_PWR);
++
++		wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_HW);
++	}
++	if (!suspend)
++		wlapi_enable_mac(pi->sh->physhim);
++}
++
++static u8 wlc_lcnphy_get_bbmult(struct brcms_phy *pi)
++{
++	u16 m0m1;
++	struct phytbl_info tab;
++
++	tab.tbl_ptr = &m0m1;
++	tab.tbl_len = 1;
++	tab.tbl_id = LCNPHY_TBL_ID_IQLOCAL;
++	tab.tbl_offset = 87;
++	tab.tbl_width = 16;
++	wlc_lcnphy_read_table(pi, &tab);
++
++	return (u8) ((m0m1 & 0xff00) >> 8);
++}
++
++static void wlc_lcnphy_set_pa_gain(struct brcms_phy *pi, u16 gain)
++{
++	mod_phy_reg(pi, 0x4fb,
++		    LCNPHY_txgainctrlovrval1_pagain_ovr_val1_MASK,
++		    gain << LCNPHY_txgainctrlovrval1_pagain_ovr_val1_SHIFT);
++	mod_phy_reg(pi, 0x4fd,
++		    LCNPHY_stxtxgainctrlovrval1_pagain_ovr_val1_MASK,
++		    gain << LCNPHY_stxtxgainctrlovrval1_pagain_ovr_val1_SHIFT);
++}
++
++void
++wlc_lcnphy_get_radio_loft(struct brcms_phy *pi,
++			  u8 *ei0, u8 *eq0, u8 *fi0, u8 *fq0)
++{
++	*ei0 = LCNPHY_IQLOCC_READ(read_radio_reg(pi, RADIO_2064_REG089));
++	*eq0 = LCNPHY_IQLOCC_READ(read_radio_reg(pi, RADIO_2064_REG08A));
++	*fi0 = LCNPHY_IQLOCC_READ(read_radio_reg(pi, RADIO_2064_REG08B));
++	*fq0 = LCNPHY_IQLOCC_READ(read_radio_reg(pi, RADIO_2064_REG08C));
++}
++
++void wlc_lcnphy_set_tx_iqcc(struct brcms_phy *pi, u16 a, u16 b)
++{
++	struct phytbl_info tab;
++	u16 iqcc[2];
++
++	iqcc[0] = a;
++	iqcc[1] = b;
++
++	tab.tbl_id = LCNPHY_TBL_ID_IQLOCAL;
++	tab.tbl_width = 16;
++	tab.tbl_ptr = iqcc;
++	tab.tbl_len = 2;
++	tab.tbl_offset = 80;
++	wlc_lcnphy_write_table(pi, &tab);
++}
++
++void wlc_lcnphy_set_tx_locc(struct brcms_phy *pi, u16 didq)
++{
++	struct phytbl_info tab;
++
++	tab.tbl_id = LCNPHY_TBL_ID_IQLOCAL;
++	tab.tbl_width = 16;
++	tab.tbl_ptr = &didq;
++	tab.tbl_len = 1;
++	tab.tbl_offset = 85;
++	wlc_lcnphy_write_table(pi, &tab);
++}
++
++void wlc_lcnphy_set_tx_pwr_by_index(struct brcms_phy *pi, int index)
++{
++	struct phytbl_info tab;
++	u16 a, b;
++	u8 bb_mult;
++	u32 bbmultiqcomp, txgain, locoeffs, rfpower;
++	struct lcnphy_txgains gains;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	pi_lcn->lcnphy_tx_power_idx_override = (s8) index;
++	pi_lcn->lcnphy_current_index = (u8) index;
++
++	tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
++	tab.tbl_width = 32;
++	tab.tbl_len = 1;
++
++	wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
++
++	tab.tbl_offset = LCNPHY_TX_PWR_CTRL_IQ_OFFSET + index;
++	tab.tbl_ptr = &bbmultiqcomp;
++	wlc_lcnphy_read_table(pi, &tab);
++
++	tab.tbl_offset = LCNPHY_TX_PWR_CTRL_GAIN_OFFSET + index;
++	tab.tbl_width = 32;
++	tab.tbl_ptr = &txgain;
++	wlc_lcnphy_read_table(pi, &tab);
++
++	gains.gm_gain = (u16) (txgain & 0xff);
++	gains.pga_gain = (u16) (txgain >> 8) & 0xff;
++	gains.pad_gain = (u16) (txgain >> 16) & 0xff;
++	gains.dac_gain = (u16) (bbmultiqcomp >> 28) & 0x07;
++	wlc_lcnphy_set_tx_gain(pi, &gains);
++	wlc_lcnphy_set_pa_gain(pi, (u16) (txgain >> 24) & 0x7f);
++
++	bb_mult = (u8) ((bbmultiqcomp >> 20) & 0xff);
++	wlc_lcnphy_set_bbmult(pi, bb_mult);
++
++	wlc_lcnphy_enable_tx_gain_override(pi);
++
++	if (!wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) {
++
++		a = (u16) ((bbmultiqcomp >> 10) & 0x3ff);
++		b = (u16) (bbmultiqcomp & 0x3ff);
++		wlc_lcnphy_set_tx_iqcc(pi, a, b);
++
++		tab.tbl_offset = LCNPHY_TX_PWR_CTRL_LO_OFFSET + index;
++		tab.tbl_ptr = &locoeffs;
++		wlc_lcnphy_read_table(pi, &tab);
++
++		wlc_lcnphy_set_tx_locc(pi, (u16) locoeffs);
++
++		tab.tbl_offset = LCNPHY_TX_PWR_CTRL_PWR_OFFSET + index;
++		tab.tbl_ptr = &rfpower;
++		wlc_lcnphy_read_table(pi, &tab);
++		mod_phy_reg(pi, 0x6a6, (0x1fff << 0), (rfpower * 8) << 0);
++
++	}
++}
++
++static void wlc_lcnphy_clear_papd_comptable(struct brcms_phy *pi)
++{
++	u32 j;
++	struct phytbl_info tab;
++	u32 temp_offset[128];
++	tab.tbl_ptr = temp_offset;
++	tab.tbl_len = 128;
++	tab.tbl_id = LCNPHY_TBL_ID_PAPDCOMPDELTATBL;
++	tab.tbl_width = 32;
++	tab.tbl_offset = 0;
++
++	memset(temp_offset, 0, sizeof(temp_offset));
++	for (j = 1; j < 128; j += 2)
++		temp_offset[j] = 0x80000;
++
++	wlc_lcnphy_write_table(pi, &tab);
++	return;
++}
++
++void wlc_lcnphy_tx_pu(struct brcms_phy *pi, bool bEnable)
++{
++	if (!bEnable) {
++
++		and_phy_reg(pi, 0x43b, ~(u16) ((0x1 << 1) | (0x1 << 4)));
++
++		mod_phy_reg(pi, 0x43c, (0x1 << 1), 1 << 1);
++
++		and_phy_reg(pi, 0x44c,
++			    ~(u16) ((0x1 << 3) |
++				    (0x1 << 5) |
++				    (0x1 << 12) |
++				    (0x1 << 0) | (0x1 << 1) | (0x1 << 2)));
++
++		and_phy_reg(pi, 0x44d,
++			    ~(u16) ((0x1 << 3) | (0x1 << 5) | (0x1 << 14)));
++		mod_phy_reg(pi, 0x44d, (0x1 << 2), 1 << 2);
++
++		mod_phy_reg(pi, 0x44d, (0x1 << 1) | (0x1 << 0), (0x1 << 0));
++
++		and_phy_reg(pi, 0x4f9,
++			    ~(u16) ((0x1 << 0) | (0x1 << 1) | (0x1 << 2)));
++
++		and_phy_reg(pi, 0x4fa,
++			    ~(u16) ((0x1 << 0) | (0x1 << 1) | (0x1 << 2)));
++	} else {
++
++		mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1);
++		mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1);
++
++		mod_phy_reg(pi, 0x43b, (0x1 << 4), 1 << 4);
++		mod_phy_reg(pi, 0x43c, (0x1 << 6), 0 << 6);
++
++		mod_phy_reg(pi, 0x44c, (0x1 << 12), 1 << 12);
++		mod_phy_reg(pi, 0x44d, (0x1 << 14), 1 << 14);
++
++		wlc_lcnphy_set_trsw_override(pi, true, false);
++
++		mod_phy_reg(pi, 0x44d, (0x1 << 2), 0 << 2);
++		mod_phy_reg(pi, 0x44c, (0x1 << 2), 1 << 2);
++
++		if (CHSPEC_IS2G(pi->radio_chanspec)) {
++
++			mod_phy_reg(pi, 0x44c, (0x1 << 3), 1 << 3);
++			mod_phy_reg(pi, 0x44d, (0x1 << 3), 1 << 3);
++
++			mod_phy_reg(pi, 0x44c, (0x1 << 5), 1 << 5);
++			mod_phy_reg(pi, 0x44d, (0x1 << 5), 0 << 5);
++
++			mod_phy_reg(pi, 0x4f9, (0x1 << 1), 1 << 1);
++			mod_phy_reg(pi, 0x4fa, (0x1 << 1), 1 << 1);
++
++			mod_phy_reg(pi, 0x4f9, (0x1 << 2), 1 << 2);
++			mod_phy_reg(pi, 0x4fa, (0x1 << 2), 1 << 2);
++
++			mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0);
++			mod_phy_reg(pi, 0x4fa, (0x1 << 0), 1 << 0);
++		} else {
++
++			mod_phy_reg(pi, 0x44c, (0x1 << 3), 1 << 3);
++			mod_phy_reg(pi, 0x44d, (0x1 << 3), 0 << 3);
++
++			mod_phy_reg(pi, 0x44c, (0x1 << 5), 1 << 5);
++			mod_phy_reg(pi, 0x44d, (0x1 << 5), 1 << 5);
++
++			mod_phy_reg(pi, 0x4f9, (0x1 << 1), 1 << 1);
++			mod_phy_reg(pi, 0x4fa, (0x1 << 1), 0 << 1);
++
++			mod_phy_reg(pi, 0x4f9, (0x1 << 2), 1 << 2);
++			mod_phy_reg(pi, 0x4fa, (0x1 << 2), 0 << 2);
++
++			mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0);
++			mod_phy_reg(pi, 0x4fa, (0x1 << 0), 0 << 0);
++		}
++	}
++}
++
++static void
++wlc_lcnphy_run_samples(struct brcms_phy *pi,
++		       u16 num_samps,
++		       u16 num_loops, u16 wait, bool iqcalmode)
++{
++
++	or_phy_reg(pi, 0x6da, 0x8080);
++
++	mod_phy_reg(pi, 0x642, (0x7f << 0), (num_samps - 1) << 0);
++	if (num_loops != 0xffff)
++		num_loops--;
++	mod_phy_reg(pi, 0x640, (0xffff << 0), num_loops << 0);
++
++	mod_phy_reg(pi, 0x641, (0xffff << 0), wait << 0);
++
++	if (iqcalmode) {
++
++		and_phy_reg(pi, 0x453, (u16) ~(0x1 << 15));
++		or_phy_reg(pi, 0x453, (0x1 << 15));
++	} else {
++		write_phy_reg(pi, 0x63f, 1);
++		wlc_lcnphy_tx_pu(pi, 1);
++	}
++
++	or_radio_reg(pi, RADIO_2064_REG112, 0x6);
++}
++
++void wlc_lcnphy_deaf_mode(struct brcms_phy *pi, bool mode)
++{
++
++	u8 phybw40;
++	phybw40 = CHSPEC_IS40(pi->radio_chanspec);
++
++	if (LCNREV_LT(pi->pubpi.phy_rev, 2)) {
++		mod_phy_reg(pi, 0x4b0, (0x1 << 5), (mode) << 5);
++		mod_phy_reg(pi, 0x4b1, (0x1 << 9), 0 << 9);
++	} else {
++		mod_phy_reg(pi, 0x4b0, (0x1 << 5), (mode) << 5);
++		mod_phy_reg(pi, 0x4b1, (0x1 << 9), 0 << 9);
++	}
++
++	if (phybw40 == 0) {
++		mod_phy_reg((pi), 0x410,
++			    (0x1 << 6) |
++			    (0x1 << 5),
++			    ((CHSPEC_IS2G(
++				      pi->radio_chanspec)) ? (!mode) : 0) <<
++			    6 | (!mode) << 5);
++		mod_phy_reg(pi, 0x410, (0x1 << 7), (mode) << 7);
++	}
++}
++
++void
++wlc_lcnphy_start_tx_tone(struct brcms_phy *pi, s32 f_kHz, u16 max_val,
++			 bool iqcalmode)
++{
++	u8 phy_bw;
++	u16 num_samps, t, k;
++	u32 bw;
++	s32 theta = 0, rot = 0;
++	struct cordic_iq tone_samp;
++	u32 data_buf[64];
++	u16 i_samp, q_samp;
++	struct phytbl_info tab;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	pi->phy_tx_tone_freq = f_kHz;
++
++	wlc_lcnphy_deaf_mode(pi, true);
++
++	phy_bw = 40;
++	if (pi_lcn->lcnphy_spurmod) {
++		write_phy_reg(pi, 0x942, 0x2);
++		write_phy_reg(pi, 0x93b, 0x0);
++		write_phy_reg(pi, 0x93c, 0x0);
++		wlc_lcnphy_txrx_spur_avoidance_mode(pi, false);
++	}
++
++	if (f_kHz) {
++		k = 1;
++		do {
++			bw = phy_bw * 1000 * k;
++			num_samps = bw / abs(f_kHz);
++			k++;
++		} while ((num_samps * (u32) (abs(f_kHz))) != bw);
++	} else
++		num_samps = 2;
++
++	rot = ((f_kHz * 36) / phy_bw) / 100;
++	theta = 0;
++
++	for (t = 0; t < num_samps; t++) {
++
++		tone_samp = cordic_calc_iq(theta);
++
++		theta += rot;
++
++		i_samp = (u16) (FLOAT(tone_samp.i * max_val) & 0x3ff);
++		q_samp = (u16) (FLOAT(tone_samp.q * max_val) & 0x3ff);
++		data_buf[t] = (i_samp << 10) | q_samp;
++	}
++
++	mod_phy_reg(pi, 0x6d6, (0x3 << 0), 0 << 0);
++
++	mod_phy_reg(pi, 0x6da, (0x1 << 3), 1 << 3);
++
++	tab.tbl_ptr = data_buf;
++	tab.tbl_len = num_samps;
++	tab.tbl_id = LCNPHY_TBL_ID_SAMPLEPLAY;
++	tab.tbl_offset = 0;
++	tab.tbl_width = 32;
++	wlc_lcnphy_write_table(pi, &tab);
++
++	wlc_lcnphy_run_samples(pi, num_samps, 0xffff, 0, iqcalmode);
++}
++
++void wlc_lcnphy_stop_tx_tone(struct brcms_phy *pi)
++{
++	s16 playback_status;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	pi->phy_tx_tone_freq = 0;
++	if (pi_lcn->lcnphy_spurmod) {
++		write_phy_reg(pi, 0x942, 0x7);
++		write_phy_reg(pi, 0x93b, 0x2017);
++		write_phy_reg(pi, 0x93c, 0x27c5);
++		wlc_lcnphy_txrx_spur_avoidance_mode(pi, true);
++	}
++
++	playback_status = read_phy_reg(pi, 0x644);
++	if (playback_status & (0x1 << 0)) {
++		wlc_lcnphy_tx_pu(pi, 0);
++		mod_phy_reg(pi, 0x63f, (0x1 << 1), 1 << 1);
++	} else if (playback_status & (0x1 << 1))
++		mod_phy_reg(pi, 0x453, (0x1 << 15), 0 << 15);
++
++	mod_phy_reg(pi, 0x6d6, (0x3 << 0), 1 << 0);
++
++	mod_phy_reg(pi, 0x6da, (0x1 << 3), 0 << 3);
++
++	mod_phy_reg(pi, 0x6da, (0x1 << 7), 0 << 7);
++
++	and_radio_reg(pi, RADIO_2064_REG112, 0xFFF9);
++
++	wlc_lcnphy_deaf_mode(pi, false);
++}
++
++static void
++wlc_lcnphy_set_cc(struct brcms_phy *pi, int cal_type, s16 coeff_x, s16 coeff_y)
++{
++	u16 di0dq0;
++	u16 x, y, data_rf;
++	int k;
++	switch (cal_type) {
++	case 0:
++		wlc_lcnphy_set_tx_iqcc(pi, coeff_x, coeff_y);
++		break;
++	case 2:
++		di0dq0 = (coeff_x & 0xff) << 8 | (coeff_y & 0xff);
++		wlc_lcnphy_set_tx_locc(pi, di0dq0);
++		break;
++	case 3:
++		k = wlc_lcnphy_calc_floor(coeff_x, 0);
++		y = 8 + k;
++		k = wlc_lcnphy_calc_floor(coeff_x, 1);
++		x = 8 - k;
++		data_rf = (x * 16 + y);
++		write_radio_reg(pi, RADIO_2064_REG089, data_rf);
++		k = wlc_lcnphy_calc_floor(coeff_y, 0);
++		y = 8 + k;
++		k = wlc_lcnphy_calc_floor(coeff_y, 1);
++		x = 8 - k;
++		data_rf = (x * 16 + y);
++		write_radio_reg(pi, RADIO_2064_REG08A, data_rf);
++		break;
++	case 4:
++		k = wlc_lcnphy_calc_floor(coeff_x, 0);
++		y = 8 + k;
++		k = wlc_lcnphy_calc_floor(coeff_x, 1);
++		x = 8 - k;
++		data_rf = (x * 16 + y);
++		write_radio_reg(pi, RADIO_2064_REG08B, data_rf);
++		k = wlc_lcnphy_calc_floor(coeff_y, 0);
++		y = 8 + k;
++		k = wlc_lcnphy_calc_floor(coeff_y, 1);
++		x = 8 - k;
++		data_rf = (x * 16 + y);
++		write_radio_reg(pi, RADIO_2064_REG08C, data_rf);
++		break;
++	}
++}
++
++static struct lcnphy_unsign16_struct
++wlc_lcnphy_get_cc(struct brcms_phy *pi, int cal_type)
++{
++	u16 a, b, didq;
++	u8 di0, dq0, ei, eq, fi, fq;
++	struct lcnphy_unsign16_struct cc;
++	cc.re = 0;
++	cc.im = 0;
++	switch (cal_type) {
++	case 0:
++		wlc_lcnphy_get_tx_iqcc(pi, &a, &b);
++		cc.re = a;
++		cc.im = b;
++		break;
++	case 2:
++		didq = wlc_lcnphy_get_tx_locc(pi);
++		di0 = (((didq & 0xff00) << 16) >> 24);
++		dq0 = (((didq & 0x00ff) << 24) >> 24);
++		cc.re = (u16) di0;
++		cc.im = (u16) dq0;
++		break;
++	case 3:
++		wlc_lcnphy_get_radio_loft(pi, &ei, &eq, &fi, &fq);
++		cc.re = (u16) ei;
++		cc.im = (u16) eq;
++		break;
++	case 4:
++		wlc_lcnphy_get_radio_loft(pi, &ei, &eq, &fi, &fq);
++		cc.re = (u16) fi;
++		cc.im = (u16) fq;
++		break;
++	}
++	return cc;
++}
++
++static void
++wlc_lcnphy_samp_cap(struct brcms_phy *pi, int clip_detect_algo, u16 thresh,
++		    s16 *ptr, int mode)
++{
++	u32 curval1, curval2, stpptr, curptr, strptr, val;
++	u16 sslpnCalibClkEnCtrl, timer;
++	u16 old_sslpnCalibClkEnCtrl;
++	s16 imag, real;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	timer = 0;
++	old_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da);
++
++	curval1 = bcma_read16(pi->d11core, D11REGOFFS(psm_corectlsts));
++	ptr[130] = 0;
++	bcma_write16(pi->d11core, D11REGOFFS(psm_corectlsts),
++		     ((1 << 6) | curval1));
++
++	bcma_write16(pi->d11core, D11REGOFFS(smpl_clct_strptr), 0x7E00);
++	bcma_write16(pi->d11core, D11REGOFFS(smpl_clct_stpptr), 0x8000);
++	udelay(20);
++	curval2 = bcma_read16(pi->d11core, D11REGOFFS(psm_phy_hdr_param));
++	bcma_write16(pi->d11core, D11REGOFFS(psm_phy_hdr_param),
++		     curval2 | 0x30);
++
++	write_phy_reg(pi, 0x555, 0x0);
++	write_phy_reg(pi, 0x5a6, 0x5);
++
++	write_phy_reg(pi, 0x5a2, (u16) (mode | mode << 6));
++	write_phy_reg(pi, 0x5cf, 3);
++	write_phy_reg(pi, 0x5a5, 0x3);
++	write_phy_reg(pi, 0x583, 0x0);
++	write_phy_reg(pi, 0x584, 0x0);
++	write_phy_reg(pi, 0x585, 0x0fff);
++	write_phy_reg(pi, 0x586, 0x0000);
++
++	write_phy_reg(pi, 0x580, 0x4501);
++
++	sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da);
++	write_phy_reg(pi, 0x6da, (u32) (sslpnCalibClkEnCtrl | 0x2008));
++	stpptr = bcma_read16(pi->d11core, D11REGOFFS(smpl_clct_stpptr));
++	curptr = bcma_read16(pi->d11core, D11REGOFFS(smpl_clct_curptr));
++	do {
++		udelay(10);
++		curptr = bcma_read16(pi->d11core, D11REGOFFS(smpl_clct_curptr));
++		timer++;
++	} while ((curptr != stpptr) && (timer < 500));
++
++	bcma_write16(pi->d11core, D11REGOFFS(psm_phy_hdr_param), 0x2);
++	strptr = 0x7E00;
++	bcma_write32(pi->d11core, D11REGOFFS(tplatewrptr), strptr);
++	while (strptr < 0x8000) {
++		val = bcma_read32(pi->d11core, D11REGOFFS(tplatewrdata));
++		imag = ((val >> 16) & 0x3ff);
++		real = ((val) & 0x3ff);
++		if (imag > 511)
++			imag -= 1024;
++
++		if (real > 511)
++			real -= 1024;
++
++		if (pi_lcn->lcnphy_iqcal_swp_dis)
++			ptr[(strptr - 0x7E00) / 4] = real;
++		else
++			ptr[(strptr - 0x7E00) / 4] = imag;
++
++		if (clip_detect_algo) {
++			if (imag > thresh || imag < -thresh) {
++				strptr = 0x8000;
++				ptr[130] = 1;
++			}
++		}
++
++		strptr += 4;
++	}
++
++	write_phy_reg(pi, 0x6da, old_sslpnCalibClkEnCtrl);
++	bcma_write16(pi->d11core, D11REGOFFS(psm_phy_hdr_param), curval2);
++	bcma_write16(pi->d11core, D11REGOFFS(psm_corectlsts), curval1);
++}
++
++static void
++wlc_lcnphy_a1(struct brcms_phy *pi, int cal_type, int num_levels,
++	      int step_size_lg2)
++{
++	const struct lcnphy_spb_tone *phy_c1;
++	struct lcnphy_spb_tone phy_c2;
++	struct lcnphy_unsign16_struct phy_c3;
++	int phy_c4, phy_c5, k, l, j, phy_c6;
++	u16 phy_c7, phy_c8, phy_c9;
++	s16 phy_c10, phy_c11, phy_c12, phy_c13, phy_c14, phy_c15, phy_c16;
++	s16 *ptr, phy_c17;
++	s32 phy_c18, phy_c19;
++	u32 phy_c20, phy_c21;
++	bool phy_c22, phy_c23, phy_c24, phy_c25;
++	u16 phy_c26, phy_c27;
++	u16 phy_c28, phy_c29, phy_c30;
++	u16 phy_c31;
++	u16 *phy_c32;
++	phy_c21 = 0;
++	phy_c10 = phy_c13 = phy_c14 = phy_c8 = 0;
++	ptr = kmalloc(sizeof(s16) * 131, GFP_ATOMIC);
++	if (NULL == ptr)
++		return;
++
++	phy_c32 = kmalloc(sizeof(u16) * 20, GFP_ATOMIC);
++	if (NULL == phy_c32) {
++		kfree(ptr);
++		return;
++	}
++	phy_c26 = read_phy_reg(pi, 0x6da);
++	phy_c27 = read_phy_reg(pi, 0x6db);
++	phy_c31 = read_radio_reg(pi, RADIO_2064_REG026);
++	write_phy_reg(pi, 0x93d, 0xC0);
++
++	wlc_lcnphy_start_tx_tone(pi, 3750, 88, 0);
++	write_phy_reg(pi, 0x6da, 0xffff);
++	or_phy_reg(pi, 0x6db, 0x3);
++
++	wlc_lcnphy_tx_iqlo_loopback(pi, phy_c32);
++	udelay(500);
++	phy_c28 = read_phy_reg(pi, 0x938);
++	phy_c29 = read_phy_reg(pi, 0x4d7);
++	phy_c30 = read_phy_reg(pi, 0x4d8);
++	or_phy_reg(pi, 0x938, 0x1 << 2);
++	or_phy_reg(pi, 0x4d7, 0x1 << 2);
++	or_phy_reg(pi, 0x4d7, 0x1 << 3);
++	mod_phy_reg(pi, 0x4d7, (0x7 << 12), 0x2 << 12);
++	or_phy_reg(pi, 0x4d8, 1 << 0);
++	or_phy_reg(pi, 0x4d8, 1 << 1);
++	mod_phy_reg(pi, 0x4d8, (0x3ff << 2), 0x23A << 2);
++	mod_phy_reg(pi, 0x4d8, (0x7 << 12), 0x7 << 12);
++	phy_c1 = &lcnphy_spb_tone_3750[0];
++	phy_c4 = 32;
++
++	if (num_levels == 0) {
++		if (cal_type != 0)
++			num_levels = 4;
++		else
++			num_levels = 9;
++	}
++	if (step_size_lg2 == 0) {
++		if (cal_type != 0)
++			step_size_lg2 = 3;
++		else
++			step_size_lg2 = 8;
++	}
++
++	phy_c7 = (1 << step_size_lg2);
++	phy_c3 = wlc_lcnphy_get_cc(pi, cal_type);
++	phy_c15 = (s16) phy_c3.re;
++	phy_c16 = (s16) phy_c3.im;
++	if (cal_type == 2) {
++		if (phy_c3.re > 127)
++			phy_c15 = phy_c3.re - 256;
++		if (phy_c3.im > 127)
++			phy_c16 = phy_c3.im - 256;
++	}
++	wlc_lcnphy_set_cc(pi, cal_type, phy_c15, phy_c16);
++	udelay(20);
++	for (phy_c8 = 0; phy_c7 != 0 && phy_c8 < num_levels; phy_c8++) {
++		phy_c23 = true;
++		phy_c22 = false;
++		switch (cal_type) {
++		case 0:
++			phy_c10 = 511;
++			break;
++		case 2:
++			phy_c10 = 127;
++			break;
++		case 3:
++			phy_c10 = 15;
++			break;
++		case 4:
++			phy_c10 = 15;
++			break;
++		}
++
++		phy_c9 = read_phy_reg(pi, 0x93d);
++		phy_c9 = 2 * phy_c9;
++		phy_c24 = false;
++		phy_c5 = 7;
++		phy_c25 = true;
++		while (1) {
++			write_radio_reg(pi, RADIO_2064_REG026,
++					(phy_c5 & 0x7) | ((phy_c5 & 0x7) << 4));
++			udelay(50);
++			phy_c22 = false;
++			ptr[130] = 0;
++			wlc_lcnphy_samp_cap(pi, 1, phy_c9, &ptr[0], 2);
++			if (ptr[130] == 1)
++				phy_c22 = true;
++			if (phy_c22)
++				phy_c5 -= 1;
++			if ((phy_c22 != phy_c24) && (!phy_c25))
++				break;
++			if (!phy_c22)
++				phy_c5 += 1;
++			if (phy_c5 <= 0 || phy_c5 >= 7)
++				break;
++			phy_c24 = phy_c22;
++			phy_c25 = false;
++		}
++
++		if (phy_c5 < 0)
++			phy_c5 = 0;
++		else if (phy_c5 > 7)
++			phy_c5 = 7;
++
++		for (k = -phy_c7; k <= phy_c7; k += phy_c7) {
++			for (l = -phy_c7; l <= phy_c7; l += phy_c7) {
++				phy_c11 = phy_c15 + k;
++				phy_c12 = phy_c16 + l;
++
++				if (phy_c11 < -phy_c10)
++					phy_c11 = -phy_c10;
++				else if (phy_c11 > phy_c10)
++					phy_c11 = phy_c10;
++				if (phy_c12 < -phy_c10)
++					phy_c12 = -phy_c10;
++				else if (phy_c12 > phy_c10)
++					phy_c12 = phy_c10;
++				wlc_lcnphy_set_cc(pi, cal_type, phy_c11,
++						  phy_c12);
++				udelay(20);
++				wlc_lcnphy_samp_cap(pi, 0, 0, ptr, 2);
++
++				phy_c18 = 0;
++				phy_c19 = 0;
++				for (j = 0; j < 128; j++) {
++					if (cal_type != 0)
++						phy_c6 = j % phy_c4;
++					else
++						phy_c6 = (2 * j) % phy_c4;
++
++					phy_c2.re = phy_c1[phy_c6].re;
++					phy_c2.im = phy_c1[phy_c6].im;
++					phy_c17 = ptr[j];
++					phy_c18 = phy_c18 + phy_c17 * phy_c2.re;
++					phy_c19 = phy_c19 + phy_c17 * phy_c2.im;
++				}
++
++				phy_c18 = phy_c18 >> 10;
++				phy_c19 = phy_c19 >> 10;
++				phy_c20 = ((phy_c18 * phy_c18) +
++					   (phy_c19 * phy_c19));
++
++				if (phy_c23 || phy_c20 < phy_c21) {
++					phy_c21 = phy_c20;
++					phy_c13 = phy_c11;
++					phy_c14 = phy_c12;
++				}
++				phy_c23 = false;
++			}
++		}
++		phy_c23 = true;
++		phy_c15 = phy_c13;
++		phy_c16 = phy_c14;
++		phy_c7 = phy_c7 >> 1;
++		wlc_lcnphy_set_cc(pi, cal_type, phy_c15, phy_c16);
++		udelay(20);
++	}
++	goto cleanup;
++cleanup:
++	wlc_lcnphy_tx_iqlo_loopback_cleanup(pi, phy_c32);
++	wlc_lcnphy_stop_tx_tone(pi);
++	write_phy_reg(pi, 0x6da, phy_c26);
++	write_phy_reg(pi, 0x6db, phy_c27);
++	write_phy_reg(pi, 0x938, phy_c28);
++	write_phy_reg(pi, 0x4d7, phy_c29);
++	write_phy_reg(pi, 0x4d8, phy_c30);
++	write_radio_reg(pi, RADIO_2064_REG026, phy_c31);
++
++	kfree(phy_c32);
++	kfree(ptr);
++}
++
++void wlc_lcnphy_get_tx_iqcc(struct brcms_phy *pi, u16 *a, u16 *b)
++{
++	u16 iqcc[2];
++	struct phytbl_info tab;
++
++	tab.tbl_ptr = iqcc;
++	tab.tbl_len = 2;
++	tab.tbl_id = 0;
++	tab.tbl_offset = 80;
++	tab.tbl_width = 16;
++	wlc_lcnphy_read_table(pi, &tab);
++
++	*a = iqcc[0];
++	*b = iqcc[1];
++}
++
++static void wlc_lcnphy_tx_iqlo_soft_cal_full(struct brcms_phy *pi)
++{
++	struct lcnphy_unsign16_struct iqcc0, locc2, locc3, locc4;
++
++	wlc_lcnphy_set_cc(pi, 0, 0, 0);
++	wlc_lcnphy_set_cc(pi, 2, 0, 0);
++	wlc_lcnphy_set_cc(pi, 3, 0, 0);
++	wlc_lcnphy_set_cc(pi, 4, 0, 0);
++
++	wlc_lcnphy_a1(pi, 4, 0, 0);
++	wlc_lcnphy_a1(pi, 3, 0, 0);
++	wlc_lcnphy_a1(pi, 2, 3, 2);
++	wlc_lcnphy_a1(pi, 0, 5, 8);
++	wlc_lcnphy_a1(pi, 2, 2, 1);
++	wlc_lcnphy_a1(pi, 0, 4, 3);
++
++	iqcc0 = wlc_lcnphy_get_cc(pi, 0);
++	locc2 = wlc_lcnphy_get_cc(pi, 2);
++	locc3 = wlc_lcnphy_get_cc(pi, 3);
++	locc4 = wlc_lcnphy_get_cc(pi, 4);
++}
++
++u16 wlc_lcnphy_get_tx_locc(struct brcms_phy *pi)
++{
++	struct phytbl_info tab;
++	u16 didq;
++
++	tab.tbl_id = 0;
++	tab.tbl_width = 16;
++	tab.tbl_ptr = &didq;
++	tab.tbl_len = 1;
++	tab.tbl_offset = 85;
++	wlc_lcnphy_read_table(pi, &tab);
++
++	return didq;
++}
++
++static void wlc_lcnphy_txpwrtbl_iqlo_cal(struct brcms_phy *pi)
++{
++
++	struct lcnphy_txgains target_gains, old_gains;
++	u8 save_bb_mult;
++	u16 a, b, didq, save_pa_gain = 0;
++	uint idx, SAVE_txpwrindex = 0xFF;
++	u32 val;
++	u16 SAVE_txpwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
++	struct phytbl_info tab;
++	u8 ei0, eq0, fi0, fq0;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	wlc_lcnphy_get_tx_gain(pi, &old_gains);
++	save_pa_gain = wlc_lcnphy_get_pa_gain(pi);
++
++	save_bb_mult = wlc_lcnphy_get_bbmult(pi);
++
++	if (SAVE_txpwrctrl == LCNPHY_TX_PWR_CTRL_OFF)
++		SAVE_txpwrindex = wlc_lcnphy_get_current_tx_pwr_idx(pi);
++
++	wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
++
++	target_gains.gm_gain = 7;
++	target_gains.pga_gain = 0;
++	target_gains.pad_gain = 21;
++	target_gains.dac_gain = 0;
++	wlc_lcnphy_set_tx_gain(pi, &target_gains);
++	wlc_lcnphy_set_tx_pwr_by_index(pi, 16);
++
++	if (LCNREV_IS(pi->pubpi.phy_rev, 1) || pi_lcn->lcnphy_hw_iqcal_en) {
++
++		wlc_lcnphy_set_tx_pwr_by_index(pi, 30);
++
++		wlc_lcnphy_tx_iqlo_cal(pi, &target_gains,
++				       (pi_lcn->
++					lcnphy_recal ? LCNPHY_CAL_RECAL :
++					LCNPHY_CAL_FULL), false);
++	} else {
++		wlc_lcnphy_tx_iqlo_soft_cal_full(pi);
++	}
++
++	wlc_lcnphy_get_radio_loft(pi, &ei0, &eq0, &fi0, &fq0);
++	if ((abs((s8) fi0) == 15) && (abs((s8) fq0) == 15)) {
++		if (CHSPEC_IS5G(pi->radio_chanspec)) {
++			target_gains.gm_gain = 255;
++			target_gains.pga_gain = 255;
++			target_gains.pad_gain = 0xf0;
++			target_gains.dac_gain = 0;
++		} else {
++			target_gains.gm_gain = 7;
++			target_gains.pga_gain = 45;
++			target_gains.pad_gain = 186;
++			target_gains.dac_gain = 0;
++		}
++
++		if (LCNREV_IS(pi->pubpi.phy_rev, 1)
++		    || pi_lcn->lcnphy_hw_iqcal_en) {
++
++			target_gains.pga_gain = 0;
++			target_gains.pad_gain = 30;
++			wlc_lcnphy_set_tx_pwr_by_index(pi, 16);
++			wlc_lcnphy_tx_iqlo_cal(pi, &target_gains,
++					       LCNPHY_CAL_FULL, false);
++		} else {
++			wlc_lcnphy_tx_iqlo_soft_cal_full(pi);
++		}
++	}
++
++	wlc_lcnphy_get_tx_iqcc(pi, &a, &b);
++
++	didq = wlc_lcnphy_get_tx_locc(pi);
++
++	tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
++	tab.tbl_width = 32;
++	tab.tbl_ptr = &val;
++
++	tab.tbl_len = 1;
++	tab.tbl_offset = LCNPHY_TX_PWR_CTRL_RATE_OFFSET;
++
++	for (idx = 0; idx < 128; idx++) {
++		tab.tbl_offset = LCNPHY_TX_PWR_CTRL_IQ_OFFSET + idx;
++
++		wlc_lcnphy_read_table(pi, &tab);
++		val = (val & 0xfff00000) |
++		      ((u32) (a & 0x3FF) << 10) | (b & 0x3ff);
++		wlc_lcnphy_write_table(pi, &tab);
++
++		val = didq;
++		tab.tbl_offset = LCNPHY_TX_PWR_CTRL_LO_OFFSET + idx;
++		wlc_lcnphy_write_table(pi, &tab);
++	}
++
++	pi_lcn->lcnphy_cal_results.txiqlocal_a = a;
++	pi_lcn->lcnphy_cal_results.txiqlocal_b = b;
++	pi_lcn->lcnphy_cal_results.txiqlocal_didq = didq;
++	pi_lcn->lcnphy_cal_results.txiqlocal_ei0 = ei0;
++	pi_lcn->lcnphy_cal_results.txiqlocal_eq0 = eq0;
++	pi_lcn->lcnphy_cal_results.txiqlocal_fi0 = fi0;
++	pi_lcn->lcnphy_cal_results.txiqlocal_fq0 = fq0;
++
++	wlc_lcnphy_set_bbmult(pi, save_bb_mult);
++	wlc_lcnphy_set_pa_gain(pi, save_pa_gain);
++	wlc_lcnphy_set_tx_gain(pi, &old_gains);
++
++	if (SAVE_txpwrctrl != LCNPHY_TX_PWR_CTRL_OFF)
++		wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_txpwrctrl);
++	else
++		wlc_lcnphy_set_tx_pwr_by_index(pi, SAVE_txpwrindex);
++}
++
++s16 wlc_lcnphy_tempsense_new(struct brcms_phy *pi, bool mode)
++{
++	u16 tempsenseval1, tempsenseval2;
++	s16 avg = 0;
++	bool suspend = false;
++
++	if (mode == 1) {
++		suspend = (0 == (bcma_read32(pi->d11core,
++					     D11REGOFFS(maccontrol)) &
++				 MCTL_EN_MAC));
++		if (!suspend)
++			wlapi_suspend_mac_and_wait(pi->sh->physhim);
++		wlc_lcnphy_vbat_temp_sense_setup(pi, TEMPSENSE);
++	}
++	tempsenseval1 = read_phy_reg(pi, 0x476) & 0x1FF;
++	tempsenseval2 = read_phy_reg(pi, 0x477) & 0x1FF;
++
++	if (tempsenseval1 > 255)
++		avg = (s16) (tempsenseval1 - 512);
++	else
++		avg = (s16) tempsenseval1;
++
++	if (tempsenseval2 > 255)
++		avg += (s16) (tempsenseval2 - 512);
++	else
++		avg += (s16) tempsenseval2;
++
++	avg /= 2;
++
++	if (mode == 1) {
++
++		mod_phy_reg(pi, 0x448, (0x1 << 14), (1) << 14);
++
++		udelay(100);
++		mod_phy_reg(pi, 0x448, (0x1 << 14), (0) << 14);
++
++		if (!suspend)
++			wlapi_enable_mac(pi->sh->physhim);
++	}
++	return avg;
++}
++
++u16 wlc_lcnphy_tempsense(struct brcms_phy *pi, bool mode)
++{
++	u16 tempsenseval1, tempsenseval2;
++	s32 avg = 0;
++	bool suspend = false;
++	u16 SAVE_txpwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	if (mode == 1) {
++		suspend = (0 == (bcma_read32(pi->d11core,
++					     D11REGOFFS(maccontrol)) &
++				 MCTL_EN_MAC));
++		if (!suspend)
++			wlapi_suspend_mac_and_wait(pi->sh->physhim);
++		wlc_lcnphy_vbat_temp_sense_setup(pi, TEMPSENSE);
++	}
++	tempsenseval1 = read_phy_reg(pi, 0x476) & 0x1FF;
++	tempsenseval2 = read_phy_reg(pi, 0x477) & 0x1FF;
++
++	if (tempsenseval1 > 255)
++		avg = (int)(tempsenseval1 - 512);
++	else
++		avg = (int)tempsenseval1;
++
++	if (pi_lcn->lcnphy_tempsense_option == 1 || pi->hwpwrctrl_capable) {
++		if (tempsenseval2 > 255)
++			avg = (int)(avg - tempsenseval2 + 512);
++		else
++			avg = (int)(avg - tempsenseval2);
++	} else {
++		if (tempsenseval2 > 255)
++			avg = (int)(avg + tempsenseval2 - 512);
++		else
++			avg = (int)(avg + tempsenseval2);
++		avg = avg / 2;
++	}
++	if (avg < 0)
++		avg = avg + 512;
++
++	if (pi_lcn->lcnphy_tempsense_option == 2)
++		avg = tempsenseval1;
++
++	if (mode)
++		wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_txpwrctrl);
++
++	if (mode == 1) {
++
++		mod_phy_reg(pi, 0x448, (0x1 << 14), (1) << 14);
++
++		udelay(100);
++		mod_phy_reg(pi, 0x448, (0x1 << 14), (0) << 14);
++
++		if (!suspend)
++			wlapi_enable_mac(pi->sh->physhim);
++	}
++	return (u16) avg;
++}
++
++s8 wlc_lcnphy_tempsense_degree(struct brcms_phy *pi, bool mode)
++{
++	s32 degree = wlc_lcnphy_tempsense_new(pi, mode);
++	degree =
++		((degree <<
++		  10) + LCN_TEMPSENSE_OFFSET + (LCN_TEMPSENSE_DEN >> 1))
++		/ LCN_TEMPSENSE_DEN;
++	return (s8) degree;
++}
++
++s8 wlc_lcnphy_vbatsense(struct brcms_phy *pi, bool mode)
++{
++	u16 vbatsenseval;
++	s32 avg = 0;
++	bool suspend = false;
++
++	if (mode == 1) {
++		suspend = (0 == (bcma_read32(pi->d11core,
++					     D11REGOFFS(maccontrol)) &
++				 MCTL_EN_MAC));
++		if (!suspend)
++			wlapi_suspend_mac_and_wait(pi->sh->physhim);
++		wlc_lcnphy_vbat_temp_sense_setup(pi, VBATSENSE);
++	}
++
++	vbatsenseval = read_phy_reg(pi, 0x475) & 0x1FF;
++
++	if (vbatsenseval > 255)
++		avg = (s32) (vbatsenseval - 512);
++	else
++		avg = (s32) vbatsenseval;
++
++	avg =	(avg * LCN_VBAT_SCALE_NOM +
++		 (LCN_VBAT_SCALE_DEN >> 1)) / LCN_VBAT_SCALE_DEN;
++
++	if (mode == 1) {
++		if (!suspend)
++			wlapi_enable_mac(pi->sh->physhim);
++	}
++	return (s8) avg;
++}
++
++static void wlc_lcnphy_afe_clk_init(struct brcms_phy *pi, u8 mode)
++{
++	u8 phybw40;
++	phybw40 = CHSPEC_IS40(pi->radio_chanspec);
++
++	mod_phy_reg(pi, 0x6d1, (0x1 << 7), (1) << 7);
++
++	if (((mode == AFE_CLK_INIT_MODE_PAPD) && (phybw40 == 0)) ||
++	    (mode == AFE_CLK_INIT_MODE_TXRX2X))
++		write_phy_reg(pi, 0x6d0, 0x7);
++
++	wlc_lcnphy_toggle_afe_pwdn(pi);
++}
++
++static void wlc_lcnphy_temp_adj(struct brcms_phy *pi)
++{
++}
++
++static void wlc_lcnphy_glacial_timer_based_cal(struct brcms_phy *pi)
++{
++	bool suspend;
++	s8 index;
++	u16 SAVE_pwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++	suspend = (0 == (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) &
++			 MCTL_EN_MAC));
++	if (!suspend)
++		wlapi_suspend_mac_and_wait(pi->sh->physhim);
++	wlc_lcnphy_deaf_mode(pi, true);
++	pi->phy_lastcal = pi->sh->now;
++	pi->phy_forcecal = false;
++	index = pi_lcn->lcnphy_current_index;
++
++	wlc_lcnphy_txpwrtbl_iqlo_cal(pi);
++
++	wlc_lcnphy_set_tx_pwr_by_index(pi, index);
++	wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_pwrctrl);
++	wlc_lcnphy_deaf_mode(pi, false);
++	if (!suspend)
++		wlapi_enable_mac(pi->sh->physhim);
++
++}
++
++static void wlc_lcnphy_periodic_cal(struct brcms_phy *pi)
++{
++	bool suspend, full_cal;
++	const struct lcnphy_rx_iqcomp *rx_iqcomp;
++	int rx_iqcomp_sz;
++	u16 SAVE_pwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
++	s8 index;
++	struct phytbl_info tab;
++	s32 a1, b0, b1;
++	s32 tssi, pwr, maxtargetpwr, mintargetpwr;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	pi->phy_lastcal = pi->sh->now;
++	pi->phy_forcecal = false;
++	full_cal =
++		(pi_lcn->lcnphy_full_cal_channel !=
++		 CHSPEC_CHANNEL(pi->radio_chanspec));
++	pi_lcn->lcnphy_full_cal_channel = CHSPEC_CHANNEL(pi->radio_chanspec);
++	index = pi_lcn->lcnphy_current_index;
++
++	suspend = (0 == (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) &
++			 MCTL_EN_MAC));
++	if (!suspend) {
++		wlapi_bmac_write_shm(pi->sh->physhim, M_CTS_DURATION, 10000);
++		wlapi_suspend_mac_and_wait(pi->sh->physhim);
++	}
++
++	wlc_lcnphy_deaf_mode(pi, true);
++
++	wlc_lcnphy_txpwrtbl_iqlo_cal(pi);
++
++	rx_iqcomp = lcnphy_rx_iqcomp_table_rev0;
++	rx_iqcomp_sz = ARRAY_SIZE(lcnphy_rx_iqcomp_table_rev0);
++
++	if (LCNREV_IS(pi->pubpi.phy_rev, 1))
++		wlc_lcnphy_rx_iq_cal(pi, NULL, 0, true, false, 1, 40);
++	else
++		wlc_lcnphy_rx_iq_cal(pi, NULL, 0, true, false, 1, 127);
++
++	if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi)) {
++
++		wlc_lcnphy_idle_tssi_est((struct brcms_phy_pub *) pi);
++
++		b0 = pi->txpa_2g[0];
++		b1 = pi->txpa_2g[1];
++		a1 = pi->txpa_2g[2];
++		maxtargetpwr = wlc_lcnphy_tssi2dbm(10, a1, b0, b1);
++		mintargetpwr = wlc_lcnphy_tssi2dbm(125, a1, b0, b1);
++
++		tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
++		tab.tbl_width = 32;
++		tab.tbl_ptr = &pwr;
++		tab.tbl_len = 1;
++		tab.tbl_offset = 0;
++		for (tssi = 0; tssi < 128; tssi++) {
++			pwr = wlc_lcnphy_tssi2dbm(tssi, a1, b0, b1);
++			pwr = (pwr < mintargetpwr) ? mintargetpwr : pwr;
++			wlc_lcnphy_write_table(pi, &tab);
++			tab.tbl_offset++;
++		}
++	}
++
++	wlc_lcnphy_set_tx_pwr_by_index(pi, index);
++	wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_pwrctrl);
++	wlc_lcnphy_deaf_mode(pi, false);
++	if (!suspend)
++		wlapi_enable_mac(pi->sh->physhim);
++}
++
++void wlc_lcnphy_calib_modes(struct brcms_phy *pi, uint mode)
++{
++	u16 temp_new;
++	int temp1, temp2, temp_diff;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	switch (mode) {
++	case PHY_PERICAL_CHAN:
++		break;
++	case PHY_FULLCAL:
++		wlc_lcnphy_periodic_cal(pi);
++		break;
++	case PHY_PERICAL_PHYINIT:
++		wlc_lcnphy_periodic_cal(pi);
++		break;
++	case PHY_PERICAL_WATCHDOG:
++		if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) {
++			temp_new = wlc_lcnphy_tempsense(pi, 0);
++			temp1 = LCNPHY_TEMPSENSE(temp_new);
++			temp2 = LCNPHY_TEMPSENSE(pi_lcn->lcnphy_cal_temper);
++			temp_diff = temp1 - temp2;
++			if ((pi_lcn->lcnphy_cal_counter > 90) ||
++			    (temp_diff > 60) || (temp_diff < -60)) {
++				wlc_lcnphy_glacial_timer_based_cal(pi);
++				wlc_2064_vco_cal(pi);
++				pi_lcn->lcnphy_cal_temper = temp_new;
++				pi_lcn->lcnphy_cal_counter = 0;
++			} else
++				pi_lcn->lcnphy_cal_counter++;
++		}
++		break;
++	case LCNPHY_PERICAL_TEMPBASED_TXPWRCTRL:
++		if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi))
++			wlc_lcnphy_tx_power_adjustment(
++				(struct brcms_phy_pub *) pi);
++		break;
++	}
++}
++
++void wlc_lcnphy_get_tssi(struct brcms_phy *pi, s8 *ofdm_pwr, s8 *cck_pwr)
++{
++	s8 cck_offset;
++	u16 status;
++	status = (read_phy_reg(pi, 0x4ab));
++	if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi) &&
++	    (status  & (0x1 << 15))) {
++		*ofdm_pwr = (s8) (((read_phy_reg(pi, 0x4ab) & (0x1ff << 0))
++				   >> 0) >> 1);
++
++		if (wlc_phy_tpc_isenabled_lcnphy(pi))
++			cck_offset = pi->tx_power_offset[TXP_FIRST_CCK];
++		else
++			cck_offset = 0;
++
++		*cck_pwr = *ofdm_pwr + cck_offset;
++	} else {
++		*cck_pwr = 0;
++		*ofdm_pwr = 0;
++	}
++}
++
++void wlc_phy_cal_init_lcnphy(struct brcms_phy *pi)
++{
++	return;
++
++}
++
++void wlc_lcnphy_tx_power_adjustment(struct brcms_phy_pub *ppi)
++{
++	s8 index;
++	u16 index2;
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++	u16 SAVE_txpwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
++	if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi) &&
++	    SAVE_txpwrctrl) {
++		index = wlc_lcnphy_tempcompensated_txpwrctrl(pi);
++		index2 = (u16) (index * 2);
++		mod_phy_reg(pi, 0x4a9, (0x1ff << 0), (index2) << 0);
++
++		pi_lcn->lcnphy_current_index =
++			(s8)((read_phy_reg(pi, 0x4a9) & 0xFF) / 2);
++	}
++}
++
++static void
++wlc_lcnphy_load_tx_gain_table(struct brcms_phy *pi,
++			      const struct lcnphy_tx_gain_tbl_entry *gain_table)
++{
++	u32 j;
++	struct phytbl_info tab;
++	u32 val;
++	u16 pa_gain;
++	u16 gm_gain;
++
++	if (CHSPEC_IS5G(pi->radio_chanspec))
++		pa_gain = 0x70;
++	else
++		pa_gain = 0x70;
++
++	if (pi->sh->boardflags & BFL_FEM)
++		pa_gain = 0x10;
++	tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
++	tab.tbl_width = 32;
++	tab.tbl_len = 1;
++	tab.tbl_ptr = &val;
++
++	for (j = 0; j < 128; j++) {
++		gm_gain = gain_table[j].gm;
++		val = (((u32) pa_gain << 24) |
++		       (gain_table[j].pad << 16) |
++		       (gain_table[j].pga << 8) | gm_gain);
++
++		tab.tbl_offset = LCNPHY_TX_PWR_CTRL_GAIN_OFFSET + j;
++		wlc_lcnphy_write_table(pi, &tab);
++
++		val = (gain_table[j].dac << 28) | (gain_table[j].bb_mult << 20);
++		tab.tbl_offset = LCNPHY_TX_PWR_CTRL_IQ_OFFSET + j;
++		wlc_lcnphy_write_table(pi, &tab);
++	}
++}
++
++static void wlc_lcnphy_load_rfpower(struct brcms_phy *pi)
++{
++	struct phytbl_info tab;
++	u32 val, bbmult, rfgain;
++	u8 index;
++	u8 scale_factor = 1;
++	s16 temp, temp1, temp2, qQ, qQ1, qQ2, shift;
++
++	tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
++	tab.tbl_width = 32;
++	tab.tbl_len = 1;
++
++	for (index = 0; index < 128; index++) {
++		tab.tbl_ptr = &bbmult;
++		tab.tbl_offset = LCNPHY_TX_PWR_CTRL_IQ_OFFSET + index;
++		wlc_lcnphy_read_table(pi, &tab);
++		bbmult = bbmult >> 20;
++
++		tab.tbl_ptr = &rfgain;
++		tab.tbl_offset = LCNPHY_TX_PWR_CTRL_GAIN_OFFSET + index;
++		wlc_lcnphy_read_table(pi, &tab);
++
++		qm_log10((s32) (bbmult), 0, &temp1, &qQ1);
++		qm_log10((s32) (1 << 6), 0, &temp2, &qQ2);
++
++		if (qQ1 < qQ2) {
++			temp2 = qm_shr16(temp2, qQ2 - qQ1);
++			qQ = qQ1;
++		} else {
++			temp1 = qm_shr16(temp1, qQ1 - qQ2);
++			qQ = qQ2;
++		}
++		temp = qm_sub16(temp1, temp2);
++
++		if (qQ >= 4)
++			shift = qQ - 4;
++		else
++			shift = 4 - qQ;
++
++		val = (((index << shift) + (5 * temp) +
++			(1 << (scale_factor + shift - 3))) >> (scale_factor +
++							       shift - 2));
++
++		tab.tbl_ptr = &val;
++		tab.tbl_offset = LCNPHY_TX_PWR_CTRL_PWR_OFFSET + index;
++		wlc_lcnphy_write_table(pi, &tab);
++	}
++}
++
++static void wlc_lcnphy_bu_tweaks(struct brcms_phy *pi)
++{
++	or_phy_reg(pi, 0x805, 0x1);
++
++	mod_phy_reg(pi, 0x42f, (0x7 << 0), (0x3) << 0);
++
++	mod_phy_reg(pi, 0x030, (0x7 << 0), (0x3) << 0);
++
++	write_phy_reg(pi, 0x414, 0x1e10);
++	write_phy_reg(pi, 0x415, 0x0640);
++
++	mod_phy_reg(pi, 0x4df, (0xff << 8), -9 << 8);
++
++	or_phy_reg(pi, 0x44a, 0x44);
++	write_phy_reg(pi, 0x44a, 0x80);
++	mod_phy_reg(pi, 0x434, (0xff << 0), (0xFD) << 0);
++
++	mod_phy_reg(pi, 0x420, (0xff << 0), (16) << 0);
++
++	if (!(pi->sh->boardrev < 0x1204))
++		mod_radio_reg(pi, RADIO_2064_REG09B, 0xF0, 0xF0);
++
++	write_phy_reg(pi, 0x7d6, 0x0902);
++	mod_phy_reg(pi, 0x429, (0xf << 0), (0x9) << 0);
++
++	mod_phy_reg(pi, 0x429, (0x3f << 4), (0xe) << 4);
++
++	if (LCNREV_IS(pi->pubpi.phy_rev, 1)) {
++		mod_phy_reg(pi, 0x423, (0xff << 0), (0x46) << 0);
++
++		mod_phy_reg(pi, 0x411, (0xff << 0), (1) << 0);
++
++		mod_phy_reg(pi, 0x434, (0xff << 0), (0xFF) << 0);
++
++		mod_phy_reg(pi, 0x656, (0xf << 0), (2) << 0);
++
++		mod_phy_reg(pi, 0x44d, (0x1 << 2), (1) << 2);
++
++		mod_radio_reg(pi, RADIO_2064_REG0F7, 0x4, 0x4);
++		mod_radio_reg(pi, RADIO_2064_REG0F1, 0x3, 0);
++		mod_radio_reg(pi, RADIO_2064_REG0F2, 0xF8, 0x90);
++		mod_radio_reg(pi, RADIO_2064_REG0F3, 0x3, 0x2);
++		mod_radio_reg(pi, RADIO_2064_REG0F3, 0xf0, 0xa0);
++
++		mod_radio_reg(pi, RADIO_2064_REG11F, 0x2, 0x2);
++
++		wlc_lcnphy_clear_tx_power_offsets(pi);
++		mod_phy_reg(pi, 0x4d0, (0x1ff << 6), (10) << 6);
++
++	}
++}
++
++static void wlc_lcnphy_rcal(struct brcms_phy *pi)
++{
++	u8 rcal_value;
++
++	and_radio_reg(pi, RADIO_2064_REG05B, 0xfD);
++
++	or_radio_reg(pi, RADIO_2064_REG004, 0x40);
++	or_radio_reg(pi, RADIO_2064_REG120, 0x10);
++
++	or_radio_reg(pi, RADIO_2064_REG078, 0x80);
++	or_radio_reg(pi, RADIO_2064_REG129, 0x02);
++
++	or_radio_reg(pi, RADIO_2064_REG057, 0x01);
++
++	or_radio_reg(pi, RADIO_2064_REG05B, 0x02);
++	mdelay(5);
++	SPINWAIT(!wlc_radio_2064_rcal_done(pi), 10 * 1000 * 1000);
++
++	if (wlc_radio_2064_rcal_done(pi)) {
++		rcal_value = (u8) read_radio_reg(pi, RADIO_2064_REG05C);
++		rcal_value = rcal_value & 0x1f;
++	}
++
++	and_radio_reg(pi, RADIO_2064_REG05B, 0xfD);
++
++	and_radio_reg(pi, RADIO_2064_REG057, 0xFE);
++}
++
++static void wlc_lcnphy_rc_cal(struct brcms_phy *pi)
++{
++	u8 dflt_rc_cal_val;
++	u16 flt_val;
++
++	dflt_rc_cal_val = 7;
++	if (LCNREV_IS(pi->pubpi.phy_rev, 1))
++		dflt_rc_cal_val = 11;
++	flt_val =
++		(dflt_rc_cal_val << 10) | (dflt_rc_cal_val << 5) |
++		(dflt_rc_cal_val);
++	write_phy_reg(pi, 0x933, flt_val);
++	write_phy_reg(pi, 0x934, flt_val);
++	write_phy_reg(pi, 0x935, flt_val);
++	write_phy_reg(pi, 0x936, flt_val);
++	write_phy_reg(pi, 0x937, (flt_val & 0x1FF));
++
++	return;
++}
++
++static void wlc_radio_2064_init(struct brcms_phy *pi)
++{
++	u32 i;
++	const struct lcnphy_radio_regs *lcnphyregs = NULL;
++
++	lcnphyregs = lcnphy_radio_regs_2064;
++
++	for (i = 0; lcnphyregs[i].address != 0xffff; i++)
++		if (CHSPEC_IS5G(pi->radio_chanspec) && lcnphyregs[i].do_init_a)
++			write_radio_reg(pi,
++					((lcnphyregs[i].address & 0x3fff) |
++					 RADIO_DEFAULT_CORE),
++					(u16) lcnphyregs[i].init_a);
++		else if (lcnphyregs[i].do_init_g)
++			write_radio_reg(pi,
++					((lcnphyregs[i].address & 0x3fff) |
++					 RADIO_DEFAULT_CORE),
++					(u16) lcnphyregs[i].init_g);
++
++	write_radio_reg(pi, RADIO_2064_REG032, 0x62);
++	write_radio_reg(pi, RADIO_2064_REG033, 0x19);
++
++	write_radio_reg(pi, RADIO_2064_REG090, 0x10);
++
++	write_radio_reg(pi, RADIO_2064_REG010, 0x00);
++
++	if (LCNREV_IS(pi->pubpi.phy_rev, 1)) {
++
++		write_radio_reg(pi, RADIO_2064_REG060, 0x7f);
++		write_radio_reg(pi, RADIO_2064_REG061, 0x72);
++		write_radio_reg(pi, RADIO_2064_REG062, 0x7f);
++	}
++
++	write_radio_reg(pi, RADIO_2064_REG01D, 0x02);
++	write_radio_reg(pi, RADIO_2064_REG01E, 0x06);
++
++	mod_phy_reg(pi, 0x4ea, (0x7 << 0), 0 << 0);
++
++	mod_phy_reg(pi, 0x4ea, (0x7 << 3), 1 << 3);
++
++	mod_phy_reg(pi, 0x4ea, (0x7 << 6), 2 << 6);
++
++	mod_phy_reg(pi, 0x4ea, (0x7 << 9), 3 << 9);
++
++	mod_phy_reg(pi, 0x4ea, (0x7 << 12), 4 << 12);
++
++	write_phy_reg(pi, 0x4ea, 0x4688);
++
++	mod_phy_reg(pi, 0x4eb, (0x7 << 0), 2 << 0);
++
++	mod_phy_reg(pi, 0x4eb, (0x7 << 6), 0 << 6);
++
++	mod_phy_reg(pi, 0x46a, (0xffff << 0), 25 << 0);
++
++	wlc_lcnphy_set_tx_locc(pi, 0);
++
++	wlc_lcnphy_rcal(pi);
++
++	wlc_lcnphy_rc_cal(pi);
++}
++
++static void wlc_lcnphy_radio_init(struct brcms_phy *pi)
++{
++	wlc_radio_2064_init(pi);
++}
++
++static void wlc_lcnphy_tbl_init(struct brcms_phy *pi)
++{
++	uint idx;
++	u8 phybw40;
++	struct phytbl_info tab;
++	u32 val;
++
++	phybw40 = CHSPEC_IS40(pi->radio_chanspec);
++
++	for (idx = 0; idx < dot11lcnphytbl_info_sz_rev0; idx++)
++		wlc_lcnphy_write_table(pi, &dot11lcnphytbl_info_rev0[idx]);
++
++	if (pi->sh->boardflags & BFL_FEM_BT) {
++		tab.tbl_id = LCNPHY_TBL_ID_RFSEQ;
++		tab.tbl_width = 16;
++		tab.tbl_ptr = &val;
++		tab.tbl_len = 1;
++		val = 100;
++		tab.tbl_offset = 4;
++		wlc_lcnphy_write_table(pi, &tab);
++	}
++
++	tab.tbl_id = LCNPHY_TBL_ID_RFSEQ;
++	tab.tbl_width = 16;
++	tab.tbl_ptr = &val;
++	tab.tbl_len = 1;
++
++	val = 114;
++	tab.tbl_offset = 0;
++	wlc_lcnphy_write_table(pi, &tab);
++
++	val = 130;
++	tab.tbl_offset = 1;
++	wlc_lcnphy_write_table(pi, &tab);
++
++	val = 6;
++	tab.tbl_offset = 8;
++	wlc_lcnphy_write_table(pi, &tab);
++
++	if (CHSPEC_IS2G(pi->radio_chanspec)) {
++		if (pi->sh->boardflags & BFL_FEM)
++			wlc_lcnphy_load_tx_gain_table(
++				pi,
++				dot11lcnphy_2GHz_extPA_gaintable_rev0);
++		else
++			wlc_lcnphy_load_tx_gain_table(
++				pi,
++				dot11lcnphy_2GHz_gaintable_rev0);
++	}
++
++	if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
++		const struct phytbl_info *tb;
++		int l;
++
++		if (CHSPEC_IS2G(pi->radio_chanspec)) {
++			l = dot11lcnphytbl_rx_gain_info_2G_rev2_sz;
++			if (pi->sh->boardflags & BFL_EXTLNA)
++				tb = dot11lcnphytbl_rx_gain_info_extlna_2G_rev2;
++			else
++				tb = dot11lcnphytbl_rx_gain_info_2G_rev2;
++		} else {
++			l = dot11lcnphytbl_rx_gain_info_5G_rev2_sz;
++			if (pi->sh->boardflags & BFL_EXTLNA_5GHz)
++				tb = dot11lcnphytbl_rx_gain_info_extlna_5G_rev2;
++			else
++				tb = dot11lcnphytbl_rx_gain_info_5G_rev2;
++		}
++
++		for (idx = 0; idx < l; idx++)
++			wlc_lcnphy_write_table(pi, &tb[idx]);
++	}
++
++	if ((pi->sh->boardflags & BFL_FEM)
++	    && !(pi->sh->boardflags & BFL_FEM_BT))
++		wlc_lcnphy_write_table(pi, &dot11lcn_sw_ctrl_tbl_info_4313_epa);
++	else if (pi->sh->boardflags & BFL_FEM_BT) {
++		if (pi->sh->boardrev < 0x1250)
++			wlc_lcnphy_write_table(
++				pi,
++				&dot11lcn_sw_ctrl_tbl_info_4313_bt_epa);
++		else
++			wlc_lcnphy_write_table(
++				pi,
++				&dot11lcn_sw_ctrl_tbl_info_4313_bt_epa_p250);
++	} else
++		wlc_lcnphy_write_table(pi, &dot11lcn_sw_ctrl_tbl_info_4313);
++
++	wlc_lcnphy_load_rfpower(pi);
++
++	wlc_lcnphy_clear_papd_comptable(pi);
++}
++
++static void wlc_lcnphy_rev0_baseband_init(struct brcms_phy *pi)
++{
++	u16 afectrl1;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	write_radio_reg(pi, RADIO_2064_REG11C, 0x0);
++
++	write_phy_reg(pi, 0x43b, 0x0);
++	write_phy_reg(pi, 0x43c, 0x0);
++	write_phy_reg(pi, 0x44c, 0x0);
++	write_phy_reg(pi, 0x4e6, 0x0);
++	write_phy_reg(pi, 0x4f9, 0x0);
++	write_phy_reg(pi, 0x4b0, 0x0);
++	write_phy_reg(pi, 0x938, 0x0);
++	write_phy_reg(pi, 0x4b0, 0x0);
++	write_phy_reg(pi, 0x44e, 0);
++
++	or_phy_reg(pi, 0x567, 0x03);
++
++	or_phy_reg(pi, 0x44a, 0x44);
++	write_phy_reg(pi, 0x44a, 0x80);
++
++	if (!(pi->sh->boardflags & BFL_FEM))
++		wlc_lcnphy_set_tx_pwr_by_index(pi, 52);
++
++	if (0) {
++		afectrl1 = 0;
++		afectrl1 = (u16) ((pi_lcn->lcnphy_rssi_vf) |
++				  (pi_lcn->lcnphy_rssi_vc << 4) |
++				  (pi_lcn->lcnphy_rssi_gs << 10));
++		write_phy_reg(pi, 0x43e, afectrl1);
++	}
++
++	mod_phy_reg(pi, 0x634, (0xff << 0), 0xC << 0);
++	if (pi->sh->boardflags & BFL_FEM) {
++		mod_phy_reg(pi, 0x634, (0xff << 0), 0xA << 0);
++
++		write_phy_reg(pi, 0x910, 0x1);
++	}
++
++	mod_phy_reg(pi, 0x448, (0x3 << 8), 1 << 8);
++	mod_phy_reg(pi, 0x608, (0xff << 0), 0x17 << 0);
++	mod_phy_reg(pi, 0x604, (0x7ff << 0), 0x3EA << 0);
++
++}
++
++static void wlc_lcnphy_rev2_baseband_init(struct brcms_phy *pi)
++{
++	if (CHSPEC_IS5G(pi->radio_chanspec)) {
++		mod_phy_reg(pi, 0x416, (0xff << 0), 80 << 0);
++		mod_phy_reg(pi, 0x416, (0xff << 8), 80 << 8);
++	}
++}
++
++static void wlc_lcnphy_agc_temp_init(struct brcms_phy *pi)
++{
++	s16 temp;
++	struct phytbl_info tab;
++	u32 tableBuffer[2];
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	temp = (s16) read_phy_reg(pi, 0x4df);
++	pi_lcn->lcnphy_ofdmgainidxtableoffset = (temp & (0xff << 0)) >> 0;
++
++	if (pi_lcn->lcnphy_ofdmgainidxtableoffset > 127)
++		pi_lcn->lcnphy_ofdmgainidxtableoffset -= 256;
++
++	pi_lcn->lcnphy_dsssgainidxtableoffset = (temp & (0xff << 8)) >> 8;
++
++	if (pi_lcn->lcnphy_dsssgainidxtableoffset > 127)
++		pi_lcn->lcnphy_dsssgainidxtableoffset -= 256;
++
++	tab.tbl_ptr = tableBuffer;
++	tab.tbl_len = 2;
++	tab.tbl_id = 17;
++	tab.tbl_offset = 59;
++	tab.tbl_width = 32;
++	wlc_lcnphy_read_table(pi, &tab);
++
++	if (tableBuffer[0] > 63)
++		tableBuffer[0] -= 128;
++	pi_lcn->lcnphy_tr_R_gain_val = tableBuffer[0];
++
++	if (tableBuffer[1] > 63)
++		tableBuffer[1] -= 128;
++	pi_lcn->lcnphy_tr_T_gain_val = tableBuffer[1];
++
++	temp = (s16) (read_phy_reg(pi, 0x434) & (0xff << 0));
++	if (temp > 127)
++		temp -= 256;
++	pi_lcn->lcnphy_input_pwr_offset_db = (s8) temp;
++
++	pi_lcn->lcnphy_Med_Low_Gain_db =
++		(read_phy_reg(pi, 0x424) & (0xff << 8)) >> 8;
++	pi_lcn->lcnphy_Very_Low_Gain_db =
++		(read_phy_reg(pi, 0x425) & (0xff << 0)) >> 0;
++
++	tab.tbl_ptr = tableBuffer;
++	tab.tbl_len = 2;
++	tab.tbl_id = LCNPHY_TBL_ID_GAIN_IDX;
++	tab.tbl_offset = 28;
++	tab.tbl_width = 32;
++	wlc_lcnphy_read_table(pi, &tab);
++
++	pi_lcn->lcnphy_gain_idx_14_lowword = tableBuffer[0];
++	pi_lcn->lcnphy_gain_idx_14_hiword = tableBuffer[1];
++
++}
++
++static void wlc_lcnphy_baseband_init(struct brcms_phy *pi)
++{
++
++	wlc_lcnphy_tbl_init(pi);
++	wlc_lcnphy_rev0_baseband_init(pi);
++	if (LCNREV_IS(pi->pubpi.phy_rev, 2))
++		wlc_lcnphy_rev2_baseband_init(pi);
++	wlc_lcnphy_bu_tweaks(pi);
++}
++
++void wlc_phy_init_lcnphy(struct brcms_phy *pi)
++{
++	u8 phybw40;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++	phybw40 = CHSPEC_IS40(pi->radio_chanspec);
++
++	pi_lcn->lcnphy_cal_counter = 0;
++	pi_lcn->lcnphy_cal_temper = pi_lcn->lcnphy_rawtempsense;
++
++	or_phy_reg(pi, 0x44a, 0x80);
++	and_phy_reg(pi, 0x44a, 0x7f);
++
++	wlc_lcnphy_afe_clk_init(pi, AFE_CLK_INIT_MODE_TXRX2X);
++
++	write_phy_reg(pi, 0x60a, 160);
++
++	write_phy_reg(pi, 0x46a, 25);
++
++	wlc_lcnphy_baseband_init(pi);
++
++	wlc_lcnphy_radio_init(pi);
++
++	if (CHSPEC_IS2G(pi->radio_chanspec))
++		wlc_lcnphy_tx_pwr_ctrl_init((struct brcms_phy_pub *) pi);
++
++	wlc_phy_chanspec_set((struct brcms_phy_pub *) pi, pi->radio_chanspec);
++
++	si_pmu_regcontrol(pi->sh->sih, 0, 0xf, 0x9);
++
++	si_pmu_chipcontrol(pi->sh->sih, 0, 0xffffffff, 0x03CDDDDD);
++
++	if ((pi->sh->boardflags & BFL_FEM)
++	    && wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi))
++		wlc_lcnphy_set_tx_pwr_by_index(pi, FIXED_TXPWR);
++
++	wlc_lcnphy_agc_temp_init(pi);
++
++	wlc_lcnphy_temp_adj(pi);
++
++	mod_phy_reg(pi, 0x448, (0x1 << 14), (1) << 14);
++
++	udelay(100);
++	mod_phy_reg(pi, 0x448, (0x1 << 14), (0) << 14);
++
++	wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_HW);
++	pi_lcn->lcnphy_noise_samples = LCNPHY_NOISE_SAMPLES_DEFAULT;
++	wlc_lcnphy_calib_modes(pi, PHY_PERICAL_PHYINIT);
++}
++
++static bool wlc_phy_txpwr_srom_read_lcnphy(struct brcms_phy *pi)
++{
++	s8 txpwr = 0;
++	int i;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++	struct ssb_sprom *sprom = &pi->d11core->bus->sprom;
++
++	if (CHSPEC_IS2G(pi->radio_chanspec)) {
++		u16 cckpo = 0;
++		u32 offset_ofdm, offset_mcs;
++
++		pi_lcn->lcnphy_tr_isolation_mid = sprom->fem.ghz2.tr_iso;
++
++		pi_lcn->lcnphy_rx_power_offset = sprom->rxpo2g;
++
++		pi->txpa_2g[0] = sprom->pa0b0;
++		pi->txpa_2g[1] = sprom->pa0b1;
++		pi->txpa_2g[2] = sprom->pa0b2;
++
++		pi_lcn->lcnphy_rssi_vf = sprom->rssismf2g;
++		pi_lcn->lcnphy_rssi_vc = sprom->rssismc2g;
++		pi_lcn->lcnphy_rssi_gs = sprom->rssisav2g;
++
++		pi_lcn->lcnphy_rssi_vf_lowtemp = pi_lcn->lcnphy_rssi_vf;
++		pi_lcn->lcnphy_rssi_vc_lowtemp = pi_lcn->lcnphy_rssi_vc;
++		pi_lcn->lcnphy_rssi_gs_lowtemp = pi_lcn->lcnphy_rssi_gs;
++
++		pi_lcn->lcnphy_rssi_vf_hightemp = pi_lcn->lcnphy_rssi_vf;
++		pi_lcn->lcnphy_rssi_vc_hightemp = pi_lcn->lcnphy_rssi_vc;
++		pi_lcn->lcnphy_rssi_gs_hightemp = pi_lcn->lcnphy_rssi_gs;
++
++		txpwr = sprom->core_pwr_info[0].maxpwr_2g;
++		pi->tx_srom_max_2g = txpwr;
++
++		for (i = 0; i < PWRTBL_NUM_COEFF; i++) {
++			pi->txpa_2g_low_temp[i] = pi->txpa_2g[i];
++			pi->txpa_2g_high_temp[i] = pi->txpa_2g[i];
++		}
++
++		cckpo = sprom->cck2gpo;
++		offset_ofdm = sprom->ofdm2gpo;
++		if (cckpo) {
++			uint max_pwr_chan = txpwr;
++
++			for (i = TXP_FIRST_CCK; i <= TXP_LAST_CCK; i++) {
++				pi->tx_srom_max_rate_2g[i] =
++					max_pwr_chan - ((cckpo & 0xf) * 2);
++				cckpo >>= 4;
++			}
++
++			for (i = TXP_FIRST_OFDM; i <= TXP_LAST_OFDM; i++) {
++				pi->tx_srom_max_rate_2g[i] =
++					max_pwr_chan -
++					((offset_ofdm & 0xf) * 2);
++				offset_ofdm >>= 4;
++			}
++		} else {
++			u8 opo = 0;
++
++			opo = sprom->opo;
++
++			for (i = TXP_FIRST_CCK; i <= TXP_LAST_CCK; i++)
++				pi->tx_srom_max_rate_2g[i] = txpwr;
++
++			for (i = TXP_FIRST_OFDM; i <= TXP_LAST_OFDM; i++) {
++				pi->tx_srom_max_rate_2g[i] = txpwr -
++						((offset_ofdm & 0xf) * 2);
++				offset_ofdm >>= 4;
++			}
++			offset_mcs = sprom->mcs2gpo[1] << 16;
++			offset_mcs |= sprom->mcs2gpo[0];
++			pi_lcn->lcnphy_mcs20_po = offset_mcs;
++			for (i = TXP_FIRST_SISO_MCS_20;
++			     i <= TXP_LAST_SISO_MCS_20; i++) {
++				pi->tx_srom_max_rate_2g[i] =
++					txpwr - ((offset_mcs & 0xf) * 2);
++				offset_mcs >>= 4;
++			}
++		}
++
++		pi_lcn->lcnphy_rawtempsense = sprom->rawtempsense;
++		pi_lcn->lcnphy_measPower = sprom->measpower;
++		pi_lcn->lcnphy_tempsense_slope = sprom->tempsense_slope;
++		pi_lcn->lcnphy_hw_iqcal_en = sprom->hw_iqcal_en;
++		pi_lcn->lcnphy_iqcal_swp_dis = sprom->iqcal_swp_dis;
++		pi_lcn->lcnphy_tempcorrx = sprom->tempcorrx;
++		pi_lcn->lcnphy_tempsense_option = sprom->tempsense_option;
++		pi_lcn->lcnphy_freqoffset_corr = sprom->freqoffset_corr;
++		if (sprom->ant_available_bg > 1)
++			wlc_phy_ant_rxdiv_set((struct brcms_phy_pub *) pi,
++				sprom->ant_available_bg);
++	}
++	pi_lcn->lcnphy_cck_dig_filt_type = -1;
++
++	return true;
++}
++
++void wlc_2064_vco_cal(struct brcms_phy *pi)
++{
++	u8 calnrst;
++
++	mod_radio_reg(pi, RADIO_2064_REG057, 1 << 3, 1 << 3);
++	calnrst = (u8) read_radio_reg(pi, RADIO_2064_REG056) & 0xf8;
++	write_radio_reg(pi, RADIO_2064_REG056, calnrst);
++	udelay(1);
++	write_radio_reg(pi, RADIO_2064_REG056, calnrst | 0x03);
++	udelay(1);
++	write_radio_reg(pi, RADIO_2064_REG056, calnrst | 0x07);
++	udelay(300);
++	mod_radio_reg(pi, RADIO_2064_REG057, 1 << 3, 0);
++}
++
++bool wlc_phy_tpc_isenabled_lcnphy(struct brcms_phy *pi)
++{
++	if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi))
++		return 0;
++	else
++		return (LCNPHY_TX_PWR_CTRL_HW ==
++			wlc_lcnphy_get_tx_pwr_ctrl((pi)));
++}
++
++void wlc_phy_txpower_recalc_target_lcnphy(struct brcms_phy *pi)
++{
++	u16 pwr_ctrl;
++	if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) {
++		wlc_lcnphy_calib_modes(pi, LCNPHY_PERICAL_TEMPBASED_TXPWRCTRL);
++	} else if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi)) {
++		pwr_ctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
++		wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
++		wlc_lcnphy_txpower_recalc_target(pi);
++		wlc_lcnphy_set_tx_pwr_ctrl(pi, pwr_ctrl);
++	}
++}
++
++void wlc_phy_detach_lcnphy(struct brcms_phy *pi)
++{
++	kfree(pi->u.pi_lcnphy);
++}
++
++bool wlc_phy_attach_lcnphy(struct brcms_phy *pi)
++{
++	struct brcms_phy_lcnphy *pi_lcn;
++
++	pi->u.pi_lcnphy = kzalloc(sizeof(struct brcms_phy_lcnphy), GFP_ATOMIC);
++	if (pi->u.pi_lcnphy == NULL)
++		return false;
++
++	pi_lcn = pi->u.pi_lcnphy;
++
++	if (0 == (pi->sh->boardflags & BFL_NOPA)) {
++		pi->hwpwrctrl = true;
++		pi->hwpwrctrl_capable = true;
++	}
++
++	pi->xtalfreq = si_pmu_alp_clock(pi->sh->sih);
++	pi_lcn->lcnphy_papd_rxGnCtrl_init = 0;
++
++	pi->pi_fptr.init = wlc_phy_init_lcnphy;
++	pi->pi_fptr.calinit = wlc_phy_cal_init_lcnphy;
++	pi->pi_fptr.chanset = wlc_phy_chanspec_set_lcnphy;
++	pi->pi_fptr.txpwrrecalc = wlc_phy_txpower_recalc_target_lcnphy;
++	pi->pi_fptr.txiqccget = wlc_lcnphy_get_tx_iqcc;
++	pi->pi_fptr.txiqccset = wlc_lcnphy_set_tx_iqcc;
++	pi->pi_fptr.txloccget = wlc_lcnphy_get_tx_locc;
++	pi->pi_fptr.radioloftget = wlc_lcnphy_get_radio_loft;
++	pi->pi_fptr.detach = wlc_phy_detach_lcnphy;
++
++	if (!wlc_phy_txpwr_srom_read_lcnphy(pi))
++		return false;
++
++	if ((pi->sh->boardflags & BFL_FEM) &&
++	    (LCNREV_IS(pi->pubpi.phy_rev, 1))) {
++		if (pi_lcn->lcnphy_tempsense_option == 3) {
++			pi->hwpwrctrl = true;
++			pi->hwpwrctrl_capable = true;
++			pi->temppwrctrl_capable = false;
++		} else {
++			pi->hwpwrctrl = false;
++			pi->hwpwrctrl_capable = false;
++			pi->temppwrctrl_capable = true;
++		}
++	}
++
++	return true;
++}
++
++static void wlc_lcnphy_set_rx_gain(struct brcms_phy *pi, u32 gain)
++{
++	u16 trsw, ext_lna, lna1, lna2, tia, biq0, biq1, gain0_15, gain16_19;
++
++	trsw = (gain & ((u32) 1 << 28)) ? 0 : 1;
++	ext_lna = (u16) (gain >> 29) & 0x01;
++	lna1 = (u16) (gain >> 0) & 0x0f;
++	lna2 = (u16) (gain >> 4) & 0x0f;
++	tia = (u16) (gain >> 8) & 0xf;
++	biq0 = (u16) (gain >> 12) & 0xf;
++	biq1 = (u16) (gain >> 16) & 0xf;
++
++	gain0_15 = (u16) ((lna1 & 0x3) | ((lna1 & 0x3) << 2) |
++			  ((lna2 & 0x3) << 4) | ((lna2 & 0x3) << 6) |
++			  ((tia & 0xf) << 8) | ((biq0 & 0xf) << 12));
++	gain16_19 = biq1;
++
++	mod_phy_reg(pi, 0x44d, (0x1 << 0), trsw << 0);
++	mod_phy_reg(pi, 0x4b1, (0x1 << 9), ext_lna << 9);
++	mod_phy_reg(pi, 0x4b1, (0x1 << 10), ext_lna << 10);
++	mod_phy_reg(pi, 0x4b6, (0xffff << 0), gain0_15 << 0);
++	mod_phy_reg(pi, 0x4b7, (0xf << 0), gain16_19 << 0);
++
++	if (CHSPEC_IS2G(pi->radio_chanspec)) {
++		mod_phy_reg(pi, 0x4b1, (0x3 << 11), lna1 << 11);
++		mod_phy_reg(pi, 0x4e6, (0x3 << 3), lna1 << 3);
++	}
++	wlc_lcnphy_rx_gain_override_enable(pi, true);
++}
++
++static u32 wlc_lcnphy_get_receive_power(struct brcms_phy *pi, s32 *gain_index)
++{
++	u32 received_power = 0;
++	s32 max_index = 0;
++	u32 gain_code = 0;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	max_index = 36;
++	if (*gain_index >= 0)
++		gain_code = lcnphy_23bitgaincode_table[*gain_index];
++
++	if (-1 == *gain_index) {
++		*gain_index = 0;
++		while ((*gain_index <= (s32) max_index)
++		       && (received_power < 700)) {
++			wlc_lcnphy_set_rx_gain(pi,
++					       lcnphy_23bitgaincode_table
++					       [*gain_index]);
++			received_power =
++				wlc_lcnphy_measure_digital_power(
++					pi,
++					pi_lcn->
++					lcnphy_noise_samples);
++			(*gain_index)++;
++		}
++		(*gain_index)--;
++	} else {
++		wlc_lcnphy_set_rx_gain(pi, gain_code);
++		received_power =
++			wlc_lcnphy_measure_digital_power(pi,
++							 pi_lcn->
++							 lcnphy_noise_samples);
++	}
++
++	return received_power;
++}
++
++s32 wlc_lcnphy_rx_signal_power(struct brcms_phy *pi, s32 gain_index)
++{
++	s32 gain = 0;
++	s32 nominal_power_db;
++	s32 log_val, gain_mismatch, desired_gain, input_power_offset_db,
++	    input_power_db;
++	s32 received_power, temperature;
++	u32 power;
++	u32 msb1, msb2, val1, val2, diff1, diff2;
++	uint freq;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	received_power = wlc_lcnphy_get_receive_power(pi, &gain_index);
++
++	gain = lcnphy_gain_table[gain_index];
++
++	nominal_power_db = read_phy_reg(pi, 0x425) >> 8;
++
++	power = (received_power * 16);
++	msb1 = ffs(power) - 1;
++	msb2 = msb1 + 1;
++	val1 = 1 << msb1;
++	val2 = 1 << msb2;
++	diff1 = (power - val1);
++	diff2 = (val2 - power);
++	if (diff1 < diff2)
++		log_val = msb1;
++	else
++		log_val = msb2;
++
++	log_val = log_val * 3;
++
++	gain_mismatch = (nominal_power_db / 2) - (log_val);
++
++	desired_gain = gain + gain_mismatch;
++
++	input_power_offset_db = read_phy_reg(pi, 0x434) & 0xFF;
++
++	if (input_power_offset_db > 127)
++		input_power_offset_db -= 256;
++
++	input_power_db = input_power_offset_db - desired_gain;
++
++	input_power_db =
++		input_power_db + lcnphy_gain_index_offset_for_rssi[gain_index];
++
++	freq = wlc_phy_channel2freq(CHSPEC_CHANNEL(pi->radio_chanspec));
++	if ((freq > 2427) && (freq <= 2467))
++		input_power_db = input_power_db - 1;
++
++	temperature = pi_lcn->lcnphy_lastsensed_temperature;
++
++	if ((temperature - 15) < -30)
++		input_power_db =
++			input_power_db +
++			(((temperature - 10 - 25) * 286) >> 12) -
++			7;
++	else if ((temperature - 15) < 4)
++		input_power_db =
++			input_power_db +
++			(((temperature - 10 - 25) * 286) >> 12) -
++			3;
++	else
++		input_power_db = input_power_db +
++					(((temperature - 10 - 25) * 286) >> 12);
++
++	wlc_lcnphy_rx_gain_override_enable(pi, 0);
++
++	return input_power_db;
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.h b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.h
+new file mode 100644
+index 0000000..f4a8ab0
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.h
+@@ -0,0 +1,121 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef _BRCM_PHY_LCN_H_
++#define _BRCM_PHY_LCN_H_
++
++#include <types.h>
++
++struct brcms_phy_lcnphy {
++	int lcnphy_txrf_sp_9_override;
++	u8 lcnphy_full_cal_channel;
++	u8 lcnphy_cal_counter;
++	u16 lcnphy_cal_temper;
++	bool lcnphy_recal;
++
++	u8 lcnphy_rc_cap;
++	u32 lcnphy_mcs20_po;
++
++	u8 lcnphy_tr_isolation_mid;
++	u8 lcnphy_tr_isolation_low;
++	u8 lcnphy_tr_isolation_hi;
++
++	u8 lcnphy_bx_arch;
++	u8 lcnphy_rx_power_offset;
++	u8 lcnphy_rssi_vf;
++	u8 lcnphy_rssi_vc;
++	u8 lcnphy_rssi_gs;
++	u8 lcnphy_tssi_val;
++	u8 lcnphy_rssi_vf_lowtemp;
++	u8 lcnphy_rssi_vc_lowtemp;
++	u8 lcnphy_rssi_gs_lowtemp;
++
++	u8 lcnphy_rssi_vf_hightemp;
++	u8 lcnphy_rssi_vc_hightemp;
++	u8 lcnphy_rssi_gs_hightemp;
++
++	s16 lcnphy_pa0b0;
++	s16 lcnphy_pa0b1;
++	s16 lcnphy_pa0b2;
++
++	u16 lcnphy_rawtempsense;
++	u8 lcnphy_measPower;
++	u8 lcnphy_tempsense_slope;
++	u8 lcnphy_freqoffset_corr;
++	u8 lcnphy_tempsense_option;
++	u8 lcnphy_tempcorrx;
++	bool lcnphy_iqcal_swp_dis;
++	bool lcnphy_hw_iqcal_en;
++	uint lcnphy_bandedge_corr;
++	bool lcnphy_spurmod;
++	u16 lcnphy_tssi_tx_cnt;
++	u16 lcnphy_tssi_idx;
++	u16 lcnphy_tssi_npt;
++
++	u16 lcnphy_target_tx_freq;
++	s8 lcnphy_tx_power_idx_override;
++	u16 lcnphy_noise_samples;
++
++	u32 lcnphy_papdRxGnIdx;
++	u32 lcnphy_papd_rxGnCtrl_init;
++
++	u32 lcnphy_gain_idx_14_lowword;
++	u32 lcnphy_gain_idx_14_hiword;
++	u32 lcnphy_gain_idx_27_lowword;
++	u32 lcnphy_gain_idx_27_hiword;
++	s16 lcnphy_ofdmgainidxtableoffset;
++	s16 lcnphy_dsssgainidxtableoffset;
++	u32 lcnphy_tr_R_gain_val;
++	u32 lcnphy_tr_T_gain_val;
++	s8 lcnphy_input_pwr_offset_db;
++	u16 lcnphy_Med_Low_Gain_db;
++	u16 lcnphy_Very_Low_Gain_db;
++	s8 lcnphy_lastsensed_temperature;
++	s8 lcnphy_pkteng_rssi_slope;
++	u8 lcnphy_saved_tx_user_target[TXP_NUM_RATES];
++	u8 lcnphy_volt_winner;
++	u8 lcnphy_volt_low;
++	u8 lcnphy_54_48_36_24mbps_backoff;
++	u8 lcnphy_11n_backoff;
++	u8 lcnphy_lowerofdm;
++	u8 lcnphy_cck;
++	u8 lcnphy_psat_2pt3_detected;
++	s32 lcnphy_lowest_Re_div_Im;
++	s8 lcnphy_final_papd_cal_idx;
++	u16 lcnphy_extstxctrl4;
++	u16 lcnphy_extstxctrl0;
++	u16 lcnphy_extstxctrl1;
++	s16 lcnphy_cck_dig_filt_type;
++	s16 lcnphy_ofdm_dig_filt_type;
++	struct lcnphy_cal_results lcnphy_cal_results;
++
++	u8 lcnphy_psat_pwr;
++	u8 lcnphy_psat_indx;
++	s32 lcnphy_min_phase;
++	u8 lcnphy_final_idx;
++	u8 lcnphy_start_idx;
++	u8 lcnphy_current_index;
++	u16 lcnphy_logen_buf_1;
++	u16 lcnphy_local_ovr_2;
++	u16 lcnphy_local_oval_6;
++	u16 lcnphy_local_oval_5;
++	u16 lcnphy_logen_mixer_1;
++
++	u8 lcnphy_aci_stat;
++	uint lcnphy_aci_start_time;
++	s8 lcnphy_tx_power_offset[TXP_NUM_RATES];
++};
++#endif				/* _BRCM_PHY_LCN_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c
+new file mode 100644
+index 0000000..06975af
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c
+@@ -0,0 +1,28685 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#undef pr_fmt
++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
++
++#include <linux/kernel.h>
++#include <linux/printk.h>
++#include <linux/delay.h>
++#include <linux/cordic.h>
++
++#include <brcm_hw_ids.h>
++#include <aiutils.h>
++#include <chipcommon.h>
++#include <pmu.h>
++#include <d11.h>
++#include <phy_shim.h>
++#include "phy_int.h"
++#include "phy_hal.h"
++#include "phy_radio.h"
++#include "phyreg_n.h"
++#include "phytbl_n.h"
++#include "soc.h"
++
++#define READ_RADIO_REG2(pi, radio_type, jspace, core, reg_name)	\
++	read_radio_reg(pi, radio_type##_##jspace##_##reg_name |	\
++		       ((core == PHY_CORE_0) ? \
++			radio_type##_##jspace##0 : \
++			radio_type##_##jspace##1))
++
++#define WRITE_RADIO_REG2(pi, radio_type, jspace, core, reg_name, value)	\
++	write_radio_reg(pi, radio_type##_##jspace##_##reg_name | \
++			((core ==  PHY_CORE_0) ? \
++			 radio_type##_##jspace##0 : \
++			 radio_type##_##jspace##1), value)
++
++#define WRITE_RADIO_SYN(pi, radio_type, reg_name, value) \
++	write_radio_reg(pi, radio_type##_##SYN##_##reg_name, value)
++
++#define READ_RADIO_REG3(pi, radio_type, jspace, core, reg_name)	\
++	read_radio_reg(pi, ((core == PHY_CORE_0) ? \
++			    radio_type##_##jspace##0##_##reg_name : \
++			    radio_type##_##jspace##1##_##reg_name))
++
++#define WRITE_RADIO_REG3(pi, radio_type, jspace, core, reg_name, value)	\
++	write_radio_reg(pi, ((core ==  PHY_CORE_0) ? \
++			     radio_type##_##jspace##0##_##reg_name : \
++			     radio_type##_##jspace##1##_##reg_name), \
++			value)
++
++#define READ_RADIO_REG4(pi, radio_type, jspace, core, reg_name)	\
++	read_radio_reg(pi, ((core == PHY_CORE_0) ? \
++			     radio_type##_##reg_name##_##jspace##0 : \
++			     radio_type##_##reg_name##_##jspace##1))
++
++#define WRITE_RADIO_REG4(pi, radio_type, jspace, core, reg_name, value)	\
++	write_radio_reg(pi, ((core == PHY_CORE_0) ? \
++			radio_type##_##reg_name##_##jspace##0 : \
++			radio_type##_##reg_name##_##jspace##1), \
++			value)
++
++#define NPHY_ACI_MAX_UNDETECT_WINDOW_SZ 40
++#define NPHY_ACI_CHANNEL_DELTA 5
++#define NPHY_ACI_CHANNEL_SKIP 4
++#define NPHY_ACI_40MHZ_CHANNEL_DELTA 6
++#define NPHY_ACI_40MHZ_CHANNEL_SKIP 5
++#define NPHY_ACI_40MHZ_CHANNEL_DELTA_GE_REV3 6
++#define NPHY_ACI_40MHZ_CHANNEL_SKIP_GE_REV3 5
++#define NPHY_ACI_CHANNEL_DELTA_GE_REV3 4
++#define NPHY_ACI_CHANNEL_SKIP_GE_REV3 3
++
++#define NPHY_NOISE_NOASSOC_GLITCH_TH_UP 2
++
++#define NPHY_NOISE_NOASSOC_GLITCH_TH_DN 8
++
++#define NPHY_NOISE_ASSOC_GLITCH_TH_UP 2
++
++#define NPHY_NOISE_ASSOC_GLITCH_TH_DN 8
++
++#define NPHY_NOISE_ASSOC_ACI_GLITCH_TH_UP 2
++
++#define NPHY_NOISE_ASSOC_ACI_GLITCH_TH_DN 8
++
++#define NPHY_NOISE_NOASSOC_ENTER_TH  400
++
++#define NPHY_NOISE_ASSOC_ENTER_TH  400
++
++#define NPHY_NOISE_ASSOC_RX_GLITCH_BADPLCP_ENTER_TH  400
++
++#define NPHY_NOISE_CRSMINPWR_ARRAY_MAX_INDEX 44
++#define NPHY_NOISE_CRSMINPWR_ARRAY_MAX_INDEX_REV_7 56
++
++#define NPHY_NOISE_NOASSOC_CRSIDX_INCR 16
++
++#define NPHY_NOISE_ASSOC_CRSIDX_INCR 8
++
++#define NPHY_IS_SROM_REINTERPRET NREV_GE(pi->pubpi.phy_rev, 5)
++
++#define NPHY_RSSICAL_MAXREAD 31
++
++#define NPHY_RSSICAL_NPOLL 8
++#define NPHY_RSSICAL_MAXD  (1<<20)
++#define NPHY_MIN_RXIQ_PWR 2
++
++#define NPHY_RSSICAL_W1_TARGET 25
++#define NPHY_RSSICAL_W2_TARGET NPHY_RSSICAL_W1_TARGET
++#define NPHY_RSSICAL_NB_TARGET 0
++
++#define NPHY_RSSICAL_W1_TARGET_REV3 29
++#define NPHY_RSSICAL_W2_TARGET_REV3 NPHY_RSSICAL_W1_TARGET_REV3
++
++#define NPHY_CALSANITY_RSSI_NB_MAX_POS  9
++#define NPHY_CALSANITY_RSSI_NB_MAX_NEG -9
++#define NPHY_CALSANITY_RSSI_W1_MAX_POS  12
++#define NPHY_CALSANITY_RSSI_W1_MAX_NEG (NPHY_RSSICAL_W1_TARGET - \
++					NPHY_RSSICAL_MAXREAD)
++#define NPHY_CALSANITY_RSSI_W2_MAX_POS  NPHY_CALSANITY_RSSI_W1_MAX_POS
++#define NPHY_CALSANITY_RSSI_W2_MAX_NEG (NPHY_RSSICAL_W2_TARGET - \
++					NPHY_RSSICAL_MAXREAD)
++#define NPHY_RSSI_SXT(x) ((s8) (-((x) & 0x20) + ((x) & 0x1f)))
++#define NPHY_RSSI_NB_VIOL(x)  (((x) > NPHY_CALSANITY_RSSI_NB_MAX_POS) || \
++			       ((x) < NPHY_CALSANITY_RSSI_NB_MAX_NEG))
++#define NPHY_RSSI_W1_VIOL(x)  (((x) > NPHY_CALSANITY_RSSI_W1_MAX_POS) || \
++			       ((x) < NPHY_CALSANITY_RSSI_W1_MAX_NEG))
++#define NPHY_RSSI_W2_VIOL(x)  (((x) > NPHY_CALSANITY_RSSI_W2_MAX_POS) || \
++			       ((x) < NPHY_CALSANITY_RSSI_W2_MAX_NEG))
++
++#define NPHY_IQCAL_NUMGAINS 9
++#define NPHY_N_GCTL 0x66
++
++#define NPHY_PAPD_EPS_TBL_SIZE 64
++#define NPHY_PAPD_SCL_TBL_SIZE 64
++#define NPHY_NUM_DIG_FILT_COEFFS 15
++
++#define NPHY_PAPD_COMP_OFF 0
++#define NPHY_PAPD_COMP_ON  1
++
++#define NPHY_SROM_TEMPSHIFT             32
++#define NPHY_SROM_MAXTEMPOFFSET         16
++#define NPHY_SROM_MINTEMPOFFSET         -16
++
++#define NPHY_CAL_MAXTEMPDELTA           64
++
++#define NPHY_NOISEVAR_TBLLEN40 256
++#define NPHY_NOISEVAR_TBLLEN20 128
++
++#define NPHY_ANARXLPFBW_REDUCTIONFACT 7
++
++#define NPHY_ADJUSTED_MINCRSPOWER 0x1e
++
++/* 5357 Chip specific ChipControl register bits */
++#define CCTRL5357_EXTPA            (1<<14) /* extPA in ChipControl 1, bit 14 */
++#define CCTRL5357_ANT_MUX_2o3      (1<<15) /* 2o3 in ChipControl 1, bit 15 */
++
++#define NPHY_CAL_TSSISAMPS      64
++#define NPHY_TEST_TONE_FREQ_40MHz 4000
++#define NPHY_TEST_TONE_FREQ_20MHz 2500
++
++#define MAX_205x_RCAL_WAITLOOPS 10000
++
++#define NPHY_RXCAL_TONEAMP 181
++#define NPHY_RXCAL_TONEFREQ_40MHz 4000
++#define NPHY_RXCAL_TONEFREQ_20MHz 2000
++
++#define TXFILT_SHAPING_OFDM20   0
++#define TXFILT_SHAPING_OFDM40   1
++#define TXFILT_SHAPING_CCK      2
++#define TXFILT_DEFAULT_OFDM20   3
++#define TXFILT_DEFAULT_OFDM40   4
++
++struct nphy_iqcal_params {
++	u16 txlpf;
++	u16 txgm;
++	u16 pga;
++	u16 pad;
++	u16 ipa;
++	u16 cal_gain;
++	u16 ncorr[5];
++};
++
++struct nphy_txiqcal_ladder {
++	u8 percent;
++	u8 g_env;
++};
++
++struct nphy_ipa_txcalgains {
++	struct nphy_txgains gains;
++	bool useindex;
++	u8 index;
++};
++
++struct nphy_papd_restore_state {
++	u16 fbmix[2];
++	u16 vga_master[2];
++	u16 intpa_master[2];
++	u16 afectrl[2];
++	u16 afeoverride[2];
++	u16 pwrup[2];
++	u16 atten[2];
++	u16 mm;
++};
++
++struct nphy_ipa_txrxgain {
++	u16 hpvga;
++	u16 lpf_biq1;
++	u16 lpf_biq0;
++	u16 lna2;
++	u16 lna1;
++	s8 txpwrindex;
++};
++
++#define NPHY_IPA_RXCAL_MAXGAININDEX (6 - 1)
++
++static const struct nphy_ipa_txrxgain nphy_ipa_rxcal_gaintbl_5GHz[] = {
++	{0, 0, 0, 0, 0, 100},
++	{0, 0, 0, 0, 0, 50},
++	{0, 0, 0, 0, 0, -1},
++	{0, 0, 0, 3, 0, -1},
++	{0, 0, 3, 3, 0, -1},
++	{0, 2, 3, 3, 0, -1}
++};
++
++static const struct nphy_ipa_txrxgain nphy_ipa_rxcal_gaintbl_2GHz[] = {
++	{0, 0, 0, 0, 0, 128},
++	{0, 0, 0, 0, 0, 70},
++	{0, 0, 0, 0, 0, 20},
++	{0, 0, 0, 3, 0, 20},
++	{0, 0, 3, 3, 0, 20},
++	{0, 2, 3, 3, 0, 20}
++};
++
++static const struct nphy_ipa_txrxgain nphy_ipa_rxcal_gaintbl_5GHz_rev7[] = {
++	{0, 0, 0, 0, 0, 100},
++	{0, 0, 0, 0, 0, 50},
++	{0, 0, 0, 0, 0, -1},
++	{0, 0, 0, 3, 0, -1},
++	{0, 0, 3, 3, 0, -1},
++	{0, 0, 5, 3, 0, -1}
++};
++
++static const struct nphy_ipa_txrxgain nphy_ipa_rxcal_gaintbl_2GHz_rev7[] = {
++	{0, 0, 0, 0, 0, 10},
++	{0, 0, 0, 1, 0, 10},
++	{0, 0, 1, 2, 0, 10},
++	{0, 0, 1, 3, 0, 10},
++	{0, 0, 4, 3, 0, 10},
++	{0, 0, 6, 3, 0, 10}
++};
++
++enum {
++	NPHY_RXCAL_GAIN_INIT = 0,
++	NPHY_RXCAL_GAIN_UP,
++	NPHY_RXCAL_GAIN_DOWN
++};
++
++#define wlc_phy_get_papd_nphy(pi) \
++	(read_phy_reg((pi), 0x1e7) & \
++	 ((0x1 << 15) |	\
++	  (0x1 << 14) |	\
++	  (0x1 << 13)))
++
++static const u16 NPHY_IPA_REV4_txdigi_filtcoeffs[][NPHY_NUM_DIG_FILT_COEFFS] = {
++	{-377, 137, -407, 208, -1527, 956, 93, 186, 93,
++	 230, -44, 230, 201, -191, 201},
++	{-77, 20, -98, 49, -93, 60, 56, 111, 56, 26, -5,
++	 26, 34, -32, 34},
++	{-360, 164, -376, 164, -1533, 576, 308, -314, 308,
++	 121, -73, 121, 91, 124, 91},
++	{-295, 200, -363, 142, -1391, 826, 151, 301, 151,
++	 151, 301, 151, 602, -752, 602},
++	{-92, 58, -96, 49, -104, 44, 17, 35, 17,
++	 12, 25, 12, 13, 27, 13},
++	{-375, 136, -399, 209, -1479, 949, 130, 260, 130,
++	 230, -44, 230, 201, -191, 201},
++	{0xed9, 0xc8, 0xe95, 0x8e, 0xa91, 0x33a, 0x97, 0x12d, 0x97,
++	 0x97, 0x12d, 0x97, 0x25a, 0xd10, 0x25a}
++};
++
++struct chan_info_nphy_2055 {
++	u16 chan;
++	u16 freq;
++	uint unknown;
++	u8 RF_pll_ref;
++	u8 RF_rf_pll_mod1;
++	u8 RF_rf_pll_mod0;
++	u8 RF_vco_cap_tail;
++	u8 RF_vco_cal1;
++	u8 RF_vco_cal2;
++	u8 RF_pll_lf_c1;
++	u8 RF_pll_lf_r1;
++	u8 RF_pll_lf_c2;
++	u8 RF_lgbuf_cen_buf;
++	u8 RF_lgen_tune1;
++	u8 RF_lgen_tune2;
++	u8 RF_core1_lgbuf_a_tune;
++	u8 RF_core1_lgbuf_g_tune;
++	u8 RF_core1_rxrf_reg1;
++	u8 RF_core1_tx_pga_pad_tn;
++	u8 RF_core1_tx_mx_bgtrim;
++	u8 RF_core2_lgbuf_a_tune;
++	u8 RF_core2_lgbuf_g_tune;
++	u8 RF_core2_rxrf_reg1;
++	u8 RF_core2_tx_pga_pad_tn;
++	u8 RF_core2_tx_mx_bgtrim;
++	u16 PHY_BW1a;
++	u16 PHY_BW2;
++	u16 PHY_BW3;
++	u16 PHY_BW4;
++	u16 PHY_BW5;
++	u16 PHY_BW6;
++};
++
++struct chan_info_nphy_radio205x {
++	u16 chan;
++	u16 freq;
++	u8 RF_SYN_pll_vcocal1;
++	u8 RF_SYN_pll_vcocal2;
++	u8 RF_SYN_pll_refdiv;
++	u8 RF_SYN_pll_mmd2;
++	u8 RF_SYN_pll_mmd1;
++	u8 RF_SYN_pll_loopfilter1;
++	u8 RF_SYN_pll_loopfilter2;
++	u8 RF_SYN_pll_loopfilter3;
++	u8 RF_SYN_pll_loopfilter4;
++	u8 RF_SYN_pll_loopfilter5;
++	u8 RF_SYN_reserved_addr27;
++	u8 RF_SYN_reserved_addr28;
++	u8 RF_SYN_reserved_addr29;
++	u8 RF_SYN_logen_VCOBUF1;
++	u8 RF_SYN_logen_MIXER2;
++	u8 RF_SYN_logen_BUF3;
++	u8 RF_SYN_logen_BUF4;
++	u8 RF_RX0_lnaa_tune;
++	u8 RF_RX0_lnag_tune;
++	u8 RF_TX0_intpaa_boost_tune;
++	u8 RF_TX0_intpag_boost_tune;
++	u8 RF_TX0_pada_boost_tune;
++	u8 RF_TX0_padg_boost_tune;
++	u8 RF_TX0_pgaa_boost_tune;
++	u8 RF_TX0_pgag_boost_tune;
++	u8 RF_TX0_mixa_boost_tune;
++	u8 RF_TX0_mixg_boost_tune;
++	u8 RF_RX1_lnaa_tune;
++	u8 RF_RX1_lnag_tune;
++	u8 RF_TX1_intpaa_boost_tune;
++	u8 RF_TX1_intpag_boost_tune;
++	u8 RF_TX1_pada_boost_tune;
++	u8 RF_TX1_padg_boost_tune;
++	u8 RF_TX1_pgaa_boost_tune;
++	u8 RF_TX1_pgag_boost_tune;
++	u8 RF_TX1_mixa_boost_tune;
++	u8 RF_TX1_mixg_boost_tune;
++	u16 PHY_BW1a;
++	u16 PHY_BW2;
++	u16 PHY_BW3;
++	u16 PHY_BW4;
++	u16 PHY_BW5;
++	u16 PHY_BW6;
++};
++
++struct chan_info_nphy_radio2057 {
++	u16 chan;
++	u16 freq;
++	u8 RF_vcocal_countval0;
++	u8 RF_vcocal_countval1;
++	u8 RF_rfpll_refmaster_sparextalsize;
++	u8 RF_rfpll_loopfilter_r1;
++	u8 RF_rfpll_loopfilter_c2;
++	u8 RF_rfpll_loopfilter_c1;
++	u8 RF_cp_kpd_idac;
++	u8 RF_rfpll_mmd0;
++	u8 RF_rfpll_mmd1;
++	u8 RF_vcobuf_tune;
++	u8 RF_logen_mx2g_tune;
++	u8 RF_logen_mx5g_tune;
++	u8 RF_logen_indbuf2g_tune;
++	u8 RF_logen_indbuf5g_tune;
++	u8 RF_txmix2g_tune_boost_pu_core0;
++	u8 RF_pad2g_tune_pus_core0;
++	u8 RF_pga_boost_tune_core0;
++	u8 RF_txmix5g_boost_tune_core0;
++	u8 RF_pad5g_tune_misc_pus_core0;
++	u8 RF_lna2g_tune_core0;
++	u8 RF_lna5g_tune_core0;
++	u8 RF_txmix2g_tune_boost_pu_core1;
++	u8 RF_pad2g_tune_pus_core1;
++	u8 RF_pga_boost_tune_core1;
++	u8 RF_txmix5g_boost_tune_core1;
++	u8 RF_pad5g_tune_misc_pus_core1;
++	u8 RF_lna2g_tune_core1;
++	u8 RF_lna5g_tune_core1;
++	u16 PHY_BW1a;
++	u16 PHY_BW2;
++	u16 PHY_BW3;
++	u16 PHY_BW4;
++	u16 PHY_BW5;
++	u16 PHY_BW6;
++};
++
++struct chan_info_nphy_radio2057_rev5 {
++	u16 chan;
++	u16 freq;
++	u8 RF_vcocal_countval0;
++	u8 RF_vcocal_countval1;
++	u8 RF_rfpll_refmaster_sparextalsize;
++	u8 RF_rfpll_loopfilter_r1;
++	u8 RF_rfpll_loopfilter_c2;
++	u8 RF_rfpll_loopfilter_c1;
++	u8 RF_cp_kpd_idac;
++	u8 RF_rfpll_mmd0;
++	u8 RF_rfpll_mmd1;
++	u8 RF_vcobuf_tune;
++	u8 RF_logen_mx2g_tune;
++	u8 RF_logen_indbuf2g_tune;
++	u8 RF_txmix2g_tune_boost_pu_core0;
++	u8 RF_pad2g_tune_pus_core0;
++	u8 RF_lna2g_tune_core0;
++	u8 RF_txmix2g_tune_boost_pu_core1;
++	u8 RF_pad2g_tune_pus_core1;
++	u8 RF_lna2g_tune_core1;
++	u16 PHY_BW1a;
++	u16 PHY_BW2;
++	u16 PHY_BW3;
++	u16 PHY_BW4;
++	u16 PHY_BW5;
++	u16 PHY_BW6;
++};
++
++struct nphy_sfo_cfg {
++	u16 PHY_BW1a;
++	u16 PHY_BW2;
++	u16 PHY_BW3;
++	u16 PHY_BW4;
++	u16 PHY_BW5;
++	u16 PHY_BW6;
++};
++
++static const struct chan_info_nphy_2055 chan_info_nphy_2055[] = {
++	{
++	 184, 4920, 3280, 0x71, 0x01, 0xEC, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
++	 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
++	 0x0F, 0x8F, 0x7B4, 0x7B0, 0x7AC, 0x214, 0x215, 0x216},
++	{
++	 186, 4930, 3287, 0x71, 0x01, 0xED, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
++	 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
++	 0x0F, 0x8F, 0x7B8, 0x7B4, 0x7B0, 0x213, 0x214, 0x215},
++	{
++	 188, 4940, 3293, 0x71, 0x01, 0xEE, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
++	 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
++	 0x0F, 0x8F, 0x7BC, 0x7B8, 0x7B4, 0x212, 0x213, 0x214},
++	{
++	 190, 4950, 3300, 0x71, 0x01, 0xEF, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
++	 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
++	 0x0F, 0x8F, 0x7C0, 0x7BC, 0x7B8, 0x211, 0x212, 0x213},
++	{
++	 192, 4960, 3307, 0x71, 0x01, 0xF0, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
++	 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
++	 0x0F, 0x8F, 0x7C4, 0x7C0, 0x7BC, 0x20F, 0x211, 0x212},
++	{
++	 194, 4970, 3313, 0x71, 0x01, 0xF1, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
++	 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
++	 0x0F, 0x8F, 0x7C8, 0x7C4, 0x7C0, 0x20E, 0x20F, 0x211},
++	{
++	 196, 4980, 3320, 0x71, 0x01, 0xF2, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
++	 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
++	 0x0F, 0x8F, 0x7CC, 0x7C8, 0x7C4, 0x20D, 0x20E, 0x20F},
++	{
++	 198, 4990, 3327, 0x71, 0x01, 0xF3, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
++	 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
++	 0x0F, 0x8F, 0x7D0, 0x7CC, 0x7C8, 0x20C, 0x20D, 0x20E},
++	{
++	 200, 5000, 3333, 0x71, 0x01, 0xF4, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
++	 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
++	 0x0F, 0x8F, 0x7D4, 0x7D0, 0x7CC, 0x20B, 0x20C, 0x20D},
++	{
++	 202, 5010, 3340, 0x71, 0x01, 0xF5, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
++	 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
++	 0x0F, 0x8F, 0x7D8, 0x7D4, 0x7D0, 0x20A, 0x20B, 0x20C},
++	{
++	 204, 5020, 3347, 0x71, 0x01, 0xF6, 0x0E, 0xF7, 0x01, 0x04, 0x0A,
++	 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
++	 0x0F, 0x8F, 0x7DC, 0x7D8, 0x7D4, 0x209, 0x20A, 0x20B},
++	{
++	 206, 5030, 3353, 0x71, 0x01, 0xF7, 0x0E, 0xF7, 0x01, 0x04, 0x0A,
++	 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
++	 0x0F, 0x8F, 0x7E0, 0x7DC, 0x7D8, 0x208, 0x209, 0x20A},
++	{
++	 208, 5040, 3360, 0x71, 0x01, 0xF8, 0x0D, 0xEF, 0x01, 0x04, 0x0A,
++	 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
++	 0x0F, 0x8F, 0x7E4, 0x7E0, 0x7DC, 0x207, 0x208, 0x209},
++	{
++	 210, 5050, 3367, 0x71, 0x01, 0xF9, 0x0D, 0xEF, 0x01, 0x04, 0x0A,
++	 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
++	 0x0F, 0x8F, 0x7E8, 0x7E4, 0x7E0, 0x206, 0x207, 0x208},
++	{
++	 212, 5060, 3373, 0x71, 0x01, 0xFA, 0x0D, 0xE6, 0x01, 0x04, 0x0A,
++	 0x00, 0x8F, 0xBB, 0xBB, 0xFF, 0x00, 0x0E, 0x0F, 0x8E, 0xFF, 0x00, 0x0E,
++	 0x0F, 0x8E, 0x7EC, 0x7E8, 0x7E4, 0x205, 0x206, 0x207},
++	{
++	 214, 5070, 3380, 0x71, 0x01, 0xFB, 0x0D, 0xE6, 0x01, 0x04, 0x0A,
++	 0x00, 0x8F, 0xBB, 0xBB, 0xFF, 0x00, 0x0E, 0x0F, 0x8E, 0xFF, 0x00, 0x0E,
++	 0x0F, 0x8E, 0x7F0, 0x7EC, 0x7E8, 0x204, 0x205, 0x206},
++	{
++	 216, 5080, 3387, 0x71, 0x01, 0xFC, 0x0D, 0xDE, 0x01, 0x04, 0x0A,
++	 0x00, 0x8E, 0xBB, 0xBB, 0xEE, 0x00, 0x0E, 0x0F, 0x8D, 0xEE, 0x00, 0x0E,
++	 0x0F, 0x8D, 0x7F4, 0x7F0, 0x7EC, 0x203, 0x204, 0x205},
++	{
++	 218, 5090, 3393, 0x71, 0x01, 0xFD, 0x0D, 0xDE, 0x01, 0x04, 0x0A,
++	 0x00, 0x8E, 0xBB, 0xBB, 0xEE, 0x00, 0x0E, 0x0F, 0x8D, 0xEE, 0x00, 0x0E,
++	 0x0F, 0x8D, 0x7F8, 0x7F4, 0x7F0, 0x202, 0x203, 0x204},
++	{
++	 220, 5100, 3400, 0x71, 0x01, 0xFE, 0x0C, 0xD6, 0x01, 0x04, 0x0A,
++	 0x00, 0x8E, 0xAA, 0xAA, 0xEE, 0x00, 0x0D, 0x0F, 0x8D, 0xEE, 0x00, 0x0D,
++	 0x0F, 0x8D, 0x7FC, 0x7F8, 0x7F4, 0x201, 0x202, 0x203},
++	{
++	 222, 5110, 3407, 0x71, 0x01, 0xFF, 0x0C, 0xD6, 0x01, 0x04, 0x0A,
++	 0x00, 0x8E, 0xAA, 0xAA, 0xEE, 0x00, 0x0D, 0x0F, 0x8D, 0xEE, 0x00, 0x0D,
++	 0x0F, 0x8D, 0x800, 0x7FC, 0x7F8, 0x200, 0x201, 0x202},
++	{
++	 224, 5120, 3413, 0x71, 0x02, 0x00, 0x0C, 0xCE, 0x01, 0x04, 0x0A,
++	 0x00, 0x8D, 0xAA, 0xAA, 0xDD, 0x00, 0x0D, 0x0F, 0x8C, 0xDD, 0x00, 0x0D,
++	 0x0F, 0x8C, 0x804, 0x800, 0x7FC, 0x1FF, 0x200, 0x201},
++	{
++	 226, 5130, 3420, 0x71, 0x02, 0x01, 0x0C, 0xCE, 0x01, 0x04, 0x0A,
++	 0x00, 0x8D, 0xAA, 0xAA, 0xDD, 0x00, 0x0D, 0x0F, 0x8C, 0xDD, 0x00, 0x0D,
++	 0x0F, 0x8C, 0x808, 0x804, 0x800, 0x1FE, 0x1FF, 0x200},
++	{
++	 228, 5140, 3427, 0x71, 0x02, 0x02, 0x0C, 0xC6, 0x01, 0x04, 0x0A,
++	 0x00, 0x8D, 0x99, 0x99, 0xDD, 0x00, 0x0C, 0x0E, 0x8B, 0xDD, 0x00, 0x0C,
++	 0x0E, 0x8B, 0x80C, 0x808, 0x804, 0x1FD, 0x1FE, 0x1FF},
++	{
++	 32, 5160, 3440, 0x71, 0x02, 0x04, 0x0B, 0xBE, 0x01, 0x04, 0x0A,
++	 0x00, 0x8C, 0x99, 0x99, 0xCC, 0x00, 0x0B, 0x0D, 0x8A, 0xCC, 0x00, 0x0B,
++	 0x0D, 0x8A, 0x814, 0x810, 0x80C, 0x1FB, 0x1FC, 0x1FD},
++	{
++	 34, 5170, 3447, 0x71, 0x02, 0x05, 0x0B, 0xBE, 0x01, 0x04, 0x0A,
++	 0x00, 0x8C, 0x99, 0x99, 0xCC, 0x00, 0x0B, 0x0D, 0x8A, 0xCC, 0x00, 0x0B,
++	 0x0D, 0x8A, 0x818, 0x814, 0x810, 0x1FA, 0x1FB, 0x1FC},
++	{
++	 36, 5180, 3453, 0x71, 0x02, 0x06, 0x0B, 0xB6, 0x01, 0x04, 0x0A,
++	 0x00, 0x8C, 0x88, 0x88, 0xCC, 0x00, 0x0B, 0x0C, 0x89, 0xCC, 0x00, 0x0B,
++	 0x0C, 0x89, 0x81C, 0x818, 0x814, 0x1F9, 0x1FA, 0x1FB},
++	{
++	 38, 5190, 3460, 0x71, 0x02, 0x07, 0x0B, 0xB6, 0x01, 0x04, 0x0A,
++	 0x00, 0x8C, 0x88, 0x88, 0xCC, 0x00, 0x0B, 0x0C, 0x89, 0xCC, 0x00, 0x0B,
++	 0x0C, 0x89, 0x820, 0x81C, 0x818, 0x1F8, 0x1F9, 0x1FA},
++	{
++	 40, 5200, 3467, 0x71, 0x02, 0x08, 0x0B, 0xAF, 0x01, 0x04, 0x0A,
++	 0x00, 0x8B, 0x88, 0x88, 0xBB, 0x00, 0x0A, 0x0B, 0x89, 0xBB, 0x00, 0x0A,
++	 0x0B, 0x89, 0x824, 0x820, 0x81C, 0x1F7, 0x1F8, 0x1F9},
++	{
++	 42, 5210, 3473, 0x71, 0x02, 0x09, 0x0B, 0xAF, 0x01, 0x04, 0x0A,
++	 0x00, 0x8B, 0x88, 0x88, 0xBB, 0x00, 0x0A, 0x0B, 0x89, 0xBB, 0x00, 0x0A,
++	 0x0B, 0x89, 0x828, 0x824, 0x820, 0x1F6, 0x1F7, 0x1F8},
++	{
++	 44, 5220, 3480, 0x71, 0x02, 0x0A, 0x0A, 0xA7, 0x01, 0x04, 0x0A,
++	 0x00, 0x8B, 0x77, 0x77, 0xBB, 0x00, 0x09, 0x0A, 0x88, 0xBB, 0x00, 0x09,
++	 0x0A, 0x88, 0x82C, 0x828, 0x824, 0x1F5, 0x1F6, 0x1F7},
++	{
++	 46, 5230, 3487, 0x71, 0x02, 0x0B, 0x0A, 0xA7, 0x01, 0x04, 0x0A,
++	 0x00, 0x8B, 0x77, 0x77, 0xBB, 0x00, 0x09, 0x0A, 0x88, 0xBB, 0x00, 0x09,
++	 0x0A, 0x88, 0x830, 0x82C, 0x828, 0x1F4, 0x1F5, 0x1F6},
++	{
++	 48, 5240, 3493, 0x71, 0x02, 0x0C, 0x0A, 0xA0, 0x01, 0x04, 0x0A,
++	 0x00, 0x8A, 0x77, 0x77, 0xAA, 0x00, 0x09, 0x0A, 0x87, 0xAA, 0x00, 0x09,
++	 0x0A, 0x87, 0x834, 0x830, 0x82C, 0x1F3, 0x1F4, 0x1F5},
++	{
++	 50, 5250, 3500, 0x71, 0x02, 0x0D, 0x0A, 0xA0, 0x01, 0x04, 0x0A,
++	 0x00, 0x8A, 0x77, 0x77, 0xAA, 0x00, 0x09, 0x0A, 0x87, 0xAA, 0x00, 0x09,
++	 0x0A, 0x87, 0x838, 0x834, 0x830, 0x1F2, 0x1F3, 0x1F4},
++	{
++	 52, 5260, 3507, 0x71, 0x02, 0x0E, 0x0A, 0x98, 0x01, 0x04, 0x0A,
++	 0x00, 0x8A, 0x66, 0x66, 0xAA, 0x00, 0x08, 0x09, 0x87, 0xAA, 0x00, 0x08,
++	 0x09, 0x87, 0x83C, 0x838, 0x834, 0x1F1, 0x1F2, 0x1F3},
++	{
++	 54, 5270, 3513, 0x71, 0x02, 0x0F, 0x0A, 0x98, 0x01, 0x04, 0x0A,
++	 0x00, 0x8A, 0x66, 0x66, 0xAA, 0x00, 0x08, 0x09, 0x87, 0xAA, 0x00, 0x08,
++	 0x09, 0x87, 0x840, 0x83C, 0x838, 0x1F0, 0x1F1, 0x1F2},
++	{
++	 56, 5280, 3520, 0x71, 0x02, 0x10, 0x09, 0x91, 0x01, 0x04, 0x0A,
++	 0x00, 0x89, 0x66, 0x66, 0x99, 0x00, 0x08, 0x08, 0x86, 0x99, 0x00, 0x08,
++	 0x08, 0x86, 0x844, 0x840, 0x83C, 0x1F0, 0x1F0, 0x1F1},
++	{
++	 58, 5290, 3527, 0x71, 0x02, 0x11, 0x09, 0x91, 0x01, 0x04, 0x0A,
++	 0x00, 0x89, 0x66, 0x66, 0x99, 0x00, 0x08, 0x08, 0x86, 0x99, 0x00, 0x08,
++	 0x08, 0x86, 0x848, 0x844, 0x840, 0x1EF, 0x1F0, 0x1F0},
++	{
++	 60, 5300, 3533, 0x71, 0x02, 0x12, 0x09, 0x8A, 0x01, 0x04, 0x0A,
++	 0x00, 0x89, 0x55, 0x55, 0x99, 0x00, 0x08, 0x07, 0x85, 0x99, 0x00, 0x08,
++	 0x07, 0x85, 0x84C, 0x848, 0x844, 0x1EE, 0x1EF, 0x1F0},
++	{
++	 62, 5310, 3540, 0x71, 0x02, 0x13, 0x09, 0x8A, 0x01, 0x04, 0x0A,
++	 0x00, 0x89, 0x55, 0x55, 0x99, 0x00, 0x08, 0x07, 0x85, 0x99, 0x00, 0x08,
++	 0x07, 0x85, 0x850, 0x84C, 0x848, 0x1ED, 0x1EE, 0x1EF},
++	{
++	 64, 5320, 3547, 0x71, 0x02, 0x14, 0x09, 0x83, 0x01, 0x04, 0x0A,
++	 0x00, 0x88, 0x55, 0x55, 0x88, 0x00, 0x07, 0x07, 0x84, 0x88, 0x00, 0x07,
++	 0x07, 0x84, 0x854, 0x850, 0x84C, 0x1EC, 0x1ED, 0x1EE},
++	{
++	 66, 5330, 3553, 0x71, 0x02, 0x15, 0x09, 0x83, 0x01, 0x04, 0x0A,
++	 0x00, 0x88, 0x55, 0x55, 0x88, 0x00, 0x07, 0x07, 0x84, 0x88, 0x00, 0x07,
++	 0x07, 0x84, 0x858, 0x854, 0x850, 0x1EB, 0x1EC, 0x1ED},
++	{
++	 68, 5340, 3560, 0x71, 0x02, 0x16, 0x08, 0x7C, 0x01, 0x04, 0x0A,
++	 0x00, 0x88, 0x44, 0x44, 0x88, 0x00, 0x07, 0x06, 0x84, 0x88, 0x00, 0x07,
++	 0x06, 0x84, 0x85C, 0x858, 0x854, 0x1EA, 0x1EB, 0x1EC},
++	{
++	 70, 5350, 3567, 0x71, 0x02, 0x17, 0x08, 0x7C, 0x01, 0x04, 0x0A,
++	 0x00, 0x88, 0x44, 0x44, 0x88, 0x00, 0x07, 0x06, 0x84, 0x88, 0x00, 0x07,
++	 0x06, 0x84, 0x860, 0x85C, 0x858, 0x1E9, 0x1EA, 0x1EB},
++	{
++	 72, 5360, 3573, 0x71, 0x02, 0x18, 0x08, 0x75, 0x01, 0x04, 0x0A,
++	 0x00, 0x87, 0x44, 0x44, 0x77, 0x00, 0x06, 0x05, 0x83, 0x77, 0x00, 0x06,
++	 0x05, 0x83, 0x864, 0x860, 0x85C, 0x1E8, 0x1E9, 0x1EA},
++	{
++	 74, 5370, 3580, 0x71, 0x02, 0x19, 0x08, 0x75, 0x01, 0x04, 0x0A,
++	 0x00, 0x87, 0x44, 0x44, 0x77, 0x00, 0x06, 0x05, 0x83, 0x77, 0x00, 0x06,
++	 0x05, 0x83, 0x868, 0x864, 0x860, 0x1E7, 0x1E8, 0x1E9},
++	{
++	 76, 5380, 3587, 0x71, 0x02, 0x1A, 0x08, 0x6E, 0x01, 0x04, 0x0A,
++	 0x00, 0x87, 0x33, 0x33, 0x77, 0x00, 0x06, 0x04, 0x82, 0x77, 0x00, 0x06,
++	 0x04, 0x82, 0x86C, 0x868, 0x864, 0x1E6, 0x1E7, 0x1E8},
++	{
++	 78, 5390, 3593, 0x71, 0x02, 0x1B, 0x08, 0x6E, 0x01, 0x04, 0x0A,
++	 0x00, 0x87, 0x33, 0x33, 0x77, 0x00, 0x06, 0x04, 0x82, 0x77, 0x00, 0x06,
++	 0x04, 0x82, 0x870, 0x86C, 0x868, 0x1E5, 0x1E6, 0x1E7},
++	{
++	 80, 5400, 3600, 0x71, 0x02, 0x1C, 0x07, 0x67, 0x01, 0x04, 0x0A,
++	 0x00, 0x86, 0x33, 0x33, 0x66, 0x00, 0x05, 0x04, 0x81, 0x66, 0x00, 0x05,
++	 0x04, 0x81, 0x874, 0x870, 0x86C, 0x1E5, 0x1E5, 0x1E6},
++	{
++	 82, 5410, 3607, 0x71, 0x02, 0x1D, 0x07, 0x67, 0x01, 0x04, 0x0A,
++	 0x00, 0x86, 0x33, 0x33, 0x66, 0x00, 0x05, 0x04, 0x81, 0x66, 0x00, 0x05,
++	 0x04, 0x81, 0x878, 0x874, 0x870, 0x1E4, 0x1E5, 0x1E5},
++	{
++	 84, 5420, 3613, 0x71, 0x02, 0x1E, 0x07, 0x61, 0x01, 0x04, 0x0A,
++	 0x00, 0x86, 0x22, 0x22, 0x66, 0x00, 0x05, 0x03, 0x80, 0x66, 0x00, 0x05,
++	 0x03, 0x80, 0x87C, 0x878, 0x874, 0x1E3, 0x1E4, 0x1E5},
++	{
++	 86, 5430, 3620, 0x71, 0x02, 0x1F, 0x07, 0x61, 0x01, 0x04, 0x0A,
++	 0x00, 0x86, 0x22, 0x22, 0x66, 0x00, 0x05, 0x03, 0x80, 0x66, 0x00, 0x05,
++	 0x03, 0x80, 0x880, 0x87C, 0x878, 0x1E2, 0x1E3, 0x1E4},
++	{
++	 88, 5440, 3627, 0x71, 0x02, 0x20, 0x07, 0x5A, 0x01, 0x04, 0x0A,
++	 0x00, 0x85, 0x22, 0x22, 0x55, 0x00, 0x04, 0x02, 0x80, 0x55, 0x00, 0x04,
++	 0x02, 0x80, 0x884, 0x880, 0x87C, 0x1E1, 0x1E2, 0x1E3},
++	{
++	 90, 5450, 3633, 0x71, 0x02, 0x21, 0x07, 0x5A, 0x01, 0x04, 0x0A,
++	 0x00, 0x85, 0x22, 0x22, 0x55, 0x00, 0x04, 0x02, 0x80, 0x55, 0x00, 0x04,
++	 0x02, 0x80, 0x888, 0x884, 0x880, 0x1E0, 0x1E1, 0x1E2},
++	{
++	 92, 5460, 3640, 0x71, 0x02, 0x22, 0x06, 0x53, 0x01, 0x04, 0x0A,
++	 0x00, 0x85, 0x11, 0x11, 0x55, 0x00, 0x04, 0x01, 0x80, 0x55, 0x00, 0x04,
++	 0x01, 0x80, 0x88C, 0x888, 0x884, 0x1DF, 0x1E0, 0x1E1},
++	{
++	 94, 5470, 3647, 0x71, 0x02, 0x23, 0x06, 0x53, 0x01, 0x04, 0x0A,
++	 0x00, 0x85, 0x11, 0x11, 0x55, 0x00, 0x04, 0x01, 0x80, 0x55, 0x00, 0x04,
++	 0x01, 0x80, 0x890, 0x88C, 0x888, 0x1DE, 0x1DF, 0x1E0},
++	{
++	 96, 5480, 3653, 0x71, 0x02, 0x24, 0x06, 0x4D, 0x01, 0x04, 0x0A,
++	 0x00, 0x84, 0x11, 0x11, 0x44, 0x00, 0x03, 0x00, 0x80, 0x44, 0x00, 0x03,
++	 0x00, 0x80, 0x894, 0x890, 0x88C, 0x1DD, 0x1DE, 0x1DF},
++	{
++	 98, 5490, 3660, 0x71, 0x02, 0x25, 0x06, 0x4D, 0x01, 0x04, 0x0A,
++	 0x00, 0x84, 0x11, 0x11, 0x44, 0x00, 0x03, 0x00, 0x80, 0x44, 0x00, 0x03,
++	 0x00, 0x80, 0x898, 0x894, 0x890, 0x1DD, 0x1DD, 0x1DE},
++	{
++	 100, 5500, 3667, 0x71, 0x02, 0x26, 0x06, 0x47, 0x01, 0x04, 0x0A,
++	 0x00, 0x84, 0x00, 0x00, 0x44, 0x00, 0x03, 0x00, 0x80, 0x44, 0x00, 0x03,
++	 0x00, 0x80, 0x89C, 0x898, 0x894, 0x1DC, 0x1DD, 0x1DD},
++	{
++	 102, 5510, 3673, 0x71, 0x02, 0x27, 0x06, 0x47, 0x01, 0x04, 0x0A,
++	 0x00, 0x84, 0x00, 0x00, 0x44, 0x00, 0x03, 0x00, 0x80, 0x44, 0x00, 0x03,
++	 0x00, 0x80, 0x8A0, 0x89C, 0x898, 0x1DB, 0x1DC, 0x1DD},
++	{
++	 104, 5520, 3680, 0x71, 0x02, 0x28, 0x05, 0x40, 0x01, 0x04, 0x0A,
++	 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, 0x80, 0x33, 0x00, 0x02,
++	 0x00, 0x80, 0x8A4, 0x8A0, 0x89C, 0x1DA, 0x1DB, 0x1DC},
++	{
++	 106, 5530, 3687, 0x71, 0x02, 0x29, 0x05, 0x40, 0x01, 0x04, 0x0A,
++	 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, 0x80, 0x33, 0x00, 0x02,
++	 0x00, 0x80, 0x8A8, 0x8A4, 0x8A0, 0x1D9, 0x1DA, 0x1DB},
++	{
++	 108, 5540, 3693, 0x71, 0x02, 0x2A, 0x05, 0x3A, 0x01, 0x04, 0x0A,
++	 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, 0x80, 0x33, 0x00, 0x02,
++	 0x00, 0x80, 0x8AC, 0x8A8, 0x8A4, 0x1D8, 0x1D9, 0x1DA},
++	{
++	 110, 5550, 3700, 0x71, 0x02, 0x2B, 0x05, 0x3A, 0x01, 0x04, 0x0A,
++	 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, 0x80, 0x33, 0x00, 0x02,
++	 0x00, 0x80, 0x8B0, 0x8AC, 0x8A8, 0x1D7, 0x1D8, 0x1D9},
++	{
++	 112, 5560, 3707, 0x71, 0x02, 0x2C, 0x05, 0x34, 0x01, 0x04, 0x0A,
++	 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, 0x80, 0x22, 0x00, 0x01,
++	 0x00, 0x80, 0x8B4, 0x8B0, 0x8AC, 0x1D7, 0x1D7, 0x1D8},
++	{
++	 114, 5570, 3713, 0x71, 0x02, 0x2D, 0x05, 0x34, 0x01, 0x04, 0x0A,
++	 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, 0x80, 0x22, 0x00, 0x01,
++	 0x00, 0x80, 0x8B8, 0x8B4, 0x8B0, 0x1D6, 0x1D7, 0x1D7},
++	{
++	 116, 5580, 3720, 0x71, 0x02, 0x2E, 0x04, 0x2E, 0x01, 0x04, 0x0A,
++	 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, 0x80, 0x22, 0x00, 0x01,
++	 0x00, 0x80, 0x8BC, 0x8B8, 0x8B4, 0x1D5, 0x1D6, 0x1D7},
++	{
++	 118, 5590, 3727, 0x71, 0x02, 0x2F, 0x04, 0x2E, 0x01, 0x04, 0x0A,
++	 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, 0x80, 0x22, 0x00, 0x01,
++	 0x00, 0x80, 0x8C0, 0x8BC, 0x8B8, 0x1D4, 0x1D5, 0x1D6},
++	{
++	 120, 5600, 3733, 0x71, 0x02, 0x30, 0x04, 0x28, 0x01, 0x04, 0x0A,
++	 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00, 0x80, 0x11, 0x00, 0x01,
++	 0x00, 0x80, 0x8C4, 0x8C0, 0x8BC, 0x1D3, 0x1D4, 0x1D5},
++	{
++	 122, 5610, 3740, 0x71, 0x02, 0x31, 0x04, 0x28, 0x01, 0x04, 0x0A,
++	 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00, 0x80, 0x11, 0x00, 0x01,
++	 0x00, 0x80, 0x8C8, 0x8C4, 0x8C0, 0x1D2, 0x1D3, 0x1D4},
++	{
++	 124, 5620, 3747, 0x71, 0x02, 0x32, 0x04, 0x21, 0x01, 0x04, 0x0A,
++	 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00,
++	 0x00, 0x80, 0x8CC, 0x8C8, 0x8C4, 0x1D2, 0x1D2, 0x1D3},
++	{
++	 126, 5630, 3753, 0x71, 0x02, 0x33, 0x04, 0x21, 0x01, 0x04, 0x0A,
++	 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00,
++	 0x00, 0x80, 0x8D0, 0x8CC, 0x8C8, 0x1D1, 0x1D2, 0x1D2},
++	{
++	 128, 5640, 3760, 0x71, 0x02, 0x34, 0x03, 0x1C, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x8D4, 0x8D0, 0x8CC, 0x1D0, 0x1D1, 0x1D2},
++	{
++	 130, 5650, 3767, 0x71, 0x02, 0x35, 0x03, 0x1C, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x8D8, 0x8D4, 0x8D0, 0x1CF, 0x1D0, 0x1D1},
++	{
++	 132, 5660, 3773, 0x71, 0x02, 0x36, 0x03, 0x16, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x8DC, 0x8D8, 0x8D4, 0x1CE, 0x1CF, 0x1D0},
++	{
++	 134, 5670, 3780, 0x71, 0x02, 0x37, 0x03, 0x16, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x8E0, 0x8DC, 0x8D8, 0x1CE, 0x1CE, 0x1CF},
++	{
++	 136, 5680, 3787, 0x71, 0x02, 0x38, 0x03, 0x10, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x8E4, 0x8E0, 0x8DC, 0x1CD, 0x1CE, 0x1CE},
++	{
++	 138, 5690, 3793, 0x71, 0x02, 0x39, 0x03, 0x10, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x8E8, 0x8E4, 0x8E0, 0x1CC, 0x1CD, 0x1CE},
++	{
++	 140, 5700, 3800, 0x71, 0x02, 0x3A, 0x02, 0x0A, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x8EC, 0x8E8, 0x8E4, 0x1CB, 0x1CC, 0x1CD},
++	{
++	 142, 5710, 3807, 0x71, 0x02, 0x3B, 0x02, 0x0A, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x8F0, 0x8EC, 0x8E8, 0x1CA, 0x1CB, 0x1CC},
++	{
++	 144, 5720, 3813, 0x71, 0x02, 0x3C, 0x02, 0x0A, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x8F4, 0x8F0, 0x8EC, 0x1C9, 0x1CA, 0x1CB},
++	{
++	 145, 5725, 3817, 0x72, 0x04, 0x79, 0x02, 0x03, 0x01, 0x03, 0x14,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x8F6, 0x8F2, 0x8EE, 0x1C9, 0x1CA, 0x1CB},
++	{
++	 146, 5730, 3820, 0x71, 0x02, 0x3D, 0x02, 0x0A, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x8F8, 0x8F4, 0x8F0, 0x1C9, 0x1C9, 0x1CA},
++	{
++	 147, 5735, 3823, 0x72, 0x04, 0x7B, 0x02, 0x03, 0x01, 0x03, 0x14,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x8FA, 0x8F6, 0x8F2, 0x1C8, 0x1C9, 0x1CA},
++	{
++	 148, 5740, 3827, 0x71, 0x02, 0x3E, 0x02, 0x0A, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x8FC, 0x8F8, 0x8F4, 0x1C8, 0x1C9, 0x1C9},
++	{
++	 149, 5745, 3830, 0x72, 0x04, 0x7D, 0x02, 0xFE, 0x00, 0x03, 0x14,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x8FE, 0x8FA, 0x8F6, 0x1C8, 0x1C8, 0x1C9},
++	{
++	 150, 5750, 3833, 0x71, 0x02, 0x3F, 0x02, 0x0A, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x900, 0x8FC, 0x8F8, 0x1C7, 0x1C8, 0x1C9},
++	{
++	 151, 5755, 3837, 0x72, 0x04, 0x7F, 0x02, 0xFE, 0x00, 0x03, 0x14,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x902, 0x8FE, 0x8FA, 0x1C7, 0x1C8, 0x1C8},
++	{
++	 152, 5760, 3840, 0x71, 0x02, 0x40, 0x02, 0x0A, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x904, 0x900, 0x8FC, 0x1C6, 0x1C7, 0x1C8},
++	{
++	 153, 5765, 3843, 0x72, 0x04, 0x81, 0x02, 0xF8, 0x00, 0x03, 0x14,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x906, 0x902, 0x8FE, 0x1C6, 0x1C7, 0x1C8},
++	{
++	 154, 5770, 3847, 0x71, 0x02, 0x41, 0x02, 0x0A, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x908, 0x904, 0x900, 0x1C6, 0x1C6, 0x1C7},
++	{
++	 155, 5775, 3850, 0x72, 0x04, 0x83, 0x02, 0xF8, 0x00, 0x03, 0x14,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x90A, 0x906, 0x902, 0x1C5, 0x1C6, 0x1C7},
++	{
++	 156, 5780, 3853, 0x71, 0x02, 0x42, 0x02, 0x0A, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x90C, 0x908, 0x904, 0x1C5, 0x1C6, 0x1C6},
++	{
++	 157, 5785, 3857, 0x72, 0x04, 0x85, 0x02, 0xF2, 0x00, 0x03, 0x14,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x90E, 0x90A, 0x906, 0x1C4, 0x1C5, 0x1C6},
++	{
++	 158, 5790, 3860, 0x71, 0x02, 0x43, 0x02, 0x0A, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x910, 0x90C, 0x908, 0x1C4, 0x1C5, 0x1C6},
++	{
++	 159, 5795, 3863, 0x72, 0x04, 0x87, 0x02, 0xF2, 0x00, 0x03, 0x14,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x912, 0x90E, 0x90A, 0x1C4, 0x1C4, 0x1C5},
++	{
++	 160, 5800, 3867, 0x71, 0x02, 0x44, 0x01, 0x0A, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x914, 0x910, 0x90C, 0x1C3, 0x1C4, 0x1C5},
++	{
++	 161, 5805, 3870, 0x72, 0x04, 0x89, 0x01, 0xED, 0x00, 0x03, 0x14,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x916, 0x912, 0x90E, 0x1C3, 0x1C4, 0x1C4},
++	{
++	 162, 5810, 3873, 0x71, 0x02, 0x45, 0x01, 0x0A, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x918, 0x914, 0x910, 0x1C2, 0x1C3, 0x1C4},
++	{
++	 163, 5815, 3877, 0x72, 0x04, 0x8B, 0x01, 0xED, 0x00, 0x03, 0x14,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x91A, 0x916, 0x912, 0x1C2, 0x1C3, 0x1C4},
++	{
++	 164, 5820, 3880, 0x71, 0x02, 0x46, 0x01, 0x0A, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x91C, 0x918, 0x914, 0x1C2, 0x1C2, 0x1C3},
++	{
++	 165, 5825, 3883, 0x72, 0x04, 0x8D, 0x01, 0xED, 0x00, 0x03, 0x14,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x91E, 0x91A, 0x916, 0x1C1, 0x1C2, 0x1C3},
++	{
++	 166, 5830, 3887, 0x71, 0x02, 0x47, 0x01, 0x0A, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x920, 0x91C, 0x918, 0x1C1, 0x1C2, 0x1C2},
++	{
++	 168, 5840, 3893, 0x71, 0x02, 0x48, 0x01, 0x0A, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x924, 0x920, 0x91C, 0x1C0, 0x1C1, 0x1C2},
++	{
++	 170, 5850, 3900, 0x71, 0x02, 0x49, 0x01, 0xE0, 0x00, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x928, 0x924, 0x920, 0x1BF, 0x1C0, 0x1C1},
++	{
++	 172, 5860, 3907, 0x71, 0x02, 0x4A, 0x01, 0xDE, 0x00, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x92C, 0x928, 0x924, 0x1BF, 0x1BF, 0x1C0},
++	{
++	 174, 5870, 3913, 0x71, 0x02, 0x4B, 0x00, 0xDB, 0x00, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x930, 0x92C, 0x928, 0x1BE, 0x1BF, 0x1BF},
++	{
++	 176, 5880, 3920, 0x71, 0x02, 0x4C, 0x00, 0xD8, 0x00, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x934, 0x930, 0x92C, 0x1BD, 0x1BE, 0x1BF},
++	{
++	 178, 5890, 3927, 0x71, 0x02, 0x4D, 0x00, 0xD6, 0x00, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x938, 0x934, 0x930, 0x1BC, 0x1BD, 0x1BE},
++	{
++	 180, 5900, 3933, 0x71, 0x02, 0x4E, 0x00, 0xD3, 0x00, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x93C, 0x938, 0x934, 0x1BC, 0x1BC, 0x1BD},
++	{
++	 182, 5910, 3940, 0x71, 0x02, 0x4F, 0x00, 0xD6, 0x00, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x940, 0x93C, 0x938, 0x1BB, 0x1BC, 0x1BC},
++	{
++	 1, 2412, 3216, 0x73, 0x09, 0x6C, 0x0F, 0x00, 0x01, 0x07, 0x15,
++	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0D, 0x0C, 0x80, 0xFF, 0x88, 0x0D,
++	 0x0C, 0x80, 0x3C9, 0x3C5, 0x3C1, 0x43A, 0x43F, 0x443},
++	{
++	 2, 2417, 3223, 0x73, 0x09, 0x71, 0x0F, 0x00, 0x01, 0x07, 0x15,
++	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0B, 0x80, 0xFF, 0x88, 0x0C,
++	 0x0B, 0x80, 0x3CB, 0x3C7, 0x3C3, 0x438, 0x43D, 0x441},
++	{
++	 3, 2422, 3229, 0x73, 0x09, 0x76, 0x0F, 0x00, 0x01, 0x07, 0x15,
++	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0A, 0x80, 0xFF, 0x88, 0x0C,
++	 0x0A, 0x80, 0x3CD, 0x3C9, 0x3C5, 0x436, 0x43A, 0x43F},
++	{
++	 4, 2427, 3236, 0x73, 0x09, 0x7B, 0x0F, 0x00, 0x01, 0x07, 0x15,
++	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0A, 0x80, 0xFF, 0x88, 0x0C,
++	 0x0A, 0x80, 0x3CF, 0x3CB, 0x3C7, 0x434, 0x438, 0x43D},
++	{
++	 5, 2432, 3243, 0x73, 0x09, 0x80, 0x0F, 0x00, 0x01, 0x07, 0x15,
++	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x09, 0x80, 0xFF, 0x88, 0x0C,
++	 0x09, 0x80, 0x3D1, 0x3CD, 0x3C9, 0x431, 0x436, 0x43A},
++	{
++	 6, 2437, 3249, 0x73, 0x09, 0x85, 0x0F, 0x00, 0x01, 0x07, 0x15,
++	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0B, 0x08, 0x80, 0xFF, 0x88, 0x0B,
++	 0x08, 0x80, 0x3D3, 0x3CF, 0x3CB, 0x42F, 0x434, 0x438},
++	{
++	 7, 2442, 3256, 0x73, 0x09, 0x8A, 0x0F, 0x00, 0x01, 0x07, 0x15,
++	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0A, 0x07, 0x80, 0xFF, 0x88, 0x0A,
++	 0x07, 0x80, 0x3D5, 0x3D1, 0x3CD, 0x42D, 0x431, 0x436},
++	{
++	 8, 2447, 3263, 0x73, 0x09, 0x8F, 0x0F, 0x00, 0x01, 0x07, 0x15,
++	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0A, 0x06, 0x80, 0xFF, 0x88, 0x0A,
++	 0x06, 0x80, 0x3D7, 0x3D3, 0x3CF, 0x42B, 0x42F, 0x434},
++	{
++	 9, 2452, 3269, 0x73, 0x09, 0x94, 0x0F, 0x00, 0x01, 0x07, 0x15,
++	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x09, 0x06, 0x80, 0xFF, 0x88, 0x09,
++	 0x06, 0x80, 0x3D9, 0x3D5, 0x3D1, 0x429, 0x42D, 0x431},
++	{
++	 10, 2457, 3276, 0x73, 0x09, 0x99, 0x0F, 0x00, 0x01, 0x07, 0x15,
++	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x05, 0x80, 0xFF, 0x88, 0x08,
++	 0x05, 0x80, 0x3DB, 0x3D7, 0x3D3, 0x427, 0x42B, 0x42F},
++	{
++	 11, 2462, 3283, 0x73, 0x09, 0x9E, 0x0F, 0x00, 0x01, 0x07, 0x15,
++	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x04, 0x80, 0xFF, 0x88, 0x08,
++	 0x04, 0x80, 0x3DD, 0x3D9, 0x3D5, 0x424, 0x429, 0x42D},
++	{
++	 12, 2467, 3289, 0x73, 0x09, 0xA3, 0x0F, 0x00, 0x01, 0x07, 0x15,
++	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x03, 0x80, 0xFF, 0x88, 0x08,
++	 0x03, 0x80, 0x3DF, 0x3DB, 0x3D7, 0x422, 0x427, 0x42B},
++	{
++	 13, 2472, 3296, 0x73, 0x09, 0xA8, 0x0F, 0x00, 0x01, 0x07, 0x15,
++	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x07, 0x03, 0x80, 0xFF, 0x88, 0x07,
++	 0x03, 0x80, 0x3E1, 0x3DD, 0x3D9, 0x420, 0x424, 0x429},
++	{
++	 14, 2484, 3312, 0x73, 0x09, 0xB4, 0x0F, 0xFF, 0x01, 0x07, 0x15,
++	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x07, 0x01, 0x80, 0xFF, 0x88, 0x07,
++	 0x01, 0x80, 0x3E6, 0x3E2, 0x3DE, 0x41B, 0x41F, 0x424}
++};
++
++static const struct chan_info_nphy_radio205x chan_info_nphyrev3_2056[] = {
++	{
++	 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xff, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216},
++	{
++	 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xff, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215},
++	{
++	 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xff, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214},
++	{
++	 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xff, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213},
++	{
++	 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xff, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212},
++	{
++	 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xff, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211},
++	{
++	 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xff, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f},
++	{
++	 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xff, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e},
++	{
++	 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xff, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d},
++	{
++	 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xff, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c},
++	{
++	 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xff, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b},
++	{
++	 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xff, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a},
++	{
++	 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xff, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209},
++	{
++	 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xff, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208},
++	{
++	 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xff, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207},
++	{
++	 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xff, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206},
++	{
++	 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xff, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205},
++	{
++	 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xff, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204},
++	{
++	 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xff, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203},
++	{
++	 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xfc, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202},
++	{
++	 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xfc, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201},
++	{
++	 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xfc, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200},
++	{
++	 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xfc, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff},
++	{
++	 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xfc, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd},
++	{
++	 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xfc, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc},
++	{
++	 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xef, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xfc, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb},
++	{
++	 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xef, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xfc, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa},
++	{
++	 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xef, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xfc, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9},
++	{
++	 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xfc, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8},
++	{
++	 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xfc, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7},
++	{
++	 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xfc, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6},
++	{
++	 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xfc, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5},
++	{
++	 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xfc, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4},
++	{
++	 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xfc, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3},
++	{
++	 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xfc, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2},
++	{
++	 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xbf, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xfc, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1},
++	{
++	 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xbf, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xfc, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0},
++	{
++	 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x05, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xfc, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0},
++	{
++	 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x05, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xfa, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef},
++	{
++	 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x05, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xfa, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee},
++	{
++	 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xaf, 0x00, 0x05, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xfa, 0x00, 0xaf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xfa, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed},
++	{
++	 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xaf, 0x00, 0x05, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xfa, 0x00, 0xaf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xfa, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec},
++	{
++	 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x05, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xfa, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb},
++	{
++	 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x05, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xfa, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea},
++	{
++	 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x05, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xfa, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9},
++	{
++	 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x05, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xfa, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8},
++	{
++	 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x8f, 0x00, 0x05, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xfa, 0x00, 0x8f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xfa, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7},
++	{
++	 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8f, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x08, 0x00, 0xfa, 0x00, 0x8f, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
++	 0x00, 0xfa, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6},
++	{
++	 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8f, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x08, 0x00, 0xfa, 0x00, 0x8f, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
++	 0x00, 0xfa, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5},
++	{
++	 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8e, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x08, 0x00, 0xfa, 0x00, 0x8e, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
++	 0x00, 0xfa, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5},
++	{
++	 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8e, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x08, 0x00, 0xfa, 0x00, 0x8e, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
++	 0x00, 0xfa, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4},
++	{
++	 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x7e, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x08, 0x00, 0xfa, 0x00, 0x7e, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
++	 0x00, 0xfa, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3},
++	{
++	 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x7d, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x08, 0x00, 0xfa, 0x00, 0x7d, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
++	 0x00, 0xfa, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2},
++	{
++	 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x6d, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x08, 0x00, 0xf8, 0x00, 0x6d, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
++	 0x00, 0xf8, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1},
++	{
++	 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x6d, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x08, 0x00, 0xf8, 0x00, 0x6d, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
++	 0x00, 0xf8, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0},
++	{
++	 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x5d, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x08, 0x00, 0xf8, 0x00, 0x5d, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
++	 0x00, 0xf8, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df},
++	{
++	 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x5c, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x08, 0x00, 0xf8, 0x00, 0x5c, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
++	 0x00, 0xf8, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de},
++	{
++	 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x5c, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x5c, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf8, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd},
++	{
++	 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x4c, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x4c, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf8, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd},
++	{
++	 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x4c, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x4c, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf8, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc},
++	{
++	 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x3b, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf8, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db},
++	{
++	 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x3b, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf8, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da},
++	{
++	 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x3b, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf8, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9},
++	{
++	 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x2b, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x2b, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf8, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8},
++	{
++	 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x2a, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x2a, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf8, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7},
++	{
++	 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x1a, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x1a, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf8, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7},
++	{
++	 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x1a, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x1a, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf8, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6},
++	{
++	 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x1a, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x1a, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf8, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5},
++	{
++	 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x19, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x19, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf8, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4},
++	{
++	 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x19, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x19, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf8, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3},
++	{
++	 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x09, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x09, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf8, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2},
++	{
++	 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x09, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x09, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf8, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2},
++	{
++	 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x08, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf8, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1},
++	{
++	 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf6, 0x00, 0x08, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf6, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0},
++	{
++	 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf6, 0x00, 0x08, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf6, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf},
++	{
++	 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf6, 0x00, 0x08, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf6, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce},
++	{
++	 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x07, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf6, 0x00, 0x07, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf6, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce},
++	{
++	 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf6, 0x00, 0x07, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf6, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd},
++	{
++	 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x07, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc},
++	{
++	 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x07, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb},
++	{
++	 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb},
++	{
++	 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca},
++	{
++	 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca},
++	{
++	 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9},
++	{
++	 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9},
++	{
++	 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9},
++	{
++	 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8},
++	{
++	 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8},
++	{
++	 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8},
++	{
++	 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7},
++	{
++	 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7},
++	{
++	 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6},
++	{
++	 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6},
++	{
++	 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6},
++	{
++	 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5},
++	{
++	 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5},
++	{
++	 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4},
++	{
++	 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4},
++	{
++	 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4},
++	{
++	 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3},
++	{
++	 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3},
++	{
++	 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2},
++	{
++	 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2},
++	{
++	 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1},
++	{
++	 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf2, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf2, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0},
++	{
++	 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x00, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf2, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf2, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf},
++	{
++	 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x00, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf2, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf2, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf},
++	{
++	 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x00, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf2, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf2, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be},
++	{
++	 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f,
++	 0x00, 0x05, 0x00, 0xf2, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x05,
++	 0x00, 0xf2, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd},
++	{
++	 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f,
++	 0x00, 0x05, 0x00, 0xf2, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x05,
++	 0x00, 0xf2, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc},
++	{
++	 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x05, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xff, 0x00, 0x05, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0f, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443},
++	{
++	 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x05, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xff, 0x00, 0x05, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0f, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441},
++	{
++	 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x05, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xff, 0x00, 0x05, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0f, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f},
++	{
++	 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x05, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xfd, 0x00, 0x05, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0f, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d},
++	{
++	 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfb, 0x00, 0x05, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xfb, 0x00, 0x05, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0f, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a},
++	{
++	 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x05, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x05, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0f, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438},
++	{
++	 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x05, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x05, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0f, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436},
++	{
++	 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x05, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xf7, 0x00, 0x05, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0f, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434},
++	{
++	 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf6, 0x00, 0x05, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xf6, 0x00, 0x05, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0f, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431},
++	{
++	 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf5, 0x00, 0x05, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0d, 0x00, 0xf5, 0x00, 0x05, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0d, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f},
++	{
++	 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf4, 0x00, 0x05, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0d, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0d, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d},
++	{
++	 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf3, 0x00, 0x05, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0d, 0x00, 0xf3, 0x00, 0x05, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0d, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b},
++	{
++	 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf2, 0x00, 0x05, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0d, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0d, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429},
++	{
++	 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x05, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0d, 0x00, 0xf0, 0x00, 0x05, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0d, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424}
++};
++
++static const struct chan_info_nphy_radio205x chan_info_nphyrev4_2056_A1[] = {
++	{
++	 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xff, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216},
++	{
++	 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xff, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215},
++	{
++	 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xff, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214},
++	{
++	 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xff, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213},
++	{
++	 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xff, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212},
++	{
++	 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xff, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211},
++	{
++	 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xff, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f},
++	{
++	 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xff, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e},
++	{
++	 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xff, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d},
++	{
++	 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xff, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c},
++	{
++	 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xff, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b},
++	{
++	 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xff, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a},
++	{
++	 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xff, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209},
++	{
++	 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xff, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208},
++	{
++	 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xff, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207},
++	{
++	 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xff, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206},
++	{
++	 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xff, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205},
++	{
++	 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xff, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204},
++	{
++	 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfe, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203},
++	{
++	 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfe, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202},
++	{
++	 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfe, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201},
++	{
++	 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfe, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200},
++	{
++	 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfe, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff},
++	{
++	 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfe, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd},
++	{
++	 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfe, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc},
++	{
++	 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x0c, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xef, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfe, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb},
++	{
++	 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x0c, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xef, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfe, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa},
++	{
++	 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x0a, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xef, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfc, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9},
++	{
++	 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x0a, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfc, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8},
++	{
++	 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x0a, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfc, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7},
++	{
++	 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x0a, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfc, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6},
++	{
++	 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x0a, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfc, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5},
++	{
++	 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x0a, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfc, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4},
++	{
++	 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x0a, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfc, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3},
++	{
++	 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x0a, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfc, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2},
++	{
++	 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xbf, 0x00, 0x0a, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfc, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1},
++	{
++	 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xbf, 0x00, 0x0a, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfc, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0},
++	{
++	 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x08, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfa, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0},
++	{
++	 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x08, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfa, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef},
++	{
++	 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x08, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfa, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee},
++	{
++	 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xaf, 0x00, 0x08, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfa, 0x00, 0xaf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfa, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed},
++	{
++	 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xaf, 0x00, 0x08, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfa, 0x00, 0xaf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfa, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec},
++	{
++	 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x08, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfa, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb},
++	{
++	 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x08, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfa, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea},
++	{
++	 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x08, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfa, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9},
++	{
++	 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x08, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfa, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8},
++	{
++	 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x8f, 0x00, 0x08, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x8f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfa, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7},
++	{
++	 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8f, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x8f, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xf8, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6},
++	{
++	 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8f, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x8f, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xf8, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5},
++	{
++	 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8e, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x8e, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xf8, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5},
++	{
++	 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8e, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x8e, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xf8, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4},
++	{
++	 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x7e, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x7e, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xf8, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3},
++	{
++	 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x7d, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x7d, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xf8, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2},
++	{
++	 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x6d, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x6d, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xf8, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1},
++	{
++	 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x6d, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x6d, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xf8, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0},
++	{
++	 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x5d, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x5d, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xf8, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df},
++	{
++	 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x5c, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x5c, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xf8, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de},
++	{
++	 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x5c, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x5c, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
++	 0x00, 0xf6, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd},
++	{
++	 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x4c, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x4c, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
++	 0x00, 0xf6, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd},
++	{
++	 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x4c, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x4c, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
++	 0x00, 0xf6, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc},
++	{
++	 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x3b, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
++	 0x00, 0xf6, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db},
++	{
++	 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x3b, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
++	 0x00, 0xf6, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da},
++	{
++	 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x3b, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
++	 0x00, 0xf6, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9},
++	{
++	 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x2b, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x2b, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
++	 0x00, 0xf6, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8},
++	{
++	 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x2a, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x2a, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
++	 0x00, 0xf6, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7},
++	{
++	 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x1a, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x1a, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
++	 0x00, 0xf6, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7},
++	{
++	 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x1a, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x1a, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
++	 0x00, 0xf6, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6},
++	{
++	 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x1a, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x1a, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xf4, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5},
++	{
++	 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x19, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x19, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xf4, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4},
++	{
++	 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x19, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x19, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xf4, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3},
++	{
++	 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x09, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x09, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xf4, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2},
++	{
++	 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x09, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x09, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xf4, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2},
++	{
++	 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x08, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xf4, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1},
++	{
++	 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x08, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xf4, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0},
++	{
++	 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x08, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xf4, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf},
++	{
++	 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x08, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xf4, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce},
++	{
++	 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x07, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x07, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xf4, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce},
++	{
++	 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x07, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xf2, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd},
++	{
++	 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x07, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xf2, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc},
++	{
++	 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x07, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xf2, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb},
++	{
++	 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xf2, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb},
++	{
++	 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xf2, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca},
++	{
++	 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xf2, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca},
++	{
++	 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xf2, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9},
++	{
++	 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xf2, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9},
++	{
++	 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xf2, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9},
++	{
++	 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xf2, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8},
++	{
++	 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xf2, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8},
++	{
++	 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xf2, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8},
++	{
++	 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xf2, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7},
++	{
++	 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xf2, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7},
++	{
++	 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xf2, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6},
++	{
++	 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x04, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xf2, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6},
++	{
++	 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x04, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xf2, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6},
++	{
++	 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x04, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xf2, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5},
++	{
++	 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xf0, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5},
++	{
++	 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xf0, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4},
++	{
++	 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xf0, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4},
++	{
++	 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xf0, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4},
++	{
++	 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xf0, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3},
++	{
++	 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xf0, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3},
++	{
++	 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xf0, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2},
++	{
++	 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xf0, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2},
++	{
++	 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xf0, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1},
++	{
++	 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xf0, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0},
++	{
++	 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x02, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xf0, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf},
++	{
++	 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x02, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xf0, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf},
++	{
++	 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x02, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xf0, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be},
++	{
++	 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf0, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf0, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd},
++	{
++	 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf0, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf0, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc},
++	{
++	 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x04, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xff, 0x00, 0x04, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0e, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443},
++	{
++	 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x04, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xff, 0x00, 0x04, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0e, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441},
++	{
++	 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x04, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xff, 0x00, 0x04, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0e, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f},
++	{
++	 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x04, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xfd, 0x00, 0x04, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0e, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d},
++	{
++	 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfb, 0x00, 0x04, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xfb, 0x00, 0x04, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0e, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a},
++	{
++	 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xfa, 0x00, 0x04, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0e, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438},
++	{
++	 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x04, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf8, 0x00, 0x04, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0e, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436},
++	{
++	 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x04, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf7, 0x00, 0x04, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0e, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434},
++	{
++	 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf6, 0x00, 0x04, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf6, 0x00, 0x04, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0e, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431},
++	{
++	 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf5, 0x00, 0x04, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf5, 0x00, 0x04, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0e, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f},
++	{
++	 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf4, 0x00, 0x04, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0e, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d},
++	{
++	 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf3, 0x00, 0x04, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf3, 0x00, 0x04, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0e, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b},
++	{
++	 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf2, 0x00, 0x04, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf2, 0x00, 0x04, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0e, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429},
++	{
++	 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x04, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf0, 0x00, 0x04, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0e, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424}
++};
++
++static const struct chan_info_nphy_radio205x chan_info_nphyrev5_2056v5[] = {
++	{
++	 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
++	 0x00, 0x0f, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216},
++	{
++	 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
++	 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
++	 0x00, 0x6f, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215},
++	{
++	 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
++	 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
++	 0x00, 0x6f, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214},
++	{
++	 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
++	 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
++	 0x00, 0x6f, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213},
++	{
++	 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
++	 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0e,
++	 0x00, 0x6f, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212},
++	{
++	 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
++	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211},
++	{
++	 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
++	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f},
++	{
++	 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
++	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e},
++	{
++	 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
++	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d},
++	{
++	 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
++	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c},
++	{
++	 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x09, 0x00, 0x70,
++	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b},
++	{
++	 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x09, 0x00, 0x70,
++	 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a},
++	{
++	 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x70,
++	 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209},
++	{
++	 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x70,
++	 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208},
++	{
++	 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x70,
++	 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207},
++	{
++	 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x08, 0x00, 0x70,
++	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206},
++	{
++	 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
++	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205},
++	{
++	 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
++	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204},
++	{
++	 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
++	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203},
++	{
++	 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
++	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202},
++	{
++	 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
++	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201},
++	{
++	 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x08, 0x00, 0x70,
++	 0x00, 0x0a, 0x00, 0x9f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200},
++	{
++	 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x07, 0x00, 0x70,
++	 0x00, 0x0a, 0x00, 0x9f, 0x00, 0xfb, 0x00, 0x07, 0x00, 0x70, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff},
++	{
++	 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x07, 0x00, 0x70,
++	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfb, 0x00, 0x07, 0x00, 0x70, 0x00, 0x09,
++	 0x00, 0x6e, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd},
++	{
++	 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x06, 0x00, 0x70,
++	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfb, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
++	 0x00, 0x6e, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc},
++	{
++	 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
++	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
++	 0x00, 0x6e, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb},
++	{
++	 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
++	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
++	 0x00, 0x6e, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa},
++	{
++	 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
++	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
++	 0x00, 0x6e, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9},
++	{
++	 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
++	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
++	 0x00, 0x6e, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8},
++	{
++	 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
++	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
++	 0x00, 0x6e, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7},
++	{
++	 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xea, 0x00, 0x06, 0x00, 0x70,
++	 0x00, 0x08, 0x00, 0x9e, 0x00, 0xea, 0x00, 0x06, 0x00, 0x70, 0x00, 0x08,
++	 0x00, 0x6e, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6},
++	{
++	 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xe9, 0x00, 0x05, 0x00, 0x70,
++	 0x00, 0x08, 0x00, 0x9d, 0x00, 0xe9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
++	 0x00, 0x6d, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5},
++	{
++	 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xe9, 0x00, 0x05, 0x00, 0x70,
++	 0x00, 0x08, 0x00, 0x9d, 0x00, 0xe9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
++	 0x00, 0x6d, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4},
++	{
++	 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xd9, 0x00, 0x05, 0x00, 0x70,
++	 0x00, 0x08, 0x00, 0x9d, 0x00, 0xd9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
++	 0x00, 0x6d, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3},
++	{
++	 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xd8, 0x00, 0x04, 0x00, 0x70,
++	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xd8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
++	 0x00, 0x6c, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2},
++	{
++	 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xc8, 0x00, 0x04, 0x00, 0x70,
++	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
++	 0x00, 0x6c, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1},
++	{
++	 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xc8, 0x00, 0x04, 0x00, 0x70,
++	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
++	 0x00, 0x6c, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0},
++	{
++	 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xc8, 0x00, 0x04, 0x00, 0x70,
++	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
++	 0x00, 0x6c, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0},
++	{
++	 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xc8, 0x00, 0x04, 0x00, 0x70,
++	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
++	 0x00, 0x6c, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef},
++	{
++	 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xb8, 0x00, 0x04, 0x00, 0x70,
++	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xb8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
++	 0x00, 0x6c, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee},
++	{
++	 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xb7, 0x00, 0x04, 0x00, 0x70,
++	 0x00, 0x07, 0x00, 0x9b, 0x00, 0xb7, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
++	 0x00, 0x6b, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed},
++	{
++	 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xb7, 0x00, 0x03, 0x00, 0x70,
++	 0x00, 0x07, 0x00, 0x9b, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x70, 0x00, 0x07,
++	 0x00, 0x6b, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec},
++	{
++	 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xa7, 0x00, 0x03, 0x00, 0x70,
++	 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa7, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
++	 0x00, 0x6b, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb},
++	{
++	 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xa6, 0x00, 0x03, 0x00, 0x70,
++	 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
++	 0x00, 0x6b, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea},
++	{
++	 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xa6, 0x00, 0x03, 0x00, 0x70,
++	 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
++	 0x00, 0x5b, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9},
++	{
++	 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x96, 0x00, 0x03, 0x00, 0x70,
++	 0x00, 0x06, 0x00, 0x9a, 0x00, 0x96, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
++	 0x00, 0x5a, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8},
++	{
++	 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x95, 0x00, 0x03, 0x00, 0x70,
++	 0x00, 0x06, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
++	 0x00, 0x5a, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7},
++	{
++	 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x95, 0x00, 0x03, 0x00, 0x70,
++	 0x00, 0x06, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
++	 0x00, 0x5a, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6},
++	{
++	 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x95, 0x00, 0x03, 0x00, 0x70,
++	 0x00, 0x05, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x05,
++	 0x00, 0x5a, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5},
++	{
++	 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x95, 0x00, 0x03, 0x00, 0x70,
++	 0x00, 0x05, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x05,
++	 0x00, 0x5a, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5},
++	{
++	 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x85, 0x00, 0x02, 0x00, 0x70,
++	 0x00, 0x05, 0x00, 0x99, 0x00, 0x85, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
++	 0x00, 0x59, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4},
++	{
++	 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x84, 0x00, 0x02, 0x00, 0x70,
++	 0x00, 0x05, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
++	 0x00, 0x59, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3},
++	{
++	 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x84, 0x00, 0x02, 0x00, 0x70,
++	 0x00, 0x05, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
++	 0x00, 0x59, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2},
++	{
++	 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x84, 0x00, 0x02, 0x00, 0x70,
++	 0x00, 0x04, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x04,
++	 0x00, 0x69, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1},
++	{
++	 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x74, 0x00, 0x01, 0x00, 0x70,
++	 0x00, 0x04, 0x00, 0x99, 0x00, 0x74, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
++	 0x00, 0x69, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0},
++	{
++	 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x73, 0x00, 0x01, 0x00, 0x70,
++	 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
++	 0x00, 0x68, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df},
++	{
++	 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x73, 0x00, 0x01, 0x00, 0x70,
++	 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
++	 0x00, 0x68, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de},
++	{
++	 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x73, 0x00, 0x01, 0x00, 0x70,
++	 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
++	 0x00, 0x78, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd},
++	{
++	 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x73, 0x00, 0x01, 0x00, 0x70,
++	 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
++	 0x00, 0x78, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd},
++	{
++	 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x73, 0x00, 0x01, 0x00, 0x70,
++	 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
++	 0x00, 0x78, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc},
++	{
++	 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x63, 0x00, 0x01, 0x00, 0x70,
++	 0x00, 0x03, 0x00, 0x98, 0x00, 0x63, 0x00, 0x01, 0x00, 0x70, 0x00, 0x03,
++	 0x00, 0x78, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db},
++	{
++	 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x62, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
++	 0x00, 0x77, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da},
++	{
++	 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x62, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
++	 0x00, 0x77, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9},
++	{
++	 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x62, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
++	 0x00, 0x77, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8},
++	{
++	 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x52, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x02, 0x00, 0x96, 0x00, 0x52, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
++	 0x00, 0x76, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7},
++	{
++	 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x52, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x02, 0x00, 0x96, 0x00, 0x52, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
++	 0x00, 0x76, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7},
++	{
++	 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x51, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
++	 0x00, 0x76, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6},
++	{
++	 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x51, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
++	 0x00, 0x76, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5},
++	{
++	 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x51, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
++	 0x00, 0x76, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4},
++	{
++	 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x51, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
++	 0x00, 0x76, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3},
++	{
++	 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x51, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
++	 0x00, 0x76, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2},
++	{
++	 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x51, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x02, 0x00, 0x95, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
++	 0x00, 0x75, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2},
++	{
++	 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x50, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x95, 0x00, 0x50, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x75, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1},
++	{
++	 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x50, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x95, 0x00, 0x50, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x75, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0},
++	{
++	 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x40, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x74, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf},
++	{
++	 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x40, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x74, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce},
++	{
++	 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x40, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x74, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce},
++	{
++	 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x74, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd},
++	{
++	 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x74, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc},
++	{
++	 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x74, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb},
++	{
++	 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x74, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb},
++	{
++	 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x94, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x84, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca},
++	{
++	 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x83, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca},
++	{
++	 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x83, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9},
++	{
++	 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x83, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9},
++	{
++	 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x83, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9},
++	{
++	 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x83, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8},
++	{
++	 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x20, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x93, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x83, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8},
++	{
++	 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x20, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x82, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8},
++	{
++	 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x20, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x82, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7},
++	{
++	 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x20, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x82, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7},
++	{
++	 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x82, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6},
++	{
++	 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x82, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6},
++	{
++	 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x82, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6},
++	{
++	 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x82, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5},
++	{
++	 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x82, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5},
++	{
++	 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x82, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4},
++	{
++	 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x82, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4},
++	{
++	 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x82, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4},
++	{
++	 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x82, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3},
++	{
++	 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x82, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3},
++	{
++	 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x72, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2},
++	{
++	 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x72, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2},
++	{
++	 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x72, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1},
++	{
++	 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x72, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0},
++	{
++	 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x71, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf},
++	{
++	 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x71, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf},
++	{
++	 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x71, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be},
++	{
++	 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x71, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd},
++	{
++	 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x71, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc},
++	{
++	 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0b, 0x00, 0x1f, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0b, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443},
++	{
++	 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0a, 0x00, 0x1f, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0a, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441},
++	{
++	 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0a, 0x00, 0x0e, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0a, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f},
++	{
++	 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0e, 0x00, 0x0a, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d},
++	{
++	 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x0c, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0e, 0x00, 0x0a, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a},
++	{
++	 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0e, 0x00, 0x0a, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438},
++	{
++	 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x09, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0e, 0x00, 0x0a, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436},
++	{
++	 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0e, 0x00, 0x09, 0x00, 0x08, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0e, 0x00, 0x09, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434},
++	{
++	 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x07, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0e, 0x00, 0x09, 0x00, 0x07, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0e, 0x00, 0x09, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431},
++	{
++	 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x06, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0d, 0x00, 0x09, 0x00, 0x06, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0d, 0x00, 0x09, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f},
++	{
++	 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x05, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0d, 0x00, 0x09, 0x00, 0x05, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0d, 0x00, 0x09, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d},
++	{
++	 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x04, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0d, 0x00, 0x08, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b},
++	{
++	 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x03, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x03, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0d, 0x00, 0x08, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429},
++	{
++	 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0d, 0x00, 0x08, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424}
++};
++
++static const struct chan_info_nphy_radio205x chan_info_nphyrev6_2056v6[] = {
++	{
++	 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216},
++	{
++	 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215},
++	{
++	 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214},
++	{
++	 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213},
++	{
++	 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212},
++	{
++	 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211},
++	{
++	 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f},
++	{
++	 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e},
++	{
++	 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d},
++	{
++	 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c},
++	{
++	 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b},
++	{
++	 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a},
++	{
++	 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209},
++	{
++	 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208},
++	{
++	 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207},
++	{
++	 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206},
++	{
++	 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205},
++	{
++	 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204},
++	{
++	 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x08, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203},
++	{
++	 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202},
++	{
++	 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201},
++	{
++	 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200},
++	{
++	 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x08, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff},
++	{
++	 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77,
++	 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e,
++	 0x00, 0x6f, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd},
++	{
++	 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77,
++	 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e,
++	 0x00, 0x6f, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc},
++	{
++	 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77,
++	 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0e,
++	 0x00, 0x6f, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb},
++	{
++	 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa},
++	{
++	 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9},
++	{
++	 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8},
++	{
++	 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xfe, 0xd8, 0x00, 0x05, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7},
++	{
++	 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xd8, 0x00, 0x05, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6},
++	{
++	 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xc8, 0x00, 0x05, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5},
++	{
++	 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xed, 0xc7, 0x00, 0x05, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4},
++	{
++	 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3},
++	{
++	 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77,
++	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2},
++	{
++	 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1},
++	{
++	 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0},
++	{
++	 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0},
++	{
++	 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef},
++	{
++	 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdb, 0xb7, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee},
++	{
++	 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xcb, 0xa6, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed},
++	{
++	 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec},
++	{
++	 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb},
++	{
++	 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea},
++	{
++	 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9},
++	{
++	 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x95, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8},
++	{
++	 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7},
++	{
++	 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6},
++	{
++	 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb7, 0x84, 0x00, 0x02, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5},
++	{
++	 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xa7, 0x84, 0x00, 0x02, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5},
++	{
++	 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4},
++	{
++	 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3},
++	{
++	 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2},
++	{
++	 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1},
++	{
++	 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x94, 0x73, 0x00, 0x01, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0},
++	{
++	 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x84, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df},
++	{
++	 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x83, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de},
++	{
++	 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd},
++	{
++	 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd},
++	{
++	 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc},
++	{
++	 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db},
++	{
++	 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x71, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da},
++	{
++	 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9},
++	{
++	 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8},
++	{
++	 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x62, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7},
++	{
++	 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x60, 0x62, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
++	 0x00, 0x6f, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7},
++	{
++	 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x50, 0x61, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x61, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
++	 0x00, 0x6f, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6},
++	{
++	 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
++	 0x00, 0x6f, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5},
++	{
++	 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
++	 0x00, 0x6f, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4},
++	{
++	 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
++	 0x00, 0x6f, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3},
++	{
++	 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
++	 0x00, 0x6f, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2},
++	{
++	 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x50, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
++	 0x00, 0x6f, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2},
++	{
++	 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
++	 0x00, 0x6f, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1},
++	{
++	 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6f, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0},
++	{
++	 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6f, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf},
++	{
++	 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6f, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce},
++	{
++	 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6f, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce},
++	{
++	 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6e, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd},
++	{
++	 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6e, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc},
++	{
++	 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6e, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb},
++	{
++	 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6e, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb},
++	{
++	 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6e, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca},
++	{
++	 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6d, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca},
++	{
++	 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6d, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9},
++	{
++	 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6d, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9},
++	{
++	 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6d, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6d, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9},
++	{
++	 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6c, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8},
++	{
++	 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6c, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8},
++	{
++	 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6c, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6c, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8},
++	{
++	 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7},
++	{
++	 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7},
++	{
++	 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6},
++	{
++	 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6},
++	{
++	 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6},
++	{
++	 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5},
++	{
++	 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5},
++	{
++	 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6a, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4},
++	{
++	 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6a, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4},
++	{
++	 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6a, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4},
++	{
++	 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6a, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3},
++	{
++	 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x69, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3},
++	{
++	 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x69, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2},
++	{
++	 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x69, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2},
++	{
++	 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x69, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1},
++	{
++	 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x69, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0},
++	{
++	 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x68, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf},
++	{
++	 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x68, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf},
++	{
++	 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x68, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be},
++	{
++	 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x68, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd},
++	{
++	 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x68, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc},
++	{
++	 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0b, 0x00, 0x0a, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443},
++	{
++	 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0b, 0x00, 0x0a, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441},
++	{
++	 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x67, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x67, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0b, 0x00, 0x0a, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f},
++	{
++	 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x57, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x57, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x0a, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d},
++	{
++	 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x56, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x56, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x0a, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a},
++	{
++	 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x46, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x46, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x0a, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438},
++	{
++	 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x45, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x45, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x0a, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436},
++	{
++	 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x34, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x34, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x09, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434},
++	{
++	 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x23, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x23, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x09, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431},
++	{
++	 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x12, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x12, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x09, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f},
++	{
++	 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x02, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x09, 0x00, 0x09, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d},
++	{
++	 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x01, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x09, 0x00, 0x09, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b},
++	{
++	 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x01, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x09, 0x00, 0x09, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429},
++	{
++	 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x07, 0x07, 0x07, 0x8f, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x09, 0x00, 0x09, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424}
++};
++
++static const struct chan_info_nphy_radio205x chan_info_nphyrev5n6_2056v7[] = {
++	{
++	 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
++	 0x00, 0x0f, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216},
++	{
++	 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
++	 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
++	 0x00, 0x6f, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215},
++	{
++	 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
++	 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
++	 0x00, 0x6f, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214},
++	{
++	 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
++	 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
++	 0x00, 0x6f, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213},
++	{
++	 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
++	 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0e,
++	 0x00, 0x6f, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212},
++	{
++	 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
++	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211},
++	{
++	 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
++	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f},
++	{
++	 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
++	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e},
++	{
++	 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
++	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d},
++	{
++	 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
++	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c},
++	{
++	 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x09, 0x00, 0x70,
++	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b},
++	{
++	 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x09, 0x00, 0x70,
++	 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a},
++	{
++	 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x70,
++	 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209},
++	{
++	 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x70,
++	 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208},
++	{
++	 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x70,
++	 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207},
++	{
++	 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x08, 0x00, 0x70,
++	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206},
++	{
++	 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
++	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205},
++	{
++	 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
++	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204},
++	{
++	 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
++	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203},
++	{
++	 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
++	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202},
++	{
++	 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
++	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201},
++	{
++	 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x08, 0x00, 0x70,
++	 0x00, 0x0a, 0x00, 0x9f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200},
++	{
++	 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x07, 0x00, 0x70,
++	 0x00, 0x0a, 0x00, 0x9f, 0x00, 0xfb, 0x00, 0x07, 0x00, 0x70, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff},
++	{
++	 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x07, 0x00, 0x70,
++	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfb, 0x00, 0x07, 0x00, 0x70, 0x00, 0x09,
++	 0x00, 0x6e, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd},
++	{
++	 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x06, 0x00, 0x70,
++	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfb, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
++	 0x00, 0x6e, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc},
++	{
++	 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
++	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
++	 0x00, 0x6e, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb},
++	{
++	 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
++	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
++	 0x00, 0x6e, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa},
++	{
++	 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
++	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
++	 0x00, 0x6e, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9},
++	{
++	 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
++	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
++	 0x00, 0x6e, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8},
++	{
++	 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xfe, 0xfa, 0x00, 0x06, 0x00, 0x70,
++	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
++	 0x00, 0x6e, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7},
++	{
++	 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xea, 0x00, 0x06, 0x00, 0x70,
++	 0x00, 0x08, 0x00, 0x9e, 0x00, 0xea, 0x00, 0x06, 0x00, 0x70, 0x00, 0x08,
++	 0x00, 0x6e, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6},
++	{
++	 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xe9, 0x00, 0x05, 0x00, 0x70,
++	 0x00, 0x08, 0x00, 0x9d, 0x00, 0xe9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
++	 0x00, 0x6d, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5},
++	{
++	 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xed, 0xe9, 0x00, 0x05, 0x00, 0x70,
++	 0x00, 0x08, 0x00, 0x9d, 0x00, 0xe9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
++	 0x00, 0x6d, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4},
++	{
++	 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0e, 0x00, 0xed, 0xd9, 0x00, 0x05, 0x00, 0x70,
++	 0x00, 0x08, 0x00, 0x9d, 0x00, 0xd9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
++	 0x00, 0x6d, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3},
++	{
++	 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8e, 0x0e, 0x00, 0xed, 0xd8, 0x00, 0x04, 0x00, 0x70,
++	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xd8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
++	 0x00, 0x6c, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2},
++	{
++	 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xc8, 0x00, 0x04, 0x00, 0x70,
++	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
++	 0x00, 0x6c, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1},
++	{
++	 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xc8, 0x00, 0x04, 0x00, 0x70,
++	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
++	 0x00, 0x6c, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0},
++	{
++	 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xc8, 0x00, 0x04, 0x00, 0x70,
++	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
++	 0x00, 0x6c, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0},
++	{
++	 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xc8, 0x00, 0x04, 0x00, 0x70,
++	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
++	 0x00, 0x6c, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef},
++	{
++	 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdb, 0xb8, 0x00, 0x04, 0x00, 0x70,
++	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xb8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
++	 0x00, 0x6c, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee},
++	{
++	 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xcb, 0xb7, 0x00, 0x04, 0x00, 0x70,
++	 0x00, 0x07, 0x00, 0x9b, 0x00, 0xb7, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
++	 0x00, 0x6b, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed},
++	{
++	 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xca, 0xb7, 0x00, 0x03, 0x00, 0x70,
++	 0x00, 0x07, 0x00, 0x9b, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x70, 0x00, 0x07,
++	 0x00, 0x6b, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec},
++	{
++	 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xca, 0xa7, 0x00, 0x03, 0x00, 0x70,
++	 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa7, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
++	 0x00, 0x6b, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb},
++	{
++	 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0xa6, 0x00, 0x03, 0x00, 0x70,
++	 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
++	 0x00, 0x6b, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea},
++	{
++	 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0xa6, 0x00, 0x03, 0x00, 0x70,
++	 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
++	 0x00, 0x7b, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9},
++	{
++	 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x96, 0x00, 0x03, 0x00, 0x70,
++	 0x00, 0x06, 0x00, 0x9a, 0x00, 0x96, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
++	 0x00, 0x7a, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8},
++	{
++	 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x95, 0x00, 0x03, 0x00, 0x70,
++	 0x00, 0x06, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
++	 0x00, 0x7a, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7},
++	{
++	 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x95, 0x00, 0x03, 0x00, 0x70,
++	 0x00, 0x06, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
++	 0x00, 0x7a, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6},
++	{
++	 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb7, 0x95, 0x00, 0x03, 0x00, 0x70,
++	 0x00, 0x05, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x05,
++	 0x00, 0x7a, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5},
++	{
++	 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xa7, 0x95, 0x00, 0x03, 0x00, 0x70,
++	 0x00, 0x05, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x05,
++	 0x00, 0x7a, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5},
++	{
++	 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0b, 0x00, 0xa6, 0x85, 0x00, 0x02, 0x00, 0x70,
++	 0x00, 0x05, 0x00, 0x99, 0x00, 0x85, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
++	 0x00, 0x79, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4},
++	{
++	 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x70,
++	 0x00, 0x05, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
++	 0x00, 0x79, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3},
++	{
++	 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x02, 0x00, 0x70,
++	 0x00, 0x05, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
++	 0x00, 0x79, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2},
++	{
++	 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x02, 0x00, 0x70,
++	 0x00, 0x04, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x04,
++	 0x00, 0x79, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1},
++	{
++	 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x94, 0x74, 0x00, 0x01, 0x00, 0x70,
++	 0x00, 0x04, 0x00, 0x99, 0x00, 0x74, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
++	 0x00, 0x79, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0},
++	{
++	 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x84, 0x73, 0x00, 0x01, 0x00, 0x70,
++	 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
++	 0x00, 0x78, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df},
++	{
++	 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x83, 0x73, 0x00, 0x01, 0x00, 0x70,
++	 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
++	 0x00, 0x78, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de},
++	{
++	 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x01, 0x00, 0x70,
++	 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
++	 0x00, 0x78, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd},
++	{
++	 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x01, 0x00, 0x70,
++	 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
++	 0x00, 0x78, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd},
++	{
++	 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x72, 0x73, 0x00, 0x01, 0x00, 0x70,
++	 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
++	 0x00, 0x78, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc},
++	{
++	 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x72, 0x63, 0x00, 0x01, 0x00, 0x70,
++	 0x00, 0x03, 0x00, 0x98, 0x00, 0x63, 0x00, 0x01, 0x00, 0x70, 0x00, 0x03,
++	 0x00, 0x78, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db},
++	{
++	 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x71, 0x62, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
++	 0x00, 0x77, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da},
++	{
++	 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x62, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
++	 0x00, 0x77, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9},
++	{
++	 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x62, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
++	 0x00, 0x77, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8},
++	{
++	 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x52, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x02, 0x00, 0x96, 0x00, 0x52, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
++	 0x00, 0x76, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7},
++	{
++	 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x60, 0x52, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x02, 0x00, 0x96, 0x00, 0x52, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
++	 0x00, 0x86, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7},
++	{
++	 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
++	 0x00, 0x86, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6},
++	{
++	 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
++	 0x00, 0x86, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5},
++	{
++	 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
++	 0x00, 0x86, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4},
++	{
++	 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
++	 0x00, 0x86, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3},
++	{
++	 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
++	 0x00, 0x86, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2},
++	{
++	 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x51, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x02, 0x00, 0x95, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
++	 0x00, 0x85, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2},
++	{
++	 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x50, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x95, 0x00, 0x50, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x85, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1},
++	{
++	 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x50, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x95, 0x00, 0x50, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x85, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0},
++	{
++	 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x84, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf},
++	{
++	 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x84, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce},
++	{
++	 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x94, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce},
++	{
++	 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x94, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd},
++	{
++	 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x94, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc},
++	{
++	 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x94, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb},
++	{
++	 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x94, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb},
++	{
++	 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x94, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x94, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca},
++	{
++	 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x93, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca},
++	{
++	 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x93, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9},
++	{
++	 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x93, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9},
++	{
++	 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x93, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9},
++	{
++	 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x10, 0x30, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x93, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8},
++	{
++	 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x93, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x93, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8},
++	{
++	 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x92, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8},
++	{
++	 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x92, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7},
++	{
++	 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x92, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7},
++	{
++	 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x92, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6},
++	{
++	 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x92, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6},
++	{
++	 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x92, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6},
++	{
++	 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x92, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5},
++	{
++	 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x92, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5},
++	{
++	 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x92, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4},
++	{
++	 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x92, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4},
++	{
++	 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x92, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4},
++	{
++	 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x92, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3},
++	{
++	 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x92, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3},
++	{
++	 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x92, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2},
++	{
++	 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x92, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2},
++	{
++	 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x92, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1},
++	{
++	 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x92, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0},
++	{
++	 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x91, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf},
++	{
++	 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x91, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf},
++	{
++	 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x91, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be},
++	{
++	 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x91, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd},
++	{
++	 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x91, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc},
++	{
++	 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x89, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0b, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0b, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443},
++	{
++	 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x89, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0a, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441},
++	{
++	 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x89, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0a, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f},
++	{
++	 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0e, 0x00, 0x0a, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d},
++	{
++	 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x77, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0e, 0x00, 0x0a, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a},
++	{
++	 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x76, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x76, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0e, 0x00, 0x0a, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438},
++	{
++	 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x66, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x66, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0e, 0x00, 0x0a, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436},
++	{
++	 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x55, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0e, 0x00, 0x09, 0x00, 0x55, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0e, 0x00, 0x09, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434},
++	{
++	 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x45, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0e, 0x00, 0x09, 0x00, 0x45, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0e, 0x00, 0x09, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431},
++	{
++	 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x34, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0d, 0x00, 0x09, 0x00, 0x34, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0d, 0x00, 0x09, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f},
++	{
++	 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0d, 0x00, 0x09, 0x00, 0x33, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0d, 0x00, 0x09, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d},
++	{
++	 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x22, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x22, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0d, 0x00, 0x08, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b},
++	{
++	 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x11, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0d, 0x00, 0x08, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429},
++	{
++	 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x07, 0x07, 0x07, 0x8f, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0d, 0x00, 0x08, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424}
++};
++
++static const struct chan_info_nphy_radio205x chan_info_nphyrev6_2056v8[] = {
++	{
++	 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216},
++	{
++	 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215},
++	{
++	 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214},
++	{
++	 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213},
++	{
++	 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212},
++	{
++	 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211},
++	{
++	 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f},
++	{
++	 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e},
++	{
++	 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d},
++	{
++	 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c},
++	{
++	 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b},
++	{
++	 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a},
++	{
++	 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209},
++	{
++	 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208},
++	{
++	 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207},
++	{
++	 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206},
++	{
++	 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205},
++	{
++	 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204},
++	{
++	 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x08, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203},
++	{
++	 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202},
++	{
++	 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201},
++	{
++	 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200},
++	{
++	 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x08, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff},
++	{
++	 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77,
++	 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e,
++	 0x00, 0x6f, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd},
++	{
++	 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77,
++	 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e,
++	 0x00, 0x6f, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc},
++	{
++	 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77,
++	 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0e,
++	 0x00, 0x6f, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb},
++	{
++	 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa},
++	{
++	 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9},
++	{
++	 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8},
++	{
++	 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xfe, 0xd8, 0x00, 0x05, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7},
++	{
++	 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xd8, 0x00, 0x05, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6},
++	{
++	 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xc8, 0x00, 0x05, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5},
++	{
++	 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xed, 0xc7, 0x00, 0x05, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4},
++	{
++	 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3},
++	{
++	 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77,
++	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2},
++	{
++	 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1},
++	{
++	 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0},
++	{
++	 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0},
++	{
++	 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef},
++	{
++	 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdb, 0xb7, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee},
++	{
++	 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xcb, 0xa6, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed},
++	{
++	 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec},
++	{
++	 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb},
++	{
++	 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea},
++	{
++	 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9},
++	{
++	 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x95, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8},
++	{
++	 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7},
++	{
++	 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6},
++	{
++	 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb7, 0x84, 0x00, 0x02, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5},
++	{
++	 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xa7, 0x84, 0x00, 0x02, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5},
++	{
++	 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4},
++	{
++	 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3},
++	{
++	 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2},
++	{
++	 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1},
++	{
++	 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x94, 0x73, 0x00, 0x01, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0},
++	{
++	 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x84, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df},
++	{
++	 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x83, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de},
++	{
++	 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd},
++	{
++	 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd},
++	{
++	 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc},
++	{
++	 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db},
++	{
++	 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x71, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da},
++	{
++	 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9},
++	{
++	 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8},
++	{
++	 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x62, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7},
++	{
++	 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x60, 0x62, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
++	 0x00, 0x6f, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7},
++	{
++	 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x50, 0x61, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x61, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
++	 0x00, 0x6f, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6},
++	{
++	 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
++	 0x00, 0x6f, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5},
++	{
++	 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
++	 0x00, 0x6f, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4},
++	{
++	 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
++	 0x00, 0x6f, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3},
++	{
++	 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
++	 0x00, 0x6f, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2},
++	{
++	 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x50, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
++	 0x00, 0x6f, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2},
++	{
++	 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
++	 0x00, 0x6f, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1},
++	{
++	 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6f, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0},
++	{
++	 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6f, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf},
++	{
++	 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6f, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce},
++	{
++	 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6f, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce},
++	{
++	 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6e, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd},
++	{
++	 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6e, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc},
++	{
++	 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6e, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb},
++	{
++	 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6e, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb},
++	{
++	 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6e, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca},
++	{
++	 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6d, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca},
++	{
++	 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6d, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9},
++	{
++	 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6d, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9},
++	{
++	 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6d, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6d, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9},
++	{
++	 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6c, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8},
++	{
++	 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6c, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8},
++	{
++	 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6c, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6c, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8},
++	{
++	 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7},
++	{
++	 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7},
++	{
++	 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6},
++	{
++	 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6},
++	{
++	 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6},
++	{
++	 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5},
++	{
++	 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5},
++	{
++	 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6a, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4},
++	{
++	 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6a, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4},
++	{
++	 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6a, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4},
++	{
++	 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6a, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3},
++	{
++	 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x69, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3},
++	{
++	 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x69, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2},
++	{
++	 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x69, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2},
++	{
++	 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x69, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1},
++	{
++	 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x69, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0},
++	{
++	 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x68, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf},
++	{
++	 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x68, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf},
++	{
++	 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x68, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be},
++	{
++	 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x68, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd},
++	{
++	 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x68, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc},
++	{
++	 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0b, 0x00, 0x0a, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443},
++	{
++	 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0b, 0x00, 0x0a, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441},
++	{
++	 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x67, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0b, 0x00, 0x0a, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f},
++	{
++	 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x57, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x0a, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d},
++	{
++	 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x56, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x77, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x0a, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a},
++	{
++	 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x46, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x76, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x0a, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438},
++	{
++	 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x45, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x66, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x0a, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436},
++	{
++	 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x34, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x55, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x09, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434},
++	{
++	 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x23, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x45, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x09, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431},
++	{
++	 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x12, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x34, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x09, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f},
++	{
++	 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x33, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x09, 0x00, 0x09, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d},
++	{
++	 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x22, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x09, 0x00, 0x09, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b},
++	{
++	 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x11, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x09, 0x00, 0x09, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429},
++	{
++	 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x07, 0x07, 0x07, 0x8f, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x09, 0x00, 0x09, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424}
++};
++
++static const struct chan_info_nphy_radio205x chan_info_nphyrev6_2056v11[] = {
++	{
++	 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216},
++	{
++	 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215},
++	{
++	 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214},
++	{
++	 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213},
++	{
++	 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212},
++	{
++	 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211},
++	{
++	 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f},
++	{
++	 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e},
++	{
++	 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d},
++	{
++	 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c},
++	{
++	 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b},
++	{
++	 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a},
++	{
++	 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209},
++	{
++	 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208},
++	{
++	 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207},
++	{
++	 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206},
++	{
++	 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205},
++	{
++	 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204},
++	{
++	 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x08, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203},
++	{
++	 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202},
++	{
++	 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201},
++	{
++	 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200},
++	{
++	 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x08, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff},
++	{
++	 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77,
++	 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e,
++	 0x00, 0x6f, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd},
++	{
++	 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77,
++	 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e,
++	 0x00, 0x6f, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc},
++	{
++	 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77,
++	 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0e,
++	 0x00, 0x6f, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb},
++	{
++	 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa},
++	{
++	 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9},
++	{
++	 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8},
++	{
++	 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xfe, 0xd8, 0x00, 0x05, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7},
++	{
++	 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xd8, 0x00, 0x05, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6},
++	{
++	 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xc8, 0x00, 0x05, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5},
++	{
++	 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xed, 0xc7, 0x00, 0x05, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4},
++	{
++	 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3},
++	{
++	 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77,
++	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2},
++	{
++	 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1},
++	{
++	 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0},
++	{
++	 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0},
++	{
++	 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef},
++	{
++	 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdb, 0xb7, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee},
++	{
++	 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xcb, 0xa6, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed},
++	{
++	 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec},
++	{
++	 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb},
++	{
++	 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea},
++	{
++	 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9},
++	{
++	 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x95, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8},
++	{
++	 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7},
++	{
++	 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6},
++	{
++	 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb7, 0x84, 0x00, 0x02, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5},
++	{
++	 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xa7, 0x84, 0x00, 0x02, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5},
++	{
++	 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4},
++	{
++	 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3},
++	{
++	 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2},
++	{
++	 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1},
++	{
++	 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x94, 0x73, 0x00, 0x01, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0},
++	{
++	 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x84, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df},
++	{
++	 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x83, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de},
++	{
++	 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd},
++	{
++	 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd},
++	{
++	 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc},
++	{
++	 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db},
++	{
++	 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x71, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da},
++	{
++	 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9},
++	{
++	 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8},
++	{
++	 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x62, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7},
++	{
++	 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x60, 0x62, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
++	 0x00, 0x6f, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7},
++	{
++	 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x50, 0x61, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x61, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
++	 0x00, 0x6f, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6},
++	{
++	 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
++	 0x00, 0x6f, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5},
++	{
++	 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
++	 0x00, 0x6f, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4},
++	{
++	 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
++	 0x00, 0x6f, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3},
++	{
++	 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
++	 0x00, 0x6f, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2},
++	{
++	 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x50, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
++	 0x00, 0x6f, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2},
++	{
++	 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
++	 0x00, 0x6f, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1},
++	{
++	 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6f, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0},
++	{
++	 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6f, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf},
++	{
++	 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6f, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce},
++	{
++	 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6f, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce},
++	{
++	 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6e, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd},
++	{
++	 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6e, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc},
++	{
++	 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6e, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb},
++	{
++	 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x05, 0x05, 0x02, 0x15, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6e, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb},
++	{
++	 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6e, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca},
++	{
++	 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x05, 0x05, 0x02, 0x15, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6d, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca},
++	{
++	 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6d, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9},
++	{
++	 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x05, 0x05, 0x02, 0x15, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6d, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9},
++	{
++	 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6d, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6d, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9},
++	{
++	 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x05, 0x05, 0x02, 0x15, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6c, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8},
++	{
++	 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6c, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8},
++	{
++	 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x05, 0x05, 0x02, 0x15, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6c, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6c, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8},
++	{
++	 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7},
++	{
++	 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x05, 0x05, 0x02, 0x15, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7},
++	{
++	 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6},
++	{
++	 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x05, 0x05, 0x02, 0x15, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6},
++	{
++	 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6},
++	{
++	 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x05, 0x05, 0x02, 0x15, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5},
++	{
++	 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5},
++	{
++	 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x05, 0x05, 0x02, 0x15, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6a, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4},
++	{
++	 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6a, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4},
++	{
++	 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x05, 0x05, 0x02, 0x15, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6a, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4},
++	{
++	 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6a, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3},
++	{
++	 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x05, 0x05, 0x02, 0x15, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x69, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3},
++	{
++	 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x69, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2},
++	{
++	 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x69, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2},
++	{
++	 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x69, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1},
++	{
++	 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x69, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0},
++	{
++	 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x68, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf},
++	{
++	 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x68, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf},
++	{
++	 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x68, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be},
++	{
++	 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x68, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd},
++	{
++	 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x68, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc},
++	{
++	 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x06, 0x06, 0x04, 0x2b, 0x01,
++	 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0b, 0x00, 0x0a, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443},
++	{
++	 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x06, 0x06, 0x04, 0x2b, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0b, 0x00, 0x0a, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441},
++	{
++	 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x06, 0x06, 0x04, 0x2b, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x67, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0b, 0x00, 0x0a, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f},
++	{
++	 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x06, 0x06, 0x04, 0x2b, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x57, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x0a, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d},
++	{
++	 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x06, 0x06, 0x04, 0x2b, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x56, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x77, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x0a, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a},
++	{
++	 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x06, 0x06, 0x04, 0x2b, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x46, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x76, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x0a, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438},
++	{
++	 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x06, 0x06, 0x04, 0x2b, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x45, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x66, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x0a, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436},
++	{
++	 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x06, 0x06, 0x04, 0x2b, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x34, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x55, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x09, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434},
++	{
++	 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x06, 0x06, 0x04, 0x2b, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x23, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x45, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x09, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431},
++	{
++	 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x06, 0x06, 0x04, 0x2b, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x12, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x34, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x09, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f},
++	{
++	 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x06, 0x06, 0x04, 0x2b, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x33, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x09, 0x00, 0x09, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d},
++	{
++	 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x06, 0x06, 0x04, 0x2b, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x22, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x09, 0x00, 0x09, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b},
++	{
++	 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x06, 0x06, 0x04, 0x2b, 0x01,
++	 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x11, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x09, 0x00, 0x09, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429},
++	{
++	 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x06, 0x06, 0x04, 0x2b, 0x01,
++	 0x07, 0x07, 0x07, 0x8f, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x09, 0x00, 0x09, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424}
++};
++
++static const struct chan_info_nphy_radio2057 chan_info_nphyrev7_2057_rev4[] = {
++	{
++	 184, 4920, 0x68, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xec, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
++	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07b4, 0x07b0, 0x07ac, 0x0214,
++	 0x0215,
++	 0x0216,
++	 },
++	{
++	 186, 4930, 0x6b, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xed, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
++	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07b8, 0x07b4, 0x07b0, 0x0213,
++	 0x0214,
++	 0x0215,
++	 },
++	{
++	 188, 4940, 0x6e, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xee, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
++	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07bc, 0x07b8, 0x07b4, 0x0212,
++	 0x0213,
++	 0x0214,
++	 },
++	{
++	 190, 4950, 0x72, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xef, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
++	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07c0, 0x07bc, 0x07b8, 0x0211,
++	 0x0212,
++	 0x0213,
++	 },
++	{
++	 192, 4960, 0x75, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf0, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
++	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07c4, 0x07c0, 0x07bc, 0x020f,
++	 0x0211,
++	 0x0212,
++	 },
++	{
++	 194, 4970, 0x78, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf1, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
++	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07c8, 0x07c4, 0x07c0, 0x020e,
++	 0x020f,
++	 0x0211,
++	 },
++	{
++	 196, 4980, 0x7c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf2, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
++	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07cc, 0x07c8, 0x07c4, 0x020d,
++	 0x020e,
++	 0x020f,
++	 },
++	{
++	 198, 4990, 0x7f, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf3, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
++	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07d0, 0x07cc, 0x07c8, 0x020c,
++	 0x020d,
++	 0x020e,
++	 },
++	{
++	 200, 5000, 0x82, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf4, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
++	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07d4, 0x07d0, 0x07cc, 0x020b,
++	 0x020c,
++	 0x020d,
++	 },
++	{
++	 202, 5010, 0x86, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf5, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
++	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07d8, 0x07d4, 0x07d0, 0x020a,
++	 0x020b,
++	 0x020c,
++	 },
++	{
++	 204, 5020, 0x89, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf6, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
++	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07dc, 0x07d8, 0x07d4, 0x0209,
++	 0x020a,
++	 0x020b,
++	 },
++	{
++	 206, 5030, 0x8c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf7, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
++	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07e0, 0x07dc, 0x07d8, 0x0208,
++	 0x0209,
++	 0x020a,
++	 },
++	{
++	 208, 5040, 0x90, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf8, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
++	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07e4, 0x07e0, 0x07dc, 0x0207,
++	 0x0208,
++	 0x0209,
++	 },
++	{
++	 210, 5050, 0x93, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf9, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
++	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07e8, 0x07e4, 0x07e0, 0x0206,
++	 0x0207,
++	 0x0208,
++	 },
++	{
++	 212, 5060, 0x96, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfa, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xe3, 0x00, 0xef, 0x00,
++	 0x00, 0x0f, 0x0f, 0xe3, 0x00, 0xef, 0x07ec, 0x07e8, 0x07e4, 0x0205,
++	 0x0206,
++	 0x0207,
++	 },
++	{
++	 214, 5070, 0x9a, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfb, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xef, 0x00,
++	 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xef, 0x07f0, 0x07ec, 0x07e8, 0x0204,
++	 0x0205,
++	 0x0206,
++	 },
++	{
++	 216, 5080, 0x9d, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfc, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xef, 0x00,
++	 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xef, 0x07f4, 0x07f0, 0x07ec, 0x0203,
++	 0x0204,
++	 0x0205,
++	 },
++	{
++	 218, 5090, 0xa0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfd, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x00,
++	 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x07f8, 0x07f4, 0x07f0, 0x0202,
++	 0x0203,
++	 0x0204,
++	 },
++	{
++	 220, 5100, 0xa4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfe, 0x01, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x00,
++	 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x07fc, 0x07f8, 0x07f4, 0x0201,
++	 0x0202,
++	 0x0203,
++	 },
++	{
++	 222, 5110, 0xa7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xff, 0x01, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x00,
++	 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x0800, 0x07fc, 0x07f8, 0x0200,
++	 0x0201,
++	 0x0202,
++	 },
++	{
++	 224, 5120, 0xaa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x00, 0x02, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x00,
++	 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x0804, 0x0800, 0x07fc, 0x01ff,
++	 0x0200,
++	 0x0201,
++	 },
++	{
++	 226, 5130, 0xae, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x01, 0x02, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x00,
++	 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x0808, 0x0804, 0x0800, 0x01fe,
++	 0x01ff,
++	 0x0200,
++	 },
++	{
++	 228, 5140, 0xb1, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x02, 0x02, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0e, 0x0e, 0xe3, 0x00, 0xd6, 0x00,
++	 0x00, 0x0e, 0x0e, 0xe3, 0x00, 0xd6, 0x080c, 0x0808, 0x0804, 0x01fd,
++	 0x01fe,
++	 0x01ff,
++	 },
++	{
++	 32, 5160, 0xb8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x04, 0x02, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0d, 0x0e, 0xe3, 0x00, 0xd6, 0x00,
++	 0x00, 0x0d, 0x0e, 0xe3, 0x00, 0xd6, 0x0814, 0x0810, 0x080c, 0x01fb,
++	 0x01fc,
++	 0x01fd,
++	 },
++	{
++	 34, 5170, 0xbb, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x05, 0x02, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0d, 0x0e, 0xe3, 0x00, 0xd6, 0x00,
++	 0x00, 0x0d, 0x0e, 0xe3, 0x00, 0xd6, 0x0818, 0x0814, 0x0810, 0x01fa,
++	 0x01fb,
++	 0x01fc,
++	 },
++	{
++	 36, 5180, 0xbe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x06, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
++	 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x081c, 0x0818, 0x0814, 0x01f9,
++	 0x01fa,
++	 0x01fb,
++	 },
++	{
++	 38, 5190, 0xc2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x07, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
++	 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x0820, 0x081c, 0x0818, 0x01f8,
++	 0x01f9,
++	 0x01fa,
++	 },
++	{
++	 40, 5200, 0xc5, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x08, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
++	 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x0824, 0x0820, 0x081c, 0x01f7,
++	 0x01f8,
++	 0x01f9,
++	 },
++	{
++	 42, 5210, 0xc8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x09, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
++	 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x0828, 0x0824, 0x0820, 0x01f6,
++	 0x01f7,
++	 0x01f8,
++	 },
++	{
++	 44, 5220, 0xcc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0a, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
++	 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x082c, 0x0828, 0x0824, 0x01f5,
++	 0x01f6,
++	 0x01f7,
++	 },
++	{
++	 46, 5230, 0xcf, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0b, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
++	 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x0830, 0x082c, 0x0828, 0x01f4,
++	 0x01f5,
++	 0x01f6,
++	 },
++	{
++	 48, 5240, 0xd2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0c, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
++	 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x0834, 0x0830, 0x082c, 0x01f3,
++	 0x01f4,
++	 0x01f5,
++	 },
++	{
++	 50, 5250, 0xd6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0d, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
++	 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x0838, 0x0834, 0x0830, 0x01f2,
++	 0x01f3,
++	 0x01f4,
++	 },
++	{
++	 52, 5260, 0xd9, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0e, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0c, 0x0d, 0xd3, 0x00, 0xd6, 0x00,
++	 0x00, 0x0c, 0x0d, 0xd3, 0x00, 0xd6, 0x083c, 0x0838, 0x0834, 0x01f1,
++	 0x01f2,
++	 0x01f3,
++	 },
++	{
++	 54, 5270, 0xdc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0f, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0c, 0x0d, 0xd3, 0x00, 0xd6, 0x00,
++	 0x00, 0x0c, 0x0d, 0xd3, 0x00, 0xd6, 0x0840, 0x083c, 0x0838, 0x01f0,
++	 0x01f1,
++	 0x01f2,
++	 },
++	{
++	 56, 5280, 0xe0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x10, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x00,
++	 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x0844, 0x0840, 0x083c, 0x01f0,
++	 0x01f0,
++	 0x01f1,
++	 },
++	{
++	 58, 5290, 0xe3, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x11, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x00,
++	 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x0848, 0x0844, 0x0840, 0x01ef,
++	 0x01f0,
++	 0x01f0,
++	 },
++	{
++	 60, 5300, 0xe6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x12, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x00,
++	 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x084c, 0x0848, 0x0844, 0x01ee,
++	 0x01ef,
++	 0x01f0,
++	 },
++	{
++	 62, 5310, 0xea, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x13, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x00,
++	 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x0850, 0x084c, 0x0848, 0x01ed,
++	 0x01ee,
++	 0x01ef,
++	 },
++	{
++	 64, 5320, 0xed, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x14, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x00,
++	 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x0854, 0x0850, 0x084c, 0x01ec,
++	 0x01ed,
++	 0x01ee,
++	 },
++	{
++	 66, 5330, 0xf0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x15, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x00,
++	 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x0858, 0x0854, 0x0850, 0x01eb,
++	 0x01ec,
++	 0x01ed,
++	 },
++	{
++	 68, 5340, 0xf4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x16, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0c, 0xc3, 0x00, 0xa1, 0x00,
++	 0x00, 0x0a, 0x0c, 0xc3, 0x00, 0xa1, 0x085c, 0x0858, 0x0854, 0x01ea,
++	 0x01eb,
++	 0x01ec,
++	 },
++	{
++	 70, 5350, 0xf7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x17, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x00,
++	 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x0860, 0x085c, 0x0858, 0x01e9,
++	 0x01ea,
++	 0x01eb,
++	 },
++	{
++	 72, 5360, 0xfa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x18, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x00,
++	 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x0864, 0x0860, 0x085c, 0x01e8,
++	 0x01e9,
++	 0x01ea,
++	 },
++	{
++	 74, 5370, 0xfe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x19, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x00,
++	 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x0868, 0x0864, 0x0860, 0x01e7,
++	 0x01e8,
++	 0x01e9,
++	 },
++	{
++	 76, 5380, 0x01, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1a, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x00,
++	 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x086c, 0x0868, 0x0864, 0x01e6,
++	 0x01e7,
++	 0x01e8,
++	 },
++	{
++	 78, 5390, 0x04, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1b, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0a, 0xa3, 0x00, 0xa1, 0x00,
++	 0x00, 0x0a, 0x0a, 0xa3, 0x00, 0xa1, 0x0870, 0x086c, 0x0868, 0x01e5,
++	 0x01e6,
++	 0x01e7,
++	 },
++	{
++	 80, 5400, 0x08, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1c, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x09, 0x0a, 0xa3, 0x00, 0x90, 0x00,
++	 0x00, 0x09, 0x0a, 0xa3, 0x00, 0x90, 0x0874, 0x0870, 0x086c, 0x01e5,
++	 0x01e5,
++	 0x01e6,
++	 },
++	{
++	 82, 5410, 0x0b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1d, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x09, 0x0a, 0xa3, 0x00, 0x90, 0x00,
++	 0x00, 0x09, 0x0a, 0xa3, 0x00, 0x90, 0x0878, 0x0874, 0x0870, 0x01e4,
++	 0x01e5,
++	 0x01e5,
++	 },
++	{
++	 84, 5420, 0x0e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1e, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x09, 0x09, 0xa3, 0x00, 0x90, 0x00,
++	 0x00, 0x09, 0x09, 0xa3, 0x00, 0x90, 0x087c, 0x0878, 0x0874, 0x01e3,
++	 0x01e4,
++	 0x01e5,
++	 },
++	{
++	 86, 5430, 0x12, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1f, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x00,
++	 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x0880, 0x087c, 0x0878, 0x01e2,
++	 0x01e3,
++	 0x01e4,
++	 },
++	{
++	 88, 5440, 0x15, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x20, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x00,
++	 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x0884, 0x0880, 0x087c, 0x01e1,
++	 0x01e2,
++	 0x01e3,
++	 },
++	{
++	 90, 5450, 0x18, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x21, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x00,
++	 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x0888, 0x0884, 0x0880, 0x01e0,
++	 0x01e1,
++	 0x01e2,
++	 },
++	{
++	 92, 5460, 0x1c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x22, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x08, 0x93, 0x00, 0x90, 0x00,
++	 0x00, 0x08, 0x08, 0x93, 0x00, 0x90, 0x088c, 0x0888, 0x0884, 0x01df,
++	 0x01e0,
++	 0x01e1,
++	 },
++	{
++	 94, 5470, 0x1f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x23, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x08, 0x93, 0x00, 0x60, 0x00,
++	 0x00, 0x08, 0x08, 0x93, 0x00, 0x60, 0x0890, 0x088c, 0x0888, 0x01de,
++	 0x01df,
++	 0x01e0,
++	 },
++	{
++	 96, 5480, 0x22, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x24, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x00,
++	 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x0894, 0x0890, 0x088c, 0x01dd,
++	 0x01de,
++	 0x01df,
++	 },
++	{
++	 98, 5490, 0x26, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x25, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x00,
++	 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x0898, 0x0894, 0x0890, 0x01dd,
++	 0x01dd,
++	 0x01de,
++	 },
++	{
++	 100, 5500, 0x29, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x26, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x00,
++	 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x089c, 0x0898, 0x0894, 0x01dc,
++	 0x01dd,
++	 0x01dd,
++	 },
++	{
++	 102, 5510, 0x2c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x27, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x00,
++	 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x08a0, 0x089c, 0x0898, 0x01db,
++	 0x01dc,
++	 0x01dd,
++	 },
++	{
++	 104, 5520, 0x30, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x28, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x00,
++	 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x08a4, 0x08a0, 0x089c, 0x01da,
++	 0x01db,
++	 0x01dc,
++	 },
++	{
++	 106, 5530, 0x33, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x29, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x00,
++	 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x08a8, 0x08a4, 0x08a0, 0x01d9,
++	 0x01da,
++	 0x01db,
++	 },
++	{
++	 108, 5540, 0x36, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2a, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x00,
++	 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x08ac, 0x08a8, 0x08a4, 0x01d8,
++	 0x01d9,
++	 0x01da,
++	 },
++	{
++	 110, 5550, 0x3a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2b, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x00,
++	 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x08b0, 0x08ac, 0x08a8, 0x01d7,
++	 0x01d8,
++	 0x01d9,
++	 },
++	{
++	 112, 5560, 0x3d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2c, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x00,
++	 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x08b4, 0x08b0, 0x08ac, 0x01d7,
++	 0x01d7,
++	 0x01d8,
++	 },
++	{
++	 114, 5570, 0x40, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2d, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x00,
++	 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x08b8, 0x08b4, 0x08b0, 0x01d6,
++	 0x01d7,
++	 0x01d7,
++	 },
++	{
++	 116, 5580, 0x44, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2e, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x07, 0x05, 0x83, 0x00, 0x60, 0x00,
++	 0x00, 0x07, 0x05, 0x83, 0x00, 0x60, 0x08bc, 0x08b8, 0x08b4, 0x01d5,
++	 0x01d6,
++	 0x01d7,
++	 },
++	{
++	 118, 5590, 0x47, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2f, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x07, 0x04, 0x83, 0x00, 0x60, 0x00,
++	 0x00, 0x07, 0x04, 0x83, 0x00, 0x60, 0x08c0, 0x08bc, 0x08b8, 0x01d4,
++	 0x01d5,
++	 0x01d6,
++	 },
++	{
++	 120, 5600, 0x4a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x30, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x07, 0x04, 0x73, 0x00, 0x30, 0x00,
++	 0x00, 0x07, 0x04, 0x73, 0x00, 0x30, 0x08c4, 0x08c0, 0x08bc, 0x01d3,
++	 0x01d4,
++	 0x01d5,
++	 },
++	{
++	 122, 5610, 0x4e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x31, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x00,
++	 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x08c8, 0x08c4, 0x08c0, 0x01d2,
++	 0x01d3,
++	 0x01d4,
++	 },
++	{
++	 124, 5620, 0x51, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x32, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x00,
++	 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x08cc, 0x08c8, 0x08c4, 0x01d2,
++	 0x01d2,
++	 0x01d3,
++	 },
++	{
++	 126, 5630, 0x54, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x33, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x00,
++	 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x08d0, 0x08cc, 0x08c8, 0x01d1,
++	 0x01d2,
++	 0x01d2,
++	 },
++	{
++	 128, 5640, 0x58, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x34, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x00,
++	 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x08d4, 0x08d0, 0x08cc, 0x01d0,
++	 0x01d1,
++	 0x01d2,
++	 },
++	{
++	 130, 5650, 0x5b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x35, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x06, 0x03, 0x63, 0x00, 0x30, 0x00,
++	 0x00, 0x06, 0x03, 0x63, 0x00, 0x30, 0x08d8, 0x08d4, 0x08d0, 0x01cf,
++	 0x01d0,
++	 0x01d1,
++	 },
++	{
++	 132, 5660, 0x5e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x36, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x06, 0x03, 0x63, 0x00, 0x30, 0x00,
++	 0x00, 0x06, 0x03, 0x63, 0x00, 0x30, 0x08dc, 0x08d8, 0x08d4, 0x01ce,
++	 0x01cf,
++	 0x01d0,
++	 },
++	{
++	 134, 5670, 0x62, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x37, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x03, 0x63, 0x00, 0x00, 0x00,
++	 0x00, 0x05, 0x03, 0x63, 0x00, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce,
++	 0x01ce,
++	 0x01cf,
++	 },
++	{
++	 136, 5680, 0x65, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x38, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x00,
++	 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd,
++	 0x01ce,
++	 0x01ce,
++	 },
++	{
++	 138, 5690, 0x68, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x39, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x00,
++	 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc,
++	 0x01cd,
++	 0x01ce,
++	 },
++	{
++	 140, 5700, 0x6c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3a, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x00,
++	 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb,
++	 0x01cc,
++	 0x01cd,
++	 },
++	{
++	 142, 5710, 0x6f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3b, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x00,
++	 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca,
++	 0x01cb,
++	 0x01cc,
++	 },
++	{
++	 144, 5720, 0x72, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3c, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x00,
++	 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9,
++	 0x01ca,
++	 0x01cb,
++	 },
++	{
++	 145, 5725, 0x74, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x79, 0x04, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x05, 0x01, 0x53, 0x00, 0x00, 0x00,
++	 0x00, 0x05, 0x01, 0x53, 0x00, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9,
++	 0x01ca,
++	 0x01cb,
++	 },
++	{
++	 146, 5730, 0x76, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3d, 0x02, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00,
++	 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9,
++	 0x01c9,
++	 0x01ca,
++	 },
++	{
++	 147, 5735, 0x77, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7b, 0x04, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00,
++	 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8,
++	 0x01c9,
++	 0x01ca,
++	 },
++	{
++	 148, 5740, 0x79, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3e, 0x02, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00,
++	 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8,
++	 0x01c9,
++	 0x01c9,
++	 },
++	{
++	 149, 5745, 0x7b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7d, 0x04, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00,
++	 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8,
++	 0x01c8,
++	 0x01c9,
++	 },
++	{
++	 150, 5750, 0x7c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3f, 0x02, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00,
++	 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7,
++	 0x01c8,
++	 0x01c9,
++	 },
++	{
++	 151, 5755, 0x7e, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7f, 0x04, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00,
++	 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7,
++	 0x01c8,
++	 0x01c8,
++	 },
++	{
++	 152, 5760, 0x80, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x40, 0x02, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6,
++	 0x01c7,
++	 0x01c8,
++	 },
++	{
++	 153, 5765, 0x81, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x81, 0x04, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6,
++	 0x01c7,
++	 0x01c8,
++	 },
++	{
++	 154, 5770, 0x83, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x41, 0x02, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6,
++	 0x01c6,
++	 0x01c7,
++	 },
++	{
++	 155, 5775, 0x85, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x83, 0x04, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5,
++	 0x01c6,
++	 0x01c7,
++	 },
++	{
++	 156, 5780, 0x86, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x42, 0x02, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x03, 0x01, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x03, 0x01, 0x43, 0x00, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5,
++	 0x01c6,
++	 0x01c6,
++	 },
++	{
++	 157, 5785, 0x88, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x85, 0x04, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4,
++	 0x01c5,
++	 0x01c6,
++	 },
++	{
++	 158, 5790, 0x8a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x43, 0x02, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4,
++	 0x01c5,
++	 0x01c6,
++	 },
++	{
++	 159, 5795, 0x8b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x87, 0x04, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4,
++	 0x01c4,
++	 0x01c5,
++	 },
++	{
++	 160, 5800, 0x8d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x44, 0x02, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3,
++	 0x01c4,
++	 0x01c5,
++	 },
++	{
++	 161, 5805, 0x8f, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x89, 0x04, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3,
++	 0x01c4,
++	 0x01c4,
++	 },
++	{
++	 162, 5810, 0x90, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x45, 0x02, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2,
++	 0x01c3,
++	 0x01c4,
++	 },
++	{
++	 163, 5815, 0x92, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8b, 0x04, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2,
++	 0x01c3,
++	 0x01c4,
++	 },
++	{
++	 164, 5820, 0x94, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x46, 0x02, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2,
++	 0x01c2,
++	 0x01c3,
++	 },
++	{
++	 165, 5825, 0x95, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8d, 0x04, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1,
++	 0x01c2,
++	 0x01c3,
++	 },
++	{
++	 166, 5830, 0x97, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x47, 0x02, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1,
++	 0x01c2,
++	 0x01c2,
++	 },
++	{
++	 168, 5840, 0x9a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x48, 0x02, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0,
++	 0x01c1,
++	 0x01c2,
++	 },
++	{
++	 170, 5850, 0x9e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x49, 0x02, 0x04,
++	 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf,
++	 0x01c0,
++	 0x01c1,
++	 },
++	{
++	 172, 5860, 0xa1, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4a, 0x02, 0x04,
++	 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf,
++	 0x01bf,
++	 0x01c0,
++	 },
++	{
++	 174, 5870, 0xa4, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4b, 0x02, 0x04,
++	 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0930, 0x092c, 0x0928, 0x01be,
++	 0x01bf,
++	 0x01bf,
++	 },
++	{
++	 176, 5880, 0xa8, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4c, 0x02, 0x03,
++	 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd,
++	 0x01be,
++	 0x01bf,
++	 },
++	{
++	 178, 5890, 0xab, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4d, 0x02, 0x03,
++	 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc,
++	 0x01bd,
++	 0x01be,
++	 },
++	{
++	 180, 5900, 0xae, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4e, 0x02, 0x03,
++	 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc,
++	 0x01bc,
++	 0x01bd,
++	 },
++	{
++	 1, 2412, 0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, 0x09, 0x0f,
++	 0x0a, 0x00, 0x0a, 0x00, 0x71, 0xa3, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x71,
++	 0xa3, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03c9, 0x03c5, 0x03c1, 0x043a,
++	 0x043f,
++	 0x0443,
++	 },
++	{
++	 2, 2417, 0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, 0x09, 0x0f,
++	 0x0a, 0x00, 0x0a, 0x00, 0x71, 0xa3, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x71,
++	 0xa3, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cb, 0x03c7, 0x03c3, 0x0438,
++	 0x043d,
++	 0x0441,
++	 },
++	{
++	 3, 2422, 0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, 0x09, 0x0f,
++	 0x09, 0x00, 0x09, 0x00, 0x71, 0x93, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x71,
++	 0x93, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cd, 0x03c9, 0x03c5, 0x0436,
++	 0x043a,
++	 0x043f,
++	 },
++	{
++	 4, 2427, 0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, 0x09, 0x0f,
++	 0x09, 0x00, 0x09, 0x00, 0x71, 0x93, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x71,
++	 0x93, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cf, 0x03cb, 0x03c7, 0x0434,
++	 0x0438,
++	 0x043d,
++	 },
++	{
++	 5, 2432, 0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, 0x09, 0x0f,
++	 0x08, 0x00, 0x08, 0x00, 0x51, 0x83, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x51,
++	 0x83, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d1, 0x03cd, 0x03c9, 0x0431,
++	 0x0436,
++	 0x043a,
++	 },
++	{
++	 6, 2437, 0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, 0x09, 0x0f,
++	 0x08, 0x00, 0x08, 0x00, 0x51, 0x83, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x51,
++	 0x83, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d3, 0x03cf, 0x03cb, 0x042f,
++	 0x0434,
++	 0x0438,
++	 },
++	{
++	 7, 2442, 0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, 0x09, 0x0f,
++	 0x07, 0x00, 0x07, 0x00, 0x51, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x51,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d5, 0x03d1, 0x03cd, 0x042d,
++	 0x0431,
++	 0x0436,
++	 },
++	{
++	 8, 2447, 0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, 0x09, 0x0f,
++	 0x07, 0x00, 0x07, 0x00, 0x31, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x31,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d7, 0x03d3, 0x03cf, 0x042b,
++	 0x042f,
++	 0x0434,
++	 },
++	{
++	 9, 2452, 0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, 0x09, 0x0f,
++	 0x07, 0x00, 0x07, 0x00, 0x31, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x31,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d9, 0x03d5, 0x03d1, 0x0429,
++	 0x042d,
++	 0x0431,
++	 },
++	{
++	 10, 2457, 0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, 0x09, 0x0f,
++	 0x06, 0x00, 0x06, 0x00, 0x31, 0x63, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x31,
++	 0x63, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03db, 0x03d7, 0x03d3, 0x0427,
++	 0x042b,
++	 0x042f,
++	 },
++	{
++	 11, 2462, 0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, 0x09, 0x0f,
++	 0x06, 0x00, 0x06, 0x00, 0x31, 0x63, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x31,
++	 0x63, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03dd, 0x03d9, 0x03d5, 0x0424,
++	 0x0429,
++	 0x042d,
++	 },
++	{
++	 12, 2467, 0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, 0x09, 0x0f,
++	 0x05, 0x00, 0x05, 0x00, 0x11, 0x53, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x11,
++	 0x53, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03df, 0x03db, 0x03d7, 0x0422,
++	 0x0427,
++	 0x042b,
++	 },
++	{
++	 13, 2472, 0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8, 0x09, 0x0f,
++	 0x05, 0x00, 0x05, 0x00, 0x11, 0x53, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x11,
++	 0x53, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03e1, 0x03dd, 0x03d9, 0x0420,
++	 0x0424,
++	 0x0429,
++	 },
++	{
++	 14, 2484, 0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4, 0x09, 0x0f,
++	 0x04, 0x00, 0x04, 0x00, 0x11, 0x43, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x11,
++	 0x43, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x03e6, 0x03e2, 0x03de, 0x041b,
++	 0x041f,
++	 0x0424}
++};
++
++static const struct chan_info_nphy_radio2057_rev5
++chan_info_nphyrev8_2057_rev5[] = {
++	{
++	 1, 2412, 0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, 0x09, 0x0d,
++	 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61, 0x03, 0xff, 0x03c9, 0x03c5, 0x03c1,
++	 0x043a, 0x043f, 0x0443},
++	{
++	 2, 2417, 0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, 0x09, 0x0d,
++	 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61, 0x03, 0xff, 0x03cb, 0x03c7, 0x03c3,
++	 0x0438, 0x043d, 0x0441},
++	{
++	 3, 2422, 0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, 0x09, 0x0d,
++	 0x08, 0x0e, 0x61, 0x03, 0xef, 0x61, 0x03, 0xef, 0x03cd, 0x03c9, 0x03c5,
++	 0x0436, 0x043a, 0x043f},
++	{
++	 4, 2427, 0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, 0x09, 0x0c,
++	 0x08, 0x0e, 0x61, 0x03, 0xdf, 0x61, 0x03, 0xdf, 0x03cf, 0x03cb, 0x03c7,
++	 0x0434, 0x0438, 0x043d},
++	{
++	 5, 2432, 0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, 0x09, 0x0c,
++	 0x07, 0x0d, 0x61, 0x03, 0xcf, 0x61, 0x03, 0xcf, 0x03d1, 0x03cd, 0x03c9,
++	 0x0431, 0x0436, 0x043a},
++	{
++	 6, 2437, 0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, 0x09, 0x0c,
++	 0x07, 0x0d, 0x61, 0x03, 0xbf, 0x61, 0x03, 0xbf, 0x03d3, 0x03cf, 0x03cb,
++	 0x042f, 0x0434, 0x0438},
++	{
++	 7, 2442, 0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, 0x09, 0x0b,
++	 0x07, 0x0d, 0x61, 0x03, 0xaf, 0x61, 0x03, 0xaf, 0x03d5, 0x03d1, 0x03cd,
++	 0x042d, 0x0431, 0x0436},
++	{
++	 8, 2447, 0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, 0x09, 0x0b,
++	 0x07, 0x0d, 0x61, 0x03, 0x9f, 0x61, 0x03, 0x9f, 0x03d7, 0x03d3, 0x03cf,
++	 0x042b, 0x042f, 0x0434},
++	{
++	 9, 2452, 0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, 0x09, 0x0b,
++	 0x07, 0x0d, 0x61, 0x03, 0x8f, 0x61, 0x03, 0x8f, 0x03d9, 0x03d5, 0x03d1,
++	 0x0429, 0x042d, 0x0431},
++	{
++	 10, 2457, 0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, 0x09, 0x0b,
++	 0x07, 0x0c, 0x61, 0x03, 0x7f, 0x61, 0x03, 0x7f, 0x03db, 0x03d7, 0x03d3,
++	 0x0427, 0x042b, 0x042f},
++	{
++	 11, 2462, 0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, 0x09, 0x0b,
++	 0x07, 0x0c, 0x61, 0x03, 0x6f, 0x61, 0x03, 0x6f, 0x03dd, 0x03d9, 0x03d5,
++	 0x0424, 0x0429, 0x042d},
++	{
++	 12, 2467, 0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, 0x09, 0x0b,
++	 0x06, 0x0c, 0x61, 0x03, 0x5f, 0x61, 0x03, 0x5f, 0x03df, 0x03db, 0x03d7,
++	 0x0422, 0x0427, 0x042b},
++	{
++	 13, 2472, 0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8, 0x09, 0x0a,
++	 0x06, 0x0b, 0x61, 0x03, 0x4f, 0x61, 0x03, 0x4f, 0x03e1, 0x03dd, 0x03d9,
++	 0x0420, 0x0424, 0x0429},
++	{
++	 14, 2484, 0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4, 0x09, 0x0a,
++	 0x06, 0x0b, 0x61, 0x03, 0x3f, 0x61, 0x03, 0x3f, 0x03e6, 0x03e2, 0x03de,
++	 0x041b, 0x041f, 0x0424}
++};
++
++static const struct chan_info_nphy_radio2057_rev5
++chan_info_nphyrev9_2057_rev5v1[] = {
++	{
++	 1, 2412, 0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, 0x09, 0x0d,
++	 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61, 0x03, 0xff, 0x03c9, 0x03c5, 0x03c1,
++	 0x043a, 0x043f, 0x0443},
++	{
++	 2, 2417, 0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, 0x09, 0x0d,
++	 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61, 0x03, 0xff, 0x03cb, 0x03c7, 0x03c3,
++	 0x0438, 0x043d, 0x0441},
++	{
++	 3, 2422, 0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, 0x09, 0x0d,
++	 0x08, 0x0e, 0x61, 0x03, 0xef, 0x61, 0x03, 0xef, 0x03cd, 0x03c9, 0x03c5,
++	 0x0436, 0x043a, 0x043f},
++	{
++	 4, 2427, 0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, 0x09, 0x0c,
++	 0x08, 0x0e, 0x61, 0x03, 0xdf, 0x61, 0x03, 0xdf, 0x03cf, 0x03cb, 0x03c7,
++	 0x0434, 0x0438, 0x043d},
++	{
++	 5, 2432, 0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, 0x09, 0x0c,
++	 0x07, 0x0d, 0x61, 0x03, 0xcf, 0x61, 0x03, 0xcf, 0x03d1, 0x03cd, 0x03c9,
++	 0x0431, 0x0436, 0x043a},
++	{
++	 6, 2437, 0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, 0x09, 0x0c,
++	 0x07, 0x0d, 0x61, 0x03, 0xbf, 0x61, 0x03, 0xbf, 0x03d3, 0x03cf, 0x03cb,
++	 0x042f, 0x0434, 0x0438},
++	{
++	 7, 2442, 0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, 0x09, 0x0b,
++	 0x07, 0x0d, 0x61, 0x03, 0xaf, 0x61, 0x03, 0xaf, 0x03d5, 0x03d1, 0x03cd,
++	 0x042d, 0x0431, 0x0436},
++	{
++	 8, 2447, 0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, 0x09, 0x0b,
++	 0x07, 0x0d, 0x61, 0x03, 0x9f, 0x61, 0x03, 0x9f, 0x03d7, 0x03d3, 0x03cf,
++	 0x042b, 0x042f, 0x0434},
++	{
++	 9, 2452, 0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, 0x09, 0x0b,
++	 0x07, 0x0d, 0x61, 0x03, 0x8f, 0x61, 0x03, 0x8f, 0x03d9, 0x03d5, 0x03d1,
++	 0x0429, 0x042d, 0x0431},
++	{
++	 10, 2457, 0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, 0x09, 0x0b,
++	 0x07, 0x0c, 0x61, 0x03, 0x7f, 0x61, 0x03, 0x7f, 0x03db, 0x03d7, 0x03d3,
++	 0x0427, 0x042b, 0x042f},
++	{
++	 11, 2462, 0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, 0x09, 0x0b,
++	 0x07, 0x0c, 0x61, 0x03, 0x6f, 0x61, 0x03, 0x6f, 0x03dd, 0x03d9, 0x03d5,
++	 0x0424, 0x0429, 0x042d},
++	{
++	 12, 2467, 0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, 0x09, 0x0b,
++	 0x06, 0x0c, 0x61, 0x03, 0x5f, 0x61, 0x03, 0x5f, 0x03df, 0x03db, 0x03d7,
++	 0x0422, 0x0427, 0x042b},
++	{
++	 13, 2472, 0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8, 0x09, 0x0a,
++	 0x06, 0x0b, 0x61, 0x03, 0x4f, 0x61, 0x03, 0x4f, 0x03e1, 0x03dd, 0x03d9,
++	 0x0420, 0x0424, 0x0429},
++	{
++	 14, 2484, 0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4, 0x09, 0x0a,
++	 0x06, 0x0b, 0x61, 0x03, 0x3f, 0x61, 0x03, 0x3f, 0x03e6, 0x03e2, 0x03de,
++	 0x041b, 0x041f, 0x0424}
++};
++
++static const struct chan_info_nphy_radio2057 chan_info_nphyrev8_2057_rev7[] = {
++	{
++	 184, 4920, 0x68, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xec, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xd3, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07b4, 0x07b0, 0x07ac, 0x0214,
++	 0x0215,
++	 0x0216},
++	{
++	 186, 4930, 0x6b, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xed, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xd3, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07b8, 0x07b4, 0x07b0, 0x0213,
++	 0x0214,
++	 0x0215},
++	{
++	 188, 4940, 0x6e, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xee, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xd3, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07bc, 0x07b8, 0x07b4, 0x0212,
++	 0x0213,
++	 0x0214},
++	{
++	 190, 4950, 0x72, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xef, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c0, 0x07bc, 0x07b8, 0x0211,
++	 0x0212,
++	 0x0213},
++	{
++	 192, 4960, 0x75, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf0, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c4, 0x07c0, 0x07bc, 0x020f,
++	 0x0211,
++	 0x0212},
++	{
++	 194, 4970, 0x78, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf1, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c8, 0x07c4, 0x07c0, 0x020e,
++	 0x020f,
++	 0x0211},
++	{
++	 196, 4980, 0x7c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf2, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07cc, 0x07c8, 0x07c4, 0x020d,
++	 0x020e,
++	 0x020f},
++	{
++	 198, 4990, 0x7f, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf3, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07d0, 0x07cc, 0x07c8, 0x020c,
++	 0x020d,
++	 0x020e},
++	{
++	 200, 5000, 0x82, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf4, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07d4, 0x07d0, 0x07cc, 0x020b,
++	 0x020c,
++	 0x020d},
++	{
++	 202, 5010, 0x86, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf5, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07d8, 0x07d4, 0x07d0, 0x020a,
++	 0x020b,
++	 0x020c},
++	{
++	 204, 5020, 0x89, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf6, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07dc, 0x07d8, 0x07d4, 0x0209,
++	 0x020a,
++	 0x020b},
++	{
++	 206, 5030, 0x8c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf7, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e0, 0x07dc, 0x07d8, 0x0208,
++	 0x0209,
++	 0x020a},
++	{
++	 208, 5040, 0x90, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf8, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e4, 0x07e0, 0x07dc, 0x0207,
++	 0x0208,
++	 0x0209},
++	{
++	 210, 5050, 0x93, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf9, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e8, 0x07e4, 0x07e0, 0x0206,
++	 0x0207,
++	 0x0208},
++	{
++	 212, 5060, 0x96, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfa, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07ec, 0x07e8, 0x07e4, 0x0205,
++	 0x0206,
++	 0x0207},
++	{
++	 214, 5070, 0x9a, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfb, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f0, 0x07ec, 0x07e8, 0x0204,
++	 0x0205,
++	 0x0206},
++	{
++	 216, 5080, 0x9d, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfc, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f4, 0x07f0, 0x07ec, 0x0203,
++	 0x0204,
++	 0x0205},
++	{
++	 218, 5090, 0xa0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfd, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f8, 0x07f4, 0x07f0, 0x0202,
++	 0x0203,
++	 0x0204},
++	{
++	 220, 5100, 0xa4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfe, 0x01, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
++	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x07fc, 0x07f8, 0x07f4, 0x0201,
++	 0x0202,
++	 0x0203},
++	{
++	 222, 5110, 0xa7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xff, 0x01, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
++	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0800, 0x07fc, 0x07f8, 0x0200,
++	 0x0201,
++	 0x0202},
++	{
++	 224, 5120, 0xaa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x00, 0x02, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
++	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0804, 0x0800, 0x07fc, 0x01ff,
++	 0x0200,
++	 0x0201},
++	{
++	 226, 5130, 0xae, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x01, 0x02, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
++	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0808, 0x0804, 0x0800, 0x01fe,
++	 0x01ff,
++	 0x0200},
++	{
++	 228, 5140, 0xb1, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x02, 0x02, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
++	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x080c, 0x0808, 0x0804, 0x01fd,
++	 0x01fe,
++	 0x01ff},
++	{
++	 32, 5160, 0xb8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x04, 0x02, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
++	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0814, 0x0810, 0x080c, 0x01fb,
++	 0x01fc,
++	 0x01fd},
++	{
++	 34, 5170, 0xbb, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x05, 0x02, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
++	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0818, 0x0814, 0x0810, 0x01fa,
++	 0x01fb,
++	 0x01fc},
++	{
++	 36, 5180, 0xbe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x06, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
++	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x081c, 0x0818, 0x0814, 0x01f9,
++	 0x01fa,
++	 0x01fb},
++	{
++	 38, 5190, 0xc2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x07, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
++	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0820, 0x081c, 0x0818, 0x01f8,
++	 0x01f9,
++	 0x01fa},
++	{
++	 40, 5200, 0xc5, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x08, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0824, 0x0820, 0x081c, 0x01f7,
++	 0x01f8,
++	 0x01f9},
++	{
++	 42, 5210, 0xc8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x09, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0828, 0x0824, 0x0820, 0x01f6,
++	 0x01f7,
++	 0x01f8},
++	{
++	 44, 5220, 0xcc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0a, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x082c, 0x0828, 0x0824, 0x01f5,
++	 0x01f6,
++	 0x01f7},
++	{
++	 46, 5230, 0xcf, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0b, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0830, 0x082c, 0x0828, 0x01f4,
++	 0x01f5,
++	 0x01f6},
++	{
++	 48, 5240, 0xd2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0c, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0834, 0x0830, 0x082c, 0x01f3,
++	 0x01f4,
++	 0x01f5},
++	{
++	 50, 5250, 0xd6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0d, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0838, 0x0834, 0x0830, 0x01f2,
++	 0x01f3,
++	 0x01f4},
++	{
++	 52, 5260, 0xd9, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0e, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x083c, 0x0838, 0x0834, 0x01f1,
++	 0x01f2,
++	 0x01f3},
++	{
++	 54, 5270, 0xdc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0f, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0840, 0x083c, 0x0838, 0x01f0,
++	 0x01f1,
++	 0x01f2},
++	{
++	 56, 5280, 0xe0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x10, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0844, 0x0840, 0x083c, 0x01f0,
++	 0x01f0,
++	 0x01f1},
++	{
++	 58, 5290, 0xe3, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x11, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0848, 0x0844, 0x0840, 0x01ef,
++	 0x01f0,
++	 0x01f0},
++	{
++	 60, 5300, 0xe6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x12, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x084c, 0x0848, 0x0844, 0x01ee,
++	 0x01ef,
++	 0x01f0},
++	{
++	 62, 5310, 0xea, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x13, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0850, 0x084c, 0x0848, 0x01ed,
++	 0x01ee,
++	 0x01ef},
++	{
++	 64, 5320, 0xed, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x14, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0854, 0x0850, 0x084c, 0x01ec,
++	 0x01ed,
++	 0x01ee},
++	{
++	 66, 5330, 0xf0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x15, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0858, 0x0854, 0x0850, 0x01eb,
++	 0x01ec,
++	 0x01ed},
++	{
++	 68, 5340, 0xf4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x16, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x085c, 0x0858, 0x0854, 0x01ea,
++	 0x01eb,
++	 0x01ec},
++	{
++	 70, 5350, 0xf7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x17, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0860, 0x085c, 0x0858, 0x01e9,
++	 0x01ea,
++	 0x01eb},
++	{
++	 72, 5360, 0xfa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x18, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0864, 0x0860, 0x085c, 0x01e8,
++	 0x01e9,
++	 0x01ea},
++	{
++	 74, 5370, 0xfe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x19, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0868, 0x0864, 0x0860, 0x01e7,
++	 0x01e8,
++	 0x01e9},
++	{
++	 76, 5380, 0x01, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1a, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x086c, 0x0868, 0x0864, 0x01e6,
++	 0x01e7,
++	 0x01e8},
++	{
++	 78, 5390, 0x04, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1b, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0870, 0x086c, 0x0868, 0x01e5,
++	 0x01e6,
++	 0x01e7},
++	{
++	 80, 5400, 0x08, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1c, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0874, 0x0870, 0x086c, 0x01e5,
++	 0x01e5,
++	 0x01e6},
++	{
++	 82, 5410, 0x0b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1d, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0878, 0x0874, 0x0870, 0x01e4,
++	 0x01e5,
++	 0x01e5},
++	{
++	 84, 5420, 0x0e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1e, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x087c, 0x0878, 0x0874, 0x01e3,
++	 0x01e4,
++	 0x01e5},
++	{
++	 86, 5430, 0x12, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1f, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0880, 0x087c, 0x0878, 0x01e2,
++	 0x01e3,
++	 0x01e4},
++	{
++	 88, 5440, 0x15, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x20, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0884, 0x0880, 0x087c, 0x01e1,
++	 0x01e2,
++	 0x01e3},
++	{
++	 90, 5450, 0x18, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x21, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0888, 0x0884, 0x0880, 0x01e0,
++	 0x01e1,
++	 0x01e2},
++	{
++	 92, 5460, 0x1c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x22, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x088c, 0x0888, 0x0884, 0x01df,
++	 0x01e0,
++	 0x01e1},
++	{
++	 94, 5470, 0x1f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x23, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0890, 0x088c, 0x0888, 0x01de,
++	 0x01df,
++	 0x01e0},
++	{
++	 96, 5480, 0x22, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x24, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0894, 0x0890, 0x088c, 0x01dd,
++	 0x01de,
++	 0x01df},
++	{
++	 98, 5490, 0x26, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x25, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0898, 0x0894, 0x0890, 0x01dd,
++	 0x01dd,
++	 0x01de},
++	{
++	 100, 5500, 0x29, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x26, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x089c, 0x0898, 0x0894, 0x01dc,
++	 0x01dd,
++	 0x01dd},
++	{
++	 102, 5510, 0x2c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x27, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a0, 0x089c, 0x0898, 0x01db,
++	 0x01dc,
++	 0x01dd},
++	{
++	 104, 5520, 0x30, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x28, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a4, 0x08a0, 0x089c, 0x01da,
++	 0x01db,
++	 0x01dc},
++	{
++	 106, 5530, 0x33, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x29, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a8, 0x08a4, 0x08a0, 0x01d9,
++	 0x01da,
++	 0x01db},
++	{
++	 108, 5540, 0x36, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2a, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08ac, 0x08a8, 0x08a4, 0x01d8,
++	 0x01d9,
++	 0x01da},
++	{
++	 110, 5550, 0x3a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2b, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b0, 0x08ac, 0x08a8, 0x01d7,
++	 0x01d8,
++	 0x01d9},
++	{
++	 112, 5560, 0x3d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2c, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b4, 0x08b0, 0x08ac, 0x01d7,
++	 0x01d7,
++	 0x01d8},
++	{
++	 114, 5570, 0x40, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2d, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b8, 0x08b4, 0x08b0, 0x01d6,
++	 0x01d7,
++	 0x01d7},
++	{
++	 116, 5580, 0x44, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2e, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08bc, 0x08b8, 0x08b4, 0x01d5,
++	 0x01d6,
++	 0x01d7},
++	{
++	 118, 5590, 0x47, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2f, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08c0, 0x08bc, 0x08b8, 0x01d4,
++	 0x01d5,
++	 0x01d6},
++	{
++	 120, 5600, 0x4a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x30, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08c4, 0x08c0, 0x08bc, 0x01d3,
++	 0x01d4,
++	 0x01d5},
++	{
++	 122, 5610, 0x4e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x31, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08c8, 0x08c4, 0x08c0, 0x01d2,
++	 0x01d3,
++	 0x01d4},
++	{
++	 124, 5620, 0x51, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x32, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08cc, 0x08c8, 0x08c4, 0x01d2,
++	 0x01d2,
++	 0x01d3},
++	{
++	 126, 5630, 0x54, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x33, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08d0, 0x08cc, 0x08c8, 0x01d1,
++	 0x01d2,
++	 0x01d2},
++	{
++	 128, 5640, 0x58, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x34, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08d4, 0x08d0, 0x08cc, 0x01d0,
++	 0x01d1,
++	 0x01d2},
++	{
++	 130, 5650, 0x5b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x35, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08d8, 0x08d4, 0x08d0, 0x01cf,
++	 0x01d0,
++	 0x01d1},
++	{
++	 132, 5660, 0x5e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x36, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08dc, 0x08d8, 0x08d4, 0x01ce,
++	 0x01cf,
++	 0x01d0},
++	{
++	 134, 5670, 0x62, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x37, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08e0, 0x08dc, 0x08d8, 0x01ce,
++	 0x01ce,
++	 0x01cf},
++	{
++	 136, 5680, 0x65, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x38, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x08e4, 0x08e0, 0x08dc, 0x01cd,
++	 0x01ce,
++	 0x01ce},
++	{
++	 138, 5690, 0x68, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x39, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x08e8, 0x08e4, 0x08e0, 0x01cc,
++	 0x01cd,
++	 0x01ce},
++	{
++	 140, 5700, 0x6c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3a, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08ec, 0x08e8, 0x08e4, 0x01cb,
++	 0x01cc,
++	 0x01cd},
++	{
++	 142, 5710, 0x6f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3b, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f0, 0x08ec, 0x08e8, 0x01ca,
++	 0x01cb,
++	 0x01cc},
++	{
++	 144, 5720, 0x72, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3c, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f4, 0x08f0, 0x08ec, 0x01c9,
++	 0x01ca,
++	 0x01cb},
++	{
++	 145, 5725, 0x74, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x79, 0x04, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f6, 0x08f2, 0x08ee, 0x01c9,
++	 0x01ca,
++	 0x01cb},
++	{
++	 146, 5730, 0x76, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3d, 0x02, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f8, 0x08f4, 0x08f0, 0x01c9,
++	 0x01c9,
++	 0x01ca},
++	{
++	 147, 5735, 0x77, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7b, 0x04, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fa, 0x08f6, 0x08f2, 0x01c8,
++	 0x01c9,
++	 0x01ca},
++	{
++	 148, 5740, 0x79, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3e, 0x02, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fc, 0x08f8, 0x08f4, 0x01c8,
++	 0x01c9,
++	 0x01c9},
++	{
++	 149, 5745, 0x7b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7d, 0x04, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fe, 0x08fa, 0x08f6, 0x01c8,
++	 0x01c8,
++	 0x01c9},
++	{
++	 150, 5750, 0x7c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3f, 0x02, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7,
++	 0x01c8,
++	 0x01c9},
++	{
++	 151, 5755, 0x7e, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7f, 0x04, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7,
++	 0x01c8,
++	 0x01c8},
++	{
++	 152, 5760, 0x80, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x40, 0x02, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6,
++	 0x01c7,
++	 0x01c8},
++	{
++	 153, 5765, 0x81, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x81, 0x04, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6,
++	 0x01c7,
++	 0x01c8},
++	{
++	 154, 5770, 0x83, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x41, 0x02, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6,
++	 0x01c6,
++	 0x01c7},
++	{
++	 155, 5775, 0x85, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x83, 0x04, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5,
++	 0x01c6,
++	 0x01c7},
++	{
++	 156, 5780, 0x86, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x42, 0x02, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5,
++	 0x01c6,
++	 0x01c6},
++	{
++	 157, 5785, 0x88, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x85, 0x04, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4,
++	 0x01c5,
++	 0x01c6},
++	{
++	 158, 5790, 0x8a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x43, 0x02, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4,
++	 0x01c5,
++	 0x01c6},
++	{
++	 159, 5795, 0x8b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x87, 0x04, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4,
++	 0x01c4,
++	 0x01c5},
++	{
++	 160, 5800, 0x8d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x44, 0x02, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x01, 0x03, 0x00, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3,
++	 0x01c4,
++	 0x01c5},
++	{
++	 161, 5805, 0x8f, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x89, 0x04, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3,
++	 0x01c4,
++	 0x01c4},
++	{
++	 162, 5810, 0x90, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x45, 0x02, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2,
++	 0x01c3,
++	 0x01c4},
++	{
++	 163, 5815, 0x92, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8b, 0x04, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2,
++	 0x01c3,
++	 0x01c4},
++	{
++	 164, 5820, 0x94, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x46, 0x02, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2,
++	 0x01c2,
++	 0x01c3},
++	{
++	 165, 5825, 0x95, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8d, 0x04, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1,
++	 0x01c2,
++	 0x01c3},
++	{
++	 166, 5830, 0x97, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x47, 0x02, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1,
++	 0x01c2,
++	 0x01c2},
++	{
++	 168, 5840, 0x9a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x48, 0x02, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0,
++	 0x01c1,
++	 0x01c2},
++	{
++	 170, 5850, 0x9e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x49, 0x02, 0x04,
++	 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf,
++	 0x01c0,
++	 0x01c1},
++	{
++	 172, 5860, 0xa1, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4a, 0x02, 0x04,
++	 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf,
++	 0x01bf,
++	 0x01c0},
++	{
++	 174, 5870, 0xa4, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4b, 0x02, 0x04,
++	 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0930, 0x092c, 0x0928, 0x01be,
++	 0x01bf,
++	 0x01bf},
++	{
++	 176, 5880, 0xa8, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4c, 0x02, 0x03,
++	 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd,
++	 0x01be,
++	 0x01bf},
++	{
++	 178, 5890, 0xab, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4d, 0x02, 0x03,
++	 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc,
++	 0x01bd,
++	 0x01be},
++	{
++	 180, 5900, 0xae, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4e, 0x02, 0x03,
++	 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc,
++	 0x01bc,
++	 0x01bd},
++	{
++	 1, 2412, 0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, 0x09, 0x0f,
++	 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03c9, 0x03c5, 0x03c1, 0x043a,
++	 0x043f,
++	 0x0443},
++	{
++	 2, 2417, 0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, 0x09, 0x0f,
++	 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cb, 0x03c7, 0x03c3, 0x0438,
++	 0x043d,
++	 0x0441},
++	{
++	 3, 2422, 0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, 0x09, 0x0f,
++	 0x09, 0x00, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cd, 0x03c9, 0x03c5, 0x0436,
++	 0x043a,
++	 0x043f},
++	{
++	 4, 2427, 0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, 0x09, 0x0f,
++	 0x09, 0x00, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cf, 0x03cb, 0x03c7, 0x0434,
++	 0x0438,
++	 0x043d},
++	{
++	 5, 2432, 0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, 0x09, 0x0f,
++	 0x08, 0x00, 0x08, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d1, 0x03cd, 0x03c9, 0x0431,
++	 0x0436,
++	 0x043a},
++	{
++	 6, 2437, 0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, 0x09, 0x0f,
++	 0x08, 0x00, 0x08, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d3, 0x03cf, 0x03cb, 0x042f,
++	 0x0434,
++	 0x0438},
++	{
++	 7, 2442, 0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, 0x09, 0x0f,
++	 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d5, 0x03d1, 0x03cd, 0x042d,
++	 0x0431,
++	 0x0436},
++	{
++	 8, 2447, 0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, 0x09, 0x0f,
++	 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d7, 0x03d3, 0x03cf, 0x042b,
++	 0x042f,
++	 0x0434},
++	{
++	 9, 2452, 0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, 0x09, 0x0f,
++	 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d9, 0x03d5, 0x03d1, 0x0429,
++	 0x042d,
++	 0x0431},
++	{
++	 10, 2457, 0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, 0x09, 0x0f,
++	 0x06, 0x00, 0x06, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03db, 0x03d7, 0x03d3, 0x0427,
++	 0x042b,
++	 0x042f},
++	{
++	 11, 2462, 0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, 0x09, 0x0f,
++	 0x06, 0x00, 0x06, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03dd, 0x03d9, 0x03d5, 0x0424,
++	 0x0429,
++	 0x042d},
++	{
++	 12, 2467, 0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, 0x09, 0x0f,
++	 0x05, 0x00, 0x05, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03df, 0x03db, 0x03d7, 0x0422,
++	 0x0427,
++	 0x042b},
++	{
++	 13, 2472, 0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8, 0x09, 0x0f,
++	 0x05, 0x00, 0x05, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03e1, 0x03dd, 0x03d9, 0x0420,
++	 0x0424,
++	 0x0429},
++	{
++	 14, 2484, 0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4, 0x09, 0x0f,
++	 0x04, 0x00, 0x04, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x03e6, 0x03e2, 0x03de, 0x041b,
++	 0x041f,
++	 0x0424}
++};
++
++static const struct chan_info_nphy_radio2057 chan_info_nphyrev8_2057_rev8[] = {
++	{
++	 186, 4930, 0x6b, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xed, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xd3, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07b8, 0x07b4, 0x07b0, 0x0213,
++	 0x0214,
++	 0x0215},
++	{
++	 188, 4940, 0x6e, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xee, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xd3, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07bc, 0x07b8, 0x07b4, 0x0212,
++	 0x0213,
++	 0x0214},
++	{
++	 190, 4950, 0x72, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xef, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c0, 0x07bc, 0x07b8, 0x0211,
++	 0x0212,
++	 0x0213},
++	{
++	 192, 4960, 0x75, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf0, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c4, 0x07c0, 0x07bc, 0x020f,
++	 0x0211,
++	 0x0212},
++	{
++	 194, 4970, 0x78, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf1, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c8, 0x07c4, 0x07c0, 0x020e,
++	 0x020f,
++	 0x0211},
++	{
++	 196, 4980, 0x7c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf2, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07cc, 0x07c8, 0x07c4, 0x020d,
++	 0x020e,
++	 0x020f},
++	{
++	 198, 4990, 0x7f, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf3, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07d0, 0x07cc, 0x07c8, 0x020c,
++	 0x020d,
++	 0x020e},
++	{
++	 200, 5000, 0x82, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf4, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07d4, 0x07d0, 0x07cc, 0x020b,
++	 0x020c,
++	 0x020d},
++	{
++	 202, 5010, 0x86, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf5, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07d8, 0x07d4, 0x07d0, 0x020a,
++	 0x020b,
++	 0x020c},
++	{
++	 204, 5020, 0x89, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf6, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07dc, 0x07d8, 0x07d4, 0x0209,
++	 0x020a,
++	 0x020b},
++	{
++	 206, 5030, 0x8c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf7, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e0, 0x07dc, 0x07d8, 0x0208,
++	 0x0209,
++	 0x020a},
++	{
++	 208, 5040, 0x90, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf8, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e4, 0x07e0, 0x07dc, 0x0207,
++	 0x0208,
++	 0x0209},
++	{
++	 210, 5050, 0x93, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf9, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e8, 0x07e4, 0x07e0, 0x0206,
++	 0x0207,
++	 0x0208},
++	{
++	 212, 5060, 0x96, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfa, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07ec, 0x07e8, 0x07e4, 0x0205,
++	 0x0206,
++	 0x0207},
++	{
++	 214, 5070, 0x9a, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfb, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f0, 0x07ec, 0x07e8, 0x0204,
++	 0x0205,
++	 0x0206},
++	{
++	 216, 5080, 0x9d, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfc, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f4, 0x07f0, 0x07ec, 0x0203,
++	 0x0204,
++	 0x0205},
++	{
++	 218, 5090, 0xa0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfd, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f8, 0x07f4, 0x07f0, 0x0202,
++	 0x0203,
++	 0x0204},
++	{
++	 220, 5100, 0xa4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfe, 0x01, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
++	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x07fc, 0x07f8, 0x07f4, 0x0201,
++	 0x0202,
++	 0x0203},
++	{
++	 222, 5110, 0xa7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xff, 0x01, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
++	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0800, 0x07fc, 0x07f8, 0x0200,
++	 0x0201,
++	 0x0202},
++	{
++	 224, 5120, 0xaa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x00, 0x02, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
++	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0804, 0x0800, 0x07fc, 0x01ff,
++	 0x0200,
++	 0x0201},
++	{
++	 226, 5130, 0xae, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x01, 0x02, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
++	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0808, 0x0804, 0x0800, 0x01fe,
++	 0x01ff,
++	 0x0200},
++	{
++	 228, 5140, 0xb1, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x02, 0x02, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
++	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x080c, 0x0808, 0x0804, 0x01fd,
++	 0x01fe,
++	 0x01ff},
++	{
++	 32, 5160, 0xb8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x04, 0x02, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
++	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0814, 0x0810, 0x080c, 0x01fb,
++	 0x01fc,
++	 0x01fd},
++	{
++	 34, 5170, 0xbb, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x05, 0x02, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
++	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0818, 0x0814, 0x0810, 0x01fa,
++	 0x01fb,
++	 0x01fc},
++	{
++	 36, 5180, 0xbe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x06, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
++	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x081c, 0x0818, 0x0814, 0x01f9,
++	 0x01fa,
++	 0x01fb},
++	{
++	 38, 5190, 0xc2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x07, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
++	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0820, 0x081c, 0x0818, 0x01f8,
++	 0x01f9,
++	 0x01fa},
++	{
++	 40, 5200, 0xc5, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x08, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0824, 0x0820, 0x081c, 0x01f7,
++	 0x01f8,
++	 0x01f9},
++	{
++	 42, 5210, 0xc8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x09, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0828, 0x0824, 0x0820, 0x01f6,
++	 0x01f7,
++	 0x01f8},
++	{
++	 44, 5220, 0xcc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0a, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x082c, 0x0828, 0x0824, 0x01f5,
++	 0x01f6,
++	 0x01f7},
++	{
++	 46, 5230, 0xcf, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0b, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0830, 0x082c, 0x0828, 0x01f4,
++	 0x01f5,
++	 0x01f6},
++	{
++	 48, 5240, 0xd2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0c, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0834, 0x0830, 0x082c, 0x01f3,
++	 0x01f4,
++	 0x01f5},
++	{
++	 50, 5250, 0xd6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0d, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0838, 0x0834, 0x0830, 0x01f2,
++	 0x01f3,
++	 0x01f4},
++	{
++	 52, 5260, 0xd9, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0e, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x083c, 0x0838, 0x0834, 0x01f1,
++	 0x01f2,
++	 0x01f3},
++	{
++	 54, 5270, 0xdc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0f, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0840, 0x083c, 0x0838, 0x01f0,
++	 0x01f1,
++	 0x01f2},
++	{
++	 56, 5280, 0xe0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x10, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0844, 0x0840, 0x083c, 0x01f0,
++	 0x01f0,
++	 0x01f1},
++	{
++	 58, 5290, 0xe3, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x11, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0848, 0x0844, 0x0840, 0x01ef,
++	 0x01f0,
++	 0x01f0},
++	{
++	 60, 5300, 0xe6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x12, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x084c, 0x0848, 0x0844, 0x01ee,
++	 0x01ef,
++	 0x01f0},
++	{
++	 62, 5310, 0xea, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x13, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0850, 0x084c, 0x0848, 0x01ed,
++	 0x01ee,
++	 0x01ef},
++	{
++	 64, 5320, 0xed, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x14, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0854, 0x0850, 0x084c, 0x01ec,
++	 0x01ed,
++	 0x01ee},
++	{
++	 66, 5330, 0xf0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x15, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0858, 0x0854, 0x0850, 0x01eb,
++	 0x01ec,
++	 0x01ed},
++	{
++	 68, 5340, 0xf4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x16, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x085c, 0x0858, 0x0854, 0x01ea,
++	 0x01eb,
++	 0x01ec},
++	{
++	 70, 5350, 0xf7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x17, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0860, 0x085c, 0x0858, 0x01e9,
++	 0x01ea,
++	 0x01eb},
++	{
++	 72, 5360, 0xfa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x18, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0864, 0x0860, 0x085c, 0x01e8,
++	 0x01e9,
++	 0x01ea},
++	{
++	 74, 5370, 0xfe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x19, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0868, 0x0864, 0x0860, 0x01e7,
++	 0x01e8,
++	 0x01e9},
++	{
++	 76, 5380, 0x01, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1a, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x086c, 0x0868, 0x0864, 0x01e6,
++	 0x01e7,
++	 0x01e8},
++	{
++	 78, 5390, 0x04, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1b, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0870, 0x086c, 0x0868, 0x01e5,
++	 0x01e6,
++	 0x01e7},
++	{
++	 80, 5400, 0x08, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1c, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0874, 0x0870, 0x086c, 0x01e5,
++	 0x01e5,
++	 0x01e6},
++	{
++	 82, 5410, 0x0b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1d, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0878, 0x0874, 0x0870, 0x01e4,
++	 0x01e5,
++	 0x01e5},
++	{
++	 84, 5420, 0x0e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1e, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x087c, 0x0878, 0x0874, 0x01e3,
++	 0x01e4,
++	 0x01e5},
++	{
++	 86, 5430, 0x12, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1f, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0880, 0x087c, 0x0878, 0x01e2,
++	 0x01e3,
++	 0x01e4},
++	{
++	 88, 5440, 0x15, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x20, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0884, 0x0880, 0x087c, 0x01e1,
++	 0x01e2,
++	 0x01e3},
++	{
++	 90, 5450, 0x18, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x21, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0888, 0x0884, 0x0880, 0x01e0,
++	 0x01e1,
++	 0x01e2},
++	{
++	 92, 5460, 0x1c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x22, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x088c, 0x0888, 0x0884, 0x01df,
++	 0x01e0,
++	 0x01e1},
++	{
++	 94, 5470, 0x1f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x23, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0890, 0x088c, 0x0888, 0x01de,
++	 0x01df,
++	 0x01e0},
++	{
++	 96, 5480, 0x22, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x24, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0894, 0x0890, 0x088c, 0x01dd,
++	 0x01de,
++	 0x01df},
++	{
++	 98, 5490, 0x26, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x25, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0898, 0x0894, 0x0890, 0x01dd,
++	 0x01dd,
++	 0x01de},
++	{
++	 100, 5500, 0x29, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x26, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x089c, 0x0898, 0x0894, 0x01dc,
++	 0x01dd,
++	 0x01dd},
++	{
++	 102, 5510, 0x2c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x27, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a0, 0x089c, 0x0898, 0x01db,
++	 0x01dc,
++	 0x01dd},
++	{
++	 104, 5520, 0x30, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x28, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a4, 0x08a0, 0x089c, 0x01da,
++	 0x01db,
++	 0x01dc},
++	{
++	 106, 5530, 0x33, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x29, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a8, 0x08a4, 0x08a0, 0x01d9,
++	 0x01da,
++	 0x01db},
++	{
++	 108, 5540, 0x36, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2a, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08ac, 0x08a8, 0x08a4, 0x01d8,
++	 0x01d9,
++	 0x01da},
++	{
++	 110, 5550, 0x3a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2b, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b0, 0x08ac, 0x08a8, 0x01d7,
++	 0x01d8,
++	 0x01d9},
++	{
++	 112, 5560, 0x3d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2c, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b4, 0x08b0, 0x08ac, 0x01d7,
++	 0x01d7,
++	 0x01d8},
++	{
++	 114, 5570, 0x40, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2d, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b8, 0x08b4, 0x08b0, 0x01d6,
++	 0x01d7,
++	 0x01d7},
++	{
++	 116, 5580, 0x44, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2e, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08bc, 0x08b8, 0x08b4, 0x01d5,
++	 0x01d6,
++	 0x01d7},
++	{
++	 118, 5590, 0x47, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2f, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08c0, 0x08bc, 0x08b8, 0x01d4,
++	 0x01d5,
++	 0x01d6},
++	{
++	 120, 5600, 0x4a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x30, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08c4, 0x08c0, 0x08bc, 0x01d3,
++	 0x01d4,
++	 0x01d5},
++	{
++	 122, 5610, 0x4e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x31, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08c8, 0x08c4, 0x08c0, 0x01d2,
++	 0x01d3,
++	 0x01d4},
++	{
++	 124, 5620, 0x51, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x32, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08cc, 0x08c8, 0x08c4, 0x01d2,
++	 0x01d2,
++	 0x01d3},
++	{
++	 126, 5630, 0x54, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x33, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08d0, 0x08cc, 0x08c8, 0x01d1,
++	 0x01d2,
++	 0x01d2},
++	{
++	 128, 5640, 0x58, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x34, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08d4, 0x08d0, 0x08cc, 0x01d0,
++	 0x01d1,
++	 0x01d2},
++	{
++	 130, 5650, 0x5b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x35, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08d8, 0x08d4, 0x08d0, 0x01cf,
++	 0x01d0,
++	 0x01d1},
++	{
++	 132, 5660, 0x5e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x36, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08dc, 0x08d8, 0x08d4, 0x01ce,
++	 0x01cf,
++	 0x01d0},
++	{
++	 134, 5670, 0x62, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x37, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08e0, 0x08dc, 0x08d8, 0x01ce,
++	 0x01ce,
++	 0x01cf},
++	{
++	 136, 5680, 0x65, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x38, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x08e4, 0x08e0, 0x08dc, 0x01cd,
++	 0x01ce,
++	 0x01ce},
++	{
++	 138, 5690, 0x68, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x39, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x08e8, 0x08e4, 0x08e0, 0x01cc,
++	 0x01cd,
++	 0x01ce},
++	{
++	 140, 5700, 0x6c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3a, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08ec, 0x08e8, 0x08e4, 0x01cb,
++	 0x01cc,
++	 0x01cd},
++	{
++	 142, 5710, 0x6f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3b, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f0, 0x08ec, 0x08e8, 0x01ca,
++	 0x01cb,
++	 0x01cc},
++	{
++	 144, 5720, 0x72, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3c, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f4, 0x08f0, 0x08ec, 0x01c9,
++	 0x01ca,
++	 0x01cb},
++	{
++	 145, 5725, 0x74, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x79, 0x04, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f6, 0x08f2, 0x08ee, 0x01c9,
++	 0x01ca,
++	 0x01cb},
++	{
++	 146, 5730, 0x76, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3d, 0x02, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f8, 0x08f4, 0x08f0, 0x01c9,
++	 0x01c9,
++	 0x01ca},
++	{
++	 147, 5735, 0x77, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7b, 0x04, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fa, 0x08f6, 0x08f2, 0x01c8,
++	 0x01c9,
++	 0x01ca},
++	{
++	 148, 5740, 0x79, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3e, 0x02, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fc, 0x08f8, 0x08f4, 0x01c8,
++	 0x01c9,
++	 0x01c9},
++	{
++	 149, 5745, 0x7b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7d, 0x04, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fe, 0x08fa, 0x08f6, 0x01c8,
++	 0x01c8,
++	 0x01c9},
++	{
++	 150, 5750, 0x7c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3f, 0x02, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7,
++	 0x01c8,
++	 0x01c9},
++	{
++	 151, 5755, 0x7e, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7f, 0x04, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7,
++	 0x01c8,
++	 0x01c8},
++	{
++	 152, 5760, 0x80, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x40, 0x02, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6,
++	 0x01c7,
++	 0x01c8},
++	{
++	 153, 5765, 0x81, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x81, 0x04, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6,
++	 0x01c7,
++	 0x01c8},
++	{
++	 154, 5770, 0x83, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x41, 0x02, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6,
++	 0x01c6,
++	 0x01c7},
++	{
++	 155, 5775, 0x85, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x83, 0x04, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5,
++	 0x01c6,
++	 0x01c7},
++	{
++	 156, 5780, 0x86, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x42, 0x02, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5,
++	 0x01c6,
++	 0x01c6},
++	{
++	 157, 5785, 0x88, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x85, 0x04, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4,
++	 0x01c5,
++	 0x01c6},
++	{
++	 158, 5790, 0x8a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x43, 0x02, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4,
++	 0x01c5,
++	 0x01c6},
++	{
++	 159, 5795, 0x8b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x87, 0x04, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4,
++	 0x01c4,
++	 0x01c5},
++	{
++	 160, 5800, 0x8d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x44, 0x02, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x01, 0x03, 0x00, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3,
++	 0x01c4,
++	 0x01c5},
++	{
++	 161, 5805, 0x8f, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x89, 0x04, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3,
++	 0x01c4,
++	 0x01c4},
++	{
++	 162, 5810, 0x90, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x45, 0x02, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2,
++	 0x01c3,
++	 0x01c4},
++	{
++	 163, 5815, 0x92, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8b, 0x04, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2,
++	 0x01c3,
++	 0x01c4},
++	{
++	 164, 5820, 0x94, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x46, 0x02, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2,
++	 0x01c2,
++	 0x01c3},
++	{
++	 165, 5825, 0x95, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8d, 0x04, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1,
++	 0x01c2,
++	 0x01c3},
++	{
++	 166, 5830, 0x97, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x47, 0x02, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1,
++	 0x01c2,
++	 0x01c2},
++	{
++	 168, 5840, 0x9a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x48, 0x02, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0,
++	 0x01c1,
++	 0x01c2},
++	{
++	 170, 5850, 0x9e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x49, 0x02, 0x04,
++	 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf,
++	 0x01c0,
++	 0x01c1},
++	{
++	 172, 5860, 0xa1, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4a, 0x02, 0x04,
++	 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf,
++	 0x01bf,
++	 0x01c0},
++	{
++	 174, 5870, 0xa4, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4b, 0x02, 0x04,
++	 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0930, 0x092c, 0x0928, 0x01be,
++	 0x01bf,
++	 0x01bf},
++	{
++	 176, 5880, 0xa8, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4c, 0x02, 0x03,
++	 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd,
++	 0x01be,
++	 0x01bf},
++	{
++	 178, 5890, 0xab, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4d, 0x02, 0x03,
++	 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc,
++	 0x01bd,
++	 0x01be},
++	{
++	 180, 5900, 0xae, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4e, 0x02, 0x03,
++	 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc,
++	 0x01bc,
++	 0x01bd},
++	{
++	 1, 2412, 0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, 0x09, 0x0f,
++	 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03c9, 0x03c5, 0x03c1, 0x043a,
++	 0x043f,
++	 0x0443},
++	{
++	 2, 2417, 0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, 0x09, 0x0f,
++	 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cb, 0x03c7, 0x03c3, 0x0438,
++	 0x043d,
++	 0x0441},
++	{
++	 3, 2422, 0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, 0x09, 0x0f,
++	 0x09, 0x00, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cd, 0x03c9, 0x03c5, 0x0436,
++	 0x043a,
++	 0x043f},
++	{
++	 4, 2427, 0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, 0x09, 0x0f,
++	 0x09, 0x00, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cf, 0x03cb, 0x03c7, 0x0434,
++	 0x0438,
++	 0x043d},
++	{
++	 5, 2432, 0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, 0x09, 0x0f,
++	 0x08, 0x00, 0x08, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d1, 0x03cd, 0x03c9, 0x0431,
++	 0x0436,
++	 0x043a},
++	{
++	 6, 2437, 0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, 0x09, 0x0f,
++	 0x08, 0x00, 0x08, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d3, 0x03cf, 0x03cb, 0x042f,
++	 0x0434,
++	 0x0438},
++	{
++	 7, 2442, 0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, 0x09, 0x0f,
++	 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d5, 0x03d1, 0x03cd, 0x042d,
++	 0x0431,
++	 0x0436},
++	{
++	 8, 2447, 0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, 0x09, 0x0f,
++	 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d7, 0x03d3, 0x03cf, 0x042b,
++	 0x042f,
++	 0x0434},
++	{
++	 9, 2452, 0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, 0x09, 0x0f,
++	 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d9, 0x03d5, 0x03d1, 0x0429,
++	 0x042d,
++	 0x0431},
++	{
++	 10, 2457, 0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, 0x09, 0x0f,
++	 0x06, 0x00, 0x06, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03db, 0x03d7, 0x03d3, 0x0427,
++	 0x042b,
++	 0x042f},
++	{
++	 11, 2462, 0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, 0x09, 0x0f,
++	 0x06, 0x00, 0x06, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03dd, 0x03d9, 0x03d5, 0x0424,
++	 0x0429,
++	 0x042d},
++	{
++	 12, 2467, 0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, 0x09, 0x0f,
++	 0x05, 0x00, 0x05, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03df, 0x03db, 0x03d7, 0x0422,
++	 0x0427,
++	 0x042b},
++	{
++	 13, 2472, 0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8, 0x09, 0x0f,
++	 0x05, 0x00, 0x05, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03e1, 0x03dd, 0x03d9, 0x0420,
++	 0x0424,
++	 0x0429},
++	{
++	 14, 2484, 0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4, 0x09, 0x0f,
++	 0x04, 0x00, 0x04, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x03e6, 0x03e2, 0x03de, 0x041b,
++	 0x041f,
++	 0x0424}
++};
++
++static struct radio_regs regs_2055[] = {
++	{0x02, 0x80, 0x80, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0x27, 0x27, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0x27, 0x27, 0, 0},
++	{0x07, 0x7f, 0x7f, 1, 1},
++	{0x08, 0x7, 0x7, 1, 1},
++	{0x09, 0x7f, 0x7f, 1, 1},
++	{0x0A, 0x7, 0x7, 1, 1},
++	{0x0B, 0x15, 0x15, 0, 0},
++	{0x0C, 0x15, 0x15, 0, 0},
++	{0x0D, 0x4f, 0x4f, 1, 1},
++	{0x0E, 0x5, 0x5, 1, 1},
++	{0x0F, 0x4f, 0x4f, 1, 1},
++	{0x10, 0x5, 0x5, 1, 1},
++	{0x11, 0xd0, 0xd0, 0, 0},
++	{0x12, 0x2, 0x2, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0x40, 0x40, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0xc0, 0xc0, 0, 0},
++	{0x1E, 0xff, 0xff, 0, 0},
++	{0x1F, 0xc0, 0xc0, 0, 0},
++	{0x20, 0xff, 0xff, 0, 0},
++	{0x21, 0xc0, 0xc0, 0, 0},
++	{0x22, 0, 0, 0, 0},
++	{0x23, 0x2c, 0x2c, 0, 0},
++	{0x24, 0, 0, 0, 0},
++	{0x25, 0, 0, 0, 0},
++	{0x26, 0, 0, 0, 0},
++	{0x27, 0, 0, 0, 0},
++	{0x28, 0, 0, 0, 0},
++	{0x29, 0, 0, 0, 0},
++	{0x2A, 0, 0, 0, 0},
++	{0x2B, 0, 0, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0xa4, 0xa4, 0, 0},
++	{0x2E, 0x38, 0x38, 0, 0},
++	{0x2F, 0, 0, 0, 0},
++	{0x30, 0x4, 0x4, 1, 1},
++	{0x31, 0, 0, 0, 0},
++	{0x32, 0xa, 0xa, 0, 0},
++	{0x33, 0x87, 0x87, 0, 0},
++	{0x34, 0x9, 0x9, 0, 0},
++	{0x35, 0x70, 0x70, 0, 0},
++	{0x36, 0x11, 0x11, 0, 0},
++	{0x37, 0x18, 0x18, 1, 1},
++	{0x38, 0x6, 0x6, 0, 0},
++	{0x39, 0x4, 0x4, 1, 1},
++	{0x3A, 0x6, 0x6, 0, 0},
++	{0x3B, 0x9e, 0x9e, 0, 0},
++	{0x3C, 0x9, 0x9, 0, 0},
++	{0x3D, 0xc8, 0xc8, 1, 1},
++	{0x3E, 0x88, 0x88, 0, 0},
++	{0x3F, 0, 0, 0, 0},
++	{0x40, 0, 0, 0, 0},
++	{0x41, 0, 0, 0, 0},
++	{0x42, 0x1, 0x1, 0, 0},
++	{0x43, 0x2, 0x2, 0, 0},
++	{0x44, 0x96, 0x96, 0, 0},
++	{0x45, 0x3e, 0x3e, 0, 0},
++	{0x46, 0x3e, 0x3e, 0, 0},
++	{0x47, 0x13, 0x13, 0, 0},
++	{0x48, 0x2, 0x2, 0, 0},
++	{0x49, 0x15, 0x15, 0, 0},
++	{0x4A, 0x7, 0x7, 0, 0},
++	{0x4B, 0, 0, 0, 0},
++	{0x4C, 0, 0, 0, 0},
++	{0x4D, 0, 0, 0, 0},
++	{0x4E, 0, 0, 0, 0},
++	{0x4F, 0, 0, 0, 0},
++	{0x50, 0x8, 0x8, 0, 0},
++	{0x51, 0x8, 0x8, 0, 0},
++	{0x52, 0x6, 0x6, 0, 0},
++	{0x53, 0x84, 0x84, 1, 1},
++	{0x54, 0xc3, 0xc3, 0, 0},
++	{0x55, 0x8f, 0x8f, 0, 0},
++	{0x56, 0xff, 0xff, 0, 0},
++	{0x57, 0xff, 0xff, 0, 0},
++	{0x58, 0x88, 0x88, 0, 0},
++	{0x59, 0x88, 0x88, 0, 0},
++	{0x5A, 0, 0, 0, 0},
++	{0x5B, 0xcc, 0xcc, 0, 0},
++	{0x5C, 0x6, 0x6, 0, 0},
++	{0x5D, 0x80, 0x80, 0, 0},
++	{0x5E, 0x80, 0x80, 0, 0},
++	{0x5F, 0xf8, 0xf8, 0, 0},
++	{0x60, 0x88, 0x88, 0, 0},
++	{0x61, 0x88, 0x88, 0, 0},
++	{0x62, 0x88, 0x8, 1, 1},
++	{0x63, 0x88, 0x88, 0, 0},
++	{0x64, 0, 0, 0, 0},
++	{0x65, 0x1, 0x1, 1, 1},
++	{0x66, 0x8a, 0x8a, 0, 0},
++	{0x67, 0x8, 0x8, 0, 0},
++	{0x68, 0x83, 0x83, 0, 0},
++	{0x69, 0x6, 0x6, 0, 0},
++	{0x6A, 0xa0, 0xa0, 0, 0},
++	{0x6B, 0xa, 0xa, 0, 0},
++	{0x6C, 0x87, 0x87, 1, 1},
++	{0x6D, 0x2a, 0x2a, 0, 0},
++	{0x6E, 0x2a, 0x2a, 0, 0},
++	{0x6F, 0x2a, 0x2a, 0, 0},
++	{0x70, 0x2a, 0x2a, 0, 0},
++	{0x71, 0x18, 0x18, 0, 0},
++	{0x72, 0x6a, 0x6a, 1, 1},
++	{0x73, 0xab, 0xab, 1, 1},
++	{0x74, 0x13, 0x13, 1, 1},
++	{0x75, 0xc1, 0xc1, 1, 1},
++	{0x76, 0xaa, 0xaa, 1, 1},
++	{0x77, 0x87, 0x87, 1, 1},
++	{0x78, 0, 0, 0, 0},
++	{0x79, 0x6, 0x6, 0, 0},
++	{0x7A, 0x7, 0x7, 0, 0},
++	{0x7B, 0x7, 0x7, 0, 0},
++	{0x7C, 0x15, 0x15, 0, 0},
++	{0x7D, 0x55, 0x55, 0, 0},
++	{0x7E, 0x97, 0x97, 1, 1},
++	{0x7F, 0x8, 0x8, 0, 0},
++	{0x80, 0x14, 0x14, 1, 1},
++	{0x81, 0x33, 0x33, 0, 0},
++	{0x82, 0x88, 0x88, 0, 0},
++	{0x83, 0x6, 0x6, 0, 0},
++	{0x84, 0x3, 0x3, 1, 1},
++	{0x85, 0xa, 0xa, 0, 0},
++	{0x86, 0x3, 0x3, 1, 1},
++	{0x87, 0x2a, 0x2a, 0, 0},
++	{0x88, 0xa4, 0xa4, 0, 0},
++	{0x89, 0x18, 0x18, 0, 0},
++	{0x8A, 0x28, 0x28, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0x4a, 0x4a, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0xf8, 0xf8, 0, 0},
++	{0x8F, 0x88, 0x88, 0, 0},
++	{0x90, 0x88, 0x88, 0, 0},
++	{0x91, 0x88, 0x8, 1, 1},
++	{0x92, 0x88, 0x88, 0, 0},
++	{0x93, 0, 0, 0, 0},
++	{0x94, 0x1, 0x1, 1, 1},
++	{0x95, 0x8a, 0x8a, 0, 0},
++	{0x96, 0x8, 0x8, 0, 0},
++	{0x97, 0x83, 0x83, 0, 0},
++	{0x98, 0x6, 0x6, 0, 0},
++	{0x99, 0xa0, 0xa0, 0, 0},
++	{0x9A, 0xa, 0xa, 0, 0},
++	{0x9B, 0x87, 0x87, 1, 1},
++	{0x9C, 0x2a, 0x2a, 0, 0},
++	{0x9D, 0x2a, 0x2a, 0, 0},
++	{0x9E, 0x2a, 0x2a, 0, 0},
++	{0x9F, 0x2a, 0x2a, 0, 0},
++	{0xA0, 0x18, 0x18, 0, 0},
++	{0xA1, 0x6a, 0x6a, 1, 1},
++	{0xA2, 0xab, 0xab, 1, 1},
++	{0xA3, 0x13, 0x13, 1, 1},
++	{0xA4, 0xc1, 0xc1, 1, 1},
++	{0xA5, 0xaa, 0xaa, 1, 1},
++	{0xA6, 0x87, 0x87, 1, 1},
++	{0xA7, 0, 0, 0, 0},
++	{0xA8, 0x6, 0x6, 0, 0},
++	{0xA9, 0x7, 0x7, 0, 0},
++	{0xAA, 0x7, 0x7, 0, 0},
++	{0xAB, 0x15, 0x15, 0, 0},
++	{0xAC, 0x55, 0x55, 0, 0},
++	{0xAD, 0x97, 0x97, 1, 1},
++	{0xAE, 0x8, 0x8, 0, 0},
++	{0xAF, 0x14, 0x14, 1, 1},
++	{0xB0, 0x33, 0x33, 0, 0},
++	{0xB1, 0x88, 0x88, 0, 0},
++	{0xB2, 0x6, 0x6, 0, 0},
++	{0xB3, 0x3, 0x3, 1, 1},
++	{0xB4, 0xa, 0xa, 0, 0},
++	{0xB5, 0x3, 0x3, 1, 1},
++	{0xB6, 0x2a, 0x2a, 0, 0},
++	{0xB7, 0xa4, 0xa4, 0, 0},
++	{0xB8, 0x18, 0x18, 0, 0},
++	{0xB9, 0x28, 0x28, 0, 0},
++	{0xBA, 0, 0, 0, 0},
++	{0xBB, 0x4a, 0x4a, 0, 0},
++	{0xBC, 0, 0, 0, 0},
++	{0xBD, 0x71, 0x71, 0, 0},
++	{0xBE, 0x72, 0x72, 0, 0},
++	{0xBF, 0x73, 0x73, 0, 0},
++	{0xC0, 0x74, 0x74, 0, 0},
++	{0xC1, 0x75, 0x75, 0, 0},
++	{0xC2, 0x76, 0x76, 0, 0},
++	{0xC3, 0x77, 0x77, 0, 0},
++	{0xC4, 0x78, 0x78, 0, 0},
++	{0xC5, 0x79, 0x79, 0, 0},
++	{0xC6, 0x7a, 0x7a, 0, 0},
++	{0xC7, 0, 0, 0, 0},
++	{0xC8, 0, 0, 0, 0},
++	{0xC9, 0, 0, 0, 0},
++	{0xCA, 0, 0, 0, 0},
++	{0xCB, 0, 0, 0, 0},
++	{0xCC, 0, 0, 0, 0},
++	{0xCD, 0, 0, 0, 0},
++	{0xCE, 0x6, 0x6, 0, 0},
++	{0xCF, 0, 0, 0, 0},
++	{0xD0, 0, 0, 0, 0},
++	{0xD1, 0x18, 0x18, 0, 0},
++	{0xD2, 0x88, 0x88, 0, 0},
++	{0xD3, 0, 0, 0, 0},
++	{0xD4, 0, 0, 0, 0},
++	{0xD5, 0, 0, 0, 0},
++	{0xD6, 0, 0, 0, 0},
++	{0xD7, 0, 0, 0, 0},
++	{0xD8, 0, 0, 0, 0},
++	{0xD9, 0, 0, 0, 0},
++	{0xDA, 0x6, 0x6, 0, 0},
++	{0xDB, 0, 0, 0, 0},
++	{0xDC, 0, 0, 0, 0},
++	{0xDD, 0x18, 0x18, 0, 0},
++	{0xDE, 0x88, 0x88, 0, 0},
++	{0xDF, 0, 0, 0, 0},
++	{0xE0, 0, 0, 0, 0},
++	{0xE1, 0, 0, 0, 0},
++	{0xE2, 0, 0, 0, 0},
++	{0xFFFF, 0, 0, 0, 0},
++};
++
++static struct radio_regs regs_SYN_2056[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0x1, 0x1, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0, 0, 0, 0},
++	{0x21, 0, 0, 0, 0},
++	{0x22, 0x60, 0x60, 0, 0},
++	{0x23, 0x6, 0x6, 0, 0},
++	{0x24, 0xc, 0xc, 0, 0},
++	{0x25, 0, 0, 0, 0},
++	{0x26, 0, 0, 0, 0},
++	{0x27, 0, 0, 0, 0},
++	{0x28, 0x1, 0x1, 0, 0},
++	{0x29, 0, 0, 0, 0},
++	{0x2A, 0, 0, 0, 0},
++	{0x2B, 0, 0, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0, 0, 0, 0},
++	{0x2E, 0xd, 0xd, 0, 0},
++	{0x2F, 0x1f, 0x1f, 0, 0},
++	{0x30, 0x15, 0x15, 0, 0},
++	{0x31, 0xf, 0xf, 0, 0},
++	{0x32, 0, 0, 0, 0},
++	{0x33, 0, 0, 0, 0},
++	{0x34, 0, 0, 0, 0},
++	{0x35, 0, 0, 0, 0},
++	{0x36, 0, 0, 0, 0},
++	{0x37, 0, 0, 0, 0},
++	{0x38, 0, 0, 0, 0},
++	{0x39, 0, 0, 0, 0},
++	{0x3A, 0, 0, 0, 0},
++	{0x3B, 0, 0, 0, 0},
++	{0x3C, 0x13, 0x13, 0, 0},
++	{0x3D, 0xf, 0xf, 0, 0},
++	{0x3E, 0x18, 0x18, 0, 0},
++	{0x3F, 0, 0, 0, 0},
++	{0x40, 0, 0, 0, 0},
++	{0x41, 0x20, 0x20, 0, 0},
++	{0x42, 0x20, 0x20, 0, 0},
++	{0x43, 0, 0, 0, 0},
++	{0x44, 0x77, 0x77, 0, 0},
++	{0x45, 0x7, 0x7, 0, 0},
++	{0x46, 0x1, 0x1, 0, 0},
++	{0x47, 0x4, 0x4, 0, 0},
++	{0x48, 0xf, 0xf, 0, 0},
++	{0x49, 0x30, 0x30, 0, 0},
++	{0x4A, 0x32, 0x32, 0, 0},
++	{0x4B, 0xd, 0xd, 0, 0},
++	{0x4C, 0xd, 0xd, 0, 0},
++	{0x4D, 0x4, 0x4, 0, 0},
++	{0x4E, 0x6, 0x6, 0, 0},
++	{0x4F, 0x1, 0x1, 0, 0},
++	{0x50, 0x1c, 0x1c, 0, 0},
++	{0x51, 0x2, 0x2, 0, 0},
++	{0x52, 0x2, 0x2, 0, 0},
++	{0x53, 0xf7, 0xf7, 1, 1},
++	{0x54, 0xb4, 0xb4, 0, 0},
++	{0x55, 0xd2, 0xd2, 0, 0},
++	{0x56, 0, 0, 0, 0},
++	{0x57, 0, 0, 0, 0},
++	{0x58, 0x4, 0x4, 0, 0},
++	{0x59, 0x96, 0x96, 0, 0},
++	{0x5A, 0x3e, 0x3e, 0, 0},
++	{0x5B, 0x3e, 0x3e, 0, 0},
++	{0x5C, 0x13, 0x13, 0, 0},
++	{0x5D, 0x2, 0x2, 0, 0},
++	{0x5E, 0, 0, 0, 0},
++	{0x5F, 0x7, 0x7, 0, 0},
++	{0x60, 0x7, 0x7, 1, 1},
++	{0x61, 0x8, 0x8, 0, 0},
++	{0x62, 0x3, 0x3, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0, 0, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0, 0, 0, 0},
++	{0x68, 0x40, 0x40, 0, 0},
++	{0x69, 0, 0, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0, 0, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0x1, 0x1, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0x60, 0x60, 0, 0},
++	{0x71, 0x66, 0x66, 0, 0},
++	{0x72, 0xc, 0xc, 0, 0},
++	{0x73, 0x66, 0x66, 0, 0},
++	{0x74, 0x8f, 0x8f, 1, 1},
++	{0x75, 0, 0, 0, 0},
++	{0x76, 0xcc, 0xcc, 0, 0},
++	{0x77, 0x1, 0x1, 0, 0},
++	{0x78, 0x66, 0x66, 0, 0},
++	{0x79, 0x66, 0x66, 0, 0},
++	{0x7A, 0, 0, 0, 0},
++	{0x7B, 0, 0, 0, 0},
++	{0x7C, 0, 0, 0, 0},
++	{0x7D, 0, 0, 0, 0},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0xff, 0xff, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0x93, 0, 0, 0, 0},
++	{0x94, 0, 0, 0, 0},
++	{0x95, 0, 0, 0, 0},
++	{0x96, 0, 0, 0, 0},
++	{0x97, 0, 0, 0, 0},
++	{0x98, 0, 0, 0, 0},
++	{0x99, 0, 0, 0, 0},
++	{0x9A, 0, 0, 0, 0},
++	{0x9B, 0, 0, 0, 0},
++	{0x9C, 0, 0, 0, 0},
++	{0x9D, 0, 0, 0, 0},
++	{0x9E, 0, 0, 0, 0},
++	{0x9F, 0x6, 0x6, 0, 0},
++	{0xA0, 0x66, 0x66, 0, 0},
++	{0xA1, 0x66, 0x66, 0, 0},
++	{0xA2, 0x66, 0x66, 0, 0},
++	{0xA3, 0x66, 0x66, 0, 0},
++	{0xA4, 0x66, 0x66, 0, 0},
++	{0xA5, 0x66, 0x66, 0, 0},
++	{0xA6, 0x66, 0x66, 0, 0},
++	{0xA7, 0x66, 0x66, 0, 0},
++	{0xA8, 0x66, 0x66, 0, 0},
++	{0xA9, 0x66, 0x66, 0, 0},
++	{0xAA, 0x66, 0x66, 0, 0},
++	{0xAB, 0x66, 0x66, 0, 0},
++	{0xAC, 0x66, 0x66, 0, 0},
++	{0xAD, 0x66, 0x66, 0, 0},
++	{0xAE, 0x66, 0x66, 0, 0},
++	{0xAF, 0x66, 0x66, 0, 0},
++	{0xB0, 0x66, 0x66, 0, 0},
++	{0xB1, 0x66, 0x66, 0, 0},
++	{0xB2, 0x66, 0x66, 0, 0},
++	{0xB3, 0xa, 0xa, 0, 0},
++	{0xB4, 0, 0, 0, 0},
++	{0xB5, 0, 0, 0, 0},
++	{0xB6, 0, 0, 0, 0},
++	{0xFFFF, 0, 0, 0, 0}
++};
++
++static struct radio_regs regs_TX_2056[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0, 0, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0, 0, 0, 0},
++	{0x21, 0x88, 0x88, 0, 0},
++	{0x22, 0x88, 0x88, 0, 0},
++	{0x23, 0x88, 0x88, 0, 0},
++	{0x24, 0x88, 0x88, 0, 0},
++	{0x25, 0xc, 0xc, 0, 0},
++	{0x26, 0, 0, 0, 0},
++	{0x27, 0x3, 0x3, 0, 0},
++	{0x28, 0, 0, 0, 0},
++	{0x29, 0x3, 0x3, 0, 0},
++	{0x2A, 0x37, 0x37, 0, 0},
++	{0x2B, 0x3, 0x3, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0, 0, 0, 0},
++	{0x2E, 0x1, 0x1, 0, 0},
++	{0x2F, 0x1, 0x1, 0, 0},
++	{0x30, 0, 0, 0, 0},
++	{0x31, 0, 0, 0, 0},
++	{0x32, 0, 0, 0, 0},
++	{0x33, 0x11, 0x11, 0, 0},
++	{0x34, 0x11, 0x11, 0, 0},
++	{0x35, 0, 0, 0, 0},
++	{0x36, 0, 0, 0, 0},
++	{0x37, 0x3, 0x3, 0, 0},
++	{0x38, 0xf, 0xf, 0, 0},
++	{0x39, 0, 0, 0, 0},
++	{0x3A, 0x2d, 0x2d, 0, 0},
++	{0x3B, 0, 0, 0, 0},
++	{0x3C, 0x6e, 0x6e, 0, 0},
++	{0x3D, 0xf0, 0xf0, 1, 1},
++	{0x3E, 0, 0, 0, 0},
++	{0x3F, 0, 0, 0, 0},
++	{0x40, 0, 0, 0, 0},
++	{0x41, 0x3, 0x3, 0, 0},
++	{0x42, 0x3, 0x3, 0, 0},
++	{0x43, 0, 0, 0, 0},
++	{0x44, 0x1e, 0x1e, 0, 0},
++	{0x45, 0, 0, 0, 0},
++	{0x46, 0x6e, 0x6e, 0, 0},
++	{0x47, 0xf0, 0xf0, 1, 1},
++	{0x48, 0, 0, 0, 0},
++	{0x49, 0x2, 0x2, 0, 0},
++	{0x4A, 0xff, 0xff, 1, 1},
++	{0x4B, 0xc, 0xc, 0, 0},
++	{0x4C, 0, 0, 0, 0},
++	{0x4D, 0x38, 0x38, 0, 0},
++	{0x4E, 0x70, 0x70, 1, 1},
++	{0x4F, 0x2, 0x2, 0, 0},
++	{0x50, 0x88, 0x88, 0, 0},
++	{0x51, 0xc, 0xc, 0, 0},
++	{0x52, 0, 0, 0, 0},
++	{0x53, 0x8, 0x8, 0, 0},
++	{0x54, 0x70, 0x70, 1, 1},
++	{0x55, 0x2, 0x2, 0, 0},
++	{0x56, 0xff, 0xff, 1, 1},
++	{0x57, 0, 0, 0, 0},
++	{0x58, 0x83, 0x83, 0, 0},
++	{0x59, 0x77, 0x77, 1, 1},
++	{0x5A, 0, 0, 0, 0},
++	{0x5B, 0x2, 0x2, 0, 0},
++	{0x5C, 0x88, 0x88, 0, 0},
++	{0x5D, 0, 0, 0, 0},
++	{0x5E, 0x8, 0x8, 0, 0},
++	{0x5F, 0x77, 0x77, 1, 1},
++	{0x60, 0x1, 0x1, 0, 0},
++	{0x61, 0, 0, 0, 0},
++	{0x62, 0x7, 0x7, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0x7, 0x7, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0x74, 0x74, 1, 1},
++	{0x68, 0, 0, 0, 0},
++	{0x69, 0xa, 0xa, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0, 0, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0, 0, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0, 0, 0, 0},
++	{0x71, 0x2, 0x2, 0, 0},
++	{0x72, 0, 0, 0, 0},
++	{0x73, 0, 0, 0, 0},
++	{0x74, 0xe, 0xe, 0, 0},
++	{0x75, 0xe, 0xe, 0, 0},
++	{0x76, 0xe, 0xe, 0, 0},
++	{0x77, 0x13, 0x13, 0, 0},
++	{0x78, 0x13, 0x13, 0, 0},
++	{0x79, 0x1b, 0x1b, 0, 0},
++	{0x7A, 0x1b, 0x1b, 0, 0},
++	{0x7B, 0x55, 0x55, 0, 0},
++	{0x7C, 0x5b, 0x5b, 0, 0},
++	{0x7D, 0, 0, 0, 0},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0, 0, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0xFFFF, 0, 0, 0, 0}
++};
++
++static struct radio_regs regs_RX_2056[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0, 0, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0x3, 0x3, 0, 0},
++	{0x21, 0, 0, 0, 0},
++	{0x22, 0, 0, 0, 0},
++	{0x23, 0x90, 0x90, 0, 0},
++	{0x24, 0x55, 0x55, 0, 0},
++	{0x25, 0x15, 0x15, 0, 0},
++	{0x26, 0x5, 0x5, 0, 0},
++	{0x27, 0x15, 0x15, 0, 0},
++	{0x28, 0x5, 0x5, 0, 0},
++	{0x29, 0x20, 0x20, 0, 0},
++	{0x2A, 0x11, 0x11, 0, 0},
++	{0x2B, 0x90, 0x90, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0x88, 0x88, 0, 0},
++	{0x2E, 0x32, 0x32, 0, 0},
++	{0x2F, 0x77, 0x77, 0, 0},
++	{0x30, 0x17, 0x17, 1, 1},
++	{0x31, 0xff, 0xff, 1, 1},
++	{0x32, 0x20, 0x20, 0, 0},
++	{0x33, 0, 0, 0, 0},
++	{0x34, 0x88, 0x88, 0, 0},
++	{0x35, 0x32, 0x32, 0, 0},
++	{0x36, 0x77, 0x77, 0, 0},
++	{0x37, 0x17, 0x17, 1, 1},
++	{0x38, 0xf0, 0xf0, 1, 1},
++	{0x39, 0x20, 0x20, 0, 0},
++	{0x3A, 0x8, 0x8, 0, 0},
++	{0x3B, 0x99, 0x99, 0, 0},
++	{0x3C, 0, 0, 0, 0},
++	{0x3D, 0x44, 0x44, 1, 1},
++	{0x3E, 0, 0, 0, 0},
++	{0x3F, 0x44, 0x44, 0, 0},
++	{0x40, 0xf, 0xf, 1, 1},
++	{0x41, 0x6, 0x6, 0, 0},
++	{0x42, 0x4, 0x4, 0, 0},
++	{0x43, 0x50, 0x50, 1, 1},
++	{0x44, 0x8, 0x8, 0, 0},
++	{0x45, 0x99, 0x99, 0, 0},
++	{0x46, 0, 0, 0, 0},
++	{0x47, 0x11, 0x11, 0, 0},
++	{0x48, 0, 0, 0, 0},
++	{0x49, 0x44, 0x44, 0, 0},
++	{0x4A, 0x7, 0x7, 0, 0},
++	{0x4B, 0x6, 0x6, 0, 0},
++	{0x4C, 0x4, 0x4, 0, 0},
++	{0x4D, 0, 0, 0, 0},
++	{0x4E, 0, 0, 0, 0},
++	{0x4F, 0x66, 0x66, 0, 0},
++	{0x50, 0x66, 0x66, 0, 0},
++	{0x51, 0x57, 0x57, 0, 0},
++	{0x52, 0x57, 0x57, 0, 0},
++	{0x53, 0x44, 0x44, 0, 0},
++	{0x54, 0, 0, 0, 0},
++	{0x55, 0, 0, 0, 0},
++	{0x56, 0x8, 0x8, 0, 0},
++	{0x57, 0x8, 0x8, 0, 0},
++	{0x58, 0x7, 0x7, 0, 0},
++	{0x59, 0x22, 0x22, 0, 0},
++	{0x5A, 0x22, 0x22, 0, 0},
++	{0x5B, 0x2, 0x2, 0, 0},
++	{0x5C, 0x23, 0x23, 0, 0},
++	{0x5D, 0x7, 0x7, 0, 0},
++	{0x5E, 0x55, 0x55, 0, 0},
++	{0x5F, 0x23, 0x23, 0, 0},
++	{0x60, 0x41, 0x41, 0, 0},
++	{0x61, 0x1, 0x1, 0, 0},
++	{0x62, 0xa, 0xa, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0, 0, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0, 0, 0, 0},
++	{0x68, 0, 0, 0, 0},
++	{0x69, 0, 0, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0xc, 0xc, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0, 0, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0, 0, 0, 0},
++	{0x71, 0, 0, 0, 0},
++	{0x72, 0x22, 0x22, 0, 0},
++	{0x73, 0x22, 0x22, 0, 0},
++	{0x74, 0x2, 0x2, 0, 0},
++	{0x75, 0xa, 0xa, 0, 0},
++	{0x76, 0x1, 0x1, 0, 0},
++	{0x77, 0x22, 0x22, 0, 0},
++	{0x78, 0x30, 0x30, 0, 0},
++	{0x79, 0, 0, 0, 0},
++	{0x7A, 0, 0, 0, 0},
++	{0x7B, 0, 0, 0, 0},
++	{0x7C, 0, 0, 0, 0},
++	{0x7D, 0, 0, 0, 0},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0, 0, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0x93, 0, 0, 0, 0},
++	{0x94, 0, 0, 0, 0},
++	{0xFFFF, 0, 0, 0, 0}
++};
++
++static struct radio_regs regs_SYN_2056_A1[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0x1, 0x1, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0, 0, 0, 0},
++	{0x21, 0, 0, 0, 0},
++	{0x22, 0x60, 0x60, 0, 0},
++	{0x23, 0x6, 0x6, 0, 0},
++	{0x24, 0xc, 0xc, 0, 0},
++	{0x25, 0, 0, 0, 0},
++	{0x26, 0, 0, 0, 0},
++	{0x27, 0, 0, 0, 0},
++	{0x28, 0x1, 0x1, 0, 0},
++	{0x29, 0, 0, 0, 0},
++	{0x2A, 0, 0, 0, 0},
++	{0x2B, 0, 0, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0, 0, 0, 0},
++	{0x2E, 0xd, 0xd, 0, 0},
++	{0x2F, 0x1f, 0x1f, 0, 0},
++	{0x30, 0x15, 0x15, 0, 0},
++	{0x31, 0xf, 0xf, 0, 0},
++	{0x32, 0, 0, 0, 0},
++	{0x33, 0, 0, 0, 0},
++	{0x34, 0, 0, 0, 0},
++	{0x35, 0, 0, 0, 0},
++	{0x36, 0, 0, 0, 0},
++	{0x37, 0, 0, 0, 0},
++	{0x38, 0, 0, 0, 0},
++	{0x39, 0, 0, 0, 0},
++	{0x3A, 0, 0, 0, 0},
++	{0x3B, 0, 0, 0, 0},
++	{0x3C, 0x13, 0x13, 0, 0},
++	{0x3D, 0xf, 0xf, 0, 0},
++	{0x3E, 0x18, 0x18, 0, 0},
++	{0x3F, 0, 0, 0, 0},
++	{0x40, 0, 0, 0, 0},
++	{0x41, 0x20, 0x20, 0, 0},
++	{0x42, 0x20, 0x20, 0, 0},
++	{0x43, 0, 0, 0, 0},
++	{0x44, 0x77, 0x77, 0, 0},
++	{0x45, 0x7, 0x7, 0, 0},
++	{0x46, 0x1, 0x1, 0, 0},
++	{0x47, 0x4, 0x4, 0, 0},
++	{0x48, 0xf, 0xf, 0, 0},
++	{0x49, 0x30, 0x30, 0, 0},
++	{0x4A, 0x32, 0x32, 0, 0},
++	{0x4B, 0xd, 0xd, 0, 0},
++	{0x4C, 0xd, 0xd, 0, 0},
++	{0x4D, 0x4, 0x4, 0, 0},
++	{0x4E, 0x6, 0x6, 0, 0},
++	{0x4F, 0x1, 0x1, 0, 0},
++	{0x50, 0x1c, 0x1c, 0, 0},
++	{0x51, 0x2, 0x2, 0, 0},
++	{0x52, 0x2, 0x2, 0, 0},
++	{0x53, 0xf7, 0xf7, 1, 1},
++	{0x54, 0xb4, 0xb4, 0, 0},
++	{0x55, 0xd2, 0xd2, 0, 0},
++	{0x56, 0, 0, 0, 0},
++	{0x57, 0, 0, 0, 0},
++	{0x58, 0x4, 0x4, 0, 0},
++	{0x59, 0x96, 0x96, 0, 0},
++	{0x5A, 0x3e, 0x3e, 0, 0},
++	{0x5B, 0x3e, 0x3e, 0, 0},
++	{0x5C, 0x13, 0x13, 0, 0},
++	{0x5D, 0x2, 0x2, 0, 0},
++	{0x5E, 0, 0, 0, 0},
++	{0x5F, 0x7, 0x7, 0, 0},
++	{0x60, 0x7, 0x7, 1, 1},
++	{0x61, 0x8, 0x8, 0, 0},
++	{0x62, 0x3, 0x3, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0, 0, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0, 0, 0, 0},
++	{0x68, 0x40, 0x40, 0, 0},
++	{0x69, 0, 0, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0, 0, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0x1, 0x1, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0x60, 0x60, 0, 0},
++	{0x71, 0x66, 0x66, 0, 0},
++	{0x72, 0xc, 0xc, 0, 0},
++	{0x73, 0x66, 0x66, 0, 0},
++	{0x74, 0x8f, 0x8f, 1, 1},
++	{0x75, 0, 0, 0, 0},
++	{0x76, 0xcc, 0xcc, 0, 0},
++	{0x77, 0x1, 0x1, 0, 0},
++	{0x78, 0x66, 0x66, 0, 0},
++	{0x79, 0x66, 0x66, 0, 0},
++	{0x7A, 0, 0, 0, 0},
++	{0x7B, 0, 0, 0, 0},
++	{0x7C, 0, 0, 0, 0},
++	{0x7D, 0, 0, 0, 0},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0xff, 0xff, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0x93, 0, 0, 0, 0},
++	{0x94, 0, 0, 0, 0},
++	{0x95, 0, 0, 0, 0},
++	{0x96, 0, 0, 0, 0},
++	{0x97, 0, 0, 0, 0},
++	{0x98, 0, 0, 0, 0},
++	{0x99, 0, 0, 0, 0},
++	{0x9A, 0, 0, 0, 0},
++	{0x9B, 0, 0, 0, 0},
++	{0x9C, 0, 0, 0, 0},
++	{0x9D, 0, 0, 0, 0},
++	{0x9E, 0, 0, 0, 0},
++	{0x9F, 0x6, 0x6, 0, 0},
++	{0xA0, 0x66, 0x66, 0, 0},
++	{0xA1, 0x66, 0x66, 0, 0},
++	{0xA2, 0x66, 0x66, 0, 0},
++	{0xA3, 0x66, 0x66, 0, 0},
++	{0xA4, 0x66, 0x66, 0, 0},
++	{0xA5, 0x66, 0x66, 0, 0},
++	{0xA6, 0x66, 0x66, 0, 0},
++	{0xA7, 0x66, 0x66, 0, 0},
++	{0xA8, 0x66, 0x66, 0, 0},
++	{0xA9, 0x66, 0x66, 0, 0},
++	{0xAA, 0x66, 0x66, 0, 0},
++	{0xAB, 0x66, 0x66, 0, 0},
++	{0xAC, 0x66, 0x66, 0, 0},
++	{0xAD, 0x66, 0x66, 0, 0},
++	{0xAE, 0x66, 0x66, 0, 0},
++	{0xAF, 0x66, 0x66, 0, 0},
++	{0xB0, 0x66, 0x66, 0, 0},
++	{0xB1, 0x66, 0x66, 0, 0},
++	{0xB2, 0x66, 0x66, 0, 0},
++	{0xB3, 0xa, 0xa, 0, 0},
++	{0xB4, 0, 0, 0, 0},
++	{0xB5, 0, 0, 0, 0},
++	{0xB6, 0, 0, 0, 0},
++	{0xFFFF, 0, 0, 0, 0}
++};
++
++static struct radio_regs regs_TX_2056_A1[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0, 0, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0, 0, 0, 0},
++	{0x21, 0x88, 0x88, 0, 0},
++	{0x22, 0x88, 0x88, 0, 0},
++	{0x23, 0x88, 0x88, 0, 0},
++	{0x24, 0x88, 0x88, 0, 0},
++	{0x25, 0xc, 0xc, 0, 0},
++	{0x26, 0, 0, 0, 0},
++	{0x27, 0x3, 0x3, 0, 0},
++	{0x28, 0, 0, 0, 0},
++	{0x29, 0x3, 0x3, 0, 0},
++	{0x2A, 0x37, 0x37, 0, 0},
++	{0x2B, 0x3, 0x3, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0, 0, 0, 0},
++	{0x2E, 0x1, 0x1, 0, 0},
++	{0x2F, 0x1, 0x1, 0, 0},
++	{0x30, 0, 0, 0, 0},
++	{0x31, 0, 0, 0, 0},
++	{0x32, 0, 0, 0, 0},
++	{0x33, 0x11, 0x11, 0, 0},
++	{0x34, 0x11, 0x11, 0, 0},
++	{0x35, 0, 0, 0, 0},
++	{0x36, 0, 0, 0, 0},
++	{0x37, 0x3, 0x3, 0, 0},
++	{0x38, 0xf, 0xf, 0, 0},
++	{0x39, 0, 0, 0, 0},
++	{0x3A, 0x2d, 0x2d, 0, 0},
++	{0x3B, 0, 0, 0, 0},
++	{0x3C, 0x6e, 0x6e, 0, 0},
++	{0x3D, 0xf0, 0xf0, 1, 1},
++	{0x3E, 0, 0, 0, 0},
++	{0x3F, 0, 0, 0, 0},
++	{0x40, 0, 0, 0, 0},
++	{0x41, 0x3, 0x3, 0, 0},
++	{0x42, 0x3, 0x3, 0, 0},
++	{0x43, 0, 0, 0, 0},
++	{0x44, 0x1e, 0x1e, 0, 0},
++	{0x45, 0, 0, 0, 0},
++	{0x46, 0x6e, 0x6e, 0, 0},
++	{0x47, 0xf0, 0xf0, 1, 1},
++	{0x48, 0, 0, 0, 0},
++	{0x49, 0x2, 0x2, 0, 0},
++	{0x4A, 0xff, 0xff, 1, 1},
++	{0x4B, 0xc, 0xc, 0, 0},
++	{0x4C, 0, 0, 0, 0},
++	{0x4D, 0x38, 0x38, 0, 0},
++	{0x4E, 0x70, 0x70, 1, 1},
++	{0x4F, 0x2, 0x2, 0, 0},
++	{0x50, 0x88, 0x88, 0, 0},
++	{0x51, 0xc, 0xc, 0, 0},
++	{0x52, 0, 0, 0, 0},
++	{0x53, 0x8, 0x8, 0, 0},
++	{0x54, 0x70, 0x70, 1, 1},
++	{0x55, 0x2, 0x2, 0, 0},
++	{0x56, 0xff, 0xff, 1, 1},
++	{0x57, 0, 0, 0, 0},
++	{0x58, 0x83, 0x83, 0, 0},
++	{0x59, 0x77, 0x77, 1, 1},
++	{0x5A, 0, 0, 0, 0},
++	{0x5B, 0x2, 0x2, 0, 0},
++	{0x5C, 0x88, 0x88, 0, 0},
++	{0x5D, 0, 0, 0, 0},
++	{0x5E, 0x8, 0x8, 0, 0},
++	{0x5F, 0x77, 0x77, 1, 1},
++	{0x60, 0x1, 0x1, 0, 0},
++	{0x61, 0, 0, 0, 0},
++	{0x62, 0x7, 0x7, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0x7, 0x7, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0x72, 0x72, 1, 1},
++	{0x68, 0, 0, 0, 0},
++	{0x69, 0xa, 0xa, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0, 0, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0, 0, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0, 0, 0, 0},
++	{0x71, 0x2, 0x2, 0, 0},
++	{0x72, 0, 0, 0, 0},
++	{0x73, 0, 0, 0, 0},
++	{0x74, 0xe, 0xe, 0, 0},
++	{0x75, 0xe, 0xe, 0, 0},
++	{0x76, 0xe, 0xe, 0, 0},
++	{0x77, 0x13, 0x13, 0, 0},
++	{0x78, 0x13, 0x13, 0, 0},
++	{0x79, 0x1b, 0x1b, 0, 0},
++	{0x7A, 0x1b, 0x1b, 0, 0},
++	{0x7B, 0x55, 0x55, 0, 0},
++	{0x7C, 0x5b, 0x5b, 0, 0},
++	{0x7D, 0, 0, 0, 0},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0, 0, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0xFFFF, 0, 0, 0, 0}
++};
++
++static struct radio_regs regs_RX_2056_A1[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0, 0, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0x3, 0x3, 0, 0},
++	{0x21, 0, 0, 0, 0},
++	{0x22, 0, 0, 0, 0},
++	{0x23, 0x90, 0x90, 0, 0},
++	{0x24, 0x55, 0x55, 0, 0},
++	{0x25, 0x15, 0x15, 0, 0},
++	{0x26, 0x5, 0x5, 0, 0},
++	{0x27, 0x15, 0x15, 0, 0},
++	{0x28, 0x5, 0x5, 0, 0},
++	{0x29, 0x20, 0x20, 0, 0},
++	{0x2A, 0x11, 0x11, 0, 0},
++	{0x2B, 0x90, 0x90, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0x88, 0x88, 0, 0},
++	{0x2E, 0x32, 0x32, 0, 0},
++	{0x2F, 0x77, 0x77, 0, 0},
++	{0x30, 0x17, 0x17, 1, 1},
++	{0x31, 0xff, 0xff, 1, 1},
++	{0x32, 0x20, 0x20, 0, 0},
++	{0x33, 0, 0, 0, 0},
++	{0x34, 0x88, 0x88, 0, 0},
++	{0x35, 0x32, 0x32, 0, 0},
++	{0x36, 0x77, 0x77, 0, 0},
++	{0x37, 0x17, 0x17, 1, 1},
++	{0x38, 0xf0, 0xf0, 1, 1},
++	{0x39, 0x20, 0x20, 0, 0},
++	{0x3A, 0x8, 0x8, 0, 0},
++	{0x3B, 0x55, 0x55, 1, 1},
++	{0x3C, 0, 0, 0, 0},
++	{0x3D, 0x44, 0x44, 1, 1},
++	{0x3E, 0, 0, 0, 0},
++	{0x3F, 0x44, 0x44, 0, 0},
++	{0x40, 0xf, 0xf, 1, 1},
++	{0x41, 0x6, 0x6, 0, 0},
++	{0x42, 0x4, 0x4, 0, 0},
++	{0x43, 0x50, 0x50, 1, 1},
++	{0x44, 0x8, 0x8, 0, 0},
++	{0x45, 0x55, 0x55, 1, 1},
++	{0x46, 0, 0, 0, 0},
++	{0x47, 0x11, 0x11, 0, 0},
++	{0x48, 0, 0, 0, 0},
++	{0x49, 0x44, 0x44, 0, 0},
++	{0x4A, 0x7, 0x7, 0, 0},
++	{0x4B, 0x6, 0x6, 0, 0},
++	{0x4C, 0x4, 0x4, 0, 0},
++	{0x4D, 0, 0, 0, 0},
++	{0x4E, 0, 0, 0, 0},
++	{0x4F, 0x26, 0x26, 1, 1},
++	{0x50, 0x26, 0x26, 1, 1},
++	{0x51, 0xf, 0xf, 1, 1},
++	{0x52, 0xf, 0xf, 1, 1},
++	{0x53, 0x44, 0x44, 0, 0},
++	{0x54, 0, 0, 0, 0},
++	{0x55, 0, 0, 0, 0},
++	{0x56, 0x8, 0x8, 0, 0},
++	{0x57, 0x8, 0x8, 0, 0},
++	{0x58, 0x7, 0x7, 0, 0},
++	{0x59, 0x22, 0x22, 0, 0},
++	{0x5A, 0x22, 0x22, 0, 0},
++	{0x5B, 0x2, 0x2, 0, 0},
++	{0x5C, 0x2f, 0x2f, 1, 1},
++	{0x5D, 0x7, 0x7, 0, 0},
++	{0x5E, 0x55, 0x55, 0, 0},
++	{0x5F, 0x23, 0x23, 0, 0},
++	{0x60, 0x41, 0x41, 0, 0},
++	{0x61, 0x1, 0x1, 0, 0},
++	{0x62, 0xa, 0xa, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0, 0, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0, 0, 0, 0},
++	{0x68, 0, 0, 0, 0},
++	{0x69, 0, 0, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0xc, 0xc, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0, 0, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0, 0, 0, 0},
++	{0x71, 0, 0, 0, 0},
++	{0x72, 0x22, 0x22, 0, 0},
++	{0x73, 0x22, 0x22, 0, 0},
++	{0x74, 0, 0, 1, 1},
++	{0x75, 0xa, 0xa, 0, 0},
++	{0x76, 0x1, 0x1, 0, 0},
++	{0x77, 0x22, 0x22, 0, 0},
++	{0x78, 0x30, 0x30, 0, 0},
++	{0x79, 0, 0, 0, 0},
++	{0x7A, 0, 0, 0, 0},
++	{0x7B, 0, 0, 0, 0},
++	{0x7C, 0, 0, 0, 0},
++	{0x7D, 0, 0, 0, 0},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0, 0, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0x93, 0, 0, 0, 0},
++	{0x94, 0, 0, 0, 0},
++	{0xFFFF, 0, 0, 0, 0}
++};
++
++static struct radio_regs regs_SYN_2056_rev5[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0x1, 0x1, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0, 0, 0, 0},
++	{0x21, 0, 0, 0, 0},
++	{0x22, 0x60, 0x60, 0, 0},
++	{0x23, 0x6, 0x6, 0, 0},
++	{0x24, 0xc, 0xc, 0, 0},
++	{0x25, 0, 0, 0, 0},
++	{0x26, 0, 0, 0, 0},
++	{0x27, 0, 0, 0, 0},
++	{0x28, 0x1, 0x1, 0, 0},
++	{0x29, 0, 0, 0, 0},
++	{0x2A, 0, 0, 0, 0},
++	{0x2B, 0, 0, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0, 0, 0, 0},
++	{0x2E, 0, 0, 0, 0},
++	{0x2F, 0x1f, 0x1f, 0, 0},
++	{0x30, 0x15, 0x15, 0, 0},
++	{0x31, 0xf, 0xf, 0, 0},
++	{0x32, 0, 0, 0, 0},
++	{0x33, 0, 0, 0, 0},
++	{0x34, 0, 0, 0, 0},
++	{0x35, 0, 0, 0, 0},
++	{0x36, 0, 0, 0, 0},
++	{0x37, 0, 0, 0, 0},
++	{0x38, 0, 0, 0, 0},
++	{0x39, 0, 0, 0, 0},
++	{0x3A, 0, 0, 0, 0},
++	{0x3B, 0, 0, 0, 0},
++	{0x3C, 0x13, 0x13, 0, 0},
++	{0x3D, 0xf, 0xf, 0, 0},
++	{0x3E, 0x18, 0x18, 0, 0},
++	{0x3F, 0, 0, 0, 0},
++	{0x40, 0, 0, 0, 0},
++	{0x41, 0x20, 0x20, 0, 0},
++	{0x42, 0x20, 0x20, 0, 0},
++	{0x43, 0, 0, 0, 0},
++	{0x44, 0x77, 0x77, 0, 0},
++	{0x45, 0x7, 0x7, 0, 0},
++	{0x46, 0x1, 0x1, 0, 0},
++	{0x47, 0x4, 0x4, 0, 0},
++	{0x48, 0xf, 0xf, 0, 0},
++	{0x49, 0x30, 0x30, 0, 0},
++	{0x4A, 0x32, 0x32, 0, 0},
++	{0x4B, 0xd, 0xd, 0, 0},
++	{0x4C, 0xd, 0xd, 0, 0},
++	{0x4D, 0x4, 0x4, 0, 0},
++	{0x4E, 0x6, 0x6, 0, 0},
++	{0x4F, 0x1, 0x1, 0, 0},
++	{0x50, 0x1c, 0x1c, 0, 0},
++	{0x51, 0x2, 0x2, 0, 0},
++	{0x52, 0x2, 0x2, 0, 0},
++	{0x53, 0xf7, 0xf7, 1, 1},
++	{0x54, 0xb4, 0xb4, 0, 0},
++	{0x55, 0xd2, 0xd2, 0, 0},
++	{0x56, 0, 0, 0, 0},
++	{0x57, 0, 0, 0, 0},
++	{0x58, 0x4, 0x4, 0, 0},
++	{0x59, 0x96, 0x96, 0, 0},
++	{0x5A, 0x3e, 0x3e, 0, 0},
++	{0x5B, 0x3e, 0x3e, 0, 0},
++	{0x5C, 0x13, 0x13, 0, 0},
++	{0x5D, 0x2, 0x2, 0, 0},
++	{0x5E, 0, 0, 0, 0},
++	{0x5F, 0x7, 0x7, 0, 0},
++	{0x60, 0x7, 0x7, 1, 1},
++	{0x61, 0x8, 0x8, 0, 0},
++	{0x62, 0x3, 0x3, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0, 0, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0, 0, 0, 0},
++	{0x68, 0x40, 0x40, 0, 0},
++	{0x69, 0, 0, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0, 0, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0x1, 0x1, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0x60, 0x60, 0, 0},
++	{0x71, 0x66, 0x66, 0, 0},
++	{0x72, 0xc, 0xc, 0, 0},
++	{0x73, 0x66, 0x66, 0, 0},
++	{0x74, 0x8f, 0x8f, 1, 1},
++	{0x75, 0, 0, 0, 0},
++	{0x76, 0xcc, 0xcc, 0, 0},
++	{0x77, 0x1, 0x1, 0, 0},
++	{0x78, 0x66, 0x66, 0, 0},
++	{0x79, 0x66, 0x66, 0, 0},
++	{0x7A, 0, 0, 0, 0},
++	{0x7B, 0, 0, 0, 0},
++	{0x7C, 0, 0, 0, 0},
++	{0x7D, 0, 0, 0, 0},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0xff, 0xff, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0x93, 0, 0, 0, 0},
++	{0x94, 0, 0, 0, 0},
++	{0x95, 0, 0, 0, 0},
++	{0x96, 0, 0, 0, 0},
++	{0x97, 0, 0, 0, 0},
++	{0x98, 0, 0, 0, 0},
++	{0x99, 0, 0, 0, 0},
++	{0x9A, 0, 0, 0, 0},
++	{0x9B, 0, 0, 0, 0},
++	{0x9C, 0, 0, 0, 0},
++	{0x9D, 0, 0, 0, 0},
++	{0x9E, 0, 0, 0, 0},
++	{0x9F, 0x6, 0x6, 0, 0},
++	{0xA0, 0x66, 0x66, 0, 0},
++	{0xA1, 0x66, 0x66, 0, 0},
++	{0xA2, 0x66, 0x66, 0, 0},
++	{0xA3, 0x66, 0x66, 0, 0},
++	{0xA4, 0x66, 0x66, 0, 0},
++	{0xA5, 0x66, 0x66, 0, 0},
++	{0xA6, 0x66, 0x66, 0, 0},
++	{0xA7, 0x66, 0x66, 0, 0},
++	{0xA8, 0x66, 0x66, 0, 0},
++	{0xA9, 0x66, 0x66, 0, 0},
++	{0xAA, 0x66, 0x66, 0, 0},
++	{0xAB, 0x66, 0x66, 0, 0},
++	{0xAC, 0x66, 0x66, 0, 0},
++	{0xAD, 0x66, 0x66, 0, 0},
++	{0xAE, 0x66, 0x66, 0, 0},
++	{0xAF, 0x66, 0x66, 0, 0},
++	{0xB0, 0x66, 0x66, 0, 0},
++	{0xB1, 0x66, 0x66, 0, 0},
++	{0xB2, 0x66, 0x66, 0, 0},
++	{0xB3, 0xa, 0xa, 0, 0},
++	{0xB4, 0, 0, 0, 0},
++	{0xB5, 0, 0, 0, 0},
++	{0xB6, 0, 0, 0, 0},
++	{0xFFFF, 0, 0, 0, 0}
++};
++
++static struct radio_regs regs_TX_2056_rev5[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0, 0, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0, 0, 0, 0},
++	{0x21, 0x88, 0x88, 0, 0},
++	{0x22, 0x88, 0x88, 0, 0},
++	{0x23, 0x88, 0x88, 0, 0},
++	{0x24, 0x88, 0x88, 0, 0},
++	{0x25, 0xc, 0xc, 0, 0},
++	{0x26, 0, 0, 0, 0},
++	{0x27, 0x3, 0x3, 0, 0},
++	{0x28, 0, 0, 0, 0},
++	{0x29, 0x3, 0x3, 0, 0},
++	{0x2A, 0x37, 0x37, 0, 0},
++	{0x2B, 0x3, 0x3, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0, 0, 0, 0},
++	{0x2E, 0x1, 0x1, 0, 0},
++	{0x2F, 0x1, 0x1, 0, 0},
++	{0x30, 0, 0, 0, 0},
++	{0x31, 0, 0, 0, 0},
++	{0x32, 0, 0, 0, 0},
++	{0x33, 0x11, 0x11, 0, 0},
++	{0x34, 0x11, 0x11, 0, 0},
++	{0x35, 0, 0, 0, 0},
++	{0x36, 0, 0, 0, 0},
++	{0x37, 0x3, 0x3, 0, 0},
++	{0x38, 0xf, 0xf, 0, 0},
++	{0x39, 0, 0, 0, 0},
++	{0x3A, 0x2d, 0x2d, 0, 0},
++	{0x3B, 0, 0, 0, 0},
++	{0x3C, 0x6e, 0x6e, 0, 0},
++	{0x3D, 0xf0, 0xf0, 1, 1},
++	{0x3E, 0, 0, 0, 0},
++	{0x3F, 0, 0, 0, 0},
++	{0x40, 0, 0, 0, 0},
++	{0x41, 0x3, 0x3, 0, 0},
++	{0x42, 0x3, 0x3, 0, 0},
++	{0x43, 0, 0, 0, 0},
++	{0x44, 0x1e, 0x1e, 0, 0},
++	{0x45, 0, 0, 0, 0},
++	{0x46, 0x6e, 0x6e, 0, 0},
++	{0x47, 0xf0, 0xf0, 1, 1},
++	{0x48, 0, 0, 0, 0},
++	{0x49, 0x2, 0x2, 0, 0},
++	{0x4A, 0xff, 0xff, 1, 1},
++	{0x4B, 0xc, 0xc, 0, 0},
++	{0x4C, 0, 0, 0, 0},
++	{0x4D, 0x38, 0x38, 0, 0},
++	{0x4E, 0x70, 0x70, 1, 1},
++	{0x4F, 0x2, 0x2, 0, 0},
++	{0x50, 0x88, 0x88, 0, 0},
++	{0x51, 0xc, 0xc, 0, 0},
++	{0x52, 0, 0, 0, 0},
++	{0x53, 0x8, 0x8, 0, 0},
++	{0x54, 0x70, 0x70, 1, 1},
++	{0x55, 0x2, 0x2, 0, 0},
++	{0x56, 0xff, 0xff, 1, 1},
++	{0x57, 0, 0, 0, 0},
++	{0x58, 0x83, 0x83, 0, 0},
++	{0x59, 0x77, 0x77, 1, 1},
++	{0x5A, 0, 0, 0, 0},
++	{0x5B, 0x2, 0x2, 0, 0},
++	{0x5C, 0x88, 0x88, 0, 0},
++	{0x5D, 0, 0, 0, 0},
++	{0x5E, 0x8, 0x8, 0, 0},
++	{0x5F, 0x77, 0x77, 1, 1},
++	{0x60, 0x1, 0x1, 0, 0},
++	{0x61, 0, 0, 0, 0},
++	{0x62, 0x7, 0x7, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0x7, 0x7, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0, 0, 1, 1},
++	{0x68, 0, 0, 0, 0},
++	{0x69, 0xa, 0xa, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0, 0, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0, 0, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0, 0, 0, 0},
++	{0x71, 0x2, 0x2, 0, 0},
++	{0x72, 0, 0, 0, 0},
++	{0x73, 0, 0, 0, 0},
++	{0x74, 0xe, 0xe, 0, 0},
++	{0x75, 0xe, 0xe, 0, 0},
++	{0x76, 0xe, 0xe, 0, 0},
++	{0x77, 0x13, 0x13, 0, 0},
++	{0x78, 0x13, 0x13, 0, 0},
++	{0x79, 0x1b, 0x1b, 0, 0},
++	{0x7A, 0x1b, 0x1b, 0, 0},
++	{0x7B, 0x55, 0x55, 0, 0},
++	{0x7C, 0x5b, 0x5b, 0, 0},
++	{0x7D, 0, 0, 0, 0},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0, 0, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0x93, 0x70, 0x70, 0, 0},
++	{0x94, 0x70, 0x70, 0, 0},
++	{0x95, 0x71, 0x71, 1, 1},
++	{0x96, 0x71, 0x71, 1, 1},
++	{0x97, 0x72, 0x72, 1, 1},
++	{0x98, 0x73, 0x73, 1, 1},
++	{0x99, 0x74, 0x74, 1, 1},
++	{0x9A, 0x75, 0x75, 1, 1},
++	{0xFFFF, 0, 0, 0, 0}
++};
++
++static struct radio_regs regs_RX_2056_rev5[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0, 0, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0x3, 0x3, 0, 0},
++	{0x21, 0, 0, 0, 0},
++	{0x22, 0, 0, 0, 0},
++	{0x23, 0x90, 0x90, 0, 0},
++	{0x24, 0x55, 0x55, 0, 0},
++	{0x25, 0x15, 0x15, 0, 0},
++	{0x26, 0x5, 0x5, 0, 0},
++	{0x27, 0x15, 0x15, 0, 0},
++	{0x28, 0x5, 0x5, 0, 0},
++	{0x29, 0x20, 0x20, 0, 0},
++	{0x2A, 0x11, 0x11, 0, 0},
++	{0x2B, 0x90, 0x90, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0x88, 0x88, 0, 0},
++	{0x2E, 0x32, 0x32, 0, 0},
++	{0x2F, 0x77, 0x77, 0, 0},
++	{0x30, 0x17, 0x17, 1, 1},
++	{0x31, 0xff, 0xff, 1, 1},
++	{0x32, 0x20, 0x20, 0, 0},
++	{0x33, 0, 0, 0, 0},
++	{0x34, 0x88, 0x88, 0, 0},
++	{0x35, 0x32, 0x32, 0, 0},
++	{0x36, 0x77, 0x77, 0, 0},
++	{0x37, 0x17, 0x17, 1, 1},
++	{0x38, 0xf0, 0xf0, 1, 1},
++	{0x39, 0x20, 0x20, 0, 0},
++	{0x3A, 0x8, 0x8, 0, 0},
++	{0x3B, 0x55, 0x55, 1, 1},
++	{0x3C, 0, 0, 0, 0},
++	{0x3D, 0x88, 0x88, 1, 1},
++	{0x3E, 0, 0, 0, 0},
++	{0x3F, 0, 0, 1, 1},
++	{0x40, 0x7, 0x7, 1, 1},
++	{0x41, 0x6, 0x6, 0, 0},
++	{0x42, 0x4, 0x4, 0, 0},
++	{0x43, 0, 0, 0, 0},
++	{0x44, 0x8, 0x8, 0, 0},
++	{0x45, 0x55, 0x55, 1, 1},
++	{0x46, 0, 0, 0, 0},
++	{0x47, 0x11, 0x11, 0, 0},
++	{0x48, 0, 0, 0, 0},
++	{0x49, 0, 0, 1, 1},
++	{0x4A, 0x7, 0x7, 0, 0},
++	{0x4B, 0x6, 0x6, 0, 0},
++	{0x4C, 0x4, 0x4, 0, 0},
++	{0x4D, 0, 0, 0, 0},
++	{0x4E, 0, 0, 0, 0},
++	{0x4F, 0x26, 0x26, 1, 1},
++	{0x50, 0x26, 0x26, 1, 1},
++	{0x51, 0xf, 0xf, 1, 1},
++	{0x52, 0xf, 0xf, 1, 1},
++	{0x53, 0x44, 0x44, 0, 0},
++	{0x54, 0, 0, 0, 0},
++	{0x55, 0, 0, 0, 0},
++	{0x56, 0x8, 0x8, 0, 0},
++	{0x57, 0x8, 0x8, 0, 0},
++	{0x58, 0x7, 0x7, 0, 0},
++	{0x59, 0x22, 0x22, 0, 0},
++	{0x5A, 0x22, 0x22, 0, 0},
++	{0x5B, 0x2, 0x2, 0, 0},
++	{0x5C, 0x4, 0x4, 1, 1},
++	{0x5D, 0x7, 0x7, 0, 0},
++	{0x5E, 0x55, 0x55, 0, 0},
++	{0x5F, 0x23, 0x23, 0, 0},
++	{0x60, 0x41, 0x41, 0, 0},
++	{0x61, 0x1, 0x1, 0, 0},
++	{0x62, 0xa, 0xa, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0, 0, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0, 0, 0, 0},
++	{0x68, 0, 0, 0, 0},
++	{0x69, 0, 0, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0xc, 0xc, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0, 0, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0, 0, 0, 0},
++	{0x71, 0, 0, 0, 0},
++	{0x72, 0x22, 0x22, 0, 0},
++	{0x73, 0x22, 0x22, 0, 0},
++	{0x74, 0, 0, 1, 1},
++	{0x75, 0xa, 0xa, 0, 0},
++	{0x76, 0x1, 0x1, 0, 0},
++	{0x77, 0x22, 0x22, 0, 0},
++	{0x78, 0x30, 0x30, 0, 0},
++	{0x79, 0, 0, 0, 0},
++	{0x7A, 0, 0, 0, 0},
++	{0x7B, 0, 0, 0, 0},
++	{0x7C, 0, 0, 0, 0},
++	{0x7D, 0, 0, 0, 0},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0, 0, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0x93, 0, 0, 0, 0},
++	{0x94, 0, 0, 0, 0},
++	{0xFFFF, 0, 0, 0, 0}
++};
++
++static struct radio_regs regs_SYN_2056_rev6[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0x1, 0x1, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0, 0, 0, 0},
++	{0x21, 0, 0, 0, 0},
++	{0x22, 0x60, 0x60, 0, 0},
++	{0x23, 0x6, 0x6, 0, 0},
++	{0x24, 0xc, 0xc, 0, 0},
++	{0x25, 0, 0, 0, 0},
++	{0x26, 0, 0, 0, 0},
++	{0x27, 0, 0, 0, 0},
++	{0x28, 0x1, 0x1, 0, 0},
++	{0x29, 0, 0, 0, 0},
++	{0x2A, 0, 0, 0, 0},
++	{0x2B, 0, 0, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0, 0, 0, 0},
++	{0x2E, 0, 0, 0, 0},
++	{0x2F, 0x1f, 0x1f, 0, 0},
++	{0x30, 0x15, 0x15, 0, 0},
++	{0x31, 0xf, 0xf, 0, 0},
++	{0x32, 0, 0, 0, 0},
++	{0x33, 0, 0, 0, 0},
++	{0x34, 0, 0, 0, 0},
++	{0x35, 0, 0, 0, 0},
++	{0x36, 0, 0, 0, 0},
++	{0x37, 0, 0, 0, 0},
++	{0x38, 0, 0, 0, 0},
++	{0x39, 0, 0, 0, 0},
++	{0x3A, 0, 0, 0, 0},
++	{0x3B, 0, 0, 0, 0},
++	{0x3C, 0x13, 0x13, 0, 0},
++	{0x3D, 0xf, 0xf, 0, 0},
++	{0x3E, 0x18, 0x18, 0, 0},
++	{0x3F, 0, 0, 0, 0},
++	{0x40, 0, 0, 0, 0},
++	{0x41, 0x20, 0x20, 0, 0},
++	{0x42, 0x20, 0x20, 0, 0},
++	{0x43, 0, 0, 0, 0},
++	{0x44, 0x77, 0x77, 0, 0},
++	{0x45, 0x7, 0x7, 0, 0},
++	{0x46, 0x1, 0x1, 0, 0},
++	{0x47, 0x4, 0x4, 0, 0},
++	{0x48, 0xf, 0xf, 0, 0},
++	{0x49, 0x30, 0x30, 0, 0},
++	{0x4A, 0x32, 0x32, 0, 0},
++	{0x4B, 0xd, 0xd, 0, 0},
++	{0x4C, 0xd, 0xd, 0, 0},
++	{0x4D, 0x4, 0x4, 0, 0},
++	{0x4E, 0x6, 0x6, 0, 0},
++	{0x4F, 0x1, 0x1, 0, 0},
++	{0x50, 0x1c, 0x1c, 0, 0},
++	{0x51, 0x2, 0x2, 0, 0},
++	{0x52, 0x2, 0x2, 0, 0},
++	{0x53, 0xf7, 0xf7, 1, 1},
++	{0x54, 0xb4, 0xb4, 0, 0},
++	{0x55, 0xd2, 0xd2, 0, 0},
++	{0x56, 0, 0, 0, 0},
++	{0x57, 0, 0, 0, 0},
++	{0x58, 0x4, 0x4, 0, 0},
++	{0x59, 0x96, 0x96, 0, 0},
++	{0x5A, 0x3e, 0x3e, 0, 0},
++	{0x5B, 0x3e, 0x3e, 0, 0},
++	{0x5C, 0x13, 0x13, 0, 0},
++	{0x5D, 0x2, 0x2, 0, 0},
++	{0x5E, 0, 0, 0, 0},
++	{0x5F, 0x7, 0x7, 0, 0},
++	{0x60, 0x7, 0x7, 1, 1},
++	{0x61, 0x8, 0x8, 0, 0},
++	{0x62, 0x3, 0x3, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0, 0, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0, 0, 0, 0},
++	{0x68, 0x40, 0x40, 0, 0},
++	{0x69, 0, 0, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0, 0, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0x1, 0x1, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0x60, 0x60, 0, 0},
++	{0x71, 0x66, 0x66, 0, 0},
++	{0x72, 0xc, 0xc, 0, 0},
++	{0x73, 0x66, 0x66, 0, 0},
++	{0x74, 0x8f, 0x8f, 1, 1},
++	{0x75, 0, 0, 0, 0},
++	{0x76, 0xcc, 0xcc, 0, 0},
++	{0x77, 0x1, 0x1, 0, 0},
++	{0x78, 0x66, 0x66, 0, 0},
++	{0x79, 0x66, 0x66, 0, 0},
++	{0x7A, 0, 0, 0, 0},
++	{0x7B, 0, 0, 0, 0},
++	{0x7C, 0, 0, 0, 0},
++	{0x7D, 0, 0, 0, 0},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0xff, 0xff, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0x93, 0, 0, 0, 0},
++	{0x94, 0, 0, 0, 0},
++	{0x95, 0, 0, 0, 0},
++	{0x96, 0, 0, 0, 0},
++	{0x97, 0, 0, 0, 0},
++	{0x98, 0, 0, 0, 0},
++	{0x99, 0, 0, 0, 0},
++	{0x9A, 0, 0, 0, 0},
++	{0x9B, 0, 0, 0, 0},
++	{0x9C, 0, 0, 0, 0},
++	{0x9D, 0, 0, 0, 0},
++	{0x9E, 0, 0, 0, 0},
++	{0x9F, 0x6, 0x6, 0, 0},
++	{0xA0, 0x66, 0x66, 0, 0},
++	{0xA1, 0x66, 0x66, 0, 0},
++	{0xA2, 0x66, 0x66, 0, 0},
++	{0xA3, 0x66, 0x66, 0, 0},
++	{0xA4, 0x66, 0x66, 0, 0},
++	{0xA5, 0x66, 0x66, 0, 0},
++	{0xA6, 0x66, 0x66, 0, 0},
++	{0xA7, 0x66, 0x66, 0, 0},
++	{0xA8, 0x66, 0x66, 0, 0},
++	{0xA9, 0x66, 0x66, 0, 0},
++	{0xAA, 0x66, 0x66, 0, 0},
++	{0xAB, 0x66, 0x66, 0, 0},
++	{0xAC, 0x66, 0x66, 0, 0},
++	{0xAD, 0x66, 0x66, 0, 0},
++	{0xAE, 0x66, 0x66, 0, 0},
++	{0xAF, 0x66, 0x66, 0, 0},
++	{0xB0, 0x66, 0x66, 0, 0},
++	{0xB1, 0x66, 0x66, 0, 0},
++	{0xB2, 0x66, 0x66, 0, 0},
++	{0xB3, 0xa, 0xa, 0, 0},
++	{0xB4, 0, 0, 0, 0},
++	{0xB5, 0, 0, 0, 0},
++	{0xB6, 0, 0, 0, 0},
++	{0xFFFF, 0, 0, 0, 0}
++};
++
++static struct radio_regs regs_TX_2056_rev6[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0, 0, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0, 0, 0, 0},
++	{0x21, 0x88, 0x88, 0, 0},
++	{0x22, 0x88, 0x88, 0, 0},
++	{0x23, 0x88, 0x88, 0, 0},
++	{0x24, 0x88, 0x88, 0, 0},
++	{0x25, 0xc, 0xc, 0, 0},
++	{0x26, 0, 0, 0, 0},
++	{0x27, 0x3, 0x3, 0, 0},
++	{0x28, 0, 0, 0, 0},
++	{0x29, 0x3, 0x3, 0, 0},
++	{0x2A, 0x37, 0x37, 0, 0},
++	{0x2B, 0x3, 0x3, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0, 0, 0, 0},
++	{0x2E, 0x1, 0x1, 0, 0},
++	{0x2F, 0x1, 0x1, 0, 0},
++	{0x30, 0, 0, 0, 0},
++	{0x31, 0, 0, 0, 0},
++	{0x32, 0, 0, 0, 0},
++	{0x33, 0x11, 0x11, 0, 0},
++	{0x34, 0xee, 0xee, 1, 1},
++	{0x35, 0, 0, 0, 0},
++	{0x36, 0, 0, 0, 0},
++	{0x37, 0x3, 0x3, 0, 0},
++	{0x38, 0x50, 0x50, 1, 1},
++	{0x39, 0, 0, 0, 0},
++	{0x3A, 0x50, 0x50, 1, 1},
++	{0x3B, 0, 0, 0, 0},
++	{0x3C, 0x6e, 0x6e, 0, 0},
++	{0x3D, 0xf0, 0xf0, 1, 1},
++	{0x3E, 0, 0, 0, 0},
++	{0x3F, 0, 0, 0, 0},
++	{0x40, 0, 0, 0, 0},
++	{0x41, 0x3, 0x3, 0, 0},
++	{0x42, 0x3, 0x3, 0, 0},
++	{0x43, 0, 0, 0, 0},
++	{0x44, 0x1e, 0x1e, 0, 0},
++	{0x45, 0, 0, 0, 0},
++	{0x46, 0x6e, 0x6e, 0, 0},
++	{0x47, 0xf0, 0xf0, 1, 1},
++	{0x48, 0, 0, 0, 0},
++	{0x49, 0x2, 0x2, 0, 0},
++	{0x4A, 0xff, 0xff, 1, 1},
++	{0x4B, 0xc, 0xc, 0, 0},
++	{0x4C, 0, 0, 0, 0},
++	{0x4D, 0x38, 0x38, 0, 0},
++	{0x4E, 0x70, 0x70, 1, 1},
++	{0x4F, 0x2, 0x2, 0, 0},
++	{0x50, 0x88, 0x88, 0, 0},
++	{0x51, 0xc, 0xc, 0, 0},
++	{0x52, 0, 0, 0, 0},
++	{0x53, 0x8, 0x8, 0, 0},
++	{0x54, 0x70, 0x70, 1, 1},
++	{0x55, 0x2, 0x2, 0, 0},
++	{0x56, 0xff, 0xff, 1, 1},
++	{0x57, 0, 0, 0, 0},
++	{0x58, 0x83, 0x83, 0, 0},
++	{0x59, 0x77, 0x77, 1, 1},
++	{0x5A, 0, 0, 0, 0},
++	{0x5B, 0x2, 0x2, 0, 0},
++	{0x5C, 0x88, 0x88, 0, 0},
++	{0x5D, 0, 0, 0, 0},
++	{0x5E, 0x8, 0x8, 0, 0},
++	{0x5F, 0x77, 0x77, 1, 1},
++	{0x60, 0x1, 0x1, 0, 0},
++	{0x61, 0, 0, 0, 0},
++	{0x62, 0x7, 0x7, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0x7, 0x7, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0, 0, 1, 1},
++	{0x68, 0, 0, 0, 0},
++	{0x69, 0xa, 0xa, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0, 0, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0, 0, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0, 0, 0, 0},
++	{0x71, 0x2, 0x2, 0, 0},
++	{0x72, 0, 0, 0, 0},
++	{0x73, 0, 0, 0, 0},
++	{0x74, 0xe, 0xe, 0, 0},
++	{0x75, 0xe, 0xe, 0, 0},
++	{0x76, 0xe, 0xe, 0, 0},
++	{0x77, 0x13, 0x13, 0, 0},
++	{0x78, 0x13, 0x13, 0, 0},
++	{0x79, 0x1b, 0x1b, 0, 0},
++	{0x7A, 0x1b, 0x1b, 0, 0},
++	{0x7B, 0x55, 0x55, 0, 0},
++	{0x7C, 0x5b, 0x5b, 0, 0},
++	{0x7D, 0x30, 0x30, 1, 1},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0, 0, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0x93, 0x70, 0x70, 0, 0},
++	{0x94, 0x70, 0x70, 0, 0},
++	{0x95, 0x70, 0x70, 0, 0},
++	{0x96, 0x70, 0x70, 0, 0},
++	{0x97, 0x70, 0x70, 0, 0},
++	{0x98, 0x70, 0x70, 0, 0},
++	{0x99, 0x70, 0x70, 0, 0},
++	{0x9A, 0x70, 0x70, 0, 0},
++	{0xFFFF, 0, 0, 0, 0}
++};
++
++static struct radio_regs regs_RX_2056_rev6[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0, 0, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0x3, 0x3, 0, 0},
++	{0x21, 0, 0, 0, 0},
++	{0x22, 0, 0, 0, 0},
++	{0x23, 0x90, 0x90, 0, 0},
++	{0x24, 0x55, 0x55, 0, 0},
++	{0x25, 0x15, 0x15, 0, 0},
++	{0x26, 0x5, 0x5, 0, 0},
++	{0x27, 0x15, 0x15, 0, 0},
++	{0x28, 0x5, 0x5, 0, 0},
++	{0x29, 0x20, 0x20, 0, 0},
++	{0x2A, 0x11, 0x11, 0, 0},
++	{0x2B, 0x90, 0x90, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0x88, 0x88, 0, 0},
++	{0x2E, 0x32, 0x32, 0, 0},
++	{0x2F, 0x77, 0x77, 0, 0},
++	{0x30, 0x17, 0x17, 1, 1},
++	{0x31, 0xff, 0xff, 1, 1},
++	{0x32, 0x20, 0x20, 0, 0},
++	{0x33, 0, 0, 0, 0},
++	{0x34, 0x88, 0x88, 0, 0},
++	{0x35, 0x32, 0x32, 0, 0},
++	{0x36, 0x77, 0x77, 0, 0},
++	{0x37, 0x17, 0x17, 1, 1},
++	{0x38, 0xf0, 0xf0, 1, 1},
++	{0x39, 0x20, 0x20, 0, 0},
++	{0x3A, 0x8, 0x8, 0, 0},
++	{0x3B, 0x55, 0x55, 1, 1},
++	{0x3C, 0, 0, 0, 0},
++	{0x3D, 0x88, 0x88, 1, 1},
++	{0x3E, 0, 0, 0, 0},
++	{0x3F, 0x44, 0x44, 0, 0},
++	{0x40, 0x7, 0x7, 1, 1},
++	{0x41, 0x6, 0x6, 0, 0},
++	{0x42, 0x4, 0x4, 0, 0},
++	{0x43, 0, 0, 0, 0},
++	{0x44, 0x8, 0x8, 0, 0},
++	{0x45, 0x55, 0x55, 1, 1},
++	{0x46, 0, 0, 0, 0},
++	{0x47, 0x11, 0x11, 0, 0},
++	{0x48, 0, 0, 0, 0},
++	{0x49, 0x44, 0x44, 0, 0},
++	{0x4A, 0x7, 0x7, 0, 0},
++	{0x4B, 0x6, 0x6, 0, 0},
++	{0x4C, 0x4, 0x4, 0, 0},
++	{0x4D, 0, 0, 0, 0},
++	{0x4E, 0, 0, 0, 0},
++	{0x4F, 0x26, 0x26, 1, 1},
++	{0x50, 0x26, 0x26, 1, 1},
++	{0x51, 0xf, 0xf, 1, 1},
++	{0x52, 0xf, 0xf, 1, 1},
++	{0x53, 0x44, 0x44, 0, 0},
++	{0x54, 0, 0, 0, 0},
++	{0x55, 0, 0, 0, 0},
++	{0x56, 0x8, 0x8, 0, 0},
++	{0x57, 0x8, 0x8, 0, 0},
++	{0x58, 0x7, 0x7, 0, 0},
++	{0x59, 0x22, 0x22, 0, 0},
++	{0x5A, 0x22, 0x22, 0, 0},
++	{0x5B, 0x2, 0x2, 0, 0},
++	{0x5C, 0x4, 0x4, 1, 1},
++	{0x5D, 0x7, 0x7, 0, 0},
++	{0x5E, 0x55, 0x55, 0, 0},
++	{0x5F, 0x23, 0x23, 0, 0},
++	{0x60, 0x41, 0x41, 0, 0},
++	{0x61, 0x1, 0x1, 0, 0},
++	{0x62, 0xa, 0xa, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0, 0, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0, 0, 0, 0},
++	{0x68, 0, 0, 0, 0},
++	{0x69, 0, 0, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0xc, 0xc, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0, 0, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0, 0, 0, 0},
++	{0x71, 0, 0, 0, 0},
++	{0x72, 0x22, 0x22, 0, 0},
++	{0x73, 0x22, 0x22, 0, 0},
++	{0x74, 0, 0, 1, 1},
++	{0x75, 0xa, 0xa, 0, 0},
++	{0x76, 0x1, 0x1, 0, 0},
++	{0x77, 0x22, 0x22, 0, 0},
++	{0x78, 0x30, 0x30, 0, 0},
++	{0x79, 0, 0, 0, 0},
++	{0x7A, 0, 0, 0, 0},
++	{0x7B, 0, 0, 0, 0},
++	{0x7C, 0, 0, 0, 0},
++	{0x7D, 0x5, 0x5, 1, 1},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0, 0, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0x93, 0, 0, 0, 0},
++	{0x94, 0, 0, 0, 0},
++	{0xFFFF, 0, 0, 0, 0}
++};
++
++static struct radio_regs regs_SYN_2056_rev7[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0x1, 0x1, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0, 0, 0, 0},
++	{0x21, 0, 0, 0, 0},
++	{0x22, 0x60, 0x60, 0, 0},
++	{0x23, 0x6, 0x6, 0, 0},
++	{0x24, 0xc, 0xc, 0, 0},
++	{0x25, 0, 0, 0, 0},
++	{0x26, 0, 0, 0, 0},
++	{0x27, 0, 0, 0, 0},
++	{0x28, 0x1, 0x1, 0, 0},
++	{0x29, 0, 0, 0, 0},
++	{0x2A, 0, 0, 0, 0},
++	{0x2B, 0, 0, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0, 0, 0, 0},
++	{0x2E, 0, 0, 0, 0},
++	{0x2F, 0x1f, 0x1f, 0, 0},
++	{0x30, 0x15, 0x15, 0, 0},
++	{0x31, 0xf, 0xf, 0, 0},
++	{0x32, 0, 0, 0, 0},
++	{0x33, 0, 0, 0, 0},
++	{0x34, 0, 0, 0, 0},
++	{0x35, 0, 0, 0, 0},
++	{0x36, 0, 0, 0, 0},
++	{0x37, 0, 0, 0, 0},
++	{0x38, 0, 0, 0, 0},
++	{0x39, 0, 0, 0, 0},
++	{0x3A, 0, 0, 0, 0},
++	{0x3B, 0, 0, 0, 0},
++	{0x3C, 0x13, 0x13, 0, 0},
++	{0x3D, 0xf, 0xf, 0, 0},
++	{0x3E, 0x18, 0x18, 0, 0},
++	{0x3F, 0, 0, 0, 0},
++	{0x40, 0, 0, 0, 0},
++	{0x41, 0x20, 0x20, 0, 0},
++	{0x42, 0x20, 0x20, 0, 0},
++	{0x43, 0, 0, 0, 0},
++	{0x44, 0x77, 0x77, 0, 0},
++	{0x45, 0x7, 0x7, 0, 0},
++	{0x46, 0x1, 0x1, 0, 0},
++	{0x47, 0x4, 0x4, 0, 0},
++	{0x48, 0xf, 0xf, 0, 0},
++	{0x49, 0x30, 0x30, 0, 0},
++	{0x4A, 0x32, 0x32, 0, 0},
++	{0x4B, 0xd, 0xd, 0, 0},
++	{0x4C, 0xd, 0xd, 0, 0},
++	{0x4D, 0x4, 0x4, 0, 0},
++	{0x4E, 0x6, 0x6, 0, 0},
++	{0x4F, 0x1, 0x1, 0, 0},
++	{0x50, 0x1c, 0x1c, 0, 0},
++	{0x51, 0x2, 0x2, 0, 0},
++	{0x52, 0x2, 0x2, 0, 0},
++	{0x53, 0xf7, 0xf7, 1, 1},
++	{0x54, 0xb4, 0xb4, 0, 0},
++	{0x55, 0xd2, 0xd2, 0, 0},
++	{0x56, 0, 0, 0, 0},
++	{0x57, 0, 0, 0, 0},
++	{0x58, 0x4, 0x4, 0, 0},
++	{0x59, 0x96, 0x96, 0, 0},
++	{0x5A, 0x3e, 0x3e, 0, 0},
++	{0x5B, 0x3e, 0x3e, 0, 0},
++	{0x5C, 0x13, 0x13, 0, 0},
++	{0x5D, 0x2, 0x2, 0, 0},
++	{0x5E, 0, 0, 0, 0},
++	{0x5F, 0x7, 0x7, 0, 0},
++	{0x60, 0x7, 0x7, 1, 1},
++	{0x61, 0x8, 0x8, 0, 0},
++	{0x62, 0x3, 0x3, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0, 0, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0, 0, 0, 0},
++	{0x68, 0x40, 0x40, 0, 0},
++	{0x69, 0, 0, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0, 0, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0x1, 0x1, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0x60, 0x60, 0, 0},
++	{0x71, 0x66, 0x66, 0, 0},
++	{0x72, 0xc, 0xc, 0, 0},
++	{0x73, 0x66, 0x66, 0, 0},
++	{0x74, 0x8f, 0x8f, 1, 1},
++	{0x75, 0, 0, 0, 0},
++	{0x76, 0xcc, 0xcc, 0, 0},
++	{0x77, 0x1, 0x1, 0, 0},
++	{0x78, 0x66, 0x66, 0, 0},
++	{0x79, 0x66, 0x66, 0, 0},
++	{0x7A, 0, 0, 0, 0},
++	{0x7B, 0, 0, 0, 0},
++	{0x7C, 0, 0, 0, 0},
++	{0x7D, 0, 0, 0, 0},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0xff, 0xff, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0x93, 0, 0, 0, 0},
++	{0x94, 0, 0, 0, 0},
++	{0x95, 0, 0, 0, 0},
++	{0x96, 0, 0, 0, 0},
++	{0x97, 0, 0, 0, 0},
++	{0x98, 0, 0, 0, 0},
++	{0x99, 0, 0, 0, 0},
++	{0x9A, 0, 0, 0, 0},
++	{0x9B, 0, 0, 0, 0},
++	{0x9C, 0, 0, 0, 0},
++	{0x9D, 0, 0, 0, 0},
++	{0x9E, 0, 0, 0, 0},
++	{0x9F, 0x6, 0x6, 0, 0},
++	{0xA0, 0x66, 0x66, 0, 0},
++	{0xA1, 0x66, 0x66, 0, 0},
++	{0xA2, 0x66, 0x66, 0, 0},
++	{0xA3, 0x66, 0x66, 0, 0},
++	{0xA4, 0x66, 0x66, 0, 0},
++	{0xA5, 0x66, 0x66, 0, 0},
++	{0xA6, 0x66, 0x66, 0, 0},
++	{0xA7, 0x66, 0x66, 0, 0},
++	{0xA8, 0x66, 0x66, 0, 0},
++	{0xA9, 0x66, 0x66, 0, 0},
++	{0xAA, 0x66, 0x66, 0, 0},
++	{0xAB, 0x66, 0x66, 0, 0},
++	{0xAC, 0x66, 0x66, 0, 0},
++	{0xAD, 0x66, 0x66, 0, 0},
++	{0xAE, 0x66, 0x66, 0, 0},
++	{0xAF, 0x66, 0x66, 0, 0},
++	{0xB0, 0x66, 0x66, 0, 0},
++	{0xB1, 0x66, 0x66, 0, 0},
++	{0xB2, 0x66, 0x66, 0, 0},
++	{0xB3, 0xa, 0xa, 0, 0},
++	{0xB4, 0, 0, 0, 0},
++	{0xB5, 0, 0, 0, 0},
++	{0xB6, 0, 0, 0, 0},
++	{0xFFFF, 0, 0, 0, 0},
++};
++
++static struct radio_regs regs_TX_2056_rev7[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0, 0, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0, 0, 0, 0},
++	{0x21, 0x88, 0x88, 0, 0},
++	{0x22, 0x88, 0x88, 0, 0},
++	{0x23, 0x88, 0x88, 0, 0},
++	{0x24, 0x88, 0x88, 0, 0},
++	{0x25, 0xc, 0xc, 0, 0},
++	{0x26, 0, 0, 0, 0},
++	{0x27, 0x3, 0x3, 0, 0},
++	{0x28, 0, 0, 0, 0},
++	{0x29, 0x3, 0x3, 0, 0},
++	{0x2A, 0x37, 0x37, 0, 0},
++	{0x2B, 0x3, 0x3, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0, 0, 0, 0},
++	{0x2E, 0x1, 0x1, 0, 0},
++	{0x2F, 0x1, 0x1, 0, 0},
++	{0x30, 0, 0, 0, 0},
++	{0x31, 0, 0, 0, 0},
++	{0x32, 0, 0, 0, 0},
++	{0x33, 0x11, 0x11, 0, 0},
++	{0x34, 0xee, 0xee, 1, 1},
++	{0x35, 0, 0, 0, 0},
++	{0x36, 0, 0, 0, 0},
++	{0x37, 0x3, 0x3, 0, 0},
++	{0x38, 0x50, 0x50, 1, 1},
++	{0x39, 0, 0, 0, 0},
++	{0x3A, 0x50, 0x50, 1, 1},
++	{0x3B, 0, 0, 0, 0},
++	{0x3C, 0x6e, 0x6e, 0, 0},
++	{0x3D, 0xf0, 0xf0, 1, 1},
++	{0x3E, 0, 0, 0, 0},
++	{0x3F, 0, 0, 0, 0},
++	{0x40, 0, 0, 0, 0},
++	{0x41, 0x3, 0x3, 0, 0},
++	{0x42, 0x3, 0x3, 0, 0},
++	{0x43, 0, 0, 0, 0},
++	{0x44, 0x1e, 0x1e, 0, 0},
++	{0x45, 0, 0, 0, 0},
++	{0x46, 0x6e, 0x6e, 0, 0},
++	{0x47, 0xf0, 0xf0, 1, 1},
++	{0x48, 0, 0, 0, 0},
++	{0x49, 0x2, 0x2, 0, 0},
++	{0x4A, 0xff, 0xff, 1, 1},
++	{0x4B, 0xc, 0xc, 0, 0},
++	{0x4C, 0, 0, 0, 0},
++	{0x4D, 0x38, 0x38, 0, 0},
++	{0x4E, 0x70, 0x70, 1, 1},
++	{0x4F, 0x2, 0x2, 0, 0},
++	{0x50, 0x88, 0x88, 0, 0},
++	{0x51, 0xc, 0xc, 0, 0},
++	{0x52, 0, 0, 0, 0},
++	{0x53, 0x8, 0x8, 0, 0},
++	{0x54, 0x70, 0x70, 1, 1},
++	{0x55, 0x2, 0x2, 0, 0},
++	{0x56, 0xff, 0xff, 1, 1},
++	{0x57, 0, 0, 0, 0},
++	{0x58, 0x83, 0x83, 0, 0},
++	{0x59, 0x77, 0x77, 1, 1},
++	{0x5A, 0, 0, 0, 0},
++	{0x5B, 0x2, 0x2, 0, 0},
++	{0x5C, 0x88, 0x88, 0, 0},
++	{0x5D, 0, 0, 0, 0},
++	{0x5E, 0x8, 0x8, 0, 0},
++	{0x5F, 0x77, 0x77, 1, 1},
++	{0x60, 0x1, 0x1, 0, 0},
++	{0x61, 0, 0, 0, 0},
++	{0x62, 0x7, 0x7, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0x7, 0x7, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0, 0, 1, 1},
++	{0x68, 0, 0, 0, 0},
++	{0x69, 0xa, 0xa, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0, 0, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0, 0, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0, 0, 0, 0},
++	{0x71, 0x2, 0x2, 0, 0},
++	{0x72, 0, 0, 0, 0},
++	{0x73, 0, 0, 0, 0},
++	{0x74, 0xe, 0xe, 0, 0},
++	{0x75, 0xe, 0xe, 0, 0},
++	{0x76, 0xe, 0xe, 0, 0},
++	{0x77, 0x13, 0x13, 0, 0},
++	{0x78, 0x13, 0x13, 0, 0},
++	{0x79, 0x1b, 0x1b, 0, 0},
++	{0x7A, 0x1b, 0x1b, 0, 0},
++	{0x7B, 0x55, 0x55, 0, 0},
++	{0x7C, 0x5b, 0x5b, 0, 0},
++	{0x7D, 0x30, 0x30, 1, 1},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0, 0, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0x93, 0x70, 0x70, 0, 0},
++	{0x94, 0x70, 0x70, 0, 0},
++	{0x95, 0x71, 0x71, 1, 1},
++	{0x96, 0x71, 0x71, 1, 1},
++	{0x97, 0x72, 0x72, 1, 1},
++	{0x98, 0x73, 0x73, 1, 1},
++	{0x99, 0x74, 0x74, 1, 1},
++	{0x9A, 0x75, 0x75, 1, 1},
++	{0xFFFF, 0, 0, 0, 0},
++};
++
++static struct radio_regs regs_RX_2056_rev7[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0, 0, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0x3, 0x3, 0, 0},
++	{0x21, 0, 0, 0, 0},
++	{0x22, 0, 0, 0, 0},
++	{0x23, 0x90, 0x90, 0, 0},
++	{0x24, 0x55, 0x55, 0, 0},
++	{0x25, 0x15, 0x15, 0, 0},
++	{0x26, 0x5, 0x5, 0, 0},
++	{0x27, 0x15, 0x15, 0, 0},
++	{0x28, 0x5, 0x5, 0, 0},
++	{0x29, 0x20, 0x20, 0, 0},
++	{0x2A, 0x11, 0x11, 0, 0},
++	{0x2B, 0x90, 0x90, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0x88, 0x88, 0, 0},
++	{0x2E, 0x32, 0x32, 0, 0},
++	{0x2F, 0x77, 0x77, 0, 0},
++	{0x30, 0x17, 0x17, 1, 1},
++	{0x31, 0xff, 0xff, 1, 1},
++	{0x32, 0x20, 0x20, 0, 0},
++	{0x33, 0, 0, 0, 0},
++	{0x34, 0x88, 0x88, 0, 0},
++	{0x35, 0x32, 0x32, 0, 0},
++	{0x36, 0x77, 0x77, 0, 0},
++	{0x37, 0x17, 0x17, 1, 1},
++	{0x38, 0xf0, 0xf0, 1, 1},
++	{0x39, 0x20, 0x20, 0, 0},
++	{0x3A, 0x8, 0x8, 0, 0},
++	{0x3B, 0x55, 0x55, 1, 1},
++	{0x3C, 0, 0, 0, 0},
++	{0x3D, 0x88, 0x88, 1, 1},
++	{0x3E, 0, 0, 0, 0},
++	{0x3F, 0, 0, 1, 1},
++	{0x40, 0x7, 0x7, 1, 1},
++	{0x41, 0x6, 0x6, 0, 0},
++	{0x42, 0x4, 0x4, 0, 0},
++	{0x43, 0, 0, 0, 0},
++	{0x44, 0x8, 0x8, 0, 0},
++	{0x45, 0x55, 0x55, 1, 1},
++	{0x46, 0, 0, 0, 0},
++	{0x47, 0x11, 0x11, 0, 0},
++	{0x48, 0, 0, 0, 0},
++	{0x49, 0, 0, 1, 1},
++	{0x4A, 0x7, 0x7, 0, 0},
++	{0x4B, 0x6, 0x6, 0, 0},
++	{0x4C, 0x4, 0x4, 0, 0},
++	{0x4D, 0, 0, 0, 0},
++	{0x4E, 0, 0, 0, 0},
++	{0x4F, 0x26, 0x26, 1, 1},
++	{0x50, 0x26, 0x26, 1, 1},
++	{0x51, 0xf, 0xf, 1, 1},
++	{0x52, 0xf, 0xf, 1, 1},
++	{0x53, 0x44, 0x44, 0, 0},
++	{0x54, 0, 0, 0, 0},
++	{0x55, 0, 0, 0, 0},
++	{0x56, 0x8, 0x8, 0, 0},
++	{0x57, 0x8, 0x8, 0, 0},
++	{0x58, 0x7, 0x7, 0, 0},
++	{0x59, 0x22, 0x22, 0, 0},
++	{0x5A, 0x22, 0x22, 0, 0},
++	{0x5B, 0x2, 0x2, 0, 0},
++	{0x5C, 0x4, 0x4, 1, 1},
++	{0x5D, 0x7, 0x7, 0, 0},
++	{0x5E, 0x55, 0x55, 0, 0},
++	{0x5F, 0x23, 0x23, 0, 0},
++	{0x60, 0x41, 0x41, 0, 0},
++	{0x61, 0x1, 0x1, 0, 0},
++	{0x62, 0xa, 0xa, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0, 0, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0, 0, 0, 0},
++	{0x68, 0, 0, 0, 0},
++	{0x69, 0, 0, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0xc, 0xc, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0, 0, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0, 0, 0, 0},
++	{0x71, 0, 0, 0, 0},
++	{0x72, 0x22, 0x22, 0, 0},
++	{0x73, 0x22, 0x22, 0, 0},
++	{0x74, 0, 0, 1, 1},
++	{0x75, 0xa, 0xa, 0, 0},
++	{0x76, 0x1, 0x1, 0, 0},
++	{0x77, 0x22, 0x22, 0, 0},
++	{0x78, 0x30, 0x30, 0, 0},
++	{0x79, 0, 0, 0, 0},
++	{0x7A, 0, 0, 0, 0},
++	{0x7B, 0, 0, 0, 0},
++	{0x7C, 0, 0, 0, 0},
++	{0x7D, 0, 0, 0, 0},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0, 0, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0x93, 0, 0, 0, 0},
++	{0x94, 0, 0, 0, 0},
++	{0xFFFF, 0, 0, 0, 0},
++};
++
++static struct radio_regs regs_SYN_2056_rev8[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0x1, 0x1, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0, 0, 0, 0},
++	{0x21, 0, 0, 0, 0},
++	{0x22, 0x60, 0x60, 0, 0},
++	{0x23, 0x6, 0x6, 0, 0},
++	{0x24, 0xc, 0xc, 0, 0},
++	{0x25, 0, 0, 0, 0},
++	{0x26, 0, 0, 0, 0},
++	{0x27, 0, 0, 0, 0},
++	{0x28, 0x1, 0x1, 0, 0},
++	{0x29, 0, 0, 0, 0},
++	{0x2A, 0, 0, 0, 0},
++	{0x2B, 0, 0, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0, 0, 0, 0},
++	{0x2E, 0, 0, 0, 0},
++	{0x2F, 0x1f, 0x1f, 0, 0},
++	{0x30, 0x15, 0x15, 0, 0},
++	{0x31, 0xf, 0xf, 0, 0},
++	{0x32, 0, 0, 0, 0},
++	{0x33, 0, 0, 0, 0},
++	{0x34, 0, 0, 0, 0},
++	{0x35, 0, 0, 0, 0},
++	{0x36, 0, 0, 0, 0},
++	{0x37, 0, 0, 0, 0},
++	{0x38, 0, 0, 0, 0},
++	{0x39, 0, 0, 0, 0},
++	{0x3A, 0, 0, 0, 0},
++	{0x3B, 0, 0, 0, 0},
++	{0x3C, 0x13, 0x13, 0, 0},
++	{0x3D, 0xf, 0xf, 0, 0},
++	{0x3E, 0x18, 0x18, 0, 0},
++	{0x3F, 0, 0, 0, 0},
++	{0x40, 0, 0, 0, 0},
++	{0x41, 0x20, 0x20, 0, 0},
++	{0x42, 0x20, 0x20, 0, 0},
++	{0x43, 0, 0, 0, 0},
++	{0x44, 0x77, 0x77, 0, 0},
++	{0x45, 0x7, 0x7, 0, 0},
++	{0x46, 0x1, 0x1, 0, 0},
++	{0x47, 0x4, 0x4, 0, 0},
++	{0x48, 0xf, 0xf, 0, 0},
++	{0x49, 0x30, 0x30, 0, 0},
++	{0x4A, 0x32, 0x32, 0, 0},
++	{0x4B, 0xd, 0xd, 0, 0},
++	{0x4C, 0xd, 0xd, 0, 0},
++	{0x4D, 0x4, 0x4, 0, 0},
++	{0x4E, 0x6, 0x6, 0, 0},
++	{0x4F, 0x1, 0x1, 0, 0},
++	{0x50, 0x1c, 0x1c, 0, 0},
++	{0x51, 0x2, 0x2, 0, 0},
++	{0x52, 0x2, 0x2, 0, 0},
++	{0x53, 0xf7, 0xf7, 1, 1},
++	{0x54, 0xb4, 0xb4, 0, 0},
++	{0x55, 0xd2, 0xd2, 0, 0},
++	{0x56, 0, 0, 0, 0},
++	{0x57, 0, 0, 0, 0},
++	{0x58, 0x4, 0x4, 0, 0},
++	{0x59, 0x96, 0x96, 0, 0},
++	{0x5A, 0x3e, 0x3e, 0, 0},
++	{0x5B, 0x3e, 0x3e, 0, 0},
++	{0x5C, 0x13, 0x13, 0, 0},
++	{0x5D, 0x2, 0x2, 0, 0},
++	{0x5E, 0, 0, 0, 0},
++	{0x5F, 0x7, 0x7, 0, 0},
++	{0x60, 0x7, 0x7, 1, 1},
++	{0x61, 0x8, 0x8, 0, 0},
++	{0x62, 0x3, 0x3, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0, 0, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0, 0, 0, 0},
++	{0x68, 0x40, 0x40, 0, 0},
++	{0x69, 0, 0, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0, 0, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0x1, 0x1, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0x60, 0x60, 0, 0},
++	{0x71, 0x66, 0x66, 0, 0},
++	{0x72, 0xc, 0xc, 0, 0},
++	{0x73, 0x66, 0x66, 0, 0},
++	{0x74, 0x8f, 0x8f, 1, 1},
++	{0x75, 0, 0, 0, 0},
++	{0x76, 0xcc, 0xcc, 0, 0},
++	{0x77, 0x1, 0x1, 0, 0},
++	{0x78, 0x66, 0x66, 0, 0},
++	{0x79, 0x66, 0x66, 0, 0},
++	{0x7A, 0, 0, 0, 0},
++	{0x7B, 0, 0, 0, 0},
++	{0x7C, 0, 0, 0, 0},
++	{0x7D, 0, 0, 0, 0},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0xff, 0xff, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0x93, 0, 0, 0, 0},
++	{0x94, 0, 0, 0, 0},
++	{0x95, 0, 0, 0, 0},
++	{0x96, 0, 0, 0, 0},
++	{0x97, 0, 0, 0, 0},
++	{0x98, 0, 0, 0, 0},
++	{0x99, 0, 0, 0, 0},
++	{0x9A, 0, 0, 0, 0},
++	{0x9B, 0, 0, 0, 0},
++	{0x9C, 0, 0, 0, 0},
++	{0x9D, 0, 0, 0, 0},
++	{0x9E, 0, 0, 0, 0},
++	{0x9F, 0x6, 0x6, 0, 0},
++	{0xA0, 0x66, 0x66, 0, 0},
++	{0xA1, 0x66, 0x66, 0, 0},
++	{0xA2, 0x66, 0x66, 0, 0},
++	{0xA3, 0x66, 0x66, 0, 0},
++	{0xA4, 0x66, 0x66, 0, 0},
++	{0xA5, 0x66, 0x66, 0, 0},
++	{0xA6, 0x66, 0x66, 0, 0},
++	{0xA7, 0x66, 0x66, 0, 0},
++	{0xA8, 0x66, 0x66, 0, 0},
++	{0xA9, 0x66, 0x66, 0, 0},
++	{0xAA, 0x66, 0x66, 0, 0},
++	{0xAB, 0x66, 0x66, 0, 0},
++	{0xAC, 0x66, 0x66, 0, 0},
++	{0xAD, 0x66, 0x66, 0, 0},
++	{0xAE, 0x66, 0x66, 0, 0},
++	{0xAF, 0x66, 0x66, 0, 0},
++	{0xB0, 0x66, 0x66, 0, 0},
++	{0xB1, 0x66, 0x66, 0, 0},
++	{0xB2, 0x66, 0x66, 0, 0},
++	{0xB3, 0xa, 0xa, 0, 0},
++	{0xB4, 0, 0, 0, 0},
++	{0xB5, 0, 0, 0, 0},
++	{0xB6, 0, 0, 0, 0},
++	{0xFFFF, 0, 0, 0, 0},
++};
++
++static struct radio_regs regs_TX_2056_rev8[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0, 0, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0, 0, 0, 0},
++	{0x21, 0x88, 0x88, 0, 0},
++	{0x22, 0x88, 0x88, 0, 0},
++	{0x23, 0x88, 0x88, 0, 0},
++	{0x24, 0x88, 0x88, 0, 0},
++	{0x25, 0xc, 0xc, 0, 0},
++	{0x26, 0, 0, 0, 0},
++	{0x27, 0x3, 0x3, 0, 0},
++	{0x28, 0, 0, 0, 0},
++	{0x29, 0x3, 0x3, 0, 0},
++	{0x2A, 0x37, 0x37, 0, 0},
++	{0x2B, 0x3, 0x3, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0, 0, 0, 0},
++	{0x2E, 0x1, 0x1, 0, 0},
++	{0x2F, 0x1, 0x1, 0, 0},
++	{0x30, 0, 0, 0, 0},
++	{0x31, 0, 0, 0, 0},
++	{0x32, 0, 0, 0, 0},
++	{0x33, 0x11, 0x11, 0, 0},
++	{0x34, 0xee, 0xee, 1, 1},
++	{0x35, 0, 0, 0, 0},
++	{0x36, 0, 0, 0, 0},
++	{0x37, 0x3, 0x3, 0, 0},
++	{0x38, 0x50, 0x50, 1, 1},
++	{0x39, 0, 0, 0, 0},
++	{0x3A, 0x50, 0x50, 1, 1},
++	{0x3B, 0, 0, 0, 0},
++	{0x3C, 0x6e, 0x6e, 0, 0},
++	{0x3D, 0xf0, 0xf0, 1, 1},
++	{0x3E, 0, 0, 0, 0},
++	{0x3F, 0, 0, 0, 0},
++	{0x40, 0, 0, 0, 0},
++	{0x41, 0x3, 0x3, 0, 0},
++	{0x42, 0x3, 0x3, 0, 0},
++	{0x43, 0, 0, 0, 0},
++	{0x44, 0x1e, 0x1e, 0, 0},
++	{0x45, 0, 0, 0, 0},
++	{0x46, 0x6e, 0x6e, 0, 0},
++	{0x47, 0xf0, 0xf0, 1, 1},
++	{0x48, 0, 0, 0, 0},
++	{0x49, 0x2, 0x2, 0, 0},
++	{0x4A, 0xff, 0xff, 1, 1},
++	{0x4B, 0xc, 0xc, 0, 0},
++	{0x4C, 0, 0, 0, 0},
++	{0x4D, 0x38, 0x38, 0, 0},
++	{0x4E, 0x70, 0x70, 1, 1},
++	{0x4F, 0x2, 0x2, 0, 0},
++	{0x50, 0x88, 0x88, 0, 0},
++	{0x51, 0xc, 0xc, 0, 0},
++	{0x52, 0, 0, 0, 0},
++	{0x53, 0x8, 0x8, 0, 0},
++	{0x54, 0x70, 0x70, 1, 1},
++	{0x55, 0x2, 0x2, 0, 0},
++	{0x56, 0xff, 0xff, 1, 1},
++	{0x57, 0, 0, 0, 0},
++	{0x58, 0x83, 0x83, 0, 0},
++	{0x59, 0x77, 0x77, 1, 1},
++	{0x5A, 0, 0, 0, 0},
++	{0x5B, 0x2, 0x2, 0, 0},
++	{0x5C, 0x88, 0x88, 0, 0},
++	{0x5D, 0, 0, 0, 0},
++	{0x5E, 0x8, 0x8, 0, 0},
++	{0x5F, 0x77, 0x77, 1, 1},
++	{0x60, 0x1, 0x1, 0, 0},
++	{0x61, 0, 0, 0, 0},
++	{0x62, 0x7, 0x7, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0x7, 0x7, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0, 0, 1, 1},
++	{0x68, 0, 0, 0, 0},
++	{0x69, 0xa, 0xa, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0, 0, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0, 0, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0, 0, 0, 0},
++	{0x71, 0x2, 0x2, 0, 0},
++	{0x72, 0, 0, 0, 0},
++	{0x73, 0, 0, 0, 0},
++	{0x74, 0xe, 0xe, 0, 0},
++	{0x75, 0xe, 0xe, 0, 0},
++	{0x76, 0xe, 0xe, 0, 0},
++	{0x77, 0x13, 0x13, 0, 0},
++	{0x78, 0x13, 0x13, 0, 0},
++	{0x79, 0x1b, 0x1b, 0, 0},
++	{0x7A, 0x1b, 0x1b, 0, 0},
++	{0x7B, 0x55, 0x55, 0, 0},
++	{0x7C, 0x5b, 0x5b, 0, 0},
++	{0x7D, 0x30, 0x30, 1, 1},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0, 0, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0x93, 0x70, 0x70, 0, 0},
++	{0x94, 0x70, 0x70, 0, 0},
++	{0x95, 0x70, 0x70, 0, 0},
++	{0x96, 0x70, 0x70, 0, 0},
++	{0x97, 0x70, 0x70, 0, 0},
++	{0x98, 0x70, 0x70, 0, 0},
++	{0x99, 0x70, 0x70, 0, 0},
++	{0x9A, 0x70, 0x70, 0, 0},
++	{0xFFFF, 0, 0, 0, 0},
++};
++
++static struct radio_regs regs_RX_2056_rev8[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0, 0, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0x3, 0x3, 0, 0},
++	{0x21, 0, 0, 0, 0},
++	{0x22, 0, 0, 0, 0},
++	{0x23, 0x90, 0x90, 0, 0},
++	{0x24, 0x55, 0x55, 0, 0},
++	{0x25, 0x15, 0x15, 0, 0},
++	{0x26, 0x5, 0x5, 0, 0},
++	{0x27, 0x15, 0x15, 0, 0},
++	{0x28, 0x5, 0x5, 0, 0},
++	{0x29, 0x20, 0x20, 0, 0},
++	{0x2A, 0x11, 0x11, 0, 0},
++	{0x2B, 0x90, 0x90, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0x88, 0x88, 0, 0},
++	{0x2E, 0x32, 0x32, 0, 0},
++	{0x2F, 0x77, 0x77, 0, 0},
++	{0x30, 0x17, 0x17, 1, 1},
++	{0x31, 0xff, 0xff, 1, 1},
++	{0x32, 0x20, 0x20, 0, 0},
++	{0x33, 0, 0, 0, 0},
++	{0x34, 0x88, 0x88, 0, 0},
++	{0x35, 0x32, 0x32, 0, 0},
++	{0x36, 0x77, 0x77, 0, 0},
++	{0x37, 0x17, 0x17, 1, 1},
++	{0x38, 0xf0, 0xf0, 1, 1},
++	{0x39, 0x20, 0x20, 0, 0},
++	{0x3A, 0x8, 0x8, 0, 0},
++	{0x3B, 0x55, 0x55, 1, 1},
++	{0x3C, 0, 0, 0, 0},
++	{0x3D, 0x88, 0x88, 1, 1},
++	{0x3E, 0, 0, 0, 0},
++	{0x3F, 0x44, 0x44, 0, 0},
++	{0x40, 0x7, 0x7, 1, 1},
++	{0x41, 0x6, 0x6, 0, 0},
++	{0x42, 0x4, 0x4, 0, 0},
++	{0x43, 0, 0, 0, 0},
++	{0x44, 0x8, 0x8, 0, 0},
++	{0x45, 0x55, 0x55, 1, 1},
++	{0x46, 0, 0, 0, 0},
++	{0x47, 0x11, 0x11, 0, 0},
++	{0x48, 0, 0, 0, 0},
++	{0x49, 0x44, 0x44, 0, 0},
++	{0x4A, 0x7, 0x7, 0, 0},
++	{0x4B, 0x6, 0x6, 0, 0},
++	{0x4C, 0x4, 0x4, 0, 0},
++	{0x4D, 0, 0, 0, 0},
++	{0x4E, 0, 0, 0, 0},
++	{0x4F, 0x26, 0x26, 1, 1},
++	{0x50, 0x26, 0x26, 1, 1},
++	{0x51, 0xf, 0xf, 1, 1},
++	{0x52, 0xf, 0xf, 1, 1},
++	{0x53, 0x44, 0x44, 0, 0},
++	{0x54, 0, 0, 0, 0},
++	{0x55, 0, 0, 0, 0},
++	{0x56, 0x8, 0x8, 0, 0},
++	{0x57, 0x8, 0x8, 0, 0},
++	{0x58, 0x7, 0x7, 0, 0},
++	{0x59, 0x22, 0x22, 0, 0},
++	{0x5A, 0x22, 0x22, 0, 0},
++	{0x5B, 0x2, 0x2, 0, 0},
++	{0x5C, 0x4, 0x4, 1, 1},
++	{0x5D, 0x7, 0x7, 0, 0},
++	{0x5E, 0x55, 0x55, 0, 0},
++	{0x5F, 0x23, 0x23, 0, 0},
++	{0x60, 0x41, 0x41, 0, 0},
++	{0x61, 0x1, 0x1, 0, 0},
++	{0x62, 0xa, 0xa, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0, 0, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0, 0, 0, 0},
++	{0x68, 0, 0, 0, 0},
++	{0x69, 0, 0, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0xc, 0xc, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0, 0, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0, 0, 0, 0},
++	{0x71, 0, 0, 0, 0},
++	{0x72, 0x22, 0x22, 0, 0},
++	{0x73, 0x22, 0x22, 0, 0},
++	{0x74, 0, 0, 1, 1},
++	{0x75, 0xa, 0xa, 0, 0},
++	{0x76, 0x1, 0x1, 0, 0},
++	{0x77, 0x22, 0x22, 0, 0},
++	{0x78, 0x30, 0x30, 0, 0},
++	{0x79, 0, 0, 0, 0},
++	{0x7A, 0, 0, 0, 0},
++	{0x7B, 0, 0, 0, 0},
++	{0x7C, 0, 0, 0, 0},
++	{0x7D, 0x5, 0x5, 1, 1},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0, 0, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0x93, 0, 0, 0, 0},
++	{0x94, 0, 0, 0, 0},
++	{0xFFFF, 0, 0, 0, 0},
++};
++
++static const struct radio_regs regs_SYN_2056_rev11[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0x1, 0x1, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0, 0, 0, 0},
++	{0x21, 0, 0, 0, 0},
++	{0x22, 0x60, 0x60, 0, 0},
++	{0x23, 0x6, 0x6, 0, 0},
++	{0x24, 0xc, 0xc, 0, 0},
++	{0x25, 0, 0, 0, 0},
++	{0x26, 0, 0, 0, 0},
++	{0x27, 0, 0, 0, 0},
++	{0x28, 0x1, 0x1, 0, 0},
++	{0x29, 0, 0, 0, 0},
++	{0x2A, 0, 0, 0, 0},
++	{0x2B, 0, 0, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0, 0, 0, 0},
++	{0x2E, 0, 0, 0, 0},
++	{0x2F, 0x1f, 0x1f, 0, 0},
++	{0x30, 0x15, 0x15, 0, 0},
++	{0x31, 0xf, 0xf, 0, 0},
++	{0x32, 0, 0, 0, 0},
++	{0x33, 0, 0, 0, 0},
++	{0x34, 0, 0, 0, 0},
++	{0x35, 0, 0, 0, 0},
++	{0x36, 0, 0, 0, 0},
++	{0x37, 0, 0, 0, 0},
++	{0x38, 0, 0, 0, 0},
++	{0x39, 0, 0, 0, 0},
++	{0x3A, 0, 0, 0, 0},
++	{0x3B, 0, 0, 0, 0},
++	{0x3C, 0x13, 0x13, 0, 0},
++	{0x3D, 0xf, 0xf, 0, 0},
++	{0x3E, 0x18, 0x18, 0, 0},
++	{0x3F, 0, 0, 0, 0},
++	{0x40, 0, 0, 0, 0},
++	{0x41, 0x20, 0x20, 0, 0},
++	{0x42, 0x20, 0x20, 0, 0},
++	{0x43, 0, 0, 0, 0},
++	{0x44, 0x77, 0x77, 0, 0},
++	{0x45, 0x7, 0x7, 0, 0},
++	{0x46, 0x1, 0x1, 0, 0},
++	{0x47, 0x6, 0x6, 1, 1},
++	{0x48, 0xf, 0xf, 0, 0},
++	{0x49, 0x3f, 0x3f, 1, 1},
++	{0x4A, 0x32, 0x32, 0, 0},
++	{0x4B, 0x6, 0x6, 1, 1},
++	{0x4C, 0x6, 0x6, 1, 1},
++	{0x4D, 0x4, 0x4, 0, 0},
++	{0x4E, 0x2b, 0x2b, 1, 1},
++	{0x4F, 0x1, 0x1, 0, 0},
++	{0x50, 0x1c, 0x1c, 0, 0},
++	{0x51, 0x2, 0x2, 0, 0},
++	{0x52, 0x2, 0x2, 0, 0},
++	{0x53, 0xf7, 0xf7, 1, 1},
++	{0x54, 0xb4, 0xb4, 0, 0},
++	{0x55, 0xd2, 0xd2, 0, 0},
++	{0x56, 0, 0, 0, 0},
++	{0x57, 0, 0, 0, 0},
++	{0x58, 0x4, 0x4, 0, 0},
++	{0x59, 0x96, 0x96, 0, 0},
++	{0x5A, 0x3e, 0x3e, 0, 0},
++	{0x5B, 0x3e, 0x3e, 0, 0},
++	{0x5C, 0x13, 0x13, 0, 0},
++	{0x5D, 0x2, 0x2, 0, 0},
++	{0x5E, 0, 0, 0, 0},
++	{0x5F, 0x7, 0x7, 0, 0},
++	{0x60, 0x7, 0x7, 1, 1},
++	{0x61, 0x8, 0x8, 0, 0},
++	{0x62, 0x3, 0x3, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0, 0, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0, 0, 0, 0},
++	{0x68, 0x40, 0x40, 0, 0},
++	{0x69, 0, 0, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0, 0, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0x1, 0x1, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0x60, 0x60, 0, 0},
++	{0x71, 0x66, 0x66, 0, 0},
++	{0x72, 0xc, 0xc, 0, 0},
++	{0x73, 0x66, 0x66, 0, 0},
++	{0x74, 0x8f, 0x8f, 1, 1},
++	{0x75, 0, 0, 0, 0},
++	{0x76, 0xcc, 0xcc, 0, 0},
++	{0x77, 0x1, 0x1, 0, 0},
++	{0x78, 0x66, 0x66, 0, 0},
++	{0x79, 0x66, 0x66, 0, 0},
++	{0x7A, 0, 0, 0, 0},
++	{0x7B, 0, 0, 0, 0},
++	{0x7C, 0, 0, 0, 0},
++	{0x7D, 0, 0, 0, 0},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0xff, 0xff, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0x93, 0, 0, 0, 0},
++	{0x94, 0, 0, 0, 0},
++	{0x95, 0, 0, 0, 0},
++	{0x96, 0, 0, 0, 0},
++	{0x97, 0, 0, 0, 0},
++	{0x98, 0, 0, 0, 0},
++	{0x99, 0, 0, 0, 0},
++	{0x9A, 0, 0, 0, 0},
++	{0x9B, 0, 0, 0, 0},
++	{0x9C, 0, 0, 0, 0},
++	{0x9D, 0, 0, 0, 0},
++	{0x9E, 0, 0, 0, 0},
++	{0x9F, 0x6, 0x6, 0, 0},
++	{0xA0, 0x66, 0x66, 0, 0},
++	{0xA1, 0x66, 0x66, 0, 0},
++	{0xA2, 0x66, 0x66, 0, 0},
++	{0xA3, 0x66, 0x66, 0, 0},
++	{0xA4, 0x66, 0x66, 0, 0},
++	{0xA5, 0x66, 0x66, 0, 0},
++	{0xA6, 0x66, 0x66, 0, 0},
++	{0xA7, 0x66, 0x66, 0, 0},
++	{0xA8, 0x66, 0x66, 0, 0},
++	{0xA9, 0x66, 0x66, 0, 0},
++	{0xAA, 0x66, 0x66, 0, 0},
++	{0xAB, 0x66, 0x66, 0, 0},
++	{0xAC, 0x66, 0x66, 0, 0},
++	{0xAD, 0x66, 0x66, 0, 0},
++	{0xAE, 0x66, 0x66, 0, 0},
++	{0xAF, 0x66, 0x66, 0, 0},
++	{0xB0, 0x66, 0x66, 0, 0},
++	{0xB1, 0x66, 0x66, 0, 0},
++	{0xB2, 0x66, 0x66, 0, 0},
++	{0xB3, 0xa, 0xa, 0, 0},
++	{0xB4, 0, 0, 0, 0},
++	{0xB5, 0, 0, 0, 0},
++	{0xB6, 0, 0, 0, 0},
++	{0xFFFF, 0, 0, 0, 0},
++};
++
++static const struct radio_regs regs_TX_2056_rev11[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0, 0, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0, 0, 0, 0},
++	{0x21, 0x88, 0x88, 0, 0},
++	{0x22, 0x88, 0x88, 0, 0},
++	{0x23, 0x88, 0x88, 0, 0},
++	{0x24, 0x88, 0x88, 0, 0},
++	{0x25, 0xc, 0xc, 0, 0},
++	{0x26, 0, 0, 0, 0},
++	{0x27, 0x3, 0x3, 0, 0},
++	{0x28, 0, 0, 0, 0},
++	{0x29, 0x3, 0x3, 0, 0},
++	{0x2A, 0x37, 0x37, 0, 0},
++	{0x2B, 0x3, 0x3, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0, 0, 0, 0},
++	{0x2E, 0x1, 0x1, 0, 0},
++	{0x2F, 0x1, 0x1, 0, 0},
++	{0x30, 0, 0, 0, 0},
++	{0x31, 0, 0, 0, 0},
++	{0x32, 0, 0, 0, 0},
++	{0x33, 0x11, 0x11, 0, 0},
++	{0x34, 0xee, 0xee, 1, 1},
++	{0x35, 0, 0, 0, 0},
++	{0x36, 0, 0, 0, 0},
++	{0x37, 0x3, 0x3, 0, 0},
++	{0x38, 0x50, 0x50, 1, 1},
++	{0x39, 0, 0, 0, 0},
++	{0x3A, 0x50, 0x50, 1, 1},
++	{0x3B, 0, 0, 0, 0},
++	{0x3C, 0x6e, 0x6e, 0, 0},
++	{0x3D, 0xf0, 0xf0, 1, 1},
++	{0x3E, 0, 0, 0, 0},
++	{0x3F, 0, 0, 0, 0},
++	{0x40, 0, 0, 0, 0},
++	{0x41, 0x3, 0x3, 0, 0},
++	{0x42, 0x3, 0x3, 0, 0},
++	{0x43, 0, 0, 0, 0},
++	{0x44, 0x1e, 0x1e, 0, 0},
++	{0x45, 0, 0, 0, 0},
++	{0x46, 0x6e, 0x6e, 0, 0},
++	{0x47, 0xf0, 0xf0, 1, 1},
++	{0x48, 0, 0, 0, 0},
++	{0x49, 0x2, 0x2, 0, 0},
++	{0x4A, 0xff, 0xff, 1, 1},
++	{0x4B, 0xc, 0xc, 0, 0},
++	{0x4C, 0, 0, 0, 0},
++	{0x4D, 0x38, 0x38, 0, 0},
++	{0x4E, 0x70, 0x70, 1, 1},
++	{0x4F, 0x2, 0x2, 0, 0},
++	{0x50, 0x88, 0x88, 0, 0},
++	{0x51, 0xc, 0xc, 0, 0},
++	{0x52, 0, 0, 0, 0},
++	{0x53, 0x8, 0x8, 0, 0},
++	{0x54, 0x70, 0x70, 1, 1},
++	{0x55, 0x2, 0x2, 0, 0},
++	{0x56, 0xff, 0xff, 1, 1},
++	{0x57, 0, 0, 0, 0},
++	{0x58, 0x83, 0x83, 0, 0},
++	{0x59, 0x77, 0x77, 1, 1},
++	{0x5A, 0, 0, 0, 0},
++	{0x5B, 0x2, 0x2, 0, 0},
++	{0x5C, 0x88, 0x88, 0, 0},
++	{0x5D, 0, 0, 0, 0},
++	{0x5E, 0x8, 0x8, 0, 0},
++	{0x5F, 0x77, 0x77, 1, 1},
++	{0x60, 0x1, 0x1, 0, 0},
++	{0x61, 0, 0, 0, 0},
++	{0x62, 0x7, 0x7, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0x7, 0x7, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0, 0, 1, 1},
++	{0x68, 0, 0, 0, 0},
++	{0x69, 0xa, 0xa, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0, 0, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0, 0, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0, 0, 0, 0},
++	{0x71, 0x2, 0x2, 0, 0},
++	{0x72, 0, 0, 0, 0},
++	{0x73, 0, 0, 0, 0},
++	{0x74, 0xe, 0xe, 0, 0},
++	{0x75, 0xe, 0xe, 0, 0},
++	{0x76, 0xe, 0xe, 0, 0},
++	{0x77, 0x13, 0x13, 0, 0},
++	{0x78, 0x13, 0x13, 0, 0},
++	{0x79, 0x1b, 0x1b, 0, 0},
++	{0x7A, 0x1b, 0x1b, 0, 0},
++	{0x7B, 0x55, 0x55, 0, 0},
++	{0x7C, 0x5b, 0x5b, 0, 0},
++	{0x7D, 0x30, 0x30, 1, 1},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0, 0, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0x93, 0x70, 0x70, 0, 0},
++	{0x94, 0x70, 0x70, 0, 0},
++	{0x95, 0x70, 0x70, 0, 0},
++	{0x96, 0x70, 0x70, 0, 0},
++	{0x97, 0x70, 0x70, 0, 0},
++	{0x98, 0x70, 0x70, 0, 0},
++	{0x99, 0x70, 0x70, 0, 0},
++	{0x9A, 0x70, 0x70, 0, 0},
++	{0xFFFF, 0, 0, 0, 0},
++};
++
++static const struct radio_regs regs_RX_2056_rev11[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0, 0, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0x3, 0x3, 0, 0},
++	{0x21, 0, 0, 0, 0},
++	{0x22, 0, 0, 0, 0},
++	{0x23, 0x90, 0x90, 0, 0},
++	{0x24, 0x55, 0x55, 0, 0},
++	{0x25, 0x15, 0x15, 0, 0},
++	{0x26, 0x5, 0x5, 0, 0},
++	{0x27, 0x15, 0x15, 0, 0},
++	{0x28, 0x5, 0x5, 0, 0},
++	{0x29, 0x20, 0x20, 0, 0},
++	{0x2A, 0x11, 0x11, 0, 0},
++	{0x2B, 0x90, 0x90, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0x88, 0x88, 0, 0},
++	{0x2E, 0x32, 0x32, 0, 0},
++	{0x2F, 0x77, 0x77, 0, 0},
++	{0x30, 0x17, 0x17, 1, 1},
++	{0x31, 0xff, 0xff, 1, 1},
++	{0x32, 0x20, 0x20, 0, 0},
++	{0x33, 0, 0, 0, 0},
++	{0x34, 0x88, 0x88, 0, 0},
++	{0x35, 0x32, 0x32, 0, 0},
++	{0x36, 0x77, 0x77, 0, 0},
++	{0x37, 0x17, 0x17, 1, 1},
++	{0x38, 0xf0, 0xf0, 1, 1},
++	{0x39, 0x20, 0x20, 0, 0},
++	{0x3A, 0x8, 0x8, 0, 0},
++	{0x3B, 0x55, 0x55, 1, 1},
++	{0x3C, 0, 0, 0, 0},
++	{0x3D, 0x88, 0x88, 1, 1},
++	{0x3E, 0, 0, 0, 0},
++	{0x3F, 0x44, 0x44, 0, 0},
++	{0x40, 0x7, 0x7, 1, 1},
++	{0x41, 0x6, 0x6, 0, 0},
++	{0x42, 0x4, 0x4, 0, 0},
++	{0x43, 0, 0, 0, 0},
++	{0x44, 0x8, 0x8, 0, 0},
++	{0x45, 0x55, 0x55, 1, 1},
++	{0x46, 0, 0, 0, 0},
++	{0x47, 0x11, 0x11, 0, 0},
++	{0x48, 0, 0, 0, 0},
++	{0x49, 0x44, 0x44, 0, 0},
++	{0x4A, 0x7, 0x7, 0, 0},
++	{0x4B, 0x6, 0x6, 0, 0},
++	{0x4C, 0x4, 0x4, 0, 0},
++	{0x4D, 0, 0, 0, 0},
++	{0x4E, 0, 0, 0, 0},
++	{0x4F, 0x26, 0x26, 1, 1},
++	{0x50, 0x26, 0x26, 1, 1},
++	{0x51, 0xf, 0xf, 1, 1},
++	{0x52, 0xf, 0xf, 1, 1},
++	{0x53, 0x44, 0x44, 0, 0},
++	{0x54, 0, 0, 0, 0},
++	{0x55, 0, 0, 0, 0},
++	{0x56, 0x8, 0x8, 0, 0},
++	{0x57, 0x8, 0x8, 0, 0},
++	{0x58, 0x7, 0x7, 0, 0},
++	{0x59, 0x22, 0x22, 0, 0},
++	{0x5A, 0x22, 0x22, 0, 0},
++	{0x5B, 0x2, 0x2, 0, 0},
++	{0x5C, 0x4, 0x4, 1, 1},
++	{0x5D, 0x7, 0x7, 0, 0},
++	{0x5E, 0x55, 0x55, 0, 0},
++	{0x5F, 0x23, 0x23, 0, 0},
++	{0x60, 0x41, 0x41, 0, 0},
++	{0x61, 0x1, 0x1, 0, 0},
++	{0x62, 0xa, 0xa, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0, 0, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0, 0, 0, 0},
++	{0x68, 0, 0, 0, 0},
++	{0x69, 0, 0, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0xc, 0xc, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0, 0, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0, 0, 0, 0},
++	{0x71, 0, 0, 0, 0},
++	{0x72, 0x22, 0x22, 0, 0},
++	{0x73, 0x22, 0x22, 0, 0},
++	{0x74, 0, 0, 1, 1},
++	{0x75, 0xa, 0xa, 0, 0},
++	{0x76, 0x1, 0x1, 0, 0},
++	{0x77, 0x22, 0x22, 0, 0},
++	{0x78, 0x30, 0x30, 0, 0},
++	{0x79, 0, 0, 0, 0},
++	{0x7A, 0, 0, 0, 0},
++	{0x7B, 0, 0, 0, 0},
++	{0x7C, 0, 0, 0, 0},
++	{0x7D, 0x5, 0x5, 1, 1},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0, 0, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0x93, 0, 0, 0, 0},
++	{0x94, 0, 0, 0, 0},
++	{0xFFFF, 0, 0, 0, 0},
++};
++
++static struct radio_20xx_regs regs_2057_rev4[] = {
++	{0x00, 0x84, 0},
++	{0x01, 0, 0},
++	{0x02, 0x60, 0},
++	{0x03, 0x1f, 0},
++	{0x04, 0x4, 0},
++	{0x05, 0x2, 0},
++	{0x06, 0x1, 0},
++	{0x07, 0x1, 0},
++	{0x08, 0x1, 0},
++	{0x09, 0x69, 0},
++	{0x0A, 0x66, 0},
++	{0x0B, 0x6, 0},
++	{0x0C, 0x18, 0},
++	{0x0D, 0x3, 0},
++	{0x0E, 0x20, 1},
++	{0x0F, 0x20, 0},
++	{0x10, 0, 0},
++	{0x11, 0x7c, 0},
++	{0x12, 0x42, 0},
++	{0x13, 0xbd, 0},
++	{0x14, 0x7, 0},
++	{0x15, 0xf7, 0},
++	{0x16, 0x8, 0},
++	{0x17, 0x17, 0},
++	{0x18, 0x7, 0},
++	{0x19, 0, 0},
++	{0x1A, 0x2, 0},
++	{0x1B, 0x13, 0},
++	{0x1C, 0x3e, 0},
++	{0x1D, 0x3e, 0},
++	{0x1E, 0x96, 0},
++	{0x1F, 0x4, 0},
++	{0x20, 0, 0},
++	{0x21, 0, 0},
++	{0x22, 0x17, 0},
++	{0x23, 0x4, 0},
++	{0x24, 0x1, 0},
++	{0x25, 0x6, 0},
++	{0x26, 0x4, 0},
++	{0x27, 0xd, 0},
++	{0x28, 0xd, 0},
++	{0x29, 0x30, 0},
++	{0x2A, 0x32, 0},
++	{0x2B, 0x8, 0},
++	{0x2C, 0x1c, 0},
++	{0x2D, 0x2, 0},
++	{0x2E, 0x4, 0},
++	{0x2F, 0x7f, 0},
++	{0x30, 0x27, 0},
++	{0x31, 0, 1},
++	{0x32, 0, 1},
++	{0x33, 0, 1},
++	{0x34, 0, 0},
++	{0x35, 0x26, 1},
++	{0x36, 0x18, 0},
++	{0x37, 0x7, 0},
++	{0x38, 0x66, 0},
++	{0x39, 0x66, 0},
++	{0x3A, 0x66, 0},
++	{0x3B, 0x66, 0},
++	{0x3C, 0xff, 1},
++	{0x3D, 0xff, 1},
++	{0x3E, 0xff, 1},
++	{0x3F, 0xff, 1},
++	{0x40, 0x16, 0},
++	{0x41, 0x7, 0},
++	{0x42, 0x19, 0},
++	{0x43, 0x7, 0},
++	{0x44, 0x6, 0},
++	{0x45, 0x3, 0},
++	{0x46, 0x1, 0},
++	{0x47, 0x7, 0},
++	{0x48, 0x33, 0},
++	{0x49, 0x5, 0},
++	{0x4A, 0x77, 0},
++	{0x4B, 0x66, 0},
++	{0x4C, 0x66, 0},
++	{0x4D, 0, 0},
++	{0x4E, 0x4, 0},
++	{0x4F, 0xc, 0},
++	{0x50, 0, 0},
++	{0x51, 0x75, 0},
++	{0x56, 0x7, 0},
++	{0x57, 0, 0},
++	{0x58, 0, 0},
++	{0x59, 0xa8, 0},
++	{0x5A, 0, 0},
++	{0x5B, 0x1f, 0},
++	{0x5C, 0x30, 0},
++	{0x5D, 0x1, 0},
++	{0x5E, 0x30, 0},
++	{0x5F, 0x70, 0},
++	{0x60, 0, 0},
++	{0x61, 0, 0},
++	{0x62, 0x33, 1},
++	{0x63, 0x19, 0},
++	{0x64, 0x62, 0},
++	{0x65, 0, 0},
++	{0x66, 0x11, 0},
++	{0x69, 0, 0},
++	{0x6A, 0x7e, 0},
++	{0x6B, 0x3f, 0},
++	{0x6C, 0x7f, 0},
++	{0x6D, 0x78, 0},
++	{0x6E, 0xc8, 0},
++	{0x6F, 0x88, 0},
++	{0x70, 0x8, 0},
++	{0x71, 0xf, 0},
++	{0x72, 0xbc, 0},
++	{0x73, 0x8, 0},
++	{0x74, 0x60, 0},
++	{0x75, 0x1e, 0},
++	{0x76, 0x70, 0},
++	{0x77, 0, 0},
++	{0x78, 0, 0},
++	{0x79, 0, 0},
++	{0x7A, 0x33, 0},
++	{0x7B, 0x1e, 0},
++	{0x7C, 0x62, 0},
++	{0x7D, 0x11, 0},
++	{0x80, 0x3c, 0},
++	{0x81, 0x9c, 0},
++	{0x82, 0xa, 0},
++	{0x83, 0x9d, 0},
++	{0x84, 0xa, 0},
++	{0x85, 0, 0},
++	{0x86, 0x40, 0},
++	{0x87, 0x40, 0},
++	{0x88, 0x88, 0},
++	{0x89, 0x10, 0},
++	{0x8A, 0xf0, 1},
++	{0x8B, 0x10, 1},
++	{0x8C, 0xf0, 1},
++	{0x8D, 0, 0},
++	{0x8E, 0, 0},
++	{0x8F, 0x10, 0},
++	{0x90, 0x55, 0},
++	{0x91, 0x3f, 1},
++	{0x92, 0x36, 1},
++	{0x93, 0, 0},
++	{0x94, 0, 0},
++	{0x95, 0, 0},
++	{0x96, 0x87, 0},
++	{0x97, 0x11, 0},
++	{0x98, 0, 0},
++	{0x99, 0x33, 0},
++	{0x9A, 0x88, 0},
++	{0x9B, 0, 0},
++	{0x9C, 0x87, 0},
++	{0x9D, 0x11, 0},
++	{0x9E, 0, 0},
++	{0x9F, 0x33, 0},
++	{0xA0, 0x88, 0},
++	{0xA1, 0xe1, 0},
++	{0xA2, 0x3f, 0},
++	{0xA3, 0x44, 0},
++	{0xA4, 0x8c, 1},
++	{0xA5, 0x6d, 0},
++	{0xA6, 0x22, 0},
++	{0xA7, 0xbe, 0},
++	{0xA8, 0x55, 1},
++	{0xA9, 0xc, 0},
++	{0xAA, 0xc, 0},
++	{0xAB, 0xaa, 0},
++	{0xAC, 0x2, 0},
++	{0xAD, 0, 0},
++	{0xAE, 0x10, 0},
++	{0xAF, 0x1, 1},
++	{0xB0, 0, 0},
++	{0xB1, 0, 0},
++	{0xB2, 0x80, 0},
++	{0xB3, 0x60, 0},
++	{0xB4, 0x44, 0},
++	{0xB5, 0x55, 0},
++	{0xB6, 0x1, 0},
++	{0xB7, 0x55, 0},
++	{0xB8, 0x1, 0},
++	{0xB9, 0x5, 0},
++	{0xBA, 0x55, 0},
++	{0xBB, 0x55, 0},
++	{0xC1, 0, 0},
++	{0xC2, 0, 0},
++	{0xC3, 0, 0},
++	{0xC4, 0, 0},
++	{0xC5, 0, 0},
++	{0xC6, 0, 0},
++	{0xC7, 0, 0},
++	{0xC8, 0, 0},
++	{0xC9, 0, 0},
++	{0xCA, 0, 0},
++	{0xCB, 0, 0},
++	{0xCC, 0, 0},
++	{0xCD, 0, 0},
++	{0xCE, 0x5e, 0},
++	{0xCF, 0xc, 0},
++	{0xD0, 0xc, 0},
++	{0xD1, 0xc, 0},
++	{0xD2, 0, 0},
++	{0xD3, 0x2b, 0},
++	{0xD4, 0xc, 0},
++	{0xD5, 0, 0},
++	{0xD6, 0x75, 0},
++	{0xDB, 0x7, 0},
++	{0xDC, 0, 0},
++	{0xDD, 0, 0},
++	{0xDE, 0xa8, 0},
++	{0xDF, 0, 0},
++	{0xE0, 0x1f, 0},
++	{0xE1, 0x30, 0},
++	{0xE2, 0x1, 0},
++	{0xE3, 0x30, 0},
++	{0xE4, 0x70, 0},
++	{0xE5, 0, 0},
++	{0xE6, 0, 0},
++	{0xE7, 0x33, 0},
++	{0xE8, 0x19, 0},
++	{0xE9, 0x62, 0},
++	{0xEA, 0, 0},
++	{0xEB, 0x11, 0},
++	{0xEE, 0, 0},
++	{0xEF, 0x7e, 0},
++	{0xF0, 0x3f, 0},
++	{0xF1, 0x7f, 0},
++	{0xF2, 0x78, 0},
++	{0xF3, 0xc8, 0},
++	{0xF4, 0x88, 0},
++	{0xF5, 0x8, 0},
++	{0xF6, 0xf, 0},
++	{0xF7, 0xbc, 0},
++	{0xF8, 0x8, 0},
++	{0xF9, 0x60, 0},
++	{0xFA, 0x1e, 0},
++	{0xFB, 0x70, 0},
++	{0xFC, 0, 0},
++	{0xFD, 0, 0},
++	{0xFE, 0, 0},
++	{0xFF, 0x33, 0},
++	{0x100, 0x1e, 0},
++	{0x101, 0x62, 0},
++	{0x102, 0x11, 0},
++	{0x105, 0x3c, 0},
++	{0x106, 0x9c, 0},
++	{0x107, 0xa, 0},
++	{0x108, 0x9d, 0},
++	{0x109, 0xa, 0},
++	{0x10A, 0, 0},
++	{0x10B, 0x40, 0},
++	{0x10C, 0x40, 0},
++	{0x10D, 0x88, 0},
++	{0x10E, 0x10, 0},
++	{0x10F, 0xf0, 1},
++	{0x110, 0x10, 1},
++	{0x111, 0xf0, 1},
++	{0x112, 0, 0},
++	{0x113, 0, 0},
++	{0x114, 0x10, 0},
++	{0x115, 0x55, 0},
++	{0x116, 0x3f, 1},
++	{0x117, 0x36, 1},
++	{0x118, 0, 0},
++	{0x119, 0, 0},
++	{0x11A, 0, 0},
++	{0x11B, 0x87, 0},
++	{0x11C, 0x11, 0},
++	{0x11D, 0, 0},
++	{0x11E, 0x33, 0},
++	{0x11F, 0x88, 0},
++	{0x120, 0, 0},
++	{0x121, 0x87, 0},
++	{0x122, 0x11, 0},
++	{0x123, 0, 0},
++	{0x124, 0x33, 0},
++	{0x125, 0x88, 0},
++	{0x126, 0xe1, 0},
++	{0x127, 0x3f, 0},
++	{0x128, 0x44, 0},
++	{0x129, 0x8c, 1},
++	{0x12A, 0x6d, 0},
++	{0x12B, 0x22, 0},
++	{0x12C, 0xbe, 0},
++	{0x12D, 0x55, 1},
++	{0x12E, 0xc, 0},
++	{0x12F, 0xc, 0},
++	{0x130, 0xaa, 0},
++	{0x131, 0x2, 0},
++	{0x132, 0, 0},
++	{0x133, 0x10, 0},
++	{0x134, 0x1, 1},
++	{0x135, 0, 0},
++	{0x136, 0, 0},
++	{0x137, 0x80, 0},
++	{0x138, 0x60, 0},
++	{0x139, 0x44, 0},
++	{0x13A, 0x55, 0},
++	{0x13B, 0x1, 0},
++	{0x13C, 0x55, 0},
++	{0x13D, 0x1, 0},
++	{0x13E, 0x5, 0},
++	{0x13F, 0x55, 0},
++	{0x140, 0x55, 0},
++	{0x146, 0, 0},
++	{0x147, 0, 0},
++	{0x148, 0, 0},
++	{0x149, 0, 0},
++	{0x14A, 0, 0},
++	{0x14B, 0, 0},
++	{0x14C, 0, 0},
++	{0x14D, 0, 0},
++	{0x14E, 0, 0},
++	{0x14F, 0, 0},
++	{0x150, 0, 0},
++	{0x151, 0, 0},
++	{0x152, 0, 0},
++	{0x153, 0, 0},
++	{0x154, 0xc, 0},
++	{0x155, 0xc, 0},
++	{0x156, 0xc, 0},
++	{0x157, 0, 0},
++	{0x158, 0x2b, 0},
++	{0x159, 0x84, 0},
++	{0x15A, 0x15, 0},
++	{0x15B, 0xf, 0},
++	{0x15C, 0, 0},
++	{0x15D, 0, 0},
++	{0x15E, 0, 1},
++	{0x15F, 0, 1},
++	{0x160, 0, 1},
++	{0x161, 0, 1},
++	{0x162, 0, 1},
++	{0x163, 0, 1},
++	{0x164, 0, 0},
++	{0x165, 0, 0},
++	{0x166, 0, 0},
++	{0x167, 0, 0},
++	{0x168, 0, 0},
++	{0x169, 0x2, 1},
++	{0x16A, 0, 1},
++	{0x16B, 0, 1},
++	{0x16C, 0, 1},
++	{0x16D, 0, 0},
++	{0x170, 0, 0},
++	{0x171, 0x77, 0},
++	{0x172, 0x77, 0},
++	{0x173, 0x77, 0},
++	{0x174, 0x77, 0},
++	{0x175, 0, 0},
++	{0x176, 0x3, 0},
++	{0x177, 0x37, 0},
++	{0x178, 0x3, 0},
++	{0x179, 0, 0},
++	{0x17A, 0x21, 0},
++	{0x17B, 0x21, 0},
++	{0x17C, 0, 0},
++	{0x17D, 0xaa, 0},
++	{0x17E, 0, 0},
++	{0x17F, 0xaa, 0},
++	{0x180, 0, 0},
++	{0x190, 0, 0},
++	{0x191, 0x77, 0},
++	{0x192, 0x77, 0},
++	{0x193, 0x77, 0},
++	{0x194, 0x77, 0},
++	{0x195, 0, 0},
++	{0x196, 0x3, 0},
++	{0x197, 0x37, 0},
++	{0x198, 0x3, 0},
++	{0x199, 0, 0},
++	{0x19A, 0x21, 0},
++	{0x19B, 0x21, 0},
++	{0x19C, 0, 0},
++	{0x19D, 0xaa, 0},
++	{0x19E, 0, 0},
++	{0x19F, 0xaa, 0},
++	{0x1A0, 0, 0},
++	{0x1A1, 0x2, 0},
++	{0x1A2, 0xf, 0},
++	{0x1A3, 0xf, 0},
++	{0x1A4, 0, 1},
++	{0x1A5, 0, 1},
++	{0x1A6, 0, 1},
++	{0x1A7, 0x2, 0},
++	{0x1A8, 0xf, 0},
++	{0x1A9, 0xf, 0},
++	{0x1AA, 0, 1},
++	{0x1AB, 0, 1},
++	{0x1AC, 0, 1},
++	{0xFFFF, 0, 0},
++};
++
++static struct radio_20xx_regs regs_2057_rev5[] = {
++	{0x00, 0, 1},
++	{0x01, 0x57, 1},
++	{0x02, 0x20, 1},
++	{0x03, 0x1f, 0},
++	{0x04, 0x4, 0},
++	{0x05, 0x2, 0},
++	{0x06, 0x1, 0},
++	{0x07, 0x1, 0},
++	{0x08, 0x1, 0},
++	{0x09, 0x69, 0},
++	{0x0A, 0x66, 0},
++	{0x0B, 0x6, 0},
++	{0x0C, 0x18, 0},
++	{0x0D, 0x3, 0},
++	{0x0E, 0x20, 0},
++	{0x0F, 0x20, 0},
++	{0x10, 0, 0},
++	{0x11, 0x7c, 0},
++	{0x12, 0x42, 0},
++	{0x13, 0xbd, 0},
++	{0x14, 0x7, 0},
++	{0x15, 0x87, 0},
++	{0x16, 0x8, 0},
++	{0x17, 0x17, 0},
++	{0x18, 0x7, 0},
++	{0x19, 0, 0},
++	{0x1A, 0x2, 0},
++	{0x1B, 0x13, 0},
++	{0x1C, 0x3e, 0},
++	{0x1D, 0x3e, 0},
++	{0x1E, 0x96, 0},
++	{0x1F, 0x4, 0},
++	{0x20, 0, 0},
++	{0x21, 0, 0},
++	{0x22, 0x17, 0},
++	{0x23, 0x6, 1},
++	{0x24, 0x1, 0},
++	{0x25, 0x6, 0},
++	{0x26, 0x4, 0},
++	{0x27, 0xd, 0},
++	{0x28, 0xd, 0},
++	{0x29, 0x30, 0},
++	{0x2A, 0x32, 0},
++	{0x2B, 0x8, 0},
++	{0x2C, 0x1c, 0},
++	{0x2D, 0x2, 0},
++	{0x2E, 0x4, 0},
++	{0x2F, 0x7f, 0},
++	{0x30, 0x27, 0},
++	{0x31, 0, 1},
++	{0x32, 0, 1},
++	{0x33, 0, 1},
++	{0x34, 0, 0},
++	{0x35, 0x20, 0},
++	{0x36, 0x18, 0},
++	{0x37, 0x7, 0},
++	{0x38, 0x66, 0},
++	{0x39, 0x66, 0},
++	{0x3C, 0xff, 0},
++	{0x3D, 0xff, 0},
++	{0x40, 0x16, 0},
++	{0x41, 0x7, 0},
++	{0x45, 0x3, 0},
++	{0x46, 0x1, 0},
++	{0x47, 0x7, 0},
++	{0x4B, 0x66, 0},
++	{0x4C, 0x66, 0},
++	{0x4D, 0, 0},
++	{0x4E, 0x4, 0},
++	{0x4F, 0xc, 0},
++	{0x50, 0, 0},
++	{0x51, 0x70, 1},
++	{0x56, 0x7, 0},
++	{0x57, 0, 0},
++	{0x58, 0, 0},
++	{0x59, 0x88, 1},
++	{0x5A, 0, 0},
++	{0x5B, 0x1f, 0},
++	{0x5C, 0x20, 1},
++	{0x5D, 0x1, 0},
++	{0x5E, 0x30, 0},
++	{0x5F, 0x70, 0},
++	{0x60, 0, 0},
++	{0x61, 0, 0},
++	{0x62, 0x33, 1},
++	{0x63, 0xf, 1},
++	{0x64, 0xf, 1},
++	{0x65, 0, 0},
++	{0x66, 0x11, 0},
++	{0x80, 0x3c, 0},
++	{0x81, 0x1, 1},
++	{0x82, 0xa, 0},
++	{0x85, 0, 0},
++	{0x86, 0x40, 0},
++	{0x87, 0x40, 0},
++	{0x88, 0x88, 0},
++	{0x89, 0x10, 0},
++	{0x8A, 0xf0, 0},
++	{0x8B, 0x10, 0},
++	{0x8C, 0xf0, 0},
++	{0x8F, 0x10, 0},
++	{0x90, 0x55, 0},
++	{0x91, 0x3f, 1},
++	{0x92, 0x36, 1},
++	{0x93, 0, 0},
++	{0x94, 0, 0},
++	{0x95, 0, 0},
++	{0x96, 0x87, 0},
++	{0x97, 0x11, 0},
++	{0x98, 0, 0},
++	{0x99, 0x33, 0},
++	{0x9A, 0x88, 0},
++	{0xA1, 0x20, 1},
++	{0xA2, 0x3f, 0},
++	{0xA3, 0x44, 0},
++	{0xA4, 0x8c, 0},
++	{0xA5, 0x6c, 0},
++	{0xA6, 0x22, 0},
++	{0xA7, 0xbe, 0},
++	{0xA8, 0x55, 0},
++	{0xAA, 0xc, 0},
++	{0xAB, 0xaa, 0},
++	{0xAC, 0x2, 0},
++	{0xAD, 0, 0},
++	{0xAE, 0x10, 0},
++	{0xAF, 0x1, 0},
++	{0xB0, 0, 0},
++	{0xB1, 0, 0},
++	{0xB2, 0x80, 0},
++	{0xB3, 0x60, 0},
++	{0xB4, 0x44, 0},
++	{0xB5, 0x55, 0},
++	{0xB6, 0x1, 0},
++	{0xB7, 0x55, 0},
++	{0xB8, 0x1, 0},
++	{0xB9, 0x5, 0},
++	{0xBA, 0x55, 0},
++	{0xBB, 0x55, 0},
++	{0xC3, 0, 0},
++	{0xC4, 0, 0},
++	{0xC5, 0, 0},
++	{0xC6, 0, 0},
++	{0xC7, 0, 0},
++	{0xC8, 0, 0},
++	{0xC9, 0, 0},
++	{0xCA, 0, 0},
++	{0xCB, 0, 0},
++	{0xCD, 0, 0},
++	{0xCE, 0x5e, 0},
++	{0xCF, 0xc, 0},
++	{0xD0, 0xc, 0},
++	{0xD1, 0xc, 0},
++	{0xD2, 0, 0},
++	{0xD3, 0x2b, 0},
++	{0xD4, 0xc, 0},
++	{0xD5, 0, 0},
++	{0xD6, 0x70, 1},
++	{0xDB, 0x7, 0},
++	{0xDC, 0, 0},
++	{0xDD, 0, 0},
++	{0xDE, 0x88, 1},
++	{0xDF, 0, 0},
++	{0xE0, 0x1f, 0},
++	{0xE1, 0x20, 1},
++	{0xE2, 0x1, 0},
++	{0xE3, 0x30, 0},
++	{0xE4, 0x70, 0},
++	{0xE5, 0, 0},
++	{0xE6, 0, 0},
++	{0xE7, 0x33, 0},
++	{0xE8, 0xf, 1},
++	{0xE9, 0xf, 1},
++	{0xEA, 0, 0},
++	{0xEB, 0x11, 0},
++	{0x105, 0x3c, 0},
++	{0x106, 0x1, 1},
++	{0x107, 0xa, 0},
++	{0x10A, 0, 0},
++	{0x10B, 0x40, 0},
++	{0x10C, 0x40, 0},
++	{0x10D, 0x88, 0},
++	{0x10E, 0x10, 0},
++	{0x10F, 0xf0, 0},
++	{0x110, 0x10, 0},
++	{0x111, 0xf0, 0},
++	{0x114, 0x10, 0},
++	{0x115, 0x55, 0},
++	{0x116, 0x3f, 1},
++	{0x117, 0x36, 1},
++	{0x118, 0, 0},
++	{0x119, 0, 0},
++	{0x11A, 0, 0},
++	{0x11B, 0x87, 0},
++	{0x11C, 0x11, 0},
++	{0x11D, 0, 0},
++	{0x11E, 0x33, 0},
++	{0x11F, 0x88, 0},
++	{0x126, 0x20, 1},
++	{0x127, 0x3f, 0},
++	{0x128, 0x44, 0},
++	{0x129, 0x8c, 0},
++	{0x12A, 0x6c, 0},
++	{0x12B, 0x22, 0},
++	{0x12C, 0xbe, 0},
++	{0x12D, 0x55, 0},
++	{0x12F, 0xc, 0},
++	{0x130, 0xaa, 0},
++	{0x131, 0x2, 0},
++	{0x132, 0, 0},
++	{0x133, 0x10, 0},
++	{0x134, 0x1, 0},
++	{0x135, 0, 0},
++	{0x136, 0, 0},
++	{0x137, 0x80, 0},
++	{0x138, 0x60, 0},
++	{0x139, 0x44, 0},
++	{0x13A, 0x55, 0},
++	{0x13B, 0x1, 0},
++	{0x13C, 0x55, 0},
++	{0x13D, 0x1, 0},
++	{0x13E, 0x5, 0},
++	{0x13F, 0x55, 0},
++	{0x140, 0x55, 0},
++	{0x148, 0, 0},
++	{0x149, 0, 0},
++	{0x14A, 0, 0},
++	{0x14B, 0, 0},
++	{0x14C, 0, 0},
++	{0x14D, 0, 0},
++	{0x14E, 0, 0},
++	{0x14F, 0, 0},
++	{0x150, 0, 0},
++	{0x154, 0xc, 0},
++	{0x155, 0xc, 0},
++	{0x156, 0xc, 0},
++	{0x157, 0, 0},
++	{0x158, 0x2b, 0},
++	{0x159, 0x84, 0},
++	{0x15A, 0x15, 0},
++	{0x15B, 0xf, 0},
++	{0x15C, 0, 0},
++	{0x15D, 0, 0},
++	{0x15E, 0, 1},
++	{0x15F, 0, 1},
++	{0x160, 0, 1},
++	{0x161, 0, 1},
++	{0x162, 0, 1},
++	{0x163, 0, 1},
++	{0x164, 0, 0},
++	{0x165, 0, 0},
++	{0x166, 0, 0},
++	{0x167, 0, 0},
++	{0x168, 0, 0},
++	{0x169, 0, 0},
++	{0x16A, 0, 1},
++	{0x16B, 0, 1},
++	{0x16C, 0, 1},
++	{0x16D, 0, 0},
++	{0x170, 0, 0},
++	{0x171, 0x77, 0},
++	{0x172, 0x77, 0},
++	{0x173, 0x77, 0},
++	{0x174, 0x77, 0},
++	{0x175, 0, 0},
++	{0x176, 0x3, 0},
++	{0x177, 0x37, 0},
++	{0x178, 0x3, 0},
++	{0x179, 0, 0},
++	{0x17B, 0x21, 0},
++	{0x17C, 0, 0},
++	{0x17D, 0xaa, 0},
++	{0x17E, 0, 0},
++	{0x190, 0, 0},
++	{0x191, 0x77, 0},
++	{0x192, 0x77, 0},
++	{0x193, 0x77, 0},
++	{0x194, 0x77, 0},
++	{0x195, 0, 0},
++	{0x196, 0x3, 0},
++	{0x197, 0x37, 0},
++	{0x198, 0x3, 0},
++	{0x199, 0, 0},
++	{0x19B, 0x21, 0},
++	{0x19C, 0, 0},
++	{0x19D, 0xaa, 0},
++	{0x19E, 0, 0},
++	{0x1A1, 0x2, 0},
++	{0x1A2, 0xf, 0},
++	{0x1A3, 0xf, 0},
++	{0x1A4, 0, 1},
++	{0x1A5, 0, 1},
++	{0x1A6, 0, 1},
++	{0x1A7, 0x2, 0},
++	{0x1A8, 0xf, 0},
++	{0x1A9, 0xf, 0},
++	{0x1AA, 0, 1},
++	{0x1AB, 0, 1},
++	{0x1AC, 0, 1},
++	{0x1AD, 0x84, 0},
++	{0x1AE, 0x60, 0},
++	{0x1AF, 0x47, 0},
++	{0x1B0, 0x47, 0},
++	{0x1B1, 0, 0},
++	{0x1B2, 0, 0},
++	{0x1B3, 0, 0},
++	{0x1B4, 0, 0},
++	{0x1B5, 0, 0},
++	{0x1B6, 0, 0},
++	{0x1B7, 0xc, 1},
++	{0x1B8, 0, 0},
++	{0x1B9, 0, 0},
++	{0x1BA, 0, 0},
++	{0x1BB, 0, 0},
++	{0x1BC, 0, 0},
++	{0x1BD, 0, 0},
++	{0x1BE, 0, 0},
++	{0x1BF, 0, 0},
++	{0x1C0, 0, 0},
++	{0x1C1, 0x1, 1},
++	{0x1C2, 0x80, 1},
++	{0x1C3, 0, 0},
++	{0x1C4, 0, 0},
++	{0x1C5, 0, 0},
++	{0x1C6, 0, 0},
++	{0x1C7, 0, 0},
++	{0x1C8, 0, 0},
++	{0x1C9, 0, 0},
++	{0x1CA, 0, 0},
++	{0xFFFF, 0, 0}
++};
++
++static struct radio_20xx_regs regs_2057_rev5v1[] = {
++	{0x00, 0x15, 1},
++	{0x01, 0x57, 1},
++	{0x02, 0x20, 1},
++	{0x03, 0x1f, 0},
++	{0x04, 0x4, 0},
++	{0x05, 0x2, 0},
++	{0x06, 0x1, 0},
++	{0x07, 0x1, 0},
++	{0x08, 0x1, 0},
++	{0x09, 0x69, 0},
++	{0x0A, 0x66, 0},
++	{0x0B, 0x6, 0},
++	{0x0C, 0x18, 0},
++	{0x0D, 0x3, 0},
++	{0x0E, 0x20, 0},
++	{0x0F, 0x20, 0},
++	{0x10, 0, 0},
++	{0x11, 0x7c, 0},
++	{0x12, 0x42, 0},
++	{0x13, 0xbd, 0},
++	{0x14, 0x7, 0},
++	{0x15, 0x87, 0},
++	{0x16, 0x8, 0},
++	{0x17, 0x17, 0},
++	{0x18, 0x7, 0},
++	{0x19, 0, 0},
++	{0x1A, 0x2, 0},
++	{0x1B, 0x13, 0},
++	{0x1C, 0x3e, 0},
++	{0x1D, 0x3e, 0},
++	{0x1E, 0x96, 0},
++	{0x1F, 0x4, 0},
++	{0x20, 0, 0},
++	{0x21, 0, 0},
++	{0x22, 0x17, 0},
++	{0x23, 0x6, 1},
++	{0x24, 0x1, 0},
++	{0x25, 0x6, 0},
++	{0x26, 0x4, 0},
++	{0x27, 0xd, 0},
++	{0x28, 0xd, 0},
++	{0x29, 0x30, 0},
++	{0x2A, 0x32, 0},
++	{0x2B, 0x8, 0},
++	{0x2C, 0x1c, 0},
++	{0x2D, 0x2, 0},
++	{0x2E, 0x4, 0},
++	{0x2F, 0x7f, 0},
++	{0x30, 0x27, 0},
++	{0x31, 0, 1},
++	{0x32, 0, 1},
++	{0x33, 0, 1},
++	{0x34, 0, 0},
++	{0x35, 0x20, 0},
++	{0x36, 0x18, 0},
++	{0x37, 0x7, 0},
++	{0x38, 0x66, 0},
++	{0x39, 0x66, 0},
++	{0x3C, 0xff, 0},
++	{0x3D, 0xff, 0},
++	{0x40, 0x16, 0},
++	{0x41, 0x7, 0},
++	{0x45, 0x3, 0},
++	{0x46, 0x1, 0},
++	{0x47, 0x7, 0},
++	{0x4B, 0x66, 0},
++	{0x4C, 0x66, 0},
++	{0x4D, 0, 0},
++	{0x4E, 0x4, 0},
++	{0x4F, 0xc, 0},
++	{0x50, 0, 0},
++	{0x51, 0x70, 1},
++	{0x56, 0x7, 0},
++	{0x57, 0, 0},
++	{0x58, 0, 0},
++	{0x59, 0x88, 1},
++	{0x5A, 0, 0},
++	{0x5B, 0x1f, 0},
++	{0x5C, 0x20, 1},
++	{0x5D, 0x1, 0},
++	{0x5E, 0x30, 0},
++	{0x5F, 0x70, 0},
++	{0x60, 0, 0},
++	{0x61, 0, 0},
++	{0x62, 0x33, 1},
++	{0x63, 0xf, 1},
++	{0x64, 0xf, 1},
++	{0x65, 0, 0},
++	{0x66, 0x11, 0},
++	{0x80, 0x3c, 0},
++	{0x81, 0x1, 1},
++	{0x82, 0xa, 0},
++	{0x85, 0, 0},
++	{0x86, 0x40, 0},
++	{0x87, 0x40, 0},
++	{0x88, 0x88, 0},
++	{0x89, 0x10, 0},
++	{0x8A, 0xf0, 0},
++	{0x8B, 0x10, 0},
++	{0x8C, 0xf0, 0},
++	{0x8F, 0x10, 0},
++	{0x90, 0x55, 0},
++	{0x91, 0x3f, 1},
++	{0x92, 0x36, 1},
++	{0x93, 0, 0},
++	{0x94, 0, 0},
++	{0x95, 0, 0},
++	{0x96, 0x87, 0},
++	{0x97, 0x11, 0},
++	{0x98, 0, 0},
++	{0x99, 0x33, 0},
++	{0x9A, 0x88, 0},
++	{0xA1, 0x20, 1},
++	{0xA2, 0x3f, 0},
++	{0xA3, 0x44, 0},
++	{0xA4, 0x8c, 0},
++	{0xA5, 0x6c, 0},
++	{0xA6, 0x22, 0},
++	{0xA7, 0xbe, 0},
++	{0xA8, 0x55, 0},
++	{0xAA, 0xc, 0},
++	{0xAB, 0xaa, 0},
++	{0xAC, 0x2, 0},
++	{0xAD, 0, 0},
++	{0xAE, 0x10, 0},
++	{0xAF, 0x1, 0},
++	{0xB0, 0, 0},
++	{0xB1, 0, 0},
++	{0xB2, 0x80, 0},
++	{0xB3, 0x60, 0},
++	{0xB4, 0x44, 0},
++	{0xB5, 0x55, 0},
++	{0xB6, 0x1, 0},
++	{0xB7, 0x55, 0},
++	{0xB8, 0x1, 0},
++	{0xB9, 0x5, 0},
++	{0xBA, 0x55, 0},
++	{0xBB, 0x55, 0},
++	{0xC3, 0, 0},
++	{0xC4, 0, 0},
++	{0xC5, 0, 0},
++	{0xC6, 0, 0},
++	{0xC7, 0, 0},
++	{0xC8, 0, 0},
++	{0xC9, 0x1, 1},
++	{0xCA, 0, 0},
++	{0xCB, 0, 0},
++	{0xCD, 0, 0},
++	{0xCE, 0x5e, 0},
++	{0xCF, 0xc, 0},
++	{0xD0, 0xc, 0},
++	{0xD1, 0xc, 0},
++	{0xD2, 0, 0},
++	{0xD3, 0x2b, 0},
++	{0xD4, 0xc, 0},
++	{0xD5, 0, 0},
++	{0xD6, 0x70, 1},
++	{0xDB, 0x7, 0},
++	{0xDC, 0, 0},
++	{0xDD, 0, 0},
++	{0xDE, 0x88, 1},
++	{0xDF, 0, 0},
++	{0xE0, 0x1f, 0},
++	{0xE1, 0x20, 1},
++	{0xE2, 0x1, 0},
++	{0xE3, 0x30, 0},
++	{0xE4, 0x70, 0},
++	{0xE5, 0, 0},
++	{0xE6, 0, 0},
++	{0xE7, 0x33, 0},
++	{0xE8, 0xf, 1},
++	{0xE9, 0xf, 1},
++	{0xEA, 0, 0},
++	{0xEB, 0x11, 0},
++	{0x105, 0x3c, 0},
++	{0x106, 0x1, 1},
++	{0x107, 0xa, 0},
++	{0x10A, 0, 0},
++	{0x10B, 0x40, 0},
++	{0x10C, 0x40, 0},
++	{0x10D, 0x88, 0},
++	{0x10E, 0x10, 0},
++	{0x10F, 0xf0, 0},
++	{0x110, 0x10, 0},
++	{0x111, 0xf0, 0},
++	{0x114, 0x10, 0},
++	{0x115, 0x55, 0},
++	{0x116, 0x3f, 1},
++	{0x117, 0x36, 1},
++	{0x118, 0, 0},
++	{0x119, 0, 0},
++	{0x11A, 0, 0},
++	{0x11B, 0x87, 0},
++	{0x11C, 0x11, 0},
++	{0x11D, 0, 0},
++	{0x11E, 0x33, 0},
++	{0x11F, 0x88, 0},
++	{0x126, 0x20, 1},
++	{0x127, 0x3f, 0},
++	{0x128, 0x44, 0},
++	{0x129, 0x8c, 0},
++	{0x12A, 0x6c, 0},
++	{0x12B, 0x22, 0},
++	{0x12C, 0xbe, 0},
++	{0x12D, 0x55, 0},
++	{0x12F, 0xc, 0},
++	{0x130, 0xaa, 0},
++	{0x131, 0x2, 0},
++	{0x132, 0, 0},
++	{0x133, 0x10, 0},
++	{0x134, 0x1, 0},
++	{0x135, 0, 0},
++	{0x136, 0, 0},
++	{0x137, 0x80, 0},
++	{0x138, 0x60, 0},
++	{0x139, 0x44, 0},
++	{0x13A, 0x55, 0},
++	{0x13B, 0x1, 0},
++	{0x13C, 0x55, 0},
++	{0x13D, 0x1, 0},
++	{0x13E, 0x5, 0},
++	{0x13F, 0x55, 0},
++	{0x140, 0x55, 0},
++	{0x148, 0, 0},
++	{0x149, 0, 0},
++	{0x14A, 0, 0},
++	{0x14B, 0, 0},
++	{0x14C, 0, 0},
++	{0x14D, 0, 0},
++	{0x14E, 0x1, 1},
++	{0x14F, 0, 0},
++	{0x150, 0, 0},
++	{0x154, 0xc, 0},
++	{0x155, 0xc, 0},
++	{0x156, 0xc, 0},
++	{0x157, 0, 0},
++	{0x158, 0x2b, 0},
++	{0x159, 0x84, 0},
++	{0x15A, 0x15, 0},
++	{0x15B, 0xf, 0},
++	{0x15C, 0, 0},
++	{0x15D, 0, 0},
++	{0x15E, 0, 1},
++	{0x15F, 0, 1},
++	{0x160, 0, 1},
++	{0x161, 0, 1},
++	{0x162, 0, 1},
++	{0x163, 0, 1},
++	{0x164, 0, 0},
++	{0x165, 0, 0},
++	{0x166, 0, 0},
++	{0x167, 0, 0},
++	{0x168, 0, 0},
++	{0x169, 0, 0},
++	{0x16A, 0, 1},
++	{0x16B, 0, 1},
++	{0x16C, 0, 1},
++	{0x16D, 0, 0},
++	{0x170, 0, 0},
++	{0x171, 0x77, 0},
++	{0x172, 0x77, 0},
++	{0x173, 0x77, 0},
++	{0x174, 0x77, 0},
++	{0x175, 0, 0},
++	{0x176, 0x3, 0},
++	{0x177, 0x37, 0},
++	{0x178, 0x3, 0},
++	{0x179, 0, 0},
++	{0x17B, 0x21, 0},
++	{0x17C, 0, 0},
++	{0x17D, 0xaa, 0},
++	{0x17E, 0, 0},
++	{0x190, 0, 0},
++	{0x191, 0x77, 0},
++	{0x192, 0x77, 0},
++	{0x193, 0x77, 0},
++	{0x194, 0x77, 0},
++	{0x195, 0, 0},
++	{0x196, 0x3, 0},
++	{0x197, 0x37, 0},
++	{0x198, 0x3, 0},
++	{0x199, 0, 0},
++	{0x19B, 0x21, 0},
++	{0x19C, 0, 0},
++	{0x19D, 0xaa, 0},
++	{0x19E, 0, 0},
++	{0x1A1, 0x2, 0},
++	{0x1A2, 0xf, 0},
++	{0x1A3, 0xf, 0},
++	{0x1A4, 0, 1},
++	{0x1A5, 0, 1},
++	{0x1A6, 0, 1},
++	{0x1A7, 0x2, 0},
++	{0x1A8, 0xf, 0},
++	{0x1A9, 0xf, 0},
++	{0x1AA, 0, 1},
++	{0x1AB, 0, 1},
++	{0x1AC, 0, 1},
++	{0x1AD, 0x84, 0},
++	{0x1AE, 0x60, 0},
++	{0x1AF, 0x47, 0},
++	{0x1B0, 0x47, 0},
++	{0x1B1, 0, 0},
++	{0x1B2, 0, 0},
++	{0x1B3, 0, 0},
++	{0x1B4, 0, 0},
++	{0x1B5, 0, 0},
++	{0x1B6, 0, 0},
++	{0x1B7, 0xc, 1},
++	{0x1B8, 0, 0},
++	{0x1B9, 0, 0},
++	{0x1BA, 0, 0},
++	{0x1BB, 0, 0},
++	{0x1BC, 0, 0},
++	{0x1BD, 0, 0},
++	{0x1BE, 0, 0},
++	{0x1BF, 0, 0},
++	{0x1C0, 0, 0},
++	{0x1C1, 0x1, 1},
++	{0x1C2, 0x80, 1},
++	{0x1C3, 0, 0},
++	{0x1C4, 0, 0},
++	{0x1C5, 0, 0},
++	{0x1C6, 0, 0},
++	{0x1C7, 0, 0},
++	{0x1C8, 0, 0},
++	{0x1C9, 0, 0},
++	{0x1CA, 0, 0},
++	{0xFFFF, 0, 0}
++};
++
++static struct radio_20xx_regs regs_2057_rev7[] = {
++	{0x00, 0, 1},
++	{0x01, 0x57, 1},
++	{0x02, 0x20, 1},
++	{0x03, 0x1f, 0},
++	{0x04, 0x4, 0},
++	{0x05, 0x2, 0},
++	{0x06, 0x1, 0},
++	{0x07, 0x1, 0},
++	{0x08, 0x1, 0},
++	{0x09, 0x69, 0},
++	{0x0A, 0x66, 0},
++	{0x0B, 0x6, 0},
++	{0x0C, 0x18, 0},
++	{0x0D, 0x3, 0},
++	{0x0E, 0x20, 0},
++	{0x0F, 0x20, 0},
++	{0x10, 0, 0},
++	{0x11, 0x7c, 0},
++	{0x12, 0x42, 0},
++	{0x13, 0xbd, 0},
++	{0x14, 0x7, 0},
++	{0x15, 0x87, 0},
++	{0x16, 0x8, 0},
++	{0x17, 0x17, 0},
++	{0x18, 0x7, 0},
++	{0x19, 0, 0},
++	{0x1A, 0x2, 0},
++	{0x1B, 0x13, 0},
++	{0x1C, 0x3e, 0},
++	{0x1D, 0x3e, 0},
++	{0x1E, 0x96, 0},
++	{0x1F, 0x4, 0},
++	{0x20, 0, 0},
++	{0x21, 0, 0},
++	{0x22, 0x17, 0},
++	{0x23, 0x6, 0},
++	{0x24, 0x1, 0},
++	{0x25, 0x6, 0},
++	{0x26, 0x4, 0},
++	{0x27, 0xd, 0},
++	{0x28, 0xd, 0},
++	{0x29, 0x30, 0},
++	{0x2A, 0x32, 0},
++	{0x2B, 0x8, 0},
++	{0x2C, 0x1c, 0},
++	{0x2D, 0x2, 0},
++	{0x2E, 0x4, 0},
++	{0x2F, 0x7f, 0},
++	{0x30, 0x27, 0},
++	{0x31, 0, 1},
++	{0x32, 0, 1},
++	{0x33, 0, 1},
++	{0x34, 0, 0},
++	{0x35, 0x20, 0},
++	{0x36, 0x18, 0},
++	{0x37, 0x7, 0},
++	{0x38, 0x66, 0},
++	{0x39, 0x66, 0},
++	{0x3A, 0x66, 0},
++	{0x3B, 0x66, 0},
++	{0x3C, 0xff, 0},
++	{0x3D, 0xff, 0},
++	{0x3E, 0xff, 0},
++	{0x3F, 0xff, 0},
++	{0x40, 0x16, 0},
++	{0x41, 0x7, 0},
++	{0x42, 0x19, 0},
++	{0x43, 0x7, 0},
++	{0x44, 0x6, 0},
++	{0x45, 0x3, 0},
++	{0x46, 0x1, 0},
++	{0x47, 0x7, 0},
++	{0x48, 0x33, 0},
++	{0x49, 0x5, 0},
++	{0x4A, 0x77, 0},
++	{0x4B, 0x66, 0},
++	{0x4C, 0x66, 0},
++	{0x4D, 0, 0},
++	{0x4E, 0x4, 0},
++	{0x4F, 0xc, 0},
++	{0x50, 0, 0},
++	{0x51, 0x70, 1},
++	{0x56, 0x7, 0},
++	{0x57, 0, 0},
++	{0x58, 0, 0},
++	{0x59, 0x88, 1},
++	{0x5A, 0, 0},
++	{0x5B, 0x1f, 0},
++	{0x5C, 0x20, 1},
++	{0x5D, 0x1, 0},
++	{0x5E, 0x30, 0},
++	{0x5F, 0x70, 0},
++	{0x60, 0, 0},
++	{0x61, 0, 0},
++	{0x62, 0x33, 1},
++	{0x63, 0xf, 1},
++	{0x64, 0x13, 1},
++	{0x65, 0, 0},
++	{0x66, 0xee, 1},
++	{0x69, 0, 0},
++	{0x6A, 0x7e, 0},
++	{0x6B, 0x3f, 0},
++	{0x6C, 0x7f, 0},
++	{0x6D, 0x78, 0},
++	{0x6E, 0x58, 1},
++	{0x6F, 0x88, 0},
++	{0x70, 0x8, 0},
++	{0x71, 0xf, 0},
++	{0x72, 0xbc, 0},
++	{0x73, 0x8, 0},
++	{0x74, 0x60, 0},
++	{0x75, 0x13, 1},
++	{0x76, 0x70, 0},
++	{0x77, 0, 0},
++	{0x78, 0, 0},
++	{0x79, 0, 0},
++	{0x7A, 0x33, 0},
++	{0x7B, 0x13, 1},
++	{0x7C, 0x14, 1},
++	{0x7D, 0xee, 1},
++	{0x80, 0x3c, 0},
++	{0x81, 0x1, 1},
++	{0x82, 0xa, 0},
++	{0x83, 0x9d, 0},
++	{0x84, 0xa, 0},
++	{0x85, 0, 0},
++	{0x86, 0x40, 0},
++	{0x87, 0x40, 0},
++	{0x88, 0x88, 0},
++	{0x89, 0x10, 0},
++	{0x8A, 0xf0, 0},
++	{0x8B, 0x10, 0},
++	{0x8C, 0xf0, 0},
++	{0x8D, 0, 0},
++	{0x8E, 0, 0},
++	{0x8F, 0x10, 0},
++	{0x90, 0x55, 0},
++	{0x91, 0x3f, 1},
++	{0x92, 0x36, 1},
++	{0x93, 0, 0},
++	{0x94, 0, 0},
++	{0x95, 0, 0},
++	{0x96, 0x87, 0},
++	{0x97, 0x11, 0},
++	{0x98, 0, 0},
++	{0x99, 0x33, 0},
++	{0x9A, 0x88, 0},
++	{0x9B, 0, 0},
++	{0x9C, 0x87, 0},
++	{0x9D, 0x11, 0},
++	{0x9E, 0, 0},
++	{0x9F, 0x33, 0},
++	{0xA0, 0x88, 0},
++	{0xA1, 0x20, 1},
++	{0xA2, 0x3f, 0},
++	{0xA3, 0x44, 0},
++	{0xA4, 0x8c, 0},
++	{0xA5, 0x6c, 0},
++	{0xA6, 0x22, 0},
++	{0xA7, 0xbe, 0},
++	{0xA8, 0x55, 0},
++	{0xAA, 0xc, 0},
++	{0xAB, 0xaa, 0},
++	{0xAC, 0x2, 0},
++	{0xAD, 0, 0},
++	{0xAE, 0x10, 0},
++	{0xAF, 0x1, 0},
++	{0xB0, 0, 0},
++	{0xB1, 0, 0},
++	{0xB2, 0x80, 0},
++	{0xB3, 0x60, 0},
++	{0xB4, 0x44, 0},
++	{0xB5, 0x55, 0},
++	{0xB6, 0x1, 0},
++	{0xB7, 0x55, 0},
++	{0xB8, 0x1, 0},
++	{0xB9, 0x5, 0},
++	{0xBA, 0x55, 0},
++	{0xBB, 0x55, 0},
++	{0xC1, 0, 0},
++	{0xC2, 0, 0},
++	{0xC3, 0, 0},
++	{0xC4, 0, 0},
++	{0xC5, 0, 0},
++	{0xC6, 0, 0},
++	{0xC7, 0, 0},
++	{0xC8, 0, 0},
++	{0xC9, 0, 0},
++	{0xCA, 0, 0},
++	{0xCB, 0, 0},
++	{0xCC, 0, 0},
++	{0xCD, 0, 0},
++	{0xCE, 0x5e, 0},
++	{0xCF, 0xc, 0},
++	{0xD0, 0xc, 0},
++	{0xD1, 0xc, 0},
++	{0xD2, 0, 0},
++	{0xD3, 0x2b, 0},
++	{0xD4, 0xc, 0},
++	{0xD5, 0, 0},
++	{0xD6, 0x70, 1},
++	{0xDB, 0x7, 0},
++	{0xDC, 0, 0},
++	{0xDD, 0, 0},
++	{0xDE, 0x88, 1},
++	{0xDF, 0, 0},
++	{0xE0, 0x1f, 0},
++	{0xE1, 0x20, 1},
++	{0xE2, 0x1, 0},
++	{0xE3, 0x30, 0},
++	{0xE4, 0x70, 0},
++	{0xE5, 0, 0},
++	{0xE6, 0, 0},
++	{0xE7, 0x33, 0},
++	{0xE8, 0xf, 1},
++	{0xE9, 0x13, 1},
++	{0xEA, 0, 0},
++	{0xEB, 0xee, 1},
++	{0xEE, 0, 0},
++	{0xEF, 0x7e, 0},
++	{0xF0, 0x3f, 0},
++	{0xF1, 0x7f, 0},
++	{0xF2, 0x78, 0},
++	{0xF3, 0x58, 1},
++	{0xF4, 0x88, 0},
++	{0xF5, 0x8, 0},
++	{0xF6, 0xf, 0},
++	{0xF7, 0xbc, 0},
++	{0xF8, 0x8, 0},
++	{0xF9, 0x60, 0},
++	{0xFA, 0x13, 1},
++	{0xFB, 0x70, 0},
++	{0xFC, 0, 0},
++	{0xFD, 0, 0},
++	{0xFE, 0, 0},
++	{0xFF, 0x33, 0},
++	{0x100, 0x13, 1},
++	{0x101, 0x14, 1},
++	{0x102, 0xee, 1},
++	{0x105, 0x3c, 0},
++	{0x106, 0x1, 1},
++	{0x107, 0xa, 0},
++	{0x108, 0x9d, 0},
++	{0x109, 0xa, 0},
++	{0x10A, 0, 0},
++	{0x10B, 0x40, 0},
++	{0x10C, 0x40, 0},
++	{0x10D, 0x88, 0},
++	{0x10E, 0x10, 0},
++	{0x10F, 0xf0, 0},
++	{0x110, 0x10, 0},
++	{0x111, 0xf0, 0},
++	{0x112, 0, 0},
++	{0x113, 0, 0},
++	{0x114, 0x10, 0},
++	{0x115, 0x55, 0},
++	{0x116, 0x3f, 1},
++	{0x117, 0x36, 1},
++	{0x118, 0, 0},
++	{0x119, 0, 0},
++	{0x11A, 0, 0},
++	{0x11B, 0x87, 0},
++	{0x11C, 0x11, 0},
++	{0x11D, 0, 0},
++	{0x11E, 0x33, 0},
++	{0x11F, 0x88, 0},
++	{0x120, 0, 0},
++	{0x121, 0x87, 0},
++	{0x122, 0x11, 0},
++	{0x123, 0, 0},
++	{0x124, 0x33, 0},
++	{0x125, 0x88, 0},
++	{0x126, 0x20, 1},
++	{0x127, 0x3f, 0},
++	{0x128, 0x44, 0},
++	{0x129, 0x8c, 0},
++	{0x12A, 0x6c, 0},
++	{0x12B, 0x22, 0},
++	{0x12C, 0xbe, 0},
++	{0x12D, 0x55, 0},
++	{0x12F, 0xc, 0},
++	{0x130, 0xaa, 0},
++	{0x131, 0x2, 0},
++	{0x132, 0, 0},
++	{0x133, 0x10, 0},
++	{0x134, 0x1, 0},
++	{0x135, 0, 0},
++	{0x136, 0, 0},
++	{0x137, 0x80, 0},
++	{0x138, 0x60, 0},
++	{0x139, 0x44, 0},
++	{0x13A, 0x55, 0},
++	{0x13B, 0x1, 0},
++	{0x13C, 0x55, 0},
++	{0x13D, 0x1, 0},
++	{0x13E, 0x5, 0},
++	{0x13F, 0x55, 0},
++	{0x140, 0x55, 0},
++	{0x146, 0, 0},
++	{0x147, 0, 0},
++	{0x148, 0, 0},
++	{0x149, 0, 0},
++	{0x14A, 0, 0},
++	{0x14B, 0, 0},
++	{0x14C, 0, 0},
++	{0x14D, 0, 0},
++	{0x14E, 0, 0},
++	{0x14F, 0, 0},
++	{0x150, 0, 0},
++	{0x151, 0, 0},
++	{0x154, 0xc, 0},
++	{0x155, 0xc, 0},
++	{0x156, 0xc, 0},
++	{0x157, 0, 0},
++	{0x158, 0x2b, 0},
++	{0x159, 0x84, 0},
++	{0x15A, 0x15, 0},
++	{0x15B, 0xf, 0},
++	{0x15C, 0, 0},
++	{0x15D, 0, 0},
++	{0x15E, 0, 1},
++	{0x15F, 0, 1},
++	{0x160, 0, 1},
++	{0x161, 0, 1},
++	{0x162, 0, 1},
++	{0x163, 0, 1},
++	{0x164, 0, 0},
++	{0x165, 0, 0},
++	{0x166, 0, 0},
++	{0x167, 0, 0},
++	{0x168, 0, 0},
++	{0x169, 0, 0},
++	{0x16A, 0, 1},
++	{0x16B, 0, 1},
++	{0x16C, 0, 1},
++	{0x16D, 0, 0},
++	{0x170, 0, 0},
++	{0x171, 0x77, 0},
++	{0x172, 0x77, 0},
++	{0x173, 0x77, 0},
++	{0x174, 0x77, 0},
++	{0x175, 0, 0},
++	{0x176, 0x3, 0},
++	{0x177, 0x37, 0},
++	{0x178, 0x3, 0},
++	{0x179, 0, 0},
++	{0x17A, 0x21, 0},
++	{0x17B, 0x21, 0},
++	{0x17C, 0, 0},
++	{0x17D, 0xaa, 0},
++	{0x17E, 0, 0},
++	{0x17F, 0xaa, 0},
++	{0x180, 0, 0},
++	{0x190, 0, 0},
++	{0x191, 0x77, 0},
++	{0x192, 0x77, 0},
++	{0x193, 0x77, 0},
++	{0x194, 0x77, 0},
++	{0x195, 0, 0},
++	{0x196, 0x3, 0},
++	{0x197, 0x37, 0},
++	{0x198, 0x3, 0},
++	{0x199, 0, 0},
++	{0x19A, 0x21, 0},
++	{0x19B, 0x21, 0},
++	{0x19C, 0, 0},
++	{0x19D, 0xaa, 0},
++	{0x19E, 0, 0},
++	{0x19F, 0xaa, 0},
++	{0x1A0, 0, 0},
++	{0x1A1, 0x2, 0},
++	{0x1A2, 0xf, 0},
++	{0x1A3, 0xf, 0},
++	{0x1A4, 0, 1},
++	{0x1A5, 0, 1},
++	{0x1A6, 0, 1},
++	{0x1A7, 0x2, 0},
++	{0x1A8, 0xf, 0},
++	{0x1A9, 0xf, 0},
++	{0x1AA, 0, 1},
++	{0x1AB, 0, 1},
++	{0x1AC, 0, 1},
++	{0x1AD, 0x84, 0},
++	{0x1AE, 0x60, 0},
++	{0x1AF, 0x47, 0},
++	{0x1B0, 0x47, 0},
++	{0x1B1, 0, 0},
++	{0x1B2, 0, 0},
++	{0x1B3, 0, 0},
++	{0x1B4, 0, 0},
++	{0x1B5, 0, 0},
++	{0x1B6, 0, 0},
++	{0x1B7, 0x5, 1},
++	{0x1B8, 0, 0},
++	{0x1B9, 0, 0},
++	{0x1BA, 0, 0},
++	{0x1BB, 0, 0},
++	{0x1BC, 0, 0},
++	{0x1BD, 0, 0},
++	{0x1BE, 0, 0},
++	{0x1BF, 0, 0},
++	{0x1C0, 0, 0},
++	{0x1C1, 0, 0},
++	{0x1C2, 0xa0, 1},
++	{0x1C3, 0, 0},
++	{0x1C4, 0, 0},
++	{0x1C5, 0, 0},
++	{0x1C6, 0, 0},
++	{0x1C7, 0, 0},
++	{0x1C8, 0, 0},
++	{0x1C9, 0, 0},
++	{0x1CA, 0, 0},
++	{0xFFFF, 0, 0}
++};
++
++static struct radio_20xx_regs regs_2057_rev8[] = {
++	{0x00, 0x8, 1},
++	{0x01, 0x57, 1},
++	{0x02, 0x20, 1},
++	{0x03, 0x1f, 0},
++	{0x04, 0x4, 0},
++	{0x05, 0x2, 0},
++	{0x06, 0x1, 0},
++	{0x07, 0x1, 0},
++	{0x08, 0x1, 0},
++	{0x09, 0x69, 0},
++	{0x0A, 0x66, 0},
++	{0x0B, 0x6, 0},
++	{0x0C, 0x18, 0},
++	{0x0D, 0x3, 0},
++	{0x0E, 0x20, 0},
++	{0x0F, 0x20, 0},
++	{0x10, 0, 0},
++	{0x11, 0x7c, 0},
++	{0x12, 0x42, 0},
++	{0x13, 0xbd, 0},
++	{0x14, 0x7, 0},
++	{0x15, 0x87, 0},
++	{0x16, 0x8, 0},
++	{0x17, 0x17, 0},
++	{0x18, 0x7, 0},
++	{0x19, 0, 0},
++	{0x1A, 0x2, 0},
++	{0x1B, 0x13, 0},
++	{0x1C, 0x3e, 0},
++	{0x1D, 0x3e, 0},
++	{0x1E, 0x96, 0},
++	{0x1F, 0x4, 0},
++	{0x20, 0, 0},
++	{0x21, 0, 0},
++	{0x22, 0x17, 0},
++	{0x23, 0x6, 0},
++	{0x24, 0x1, 0},
++	{0x25, 0x6, 0},
++	{0x26, 0x4, 0},
++	{0x27, 0xd, 0},
++	{0x28, 0xd, 0},
++	{0x29, 0x30, 0},
++	{0x2A, 0x32, 0},
++	{0x2B, 0x8, 0},
++	{0x2C, 0x1c, 0},
++	{0x2D, 0x2, 0},
++	{0x2E, 0x4, 0},
++	{0x2F, 0x7f, 0},
++	{0x30, 0x27, 0},
++	{0x31, 0, 1},
++	{0x32, 0, 1},
++	{0x33, 0, 1},
++	{0x34, 0, 0},
++	{0x35, 0x20, 0},
++	{0x36, 0x18, 0},
++	{0x37, 0x7, 0},
++	{0x38, 0x66, 0},
++	{0x39, 0x66, 0},
++	{0x3A, 0x66, 0},
++	{0x3B, 0x66, 0},
++	{0x3C, 0xff, 0},
++	{0x3D, 0xff, 0},
++	{0x3E, 0xff, 0},
++	{0x3F, 0xff, 0},
++	{0x40, 0x16, 0},
++	{0x41, 0x7, 0},
++	{0x42, 0x19, 0},
++	{0x43, 0x7, 0},
++	{0x44, 0x6, 0},
++	{0x45, 0x3, 0},
++	{0x46, 0x1, 0},
++	{0x47, 0x7, 0},
++	{0x48, 0x33, 0},
++	{0x49, 0x5, 0},
++	{0x4A, 0x77, 0},
++	{0x4B, 0x66, 0},
++	{0x4C, 0x66, 0},
++	{0x4D, 0, 0},
++	{0x4E, 0x4, 0},
++	{0x4F, 0xc, 0},
++	{0x50, 0, 0},
++	{0x51, 0x70, 1},
++	{0x56, 0x7, 0},
++	{0x57, 0, 0},
++	{0x58, 0, 0},
++	{0x59, 0x88, 1},
++	{0x5A, 0, 0},
++	{0x5B, 0x1f, 0},
++	{0x5C, 0x20, 1},
++	{0x5D, 0x1, 0},
++	{0x5E, 0x30, 0},
++	{0x5F, 0x70, 0},
++	{0x60, 0, 0},
++	{0x61, 0, 0},
++	{0x62, 0x33, 1},
++	{0x63, 0xf, 1},
++	{0x64, 0xf, 1},
++	{0x65, 0, 0},
++	{0x66, 0x11, 0},
++	{0x69, 0, 0},
++	{0x6A, 0x7e, 0},
++	{0x6B, 0x3f, 0},
++	{0x6C, 0x7f, 0},
++	{0x6D, 0x78, 0},
++	{0x6E, 0x58, 1},
++	{0x6F, 0x88, 0},
++	{0x70, 0x8, 0},
++	{0x71, 0xf, 0},
++	{0x72, 0xbc, 0},
++	{0x73, 0x8, 0},
++	{0x74, 0x60, 0},
++	{0x75, 0x13, 1},
++	{0x76, 0x70, 0},
++	{0x77, 0, 0},
++	{0x78, 0, 0},
++	{0x79, 0, 0},
++	{0x7A, 0x33, 0},
++	{0x7B, 0x13, 1},
++	{0x7C, 0xf, 1},
++	{0x7D, 0xee, 1},
++	{0x80, 0x3c, 0},
++	{0x81, 0x1, 1},
++	{0x82, 0xa, 0},
++	{0x83, 0x9d, 0},
++	{0x84, 0xa, 0},
++	{0x85, 0, 0},
++	{0x86, 0x40, 0},
++	{0x87, 0x40, 0},
++	{0x88, 0x88, 0},
++	{0x89, 0x10, 0},
++	{0x8A, 0xf0, 0},
++	{0x8B, 0x10, 0},
++	{0x8C, 0xf0, 0},
++	{0x8D, 0, 0},
++	{0x8E, 0, 0},
++	{0x8F, 0x10, 0},
++	{0x90, 0x55, 0},
++	{0x91, 0x3f, 1},
++	{0x92, 0x36, 1},
++	{0x93, 0, 0},
++	{0x94, 0, 0},
++	{0x95, 0, 0},
++	{0x96, 0x87, 0},
++	{0x97, 0x11, 0},
++	{0x98, 0, 0},
++	{0x99, 0x33, 0},
++	{0x9A, 0x88, 0},
++	{0x9B, 0, 0},
++	{0x9C, 0x87, 0},
++	{0x9D, 0x11, 0},
++	{0x9E, 0, 0},
++	{0x9F, 0x33, 0},
++	{0xA0, 0x88, 0},
++	{0xA1, 0x20, 1},
++	{0xA2, 0x3f, 0},
++	{0xA3, 0x44, 0},
++	{0xA4, 0x8c, 0},
++	{0xA5, 0x6c, 0},
++	{0xA6, 0x22, 0},
++	{0xA7, 0xbe, 0},
++	{0xA8, 0x55, 0},
++	{0xAA, 0xc, 0},
++	{0xAB, 0xaa, 0},
++	{0xAC, 0x2, 0},
++	{0xAD, 0, 0},
++	{0xAE, 0x10, 0},
++	{0xAF, 0x1, 0},
++	{0xB0, 0, 0},
++	{0xB1, 0, 0},
++	{0xB2, 0x80, 0},
++	{0xB3, 0x60, 0},
++	{0xB4, 0x44, 0},
++	{0xB5, 0x55, 0},
++	{0xB6, 0x1, 0},
++	{0xB7, 0x55, 0},
++	{0xB8, 0x1, 0},
++	{0xB9, 0x5, 0},
++	{0xBA, 0x55, 0},
++	{0xBB, 0x55, 0},
++	{0xC1, 0, 0},
++	{0xC2, 0, 0},
++	{0xC3, 0, 0},
++	{0xC4, 0, 0},
++	{0xC5, 0, 0},
++	{0xC6, 0, 0},
++	{0xC7, 0, 0},
++	{0xC8, 0, 0},
++	{0xC9, 0x1, 1},
++	{0xCA, 0, 0},
++	{0xCB, 0, 0},
++	{0xCC, 0, 0},
++	{0xCD, 0, 0},
++	{0xCE, 0x5e, 0},
++	{0xCF, 0xc, 0},
++	{0xD0, 0xc, 0},
++	{0xD1, 0xc, 0},
++	{0xD2, 0, 0},
++	{0xD3, 0x2b, 0},
++	{0xD4, 0xc, 0},
++	{0xD5, 0, 0},
++	{0xD6, 0x70, 1},
++	{0xDB, 0x7, 0},
++	{0xDC, 0, 0},
++	{0xDD, 0, 0},
++	{0xDE, 0x88, 1},
++	{0xDF, 0, 0},
++	{0xE0, 0x1f, 0},
++	{0xE1, 0x20, 1},
++	{0xE2, 0x1, 0},
++	{0xE3, 0x30, 0},
++	{0xE4, 0x70, 0},
++	{0xE5, 0, 0},
++	{0xE6, 0, 0},
++	{0xE7, 0x33, 0},
++	{0xE8, 0xf, 1},
++	{0xE9, 0xf, 1},
++	{0xEA, 0, 0},
++	{0xEB, 0x11, 0},
++	{0xEE, 0, 0},
++	{0xEF, 0x7e, 0},
++	{0xF0, 0x3f, 0},
++	{0xF1, 0x7f, 0},
++	{0xF2, 0x78, 0},
++	{0xF3, 0x58, 1},
++	{0xF4, 0x88, 0},
++	{0xF5, 0x8, 0},
++	{0xF6, 0xf, 0},
++	{0xF7, 0xbc, 0},
++	{0xF8, 0x8, 0},
++	{0xF9, 0x60, 0},
++	{0xFA, 0x13, 1},
++	{0xFB, 0x70, 0},
++	{0xFC, 0, 0},
++	{0xFD, 0, 0},
++	{0xFE, 0, 0},
++	{0xFF, 0x33, 0},
++	{0x100, 0x13, 1},
++	{0x101, 0xf, 1},
++	{0x102, 0xee, 1},
++	{0x105, 0x3c, 0},
++	{0x106, 0x1, 1},
++	{0x107, 0xa, 0},
++	{0x108, 0x9d, 0},
++	{0x109, 0xa, 0},
++	{0x10A, 0, 0},
++	{0x10B, 0x40, 0},
++	{0x10C, 0x40, 0},
++	{0x10D, 0x88, 0},
++	{0x10E, 0x10, 0},
++	{0x10F, 0xf0, 0},
++	{0x110, 0x10, 0},
++	{0x111, 0xf0, 0},
++	{0x112, 0, 0},
++	{0x113, 0, 0},
++	{0x114, 0x10, 0},
++	{0x115, 0x55, 0},
++	{0x116, 0x3f, 1},
++	{0x117, 0x36, 1},
++	{0x118, 0, 0},
++	{0x119, 0, 0},
++	{0x11A, 0, 0},
++	{0x11B, 0x87, 0},
++	{0x11C, 0x11, 0},
++	{0x11D, 0, 0},
++	{0x11E, 0x33, 0},
++	{0x11F, 0x88, 0},
++	{0x120, 0, 0},
++	{0x121, 0x87, 0},
++	{0x122, 0x11, 0},
++	{0x123, 0, 0},
++	{0x124, 0x33, 0},
++	{0x125, 0x88, 0},
++	{0x126, 0x20, 1},
++	{0x127, 0x3f, 0},
++	{0x128, 0x44, 0},
++	{0x129, 0x8c, 0},
++	{0x12A, 0x6c, 0},
++	{0x12B, 0x22, 0},
++	{0x12C, 0xbe, 0},
++	{0x12D, 0x55, 0},
++	{0x12F, 0xc, 0},
++	{0x130, 0xaa, 0},
++	{0x131, 0x2, 0},
++	{0x132, 0, 0},
++	{0x133, 0x10, 0},
++	{0x134, 0x1, 0},
++	{0x135, 0, 0},
++	{0x136, 0, 0},
++	{0x137, 0x80, 0},
++	{0x138, 0x60, 0},
++	{0x139, 0x44, 0},
++	{0x13A, 0x55, 0},
++	{0x13B, 0x1, 0},
++	{0x13C, 0x55, 0},
++	{0x13D, 0x1, 0},
++	{0x13E, 0x5, 0},
++	{0x13F, 0x55, 0},
++	{0x140, 0x55, 0},
++	{0x146, 0, 0},
++	{0x147, 0, 0},
++	{0x148, 0, 0},
++	{0x149, 0, 0},
++	{0x14A, 0, 0},
++	{0x14B, 0, 0},
++	{0x14C, 0, 0},
++	{0x14D, 0, 0},
++	{0x14E, 0x1, 1},
++	{0x14F, 0, 0},
++	{0x150, 0, 0},
++	{0x151, 0, 0},
++	{0x154, 0xc, 0},
++	{0x155, 0xc, 0},
++	{0x156, 0xc, 0},
++	{0x157, 0, 0},
++	{0x158, 0x2b, 0},
++	{0x159, 0x84, 0},
++	{0x15A, 0x15, 0},
++	{0x15B, 0xf, 0},
++	{0x15C, 0, 0},
++	{0x15D, 0, 0},
++	{0x15E, 0, 1},
++	{0x15F, 0, 1},
++	{0x160, 0, 1},
++	{0x161, 0, 1},
++	{0x162, 0, 1},
++	{0x163, 0, 1},
++	{0x164, 0, 0},
++	{0x165, 0, 0},
++	{0x166, 0, 0},
++	{0x167, 0, 0},
++	{0x168, 0, 0},
++	{0x169, 0, 0},
++	{0x16A, 0, 1},
++	{0x16B, 0, 1},
++	{0x16C, 0, 1},
++	{0x16D, 0, 0},
++	{0x170, 0, 0},
++	{0x171, 0x77, 0},
++	{0x172, 0x77, 0},
++	{0x173, 0x77, 0},
++	{0x174, 0x77, 0},
++	{0x175, 0, 0},
++	{0x176, 0x3, 0},
++	{0x177, 0x37, 0},
++	{0x178, 0x3, 0},
++	{0x179, 0, 0},
++	{0x17A, 0x21, 0},
++	{0x17B, 0x21, 0},
++	{0x17C, 0, 0},
++	{0x17D, 0xaa, 0},
++	{0x17E, 0, 0},
++	{0x17F, 0xaa, 0},
++	{0x180, 0, 0},
++	{0x190, 0, 0},
++	{0x191, 0x77, 0},
++	{0x192, 0x77, 0},
++	{0x193, 0x77, 0},
++	{0x194, 0x77, 0},
++	{0x195, 0, 0},
++	{0x196, 0x3, 0},
++	{0x197, 0x37, 0},
++	{0x198, 0x3, 0},
++	{0x199, 0, 0},
++	{0x19A, 0x21, 0},
++	{0x19B, 0x21, 0},
++	{0x19C, 0, 0},
++	{0x19D, 0xaa, 0},
++	{0x19E, 0, 0},
++	{0x19F, 0xaa, 0},
++	{0x1A0, 0, 0},
++	{0x1A1, 0x2, 0},
++	{0x1A2, 0xf, 0},
++	{0x1A3, 0xf, 0},
++	{0x1A4, 0, 1},
++	{0x1A5, 0, 1},
++	{0x1A6, 0, 1},
++	{0x1A7, 0x2, 0},
++	{0x1A8, 0xf, 0},
++	{0x1A9, 0xf, 0},
++	{0x1AA, 0, 1},
++	{0x1AB, 0, 1},
++	{0x1AC, 0, 1},
++	{0x1AD, 0x84, 0},
++	{0x1AE, 0x60, 0},
++	{0x1AF, 0x47, 0},
++	{0x1B0, 0x47, 0},
++	{0x1B1, 0, 0},
++	{0x1B2, 0, 0},
++	{0x1B3, 0, 0},
++	{0x1B4, 0, 0},
++	{0x1B5, 0, 0},
++	{0x1B6, 0, 0},
++	{0x1B7, 0x5, 1},
++	{0x1B8, 0, 0},
++	{0x1B9, 0, 0},
++	{0x1BA, 0, 0},
++	{0x1BB, 0, 0},
++	{0x1BC, 0, 0},
++	{0x1BD, 0, 0},
++	{0x1BE, 0, 0},
++	{0x1BF, 0, 0},
++	{0x1C0, 0, 0},
++	{0x1C1, 0, 0},
++	{0x1C2, 0xa0, 1},
++	{0x1C3, 0, 0},
++	{0x1C4, 0, 0},
++	{0x1C5, 0, 0},
++	{0x1C6, 0, 0},
++	{0x1C7, 0, 0},
++	{0x1C8, 0, 0},
++	{0x1C9, 0, 0},
++	{0x1CA, 0, 0},
++	{0xFFFF, 0, 0}
++};
++
++static s16 nphy_def_lnagains[] = { -2, 10, 19, 25 };
++
++static s32 nphy_lnagain_est0[] = { -315, 40370 };
++static s32 nphy_lnagain_est1[] = { -224, 23242 };
++
++static const u16 tbl_iqcal_gainparams_nphy[2][NPHY_IQCAL_NUMGAINS][8] = {
++	{
++		{0x000, 0, 0, 2, 0x69, 0x69, 0x69, 0x69},
++		{0x700, 7, 0, 0, 0x69, 0x69, 0x69, 0x69},
++		{0x710, 7, 1, 0, 0x68, 0x68, 0x68, 0x68},
++		{0x720, 7, 2, 0, 0x67, 0x67, 0x67, 0x67},
++		{0x730, 7, 3, 0, 0x66, 0x66, 0x66, 0x66},
++		{0x740, 7, 4, 0, 0x65, 0x65, 0x65, 0x65},
++		{0x741, 7, 4, 1, 0x65, 0x65, 0x65, 0x65},
++		{0x742, 7, 4, 2, 0x65, 0x65, 0x65, 0x65},
++		{0x743, 7, 4, 3, 0x65, 0x65, 0x65, 0x65}
++	},
++	{
++		{0x000, 7, 0, 0, 0x79, 0x79, 0x79, 0x79},
++		{0x700, 7, 0, 0, 0x79, 0x79, 0x79, 0x79},
++		{0x710, 7, 1, 0, 0x79, 0x79, 0x79, 0x79},
++		{0x720, 7, 2, 0, 0x78, 0x78, 0x78, 0x78},
++		{0x730, 7, 3, 0, 0x78, 0x78, 0x78, 0x78},
++		{0x740, 7, 4, 0, 0x78, 0x78, 0x78, 0x78},
++		{0x741, 7, 4, 1, 0x78, 0x78, 0x78, 0x78},
++		{0x742, 7, 4, 2, 0x78, 0x78, 0x78, 0x78},
++		{0x743, 7, 4, 3, 0x78, 0x78, 0x78, 0x78}
++	}
++};
++
++static const u32 nphy_tpc_txgain[] = {
++	0x03cc2b44, 0x03cc2b42, 0x03cc2a44, 0x03cc2a42,
++	0x03cc2944, 0x03c82b44, 0x03c82b42, 0x03c82a44,
++	0x03c82a42, 0x03c82944, 0x03c82942, 0x03c82844,
++	0x03c82842, 0x03c42b44, 0x03c42b42, 0x03c42a44,
++	0x03c42a42, 0x03c42944, 0x03c42942, 0x03c42844,
++	0x03c42842, 0x03c42744, 0x03c42742, 0x03c42644,
++	0x03c42642, 0x03c42544, 0x03c42542, 0x03c42444,
++	0x03c42442, 0x03c02b44, 0x03c02b42, 0x03c02a44,
++	0x03c02a42, 0x03c02944, 0x03c02942, 0x03c02844,
++	0x03c02842, 0x03c02744, 0x03c02742, 0x03b02b44,
++	0x03b02b42, 0x03b02a44, 0x03b02a42, 0x03b02944,
++	0x03b02942, 0x03b02844, 0x03b02842, 0x03b02744,
++	0x03b02742, 0x03b02644, 0x03b02642, 0x03b02544,
++	0x03b02542, 0x03a02b44, 0x03a02b42, 0x03a02a44,
++	0x03a02a42, 0x03a02944, 0x03a02942, 0x03a02844,
++	0x03a02842, 0x03a02744, 0x03a02742, 0x03902b44,
++	0x03902b42, 0x03902a44, 0x03902a42, 0x03902944,
++	0x03902942, 0x03902844, 0x03902842, 0x03902744,
++	0x03902742, 0x03902644, 0x03902642, 0x03902544,
++	0x03902542, 0x03802b44, 0x03802b42, 0x03802a44,
++	0x03802a42, 0x03802944, 0x03802942, 0x03802844,
++	0x03802842, 0x03802744, 0x03802742, 0x03802644,
++	0x03802642, 0x03802544, 0x03802542, 0x03802444,
++	0x03802442, 0x03802344, 0x03802342, 0x03802244,
++	0x03802242, 0x03802144, 0x03802142, 0x03802044,
++	0x03802042, 0x03801f44, 0x03801f42, 0x03801e44,
++	0x03801e42, 0x03801d44, 0x03801d42, 0x03801c44,
++	0x03801c42, 0x03801b44, 0x03801b42, 0x03801a44,
++	0x03801a42, 0x03801944, 0x03801942, 0x03801844,
++	0x03801842, 0x03801744, 0x03801742, 0x03801644,
++	0x03801642, 0x03801544, 0x03801542, 0x03801444,
++	0x03801442, 0x03801344, 0x03801342, 0x00002b00
++};
++
++static const u16 nphy_tpc_loscale[] = {
++	256, 256, 271, 271, 287, 256, 256, 271,
++	271, 287, 287, 304, 304, 256, 256, 271,
++	271, 287, 287, 304, 304, 322, 322, 341,
++	341, 362, 362, 383, 383, 256, 256, 271,
++	271, 287, 287, 304, 304, 322, 322, 256,
++	256, 271, 271, 287, 287, 304, 304, 322,
++	322, 341, 341, 362, 362, 256, 256, 271,
++	271, 287, 287, 304, 304, 322, 322, 256,
++	256, 271, 271, 287, 287, 304, 304, 322,
++	322, 341, 341, 362, 362, 256, 256, 271,
++	271, 287, 287, 304, 304, 322, 322, 341,
++	341, 362, 362, 383, 383, 406, 406, 430,
++	430, 455, 455, 482, 482, 511, 511, 541,
++	541, 573, 573, 607, 607, 643, 643, 681,
++	681, 722, 722, 764, 764, 810, 810, 858,
++	858, 908, 908, 962, 962, 1019, 1019, 256
++};
++
++static u32 nphy_tpc_txgain_ipa[] = {
++	0x5ff7002d, 0x5ff7002b, 0x5ff7002a, 0x5ff70029,
++	0x5ff70028, 0x5ff70027, 0x5ff70026, 0x5ff70025,
++	0x5ef7002d, 0x5ef7002b, 0x5ef7002a, 0x5ef70029,
++	0x5ef70028, 0x5ef70027, 0x5ef70026, 0x5ef70025,
++	0x5df7002d, 0x5df7002b, 0x5df7002a, 0x5df70029,
++	0x5df70028, 0x5df70027, 0x5df70026, 0x5df70025,
++	0x5cf7002d, 0x5cf7002b, 0x5cf7002a, 0x5cf70029,
++	0x5cf70028, 0x5cf70027, 0x5cf70026, 0x5cf70025,
++	0x5bf7002d, 0x5bf7002b, 0x5bf7002a, 0x5bf70029,
++	0x5bf70028, 0x5bf70027, 0x5bf70026, 0x5bf70025,
++	0x5af7002d, 0x5af7002b, 0x5af7002a, 0x5af70029,
++	0x5af70028, 0x5af70027, 0x5af70026, 0x5af70025,
++	0x59f7002d, 0x59f7002b, 0x59f7002a, 0x59f70029,
++	0x59f70028, 0x59f70027, 0x59f70026, 0x59f70025,
++	0x58f7002d, 0x58f7002b, 0x58f7002a, 0x58f70029,
++	0x58f70028, 0x58f70027, 0x58f70026, 0x58f70025,
++	0x57f7002d, 0x57f7002b, 0x57f7002a, 0x57f70029,
++	0x57f70028, 0x57f70027, 0x57f70026, 0x57f70025,
++	0x56f7002d, 0x56f7002b, 0x56f7002a, 0x56f70029,
++	0x56f70028, 0x56f70027, 0x56f70026, 0x56f70025,
++	0x55f7002d, 0x55f7002b, 0x55f7002a, 0x55f70029,
++	0x55f70028, 0x55f70027, 0x55f70026, 0x55f70025,
++	0x54f7002d, 0x54f7002b, 0x54f7002a, 0x54f70029,
++	0x54f70028, 0x54f70027, 0x54f70026, 0x54f70025,
++	0x53f7002d, 0x53f7002b, 0x53f7002a, 0x53f70029,
++	0x53f70028, 0x53f70027, 0x53f70026, 0x53f70025,
++	0x52f7002d, 0x52f7002b, 0x52f7002a, 0x52f70029,
++	0x52f70028, 0x52f70027, 0x52f70026, 0x52f70025,
++	0x51f7002d, 0x51f7002b, 0x51f7002a, 0x51f70029,
++	0x51f70028, 0x51f70027, 0x51f70026, 0x51f70025,
++	0x50f7002d, 0x50f7002b, 0x50f7002a, 0x50f70029,
++	0x50f70028, 0x50f70027, 0x50f70026, 0x50f70025
++};
++
++static u32 nphy_tpc_txgain_ipa_rev5[] = {
++	0x1ff7002d, 0x1ff7002b, 0x1ff7002a, 0x1ff70029,
++	0x1ff70028, 0x1ff70027, 0x1ff70026, 0x1ff70025,
++	0x1ef7002d, 0x1ef7002b, 0x1ef7002a, 0x1ef70029,
++	0x1ef70028, 0x1ef70027, 0x1ef70026, 0x1ef70025,
++	0x1df7002d, 0x1df7002b, 0x1df7002a, 0x1df70029,
++	0x1df70028, 0x1df70027, 0x1df70026, 0x1df70025,
++	0x1cf7002d, 0x1cf7002b, 0x1cf7002a, 0x1cf70029,
++	0x1cf70028, 0x1cf70027, 0x1cf70026, 0x1cf70025,
++	0x1bf7002d, 0x1bf7002b, 0x1bf7002a, 0x1bf70029,
++	0x1bf70028, 0x1bf70027, 0x1bf70026, 0x1bf70025,
++	0x1af7002d, 0x1af7002b, 0x1af7002a, 0x1af70029,
++	0x1af70028, 0x1af70027, 0x1af70026, 0x1af70025,
++	0x19f7002d, 0x19f7002b, 0x19f7002a, 0x19f70029,
++	0x19f70028, 0x19f70027, 0x19f70026, 0x19f70025,
++	0x18f7002d, 0x18f7002b, 0x18f7002a, 0x18f70029,
++	0x18f70028, 0x18f70027, 0x18f70026, 0x18f70025,
++	0x17f7002d, 0x17f7002b, 0x17f7002a, 0x17f70029,
++	0x17f70028, 0x17f70027, 0x17f70026, 0x17f70025,
++	0x16f7002d, 0x16f7002b, 0x16f7002a, 0x16f70029,
++	0x16f70028, 0x16f70027, 0x16f70026, 0x16f70025,
++	0x15f7002d, 0x15f7002b, 0x15f7002a, 0x15f70029,
++	0x15f70028, 0x15f70027, 0x15f70026, 0x15f70025,
++	0x14f7002d, 0x14f7002b, 0x14f7002a, 0x14f70029,
++	0x14f70028, 0x14f70027, 0x14f70026, 0x14f70025,
++	0x13f7002d, 0x13f7002b, 0x13f7002a, 0x13f70029,
++	0x13f70028, 0x13f70027, 0x13f70026, 0x13f70025,
++	0x12f7002d, 0x12f7002b, 0x12f7002a, 0x12f70029,
++	0x12f70028, 0x12f70027, 0x12f70026, 0x12f70025,
++	0x11f7002d, 0x11f7002b, 0x11f7002a, 0x11f70029,
++	0x11f70028, 0x11f70027, 0x11f70026, 0x11f70025,
++	0x10f7002d, 0x10f7002b, 0x10f7002a, 0x10f70029,
++	0x10f70028, 0x10f70027, 0x10f70026, 0x10f70025
++};
++
++static u32 nphy_tpc_txgain_ipa_rev6[] = {
++	0x0ff7002d, 0x0ff7002b, 0x0ff7002a, 0x0ff70029,
++	0x0ff70028, 0x0ff70027, 0x0ff70026, 0x0ff70025,
++	0x0ef7002d, 0x0ef7002b, 0x0ef7002a, 0x0ef70029,
++	0x0ef70028, 0x0ef70027, 0x0ef70026, 0x0ef70025,
++	0x0df7002d, 0x0df7002b, 0x0df7002a, 0x0df70029,
++	0x0df70028, 0x0df70027, 0x0df70026, 0x0df70025,
++	0x0cf7002d, 0x0cf7002b, 0x0cf7002a, 0x0cf70029,
++	0x0cf70028, 0x0cf70027, 0x0cf70026, 0x0cf70025,
++	0x0bf7002d, 0x0bf7002b, 0x0bf7002a, 0x0bf70029,
++	0x0bf70028, 0x0bf70027, 0x0bf70026, 0x0bf70025,
++	0x0af7002d, 0x0af7002b, 0x0af7002a, 0x0af70029,
++	0x0af70028, 0x0af70027, 0x0af70026, 0x0af70025,
++	0x09f7002d, 0x09f7002b, 0x09f7002a, 0x09f70029,
++	0x09f70028, 0x09f70027, 0x09f70026, 0x09f70025,
++	0x08f7002d, 0x08f7002b, 0x08f7002a, 0x08f70029,
++	0x08f70028, 0x08f70027, 0x08f70026, 0x08f70025,
++	0x07f7002d, 0x07f7002b, 0x07f7002a, 0x07f70029,
++	0x07f70028, 0x07f70027, 0x07f70026, 0x07f70025,
++	0x06f7002d, 0x06f7002b, 0x06f7002a, 0x06f70029,
++	0x06f70028, 0x06f70027, 0x06f70026, 0x06f70025,
++	0x05f7002d, 0x05f7002b, 0x05f7002a, 0x05f70029,
++	0x05f70028, 0x05f70027, 0x05f70026, 0x05f70025,
++	0x04f7002d, 0x04f7002b, 0x04f7002a, 0x04f70029,
++	0x04f70028, 0x04f70027, 0x04f70026, 0x04f70025,
++	0x03f7002d, 0x03f7002b, 0x03f7002a, 0x03f70029,
++	0x03f70028, 0x03f70027, 0x03f70026, 0x03f70025,
++	0x02f7002d, 0x02f7002b, 0x02f7002a, 0x02f70029,
++	0x02f70028, 0x02f70027, 0x02f70026, 0x02f70025,
++	0x01f7002d, 0x01f7002b, 0x01f7002a, 0x01f70029,
++	0x01f70028, 0x01f70027, 0x01f70026, 0x01f70025,
++	0x00f7002d, 0x00f7002b, 0x00f7002a, 0x00f70029,
++	0x00f70028, 0x00f70027, 0x00f70026, 0x00f70025
++};
++
++static u32 nphy_tpc_txgain_ipa_2g_2057rev3[] = {
++	0x70ff0040, 0x70f7003e, 0x70ef003b, 0x70e70039,
++	0x70df0037, 0x70d70036, 0x70cf0033, 0x70c70032,
++	0x70bf0031, 0x70b7002f, 0x70af002e, 0x70a7002d,
++	0x709f002d, 0x7097002c, 0x708f002c, 0x7087002c,
++	0x707f002b, 0x7077002c, 0x706f002c, 0x7067002d,
++	0x705f002e, 0x705f002b, 0x705f0029, 0x7057002a,
++	0x70570028, 0x704f002a, 0x7047002c, 0x7047002a,
++	0x70470028, 0x70470026, 0x70470024, 0x70470022,
++	0x7047001f, 0x70370027, 0x70370024, 0x70370022,
++	0x70370020, 0x7037001f, 0x7037001d, 0x7037001b,
++	0x7037001a, 0x70370018, 0x70370017, 0x7027001e,
++	0x7027001d, 0x7027001a, 0x701f0024, 0x701f0022,
++	0x701f0020, 0x701f001f, 0x701f001d, 0x701f001b,
++	0x701f001a, 0x701f0018, 0x701f0017, 0x701f0015,
++	0x701f0014, 0x701f0013, 0x701f0012, 0x701f0011,
++	0x70170019, 0x70170018, 0x70170016, 0x70170015,
++	0x70170014, 0x70170013, 0x70170012, 0x70170010,
++	0x70170010, 0x7017000f, 0x700f001d, 0x700f001b,
++	0x700f001a, 0x700f0018, 0x700f0017, 0x700f0015,
++	0x700f0015, 0x700f0013, 0x700f0013, 0x700f0011,
++	0x700f0010, 0x700f0010, 0x700f000f, 0x700f000e,
++	0x700f000d, 0x700f000c, 0x700f000b, 0x700f000b,
++	0x700f000b, 0x700f000a, 0x700f0009, 0x700f0009,
++	0x700f0009, 0x700f0008, 0x700f0007, 0x700f0007,
++	0x700f0006, 0x700f0006, 0x700f0006, 0x700f0006,
++	0x700f0005, 0x700f0005, 0x700f0005, 0x700f0004,
++	0x700f0004, 0x700f0004, 0x700f0004, 0x700f0004,
++	0x700f0004, 0x700f0003, 0x700f0003, 0x700f0003,
++	0x700f0003, 0x700f0002, 0x700f0002, 0x700f0002,
++	0x700f0002, 0x700f0002, 0x700f0002, 0x700f0001,
++	0x700f0001, 0x700f0001, 0x700f0001, 0x700f0001,
++	0x700f0001, 0x700f0001, 0x700f0001, 0x700f0001
++};
++
++static u32 nphy_tpc_txgain_ipa_2g_2057rev4n6[] = {
++	0xf0ff0040, 0xf0f7003e, 0xf0ef003b, 0xf0e70039,
++	0xf0df0037, 0xf0d70036, 0xf0cf0033, 0xf0c70032,
++	0xf0bf0031, 0xf0b7002f, 0xf0af002e, 0xf0a7002d,
++	0xf09f002d, 0xf097002c, 0xf08f002c, 0xf087002c,
++	0xf07f002b, 0xf077002c, 0xf06f002c, 0xf067002d,
++	0xf05f002e, 0xf05f002b, 0xf05f0029, 0xf057002a,
++	0xf0570028, 0xf04f002a, 0xf047002c, 0xf047002a,
++	0xf0470028, 0xf0470026, 0xf0470024, 0xf0470022,
++	0xf047001f, 0xf0370027, 0xf0370024, 0xf0370022,
++	0xf0370020, 0xf037001f, 0xf037001d, 0xf037001b,
++	0xf037001a, 0xf0370018, 0xf0370017, 0xf027001e,
++	0xf027001d, 0xf027001a, 0xf01f0024, 0xf01f0022,
++	0xf01f0020, 0xf01f001f, 0xf01f001d, 0xf01f001b,
++	0xf01f001a, 0xf01f0018, 0xf01f0017, 0xf01f0015,
++	0xf01f0014, 0xf01f0013, 0xf01f0012, 0xf01f0011,
++	0xf0170019, 0xf0170018, 0xf0170016, 0xf0170015,
++	0xf0170014, 0xf0170013, 0xf0170012, 0xf0170010,
++	0xf0170010, 0xf017000f, 0xf00f001d, 0xf00f001b,
++	0xf00f001a, 0xf00f0018, 0xf00f0017, 0xf00f0015,
++	0xf00f0015, 0xf00f0013, 0xf00f0013, 0xf00f0011,
++	0xf00f0010, 0xf00f0010, 0xf00f000f, 0xf00f000e,
++	0xf00f000d, 0xf00f000c, 0xf00f000b, 0xf00f000b,
++	0xf00f000b, 0xf00f000a, 0xf00f0009, 0xf00f0009,
++	0xf00f0009, 0xf00f0008, 0xf00f0007, 0xf00f0007,
++	0xf00f0006, 0xf00f0006, 0xf00f0006, 0xf00f0006,
++	0xf00f0005, 0xf00f0005, 0xf00f0005, 0xf00f0004,
++	0xf00f0004, 0xf00f0004, 0xf00f0004, 0xf00f0004,
++	0xf00f0004, 0xf00f0003, 0xf00f0003, 0xf00f0003,
++	0xf00f0003, 0xf00f0002, 0xf00f0002, 0xf00f0002,
++	0xf00f0002, 0xf00f0002, 0xf00f0002, 0xf00f0001,
++	0xf00f0001, 0xf00f0001, 0xf00f0001, 0xf00f0001,
++	0xf00f0001, 0xf00f0001, 0xf00f0001, 0xf00f0001
++};
++
++static u32 nphy_tpc_txgain_ipa_2g_2057rev5[] = {
++	0x30ff0031, 0x30e70031, 0x30e7002e, 0x30cf002e,
++	0x30bf002e, 0x30af002e, 0x309f002f, 0x307f0033,
++	0x307f0031, 0x307f002e, 0x3077002e, 0x306f002e,
++	0x3067002e, 0x305f002f, 0x30570030, 0x3057002d,
++	0x304f002e, 0x30470031, 0x3047002e, 0x3047002c,
++	0x30470029, 0x303f002c, 0x303f0029, 0x3037002d,
++	0x3037002a, 0x30370028, 0x302f002c, 0x302f002a,
++	0x302f0028, 0x302f0026, 0x3027002c, 0x30270029,
++	0x30270027, 0x30270025, 0x30270023, 0x301f002c,
++	0x301f002a, 0x301f0028, 0x301f0025, 0x301f0024,
++	0x301f0022, 0x301f001f, 0x3017002d, 0x3017002b,
++	0x30170028, 0x30170026, 0x30170024, 0x30170022,
++	0x30170020, 0x3017001e, 0x3017001d, 0x3017001b,
++	0x3017001a, 0x30170018, 0x30170017, 0x30170015,
++	0x300f002c, 0x300f0029, 0x300f0027, 0x300f0024,
++	0x300f0022, 0x300f0021, 0x300f001f, 0x300f001d,
++	0x300f001b, 0x300f001a, 0x300f0018, 0x300f0017,
++	0x300f0016, 0x300f0015, 0x300f0115, 0x300f0215,
++	0x300f0315, 0x300f0415, 0x300f0515, 0x300f0615,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715
++};
++
++static u32 nphy_tpc_txgain_ipa_2g_2057rev7[] = {
++	0x30ff0031, 0x30e70031, 0x30e7002e, 0x30cf002e,
++	0x30bf002e, 0x30af002e, 0x309f002f, 0x307f0033,
++	0x307f0031, 0x307f002e, 0x3077002e, 0x306f002e,
++	0x3067002e, 0x305f002f, 0x30570030, 0x3057002d,
++	0x304f002e, 0x30470031, 0x3047002e, 0x3047002c,
++	0x30470029, 0x303f002c, 0x303f0029, 0x3037002d,
++	0x3037002a, 0x30370028, 0x302f002c, 0x302f002a,
++	0x302f0028, 0x302f0026, 0x3027002c, 0x30270029,
++	0x30270027, 0x30270025, 0x30270023, 0x301f002c,
++	0x301f002a, 0x301f0028, 0x301f0025, 0x301f0024,
++	0x301f0022, 0x301f001f, 0x3017002d, 0x3017002b,
++	0x30170028, 0x30170026, 0x30170024, 0x30170022,
++	0x30170020, 0x3017001e, 0x3017001d, 0x3017001b,
++	0x3017001a, 0x30170018, 0x30170017, 0x30170015,
++	0x300f002c, 0x300f0029, 0x300f0027, 0x300f0024,
++	0x300f0022, 0x300f0021, 0x300f001f, 0x300f001d,
++	0x300f001b, 0x300f001a, 0x300f0018, 0x300f0017,
++	0x300f0016, 0x300f0015, 0x300f0115, 0x300f0215,
++	0x300f0315, 0x300f0415, 0x300f0515, 0x300f0615,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715
++};
++
++static u32 nphy_tpc_txgain_ipa_5g[] = {
++	0x7ff70035, 0x7ff70033, 0x7ff70032, 0x7ff70031,
++	0x7ff7002f, 0x7ff7002e, 0x7ff7002d, 0x7ff7002b,
++	0x7ff7002a, 0x7ff70029, 0x7ff70028, 0x7ff70027,
++	0x7ff70026, 0x7ff70024, 0x7ff70023, 0x7ff70022,
++	0x7ef70028, 0x7ef70027, 0x7ef70026, 0x7ef70025,
++	0x7ef70024, 0x7ef70023, 0x7df70028, 0x7df70027,
++	0x7df70026, 0x7df70025, 0x7df70024, 0x7df70023,
++	0x7df70022, 0x7cf70029, 0x7cf70028, 0x7cf70027,
++	0x7cf70026, 0x7cf70025, 0x7cf70023, 0x7cf70022,
++	0x7bf70029, 0x7bf70028, 0x7bf70026, 0x7bf70025,
++	0x7bf70024, 0x7bf70023, 0x7bf70022, 0x7bf70021,
++	0x7af70029, 0x7af70028, 0x7af70027, 0x7af70026,
++	0x7af70025, 0x7af70024, 0x7af70023, 0x7af70022,
++	0x79f70029, 0x79f70028, 0x79f70027, 0x79f70026,
++	0x79f70025, 0x79f70024, 0x79f70023, 0x79f70022,
++	0x78f70029, 0x78f70028, 0x78f70027, 0x78f70026,
++	0x78f70025, 0x78f70024, 0x78f70023, 0x78f70022,
++	0x77f70029, 0x77f70028, 0x77f70027, 0x77f70026,
++	0x77f70025, 0x77f70024, 0x77f70023, 0x77f70022,
++	0x76f70029, 0x76f70028, 0x76f70027, 0x76f70026,
++	0x76f70024, 0x76f70023, 0x76f70022, 0x76f70021,
++	0x75f70029, 0x75f70028, 0x75f70027, 0x75f70026,
++	0x75f70025, 0x75f70024, 0x75f70023, 0x74f70029,
++	0x74f70028, 0x74f70026, 0x74f70025, 0x74f70024,
++	0x74f70023, 0x74f70022, 0x73f70029, 0x73f70027,
++	0x73f70026, 0x73f70025, 0x73f70024, 0x73f70023,
++	0x73f70022, 0x72f70028, 0x72f70027, 0x72f70026,
++	0x72f70025, 0x72f70024, 0x72f70023, 0x72f70022,
++	0x71f70028, 0x71f70027, 0x71f70026, 0x71f70025,
++	0x71f70024, 0x71f70023, 0x70f70028, 0x70f70027,
++	0x70f70026, 0x70f70024, 0x70f70023, 0x70f70022,
++	0x70f70021, 0x70f70020, 0x70f70020, 0x70f7001f
++};
++
++static u32 nphy_tpc_txgain_ipa_5g_2057[] = {
++	0x7f7f0044, 0x7f7f0040, 0x7f7f003c, 0x7f7f0039,
++	0x7f7f0036, 0x7e7f003c, 0x7e7f0038, 0x7e7f0035,
++	0x7d7f003c, 0x7d7f0039, 0x7d7f0036, 0x7d7f0033,
++	0x7c7f003b, 0x7c7f0037, 0x7c7f0034, 0x7b7f003a,
++	0x7b7f0036, 0x7b7f0033, 0x7a7f003c, 0x7a7f0039,
++	0x7a7f0036, 0x7a7f0033, 0x797f003b, 0x797f0038,
++	0x797f0035, 0x797f0032, 0x787f003b, 0x787f0038,
++	0x787f0035, 0x787f0032, 0x777f003a, 0x777f0037,
++	0x777f0034, 0x777f0031, 0x767f003a, 0x767f0036,
++	0x767f0033, 0x767f0031, 0x757f003a, 0x757f0037,
++	0x757f0034, 0x747f003c, 0x747f0039, 0x747f0036,
++	0x747f0033, 0x737f003b, 0x737f0038, 0x737f0035,
++	0x737f0032, 0x727f0039, 0x727f0036, 0x727f0033,
++	0x727f0030, 0x717f003a, 0x717f0037, 0x717f0034,
++	0x707f003b, 0x707f0038, 0x707f0035, 0x707f0032,
++	0x707f002f, 0x707f002d, 0x707f002a, 0x707f0028,
++	0x707f0025, 0x707f0023, 0x707f0021, 0x707f0020,
++	0x707f001e, 0x707f001c, 0x707f001b, 0x707f0019,
++	0x707f0018, 0x707f0016, 0x707f0015, 0x707f0014,
++	0x707f0013, 0x707f0012, 0x707f0011, 0x707f0010,
++	0x707f000f, 0x707f000e, 0x707f000d, 0x707f000d,
++	0x707f000c, 0x707f000b, 0x707f000b, 0x707f000a,
++	0x707f0009, 0x707f0009, 0x707f0008, 0x707f0008,
++	0x707f0007, 0x707f0007, 0x707f0007, 0x707f0006,
++	0x707f0006, 0x707f0006, 0x707f0005, 0x707f0005,
++	0x707f0005, 0x707f0004, 0x707f0004, 0x707f0004,
++	0x707f0004, 0x707f0004, 0x707f0003, 0x707f0003,
++	0x707f0003, 0x707f0003, 0x707f0003, 0x707f0003,
++	0x707f0002, 0x707f0002, 0x707f0002, 0x707f0002,
++	0x707f0002, 0x707f0002, 0x707f0002, 0x707f0002,
++	0x707f0001, 0x707f0001, 0x707f0001, 0x707f0001,
++	0x707f0001, 0x707f0001, 0x707f0001, 0x707f0001
++};
++
++static u32 nphy_tpc_txgain_ipa_5g_2057rev7[] = {
++	0x6f7f0031, 0x6f7f002e, 0x6f7f002c, 0x6f7f002a,
++	0x6f7f0027, 0x6e7f002e, 0x6e7f002c, 0x6e7f002a,
++	0x6d7f0030, 0x6d7f002d, 0x6d7f002a, 0x6d7f0028,
++	0x6c7f0030, 0x6c7f002d, 0x6c7f002b, 0x6b7f002e,
++	0x6b7f002c, 0x6b7f002a, 0x6b7f0027, 0x6a7f002e,
++	0x6a7f002c, 0x6a7f002a, 0x697f0030, 0x697f002e,
++	0x697f002b, 0x697f0029, 0x687f002f, 0x687f002d,
++	0x687f002a, 0x687f0027, 0x677f002f, 0x677f002d,
++	0x677f002a, 0x667f0031, 0x667f002e, 0x667f002c,
++	0x667f002a, 0x657f0030, 0x657f002e, 0x657f002b,
++	0x657f0029, 0x647f0030, 0x647f002d, 0x647f002b,
++	0x647f0029, 0x637f002f, 0x637f002d, 0x637f002a,
++	0x627f0030, 0x627f002d, 0x627f002b, 0x627f0029,
++	0x617f0030, 0x617f002e, 0x617f002b, 0x617f0029,
++	0x607f002f, 0x607f002d, 0x607f002a, 0x607f0027,
++	0x607f0026, 0x607f0023, 0x607f0021, 0x607f0020,
++	0x607f001e, 0x607f001c, 0x607f001a, 0x607f0019,
++	0x607f0018, 0x607f0016, 0x607f0015, 0x607f0014,
++	0x607f0012, 0x607f0012, 0x607f0011, 0x607f000f,
++	0x607f000f, 0x607f000e, 0x607f000d, 0x607f000c,
++	0x607f000c, 0x607f000b, 0x607f000b, 0x607f000a,
++	0x607f0009, 0x607f0009, 0x607f0008, 0x607f0008,
++	0x607f0008, 0x607f0007, 0x607f0007, 0x607f0006,
++	0x607f0006, 0x607f0005, 0x607f0005, 0x607f0005,
++	0x607f0005, 0x607f0005, 0x607f0004, 0x607f0004,
++	0x607f0004, 0x607f0004, 0x607f0003, 0x607f0003,
++	0x607f0003, 0x607f0003, 0x607f0002, 0x607f0002,
++	0x607f0002, 0x607f0002, 0x607f0002, 0x607f0002,
++	0x607f0002, 0x607f0002, 0x607f0002, 0x607f0002,
++	0x607f0002, 0x607f0002, 0x607f0002, 0x607f0002,
++	0x607f0002, 0x607f0001, 0x607f0001, 0x607f0001,
++	0x607f0001, 0x607f0001, 0x607f0001, 0x607f0001
++};
++
++static s8 nphy_papd_pga_gain_delta_ipa_2g[] = {
++	-114, -108, -98, -91, -84, -78, -70, -62,
++	-54, -46, -39, -31, -23, -15, -8, 0
++};
++
++static s8 nphy_papd_pga_gain_delta_ipa_5g[] = {
++	-100, -95, -89, -83, -77, -70, -63, -56,
++	-48, -41, -33, -25, -19, -12, -6, 0
++};
++
++static s16 nphy_papd_padgain_dlt_2g_2057rev3n4[] = {
++	-159, -113, -86, -72, -62, -54, -48, -43,
++	-39, -35, -31, -28, -25, -23, -20, -18,
++	-17, -15, -13, -11, -10, -8, -7, -6,
++	-5, -4, -3, -3, -2, -1, -1, 0
++};
++
++static s16 nphy_papd_padgain_dlt_2g_2057rev5[] = {
++	-109, -109, -82, -68, -58, -50, -44, -39,
++	-35, -31, -28, -26, -23, -21, -19, -17,
++	-16, -14, -13, -11, -10, -9, -8, -7,
++	-5, -5, -4, -3, -2, -1, -1, 0
++};
++
++static s16 nphy_papd_padgain_dlt_2g_2057rev7[] = {
++	-122, -122, -95, -80, -69, -61, -54, -49,
++	-43, -39, -35, -32, -28, -26, -23, -21,
++	-18, -16, -15, -13, -11, -10, -8, -7,
++	-6, -5, -4, -3, -2, -1, -1, 0
++};
++
++static s8 nphy_papd_pgagain_dlt_5g_2057[] = {
++	-107, -101, -92, -85, -78, -71, -62, -55,
++	-47, -39, -32, -24, -19, -12, -6, 0
++};
++
++static s8 nphy_papd_pgagain_dlt_5g_2057rev7[] = {
++	-110, -104, -95, -88, -81, -74, -66, -58,
++	-50, -44, -36, -28, -23, -15, -8, 0
++};
++
++static u8 pad_gain_codes_used_2057rev5[] = {
++	20, 19, 18, 17, 16, 15, 14, 13, 12, 11,
++	10, 9, 8, 7, 6, 5, 4, 3, 2, 1
++};
++
++static u8 pad_gain_codes_used_2057rev7[] = {
++	15, 14, 13, 12, 11, 10, 9, 8, 7, 6,
++	5, 4, 3, 2, 1
++};
++
++static u8 pad_all_gain_codes_2057[] = {
++	31, 30, 29, 28, 27, 26, 25, 24, 23, 22,
++	21, 20, 19, 18, 17, 16, 15, 14, 13, 12,
++	11, 10, 9, 8, 7, 6, 5, 4, 3, 2,
++	1, 0
++};
++
++static u8 pga_all_gain_codes_2057[] = {
++	15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
++};
++
++static u32 nphy_papd_scaltbl[] = {
++	0x0ae2002f, 0x0a3b0032, 0x09a70035, 0x09220038,
++	0x0887003c, 0x081f003f, 0x07a20043, 0x07340047,
++	0x06d2004b, 0x067a004f, 0x06170054, 0x05bf0059,
++	0x0571005e, 0x051e0064, 0x04d3006a, 0x04910070,
++	0x044c0077, 0x040f007e, 0x03d90085, 0x03a1008d,
++	0x036f0095, 0x033d009e, 0x030b00a8, 0x02e000b2,
++	0x02b900bc, 0x029200c7, 0x026d00d3, 0x024900e0,
++	0x022900ed, 0x020a00fb, 0x01ec010a, 0x01d0011a,
++	0x01b7012a, 0x019e013c, 0x0187014f, 0x01720162,
++	0x015d0177, 0x0149018e, 0x013701a5, 0x012601be,
++	0x011501d9, 0x010501f5, 0x00f70212, 0x00e90232,
++	0x00dc0253, 0x00d00276, 0x00c4029c, 0x00b902c3,
++	0x00af02ed, 0x00a5031a, 0x009c0349, 0x0093037a,
++	0x008b03af, 0x008303e7, 0x007c0422, 0x00750461,
++	0x006e04a3, 0x006804ea, 0x00620534, 0x005d0583,
++	0x005805d7, 0x0053062f, 0x004e068d, 0x004a06f1
++};
++
++static u32 nphy_tpc_txgain_rev3[] = {
++	0x1f410044, 0x1f410042, 0x1f410040, 0x1f41003e,
++	0x1f41003c, 0x1f41003b, 0x1f410039, 0x1f410037,
++	0x1e410044, 0x1e410042, 0x1e410040, 0x1e41003e,
++	0x1e41003c, 0x1e41003b, 0x1e410039, 0x1e410037,
++	0x1d410044, 0x1d410042, 0x1d410040, 0x1d41003e,
++	0x1d41003c, 0x1d41003b, 0x1d410039, 0x1d410037,
++	0x1c410044, 0x1c410042, 0x1c410040, 0x1c41003e,
++	0x1c41003c, 0x1c41003b, 0x1c410039, 0x1c410037,
++	0x1b410044, 0x1b410042, 0x1b410040, 0x1b41003e,
++	0x1b41003c, 0x1b41003b, 0x1b410039, 0x1b410037,
++	0x1a410044, 0x1a410042, 0x1a410040, 0x1a41003e,
++	0x1a41003c, 0x1a41003b, 0x1a410039, 0x1a410037,
++	0x19410044, 0x19410042, 0x19410040, 0x1941003e,
++	0x1941003c, 0x1941003b, 0x19410039, 0x19410037,
++	0x18410044, 0x18410042, 0x18410040, 0x1841003e,
++	0x1841003c, 0x1841003b, 0x18410039, 0x18410037,
++	0x17410044, 0x17410042, 0x17410040, 0x1741003e,
++	0x1741003c, 0x1741003b, 0x17410039, 0x17410037,
++	0x16410044, 0x16410042, 0x16410040, 0x1641003e,
++	0x1641003c, 0x1641003b, 0x16410039, 0x16410037,
++	0x15410044, 0x15410042, 0x15410040, 0x1541003e,
++	0x1541003c, 0x1541003b, 0x15410039, 0x15410037,
++	0x14410044, 0x14410042, 0x14410040, 0x1441003e,
++	0x1441003c, 0x1441003b, 0x14410039, 0x14410037,
++	0x13410044, 0x13410042, 0x13410040, 0x1341003e,
++	0x1341003c, 0x1341003b, 0x13410039, 0x13410037,
++	0x12410044, 0x12410042, 0x12410040, 0x1241003e,
++	0x1241003c, 0x1241003b, 0x12410039, 0x12410037,
++	0x11410044, 0x11410042, 0x11410040, 0x1141003e,
++	0x1141003c, 0x1141003b, 0x11410039, 0x11410037,
++	0x10410044, 0x10410042, 0x10410040, 0x1041003e,
++	0x1041003c, 0x1041003b, 0x10410039, 0x10410037
++};
++
++static u32 nphy_tpc_txgain_HiPwrEPA[] = {
++	0x0f410044, 0x0f410042, 0x0f410040, 0x0f41003e,
++	0x0f41003c, 0x0f41003b, 0x0f410039, 0x0f410037,
++	0x0e410044, 0x0e410042, 0x0e410040, 0x0e41003e,
++	0x0e41003c, 0x0e41003b, 0x0e410039, 0x0e410037,
++	0x0d410044, 0x0d410042, 0x0d410040, 0x0d41003e,
++	0x0d41003c, 0x0d41003b, 0x0d410039, 0x0d410037,
++	0x0c410044, 0x0c410042, 0x0c410040, 0x0c41003e,
++	0x0c41003c, 0x0c41003b, 0x0c410039, 0x0c410037,
++	0x0b410044, 0x0b410042, 0x0b410040, 0x0b41003e,
++	0x0b41003c, 0x0b41003b, 0x0b410039, 0x0b410037,
++	0x0a410044, 0x0a410042, 0x0a410040, 0x0a41003e,
++	0x0a41003c, 0x0a41003b, 0x0a410039, 0x0a410037,
++	0x09410044, 0x09410042, 0x09410040, 0x0941003e,
++	0x0941003c, 0x0941003b, 0x09410039, 0x09410037,
++	0x08410044, 0x08410042, 0x08410040, 0x0841003e,
++	0x0841003c, 0x0841003b, 0x08410039, 0x08410037,
++	0x07410044, 0x07410042, 0x07410040, 0x0741003e,
++	0x0741003c, 0x0741003b, 0x07410039, 0x07410037,
++	0x06410044, 0x06410042, 0x06410040, 0x0641003e,
++	0x0641003c, 0x0641003b, 0x06410039, 0x06410037,
++	0x05410044, 0x05410042, 0x05410040, 0x0541003e,
++	0x0541003c, 0x0541003b, 0x05410039, 0x05410037,
++	0x04410044, 0x04410042, 0x04410040, 0x0441003e,
++	0x0441003c, 0x0441003b, 0x04410039, 0x04410037,
++	0x03410044, 0x03410042, 0x03410040, 0x0341003e,
++	0x0341003c, 0x0341003b, 0x03410039, 0x03410037,
++	0x02410044, 0x02410042, 0x02410040, 0x0241003e,
++	0x0241003c, 0x0241003b, 0x02410039, 0x02410037,
++	0x01410044, 0x01410042, 0x01410040, 0x0141003e,
++	0x0141003c, 0x0141003b, 0x01410039, 0x01410037,
++	0x00410044, 0x00410042, 0x00410040, 0x0041003e,
++	0x0041003c, 0x0041003b, 0x00410039, 0x00410037
++};
++
++static u32 nphy_tpc_txgain_epa_2057rev3[] = {
++	0x80f90040, 0x80e10040, 0x80e1003c, 0x80c9003d,
++	0x80b9003c, 0x80a9003d, 0x80a1003c, 0x8099003b,
++	0x8091003b, 0x8089003a, 0x8081003a, 0x80790039,
++	0x80710039, 0x8069003a, 0x8061003b, 0x8059003d,
++	0x8051003f, 0x80490042, 0x8049003e, 0x8049003b,
++	0x8041003e, 0x8041003b, 0x8039003e, 0x8039003b,
++	0x80390038, 0x80390035, 0x8031003a, 0x80310036,
++	0x80310033, 0x8029003a, 0x80290037, 0x80290034,
++	0x80290031, 0x80210039, 0x80210036, 0x80210033,
++	0x80210030, 0x8019003c, 0x80190039, 0x80190036,
++	0x80190033, 0x80190030, 0x8019002d, 0x8019002b,
++	0x80190028, 0x8011003a, 0x80110036, 0x80110033,
++	0x80110030, 0x8011002e, 0x8011002b, 0x80110029,
++	0x80110027, 0x80110024, 0x80110022, 0x80110020,
++	0x8011001f, 0x8011001d, 0x8009003a, 0x80090037,
++	0x80090034, 0x80090031, 0x8009002e, 0x8009002c,
++	0x80090029, 0x80090027, 0x80090025, 0x80090023,
++	0x80090021, 0x8009001f, 0x8009001d, 0x8009011d,
++	0x8009021d, 0x8009031d, 0x8009041d, 0x8009051d,
++	0x8009061d, 0x8009071d, 0x8009071d, 0x8009071d,
++	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
++	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
++	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
++	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
++	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
++	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
++	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
++	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
++	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
++	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
++	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
++	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d
++};
++
++static u32 nphy_tpc_txgain_epa_2057rev5[] = {
++	0x10f90040, 0x10e10040, 0x10e1003c, 0x10c9003d,
++	0x10b9003c, 0x10a9003d, 0x10a1003c, 0x1099003b,
++	0x1091003b, 0x1089003a, 0x1081003a, 0x10790039,
++	0x10710039, 0x1069003a, 0x1061003b, 0x1059003d,
++	0x1051003f, 0x10490042, 0x1049003e, 0x1049003b,
++	0x1041003e, 0x1041003b, 0x1039003e, 0x1039003b,
++	0x10390038, 0x10390035, 0x1031003a, 0x10310036,
++	0x10310033, 0x1029003a, 0x10290037, 0x10290034,
++	0x10290031, 0x10210039, 0x10210036, 0x10210033,
++	0x10210030, 0x1019003c, 0x10190039, 0x10190036,
++	0x10190033, 0x10190030, 0x1019002d, 0x1019002b,
++	0x10190028, 0x1011003a, 0x10110036, 0x10110033,
++	0x10110030, 0x1011002e, 0x1011002b, 0x10110029,
++	0x10110027, 0x10110024, 0x10110022, 0x10110020,
++	0x1011001f, 0x1011001d, 0x1009003a, 0x10090037,
++	0x10090034, 0x10090031, 0x1009002e, 0x1009002c,
++	0x10090029, 0x10090027, 0x10090025, 0x10090023,
++	0x10090021, 0x1009001f, 0x1009001d, 0x1009001b,
++	0x1009001a, 0x10090018, 0x10090017, 0x10090016,
++	0x10090015, 0x10090013, 0x10090012, 0x10090011,
++	0x10090010, 0x1009000f, 0x1009000f, 0x1009000e,
++	0x1009000d, 0x1009000c, 0x1009000c, 0x1009000b,
++	0x1009000a, 0x1009000a, 0x10090009, 0x10090009,
++	0x10090008, 0x10090008, 0x10090007, 0x10090007,
++	0x10090007, 0x10090006, 0x10090006, 0x10090005,
++	0x10090005, 0x10090005, 0x10090005, 0x10090004,
++	0x10090004, 0x10090004, 0x10090004, 0x10090003,
++	0x10090003, 0x10090003, 0x10090003, 0x10090003,
++	0x10090003, 0x10090002, 0x10090002, 0x10090002,
++	0x10090002, 0x10090002, 0x10090002, 0x10090002,
++	0x10090002, 0x10090002, 0x10090001, 0x10090001,
++	0x10090001, 0x10090001, 0x10090001, 0x10090001
++};
++
++static u32 nphy_tpc_5GHz_txgain_rev3[] = {
++	0xcff70044, 0xcff70042, 0xcff70040, 0xcff7003e,
++	0xcff7003c, 0xcff7003b, 0xcff70039, 0xcff70037,
++	0xcef70044, 0xcef70042, 0xcef70040, 0xcef7003e,
++	0xcef7003c, 0xcef7003b, 0xcef70039, 0xcef70037,
++	0xcdf70044, 0xcdf70042, 0xcdf70040, 0xcdf7003e,
++	0xcdf7003c, 0xcdf7003b, 0xcdf70039, 0xcdf70037,
++	0xccf70044, 0xccf70042, 0xccf70040, 0xccf7003e,
++	0xccf7003c, 0xccf7003b, 0xccf70039, 0xccf70037,
++	0xcbf70044, 0xcbf70042, 0xcbf70040, 0xcbf7003e,
++	0xcbf7003c, 0xcbf7003b, 0xcbf70039, 0xcbf70037,
++	0xcaf70044, 0xcaf70042, 0xcaf70040, 0xcaf7003e,
++	0xcaf7003c, 0xcaf7003b, 0xcaf70039, 0xcaf70037,
++	0xc9f70044, 0xc9f70042, 0xc9f70040, 0xc9f7003e,
++	0xc9f7003c, 0xc9f7003b, 0xc9f70039, 0xc9f70037,
++	0xc8f70044, 0xc8f70042, 0xc8f70040, 0xc8f7003e,
++	0xc8f7003c, 0xc8f7003b, 0xc8f70039, 0xc8f70037,
++	0xc7f70044, 0xc7f70042, 0xc7f70040, 0xc7f7003e,
++	0xc7f7003c, 0xc7f7003b, 0xc7f70039, 0xc7f70037,
++	0xc6f70044, 0xc6f70042, 0xc6f70040, 0xc6f7003e,
++	0xc6f7003c, 0xc6f7003b, 0xc6f70039, 0xc6f70037,
++	0xc5f70044, 0xc5f70042, 0xc5f70040, 0xc5f7003e,
++	0xc5f7003c, 0xc5f7003b, 0xc5f70039, 0xc5f70037,
++	0xc4f70044, 0xc4f70042, 0xc4f70040, 0xc4f7003e,
++	0xc4f7003c, 0xc4f7003b, 0xc4f70039, 0xc4f70037,
++	0xc3f70044, 0xc3f70042, 0xc3f70040, 0xc3f7003e,
++	0xc3f7003c, 0xc3f7003b, 0xc3f70039, 0xc3f70037,
++	0xc2f70044, 0xc2f70042, 0xc2f70040, 0xc2f7003e,
++	0xc2f7003c, 0xc2f7003b, 0xc2f70039, 0xc2f70037,
++	0xc1f70044, 0xc1f70042, 0xc1f70040, 0xc1f7003e,
++	0xc1f7003c, 0xc1f7003b, 0xc1f70039, 0xc1f70037,
++	0xc0f70044, 0xc0f70042, 0xc0f70040, 0xc0f7003e,
++	0xc0f7003c, 0xc0f7003b, 0xc0f70039, 0xc0f70037
++};
++
++static u32 nphy_tpc_5GHz_txgain_rev4[] = {
++	0x2ff20044, 0x2ff20042, 0x2ff20040, 0x2ff2003e,
++	0x2ff2003c, 0x2ff2003b, 0x2ff20039, 0x2ff20037,
++	0x2ef20044, 0x2ef20042, 0x2ef20040, 0x2ef2003e,
++	0x2ef2003c, 0x2ef2003b, 0x2ef20039, 0x2ef20037,
++	0x2df20044, 0x2df20042, 0x2df20040, 0x2df2003e,
++	0x2df2003c, 0x2df2003b, 0x2df20039, 0x2df20037,
++	0x2cf20044, 0x2cf20042, 0x2cf20040, 0x2cf2003e,
++	0x2cf2003c, 0x2cf2003b, 0x2cf20039, 0x2cf20037,
++	0x2bf20044, 0x2bf20042, 0x2bf20040, 0x2bf2003e,
++	0x2bf2003c, 0x2bf2003b, 0x2bf20039, 0x2bf20037,
++	0x2af20044, 0x2af20042, 0x2af20040, 0x2af2003e,
++	0x2af2003c, 0x2af2003b, 0x2af20039, 0x2af20037,
++	0x29f20044, 0x29f20042, 0x29f20040, 0x29f2003e,
++	0x29f2003c, 0x29f2003b, 0x29f20039, 0x29f20037,
++	0x28f20044, 0x28f20042, 0x28f20040, 0x28f2003e,
++	0x28f2003c, 0x28f2003b, 0x28f20039, 0x28f20037,
++	0x27f20044, 0x27f20042, 0x27f20040, 0x27f2003e,
++	0x27f2003c, 0x27f2003b, 0x27f20039, 0x27f20037,
++	0x26f20044, 0x26f20042, 0x26f20040, 0x26f2003e,
++	0x26f2003c, 0x26f2003b, 0x26f20039, 0x26f20037,
++	0x25f20044, 0x25f20042, 0x25f20040, 0x25f2003e,
++	0x25f2003c, 0x25f2003b, 0x25f20039, 0x25f20037,
++	0x24f20044, 0x24f20042, 0x24f20040, 0x24f2003e,
++	0x24f2003c, 0x24f2003b, 0x24f20039, 0x24f20038,
++	0x23f20041, 0x23f20040, 0x23f2003f, 0x23f2003e,
++	0x23f2003c, 0x23f2003b, 0x23f20039, 0x23f20037,
++	0x22f20044, 0x22f20042, 0x22f20040, 0x22f2003e,
++	0x22f2003c, 0x22f2003b, 0x22f20039, 0x22f20037,
++	0x21f20044, 0x21f20042, 0x21f20040, 0x21f2003e,
++	0x21f2003c, 0x21f2003b, 0x21f20039, 0x21f20037,
++	0x20d20043, 0x20d20041, 0x20d2003e, 0x20d2003c,
++	0x20d2003a, 0x20d20038, 0x20d20036, 0x20d20034
++};
++
++static u32 nphy_tpc_5GHz_txgain_rev5[] = {
++	0x0f62004a, 0x0f620048, 0x0f620046, 0x0f620044,
++	0x0f620042, 0x0f620040, 0x0f62003e, 0x0f62003c,
++	0x0e620044, 0x0e620042, 0x0e620040, 0x0e62003e,
++	0x0e62003c, 0x0e62003d, 0x0e62003b, 0x0e62003a,
++	0x0d620043, 0x0d620041, 0x0d620040, 0x0d62003e,
++	0x0d62003d, 0x0d62003c, 0x0d62003b, 0x0d62003a,
++	0x0c620041, 0x0c620040, 0x0c62003f, 0x0c62003e,
++	0x0c62003c, 0x0c62003b, 0x0c620039, 0x0c620037,
++	0x0b620046, 0x0b620044, 0x0b620042, 0x0b620040,
++	0x0b62003e, 0x0b62003c, 0x0b62003b, 0x0b62003a,
++	0x0a620041, 0x0a620040, 0x0a62003e, 0x0a62003c,
++	0x0a62003b, 0x0a62003a, 0x0a620039, 0x0a620038,
++	0x0962003e, 0x0962003d, 0x0962003c, 0x0962003b,
++	0x09620039, 0x09620037, 0x09620035, 0x09620033,
++	0x08620044, 0x08620042, 0x08620040, 0x0862003e,
++	0x0862003c, 0x0862003b, 0x0862003a, 0x08620039,
++	0x07620043, 0x07620042, 0x07620040, 0x0762003f,
++	0x0762003d, 0x0762003b, 0x0762003a, 0x07620039,
++	0x0662003e, 0x0662003d, 0x0662003c, 0x0662003b,
++	0x06620039, 0x06620037, 0x06620035, 0x06620033,
++	0x05620046, 0x05620044, 0x05620042, 0x05620040,
++	0x0562003e, 0x0562003c, 0x0562003b, 0x05620039,
++	0x04620044, 0x04620042, 0x04620040, 0x0462003e,
++	0x0462003c, 0x0462003b, 0x04620039, 0x04620038,
++	0x0362003c, 0x0362003b, 0x0362003a, 0x03620039,
++	0x03620038, 0x03620037, 0x03620035, 0x03620033,
++	0x0262004c, 0x0262004a, 0x02620048, 0x02620047,
++	0x02620046, 0x02620044, 0x02620043, 0x02620042,
++	0x0162004a, 0x01620048, 0x01620046, 0x01620044,
++	0x01620043, 0x01620042, 0x01620041, 0x01620040,
++	0x00620042, 0x00620040, 0x0062003e, 0x0062003c,
++	0x0062003b, 0x00620039, 0x00620037, 0x00620035
++};
++
++static u32 nphy_tpc_5GHz_txgain_HiPwrEPA[] = {
++	0x2ff10044, 0x2ff10042, 0x2ff10040, 0x2ff1003e,
++	0x2ff1003c, 0x2ff1003b, 0x2ff10039, 0x2ff10037,
++	0x2ef10044, 0x2ef10042, 0x2ef10040, 0x2ef1003e,
++	0x2ef1003c, 0x2ef1003b, 0x2ef10039, 0x2ef10037,
++	0x2df10044, 0x2df10042, 0x2df10040, 0x2df1003e,
++	0x2df1003c, 0x2df1003b, 0x2df10039, 0x2df10037,
++	0x2cf10044, 0x2cf10042, 0x2cf10040, 0x2cf1003e,
++	0x2cf1003c, 0x2cf1003b, 0x2cf10039, 0x2cf10037,
++	0x2bf10044, 0x2bf10042, 0x2bf10040, 0x2bf1003e,
++	0x2bf1003c, 0x2bf1003b, 0x2bf10039, 0x2bf10037,
++	0x2af10044, 0x2af10042, 0x2af10040, 0x2af1003e,
++	0x2af1003c, 0x2af1003b, 0x2af10039, 0x2af10037,
++	0x29f10044, 0x29f10042, 0x29f10040, 0x29f1003e,
++	0x29f1003c, 0x29f1003b, 0x29f10039, 0x29f10037,
++	0x28f10044, 0x28f10042, 0x28f10040, 0x28f1003e,
++	0x28f1003c, 0x28f1003b, 0x28f10039, 0x28f10037,
++	0x27f10044, 0x27f10042, 0x27f10040, 0x27f1003e,
++	0x27f1003c, 0x27f1003b, 0x27f10039, 0x27f10037,
++	0x26f10044, 0x26f10042, 0x26f10040, 0x26f1003e,
++	0x26f1003c, 0x26f1003b, 0x26f10039, 0x26f10037,
++	0x25f10044, 0x25f10042, 0x25f10040, 0x25f1003e,
++	0x25f1003c, 0x25f1003b, 0x25f10039, 0x25f10037,
++	0x24f10044, 0x24f10042, 0x24f10040, 0x24f1003e,
++	0x24f1003c, 0x24f1003b, 0x24f10039, 0x24f10038,
++	0x23f10041, 0x23f10040, 0x23f1003f, 0x23f1003e,
++	0x23f1003c, 0x23f1003b, 0x23f10039, 0x23f10037,
++	0x22f10044, 0x22f10042, 0x22f10040, 0x22f1003e,
++	0x22f1003c, 0x22f1003b, 0x22f10039, 0x22f10037,
++	0x21f10044, 0x21f10042, 0x21f10040, 0x21f1003e,
++	0x21f1003c, 0x21f1003b, 0x21f10039, 0x21f10037,
++	0x20d10043, 0x20d10041, 0x20d1003e, 0x20d1003c,
++	0x20d1003a, 0x20d10038, 0x20d10036, 0x20d10034
++};
++
++static u8 ant_sw_ctrl_tbl_rev8_2o3[] = { 0x14, 0x18 };
++static u8 ant_sw_ctrl_tbl_rev8[] = { 0x4, 0x8, 0x4, 0x8, 0x11, 0x12 };
++static u8 ant_sw_ctrl_tbl_rev8_2057v7_core0[] = {
++	0x09, 0x0a, 0x15, 0x16, 0x09, 0x0a
++};
++static u8 ant_sw_ctrl_tbl_rev8_2057v7_core1[] = {
++	0x09, 0x0a, 0x09, 0x0a, 0x15, 0x16
++};
++
++bool wlc_phy_bist_check_phy(struct brcms_phy_pub *pih)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++	u32 phybist0, phybist1, phybist2, phybist3, phybist4;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 16))
++		return true;
++
++	phybist0 = read_phy_reg(pi, 0x0e);
++	phybist1 = read_phy_reg(pi, 0x0f);
++	phybist2 = read_phy_reg(pi, 0xea);
++	phybist3 = read_phy_reg(pi, 0xeb);
++	phybist4 = read_phy_reg(pi, 0x156);
++
++	if ((phybist0 == 0) && (phybist1 == 0x4000) && (phybist2 == 0x1fe0) &&
++	    (phybist3 == 0) && (phybist4 == 0))
++		return true;
++
++	return false;
++}
++
++static void wlc_phy_bphy_init_nphy(struct brcms_phy *pi)
++{
++	u16 addr, val;
++
++	val = 0x1e1f;
++	for (addr = (NPHY_TO_BPHY_OFF + BPHY_RSSI_LUT);
++	     addr <= (NPHY_TO_BPHY_OFF + BPHY_RSSI_LUT_END); addr++) {
++		write_phy_reg(pi, addr, val);
++		if (addr == (NPHY_TO_BPHY_OFF + 0x97))
++			val = 0x3e3f;
++		else
++			val -= 0x0202;
++	}
++
++	write_phy_reg(pi, NPHY_TO_BPHY_OFF + BPHY_STEP, 0x668);
++}
++
++void
++wlc_phy_table_write_nphy(struct brcms_phy *pi, u32 id, u32 len, u32 offset,
++			 u32 width, const void *data)
++{
++	struct phytbl_info tbl;
++
++	tbl.tbl_id = id;
++	tbl.tbl_len = len;
++	tbl.tbl_offset = offset;
++	tbl.tbl_width = width;
++	tbl.tbl_ptr = data;
++	wlc_phy_write_table_nphy(pi, &tbl);
++}
++
++void
++wlc_phy_table_read_nphy(struct brcms_phy *pi, u32 id, u32 len, u32 offset,
++			u32 width, void *data)
++{
++	struct phytbl_info tbl;
++
++	tbl.tbl_id = id;
++	tbl.tbl_len = len;
++	tbl.tbl_offset = offset;
++	tbl.tbl_width = width;
++	tbl.tbl_ptr = data;
++	wlc_phy_read_table_nphy(pi, &tbl);
++}
++
++static void
++wlc_phy_static_table_download_nphy(struct brcms_phy *pi)
++{
++	uint idx;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 16)) {
++		for (idx = 0; idx < mimophytbl_info_sz_rev16; idx++)
++			wlc_phy_write_table_nphy(pi,
++						 &mimophytbl_info_rev16[idx]);
++	} else if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		for (idx = 0; idx < mimophytbl_info_sz_rev7; idx++)
++			wlc_phy_write_table_nphy(pi,
++						 &mimophytbl_info_rev7[idx]);
++	} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		for (idx = 0; idx < mimophytbl_info_sz_rev3; idx++)
++			wlc_phy_write_table_nphy(pi,
++						 &mimophytbl_info_rev3[idx]);
++	} else {
++		for (idx = 0; idx < mimophytbl_info_sz_rev0; idx++)
++			wlc_phy_write_table_nphy(pi,
++						 &mimophytbl_info_rev0[idx]);
++	}
++}
++
++static void wlc_phy_tbl_init_nphy(struct brcms_phy *pi)
++{
++	uint idx = 0;
++	u8 antswctrllut;
++
++	if (pi->phy_init_por)
++		wlc_phy_static_table_download_nphy(pi);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++
++		antswctrllut = CHSPEC_IS2G(pi->radio_chanspec) ?
++			       pi->srom_fem2g.antswctrllut : pi->srom_fem5g.
++			       antswctrllut;
++
++		switch (antswctrllut) {
++		case 0:
++
++			break;
++
++		case 1:
++
++			if (pi->aa2g == 7)
++				wlc_phy_table_write_nphy(
++					pi,
++					NPHY_TBL_ID_ANTSWCTRLLUT,
++					2, 0x21, 8,
++					&ant_sw_ctrl_tbl_rev8_2o3[0]);
++			else
++				wlc_phy_table_write_nphy(
++					pi,
++					NPHY_TBL_ID_ANTSWCTRLLUT,
++					2, 0x21, 8,
++					&ant_sw_ctrl_tbl_rev8
++					[0]);
++
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
++						 2, 0x25, 8,
++						 &ant_sw_ctrl_tbl_rev8[2]);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
++						 2, 0x29, 8,
++						 &ant_sw_ctrl_tbl_rev8[4]);
++			break;
++
++		case 2:
++
++			wlc_phy_table_write_nphy(
++				pi, NPHY_TBL_ID_ANTSWCTRLLUT,
++				2, 0x1, 8,
++				&ant_sw_ctrl_tbl_rev8_2057v7_core0[0]);
++			wlc_phy_table_write_nphy(
++				pi, NPHY_TBL_ID_ANTSWCTRLLUT,
++				2, 0x5, 8,
++				&ant_sw_ctrl_tbl_rev8_2057v7_core0[2]);
++			wlc_phy_table_write_nphy(
++				pi, NPHY_TBL_ID_ANTSWCTRLLUT,
++				2, 0x9, 8,
++				&ant_sw_ctrl_tbl_rev8_2057v7_core0[4]);
++
++			wlc_phy_table_write_nphy(
++				pi, NPHY_TBL_ID_ANTSWCTRLLUT,
++				2, 0x21, 8,
++				&ant_sw_ctrl_tbl_rev8_2057v7_core1[0]);
++			wlc_phy_table_write_nphy(
++				pi, NPHY_TBL_ID_ANTSWCTRLLUT,
++				2, 0x25, 8,
++				&ant_sw_ctrl_tbl_rev8_2057v7_core1[2]);
++			wlc_phy_table_write_nphy(
++				pi, NPHY_TBL_ID_ANTSWCTRLLUT,
++				2, 0x29, 8,
++				&ant_sw_ctrl_tbl_rev8_2057v7_core1[4]);
++			break;
++
++		default:
++			break;
++		}
++
++	} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		for (idx = 0; idx < mimophytbl_info_sz_rev3_volatile; idx++) {
++
++			if (idx == ANT_SWCTRL_TBL_REV3_IDX) {
++				antswctrllut =
++					CHSPEC_IS2G(pi->radio_chanspec) ?
++					pi->srom_fem2g.antswctrllut :
++					pi->srom_fem5g.antswctrllut;
++				switch (antswctrllut) {
++				case 0:
++					wlc_phy_write_table_nphy(
++						pi,
++						&mimophytbl_info_rev3_volatile
++						[idx]);
++					break;
++				case 1:
++					wlc_phy_write_table_nphy(
++						pi,
++						&mimophytbl_info_rev3_volatile1
++						[idx]);
++					break;
++				case 2:
++					wlc_phy_write_table_nphy(
++						pi,
++						&mimophytbl_info_rev3_volatile2
++						[idx]);
++					break;
++				case 3:
++					wlc_phy_write_table_nphy(
++						pi,
++						&mimophytbl_info_rev3_volatile3
++						[idx]);
++					break;
++				default:
++					break;
++				}
++			} else {
++				wlc_phy_write_table_nphy(
++					pi,
++					&mimophytbl_info_rev3_volatile[idx]);
++			}
++		}
++	} else {
++		for (idx = 0; idx < mimophytbl_info_sz_rev0_volatile; idx++)
++			wlc_phy_write_table_nphy(pi,
++						 &mimophytbl_info_rev0_volatile
++						 [idx]);
++	}
++}
++
++static void
++wlc_phy_write_txmacreg_nphy(struct brcms_phy *pi, u16 holdoff, u16 delay)
++{
++	write_phy_reg(pi, 0x77, holdoff);
++	write_phy_reg(pi, 0xb4, delay);
++}
++
++void wlc_phy_nphy_tkip_rifs_war(struct brcms_phy *pi, u8 rifs)
++{
++	u16 holdoff, delay;
++
++	if (rifs) {
++
++		holdoff = 0x10;
++		delay = 0x258;
++	} else {
++
++		holdoff = 0x15;
++		delay = 0x320;
++	}
++
++	wlc_phy_write_txmacreg_nphy(pi, holdoff, delay);
++
++	if (pi && pi->sh && (pi->sh->_rifs_phy != rifs))
++		pi->sh->_rifs_phy = rifs;
++}
++
++static void wlc_phy_txpwrctrl_config_nphy(struct brcms_phy *pi)
++{
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		pi->nphy_txpwrctrl = PHY_TPC_HW_ON;
++		pi->phy_5g_pwrgain = true;
++		return;
++	}
++
++	pi->nphy_txpwrctrl = PHY_TPC_HW_OFF;
++	pi->phy_5g_pwrgain = false;
++
++	if ((pi->sh->boardflags2 & BFL2_TXPWRCTRL_EN) &&
++	    NREV_GE(pi->pubpi.phy_rev, 2) && (pi->sh->sromrev >= 4))
++		pi->nphy_txpwrctrl = PHY_TPC_HW_ON;
++	else if ((pi->sh->sromrev >= 4)
++		 && (pi->sh->boardflags2 & BFL2_5G_PWRGAIN))
++		pi->phy_5g_pwrgain = true;
++}
++
++static void wlc_phy_txpwr_srom_read_ppr_nphy(struct brcms_phy *pi)
++{
++	u16 bw40po, cddpo, stbcpo, bwduppo;
++	uint band_num;
++	struct ssb_sprom *sprom = &pi->d11core->bus->sprom;
++
++	if (pi->sh->sromrev >= 9)
++		return;
++
++	bw40po = sprom->bw40po;
++	pi->bw402gpo = bw40po & 0xf;
++	pi->bw405gpo = (bw40po & 0xf0) >> 4;
++	pi->bw405glpo = (bw40po & 0xf00) >> 8;
++	pi->bw405ghpo = (bw40po & 0xf000) >> 12;
++
++	cddpo = sprom->cddpo;
++	pi->cdd2gpo = cddpo & 0xf;
++	pi->cdd5gpo = (cddpo & 0xf0) >> 4;
++	pi->cdd5glpo = (cddpo & 0xf00) >> 8;
++	pi->cdd5ghpo = (cddpo & 0xf000) >> 12;
++
++	stbcpo = sprom->stbcpo;
++	pi->stbc2gpo = stbcpo & 0xf;
++	pi->stbc5gpo = (stbcpo & 0xf0) >> 4;
++	pi->stbc5glpo = (stbcpo & 0xf00) >> 8;
++	pi->stbc5ghpo = (stbcpo & 0xf000) >> 12;
++
++	bwduppo = sprom->bwduppo;
++	pi->bwdup2gpo = bwduppo & 0xf;
++	pi->bwdup5gpo = (bwduppo & 0xf0) >> 4;
++	pi->bwdup5glpo = (bwduppo & 0xf00) >> 8;
++	pi->bwdup5ghpo = (bwduppo & 0xf000) >> 12;
++
++	for (band_num = 0; band_num < (CH_2G_GROUP + CH_5G_GROUP);
++	     band_num++) {
++		switch (band_num) {
++		case 0:
++			pi->nphy_pwrctrl_info[PHY_CORE_0].max_pwr_2g =
++				sprom->core_pwr_info[0].maxpwr_2g;
++			pi->nphy_pwrctrl_info[PHY_CORE_1].max_pwr_2g =
++				sprom->core_pwr_info[1].maxpwr_2g;
++			pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_2g_a1 =
++				sprom->core_pwr_info[0].pa_2g[0];
++			pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_2g_a1 =
++				sprom->core_pwr_info[1].pa_2g[0];
++			pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_2g_b0 =
++				sprom->core_pwr_info[0].pa_2g[1];
++			pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_2g_b0 =
++				sprom->core_pwr_info[1].pa_2g[1];
++			pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_2g_b1 =
++				sprom->core_pwr_info[0].pa_2g[2];
++			pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_2g_b1 =
++				sprom->core_pwr_info[1].pa_2g[2];
++			pi->nphy_pwrctrl_info[PHY_CORE_0].idle_targ_2g =
++				sprom->core_pwr_info[0].itssi_2g;
++			pi->nphy_pwrctrl_info[PHY_CORE_1].idle_targ_2g =
++				sprom->core_pwr_info[1].itssi_2g;
++
++			pi->cck2gpo = sprom->cck2gpo;
++
++			pi->ofdm2gpo = sprom->ofdm2gpo;
++
++			pi->mcs2gpo[0] = sprom->mcs2gpo[0];
++			pi->mcs2gpo[1] = sprom->mcs2gpo[1];
++			pi->mcs2gpo[2] = sprom->mcs2gpo[2];
++			pi->mcs2gpo[3] = sprom->mcs2gpo[3];
++			pi->mcs2gpo[4] = sprom->mcs2gpo[4];
++			pi->mcs2gpo[5] = sprom->mcs2gpo[5];
++			pi->mcs2gpo[6] = sprom->mcs2gpo[6];
++			pi->mcs2gpo[7] = sprom->mcs2gpo[7];
++			break;
++		case 1:
++
++			pi->nphy_pwrctrl_info[PHY_CORE_0].max_pwr_5gm =
++				sprom->core_pwr_info[0].maxpwr_5g;
++			pi->nphy_pwrctrl_info[PHY_CORE_1].max_pwr_5gm =
++				sprom->core_pwr_info[1].maxpwr_5g;
++			pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_5gm_a1 =
++				sprom->core_pwr_info[0].pa_5g[0];
++			pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_5gm_a1 =
++				sprom->core_pwr_info[1].pa_5g[0];
++			pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_5gm_b0 =
++				sprom->core_pwr_info[0].pa_5g[1];
++			pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_5gm_b0 =
++				sprom->core_pwr_info[1].pa_5g[1];
++			pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_5gm_b1 =
++				sprom->core_pwr_info[0].pa_5g[2];
++			pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_5gm_b1 =
++				sprom->core_pwr_info[1].pa_5g[2];
++			pi->nphy_pwrctrl_info[PHY_CORE_0].idle_targ_5gm =
++				sprom->core_pwr_info[0].itssi_5g;
++			pi->nphy_pwrctrl_info[PHY_CORE_1].idle_targ_5gm =
++				sprom->core_pwr_info[1].itssi_5g;
++
++			pi->ofdm5gpo = sprom->ofdm5gpo;
++
++			pi->mcs5gpo[0] = sprom->mcs5gpo[0];
++			pi->mcs5gpo[1] = sprom->mcs5gpo[1];
++			pi->mcs5gpo[2] = sprom->mcs5gpo[2];
++			pi->mcs5gpo[3] = sprom->mcs5gpo[3];
++			pi->mcs5gpo[4] = sprom->mcs5gpo[4];
++			pi->mcs5gpo[5] = sprom->mcs5gpo[5];
++			pi->mcs5gpo[6] = sprom->mcs5gpo[6];
++			pi->mcs5gpo[7] = sprom->mcs5gpo[7];
++			break;
++		case 2:
++
++			pi->nphy_pwrctrl_info[0].max_pwr_5gl =
++				sprom->core_pwr_info[0].maxpwr_5gl;
++			pi->nphy_pwrctrl_info[1].max_pwr_5gl =
++				sprom->core_pwr_info[1].maxpwr_5gl;
++			pi->nphy_pwrctrl_info[0].pwrdet_5gl_a1 =
++				sprom->core_pwr_info[0].pa_5gl[0];
++			pi->nphy_pwrctrl_info[1].pwrdet_5gl_a1 =
++				sprom->core_pwr_info[1].pa_5gl[0];
++			pi->nphy_pwrctrl_info[0].pwrdet_5gl_b0 =
++				sprom->core_pwr_info[0].pa_5gl[1];
++			pi->nphy_pwrctrl_info[1].pwrdet_5gl_b0 =
++				sprom->core_pwr_info[1].pa_5gl[1];
++			pi->nphy_pwrctrl_info[0].pwrdet_5gl_b1 =
++				sprom->core_pwr_info[0].pa_5gl[2];
++			pi->nphy_pwrctrl_info[1].pwrdet_5gl_b1 =
++				sprom->core_pwr_info[1].pa_5gl[2];
++			pi->nphy_pwrctrl_info[0].idle_targ_5gl = 0;
++			pi->nphy_pwrctrl_info[1].idle_targ_5gl = 0;
++
++			pi->ofdm5glpo = sprom->ofdm5glpo;
++
++			pi->mcs5glpo[0] = sprom->mcs5glpo[0];
++			pi->mcs5glpo[1] = sprom->mcs5glpo[1];
++			pi->mcs5glpo[2] = sprom->mcs5glpo[2];
++			pi->mcs5glpo[3] = sprom->mcs5glpo[3];
++			pi->mcs5glpo[4] = sprom->mcs5glpo[4];
++			pi->mcs5glpo[5] = sprom->mcs5glpo[5];
++			pi->mcs5glpo[6] = sprom->mcs5glpo[6];
++			pi->mcs5glpo[7] = sprom->mcs5glpo[7];
++			break;
++		case 3:
++
++			pi->nphy_pwrctrl_info[0].max_pwr_5gh =
++				sprom->core_pwr_info[0].maxpwr_5gh;
++			pi->nphy_pwrctrl_info[1].max_pwr_5gh =
++				sprom->core_pwr_info[1].maxpwr_5gh;
++			pi->nphy_pwrctrl_info[0].pwrdet_5gh_a1 =
++				sprom->core_pwr_info[0].pa_5gh[0];
++			pi->nphy_pwrctrl_info[1].pwrdet_5gh_a1 =
++				sprom->core_pwr_info[1].pa_5gh[0];
++			pi->nphy_pwrctrl_info[0].pwrdet_5gh_b0 =
++				sprom->core_pwr_info[0].pa_5gh[1];
++			pi->nphy_pwrctrl_info[1].pwrdet_5gh_b0 =
++				sprom->core_pwr_info[1].pa_5gh[1];
++			pi->nphy_pwrctrl_info[0].pwrdet_5gh_b1 =
++				sprom->core_pwr_info[0].pa_5gh[2];
++			pi->nphy_pwrctrl_info[1].pwrdet_5gh_b1 =
++				sprom->core_pwr_info[1].pa_5gh[2];
++			pi->nphy_pwrctrl_info[0].idle_targ_5gh = 0;
++			pi->nphy_pwrctrl_info[1].idle_targ_5gh = 0;
++
++			pi->ofdm5ghpo = sprom->ofdm5ghpo;
++
++			pi->mcs5ghpo[0] = sprom->mcs5ghpo[0];
++			pi->mcs5ghpo[1] = sprom->mcs5ghpo[1];
++			pi->mcs5ghpo[2] = sprom->mcs5ghpo[2];
++			pi->mcs5ghpo[3] = sprom->mcs5ghpo[3];
++			pi->mcs5ghpo[4] = sprom->mcs5ghpo[4];
++			pi->mcs5ghpo[5] = sprom->mcs5ghpo[5];
++			pi->mcs5ghpo[6] = sprom->mcs5ghpo[6];
++			pi->mcs5ghpo[7] = sprom->mcs5ghpo[7];
++			break;
++		}
++	}
++
++	wlc_phy_txpwr_apply_nphy(pi);
++}
++
++static bool wlc_phy_txpwr_srom_read_nphy(struct brcms_phy *pi)
++{
++	struct ssb_sprom *sprom = &pi->d11core->bus->sprom;
++
++	pi->antswitch = sprom->antswitch;
++	pi->aa2g = sprom->ant_available_bg;
++	pi->aa5g = sprom->ant_available_a;
++
++	pi->srom_fem2g.tssipos = sprom->fem.ghz2.tssipos;
++	pi->srom_fem2g.extpagain = sprom->fem.ghz2.extpa_gain;
++	pi->srom_fem2g.pdetrange = sprom->fem.ghz2.pdet_range;
++	pi->srom_fem2g.triso = sprom->fem.ghz2.tr_iso;
++	pi->srom_fem2g.antswctrllut = sprom->fem.ghz2.antswlut;
++
++	pi->srom_fem5g.tssipos = sprom->fem.ghz5.tssipos;
++	pi->srom_fem5g.extpagain = sprom->fem.ghz5.extpa_gain;
++	pi->srom_fem5g.pdetrange = sprom->fem.ghz5.pdet_range;
++	pi->srom_fem5g.triso = sprom->fem.ghz5.tr_iso;
++	if (sprom->fem.ghz5.antswlut)
++		pi->srom_fem5g.antswctrllut = sprom->fem.ghz5.antswlut;
++	else
++		pi->srom_fem5g.antswctrllut = sprom->fem.ghz2.antswlut;
++
++	wlc_phy_txpower_ipa_upd(pi);
++
++	pi->phy_txcore_disable_temp = sprom->tempthresh;
++	if (pi->phy_txcore_disable_temp == 0)
++		pi->phy_txcore_disable_temp = PHY_CHAIN_TX_DISABLE_TEMP;
++
++	pi->phy_tempsense_offset = sprom->tempoffset;
++	if (pi->phy_tempsense_offset != 0) {
++		if (pi->phy_tempsense_offset >
++		    (NPHY_SROM_TEMPSHIFT + NPHY_SROM_MAXTEMPOFFSET))
++			pi->phy_tempsense_offset = NPHY_SROM_MAXTEMPOFFSET;
++		else if (pi->phy_tempsense_offset < (NPHY_SROM_TEMPSHIFT +
++						     NPHY_SROM_MINTEMPOFFSET))
++			pi->phy_tempsense_offset = NPHY_SROM_MINTEMPOFFSET;
++		else
++			pi->phy_tempsense_offset -= NPHY_SROM_TEMPSHIFT;
++	}
++
++	pi->phy_txcore_enable_temp =
++		pi->phy_txcore_disable_temp - PHY_HYSTERESIS_DELTATEMP;
++
++	pi->phycal_tempdelta = sprom->phycal_tempdelta;
++	if (pi->phycal_tempdelta > NPHY_CAL_MAXTEMPDELTA)
++		pi->phycal_tempdelta = 0;
++
++	wlc_phy_txpwr_srom_read_ppr_nphy(pi);
++
++	return true;
++}
++
++bool wlc_phy_attach_nphy(struct brcms_phy *pi)
++{
++	uint i;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 6))
++		pi->phyhang_avoid = true;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 7)) {
++		pi->nphy_gband_spurwar_en = true;
++		if (pi->sh->boardflags2 & BFL2_SPUR_WAR)
++			pi->nphy_aband_spurwar_en = true;
++	}
++	if (NREV_GE(pi->pubpi.phy_rev, 6) && NREV_LT(pi->pubpi.phy_rev, 7)) {
++		if (pi->sh->boardflags2 & BFL2_2G_SPUR_WAR)
++			pi->nphy_gband_spurwar2_en = true;
++	}
++
++	pi->n_preamble_override = AUTO;
++	if (NREV_IS(pi->pubpi.phy_rev, 3) || NREV_IS(pi->pubpi.phy_rev, 4))
++		pi->n_preamble_override = BRCMS_N_PREAMBLE_MIXEDMODE;
++
++	pi->nphy_txrx_chain = AUTO;
++	pi->phy_scraminit = AUTO;
++
++	pi->nphy_rxcalparams = 0x010100B5;
++
++	pi->nphy_perical = PHY_PERICAL_MPHASE;
++	pi->mphase_cal_phase_id = MPHASE_CAL_STATE_IDLE;
++	pi->mphase_txcal_numcmds = MPHASE_TXCAL_NUMCMDS;
++
++	pi->nphy_gain_boost = true;
++	pi->nphy_elna_gain_config = false;
++	pi->radio_is_on = false;
++
++	for (i = 0; i < pi->pubpi.phy_corenum; i++)
++		pi->nphy_txpwrindex[i].index = AUTO;
++
++	wlc_phy_txpwrctrl_config_nphy(pi);
++	if (pi->nphy_txpwrctrl == PHY_TPC_HW_ON)
++		pi->hwpwrctrl_capable = true;
++
++	pi->pi_fptr.init = wlc_phy_init_nphy;
++	pi->pi_fptr.calinit = wlc_phy_cal_init_nphy;
++	pi->pi_fptr.chanset = wlc_phy_chanspec_set_nphy;
++	pi->pi_fptr.txpwrrecalc = wlc_phy_txpower_recalc_target_nphy;
++
++	if (!wlc_phy_txpwr_srom_read_nphy(pi))
++		return false;
++
++	return true;
++}
++
++static s32 get_rf_pwr_offset(struct brcms_phy *pi, s16 pga_gn, s16 pad_gn)
++{
++	s32 rfpwr_offset = 0;
++
++	if (CHSPEC_IS2G(pi->radio_chanspec)) {
++		if ((pi->pubpi.radiorev == 3) ||
++		    (pi->pubpi.radiorev == 4) ||
++		    (pi->pubpi.radiorev == 6))
++			rfpwr_offset = (s16)
++				       nphy_papd_padgain_dlt_2g_2057rev3n4
++				       [pad_gn];
++		else if (pi->pubpi.radiorev == 5)
++			rfpwr_offset = (s16)
++				       nphy_papd_padgain_dlt_2g_2057rev5
++				       [pad_gn];
++		else if ((pi->pubpi.radiorev == 7)
++			 || (pi->pubpi.radiorev ==
++			     8))
++			rfpwr_offset = (s16)
++				       nphy_papd_padgain_dlt_2g_2057rev7
++				       [pad_gn];
++	} else {
++		if ((pi->pubpi.radiorev == 3) ||
++		    (pi->pubpi.radiorev == 4) ||
++		    (pi->pubpi.radiorev == 6))
++			rfpwr_offset = (s16)
++				       nphy_papd_pgagain_dlt_5g_2057
++				       [pga_gn];
++		else if ((pi->pubpi.radiorev == 7)
++			 || (pi->pubpi.radiorev ==
++			     8))
++			rfpwr_offset = (s16)
++				       nphy_papd_pgagain_dlt_5g_2057rev7
++				       [pga_gn];
++	}
++	return rfpwr_offset;
++}
++
++static void wlc_phy_update_mimoconfig_nphy(struct brcms_phy *pi, s32 preamble)
++{
++	bool gf_preamble = false;
++	u16 val;
++
++	if (preamble == BRCMS_N_PREAMBLE_GF)
++		gf_preamble = true;
++
++	val = read_phy_reg(pi, 0xed);
++
++	val |= RX_GF_MM_AUTO;
++	val &= ~RX_GF_OR_MM;
++	if (gf_preamble)
++		val |= RX_GF_OR_MM;
++
++	write_phy_reg(pi, 0xed, val);
++}
++
++static void wlc_phy_ipa_set_tx_digi_filts_nphy(struct brcms_phy *pi)
++{
++	int j, type;
++	u16 addr_offset[] = { 0x186, 0x195, 0x2c5};
++
++	for (type = 0; type < 3; type++) {
++		for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++)
++			write_phy_reg(pi, addr_offset[type] + j,
++				      NPHY_IPA_REV4_txdigi_filtcoeffs[type][j]);
++	}
++
++	if (pi->bw == WL_CHANSPEC_BW_40) {
++		for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++)
++			write_phy_reg(pi, 0x186 + j,
++				      NPHY_IPA_REV4_txdigi_filtcoeffs[3][j]);
++	} else {
++		if (CHSPEC_IS5G(pi->radio_chanspec)) {
++			for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++)
++				write_phy_reg(pi, 0x186 + j,
++					NPHY_IPA_REV4_txdigi_filtcoeffs[5][j]);
++		}
++
++		if (CHSPEC_CHANNEL(pi->radio_chanspec) == 14) {
++			for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++)
++				write_phy_reg(pi, 0x2c5 + j,
++					NPHY_IPA_REV4_txdigi_filtcoeffs[6][j]);
++		}
++	}
++}
++
++static void wlc_phy_ipa_restore_tx_digi_filts_nphy(struct brcms_phy *pi)
++{
++	int j;
++
++	if (pi->bw == WL_CHANSPEC_BW_40) {
++		for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++)
++			write_phy_reg(pi, 0x195 + j,
++				      NPHY_IPA_REV4_txdigi_filtcoeffs[4][j]);
++	} else {
++		for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++)
++			write_phy_reg(pi, 0x186 + j,
++				      NPHY_IPA_REV4_txdigi_filtcoeffs[3][j]);
++	}
++}
++
++static void
++wlc_phy_set_rfseq_nphy(struct brcms_phy *pi, u8 cmd, u8 *events, u8 *dlys,
++		       u8 len)
++{
++	u32 t1_offset, t2_offset;
++	u8 ctr;
++	u8 end_event =
++		NREV_GE(pi->pubpi.phy_rev,
++			3) ? NPHY_REV3_RFSEQ_CMD_END : NPHY_RFSEQ_CMD_END;
++	u8 end_dly = 1;
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++	t1_offset = cmd << 4;
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, len, t1_offset, 8,
++				 events);
++	t2_offset = t1_offset + 0x080;
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, len, t2_offset, 8,
++				 dlys);
++
++	for (ctr = len; ctr < 16; ctr++) {
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1,
++					 t1_offset + ctr, 8, &end_event);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1,
++					 t2_offset + ctr, 8, &end_dly);
++	}
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, false);
++}
++
++static u16 wlc_phy_read_lpf_bw_ctl_nphy(struct brcms_phy *pi, u16 offset)
++{
++	u16 lpf_bw_ctl_val = 0;
++	u16 rx2tx_lpf_rc_lut_offset = 0;
++
++	if (offset == 0) {
++		if (CHSPEC_IS40(pi->radio_chanspec))
++			rx2tx_lpf_rc_lut_offset = 0x159;
++		else
++			rx2tx_lpf_rc_lut_offset = 0x154;
++	} else {
++		rx2tx_lpf_rc_lut_offset = offset;
++	}
++	wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 1,
++				(u32) rx2tx_lpf_rc_lut_offset, 16,
++				&lpf_bw_ctl_val);
++
++	lpf_bw_ctl_val = lpf_bw_ctl_val & 0x7;
++
++	return lpf_bw_ctl_val;
++}
++
++static void
++wlc_phy_rfctrl_override_nphy_rev7(struct brcms_phy *pi, u16 field, u16 value,
++				  u8 core_mask, u8 off, u8 override_id)
++{
++	u8 core_num;
++	u16 addr = 0, en_addr = 0, val_addr = 0, en_mask = 0, val_mask = 0;
++	u8 val_shift = 0;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		en_mask = field;
++		for (core_num = 0; core_num < 2; core_num++) {
++			if (override_id == NPHY_REV7_RFCTRLOVERRIDE_ID0) {
++
++				switch (field) {
++				case (0x1 << 2):
++					en_addr = (core_num == 0) ? 0xe7 : 0xec;
++					val_addr = (core_num == 0) ? 0x7a :
++						   0x7d;
++					val_mask = (0x1 << 1);
++					val_shift = 1;
++					break;
++				case (0x1 << 3):
++					en_addr = (core_num == 0) ? 0xe7 : 0xec;
++					val_addr = (core_num == 0) ? 0x7a :
++						   0x7d;
++					val_mask = (0x1 << 2);
++					val_shift = 2;
++					break;
++				case (0x1 << 4):
++					en_addr = (core_num == 0) ? 0xe7 : 0xec;
++					val_addr = (core_num == 0) ? 0x7a :
++						   0x7d;
++					val_mask = (0x1 << 4);
++					val_shift = 4;
++					break;
++				case (0x1 << 5):
++					en_addr = (core_num == 0) ? 0xe7 : 0xec;
++					val_addr = (core_num == 0) ? 0x7a :
++						   0x7d;
++					val_mask = (0x1 << 5);
++					val_shift = 5;
++					break;
++				case (0x1 << 6):
++					en_addr = (core_num == 0) ? 0xe7 : 0xec;
++					val_addr = (core_num == 0) ? 0x7a :
++						   0x7d;
++					val_mask = (0x1 << 6);
++					val_shift = 6;
++					break;
++				case (0x1 << 7):
++					en_addr = (core_num == 0) ? 0xe7 : 0xec;
++					val_addr = (core_num == 0) ? 0x7a :
++						   0x7d;
++					val_mask = (0x1 << 7);
++					val_shift = 7;
++					break;
++				case (0x1 << 10):
++					en_addr = (core_num == 0) ? 0xe7 : 0xec;
++					val_addr = (core_num == 0) ? 0xf8 :
++						   0xfa;
++					val_mask = (0x7 << 4);
++					val_shift = 4;
++					break;
++				case (0x1 << 11):
++					en_addr = (core_num == 0) ? 0xe7 : 0xec;
++					val_addr = (core_num == 0) ? 0x7b :
++						   0x7e;
++					val_mask = (0xffff << 0);
++					val_shift = 0;
++					break;
++				case (0x1 << 12):
++					en_addr = (core_num == 0) ? 0xe7 : 0xec;
++					val_addr = (core_num == 0) ? 0x7c :
++						   0x7f;
++					val_mask = (0xffff << 0);
++					val_shift = 0;
++					break;
++				case (0x3 << 13):
++					en_addr = (core_num == 0) ? 0xe7 : 0xec;
++					val_addr = (core_num == 0) ? 0x348 :
++						   0x349;
++					val_mask = (0xff << 0);
++					val_shift = 0;
++					break;
++				case (0x1 << 13):
++					en_addr = (core_num == 0) ? 0xe7 : 0xec;
++					val_addr = (core_num == 0) ? 0x348 :
++						   0x349;
++					val_mask = (0xf << 0);
++					val_shift = 0;
++					break;
++				default:
++					addr = 0xffff;
++					break;
++				}
++			} else if (override_id ==
++				   NPHY_REV7_RFCTRLOVERRIDE_ID1) {
++
++				switch (field) {
++				case (0x1 << 1):
++					en_addr = (core_num == 0) ? 0x342 :
++						  0x343;
++					val_addr = (core_num == 0) ? 0x340 :
++						   0x341;
++					val_mask = (0x1 << 1);
++					val_shift = 1;
++					break;
++				case (0x1 << 3):
++					en_addr = (core_num == 0) ? 0x342 :
++						  0x343;
++					val_addr = (core_num == 0) ? 0x340 :
++						   0x341;
++					val_mask = (0x1 << 3);
++					val_shift = 3;
++					break;
++				case (0x1 << 5):
++					en_addr = (core_num == 0) ? 0x342 :
++						  0x343;
++					val_addr = (core_num == 0) ? 0x340 :
++						   0x341;
++					val_mask = (0x1 << 5);
++					val_shift = 5;
++					break;
++				case (0x1 << 4):
++					en_addr = (core_num == 0) ? 0x342 :
++						  0x343;
++					val_addr = (core_num == 0) ? 0x340 :
++						   0x341;
++					val_mask = (0x1 << 4);
++					val_shift = 4;
++					break;
++				case (0x1 << 2):
++
++					en_addr = (core_num == 0) ? 0x342 :
++						  0x343;
++					val_addr = (core_num == 0) ? 0x340 :
++						   0x341;
++					val_mask = (0x1 << 2);
++					val_shift = 2;
++					break;
++				case (0x1 << 7):
++
++					en_addr = (core_num == 0) ? 0x342 :
++						  0x343;
++					val_addr = (core_num == 0) ? 0x340 :
++						   0x341;
++					val_mask = (0x7 << 8);
++					val_shift = 8;
++					break;
++				case (0x1 << 11):
++					en_addr = (core_num == 0) ? 0x342 :
++						  0x343;
++					val_addr = (core_num == 0) ? 0x340 :
++						   0x341;
++					val_mask = (0x1 << 14);
++					val_shift = 14;
++					break;
++				case (0x1 << 10):
++					en_addr = (core_num == 0) ? 0x342 :
++						  0x343;
++					val_addr = (core_num == 0) ? 0x340 :
++						   0x341;
++					val_mask = (0x1 << 13);
++					val_shift = 13;
++					break;
++				case (0x1 << 9):
++					en_addr = (core_num == 0) ? 0x342 :
++						  0x343;
++					val_addr = (core_num == 0) ? 0x340 :
++						   0x341;
++					val_mask = (0x1 << 12);
++					val_shift = 12;
++					break;
++				case (0x1 << 8):
++					en_addr = (core_num == 0) ? 0x342 :
++						  0x343;
++					val_addr = (core_num == 0) ? 0x340 :
++						   0x341;
++					val_mask = (0x1 << 11);
++					val_shift = 11;
++					break;
++				case (0x1 << 6):
++					en_addr = (core_num == 0) ? 0x342 :
++						  0x343;
++					val_addr = (core_num == 0) ? 0x340 :
++						   0x341;
++					val_mask = (0x1 << 6);
++					val_shift = 6;
++					break;
++				case (0x1 << 0):
++					en_addr = (core_num == 0) ? 0x342 :
++						  0x343;
++					val_addr = (core_num == 0) ? 0x340 :
++						   0x341;
++					val_mask = (0x1 << 0);
++					val_shift = 0;
++					break;
++				default:
++					addr = 0xffff;
++					break;
++				}
++			} else if (override_id ==
++				   NPHY_REV7_RFCTRLOVERRIDE_ID2) {
++
++				switch (field) {
++				case (0x1 << 3):
++					en_addr = (core_num == 0) ? 0x346 :
++						  0x347;
++					val_addr = (core_num == 0) ? 0x344 :
++						   0x345;
++					val_mask = (0x1 << 3);
++					val_shift = 3;
++					break;
++				case (0x1 << 1):
++					en_addr = (core_num == 0) ? 0x346 :
++						  0x347;
++					val_addr = (core_num == 0) ? 0x344 :
++						   0x345;
++					val_mask = (0x1 << 1);
++					val_shift = 1;
++					break;
++				case (0x1 << 0):
++					en_addr = (core_num == 0) ? 0x346 :
++						  0x347;
++					val_addr = (core_num == 0) ? 0x344 :
++						   0x345;
++					val_mask = (0x1 << 0);
++					val_shift = 0;
++					break;
++				case (0x1 << 2):
++					en_addr = (core_num == 0) ? 0x346 :
++						  0x347;
++					val_addr = (core_num == 0) ? 0x344 :
++						   0x345;
++					val_mask = (0x1 << 2);
++					val_shift = 2;
++					break;
++				case (0x1 << 4):
++					en_addr = (core_num == 0) ? 0x346 :
++						  0x347;
++					val_addr = (core_num == 0) ? 0x344 :
++						   0x345;
++					val_mask = (0x1 << 4);
++					val_shift = 4;
++					break;
++				default:
++					addr = 0xffff;
++					break;
++				}
++			}
++
++			if (off) {
++				and_phy_reg(pi, en_addr, ~en_mask);
++				and_phy_reg(pi, val_addr, ~val_mask);
++			} else {
++
++				if ((core_mask == 0)
++				    || (core_mask & (1 << core_num))) {
++					or_phy_reg(pi, en_addr, en_mask);
++
++					if (addr != 0xffff)
++						mod_phy_reg(pi, val_addr,
++							    val_mask,
++							    (value <<
++							     val_shift));
++				}
++			}
++		}
++	}
++}
++
++static void wlc_phy_adjust_lnagaintbl_nphy(struct brcms_phy *pi)
++{
++	uint core;
++	int ctr;
++	s16 gain_delta[2];
++	u8 curr_channel;
++	u16 minmax_gain[2];
++	u16 regval[4];
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++	if (pi->nphy_gain_boost) {
++		if ((CHSPEC_IS2G(pi->radio_chanspec))) {
++
++			gain_delta[0] = 6;
++			gain_delta[1] = 6;
++		} else {
++
++			curr_channel = CHSPEC_CHANNEL(pi->radio_chanspec);
++			gain_delta[0] =
++				(s16)
++				PHY_HW_ROUND(((nphy_lnagain_est0[0] *
++					       curr_channel) +
++					      nphy_lnagain_est0[1]), 13);
++			gain_delta[1] =
++				(s16)
++				PHY_HW_ROUND(((nphy_lnagain_est1[0] *
++					       curr_channel) +
++					      nphy_lnagain_est1[1]), 13);
++		}
++	} else {
++
++		gain_delta[0] = 0;
++		gain_delta[1] = 0;
++	}
++
++	for (core = 0; core < pi->pubpi.phy_corenum; core++) {
++		if (pi->nphy_elna_gain_config) {
++
++			regval[0] = nphy_def_lnagains[2] + gain_delta[core];
++			regval[1] = nphy_def_lnagains[3] + gain_delta[core];
++			regval[2] = nphy_def_lnagains[3] + gain_delta[core];
++			regval[3] = nphy_def_lnagains[3] + gain_delta[core];
++		} else {
++			for (ctr = 0; ctr < 4; ctr++)
++				regval[ctr] =
++					nphy_def_lnagains[ctr] +
++					gain_delta[core];
++		}
++		wlc_phy_table_write_nphy(pi, core, 4, 8, 16, regval);
++
++		minmax_gain[core] =
++			(u16) (nphy_def_lnagains[2] + gain_delta[core] + 4);
++	}
++
++	mod_phy_reg(pi, 0x1e, (0xff << 0), (minmax_gain[0] << 0));
++	mod_phy_reg(pi, 0x34, (0xff << 0), (minmax_gain[1] << 0));
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, false);
++}
++
++static void
++wlc_phy_war_force_trsw_to_R_cliplo_nphy(struct brcms_phy *pi, u8 core)
++{
++	if (core == PHY_CORE_0) {
++		write_phy_reg(pi, 0x38, 0x4);
++		if (CHSPEC_IS2G(pi->radio_chanspec))
++			write_phy_reg(pi, 0x37, 0x0060);
++		else
++			write_phy_reg(pi, 0x37, 0x1080);
++	} else if (core == PHY_CORE_1) {
++		write_phy_reg(pi, 0x2ae, 0x4);
++		if (CHSPEC_IS2G(pi->radio_chanspec))
++			write_phy_reg(pi, 0x2ad, 0x0060);
++		else
++			write_phy_reg(pi, 0x2ad, 0x1080);
++	}
++}
++
++static void wlc_phy_war_txchain_upd_nphy(struct brcms_phy *pi, u8 txchain)
++{
++	u8 txchain0, txchain1;
++
++	txchain0 = txchain & 0x1;
++	txchain1 = (txchain & 0x2) >> 1;
++	if (!txchain0)
++		wlc_phy_war_force_trsw_to_R_cliplo_nphy(pi, PHY_CORE_0);
++
++	if (!txchain1)
++		wlc_phy_war_force_trsw_to_R_cliplo_nphy(pi, PHY_CORE_1);
++}
++
++static void wlc_phy_workarounds_nphy_gainctrl_2057_rev5(struct brcms_phy *pi)
++{
++	s8 lna1_gain_db[] = { 8, 13, 17, 22 };
++	s8 lna2_gain_db[] = { -2, 7, 11, 15 };
++	s8 tia_gain_db[] = { -4, -1, 2, 5, 5, 5, 5, 5, 5, 5 };
++	s8 tia_gainbits[] = {
++		0x0, 0x01, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 };
++
++	mod_phy_reg(pi, 0x1c, (0x1 << 13), (1 << 13));
++	mod_phy_reg(pi, 0x32, (0x1 << 13), (1 << 13));
++
++	mod_phy_reg(pi, 0x289, (0xff << 0), (0x46 << 0));
++
++	mod_phy_reg(pi, 0x283, (0xff << 0), (0x3c << 0));
++	mod_phy_reg(pi, 0x280, (0xff << 0), (0x3c << 0));
++
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 0x8, 8,
++				 lna1_gain_db);
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 0x8, 8,
++				 lna1_gain_db);
++
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 0x10, 8,
++				 lna2_gain_db);
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 0x10, 8,
++				 lna2_gain_db);
++
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 10, 0x20, 8,
++				 tia_gain_db);
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 10, 0x20, 8,
++				 tia_gain_db);
++
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS1, 10, 0x20, 8,
++				 tia_gainbits);
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS2, 10, 0x20, 8,
++				 tia_gainbits);
++
++	write_phy_reg(pi, 0x37, 0x74);
++	write_phy_reg(pi, 0x2ad, 0x74);
++	write_phy_reg(pi, 0x38, 0x18);
++	write_phy_reg(pi, 0x2ae, 0x18);
++
++	write_phy_reg(pi, 0x2b, 0xe8);
++	write_phy_reg(pi, 0x41, 0xe8);
++
++	if (CHSPEC_IS20(pi->radio_chanspec)) {
++
++		mod_phy_reg(pi, 0x300, (0x3f << 0), (0x12 << 0));
++		mod_phy_reg(pi, 0x301, (0x3f << 0), (0x12 << 0));
++	} else {
++
++		mod_phy_reg(pi, 0x300, (0x3f << 0), (0x10 << 0));
++		mod_phy_reg(pi, 0x301, (0x3f << 0), (0x10 << 0));
++	}
++}
++
++static void wlc_phy_workarounds_nphy_gainctrl_2057_rev6(struct brcms_phy *pi)
++{
++	u16 currband;
++	s8 lna1G_gain_db_rev7[] = { 9, 14, 19, 24 };
++	s8 *lna1_gain_db = NULL;
++	s8 *lna1_gain_db_2 = NULL;
++	s8 *lna2_gain_db = NULL;
++	s8 tiaA_gain_db_rev7[] = { -9, -6, -3, 0, 3, 3, 3, 3, 3, 3 };
++	s8 *tia_gain_db;
++	s8 tiaA_gainbits_rev7[] = { 0, 1, 2, 3, 4, 4, 4, 4, 4, 4 };
++	s8 *tia_gainbits;
++	u16 rfseqA_init_gain_rev7[] = { 0x624f, 0x624f };
++	u16 *rfseq_init_gain;
++	u16 init_gaincode;
++	u16 clip1hi_gaincode;
++	u16 clip1md_gaincode = 0;
++	u16 clip1md_gaincode_B;
++	u16 clip1lo_gaincode;
++	u16 clip1lo_gaincode_B;
++	u8 crsminl_th = 0;
++	u8 crsminu_th;
++	u16 nbclip_th = 0;
++	u8 w1clip_th;
++	u16 freq;
++	s8 nvar_baseline_offset0 = 0, nvar_baseline_offset1 = 0;
++	u8 chg_nbclip_th = 0;
++
++	mod_phy_reg(pi, 0x1c, (0x1 << 13), (1 << 13));
++	mod_phy_reg(pi, 0x32, (0x1 << 13), (1 << 13));
++
++	currband = read_phy_reg(pi, 0x09) & NPHY_BandControl_currentBand;
++	if (currband == 0) {
++
++		lna1_gain_db = lna1G_gain_db_rev7;
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 8, 8,
++					 lna1_gain_db);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 8, 8,
++					 lna1_gain_db);
++
++		mod_phy_reg(pi, 0x283, (0xff << 0), (0x40 << 0));
++
++		if (CHSPEC_IS40(pi->radio_chanspec)) {
++			mod_phy_reg(pi, 0x280, (0xff << 0), (0x3e << 0));
++			mod_phy_reg(pi, 0x283, (0xff << 0), (0x3e << 0));
++		}
++
++		mod_phy_reg(pi, 0x289, (0xff << 0), (0x46 << 0));
++
++		if (CHSPEC_IS20(pi->radio_chanspec)) {
++			mod_phy_reg(pi, 0x300, (0x3f << 0), (13 << 0));
++			mod_phy_reg(pi, 0x301, (0x3f << 0), (13 << 0));
++		}
++	} else {
++
++		init_gaincode = 0x9e;
++		clip1hi_gaincode = 0x9e;
++		clip1md_gaincode_B = 0x24;
++		clip1lo_gaincode = 0x8a;
++		clip1lo_gaincode_B = 8;
++		rfseq_init_gain = rfseqA_init_gain_rev7;
++
++		tia_gain_db = tiaA_gain_db_rev7;
++		tia_gainbits = tiaA_gainbits_rev7;
++
++		freq = CHAN5G_FREQ(CHSPEC_CHANNEL(pi->radio_chanspec));
++		if (CHSPEC_IS20(pi->radio_chanspec)) {
++
++			w1clip_th = 25;
++			clip1md_gaincode = 0x82;
++
++			if ((freq <= 5080) || (freq == 5825)) {
++
++				s8 lna1A_gain_db_rev7[] = { 11, 16, 20, 24 };
++				s8 lna1A_gain_db_2_rev7[] = {
++					11, 17, 22, 25};
++				s8 lna2A_gain_db_rev7[] = { -1, 6, 10, 14 };
++
++				crsminu_th = 0x3e;
++				lna1_gain_db = lna1A_gain_db_rev7;
++				lna1_gain_db_2 = lna1A_gain_db_2_rev7;
++				lna2_gain_db = lna2A_gain_db_rev7;
++			} else if ((freq >= 5500) && (freq <= 5700)) {
++
++				s8 lna1A_gain_db_rev7[] = { 11, 17, 21, 25 };
++				s8 lna1A_gain_db_2_rev7[] = {
++					12, 18, 22, 26};
++				s8 lna2A_gain_db_rev7[] = { 1, 8, 12, 16 };
++
++				crsminu_th = 0x45;
++				clip1md_gaincode_B = 0x14;
++				nbclip_th = 0xff;
++				chg_nbclip_th = 1;
++				lna1_gain_db = lna1A_gain_db_rev7;
++				lna1_gain_db_2 = lna1A_gain_db_2_rev7;
++				lna2_gain_db = lna2A_gain_db_rev7;
++			} else {
++
++				s8 lna1A_gain_db_rev7[] = { 12, 18, 22, 26 };
++				s8 lna1A_gain_db_2_rev7[] = {
++					12, 18, 22, 26};
++				s8 lna2A_gain_db_rev7[] = { -1, 6, 10, 14 };
++
++				crsminu_th = 0x41;
++				lna1_gain_db = lna1A_gain_db_rev7;
++				lna1_gain_db_2 = lna1A_gain_db_2_rev7;
++				lna2_gain_db = lna2A_gain_db_rev7;
++			}
++
++			if (freq <= 4920) {
++				nvar_baseline_offset0 = 5;
++				nvar_baseline_offset1 = 5;
++			} else if ((freq > 4920) && (freq <= 5320)) {
++				nvar_baseline_offset0 = 3;
++				nvar_baseline_offset1 = 5;
++			} else if ((freq > 5320) && (freq <= 5700)) {
++				nvar_baseline_offset0 = 3;
++				nvar_baseline_offset1 = 2;
++			} else {
++				nvar_baseline_offset0 = 4;
++				nvar_baseline_offset1 = 0;
++			}
++		} else {
++
++			crsminu_th = 0x3a;
++			crsminl_th = 0x3a;
++			w1clip_th = 20;
++
++			if ((freq >= 4920) && (freq <= 5320)) {
++				nvar_baseline_offset0 = 4;
++				nvar_baseline_offset1 = 5;
++			} else if ((freq > 5320) && (freq <= 5550)) {
++				nvar_baseline_offset0 = 4;
++				nvar_baseline_offset1 = 2;
++			} else {
++				nvar_baseline_offset0 = 5;
++				nvar_baseline_offset1 = 3;
++			}
++		}
++
++		write_phy_reg(pi, 0x20, init_gaincode);
++		write_phy_reg(pi, 0x2a7, init_gaincode);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
++					 pi->pubpi.phy_corenum, 0x106, 16,
++					 rfseq_init_gain);
++
++		write_phy_reg(pi, 0x22, clip1hi_gaincode);
++		write_phy_reg(pi, 0x2a9, clip1hi_gaincode);
++
++		write_phy_reg(pi, 0x36, clip1md_gaincode_B);
++		write_phy_reg(pi, 0x2ac, clip1md_gaincode_B);
++
++		write_phy_reg(pi, 0x37, clip1lo_gaincode);
++		write_phy_reg(pi, 0x2ad, clip1lo_gaincode);
++		write_phy_reg(pi, 0x38, clip1lo_gaincode_B);
++		write_phy_reg(pi, 0x2ae, clip1lo_gaincode_B);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 10, 0x20, 8,
++					 tia_gain_db);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 10, 0x20, 8,
++					 tia_gain_db);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS1, 10, 0x20, 8,
++					 tia_gainbits);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS2, 10, 0x20, 8,
++					 tia_gainbits);
++
++		mod_phy_reg(pi, 0x283, (0xff << 0), (crsminu_th << 0));
++
++		if (chg_nbclip_th == 1) {
++			write_phy_reg(pi, 0x2b, nbclip_th);
++			write_phy_reg(pi, 0x41, nbclip_th);
++		}
++
++		mod_phy_reg(pi, 0x300, (0x3f << 0), (w1clip_th << 0));
++		mod_phy_reg(pi, 0x301, (0x3f << 0), (w1clip_th << 0));
++
++		mod_phy_reg(pi, 0x2e4,
++			    (0x3f << 0), (nvar_baseline_offset0 << 0));
++
++		mod_phy_reg(pi, 0x2e4,
++			    (0x3f << 6), (nvar_baseline_offset1 << 6));
++
++		if (CHSPEC_IS20(pi->radio_chanspec)) {
++
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 8, 8,
++						 lna1_gain_db);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 8, 8,
++						 lna1_gain_db_2);
++
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 0x10,
++						 8, lna2_gain_db);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 0x10,
++						 8, lna2_gain_db);
++
++			write_phy_reg(pi, 0x24, clip1md_gaincode);
++			write_phy_reg(pi, 0x2ab, clip1md_gaincode);
++		} else {
++			mod_phy_reg(pi, 0x280, (0xff << 0), (crsminl_th << 0));
++		}
++	}
++}
++
++static void wlc_phy_workarounds_nphy_gainctrl(struct brcms_phy *pi)
++{
++	u16 w1th, hpf_code, currband;
++	int ctr;
++	u8 rfseq_updategainu_events[] = {
++		NPHY_RFSEQ_CMD_RX_GAIN,
++		NPHY_RFSEQ_CMD_CLR_HIQ_DIS,
++		NPHY_RFSEQ_CMD_SET_HPF_BW
++	};
++	u8 rfseq_updategainu_dlys[] = { 10, 30, 1 };
++	s8 lna1G_gain_db[] = { 7, 11, 16, 23 };
++	s8 lna1G_gain_db_rev4[] = { 8, 12, 17, 25 };
++	s8 lna1G_gain_db_rev5[] = { 9, 13, 18, 26 };
++	s8 lna1G_gain_db_rev6[] = { 8, 13, 18, 25 };
++	s8 lna1G_gain_db_rev6_224B0[] = { 10, 14, 19, 27 };
++	s8 lna1A_gain_db[] = { 7, 11, 17, 23 };
++	s8 lna1A_gain_db_rev4[] = { 8, 12, 18, 23 };
++	s8 lna1A_gain_db_rev5[] = { 6, 10, 16, 21 };
++	s8 lna1A_gain_db_rev6[] = { 6, 10, 16, 21 };
++	s8 *lna1_gain_db = NULL;
++	s8 lna2G_gain_db[] = { -5, 6, 10, 14 };
++	s8 lna2G_gain_db_rev5[] = { -3, 7, 11, 16 };
++	s8 lna2G_gain_db_rev6[] = { -5, 6, 10, 14 };
++	s8 lna2G_gain_db_rev6_224B0[] = { -5, 6, 10, 15 };
++	s8 lna2A_gain_db[] = { -6, 2, 6, 10 };
++	s8 lna2A_gain_db_rev4[] = { -5, 2, 6, 10 };
++	s8 lna2A_gain_db_rev5[] = { -7, 0, 4, 8 };
++	s8 lna2A_gain_db_rev6[] = { -7, 0, 4, 8 };
++	s8 *lna2_gain_db = NULL;
++	s8 tiaG_gain_db[] = {
++		0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A };
++	s8 tiaA_gain_db[] = {
++		0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13 };
++	s8 tiaA_gain_db_rev4[] = {
++		0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d };
++	s8 tiaA_gain_db_rev5[] = {
++		0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d };
++	s8 tiaA_gain_db_rev6[] = {
++		0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d };
++	s8 *tia_gain_db;
++	s8 tiaG_gainbits[] = {
++		0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 };
++	s8 tiaA_gainbits[] = {
++		0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06 };
++	s8 tiaA_gainbits_rev4[] = {
++		0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 };
++	s8 tiaA_gainbits_rev5[] = {
++		0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 };
++	s8 tiaA_gainbits_rev6[] = {
++		0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 };
++	s8 *tia_gainbits;
++	s8 lpf_gain_db[] = { 0x00, 0x06, 0x0c, 0x12, 0x12, 0x12 };
++	s8 lpf_gainbits[] = { 0x00, 0x01, 0x02, 0x03, 0x03, 0x03 };
++	u16 rfseqG_init_gain[] = { 0x613f, 0x613f, 0x613f, 0x613f };
++	u16 rfseqG_init_gain_rev4[] = { 0x513f, 0x513f, 0x513f, 0x513f };
++	u16 rfseqG_init_gain_rev5[] = { 0x413f, 0x413f, 0x413f, 0x413f };
++	u16 rfseqG_init_gain_rev5_elna[] = {
++		0x013f, 0x013f, 0x013f, 0x013f };
++	u16 rfseqG_init_gain_rev6[] = { 0x513f, 0x513f };
++	u16 rfseqG_init_gain_rev6_224B0[] = { 0x413f, 0x413f };
++	u16 rfseqG_init_gain_rev6_elna[] = { 0x113f, 0x113f };
++	u16 rfseqA_init_gain[] = { 0x516f, 0x516f, 0x516f, 0x516f };
++	u16 rfseqA_init_gain_rev4[] = { 0x614f, 0x614f, 0x614f, 0x614f };
++	u16 rfseqA_init_gain_rev4_elna[] = {
++		0x314f, 0x314f, 0x314f, 0x314f };
++	u16 rfseqA_init_gain_rev5[] = { 0x714f, 0x714f, 0x714f, 0x714f };
++	u16 rfseqA_init_gain_rev6[] = { 0x714f, 0x714f };
++	u16 *rfseq_init_gain;
++	u16 initG_gaincode = 0x627e;
++	u16 initG_gaincode_rev4 = 0x527e;
++	u16 initG_gaincode_rev5 = 0x427e;
++	u16 initG_gaincode_rev5_elna = 0x027e;
++	u16 initG_gaincode_rev6 = 0x527e;
++	u16 initG_gaincode_rev6_224B0 = 0x427e;
++	u16 initG_gaincode_rev6_elna = 0x127e;
++	u16 initA_gaincode = 0x52de;
++	u16 initA_gaincode_rev4 = 0x629e;
++	u16 initA_gaincode_rev4_elna = 0x329e;
++	u16 initA_gaincode_rev5 = 0x729e;
++	u16 initA_gaincode_rev6 = 0x729e;
++	u16 init_gaincode;
++	u16 clip1hiG_gaincode = 0x107e;
++	u16 clip1hiG_gaincode_rev4 = 0x007e;
++	u16 clip1hiG_gaincode_rev5 = 0x1076;
++	u16 clip1hiG_gaincode_rev6 = 0x007e;
++	u16 clip1hiA_gaincode = 0x00de;
++	u16 clip1hiA_gaincode_rev4 = 0x029e;
++	u16 clip1hiA_gaincode_rev5 = 0x029e;
++	u16 clip1hiA_gaincode_rev6 = 0x029e;
++	u16 clip1hi_gaincode;
++	u16 clip1mdG_gaincode = 0x0066;
++	u16 clip1mdA_gaincode = 0x00ca;
++	u16 clip1mdA_gaincode_rev4 = 0x1084;
++	u16 clip1mdA_gaincode_rev5 = 0x2084;
++	u16 clip1mdA_gaincode_rev6 = 0x2084;
++	u16 clip1md_gaincode = 0;
++	u16 clip1loG_gaincode = 0x0074;
++	u16 clip1loG_gaincode_rev5[] = {
++		0x0062, 0x0064, 0x006a, 0x106a, 0x106c, 0x1074, 0x107c, 0x207c
++	};
++	u16 clip1loG_gaincode_rev6[] = {
++		0x106a, 0x106c, 0x1074, 0x107c, 0x007e, 0x107e, 0x207e, 0x307e
++	};
++	u16 clip1loG_gaincode_rev6_224B0 = 0x1074;
++	u16 clip1loA_gaincode = 0x00cc;
++	u16 clip1loA_gaincode_rev4 = 0x0086;
++	u16 clip1loA_gaincode_rev5 = 0x2086;
++	u16 clip1loA_gaincode_rev6 = 0x2086;
++	u16 clip1lo_gaincode;
++	u8 crsminG_th = 0x18;
++	u8 crsminG_th_rev5 = 0x18;
++	u8 crsminG_th_rev6 = 0x18;
++	u8 crsminA_th = 0x1e;
++	u8 crsminA_th_rev4 = 0x24;
++	u8 crsminA_th_rev5 = 0x24;
++	u8 crsminA_th_rev6 = 0x24;
++	u8 crsmin_th;
++	u8 crsminlG_th = 0x18;
++	u8 crsminlG_th_rev5 = 0x18;
++	u8 crsminlG_th_rev6 = 0x18;
++	u8 crsminlA_th = 0x1e;
++	u8 crsminlA_th_rev4 = 0x24;
++	u8 crsminlA_th_rev5 = 0x24;
++	u8 crsminlA_th_rev6 = 0x24;
++	u8 crsminl_th = 0;
++	u8 crsminuG_th = 0x18;
++	u8 crsminuG_th_rev5 = 0x18;
++	u8 crsminuG_th_rev6 = 0x18;
++	u8 crsminuA_th = 0x1e;
++	u8 crsminuA_th_rev4 = 0x24;
++	u8 crsminuA_th_rev5 = 0x24;
++	u8 crsminuA_th_rev6 = 0x24;
++	u8 crsminuA_th_rev6_224B0 = 0x2d;
++	u8 crsminu_th;
++	u16 nbclipG_th = 0x20d;
++	u16 nbclipG_th_rev4 = 0x1a1;
++	u16 nbclipG_th_rev5 = 0x1d0;
++	u16 nbclipG_th_rev6 = 0x1d0;
++	u16 nbclipA_th = 0x1a1;
++	u16 nbclipA_th_rev4 = 0x107;
++	u16 nbclipA_th_rev5 = 0x0a9;
++	u16 nbclipA_th_rev6 = 0x0f0;
++	u16 nbclip_th = 0;
++	u8 w1clipG_th = 5;
++	u8 w1clipG_th_rev5 = 9;
++	u8 w1clipG_th_rev6 = 5;
++	u8 w1clipA_th = 25, w1clip_th;
++	u8 rssi_gain_default = 0x50;
++	u8 rssiG_gain_rev6_224B0 = 0x50;
++	u8 rssiA_gain_rev5 = 0x90;
++	u8 rssiA_gain_rev6 = 0x90;
++	u8 rssi_gain;
++	u16 regval[21];
++	u8 triso;
++
++	triso = (CHSPEC_IS5G(pi->radio_chanspec)) ? pi->srom_fem5g.triso :
++		pi->srom_fem2g.triso;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		if (pi->pubpi.radiorev == 5) {
++			wlc_phy_workarounds_nphy_gainctrl_2057_rev5(pi);
++		} else if (pi->pubpi.radiorev == 7) {
++			wlc_phy_workarounds_nphy_gainctrl_2057_rev6(pi);
++
++			mod_phy_reg(pi, 0x283, (0xff << 0), (0x44 << 0));
++			mod_phy_reg(pi, 0x280, (0xff << 0), (0x44 << 0));
++
++		} else if ((pi->pubpi.radiorev == 3)
++			   || (pi->pubpi.radiorev == 8)) {
++			wlc_phy_workarounds_nphy_gainctrl_2057_rev6(pi);
++
++			if (pi->pubpi.radiorev == 8) {
++				mod_phy_reg(pi, 0x283,
++					    (0xff << 0), (0x44 << 0));
++				mod_phy_reg(pi, 0x280,
++					    (0xff << 0), (0x44 << 0));
++			}
++		} else {
++			wlc_phy_workarounds_nphy_gainctrl_2057_rev6(pi);
++		}
++	} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++
++		mod_phy_reg(pi, 0xa0, (0x1 << 6), (1 << 6));
++
++		mod_phy_reg(pi, 0x1c, (0x1 << 13), (1 << 13));
++		mod_phy_reg(pi, 0x32, (0x1 << 13), (1 << 13));
++
++		currband =
++			read_phy_reg(pi, 0x09) & NPHY_BandControl_currentBand;
++		if (currband == 0) {
++			if (NREV_GE(pi->pubpi.phy_rev, 6)) {
++				if (pi->pubpi.radiorev == 11) {
++					lna1_gain_db = lna1G_gain_db_rev6_224B0;
++					lna2_gain_db = lna2G_gain_db_rev6_224B0;
++					rfseq_init_gain =
++						rfseqG_init_gain_rev6_224B0;
++					init_gaincode =
++						initG_gaincode_rev6_224B0;
++					clip1hi_gaincode =
++						clip1hiG_gaincode_rev6;
++					clip1lo_gaincode =
++						clip1loG_gaincode_rev6_224B0;
++					nbclip_th = nbclipG_th_rev6;
++					w1clip_th = w1clipG_th_rev6;
++					crsmin_th = crsminG_th_rev6;
++					crsminl_th = crsminlG_th_rev6;
++					crsminu_th = crsminuG_th_rev6;
++					rssi_gain = rssiG_gain_rev6_224B0;
++				} else {
++					lna1_gain_db = lna1G_gain_db_rev6;
++					lna2_gain_db = lna2G_gain_db_rev6;
++					if (pi->sh->boardflags & BFL_EXTLNA) {
++
++						rfseq_init_gain =
++						     rfseqG_init_gain_rev6_elna;
++						init_gaincode =
++						       initG_gaincode_rev6_elna;
++					} else {
++						rfseq_init_gain =
++							rfseqG_init_gain_rev6;
++						init_gaincode =
++							initG_gaincode_rev6;
++					}
++					clip1hi_gaincode =
++						clip1hiG_gaincode_rev6;
++					switch (triso) {
++					case 0:
++						clip1lo_gaincode =
++							clip1loG_gaincode_rev6
++							[0];
++						break;
++					case 1:
++						clip1lo_gaincode =
++							clip1loG_gaincode_rev6
++							[1];
++						break;
++					case 2:
++						clip1lo_gaincode =
++							clip1loG_gaincode_rev6
++							[2];
++						break;
++					case 3:
++					default:
++
++						clip1lo_gaincode =
++							clip1loG_gaincode_rev6
++							[3];
++						break;
++					case 4:
++						clip1lo_gaincode =
++							clip1loG_gaincode_rev6
++							[4];
++						break;
++					case 5:
++						clip1lo_gaincode =
++							clip1loG_gaincode_rev6
++							[5];
++						break;
++					case 6:
++						clip1lo_gaincode =
++							clip1loG_gaincode_rev6
++							[6];
++						break;
++					case 7:
++						clip1lo_gaincode =
++							clip1loG_gaincode_rev6
++							[7];
++						break;
++					}
++					nbclip_th = nbclipG_th_rev6;
++					w1clip_th = w1clipG_th_rev6;
++					crsmin_th = crsminG_th_rev6;
++					crsminl_th = crsminlG_th_rev6;
++					crsminu_th = crsminuG_th_rev6;
++					rssi_gain = rssi_gain_default;
++				}
++			} else if (NREV_IS(pi->pubpi.phy_rev, 5)) {
++				lna1_gain_db = lna1G_gain_db_rev5;
++				lna2_gain_db = lna2G_gain_db_rev5;
++				if (pi->sh->boardflags & BFL_EXTLNA) {
++
++					rfseq_init_gain =
++						rfseqG_init_gain_rev5_elna;
++					init_gaincode =
++						initG_gaincode_rev5_elna;
++				} else {
++					rfseq_init_gain = rfseqG_init_gain_rev5;
++					init_gaincode = initG_gaincode_rev5;
++				}
++				clip1hi_gaincode = clip1hiG_gaincode_rev5;
++				switch (triso) {
++				case 0:
++					clip1lo_gaincode =
++						clip1loG_gaincode_rev5[0];
++					break;
++				case 1:
++					clip1lo_gaincode =
++						clip1loG_gaincode_rev5[1];
++					break;
++				case 2:
++					clip1lo_gaincode =
++						clip1loG_gaincode_rev5[2];
++					break;
++				case 3:
++
++					clip1lo_gaincode =
++						clip1loG_gaincode_rev5[3];
++					break;
++				case 4:
++					clip1lo_gaincode =
++						clip1loG_gaincode_rev5[4];
++					break;
++				case 5:
++					clip1lo_gaincode =
++						clip1loG_gaincode_rev5[5];
++					break;
++				case 6:
++					clip1lo_gaincode =
++						clip1loG_gaincode_rev5[6];
++					break;
++				case 7:
++					clip1lo_gaincode =
++						clip1loG_gaincode_rev5[7];
++					break;
++				default:
++					clip1lo_gaincode =
++						clip1loG_gaincode_rev5[3];
++					break;
++				}
++				nbclip_th = nbclipG_th_rev5;
++				w1clip_th = w1clipG_th_rev5;
++				crsmin_th = crsminG_th_rev5;
++				crsminl_th = crsminlG_th_rev5;
++				crsminu_th = crsminuG_th_rev5;
++				rssi_gain = rssi_gain_default;
++			} else if (NREV_IS(pi->pubpi.phy_rev, 4)) {
++				lna1_gain_db = lna1G_gain_db_rev4;
++				lna2_gain_db = lna2G_gain_db;
++				rfseq_init_gain = rfseqG_init_gain_rev4;
++				init_gaincode = initG_gaincode_rev4;
++				clip1hi_gaincode = clip1hiG_gaincode_rev4;
++				clip1lo_gaincode = clip1loG_gaincode;
++				nbclip_th = nbclipG_th_rev4;
++				w1clip_th = w1clipG_th;
++				crsmin_th = crsminG_th;
++				crsminl_th = crsminlG_th;
++				crsminu_th = crsminuG_th;
++				rssi_gain = rssi_gain_default;
++			} else {
++				lna1_gain_db = lna1G_gain_db;
++				lna2_gain_db = lna2G_gain_db;
++				rfseq_init_gain = rfseqG_init_gain;
++				init_gaincode = initG_gaincode;
++				clip1hi_gaincode = clip1hiG_gaincode;
++				clip1lo_gaincode = clip1loG_gaincode;
++				nbclip_th = nbclipG_th;
++				w1clip_th = w1clipG_th;
++				crsmin_th = crsminG_th;
++				crsminl_th = crsminlG_th;
++				crsminu_th = crsminuG_th;
++				rssi_gain = rssi_gain_default;
++			}
++			tia_gain_db = tiaG_gain_db;
++			tia_gainbits = tiaG_gainbits;
++			clip1md_gaincode = clip1mdG_gaincode;
++		} else {
++			if (NREV_GE(pi->pubpi.phy_rev, 6)) {
++				lna1_gain_db = lna1A_gain_db_rev6;
++				lna2_gain_db = lna2A_gain_db_rev6;
++				tia_gain_db = tiaA_gain_db_rev6;
++				tia_gainbits = tiaA_gainbits_rev6;
++				rfseq_init_gain = rfseqA_init_gain_rev6;
++				init_gaincode = initA_gaincode_rev6;
++				clip1hi_gaincode = clip1hiA_gaincode_rev6;
++				clip1md_gaincode = clip1mdA_gaincode_rev6;
++				clip1lo_gaincode = clip1loA_gaincode_rev6;
++				crsmin_th = crsminA_th_rev6;
++				crsminl_th = crsminlA_th_rev6;
++				if ((pi->pubpi.radiorev == 11) &&
++				    (CHSPEC_IS40(pi->radio_chanspec) == 0))
++					crsminu_th = crsminuA_th_rev6_224B0;
++				else
++					crsminu_th = crsminuA_th_rev6;
++
++				nbclip_th = nbclipA_th_rev6;
++				rssi_gain = rssiA_gain_rev6;
++			} else if (NREV_IS(pi->pubpi.phy_rev, 5)) {
++				lna1_gain_db = lna1A_gain_db_rev5;
++				lna2_gain_db = lna2A_gain_db_rev5;
++				tia_gain_db = tiaA_gain_db_rev5;
++				tia_gainbits = tiaA_gainbits_rev5;
++				rfseq_init_gain = rfseqA_init_gain_rev5;
++				init_gaincode = initA_gaincode_rev5;
++				clip1hi_gaincode = clip1hiA_gaincode_rev5;
++				clip1md_gaincode = clip1mdA_gaincode_rev5;
++				clip1lo_gaincode = clip1loA_gaincode_rev5;
++				crsmin_th = crsminA_th_rev5;
++				crsminl_th = crsminlA_th_rev5;
++				crsminu_th = crsminuA_th_rev5;
++				nbclip_th = nbclipA_th_rev5;
++				rssi_gain = rssiA_gain_rev5;
++			} else if (NREV_IS(pi->pubpi.phy_rev, 4)) {
++				lna1_gain_db = lna1A_gain_db_rev4;
++				lna2_gain_db = lna2A_gain_db_rev4;
++				tia_gain_db = tiaA_gain_db_rev4;
++				tia_gainbits = tiaA_gainbits_rev4;
++				if (pi->sh->boardflags & BFL_EXTLNA_5GHz) {
++
++					rfseq_init_gain =
++						rfseqA_init_gain_rev4_elna;
++					init_gaincode =
++						initA_gaincode_rev4_elna;
++				} else {
++					rfseq_init_gain = rfseqA_init_gain_rev4;
++					init_gaincode = initA_gaincode_rev4;
++				}
++				clip1hi_gaincode = clip1hiA_gaincode_rev4;
++				clip1md_gaincode = clip1mdA_gaincode_rev4;
++				clip1lo_gaincode = clip1loA_gaincode_rev4;
++				crsmin_th = crsminA_th_rev4;
++				crsminl_th = crsminlA_th_rev4;
++				crsminu_th = crsminuA_th_rev4;
++				nbclip_th = nbclipA_th_rev4;
++				rssi_gain = rssi_gain_default;
++			} else {
++				lna1_gain_db = lna1A_gain_db;
++				lna2_gain_db = lna2A_gain_db;
++				tia_gain_db = tiaA_gain_db;
++				tia_gainbits = tiaA_gainbits;
++				rfseq_init_gain = rfseqA_init_gain;
++				init_gaincode = initA_gaincode;
++				clip1hi_gaincode = clip1hiA_gaincode;
++				clip1md_gaincode = clip1mdA_gaincode;
++				clip1lo_gaincode = clip1loA_gaincode;
++				crsmin_th = crsminA_th;
++				crsminl_th = crsminlA_th;
++				crsminu_th = crsminuA_th;
++				nbclip_th = nbclipA_th;
++				rssi_gain = rssi_gain_default;
++			}
++			w1clip_th = w1clipA_th;
++		}
++
++		write_radio_reg(pi,
++				(RADIO_2056_RX_BIASPOLE_LNAG1_IDAC |
++				 RADIO_2056_RX0), 0x17);
++		write_radio_reg(pi,
++				(RADIO_2056_RX_BIASPOLE_LNAG1_IDAC |
++				 RADIO_2056_RX1), 0x17);
++
++		write_radio_reg(pi, (RADIO_2056_RX_LNAG2_IDAC | RADIO_2056_RX0),
++				0xf0);
++		write_radio_reg(pi, (RADIO_2056_RX_LNAG2_IDAC | RADIO_2056_RX1),
++				0xf0);
++
++		write_radio_reg(pi, (RADIO_2056_RX_RSSI_POLE | RADIO_2056_RX0),
++				0x0);
++		write_radio_reg(pi, (RADIO_2056_RX_RSSI_POLE | RADIO_2056_RX1),
++				0x0);
++
++		write_radio_reg(pi, (RADIO_2056_RX_RSSI_GAIN | RADIO_2056_RX0),
++				rssi_gain);
++		write_radio_reg(pi, (RADIO_2056_RX_RSSI_GAIN | RADIO_2056_RX1),
++				rssi_gain);
++
++		write_radio_reg(pi,
++				(RADIO_2056_RX_BIASPOLE_LNAA1_IDAC |
++				 RADIO_2056_RX0), 0x17);
++		write_radio_reg(pi,
++				(RADIO_2056_RX_BIASPOLE_LNAA1_IDAC |
++				 RADIO_2056_RX1), 0x17);
++
++		write_radio_reg(pi, (RADIO_2056_RX_LNAA2_IDAC | RADIO_2056_RX0),
++				0xFF);
++		write_radio_reg(pi, (RADIO_2056_RX_LNAA2_IDAC | RADIO_2056_RX1),
++				0xFF);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 8,
++					 8, lna1_gain_db);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 8,
++					 8, lna1_gain_db);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 0x10,
++					 8, lna2_gain_db);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 0x10,
++					 8, lna2_gain_db);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 10, 0x20,
++					 8, tia_gain_db);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 10, 0x20,
++					 8, tia_gain_db);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS1, 10, 0x20,
++					 8, tia_gainbits);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS2, 10, 0x20,
++					 8, tia_gainbits);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 6, 0x40,
++					 8, &lpf_gain_db);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 6, 0x40,
++					 8, &lpf_gain_db);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS1, 6, 0x40,
++					 8, &lpf_gainbits);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS2, 6, 0x40,
++					 8, &lpf_gainbits);
++
++		write_phy_reg(pi, 0x20, init_gaincode);
++		write_phy_reg(pi, 0x2a7, init_gaincode);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
++					 pi->pubpi.phy_corenum, 0x106, 16,
++					 rfseq_init_gain);
++
++		write_phy_reg(pi, 0x22, clip1hi_gaincode);
++		write_phy_reg(pi, 0x2a9, clip1hi_gaincode);
++
++		write_phy_reg(pi, 0x24, clip1md_gaincode);
++		write_phy_reg(pi, 0x2ab, clip1md_gaincode);
++
++		write_phy_reg(pi, 0x37, clip1lo_gaincode);
++		write_phy_reg(pi, 0x2ad, clip1lo_gaincode);
++
++		mod_phy_reg(pi, 0x27d, (0xff << 0), (crsmin_th << 0));
++		mod_phy_reg(pi, 0x280, (0xff << 0), (crsminl_th << 0));
++		mod_phy_reg(pi, 0x283, (0xff << 0), (crsminu_th << 0));
++
++		write_phy_reg(pi, 0x2b, nbclip_th);
++		write_phy_reg(pi, 0x41, nbclip_th);
++
++		mod_phy_reg(pi, 0x27, (0x3f << 0), (w1clip_th << 0));
++		mod_phy_reg(pi, 0x3d, (0x3f << 0), (w1clip_th << 0));
++
++		write_phy_reg(pi, 0x150, 0x809c);
++
++	} else {
++
++		mod_phy_reg(pi, 0x1c, (0x1 << 13), (1 << 13));
++		mod_phy_reg(pi, 0x32, (0x1 << 13), (1 << 13));
++
++		write_phy_reg(pi, 0x2b, 0x84);
++		write_phy_reg(pi, 0x41, 0x84);
++
++		if (CHSPEC_IS20(pi->radio_chanspec)) {
++			write_phy_reg(pi, 0x6b, 0x2b);
++			write_phy_reg(pi, 0x6c, 0x2b);
++			write_phy_reg(pi, 0x6d, 0x9);
++			write_phy_reg(pi, 0x6e, 0x9);
++		}
++
++		w1th = NPHY_RSSICAL_W1_TARGET - 4;
++		mod_phy_reg(pi, 0x27, (0x3f << 0), (w1th << 0));
++		mod_phy_reg(pi, 0x3d, (0x3f << 0), (w1th << 0));
++
++		if (CHSPEC_IS20(pi->radio_chanspec)) {
++			mod_phy_reg(pi, 0x1c, (0x1f << 0), (0x1 << 0));
++			mod_phy_reg(pi, 0x32, (0x1f << 0), (0x1 << 0));
++
++			mod_phy_reg(pi, 0x1d, (0x1f << 0), (0x1 << 0));
++			mod_phy_reg(pi, 0x33, (0x1f << 0), (0x1 << 0));
++		}
++
++		write_phy_reg(pi, 0x150, 0x809c);
++
++		if (pi->nphy_gain_boost)
++			if ((CHSPEC_IS2G(pi->radio_chanspec)) &&
++			    (CHSPEC_IS40(pi->radio_chanspec)))
++				hpf_code = 4;
++			else
++				hpf_code = 5;
++		else if (CHSPEC_IS40(pi->radio_chanspec))
++			hpf_code = 6;
++		else
++			hpf_code = 7;
++
++		mod_phy_reg(pi, 0x20, (0x1f << 7), (hpf_code << 7));
++		mod_phy_reg(pi, 0x36, (0x1f << 7), (hpf_code << 7));
++
++		for (ctr = 0; ctr < 4; ctr++)
++			regval[ctr] = (hpf_code << 8) | 0x7c;
++		wlc_phy_table_write_nphy(pi, 7, 4, 0x106, 16, regval);
++
++		wlc_phy_adjust_lnagaintbl_nphy(pi);
++
++		if (pi->nphy_elna_gain_config) {
++			regval[0] = 0;
++			regval[1] = 1;
++			regval[2] = 1;
++			regval[3] = 1;
++			wlc_phy_table_write_nphy(pi, 2, 4, 8, 16, regval);
++			wlc_phy_table_write_nphy(pi, 3, 4, 8, 16, regval);
++
++			for (ctr = 0; ctr < 4; ctr++)
++				regval[ctr] = (hpf_code << 8) | 0x74;
++			wlc_phy_table_write_nphy(pi, 7, 4, 0x106, 16, regval);
++		}
++
++		if (NREV_IS(pi->pubpi.phy_rev, 2)) {
++			for (ctr = 0; ctr < 21; ctr++)
++				regval[ctr] = 3 * ctr;
++			wlc_phy_table_write_nphy(pi, 0, 21, 32, 16, regval);
++			wlc_phy_table_write_nphy(pi, 1, 21, 32, 16, regval);
++
++			for (ctr = 0; ctr < 21; ctr++)
++				regval[ctr] = (u16) ctr;
++			wlc_phy_table_write_nphy(pi, 2, 21, 32, 16, regval);
++			wlc_phy_table_write_nphy(pi, 3, 21, 32, 16, regval);
++		}
++
++		wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_UPDATEGAINU,
++				       rfseq_updategainu_events,
++				       rfseq_updategainu_dlys,
++				       sizeof(rfseq_updategainu_events) /
++				       sizeof(rfseq_updategainu_events[0]));
++
++		mod_phy_reg(pi, 0x153, (0xff << 8), (90 << 8));
++
++		if (CHSPEC_IS2G(pi->radio_chanspec))
++			mod_phy_reg(pi,
++				    (NPHY_TO_BPHY_OFF + BPHY_OPTIONAL_MODES),
++				    0x7f, 0x4);
++	}
++}
++
++static void wlc_phy_workarounds_nphy(struct brcms_phy *pi)
++{
++	u8 rfseq_rx2tx_events[] = {
++		NPHY_RFSEQ_CMD_NOP,
++		NPHY_RFSEQ_CMD_RXG_FBW,
++		NPHY_RFSEQ_CMD_TR_SWITCH,
++		NPHY_RFSEQ_CMD_CLR_HIQ_DIS,
++		NPHY_RFSEQ_CMD_RXPD_TXPD,
++		NPHY_RFSEQ_CMD_TX_GAIN,
++		NPHY_RFSEQ_CMD_EXT_PA
++	};
++	u8 rfseq_rx2tx_dlys[] = { 8, 6, 6, 2, 4, 60, 1 };
++	u8 rfseq_tx2rx_events[] = {
++		NPHY_RFSEQ_CMD_NOP,
++		NPHY_RFSEQ_CMD_EXT_PA,
++		NPHY_RFSEQ_CMD_TX_GAIN,
++		NPHY_RFSEQ_CMD_RXPD_TXPD,
++		NPHY_RFSEQ_CMD_TR_SWITCH,
++		NPHY_RFSEQ_CMD_RXG_FBW,
++		NPHY_RFSEQ_CMD_CLR_HIQ_DIS
++	};
++	u8 rfseq_tx2rx_dlys[] = { 8, 6, 2, 4, 4, 6, 1 };
++	u8 rfseq_tx2rx_events_rev3[] = {
++		NPHY_REV3_RFSEQ_CMD_EXT_PA,
++		NPHY_REV3_RFSEQ_CMD_INT_PA_PU,
++		NPHY_REV3_RFSEQ_CMD_TX_GAIN,
++		NPHY_REV3_RFSEQ_CMD_RXPD_TXPD,
++		NPHY_REV3_RFSEQ_CMD_TR_SWITCH,
++		NPHY_REV3_RFSEQ_CMD_RXG_FBW,
++		NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS,
++		NPHY_REV3_RFSEQ_CMD_END
++	};
++	u8 rfseq_tx2rx_dlys_rev3[] = { 8, 4, 2, 2, 4, 4, 6, 1 };
++	u8 rfseq_rx2tx_events_rev3[] = {
++		NPHY_REV3_RFSEQ_CMD_NOP,
++		NPHY_REV3_RFSEQ_CMD_RXG_FBW,
++		NPHY_REV3_RFSEQ_CMD_TR_SWITCH,
++		NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS,
++		NPHY_REV3_RFSEQ_CMD_RXPD_TXPD,
++		NPHY_REV3_RFSEQ_CMD_TX_GAIN,
++		NPHY_REV3_RFSEQ_CMD_INT_PA_PU,
++		NPHY_REV3_RFSEQ_CMD_EXT_PA,
++		NPHY_REV3_RFSEQ_CMD_END
++	};
++	u8 rfseq_rx2tx_dlys_rev3[] = { 8, 6, 6, 4, 4, 18, 42, 1, 1 };
++
++	u8 rfseq_rx2tx_events_rev3_ipa[] = {
++		NPHY_REV3_RFSEQ_CMD_NOP,
++		NPHY_REV3_RFSEQ_CMD_RXG_FBW,
++		NPHY_REV3_RFSEQ_CMD_TR_SWITCH,
++		NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS,
++		NPHY_REV3_RFSEQ_CMD_RXPD_TXPD,
++		NPHY_REV3_RFSEQ_CMD_TX_GAIN,
++		NPHY_REV3_RFSEQ_CMD_CLR_RXRX_BIAS,
++		NPHY_REV3_RFSEQ_CMD_INT_PA_PU,
++		NPHY_REV3_RFSEQ_CMD_END
++	};
++	u8 rfseq_rx2tx_dlys_rev3_ipa[] = { 8, 6, 6, 4, 4, 16, 43, 1, 1 };
++	u16 rfseq_rx2tx_dacbufpu_rev7[] = { 0x10f, 0x10f };
++
++	s16 alpha0, alpha1, alpha2;
++	s16 beta0, beta1, beta2;
++	u32 leg_data_weights, ht_data_weights, nss1_data_weights,
++	    stbc_data_weights;
++	u8 chan_freq_range = 0;
++	u16 dac_control = 0x0002;
++	u16 aux_adc_vmid_rev7_core0[] = { 0x8e, 0x96, 0x96, 0x96 };
++	u16 aux_adc_vmid_rev7_core1[] = { 0x8f, 0x9f, 0x9f, 0x96 };
++	u16 aux_adc_vmid_rev4[] = { 0xa2, 0xb4, 0xb4, 0x89 };
++	u16 aux_adc_vmid_rev3[] = { 0xa2, 0xb4, 0xb4, 0x89 };
++	u16 *aux_adc_vmid;
++	u16 aux_adc_gain_rev7[] = { 0x02, 0x02, 0x02, 0x02 };
++	u16 aux_adc_gain_rev4[] = { 0x02, 0x02, 0x02, 0x00 };
++	u16 aux_adc_gain_rev3[] = { 0x02, 0x02, 0x02, 0x00 };
++	u16 *aux_adc_gain;
++	u16 sk_adc_vmid[] = { 0xb4, 0xb4, 0xb4, 0x24 };
++	u16 sk_adc_gain[] = { 0x02, 0x02, 0x02, 0x02 };
++	s32 min_nvar_val = 0x18d;
++	s32 min_nvar_offset_6mbps = 20;
++	u8 pdetrange;
++	u8 triso;
++	u16 regval;
++	u16 afectrl_adc_ctrl1_rev7 = 0x20;
++	u16 afectrl_adc_ctrl2_rev7 = 0x0;
++	u16 rfseq_rx2tx_lpf_h_hpc_rev7 = 0x77;
++	u16 rfseq_tx2rx_lpf_h_hpc_rev7 = 0x77;
++	u16 rfseq_pktgn_lpf_h_hpc_rev7 = 0x77;
++	u16 rfseq_htpktgn_lpf_hpc_rev7[] = { 0x77, 0x11, 0x11 };
++	u16 rfseq_pktgn_lpf_hpc_rev7[] = { 0x11, 0x11 };
++	u16 rfseq_cckpktgn_lpf_hpc_rev7[] = { 0x11, 0x11 };
++	u16 ipalvlshift_3p3_war_en = 0;
++	u16 rccal_bcap_val, rccal_scap_val;
++	u16 rccal_tx20_11b_bcap = 0;
++	u16 rccal_tx20_11b_scap = 0;
++	u16 rccal_tx20_11n_bcap = 0;
++	u16 rccal_tx20_11n_scap = 0;
++	u16 rccal_tx40_11n_bcap = 0;
++	u16 rccal_tx40_11n_scap = 0;
++	u16 rx2tx_lpf_rc_lut_tx20_11b = 0;
++	u16 rx2tx_lpf_rc_lut_tx20_11n = 0;
++	u16 rx2tx_lpf_rc_lut_tx40_11n = 0;
++	u16 tx_lpf_bw_ofdm_20mhz = 0;
++	u16 tx_lpf_bw_ofdm_40mhz = 0;
++	u16 tx_lpf_bw_11b = 0;
++	u16 ipa2g_mainbias, ipa2g_casconv, ipa2g_biasfilt;
++	u16 txgm_idac_bleed = 0;
++	bool rccal_ovrd = false;
++	u16 freq;
++	int coreNum;
++
++	if (CHSPEC_IS5G(pi->radio_chanspec))
++		wlc_phy_classifier_nphy(pi, NPHY_ClassifierCtrl_cck_en, 0);
++	else
++		wlc_phy_classifier_nphy(pi, NPHY_ClassifierCtrl_cck_en, 1);
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++	or_phy_reg(pi, 0xb1, NPHY_IQFlip_ADC1 | NPHY_IQFlip_ADC2);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++
++		if (NREV_IS(pi->pubpi.phy_rev, 7)) {
++			mod_phy_reg(pi, 0x221, (0x1 << 4), (1 << 4));
++
++			mod_phy_reg(pi, 0x160, (0x7f << 0), (32 << 0));
++			mod_phy_reg(pi, 0x160, (0x7f << 8), (39 << 8));
++			mod_phy_reg(pi, 0x161, (0x7f << 0), (46 << 0));
++			mod_phy_reg(pi, 0x161, (0x7f << 8), (51 << 8));
++			mod_phy_reg(pi, 0x162, (0x7f << 0), (55 << 0));
++			mod_phy_reg(pi, 0x162, (0x7f << 8), (58 << 8));
++			mod_phy_reg(pi, 0x163, (0x7f << 0), (60 << 0));
++			mod_phy_reg(pi, 0x163, (0x7f << 8), (62 << 8));
++			mod_phy_reg(pi, 0x164, (0x7f << 0), (62 << 0));
++			mod_phy_reg(pi, 0x164, (0x7f << 8), (63 << 8));
++			mod_phy_reg(pi, 0x165, (0x7f << 0), (63 << 0));
++			mod_phy_reg(pi, 0x165, (0x7f << 8), (64 << 8));
++			mod_phy_reg(pi, 0x166, (0x7f << 0), (64 << 0));
++			mod_phy_reg(pi, 0x166, (0x7f << 8), (64 << 8));
++			mod_phy_reg(pi, 0x167, (0x7f << 0), (64 << 0));
++			mod_phy_reg(pi, 0x167, (0x7f << 8), (64 << 8));
++		}
++
++		if (NREV_LE(pi->pubpi.phy_rev, 8)) {
++			write_phy_reg(pi, 0x23f, 0x1b0);
++			write_phy_reg(pi, 0x240, 0x1b0);
++		}
++
++		if (NREV_GE(pi->pubpi.phy_rev, 8))
++			mod_phy_reg(pi, 0xbd, (0xff << 0), (114 << 0));
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x00, 16,
++					 &dac_control);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x10, 16,
++					 &dac_control);
++
++		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
++					1, 0, 32, &leg_data_weights);
++		leg_data_weights = leg_data_weights & 0xffffff;
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
++					 1, 0, 32, &leg_data_weights);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
++					 2, 0x15e, 16,
++					 rfseq_rx2tx_dacbufpu_rev7);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x16e, 16,
++					 rfseq_rx2tx_dacbufpu_rev7);
++
++		if (PHY_IPA(pi))
++			wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX,
++					       rfseq_rx2tx_events_rev3_ipa,
++					       rfseq_rx2tx_dlys_rev3_ipa,
++					       ARRAY_SIZE(rfseq_rx2tx_events_rev3_ipa));
++
++		mod_phy_reg(pi, 0x299, (0x3 << 14), (0x1 << 14));
++		mod_phy_reg(pi, 0x29d, (0x3 << 14), (0x1 << 14));
++
++		tx_lpf_bw_ofdm_20mhz = wlc_phy_read_lpf_bw_ctl_nphy(pi, 0x154);
++		tx_lpf_bw_ofdm_40mhz = wlc_phy_read_lpf_bw_ctl_nphy(pi, 0x159);
++		tx_lpf_bw_11b = wlc_phy_read_lpf_bw_ctl_nphy(pi, 0x152);
++
++		if (PHY_IPA(pi)) {
++
++			if (((pi->pubpi.radiorev == 5)
++			     && (CHSPEC_IS40(pi->radio_chanspec) == 1))
++			    || (pi->pubpi.radiorev == 7)
++			    || (pi->pubpi.radiorev == 8)) {
++
++				rccal_bcap_val =
++					read_radio_reg(
++						pi,
++						RADIO_2057_RCCAL_BCAP_VAL);
++				rccal_scap_val =
++					read_radio_reg(
++						pi,
++						RADIO_2057_RCCAL_SCAP_VAL);
++
++				rccal_tx20_11b_bcap = rccal_bcap_val;
++				rccal_tx20_11b_scap = rccal_scap_val;
++
++				if ((pi->pubpi.radiorev == 5) &&
++				    (CHSPEC_IS40(pi->radio_chanspec) == 1)) {
++
++					rccal_tx20_11n_bcap = rccal_bcap_val;
++					rccal_tx20_11n_scap = rccal_scap_val;
++					rccal_tx40_11n_bcap = 0xc;
++					rccal_tx40_11n_scap = 0xc;
++
++					rccal_ovrd = true;
++
++				} else if ((pi->pubpi.radiorev == 7)
++					   || (pi->pubpi.radiorev == 8)) {
++
++					tx_lpf_bw_ofdm_20mhz = 4;
++					tx_lpf_bw_11b = 1;
++
++					if (CHSPEC_IS2G(pi->radio_chanspec)) {
++						rccal_tx20_11n_bcap = 0xc;
++						rccal_tx20_11n_scap = 0xc;
++						rccal_tx40_11n_bcap = 0xa;
++						rccal_tx40_11n_scap = 0xa;
++					} else {
++						rccal_tx20_11n_bcap = 0x14;
++						rccal_tx20_11n_scap = 0x14;
++						rccal_tx40_11n_bcap = 0xf;
++						rccal_tx40_11n_scap = 0xf;
++					}
++
++					rccal_ovrd = true;
++				}
++			}
++
++		} else {
++
++			if (pi->pubpi.radiorev == 5) {
++
++				tx_lpf_bw_ofdm_20mhz = 1;
++				tx_lpf_bw_ofdm_40mhz = 3;
++
++				rccal_bcap_val =
++					read_radio_reg(
++						pi,
++						RADIO_2057_RCCAL_BCAP_VAL);
++				rccal_scap_val =
++					read_radio_reg(
++						pi,
++						RADIO_2057_RCCAL_SCAP_VAL);
++
++				rccal_tx20_11b_bcap = rccal_bcap_val;
++				rccal_tx20_11b_scap = rccal_scap_val;
++
++				rccal_tx20_11n_bcap = 0x13;
++				rccal_tx20_11n_scap = 0x11;
++				rccal_tx40_11n_bcap = 0x13;
++				rccal_tx40_11n_scap = 0x11;
++
++				rccal_ovrd = true;
++			}
++		}
++
++		if (rccal_ovrd) {
++
++			rx2tx_lpf_rc_lut_tx20_11b =
++				(rccal_tx20_11b_bcap << 8) |
++				(rccal_tx20_11b_scap << 3) |
++				tx_lpf_bw_11b;
++			rx2tx_lpf_rc_lut_tx20_11n =
++				(rccal_tx20_11n_bcap << 8) |
++				(rccal_tx20_11n_scap << 3) |
++				tx_lpf_bw_ofdm_20mhz;
++			rx2tx_lpf_rc_lut_tx40_11n =
++				(rccal_tx40_11n_bcap << 8) |
++				(rccal_tx40_11n_scap << 3) |
++				tx_lpf_bw_ofdm_40mhz;
++
++			for (coreNum = 0; coreNum <= 1; coreNum++) {
++				wlc_phy_table_write_nphy(
++					pi, NPHY_TBL_ID_RFSEQ,
++					1,
++					0x152 + coreNum * 0x10,
++					16,
++					&rx2tx_lpf_rc_lut_tx20_11b);
++				wlc_phy_table_write_nphy(
++					pi, NPHY_TBL_ID_RFSEQ,
++					1,
++					0x153 + coreNum * 0x10,
++					16,
++					&rx2tx_lpf_rc_lut_tx20_11n);
++				wlc_phy_table_write_nphy(
++					pi, NPHY_TBL_ID_RFSEQ,
++					1,
++					0x154 + coreNum * 0x10,
++					16,
++					&rx2tx_lpf_rc_lut_tx20_11n);
++				wlc_phy_table_write_nphy(
++					pi, NPHY_TBL_ID_RFSEQ,
++					1,
++					0x155 + coreNum * 0x10,
++					16,
++					&rx2tx_lpf_rc_lut_tx40_11n);
++				wlc_phy_table_write_nphy(
++					pi, NPHY_TBL_ID_RFSEQ,
++					1,
++					0x156 + coreNum * 0x10,
++					16,
++					&rx2tx_lpf_rc_lut_tx40_11n);
++				wlc_phy_table_write_nphy(
++					pi, NPHY_TBL_ID_RFSEQ,
++					1,
++					0x157 + coreNum * 0x10,
++					16,
++					&rx2tx_lpf_rc_lut_tx40_11n);
++				wlc_phy_table_write_nphy(
++					pi, NPHY_TBL_ID_RFSEQ,
++					1,
++					0x158 + coreNum * 0x10,
++					16,
++					&rx2tx_lpf_rc_lut_tx40_11n);
++				wlc_phy_table_write_nphy(
++					pi, NPHY_TBL_ID_RFSEQ,
++					1,
++					0x159 + coreNum * 0x10,
++					16,
++					&rx2tx_lpf_rc_lut_tx40_11n);
++			}
++
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 4),
++				1, 0x3, 0,
++				NPHY_REV7_RFCTRLOVERRIDE_ID2);
++		}
++
++		write_phy_reg(pi, 0x32f, 0x3);
++
++		if ((pi->pubpi.radiorev == 4) || (pi->pubpi.radiorev == 6))
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 2),
++				1, 0x3, 0,
++				NPHY_REV7_RFCTRLOVERRIDE_ID0);
++
++		if ((pi->pubpi.radiorev == 3) || (pi->pubpi.radiorev == 4) ||
++		    (pi->pubpi.radiorev == 6)) {
++			if ((pi->sh->sromrev >= 8)
++			    && (pi->sh->boardflags2 & BFL2_IPALVLSHIFT_3P3))
++				ipalvlshift_3p3_war_en = 1;
++
++			if (ipalvlshift_3p3_war_en) {
++				write_radio_reg(pi, RADIO_2057_GPAIO_CONFIG,
++						0x5);
++				write_radio_reg(pi, RADIO_2057_GPAIO_SEL1,
++						0x30);
++				write_radio_reg(pi, RADIO_2057_GPAIO_SEL0, 0x0);
++				or_radio_reg(pi,
++					     RADIO_2057_RXTXBIAS_CONFIG_CORE0,
++					     0x1);
++				or_radio_reg(pi,
++					     RADIO_2057_RXTXBIAS_CONFIG_CORE1,
++					     0x1);
++
++				ipa2g_mainbias = 0x1f;
++
++				ipa2g_casconv = 0x6f;
++
++				ipa2g_biasfilt = 0xaa;
++			} else {
++
++				ipa2g_mainbias = 0x2b;
++
++				ipa2g_casconv = 0x7f;
++
++				ipa2g_biasfilt = 0xee;
++			}
++
++			if (CHSPEC_IS2G(pi->radio_chanspec)) {
++				for (coreNum = 0; coreNum <= 1; coreNum++) {
++					WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
++							 coreNum, IPA2G_IMAIN,
++							 ipa2g_mainbias);
++					WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
++							 coreNum, IPA2G_CASCONV,
++							 ipa2g_casconv);
++					WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
++							 coreNum,
++							 IPA2G_BIAS_FILTER,
++							 ipa2g_biasfilt);
++				}
++			}
++		}
++
++		if (PHY_IPA(pi)) {
++			if (CHSPEC_IS2G(pi->radio_chanspec)) {
++				if ((pi->pubpi.radiorev == 3)
++				    || (pi->pubpi.radiorev == 4)
++				    || (pi->pubpi.radiorev == 6))
++					txgm_idac_bleed = 0x7f;
++
++				for (coreNum = 0; coreNum <= 1; coreNum++) {
++					if (txgm_idac_bleed != 0)
++						WRITE_RADIO_REG4(
++							pi, RADIO_2057,
++							CORE, coreNum,
++							TXGM_IDAC_BLEED,
++							txgm_idac_bleed);
++				}
++
++				if (pi->pubpi.radiorev == 5) {
++
++					for (coreNum = 0; coreNum <= 1;
++					     coreNum++) {
++						WRITE_RADIO_REG4(pi, RADIO_2057,
++								 CORE, coreNum,
++								 IPA2G_CASCONV,
++								 0x13);
++						WRITE_RADIO_REG4(pi, RADIO_2057,
++								 CORE, coreNum,
++								 IPA2G_IMAIN,
++								 0x1f);
++						WRITE_RADIO_REG4(
++							pi, RADIO_2057,
++							CORE, coreNum,
++							IPA2G_BIAS_FILTER,
++							0xee);
++						WRITE_RADIO_REG4(pi, RADIO_2057,
++								 CORE, coreNum,
++								 PAD2G_IDACS,
++								 0x8a);
++						WRITE_RADIO_REG4(
++							pi, RADIO_2057,
++							CORE, coreNum,
++							PAD_BIAS_FILTER_BWS,
++							0x3e);
++					}
++
++				} else if ((pi->pubpi.radiorev == 7)
++					   || (pi->pubpi.radiorev == 8)) {
++
++					if (CHSPEC_IS40(pi->radio_chanspec) ==
++					    0) {
++						WRITE_RADIO_REG4(pi, RADIO_2057,
++								 CORE, 0,
++								 IPA2G_IMAIN,
++								 0x14);
++						WRITE_RADIO_REG4(pi, RADIO_2057,
++								 CORE, 1,
++								 IPA2G_IMAIN,
++								 0x12);
++					} else {
++						WRITE_RADIO_REG4(pi, RADIO_2057,
++								 CORE, 0,
++								 IPA2G_IMAIN,
++								 0x16);
++						WRITE_RADIO_REG4(pi, RADIO_2057,
++								 CORE, 1,
++								 IPA2G_IMAIN,
++								 0x16);
++					}
++				}
++
++			} else {
++				freq = CHAN5G_FREQ(CHSPEC_CHANNEL(
++							pi->radio_chanspec));
++				if (((freq >= 5180) && (freq <= 5230))
++				    || ((freq >= 5745) && (freq <= 5805))) {
++					WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
++							 0, IPA5G_BIAS_FILTER,
++							 0xff);
++					WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
++							 1, IPA5G_BIAS_FILTER,
++							 0xff);
++				}
++			}
++		} else {
++
++			if (pi->pubpi.radiorev != 5) {
++				for (coreNum = 0; coreNum <= 1; coreNum++) {
++					WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
++							 coreNum,
++							 TXMIX2G_TUNE_BOOST_PU,
++							 0x61);
++					WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
++							 coreNum,
++							 TXGM_IDAC_BLEED, 0x70);
++				}
++			}
++		}
++
++		if (pi->pubpi.radiorev == 4) {
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1,
++						 0x05, 16,
++						 &afectrl_adc_ctrl1_rev7);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1,
++						 0x15, 16,
++						 &afectrl_adc_ctrl1_rev7);
++
++			for (coreNum = 0; coreNum <= 1; coreNum++) {
++				WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum,
++						 AFE_VCM_CAL_MASTER, 0x0);
++				WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum,
++						 AFE_SET_VCM_I, 0x3f);
++				WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum,
++						 AFE_SET_VCM_Q, 0x3f);
++			}
++		} else {
++			mod_phy_reg(pi, 0xa6, (0x1 << 2), (0x1 << 2));
++			mod_phy_reg(pi, 0x8f, (0x1 << 2), (0x1 << 2));
++			mod_phy_reg(pi, 0xa7, (0x1 << 2), (0x1 << 2));
++			mod_phy_reg(pi, 0xa5, (0x1 << 2), (0x1 << 2));
++
++			mod_phy_reg(pi, 0xa6, (0x1 << 0), 0);
++			mod_phy_reg(pi, 0x8f, (0x1 << 0), (0x1 << 0));
++			mod_phy_reg(pi, 0xa7, (0x1 << 0), 0);
++			mod_phy_reg(pi, 0xa5, (0x1 << 0), (0x1 << 0));
++
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1,
++						 0x05, 16,
++						 &afectrl_adc_ctrl2_rev7);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1,
++						 0x15, 16,
++						 &afectrl_adc_ctrl2_rev7);
++
++			mod_phy_reg(pi, 0xa6, (0x1 << 2), 0);
++			mod_phy_reg(pi, 0x8f, (0x1 << 2), 0);
++			mod_phy_reg(pi, 0xa7, (0x1 << 2), 0);
++			mod_phy_reg(pi, 0xa5, (0x1 << 2), 0);
++		}
++
++		write_phy_reg(pi, 0x6a, 0x2);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 256, 32,
++					 &min_nvar_offset_6mbps);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x138, 16,
++					 &rfseq_pktgn_lpf_hpc_rev7);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1, 0x141, 16,
++					 &rfseq_pktgn_lpf_h_hpc_rev7);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 3, 0x133, 16,
++					 &rfseq_htpktgn_lpf_hpc_rev7);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x146, 16,
++					 &rfseq_cckpktgn_lpf_hpc_rev7);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1, 0x123, 16,
++					 &rfseq_tx2rx_lpf_h_hpc_rev7);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1, 0x12A, 16,
++					 &rfseq_rx2tx_lpf_h_hpc_rev7);
++
++		if (CHSPEC_IS40(pi->radio_chanspec) == 0) {
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 3,
++						 32, &min_nvar_val);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
++						 127, 32, &min_nvar_val);
++		} else {
++			min_nvar_val = noise_var_tbl_rev7[3];
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 3,
++						 32, &min_nvar_val);
++
++			min_nvar_val = noise_var_tbl_rev7[127];
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
++						 127, 32, &min_nvar_val);
++		}
++
++		wlc_phy_workarounds_nphy_gainctrl(pi);
++
++		pdetrange =
++			(CHSPEC_IS5G(pi->radio_chanspec)) ? pi->srom_fem5g.
++			pdetrange : pi->srom_fem2g.pdetrange;
++
++		if (pdetrange == 0) {
++			chan_freq_range =
++				wlc_phy_get_chan_freq_range_nphy(pi, 0);
++			if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
++				aux_adc_vmid_rev7_core0[3] = 0x70;
++				aux_adc_vmid_rev7_core1[3] = 0x70;
++				aux_adc_gain_rev7[3] = 2;
++			} else {
++				aux_adc_vmid_rev7_core0[3] = 0x80;
++				aux_adc_vmid_rev7_core1[3] = 0x80;
++				aux_adc_gain_rev7[3] = 3;
++			}
++		} else if (pdetrange == 1) {
++			if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
++				aux_adc_vmid_rev7_core0[3] = 0x7c;
++				aux_adc_vmid_rev7_core1[3] = 0x7c;
++				aux_adc_gain_rev7[3] = 2;
++			} else {
++				aux_adc_vmid_rev7_core0[3] = 0x8c;
++				aux_adc_vmid_rev7_core1[3] = 0x8c;
++				aux_adc_gain_rev7[3] = 1;
++			}
++		} else if (pdetrange == 2) {
++			if (pi->pubpi.radioid == BCM2057_ID) {
++				if ((pi->pubpi.radiorev == 5)
++				    || (pi->pubpi.radiorev == 7)
++				    || (pi->pubpi.radiorev == 8)) {
++					if (chan_freq_range ==
++					    WL_CHAN_FREQ_RANGE_2G) {
++						aux_adc_vmid_rev7_core0[3] =
++							0x8c;
++						aux_adc_vmid_rev7_core1[3] =
++							0x8c;
++						aux_adc_gain_rev7[3] = 0;
++					} else {
++						aux_adc_vmid_rev7_core0[3] =
++							0x96;
++						aux_adc_vmid_rev7_core1[3] =
++							0x96;
++						aux_adc_gain_rev7[3] = 0;
++					}
++				}
++			}
++
++		} else if (pdetrange == 3) {
++			if (chan_freq_range == WL_CHAN_FREQ_RANGE_2G) {
++				aux_adc_vmid_rev7_core0[3] = 0x89;
++				aux_adc_vmid_rev7_core1[3] = 0x89;
++				aux_adc_gain_rev7[3] = 0;
++			}
++
++		} else if (pdetrange == 5) {
++
++			if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
++				aux_adc_vmid_rev7_core0[3] = 0x80;
++				aux_adc_vmid_rev7_core1[3] = 0x80;
++				aux_adc_gain_rev7[3] = 3;
++			} else {
++				aux_adc_vmid_rev7_core0[3] = 0x70;
++				aux_adc_vmid_rev7_core1[3] = 0x70;
++				aux_adc_gain_rev7[3] = 2;
++			}
++		}
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, 0x08, 16,
++					 &aux_adc_vmid_rev7_core0);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, 0x18, 16,
++					 &aux_adc_vmid_rev7_core1);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, 0x0c, 16,
++					 &aux_adc_gain_rev7);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, 0x1c, 16,
++					 &aux_adc_gain_rev7);
++
++	} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++
++		write_phy_reg(pi, 0x23f, 0x1f8);
++		write_phy_reg(pi, 0x240, 0x1f8);
++
++		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
++					1, 0, 32, &leg_data_weights);
++		leg_data_weights = leg_data_weights & 0xffffff;
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
++					 1, 0, 32, &leg_data_weights);
++
++		alpha0 = 293;
++		alpha1 = 435;
++		alpha2 = 261;
++		beta0 = 366;
++		beta1 = 205;
++		beta2 = 32;
++		write_phy_reg(pi, 0x145, alpha0);
++		write_phy_reg(pi, 0x146, alpha1);
++		write_phy_reg(pi, 0x147, alpha2);
++		write_phy_reg(pi, 0x148, beta0);
++		write_phy_reg(pi, 0x149, beta1);
++		write_phy_reg(pi, 0x14a, beta2);
++
++		write_phy_reg(pi, 0x38, 0xC);
++		write_phy_reg(pi, 0x2ae, 0xC);
++
++		wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_TX2RX,
++				       rfseq_tx2rx_events_rev3,
++				       rfseq_tx2rx_dlys_rev3,
++				       ARRAY_SIZE(rfseq_tx2rx_events_rev3));
++
++		if (PHY_IPA(pi))
++			wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX,
++					       rfseq_rx2tx_events_rev3_ipa,
++					       rfseq_rx2tx_dlys_rev3_ipa,
++					       ARRAY_SIZE(rfseq_rx2tx_events_rev3_ipa));
++
++		if ((pi->sh->hw_phyrxchain != 0x3) &&
++		    (pi->sh->hw_phyrxchain != pi->sh->hw_phytxchain)) {
++
++			if (PHY_IPA(pi)) {
++				rfseq_rx2tx_dlys_rev3[5] = 59;
++				rfseq_rx2tx_dlys_rev3[6] = 1;
++				rfseq_rx2tx_events_rev3[7] =
++					NPHY_REV3_RFSEQ_CMD_END;
++			}
++
++			wlc_phy_set_rfseq_nphy(
++				pi, NPHY_RFSEQ_RX2TX,
++				rfseq_rx2tx_events_rev3,
++				rfseq_rx2tx_dlys_rev3,
++				ARRAY_SIZE(rfseq_rx2tx_events_rev3));
++		}
++
++		if (CHSPEC_IS2G(pi->radio_chanspec))
++			write_phy_reg(pi, 0x6a, 0x2);
++		else
++			write_phy_reg(pi, 0x6a, 0x9c40);
++
++		mod_phy_reg(pi, 0x294, (0xf << 8), (7 << 8));
++
++		if (CHSPEC_IS40(pi->radio_chanspec) == 0) {
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 3,
++						 32, &min_nvar_val);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
++						 127, 32, &min_nvar_val);
++		} else {
++			min_nvar_val = noise_var_tbl_rev3[3];
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 3,
++						 32, &min_nvar_val);
++
++			min_nvar_val = noise_var_tbl_rev3[127];
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
++						 127, 32, &min_nvar_val);
++		}
++
++		wlc_phy_workarounds_nphy_gainctrl(pi);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x00, 16,
++					 &dac_control);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x10, 16,
++					 &dac_control);
++
++		pdetrange =
++			(CHSPEC_IS5G(pi->radio_chanspec)) ? pi->srom_fem5g.
++			pdetrange : pi->srom_fem2g.pdetrange;
++
++		if (pdetrange == 0) {
++			if (NREV_GE(pi->pubpi.phy_rev, 4)) {
++				aux_adc_vmid = aux_adc_vmid_rev4;
++				aux_adc_gain = aux_adc_gain_rev4;
++			} else {
++				aux_adc_vmid = aux_adc_vmid_rev3;
++				aux_adc_gain = aux_adc_gain_rev3;
++			}
++			chan_freq_range =
++				wlc_phy_get_chan_freq_range_nphy(pi, 0);
++			if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
++				switch (chan_freq_range) {
++				case WL_CHAN_FREQ_RANGE_5GL:
++					aux_adc_vmid[3] = 0x89;
++					aux_adc_gain[3] = 0;
++					break;
++				case WL_CHAN_FREQ_RANGE_5GM:
++					aux_adc_vmid[3] = 0x89;
++					aux_adc_gain[3] = 0;
++					break;
++				case WL_CHAN_FREQ_RANGE_5GH:
++					aux_adc_vmid[3] = 0x89;
++					aux_adc_gain[3] = 0;
++					break;
++				default:
++					break;
++				}
++			}
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
++						 0x08, 16, aux_adc_vmid);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
++						 0x18, 16, aux_adc_vmid);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
++						 0x0c, 16, aux_adc_gain);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
++						 0x1c, 16, aux_adc_gain);
++		} else if (pdetrange == 1) {
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
++						 0x08, 16, sk_adc_vmid);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
++						 0x18, 16, sk_adc_vmid);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
++						 0x0c, 16, sk_adc_gain);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
++						 0x1c, 16, sk_adc_gain);
++		} else if (pdetrange == 2) {
++
++			u16 bcm_adc_vmid[] = { 0xa2, 0xb4, 0xb4, 0x74 };
++			u16 bcm_adc_gain[] = { 0x02, 0x02, 0x02, 0x04 };
++
++			if (NREV_GE(pi->pubpi.phy_rev, 6)) {
++				chan_freq_range =
++					wlc_phy_get_chan_freq_range_nphy(pi, 0);
++				if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
++					bcm_adc_vmid[3] = 0x8e;
++					bcm_adc_gain[3] = 0x03;
++				} else {
++					bcm_adc_vmid[3] = 0x94;
++					bcm_adc_gain[3] = 0x03;
++				}
++			} else if (NREV_IS(pi->pubpi.phy_rev, 5)) {
++				bcm_adc_vmid[3] = 0x84;
++				bcm_adc_gain[3] = 0x02;
++			}
++
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
++						 0x08, 16, bcm_adc_vmid);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
++						 0x18, 16, bcm_adc_vmid);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
++						 0x0c, 16, bcm_adc_gain);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
++						 0x1c, 16, bcm_adc_gain);
++		} else if (pdetrange == 3) {
++			chan_freq_range =
++				wlc_phy_get_chan_freq_range_nphy(pi, 0);
++			if ((NREV_GE(pi->pubpi.phy_rev, 4))
++			    && (chan_freq_range == WL_CHAN_FREQ_RANGE_2G)) {
++
++				u16 auxadc_vmid[] = {
++					0xa2, 0xb4, 0xb4, 0x270
++				};
++				u16 auxadc_gain[] = {
++					0x02, 0x02, 0x02, 0x00
++				};
++
++				wlc_phy_table_write_nphy(pi,
++							 NPHY_TBL_ID_AFECTRL, 4,
++							 0x08, 16, auxadc_vmid);
++				wlc_phy_table_write_nphy(pi,
++							 NPHY_TBL_ID_AFECTRL, 4,
++							 0x18, 16, auxadc_vmid);
++				wlc_phy_table_write_nphy(pi,
++							 NPHY_TBL_ID_AFECTRL, 4,
++							 0x0c, 16, auxadc_gain);
++				wlc_phy_table_write_nphy(pi,
++							 NPHY_TBL_ID_AFECTRL, 4,
++							 0x1c, 16, auxadc_gain);
++			}
++		} else if ((pdetrange == 4) || (pdetrange == 5)) {
++			u16 bcm_adc_vmid[] = { 0xa2, 0xb4, 0xb4, 0x0 };
++			u16 bcm_adc_gain[] = { 0x02, 0x02, 0x02, 0x0 };
++			u16 Vmid[2], Av[2];
++
++			chan_freq_range =
++				wlc_phy_get_chan_freq_range_nphy(pi, 0);
++			if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
++				Vmid[0] = (pdetrange == 4) ? 0x8e : 0x89;
++				Vmid[1] = (pdetrange == 4) ? 0x96 : 0x89;
++				Av[0] = (pdetrange == 4) ? 2 : 0;
++				Av[1] = (pdetrange == 4) ? 2 : 0;
++			} else {
++				Vmid[0] = (pdetrange == 4) ? 0x89 : 0x74;
++				Vmid[1] = (pdetrange == 4) ? 0x8b : 0x70;
++				Av[0] = (pdetrange == 4) ? 2 : 0;
++				Av[1] = (pdetrange == 4) ? 2 : 0;
++			}
++
++			bcm_adc_vmid[3] = Vmid[0];
++			bcm_adc_gain[3] = Av[0];
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
++						 0x08, 16, bcm_adc_vmid);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
++						 0x0c, 16, bcm_adc_gain);
++
++			bcm_adc_vmid[3] = Vmid[1];
++			bcm_adc_gain[3] = Av[1];
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
++						 0x18, 16, bcm_adc_vmid);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
++						 0x1c, 16, bcm_adc_gain);
++		}
++
++		write_radio_reg(pi,
++				(RADIO_2056_RX_MIXA_MAST_BIAS | RADIO_2056_RX0),
++				0x0);
++		write_radio_reg(pi,
++				(RADIO_2056_RX_MIXA_MAST_BIAS | RADIO_2056_RX1),
++				0x0);
++
++		write_radio_reg(pi,
++				(RADIO_2056_RX_MIXA_BIAS_MAIN | RADIO_2056_RX0),
++				0x6);
++		write_radio_reg(pi,
++				(RADIO_2056_RX_MIXA_BIAS_MAIN | RADIO_2056_RX1),
++				0x6);
++
++		write_radio_reg(pi,
++				(RADIO_2056_RX_MIXA_BIAS_AUX | RADIO_2056_RX0),
++				0x7);
++		write_radio_reg(pi,
++				(RADIO_2056_RX_MIXA_BIAS_AUX | RADIO_2056_RX1),
++				0x7);
++
++		write_radio_reg(pi,
++				(RADIO_2056_RX_MIXA_LOB_BIAS | RADIO_2056_RX0),
++				0x88);
++		write_radio_reg(pi,
++				(RADIO_2056_RX_MIXA_LOB_BIAS | RADIO_2056_RX1),
++				0x88);
++
++		write_radio_reg(pi,
++				(RADIO_2056_RX_MIXA_CMFB_IDAC | RADIO_2056_RX0),
++				0x0);
++		write_radio_reg(pi,
++				(RADIO_2056_RX_MIXA_CMFB_IDAC | RADIO_2056_RX1),
++				0x0);
++
++		write_radio_reg(pi,
++				(RADIO_2056_RX_MIXG_CMFB_IDAC | RADIO_2056_RX0),
++				0x0);
++		write_radio_reg(pi,
++				(RADIO_2056_RX_MIXG_CMFB_IDAC | RADIO_2056_RX1),
++				0x0);
++
++		triso =
++			(CHSPEC_IS5G(pi->radio_chanspec)) ? pi->srom_fem5g.
++			triso : pi->srom_fem2g.triso;
++		if (triso == 7) {
++			wlc_phy_war_force_trsw_to_R_cliplo_nphy(pi, PHY_CORE_0);
++			wlc_phy_war_force_trsw_to_R_cliplo_nphy(pi, PHY_CORE_1);
++		}
++
++		wlc_phy_war_txchain_upd_nphy(pi, pi->sh->hw_phytxchain);
++
++		if (((pi->sh->boardflags2 & BFL2_APLL_WAR) &&
++		     (CHSPEC_IS5G(pi->radio_chanspec))) ||
++		    (((pi->sh->boardflags2 & BFL2_GPLL_WAR) ||
++		      (pi->sh->boardflags2 & BFL2_GPLL_WAR2)) &&
++		     (CHSPEC_IS2G(pi->radio_chanspec)))) {
++			nss1_data_weights = 0x00088888;
++			ht_data_weights = 0x00088888;
++			stbc_data_weights = 0x00088888;
++		} else {
++			nss1_data_weights = 0x88888888;
++			ht_data_weights = 0x88888888;
++			stbc_data_weights = 0x88888888;
++		}
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
++					 1, 1, 32, &nss1_data_weights);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
++					 1, 2, 32, &ht_data_weights);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
++					 1, 3, 32, &stbc_data_weights);
++
++		if (NREV_IS(pi->pubpi.phy_rev, 4)) {
++			if (CHSPEC_IS5G(pi->radio_chanspec)) {
++				write_radio_reg(pi,
++						RADIO_2056_TX_GMBB_IDAC |
++						RADIO_2056_TX0, 0x70);
++				write_radio_reg(pi,
++						RADIO_2056_TX_GMBB_IDAC |
++						RADIO_2056_TX1, 0x70);
++			}
++		}
++
++		if (!pi->edcrs_threshold_lock) {
++			write_phy_reg(pi, 0x224, 0x3eb);
++			write_phy_reg(pi, 0x225, 0x3eb);
++			write_phy_reg(pi, 0x226, 0x341);
++			write_phy_reg(pi, 0x227, 0x341);
++			write_phy_reg(pi, 0x228, 0x42b);
++			write_phy_reg(pi, 0x229, 0x42b);
++			write_phy_reg(pi, 0x22a, 0x381);
++			write_phy_reg(pi, 0x22b, 0x381);
++			write_phy_reg(pi, 0x22c, 0x42b);
++			write_phy_reg(pi, 0x22d, 0x42b);
++			write_phy_reg(pi, 0x22e, 0x381);
++			write_phy_reg(pi, 0x22f, 0x381);
++		}
++
++		if (NREV_GE(pi->pubpi.phy_rev, 6)) {
++
++			if (pi->sh->boardflags2 & BFL2_SINGLEANT_CCK)
++				wlapi_bmac_mhf(pi->sh->physhim, MHF4,
++					      MHF4_BPHY_TXCORE0,
++					      MHF4_BPHY_TXCORE0, BRCM_BAND_ALL);
++		}
++	} else {
++
++		if (pi->sh->boardflags2 & BFL2_SKWRKFEM_BRD ||
++		    (pi->sh->boardtype == 0x8b)) {
++			uint i;
++			u8 war_dlys[] = { 1, 6, 6, 2, 4, 20, 1 };
++			for (i = 0; i < ARRAY_SIZE(rfseq_rx2tx_dlys); i++)
++				rfseq_rx2tx_dlys[i] = war_dlys[i];
++		}
++
++		if (CHSPEC_IS5G(pi->radio_chanspec) && pi->phy_5g_pwrgain) {
++			and_radio_reg(pi, RADIO_2055_CORE1_TX_RF_SPARE, 0xf7);
++			and_radio_reg(pi, RADIO_2055_CORE2_TX_RF_SPARE, 0xf7);
++		} else {
++			or_radio_reg(pi, RADIO_2055_CORE1_TX_RF_SPARE, 0x8);
++			or_radio_reg(pi, RADIO_2055_CORE2_TX_RF_SPARE, 0x8);
++		}
++
++		regval = 0x000a;
++		wlc_phy_table_write_nphy(pi, 8, 1, 0, 16, &regval);
++		wlc_phy_table_write_nphy(pi, 8, 1, 0x10, 16, &regval);
++
++		if (NREV_LT(pi->pubpi.phy_rev, 3)) {
++			regval = 0xcdaa;
++			wlc_phy_table_write_nphy(pi, 8, 1, 0x02, 16, &regval);
++			wlc_phy_table_write_nphy(pi, 8, 1, 0x12, 16, &regval);
++		}
++
++		if (NREV_LT(pi->pubpi.phy_rev, 2)) {
++			regval = 0x0000;
++			wlc_phy_table_write_nphy(pi, 8, 1, 0x08, 16, &regval);
++			wlc_phy_table_write_nphy(pi, 8, 1, 0x18, 16, &regval);
++
++			regval = 0x7aab;
++			wlc_phy_table_write_nphy(pi, 8, 1, 0x07, 16, &regval);
++			wlc_phy_table_write_nphy(pi, 8, 1, 0x17, 16, &regval);
++
++			regval = 0x0800;
++			wlc_phy_table_write_nphy(pi, 8, 1, 0x06, 16, &regval);
++			wlc_phy_table_write_nphy(pi, 8, 1, 0x16, 16, &regval);
++		}
++
++		write_phy_reg(pi, 0xf8, 0x02d8);
++		write_phy_reg(pi, 0xf9, 0x0301);
++		write_phy_reg(pi, 0xfa, 0x02d8);
++		write_phy_reg(pi, 0xfb, 0x0301);
++
++		wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX, rfseq_rx2tx_events,
++				       rfseq_rx2tx_dlys,
++				       ARRAY_SIZE(rfseq_rx2tx_events));
++
++		wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_TX2RX, rfseq_tx2rx_events,
++				       rfseq_tx2rx_dlys,
++				       ARRAY_SIZE(rfseq_tx2rx_events));
++
++		wlc_phy_workarounds_nphy_gainctrl(pi);
++
++		if (NREV_LT(pi->pubpi.phy_rev, 2)) {
++
++			if (read_phy_reg(pi, 0xa0) & NPHY_MLenable)
++				wlapi_bmac_mhf(pi->sh->physhim, MHF3,
++					       MHF3_NPHY_MLADV_WAR,
++					       MHF3_NPHY_MLADV_WAR,
++					       BRCM_BAND_ALL);
++
++		} else if (NREV_IS(pi->pubpi.phy_rev, 2)) {
++			write_phy_reg(pi, 0x1e3, 0x0);
++			write_phy_reg(pi, 0x1e4, 0x0);
++		}
++
++		if (NREV_LT(pi->pubpi.phy_rev, 2))
++			mod_phy_reg(pi, 0x90, (0x1 << 7), 0);
++
++		alpha0 = 293;
++		alpha1 = 435;
++		alpha2 = 261;
++		beta0 = 366;
++		beta1 = 205;
++		beta2 = 32;
++		write_phy_reg(pi, 0x145, alpha0);
++		write_phy_reg(pi, 0x146, alpha1);
++		write_phy_reg(pi, 0x147, alpha2);
++		write_phy_reg(pi, 0x148, beta0);
++		write_phy_reg(pi, 0x149, beta1);
++		write_phy_reg(pi, 0x14a, beta2);
++
++		if (NREV_LT(pi->pubpi.phy_rev, 3)) {
++			mod_phy_reg(pi, 0x142, (0xf << 12), 0);
++
++			write_phy_reg(pi, 0x192, 0xb5);
++			write_phy_reg(pi, 0x193, 0xa4);
++			write_phy_reg(pi, 0x194, 0x0);
++		}
++
++		if (NREV_IS(pi->pubpi.phy_rev, 2))
++			mod_phy_reg(pi, 0x221,
++				    NPHY_FORCESIG_DECODEGATEDCLKS,
++				    NPHY_FORCESIG_DECODEGATEDCLKS);
++	}
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, false);
++}
++
++static void wlc_phy_extpa_set_tx_digi_filts_nphy(struct brcms_phy *pi)
++{
++	int j, type = 2;
++	u16 addr_offset = 0x2c5;
++
++	for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++)
++		write_phy_reg(pi, addr_offset + j,
++			      NPHY_IPA_REV4_txdigi_filtcoeffs[type][j]);
++}
++
++static void wlc_phy_clip_det_nphy(struct brcms_phy *pi, u8 write, u16 *vals)
++{
++
++	if (write == 0) {
++		vals[0] = read_phy_reg(pi, 0x2c);
++		vals[1] = read_phy_reg(pi, 0x42);
++	} else {
++		write_phy_reg(pi, 0x2c, vals[0]);
++		write_phy_reg(pi, 0x42, vals[1]);
++	}
++}
++
++static void wlc_phy_ipa_internal_tssi_setup_nphy(struct brcms_phy *pi)
++{
++	u8 core;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		for (core = 0; core < pi->pubpi.phy_corenum; core++) {
++			if (CHSPEC_IS2G(pi->radio_chanspec)) {
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TX_SSI_MASTER, 0x5);
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TX_SSI_MUX, 0xe);
++
++				if (pi->pubpi.radiorev != 5)
++					WRITE_RADIO_REG3(pi, RADIO_2057, TX,
++							 core, TSSIA, 0);
++
++				if (!NREV_IS(pi->pubpi.phy_rev, 7))
++					WRITE_RADIO_REG3(pi, RADIO_2057, TX,
++							 core, TSSIG, 0x1);
++				else
++					WRITE_RADIO_REG3(pi, RADIO_2057, TX,
++							 core, TSSIG, 0x31);
++			} else {
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TX_SSI_MASTER, 0x9);
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TX_SSI_MUX, 0xc);
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TSSIG, 0);
++
++				if (pi->pubpi.radiorev != 5) {
++					if (!NREV_IS(pi->pubpi.phy_rev, 7))
++						WRITE_RADIO_REG3(pi, RADIO_2057,
++								 TX, core,
++								 TSSIA, 0x1);
++					else
++						WRITE_RADIO_REG3(pi, RADIO_2057,
++								 TX, core,
++								 TSSIA, 0x31);
++				}
++			}
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, IQCAL_VCM_HG,
++					 0);
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, IQCAL_IDAC,
++					 0);
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSI_VCM,
++					 0x3);
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSI_MISC1,
++					 0x0);
++		}
++	} else {
++		WRITE_RADIO_SYN(pi, RADIO_2056, RESERVED_ADDR31,
++				(CHSPEC_IS2G(pi->radio_chanspec)) ? 0x128 :
++				0x80);
++		WRITE_RADIO_SYN(pi, RADIO_2056, RESERVED_ADDR30, 0x0);
++		WRITE_RADIO_SYN(pi, RADIO_2056, GPIO_MASTER1, 0x29);
++
++		for (core = 0; core < pi->pubpi.phy_corenum; core++) {
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, IQCAL_VCM_HG,
++					 0x0);
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, IQCAL_IDAC,
++					 0x0);
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TSSI_VCM,
++					 0x3);
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TX_AMP_DET,
++					 0x0);
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TSSI_MISC1,
++					 0x8);
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TSSI_MISC2,
++					 0x0);
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TSSI_MISC3,
++					 0x0);
++
++			if (CHSPEC_IS2G(pi->radio_chanspec)) {
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++						 TX_SSI_MASTER, 0x5);
++
++				if (pi->pubpi.radiorev != 5)
++					WRITE_RADIO_REG2(pi, RADIO_2056, TX,
++							 core, TSSIA, 0x0);
++				if (NREV_GE(pi->pubpi.phy_rev, 5))
++					WRITE_RADIO_REG2(pi, RADIO_2056, TX,
++							 core, TSSIG, 0x31);
++				else
++					WRITE_RADIO_REG2(pi, RADIO_2056, TX,
++							 core, TSSIG, 0x11);
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++						 TX_SSI_MUX, 0xe);
++			} else {
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++						 TX_SSI_MASTER, 0x9);
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++						 TSSIA, 0x31);
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++						 TSSIG, 0x0);
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++						 TX_SSI_MUX, 0xc);
++			}
++		}
++	}
++}
++
++static void
++wlc_phy_rfctrl_override_nphy(struct brcms_phy *pi, u16 field, u16 value,
++			     u8 core_mask, u8 off)
++{
++	u8 core_num;
++	u16 addr = 0, mask = 0, en_addr = 0, val_addr = 0, en_mask =
++		0, val_mask = 0;
++	u8 shift = 0, val_shift = 0;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 7)) {
++
++		en_mask = field;
++		for (core_num = 0; core_num < 2; core_num++) {
++
++			switch (field) {
++			case (0x1 << 1):
++				en_addr = (core_num == 0) ? 0xe7 : 0xec;
++				val_addr = (core_num == 0) ? 0x7a : 0x7d;
++				val_mask = (0x1 << 0);
++				val_shift = 0;
++				break;
++			case (0x1 << 2):
++				en_addr = (core_num == 0) ? 0xe7 : 0xec;
++				val_addr = (core_num == 0) ? 0x7a : 0x7d;
++				val_mask = (0x1 << 1);
++				val_shift = 1;
++				break;
++			case (0x1 << 3):
++				en_addr = (core_num == 0) ? 0xe7 : 0xec;
++				val_addr = (core_num == 0) ? 0x7a : 0x7d;
++				val_mask = (0x1 << 2);
++				val_shift = 2;
++				break;
++			case (0x1 << 4):
++				en_addr = (core_num == 0) ? 0xe7 : 0xec;
++				val_addr = (core_num == 0) ? 0x7a : 0x7d;
++				val_mask = (0x1 << 4);
++				val_shift = 4;
++				break;
++			case (0x1 << 5):
++				en_addr = (core_num == 0) ? 0xe7 : 0xec;
++				val_addr = (core_num == 0) ? 0x7a : 0x7d;
++				val_mask = (0x1 << 5);
++				val_shift = 5;
++				break;
++			case (0x1 << 6):
++				en_addr = (core_num == 0) ? 0xe7 : 0xec;
++				val_addr = (core_num == 0) ? 0x7a : 0x7d;
++				val_mask = (0x1 << 6);
++				val_shift = 6;
++				break;
++			case (0x1 << 7):
++				en_addr = (core_num == 0) ? 0xe7 : 0xec;
++				val_addr = (core_num == 0) ? 0x7a : 0x7d;
++				val_mask = (0x1 << 7);
++				val_shift = 7;
++				break;
++			case (0x1 << 8):
++				en_addr = (core_num == 0) ? 0xe7 : 0xec;
++				val_addr = (core_num == 0) ? 0x7a : 0x7d;
++				val_mask = (0x7 << 8);
++				val_shift = 8;
++				break;
++			case (0x1 << 11):
++				en_addr = (core_num == 0) ? 0xe7 : 0xec;
++				val_addr = (core_num == 0) ? 0x7a : 0x7d;
++				val_mask = (0x7 << 13);
++				val_shift = 13;
++				break;
++
++			case (0x1 << 9):
++				en_addr = (core_num == 0) ? 0xe7 : 0xec;
++				val_addr = (core_num == 0) ? 0xf8 : 0xfa;
++				val_mask = (0x7 << 0);
++				val_shift = 0;
++				break;
++
++			case (0x1 << 10):
++				en_addr = (core_num == 0) ? 0xe7 : 0xec;
++				val_addr = (core_num == 0) ? 0xf8 : 0xfa;
++				val_mask = (0x7 << 4);
++				val_shift = 4;
++				break;
++
++			case (0x1 << 12):
++				en_addr = (core_num == 0) ? 0xe7 : 0xec;
++				val_addr = (core_num == 0) ? 0x7b : 0x7e;
++				val_mask = (0xffff << 0);
++				val_shift = 0;
++				break;
++			case (0x1 << 13):
++				en_addr = (core_num == 0) ? 0xe7 : 0xec;
++				val_addr = (core_num == 0) ? 0x7c : 0x7f;
++				val_mask = (0xffff << 0);
++				val_shift = 0;
++				break;
++			case (0x1 << 14):
++				en_addr = (core_num == 0) ? 0xe7 : 0xec;
++				val_addr = (core_num == 0) ? 0xf9 : 0xfb;
++				val_mask = (0x3 << 6);
++				val_shift = 6;
++				break;
++			case (0x1 << 0):
++				en_addr = (core_num == 0) ? 0xe5 : 0xe6;
++				val_addr = (core_num == 0) ? 0xf9 : 0xfb;
++				val_mask = (0x1 << 15);
++				val_shift = 15;
++				break;
++			default:
++				addr = 0xffff;
++				break;
++			}
++
++			if (off) {
++				and_phy_reg(pi, en_addr, ~en_mask);
++				and_phy_reg(pi, val_addr, ~val_mask);
++			} else {
++
++				if ((core_mask == 0)
++				    || (core_mask & (1 << core_num))) {
++					or_phy_reg(pi, en_addr, en_mask);
++
++					if (addr != 0xffff)
++						mod_phy_reg(pi, val_addr,
++							    val_mask,
++							    (value <<
++							     val_shift));
++				}
++			}
++		}
++	} else {
++
++		if (off) {
++			and_phy_reg(pi, 0xec, ~field);
++			value = 0x0;
++		} else {
++			or_phy_reg(pi, 0xec, field);
++		}
++
++		for (core_num = 0; core_num < 2; core_num++) {
++
++			switch (field) {
++			case (0x1 << 1):
++			case (0x1 << 9):
++			case (0x1 << 12):
++			case (0x1 << 13):
++			case (0x1 << 14):
++				addr = 0x78;
++
++				core_mask = 0x1;
++				break;
++			case (0x1 << 2):
++			case (0x1 << 3):
++			case (0x1 << 4):
++			case (0x1 << 5):
++			case (0x1 << 6):
++			case (0x1 << 7):
++			case (0x1 << 8):
++				addr = (core_num == 0) ? 0x7a : 0x7d;
++				break;
++			case (0x1 << 10):
++				addr = (core_num == 0) ? 0x7b : 0x7e;
++				break;
++			case (0x1 << 11):
++				addr = (core_num == 0) ? 0x7c : 0x7f;
++				break;
++			default:
++				addr = 0xffff;
++			}
++
++			switch (field) {
++			case (0x1 << 1):
++				mask = (0x7 << 3);
++				shift = 3;
++				break;
++			case (0x1 << 9):
++				mask = (0x1 << 2);
++				shift = 2;
++				break;
++			case (0x1 << 12):
++				mask = (0x1 << 8);
++				shift = 8;
++				break;
++			case (0x1 << 13):
++				mask = (0x1 << 9);
++				shift = 9;
++				break;
++			case (0x1 << 14):
++				mask = (0xf << 12);
++				shift = 12;
++				break;
++			case (0x1 << 2):
++				mask = (0x1 << 0);
++				shift = 0;
++				break;
++			case (0x1 << 3):
++				mask = (0x1 << 1);
++				shift = 1;
++				break;
++			case (0x1 << 4):
++				mask = (0x1 << 2);
++				shift = 2;
++				break;
++			case (0x1 << 5):
++				mask = (0x3 << 4);
++				shift = 4;
++				break;
++			case (0x1 << 6):
++				mask = (0x3 << 6);
++				shift = 6;
++				break;
++			case (0x1 << 7):
++				mask = (0x1 << 8);
++				shift = 8;
++				break;
++			case (0x1 << 8):
++				mask = (0x1 << 9);
++				shift = 9;
++				break;
++			case (0x1 << 10):
++				mask = 0x1fff;
++				shift = 0x0;
++				break;
++			case (0x1 << 11):
++				mask = 0x1fff;
++				shift = 0x0;
++				break;
++			default:
++				mask = 0x0;
++				shift = 0x0;
++				break;
++			}
++
++			if ((addr != 0xffff) && (core_mask & (1 << core_num)))
++				mod_phy_reg(pi, addr, mask, (value << shift));
++		}
++
++		or_phy_reg(pi, 0xec, (0x1 << 0));
++		or_phy_reg(pi, 0x78, (0x1 << 0));
++		udelay(1);
++		and_phy_reg(pi, 0xec, ~(0x1 << 0));
++	}
++}
++
++static void wlc_phy_txpwrctrl_idle_tssi_nphy(struct brcms_phy *pi)
++{
++	s32 rssi_buf[4];
++	s32 int_val;
++
++	if (SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi) || PHY_MUTED(pi))
++
++		return;
++
++	if (PHY_IPA(pi))
++		wlc_phy_ipa_internal_tssi_setup_nphy(pi);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7))
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 12),
++						  0, 0x3, 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
++	else if (NREV_GE(pi->pubpi.phy_rev, 3))
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 13), 0, 3, 0);
++
++	wlc_phy_stopplayback_nphy(pi);
++
++	wlc_phy_tx_tone_nphy(pi, 4000, 0, 0, 0, false);
++
++	udelay(20);
++	int_val =
++		wlc_phy_poll_rssi_nphy(pi, (u8) NPHY_RSSI_SEL_TSSI_2G, rssi_buf,
++				       1);
++	wlc_phy_stopplayback_nphy(pi);
++	wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_OFF, 0);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7))
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 12),
++						  0, 0x3, 1,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
++	else if (NREV_GE(pi->pubpi.phy_rev, 3))
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 13), 0, 3, 1);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++
++		pi->nphy_pwrctrl_info[PHY_CORE_0].idle_tssi_2g =
++			(u8) ((int_val >> 24) & 0xff);
++		pi->nphy_pwrctrl_info[PHY_CORE_0].idle_tssi_5g =
++			(u8) ((int_val >> 24) & 0xff);
++
++		pi->nphy_pwrctrl_info[PHY_CORE_1].idle_tssi_2g =
++			(u8) ((int_val >> 8) & 0xff);
++		pi->nphy_pwrctrl_info[PHY_CORE_1].idle_tssi_5g =
++			(u8) ((int_val >> 8) & 0xff);
++	} else {
++		pi->nphy_pwrctrl_info[PHY_CORE_0].idle_tssi_2g =
++			(u8) ((int_val >> 24) & 0xff);
++
++		pi->nphy_pwrctrl_info[PHY_CORE_1].idle_tssi_2g =
++			(u8) ((int_val >> 8) & 0xff);
++
++		pi->nphy_pwrctrl_info[PHY_CORE_0].idle_tssi_5g =
++			(u8) ((int_val >> 16) & 0xff);
++		pi->nphy_pwrctrl_info[PHY_CORE_1].idle_tssi_5g =
++			(u8) ((int_val) & 0xff);
++	}
++
++}
++
++static void wlc_phy_txpwr_limit_to_tbl_nphy(struct brcms_phy *pi)
++{
++	u8 idx, idx2, i, delta_ind;
++
++	for (idx = TXP_FIRST_CCK; idx <= TXP_LAST_CCK; idx++)
++		pi->adj_pwr_tbl_nphy[idx] = pi->tx_power_offset[idx];
++
++	for (i = 0; i < 4; i++) {
++		idx2 = 0;
++
++		delta_ind = 0;
++
++		switch (i) {
++		case 0:
++
++			if (CHSPEC_IS40(pi->radio_chanspec)
++			    && NPHY_IS_SROM_REINTERPRET) {
++				idx = TXP_FIRST_MCS_40_SISO;
++			} else {
++				idx = (CHSPEC_IS40(pi->radio_chanspec)) ?
++				      TXP_FIRST_OFDM_40_SISO : TXP_FIRST_OFDM;
++				delta_ind = 1;
++			}
++			break;
++
++		case 1:
++
++			idx = (CHSPEC_IS40(pi->radio_chanspec)) ?
++			      TXP_FIRST_MCS_40_CDD : TXP_FIRST_MCS_20_CDD;
++			break;
++
++		case 2:
++
++			idx = (CHSPEC_IS40(pi->radio_chanspec)) ?
++			      TXP_FIRST_MCS_40_STBC : TXP_FIRST_MCS_20_STBC;
++			break;
++
++		case 3:
++
++			idx = (CHSPEC_IS40(pi->radio_chanspec)) ?
++			      TXP_FIRST_MCS_40_SDM : TXP_FIRST_MCS_20_SDM;
++			break;
++		}
++
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx];
++		idx = idx + delta_ind;
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx];
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx];
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx++];
++
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx++];
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx];
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx];
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx++];
++
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx++];
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx];
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx];
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx++];
++
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx];
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx++];
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx];
++		idx = idx + 1 - delta_ind;
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx];
++
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx];
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx];
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx];
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx];
++	}
++}
++
++static void wlc_phy_txpwrctrl_pwr_setup_nphy(struct brcms_phy *pi)
++{
++	u32 idx;
++	s16 a1[2], b0[2], b1[2];
++	s8 target_pwr_qtrdbm[2];
++	s32 num, den, pwr_est;
++	u8 chan_freq_range;
++	u8 idle_tssi[2];
++	u32 tbl_id, tbl_len, tbl_offset;
++	u32 regval[64];
++	u8 core;
++
++	if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12)) {
++		wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, MCTL_PHYLOCK);
++		(void)bcma_read32(pi->d11core, D11REGOFFS(maccontrol));
++		udelay(1);
++	}
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++	or_phy_reg(pi, 0x122, (0x1 << 0));
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3))
++		and_phy_reg(pi, 0x1e7, (u16) (~(0x1 << 15)));
++	else
++		or_phy_reg(pi, 0x1e7, (0x1 << 15));
++
++	if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12))
++		wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, 0);
++
++	if (pi->sh->sromrev < 4) {
++		idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_2g;
++		idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_2g;
++		a1[0] = -424;
++		a1[1] = -424;
++		b0[0] = 5612;
++		b0[1] = 5612;
++		b1[1] = -1393;
++		b1[0] = -1393;
++	} else {
++
++		chan_freq_range = wlc_phy_get_chan_freq_range_nphy(pi, 0);
++		switch (chan_freq_range) {
++		case WL_CHAN_FREQ_RANGE_2G:
++			idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_2g;
++			idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_2g;
++			a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_2g_a1;
++			a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_2g_a1;
++			b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_2g_b0;
++			b0[1] = pi->nphy_pwrctrl_info[1].pwrdet_2g_b0;
++			b1[0] = pi->nphy_pwrctrl_info[0].pwrdet_2g_b1;
++			b1[1] = pi->nphy_pwrctrl_info[1].pwrdet_2g_b1;
++			break;
++		case WL_CHAN_FREQ_RANGE_5GL:
++			idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_5g;
++			idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_5g;
++			a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gl_a1;
++			a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gl_a1;
++			b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gl_b0;
++			b0[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gl_b0;
++			b1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gl_b1;
++			b1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gl_b1;
++			break;
++		case WL_CHAN_FREQ_RANGE_5GM:
++			idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_5g;
++			idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_5g;
++			a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gm_a1;
++			a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gm_a1;
++			b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gm_b0;
++			b0[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gm_b0;
++			b1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gm_b1;
++			b1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gm_b1;
++			break;
++		case WL_CHAN_FREQ_RANGE_5GH:
++			idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_5g;
++			idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_5g;
++			a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gh_a1;
++			a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gh_a1;
++			b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gh_b0;
++			b0[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gh_b0;
++			b1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gh_b1;
++			b1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gh_b1;
++			break;
++		default:
++			idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_2g;
++			idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_2g;
++			a1[0] = -424;
++			a1[1] = -424;
++			b0[0] = 5612;
++			b0[1] = 5612;
++			b1[1] = -1393;
++			b1[0] = -1393;
++			break;
++		}
++	}
++
++	/* use the provided transmit power */
++	target_pwr_qtrdbm[0] = (s8) pi->tx_power_max;
++	target_pwr_qtrdbm[1] = (s8) pi->tx_power_max;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		if (pi->srom_fem2g.tssipos)
++			or_phy_reg(pi, 0x1e9, (0x1 << 14));
++
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			for (core = 0; core <= 1; core++) {
++				if (PHY_IPA(pi)) {
++					if (CHSPEC_IS2G(pi->radio_chanspec))
++						WRITE_RADIO_REG3(pi, RADIO_2057,
++								 TX, core,
++								 TX_SSI_MUX,
++								 0xe);
++					else
++						WRITE_RADIO_REG3(pi, RADIO_2057,
++								 TX, core,
++								 TX_SSI_MUX,
++								 0xc);
++				}
++			}
++		} else {
++			if (PHY_IPA(pi)) {
++
++				write_radio_reg(pi, RADIO_2056_TX_TX_SSI_MUX |
++						RADIO_2056_TX0,
++						(CHSPEC_IS5G
++						 (pi->radio_chanspec)) ?
++						 0xc : 0xe);
++				write_radio_reg(pi,
++						RADIO_2056_TX_TX_SSI_MUX |
++						RADIO_2056_TX1,
++						(CHSPEC_IS5G
++						 (pi->radio_chanspec)) ?
++						 0xc : 0xe);
++			} else {
++
++				write_radio_reg(pi, RADIO_2056_TX_TX_SSI_MUX |
++						RADIO_2056_TX0, 0x11);
++				write_radio_reg(pi, RADIO_2056_TX_TX_SSI_MUX |
++						RADIO_2056_TX1, 0x11);
++			}
++		}
++	}
++
++	if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12)) {
++		wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, MCTL_PHYLOCK);
++		(void)bcma_read32(pi->d11core, D11REGOFFS(maccontrol));
++		udelay(1);
++	}
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7))
++		mod_phy_reg(pi, 0x1e7, (0x7f << 0),
++			    (NPHY_TxPwrCtrlCmd_pwrIndex_init_rev7 << 0));
++	else
++		mod_phy_reg(pi, 0x1e7, (0x7f << 0),
++			    (NPHY_TxPwrCtrlCmd_pwrIndex_init << 0));
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7))
++		mod_phy_reg(pi, 0x222, (0xff << 0),
++			    (NPHY_TxPwrCtrlCmd_pwrIndex_init_rev7 << 0));
++	else if (NREV_GT(pi->pubpi.phy_rev, 1))
++		mod_phy_reg(pi, 0x222, (0xff << 0),
++			    (NPHY_TxPwrCtrlCmd_pwrIndex_init << 0));
++
++	if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12))
++		wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, 0);
++
++	write_phy_reg(pi, 0x1e8, (0x3 << 8) | (240 << 0));
++
++	write_phy_reg(pi, 0x1e9,
++		      (1 << 15) | (idle_tssi[0] << 0) | (idle_tssi[1] << 8));
++
++	write_phy_reg(pi, 0x1ea,
++		      (target_pwr_qtrdbm[0] << 0) |
++		      (target_pwr_qtrdbm[1] << 8));
++
++	tbl_len = 64;
++	tbl_offset = 0;
++	for (tbl_id = NPHY_TBL_ID_CORE1TXPWRCTL;
++	     tbl_id <= NPHY_TBL_ID_CORE2TXPWRCTL; tbl_id++) {
++
++		for (idx = 0; idx < tbl_len; idx++) {
++			num = 8 *
++			      (16 * b0[tbl_id - 26] + b1[tbl_id - 26] * idx);
++			den = 32768 + a1[tbl_id - 26] * idx;
++			pwr_est = max(((4 * num + den / 2) / den), -8);
++			if (NREV_LT(pi->pubpi.phy_rev, 3)) {
++				if (idx <=
++				    (uint) (31 - idle_tssi[tbl_id - 26] + 1))
++					pwr_est =
++						max(pwr_est,
++						    target_pwr_qtrdbm
++						    [tbl_id - 26] + 1);
++			}
++			regval[idx] = (u32) pwr_est;
++		}
++		wlc_phy_table_write_nphy(pi, tbl_id, tbl_len, tbl_offset, 32,
++					 regval);
++	}
++
++	wlc_phy_txpwr_limit_to_tbl_nphy(pi);
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE1TXPWRCTL, 84, 64, 8,
++				 pi->adj_pwr_tbl_nphy);
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE2TXPWRCTL, 84, 64, 8,
++				 pi->adj_pwr_tbl_nphy);
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, false);
++}
++
++static u32 *wlc_phy_get_ipa_gaintbl_nphy(struct brcms_phy *pi)
++{
++	u32 *tx_pwrctrl_tbl = NULL;
++
++	if (CHSPEC_IS2G(pi->radio_chanspec)) {
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			if ((pi->pubpi.radiorev == 4)
++			    || (pi->pubpi.radiorev == 6))
++				tx_pwrctrl_tbl =
++					nphy_tpc_txgain_ipa_2g_2057rev4n6;
++			else if (pi->pubpi.radiorev == 3)
++				tx_pwrctrl_tbl =
++					nphy_tpc_txgain_ipa_2g_2057rev3;
++			else if (pi->pubpi.radiorev == 5)
++				tx_pwrctrl_tbl =
++					nphy_tpc_txgain_ipa_2g_2057rev5;
++			else if ((pi->pubpi.radiorev == 7)
++				 || (pi->pubpi.radiorev == 8))
++				tx_pwrctrl_tbl =
++					nphy_tpc_txgain_ipa_2g_2057rev7;
++		} else if (NREV_IS(pi->pubpi.phy_rev, 6)) {
++			tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_rev6;
++		} else if (NREV_IS(pi->pubpi.phy_rev, 5)) {
++			tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_rev5;
++		} else {
++			tx_pwrctrl_tbl = nphy_tpc_txgain_ipa;
++		}
++	} else {
++
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			if ((pi->pubpi.radiorev == 3) ||
++			    (pi->pubpi.radiorev == 4) ||
++			    (pi->pubpi.radiorev == 6))
++				tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_5g_2057;
++			else if ((pi->pubpi.radiorev == 7)
++				 || (pi->pubpi.radiorev == 8))
++				tx_pwrctrl_tbl =
++					nphy_tpc_txgain_ipa_5g_2057rev7;
++		} else {
++			tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_5g;
++		}
++	}
++
++	return tx_pwrctrl_tbl;
++}
++
++static void wlc_phy_restore_rssical_nphy(struct brcms_phy *pi)
++{
++	if (CHSPEC_IS2G(pi->radio_chanspec)) {
++		if (pi->nphy_rssical_chanspec_2G == 0)
++			return;
++
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			mod_radio_reg(pi, RADIO_2057_NB_MASTER_CORE0,
++				      RADIO_2057_VCM_MASK,
++				      pi->rssical_cache.
++				      rssical_radio_regs_2G[0]);
++			mod_radio_reg(pi, RADIO_2057_NB_MASTER_CORE1,
++				      RADIO_2057_VCM_MASK,
++				      pi->rssical_cache.
++				      rssical_radio_regs_2G[1]);
++		} else {
++			mod_radio_reg(pi,
++				      RADIO_2056_RX_RSSI_MISC | RADIO_2056_RX0,
++				      RADIO_2056_VCM_MASK,
++				      pi->rssical_cache.
++				      rssical_radio_regs_2G[0]);
++			mod_radio_reg(pi,
++				      RADIO_2056_RX_RSSI_MISC | RADIO_2056_RX1,
++				      RADIO_2056_VCM_MASK,
++				      pi->rssical_cache.
++				      rssical_radio_regs_2G[1]);
++		}
++
++		write_phy_reg(pi, 0x1a6,
++			      pi->rssical_cache.rssical_phyregs_2G[0]);
++		write_phy_reg(pi, 0x1ac,
++			      pi->rssical_cache.rssical_phyregs_2G[1]);
++		write_phy_reg(pi, 0x1b2,
++			      pi->rssical_cache.rssical_phyregs_2G[2]);
++		write_phy_reg(pi, 0x1b8,
++			      pi->rssical_cache.rssical_phyregs_2G[3]);
++		write_phy_reg(pi, 0x1a4,
++			      pi->rssical_cache.rssical_phyregs_2G[4]);
++		write_phy_reg(pi, 0x1aa,
++			      pi->rssical_cache.rssical_phyregs_2G[5]);
++		write_phy_reg(pi, 0x1b0,
++			      pi->rssical_cache.rssical_phyregs_2G[6]);
++		write_phy_reg(pi, 0x1b6,
++			      pi->rssical_cache.rssical_phyregs_2G[7]);
++		write_phy_reg(pi, 0x1a5,
++			      pi->rssical_cache.rssical_phyregs_2G[8]);
++		write_phy_reg(pi, 0x1ab,
++			      pi->rssical_cache.rssical_phyregs_2G[9]);
++		write_phy_reg(pi, 0x1b1,
++			      pi->rssical_cache.rssical_phyregs_2G[10]);
++		write_phy_reg(pi, 0x1b7,
++			      pi->rssical_cache.rssical_phyregs_2G[11]);
++
++	} else {
++		if (pi->nphy_rssical_chanspec_5G == 0)
++			return;
++
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			mod_radio_reg(pi, RADIO_2057_NB_MASTER_CORE0,
++				      RADIO_2057_VCM_MASK,
++				      pi->rssical_cache.
++				      rssical_radio_regs_5G[0]);
++			mod_radio_reg(pi, RADIO_2057_NB_MASTER_CORE1,
++				      RADIO_2057_VCM_MASK,
++				      pi->rssical_cache.
++				      rssical_radio_regs_5G[1]);
++		} else {
++			mod_radio_reg(pi,
++				      RADIO_2056_RX_RSSI_MISC | RADIO_2056_RX0,
++				      RADIO_2056_VCM_MASK,
++				      pi->rssical_cache.
++				      rssical_radio_regs_5G[0]);
++			mod_radio_reg(pi,
++				      RADIO_2056_RX_RSSI_MISC | RADIO_2056_RX1,
++				      RADIO_2056_VCM_MASK,
++				      pi->rssical_cache.
++				      rssical_radio_regs_5G[1]);
++		}
++
++		write_phy_reg(pi, 0x1a6,
++			      pi->rssical_cache.rssical_phyregs_5G[0]);
++		write_phy_reg(pi, 0x1ac,
++			      pi->rssical_cache.rssical_phyregs_5G[1]);
++		write_phy_reg(pi, 0x1b2,
++			      pi->rssical_cache.rssical_phyregs_5G[2]);
++		write_phy_reg(pi, 0x1b8,
++			      pi->rssical_cache.rssical_phyregs_5G[3]);
++		write_phy_reg(pi, 0x1a4,
++			      pi->rssical_cache.rssical_phyregs_5G[4]);
++		write_phy_reg(pi, 0x1aa,
++			      pi->rssical_cache.rssical_phyregs_5G[5]);
++		write_phy_reg(pi, 0x1b0,
++			      pi->rssical_cache.rssical_phyregs_5G[6]);
++		write_phy_reg(pi, 0x1b6,
++			      pi->rssical_cache.rssical_phyregs_5G[7]);
++		write_phy_reg(pi, 0x1a5,
++			      pi->rssical_cache.rssical_phyregs_5G[8]);
++		write_phy_reg(pi, 0x1ab,
++			      pi->rssical_cache.rssical_phyregs_5G[9]);
++		write_phy_reg(pi, 0x1b1,
++			      pi->rssical_cache.rssical_phyregs_5G[10]);
++		write_phy_reg(pi, 0x1b7,
++			      pi->rssical_cache.rssical_phyregs_5G[11]);
++	}
++}
++
++static void wlc_phy_internal_cal_txgain_nphy(struct brcms_phy *pi)
++{
++	u16 txcal_gain[2];
++
++	pi->nphy_txcal_pwr_idx[0] = pi->nphy_cal_orig_pwr_idx[0];
++	pi->nphy_txcal_pwr_idx[1] = pi->nphy_cal_orig_pwr_idx[0];
++	wlc_phy_txpwr_index_nphy(pi, 1, pi->nphy_cal_orig_pwr_idx[0], true);
++	wlc_phy_txpwr_index_nphy(pi, 2, pi->nphy_cal_orig_pwr_idx[1], true);
++
++	wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16,
++				txcal_gain);
++
++	if (CHSPEC_IS2G(pi->radio_chanspec)) {
++		txcal_gain[0] = (txcal_gain[0] & 0xF000) | 0x0F40;
++		txcal_gain[1] = (txcal_gain[1] & 0xF000) | 0x0F40;
++	} else {
++		txcal_gain[0] = (txcal_gain[0] & 0xF000) | 0x0F60;
++		txcal_gain[1] = (txcal_gain[1] & 0xF000) | 0x0F60;
++	}
++
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16,
++				 txcal_gain);
++}
++
++static void wlc_phy_precal_txgain_nphy(struct brcms_phy *pi)
++{
++	bool save_bbmult = false;
++	u8 txcal_index_2057_rev5n7 = 0;
++	u8 txcal_index_2057_rev3n4n6 = 10;
++
++	if (pi->use_int_tx_iqlo_cal_nphy) {
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			if ((pi->pubpi.radiorev == 3) ||
++			    (pi->pubpi.radiorev == 4) ||
++			    (pi->pubpi.radiorev == 6)) {
++
++				pi->nphy_txcal_pwr_idx[0] =
++					txcal_index_2057_rev3n4n6;
++				pi->nphy_txcal_pwr_idx[1] =
++					txcal_index_2057_rev3n4n6;
++				wlc_phy_txpwr_index_nphy(
++					pi, 3,
++					txcal_index_2057_rev3n4n6,
++					false);
++			} else {
++
++				pi->nphy_txcal_pwr_idx[0] =
++					txcal_index_2057_rev5n7;
++				pi->nphy_txcal_pwr_idx[1] =
++					txcal_index_2057_rev5n7;
++				wlc_phy_txpwr_index_nphy(
++					pi, 3,
++					txcal_index_2057_rev5n7,
++					false);
++			}
++			save_bbmult = true;
++
++		} else if (NREV_LT(pi->pubpi.phy_rev, 5)) {
++			wlc_phy_cal_txgainctrl_nphy(pi, 11, false);
++			if (pi->sh->hw_phytxchain != 3) {
++				pi->nphy_txcal_pwr_idx[1] =
++					pi->nphy_txcal_pwr_idx[0];
++				wlc_phy_txpwr_index_nphy(pi, 3,
++							 pi->
++							 nphy_txcal_pwr_idx[0],
++							 true);
++				save_bbmult = true;
++			}
++
++		} else if (NREV_IS(pi->pubpi.phy_rev, 5)) {
++			if (PHY_IPA(pi)) {
++				if (CHSPEC_IS2G(pi->radio_chanspec)) {
++					wlc_phy_cal_txgainctrl_nphy(pi, 12,
++								    false);
++				} else {
++					pi->nphy_txcal_pwr_idx[0] = 80;
++					pi->nphy_txcal_pwr_idx[1] = 80;
++					wlc_phy_txpwr_index_nphy(pi, 3, 80,
++								 false);
++					save_bbmult = true;
++				}
++			} else {
++				wlc_phy_internal_cal_txgain_nphy(pi);
++				save_bbmult = true;
++			}
++
++		} else if (NREV_IS(pi->pubpi.phy_rev, 6)) {
++			if (PHY_IPA(pi)) {
++				if (CHSPEC_IS2G(pi->radio_chanspec))
++					wlc_phy_cal_txgainctrl_nphy(pi, 12,
++								    false);
++				else
++					wlc_phy_cal_txgainctrl_nphy(pi, 14,
++								    false);
++			} else {
++				wlc_phy_internal_cal_txgain_nphy(pi);
++				save_bbmult = true;
++			}
++		}
++
++	} else {
++		wlc_phy_cal_txgainctrl_nphy(pi, 10, false);
++	}
++
++	if (save_bbmult)
++		wlc_phy_table_read_nphy(pi, 15, 1, 87, 16,
++					&pi->nphy_txcal_bbmult);
++}
++
++static void
++wlc_phy_rfctrlintc_override_nphy(struct brcms_phy *pi, u8 field, u16 value,
++				 u8 core_code)
++{
++	u16 mask;
++	u16 val;
++	u8 core;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		for (core = 0; core < pi->pubpi.phy_corenum; core++) {
++			if (core_code == RADIO_MIMO_CORESEL_CORE1
++			    && core == PHY_CORE_1)
++				continue;
++			else if (core_code == RADIO_MIMO_CORESEL_CORE2
++				 && core == PHY_CORE_0)
++				continue;
++
++			if (NREV_LT(pi->pubpi.phy_rev, 7)) {
++
++				mask = (0x1 << 10);
++				val = 1 << 10;
++				mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x91 :
++					    0x92, mask, val);
++			}
++
++			if (field == NPHY_RfctrlIntc_override_OFF) {
++
++				write_phy_reg(pi, (core == PHY_CORE_0) ? 0x91 :
++					      0x92, 0);
++
++				wlc_phy_force_rfseq_nphy(pi,
++							 NPHY_RFSEQ_RESET2RX);
++			} else if (field == NPHY_RfctrlIntc_override_TRSW) {
++
++				if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++
++					mask = (0x1 << 6) | (0x1 << 7);
++
++					val = value << 6;
++					mod_phy_reg(pi,
++						    (core ==
++						     PHY_CORE_0) ? 0x91 : 0x92,
++						    mask, val);
++
++					or_phy_reg(pi,
++						   (core ==
++						    PHY_CORE_0) ? 0x91 : 0x92,
++						   (0x1 << 10));
++
++					and_phy_reg(pi, 0x2ff, (u16)
++						    ~(0x3 << 14));
++					or_phy_reg(pi, 0x2ff, (0x1 << 13));
++					or_phy_reg(pi, 0x2ff, (0x1 << 0));
++				} else {
++
++					mask = (0x1 << 6) |
++					       (0x1 << 7) |
++					       (0x1 << 8) | (0x1 << 9);
++					val = value << 6;
++					mod_phy_reg(pi,
++						    (core ==
++						     PHY_CORE_0) ? 0x91 : 0x92,
++						    mask, val);
++
++					mask = (0x1 << 0);
++					val = 1 << 0;
++					mod_phy_reg(pi,
++						    (core ==
++						     PHY_CORE_0) ? 0xe7 : 0xec,
++						    mask, val);
++
++					mask = (core == PHY_CORE_0) ?
++					       (0x1 << 0) : (0x1 << 1);
++					val = 1 << ((core == PHY_CORE_0) ?
++						    0 : 1);
++					mod_phy_reg(pi, 0x78, mask, val);
++
++					SPINWAIT(((read_phy_reg(pi, 0x78) & val)
++						  != 0), 10000);
++					if (WARN(read_phy_reg(pi, 0x78) & val,
++						 "HW error: override failed"))
++						return;
++
++					mask = (0x1 << 0);
++					val = 0 << 0;
++					mod_phy_reg(pi,
++						    (core ==
++						     PHY_CORE_0) ? 0xe7 : 0xec,
++						    mask, val);
++				}
++			} else if (field == NPHY_RfctrlIntc_override_PA) {
++				if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++
++					mask = (0x1 << 4) | (0x1 << 5);
++
++					if (CHSPEC_IS5G(pi->radio_chanspec))
++						val = value << 5;
++					else
++						val = value << 4;
++
++					mod_phy_reg(pi,
++						    (core ==
++						     PHY_CORE_0) ? 0x91 : 0x92,
++						    mask, val);
++
++					or_phy_reg(pi,
++						   (core ==
++						    PHY_CORE_0) ? 0x91 : 0x92,
++						   (0x1 << 12));
++				} else {
++
++					if (CHSPEC_IS5G(pi->radio_chanspec)) {
++						mask = (0x1 << 5);
++						val = value << 5;
++					} else {
++						mask = (0x1 << 4);
++						val = value << 4;
++					}
++					mod_phy_reg(pi,
++						    (core ==
++						     PHY_CORE_0) ? 0x91 : 0x92,
++						    mask, val);
++				}
++			} else if (field ==
++				   NPHY_RfctrlIntc_override_EXT_LNA_PU) {
++				if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++					if (CHSPEC_IS5G(pi->radio_chanspec)) {
++
++						mask = (0x1 << 0);
++						val = value << 0;
++						mod_phy_reg(pi,
++							    (core ==
++							     PHY_CORE_0) ? 0x91
++							    : 0x92, mask, val);
++
++						mask = (0x1 << 2);
++						mod_phy_reg(pi,
++							    (core ==
++							     PHY_CORE_0) ? 0x91
++							    : 0x92, mask, 0);
++					} else {
++
++						mask = (0x1 << 2);
++						val = value << 2;
++						mod_phy_reg(pi,
++							    (core ==
++							     PHY_CORE_0) ? 0x91
++							    : 0x92, mask, val);
++
++						mask = (0x1 << 0);
++						mod_phy_reg(pi,
++							    (core ==
++							     PHY_CORE_0) ? 0x91
++							    : 0x92, mask, 0);
++					}
++
++					mask = (0x1 << 11);
++					val = 1 << 11;
++					mod_phy_reg(pi,
++						    (core ==
++						     PHY_CORE_0) ? 0x91 : 0x92,
++						    mask, val);
++				} else {
++
++					if (CHSPEC_IS5G(pi->radio_chanspec)) {
++						mask = (0x1 << 0);
++						val = value << 0;
++					} else {
++						mask = (0x1 << 2);
++						val = value << 2;
++					}
++					mod_phy_reg(pi,
++						    (core ==
++						     PHY_CORE_0) ? 0x91 : 0x92,
++						    mask, val);
++				}
++			} else if (field ==
++				   NPHY_RfctrlIntc_override_EXT_LNA_GAIN) {
++				if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++					if (CHSPEC_IS5G(pi->radio_chanspec)) {
++
++						mask = (0x1 << 1);
++						val = value << 1;
++						mod_phy_reg(pi,
++							    (core ==
++							     PHY_CORE_0) ? 0x91
++							    : 0x92, mask, val);
++
++						mask = (0x1 << 3);
++						mod_phy_reg(pi,
++							    (core ==
++							     PHY_CORE_0) ? 0x91
++							    : 0x92, mask, 0);
++					} else {
++
++						mask = (0x1 << 3);
++						val = value << 3;
++						mod_phy_reg(pi,
++							    (core ==
++							     PHY_CORE_0) ? 0x91
++							    : 0x92, mask, val);
++
++						mask = (0x1 << 1);
++						mod_phy_reg(pi,
++							    (core ==
++							     PHY_CORE_0) ? 0x91
++							    : 0x92, mask, 0);
++					}
++
++					mask = (0x1 << 11);
++					val = 1 << 11;
++					mod_phy_reg(pi,
++						    (core ==
++						     PHY_CORE_0) ? 0x91 : 0x92,
++						    mask, val);
++				} else {
++
++					if (CHSPEC_IS5G(pi->radio_chanspec)) {
++						mask = (0x1 << 1);
++						val = value << 1;
++					} else {
++						mask = (0x1 << 3);
++						val = value << 3;
++					}
++					mod_phy_reg(pi,
++						    (core ==
++						     PHY_CORE_0) ? 0x91 : 0x92,
++						    mask, val);
++				}
++			}
++		}
++	}
++}
++
++void
++wlc_phy_cal_txgainctrl_nphy(struct brcms_phy *pi, s32 dBm_targetpower,
++			    bool debug)
++{
++	int gainctrl_loopidx;
++	uint core;
++	u16 m0m1, curr_m0m1;
++	s32 delta_power;
++	s32 txpwrindex;
++	s32 qdBm_power[2];
++	u16 orig_BBConfig;
++	u16 phy_saveregs[4];
++	u32 freq_test;
++	u16 ampl_test = 250;
++	uint stepsize;
++	bool phyhang_avoid_state = false;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7))
++		stepsize = 2;
++	else
++		stepsize = 1;
++
++	if (CHSPEC_IS40(pi->radio_chanspec))
++		freq_test = 5000;
++	else
++		freq_test = 2500;
++
++	wlc_phy_txpwr_index_nphy(pi, 1, pi->nphy_cal_orig_pwr_idx[0], true);
++	wlc_phy_txpwr_index_nphy(pi, 2, pi->nphy_cal_orig_pwr_idx[1], true);
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++	phyhang_avoid_state = pi->phyhang_avoid;
++	pi->phyhang_avoid = false;
++
++	phy_saveregs[0] = read_phy_reg(pi, 0x91);
++	phy_saveregs[1] = read_phy_reg(pi, 0x92);
++	phy_saveregs[2] = read_phy_reg(pi, 0xe7);
++	phy_saveregs[3] = read_phy_reg(pi, 0xec);
++	wlc_phy_rfctrlintc_override_nphy(pi, NPHY_RfctrlIntc_override_PA, 1,
++					 RADIO_MIMO_CORESEL_CORE1 |
++					 RADIO_MIMO_CORESEL_CORE2);
++
++	if (!debug) {
++		wlc_phy_rfctrlintc_override_nphy(pi,
++						 NPHY_RfctrlIntc_override_TRSW,
++						 0x2, RADIO_MIMO_CORESEL_CORE1);
++		wlc_phy_rfctrlintc_override_nphy(pi,
++						 NPHY_RfctrlIntc_override_TRSW,
++						 0x8, RADIO_MIMO_CORESEL_CORE2);
++	} else {
++		wlc_phy_rfctrlintc_override_nphy(pi,
++						 NPHY_RfctrlIntc_override_TRSW,
++						 0x1, RADIO_MIMO_CORESEL_CORE1);
++		wlc_phy_rfctrlintc_override_nphy(pi,
++						 NPHY_RfctrlIntc_override_TRSW,
++						 0x7, RADIO_MIMO_CORESEL_CORE2);
++	}
++
++	orig_BBConfig = read_phy_reg(pi, 0x01);
++	mod_phy_reg(pi, 0x01, (0x1 << 15), 0);
++
++	wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &m0m1);
++
++	for (core = 0; core < pi->pubpi.phy_corenum; core++) {
++		txpwrindex = (s32) pi->nphy_cal_orig_pwr_idx[core];
++
++		for (gainctrl_loopidx = 0; gainctrl_loopidx < 2;
++		     gainctrl_loopidx++) {
++			wlc_phy_tx_tone_nphy(pi, freq_test, ampl_test, 0, 0,
++					     false);
++
++			if (core == PHY_CORE_0)
++				curr_m0m1 = m0m1 & 0xff00;
++			else
++				curr_m0m1 = m0m1 & 0x00ff;
++
++			wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &curr_m0m1);
++			wlc_phy_table_write_nphy(pi, 15, 1, 95, 16, &curr_m0m1);
++
++			udelay(50);
++
++			wlc_phy_est_tonepwr_nphy(pi, qdBm_power,
++						 NPHY_CAL_TSSISAMPS);
++
++			pi->nphy_bb_mult_save = 0;
++			wlc_phy_stopplayback_nphy(pi);
++
++			delta_power = (dBm_targetpower * 4) - qdBm_power[core];
++
++			txpwrindex -= stepsize * delta_power;
++			if (txpwrindex < 0)
++				txpwrindex = 0;
++			else if (txpwrindex > 127)
++				txpwrindex = 127;
++
++			if (CHSPEC_IS5G(pi->radio_chanspec)) {
++				if (NREV_IS(pi->pubpi.phy_rev, 4) &&
++				    (pi->srom_fem5g.extpagain == 3)) {
++					if (txpwrindex < 30)
++						txpwrindex = 30;
++				}
++			} else {
++				if (NREV_GE(pi->pubpi.phy_rev, 5) &&
++				    (pi->srom_fem2g.extpagain == 3)) {
++					if (txpwrindex < 50)
++						txpwrindex = 50;
++				}
++			}
++
++			wlc_phy_txpwr_index_nphy(pi, (1 << core),
++						 (u8) txpwrindex, true);
++		}
++
++		pi->nphy_txcal_pwr_idx[core] = (u8) txpwrindex;
++
++		if (debug) {
++			u16 radio_gain;
++			u16 dbg_m0m1;
++
++			wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &dbg_m0m1);
++
++			wlc_phy_tx_tone_nphy(pi, freq_test, ampl_test, 0, 0,
++					     false);
++
++			wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &dbg_m0m1);
++			wlc_phy_table_write_nphy(pi, 15, 1, 95, 16, &dbg_m0m1);
++
++			udelay(100);
++
++			wlc_phy_est_tonepwr_nphy(pi, qdBm_power,
++						 NPHY_CAL_TSSISAMPS);
++
++			wlc_phy_table_read_nphy(pi, 7, 1, (0x110 + core), 16,
++						&radio_gain);
++
++			mdelay(4000);
++			pi->nphy_bb_mult_save = 0;
++			wlc_phy_stopplayback_nphy(pi);
++		}
++	}
++
++	wlc_phy_txpwr_index_nphy(pi, 1, pi->nphy_txcal_pwr_idx[0], true);
++	wlc_phy_txpwr_index_nphy(pi, 2, pi->nphy_txcal_pwr_idx[1], true);
++
++	wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &pi->nphy_txcal_bbmult);
++
++	write_phy_reg(pi, 0x01, orig_BBConfig);
++
++	write_phy_reg(pi, 0x91, phy_saveregs[0]);
++	write_phy_reg(pi, 0x92, phy_saveregs[1]);
++	write_phy_reg(pi, 0xe7, phy_saveregs[2]);
++	write_phy_reg(pi, 0xec, phy_saveregs[3]);
++
++	pi->phyhang_avoid = phyhang_avoid_state;
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, false);
++}
++
++static void wlc_phy_savecal_nphy(struct brcms_phy *pi)
++{
++	void *tbl_ptr;
++	int coreNum;
++	u16 *txcal_radio_regs = NULL;
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++	if (CHSPEC_IS2G(pi->radio_chanspec)) {
++
++		wlc_phy_rx_iq_coeffs_nphy(pi, 0,
++					  &pi->calibration_cache.
++					  rxcal_coeffs_2G);
++
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			txcal_radio_regs =
++				pi->calibration_cache.txcal_radio_regs_2G;
++		} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++
++			pi->calibration_cache.txcal_radio_regs_2G[0] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_LOFT_FINE_I |
++					       RADIO_2056_TX0);
++			pi->calibration_cache.txcal_radio_regs_2G[1] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_LOFT_FINE_Q |
++					       RADIO_2056_TX0);
++			pi->calibration_cache.txcal_radio_regs_2G[2] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_LOFT_FINE_I |
++					       RADIO_2056_TX1);
++			pi->calibration_cache.txcal_radio_regs_2G[3] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_LOFT_FINE_Q |
++					       RADIO_2056_TX1);
++
++			pi->calibration_cache.txcal_radio_regs_2G[4] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_LOFT_COARSE_I |
++					       RADIO_2056_TX0);
++			pi->calibration_cache.txcal_radio_regs_2G[5] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_LOFT_COARSE_Q |
++					       RADIO_2056_TX0);
++			pi->calibration_cache.txcal_radio_regs_2G[6] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_LOFT_COARSE_I |
++					       RADIO_2056_TX1);
++			pi->calibration_cache.txcal_radio_regs_2G[7] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_LOFT_COARSE_Q |
++					       RADIO_2056_TX1);
++		} else {
++			pi->calibration_cache.txcal_radio_regs_2G[0] =
++			       read_radio_reg(pi, RADIO_2055_CORE1_TX_VOS_CNCL);
++			pi->calibration_cache.txcal_radio_regs_2G[1] =
++			       read_radio_reg(pi, RADIO_2055_CORE2_TX_VOS_CNCL);
++			pi->calibration_cache.txcal_radio_regs_2G[2] =
++			       read_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM);
++			pi->calibration_cache.txcal_radio_regs_2G[3] =
++			       read_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM);
++		}
++
++		pi->nphy_iqcal_chanspec_2G = pi->radio_chanspec;
++		tbl_ptr = pi->calibration_cache.txcal_coeffs_2G;
++	} else {
++
++		wlc_phy_rx_iq_coeffs_nphy(pi, 0,
++					  &pi->calibration_cache.
++					  rxcal_coeffs_5G);
++
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			txcal_radio_regs =
++				pi->calibration_cache.txcal_radio_regs_5G;
++		} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++
++			pi->calibration_cache.txcal_radio_regs_5G[0] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_LOFT_FINE_I |
++					       RADIO_2056_TX0);
++			pi->calibration_cache.txcal_radio_regs_5G[1] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_LOFT_FINE_Q |
++					       RADIO_2056_TX0);
++			pi->calibration_cache.txcal_radio_regs_5G[2] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_LOFT_FINE_I |
++					       RADIO_2056_TX1);
++			pi->calibration_cache.txcal_radio_regs_5G[3] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_LOFT_FINE_Q |
++					       RADIO_2056_TX1);
++
++			pi->calibration_cache.txcal_radio_regs_5G[4] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_LOFT_COARSE_I |
++					       RADIO_2056_TX0);
++			pi->calibration_cache.txcal_radio_regs_5G[5] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_LOFT_COARSE_Q |
++					       RADIO_2056_TX0);
++			pi->calibration_cache.txcal_radio_regs_5G[6] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_LOFT_COARSE_I |
++					       RADIO_2056_TX1);
++			pi->calibration_cache.txcal_radio_regs_5G[7] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_LOFT_COARSE_Q |
++					       RADIO_2056_TX1);
++		} else {
++			pi->calibration_cache.txcal_radio_regs_5G[0] =
++			       read_radio_reg(pi, RADIO_2055_CORE1_TX_VOS_CNCL);
++			pi->calibration_cache.txcal_radio_regs_5G[1] =
++			       read_radio_reg(pi, RADIO_2055_CORE2_TX_VOS_CNCL);
++			pi->calibration_cache.txcal_radio_regs_5G[2] =
++			       read_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM);
++			pi->calibration_cache.txcal_radio_regs_5G[3] =
++			       read_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM);
++		}
++
++		pi->nphy_iqcal_chanspec_5G = pi->radio_chanspec;
++		tbl_ptr = pi->calibration_cache.txcal_coeffs_5G;
++	}
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		for (coreNum = 0; coreNum <= 1; coreNum++) {
++
++			txcal_radio_regs[2 * coreNum] =
++				READ_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
++						LOFT_FINE_I);
++			txcal_radio_regs[2 * coreNum + 1] =
++				READ_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
++						LOFT_FINE_Q);
++
++			txcal_radio_regs[2 * coreNum + 4] =
++				READ_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
++						LOFT_COARSE_I);
++			txcal_radio_regs[2 * coreNum + 5] =
++				READ_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
++						LOFT_COARSE_Q);
++		}
++	}
++
++	wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL, 8, 80, 16, tbl_ptr);
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, false);
++}
++
++static void wlc_phy_tx_iq_war_nphy(struct brcms_phy *pi)
++{
++	struct nphy_iq_comp tx_comp;
++
++	wlc_phy_table_read_nphy(pi, 15, 4, 0x50, 16, &tx_comp);
++
++	wlapi_bmac_write_shm(pi->sh->physhim, M_20IN40_IQ, tx_comp.a0);
++	wlapi_bmac_write_shm(pi->sh->physhim, M_20IN40_IQ + 2, tx_comp.b0);
++	wlapi_bmac_write_shm(pi->sh->physhim, M_20IN40_IQ + 4, tx_comp.a1);
++	wlapi_bmac_write_shm(pi->sh->physhim, M_20IN40_IQ + 6, tx_comp.b1);
++}
++
++static void wlc_phy_restorecal_nphy(struct brcms_phy *pi)
++{
++	u16 *loft_comp;
++	u16 txcal_coeffs_bphy[4];
++	u16 *tbl_ptr;
++	int coreNum;
++	u16 *txcal_radio_regs = NULL;
++
++	if (CHSPEC_IS2G(pi->radio_chanspec)) {
++		if (pi->nphy_iqcal_chanspec_2G == 0)
++			return;
++
++		tbl_ptr = pi->calibration_cache.txcal_coeffs_2G;
++		loft_comp = &pi->calibration_cache.txcal_coeffs_2G[5];
++	} else {
++		if (pi->nphy_iqcal_chanspec_5G == 0)
++			return;
++
++		tbl_ptr = pi->calibration_cache.txcal_coeffs_5G;
++		loft_comp = &pi->calibration_cache.txcal_coeffs_5G[5];
++	}
++
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 80, 16, tbl_ptr);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		txcal_coeffs_bphy[0] = tbl_ptr[0];
++		txcal_coeffs_bphy[1] = tbl_ptr[1];
++		txcal_coeffs_bphy[2] = tbl_ptr[2];
++		txcal_coeffs_bphy[3] = tbl_ptr[3];
++	} else {
++		txcal_coeffs_bphy[0] = 0;
++		txcal_coeffs_bphy[1] = 0;
++		txcal_coeffs_bphy[2] = 0;
++		txcal_coeffs_bphy[3] = 0;
++	}
++
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 88, 16,
++				 txcal_coeffs_bphy);
++
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 85, 16, loft_comp);
++
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 93, 16, loft_comp);
++
++	if (NREV_LT(pi->pubpi.phy_rev, 2))
++		wlc_phy_tx_iq_war_nphy(pi);
++
++	if (CHSPEC_IS2G(pi->radio_chanspec)) {
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			txcal_radio_regs =
++				pi->calibration_cache.txcal_radio_regs_2G;
++		} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++
++			write_radio_reg(pi,
++					RADIO_2056_TX_LOFT_FINE_I |
++					RADIO_2056_TX0,
++					pi->calibration_cache.
++					txcal_radio_regs_2G[0]);
++			write_radio_reg(pi,
++					RADIO_2056_TX_LOFT_FINE_Q |
++					RADIO_2056_TX0,
++					pi->calibration_cache.
++					txcal_radio_regs_2G[1]);
++			write_radio_reg(pi,
++					RADIO_2056_TX_LOFT_FINE_I |
++					RADIO_2056_TX1,
++					pi->calibration_cache.
++					txcal_radio_regs_2G[2]);
++			write_radio_reg(pi,
++					RADIO_2056_TX_LOFT_FINE_Q |
++					RADIO_2056_TX1,
++					pi->calibration_cache.
++					txcal_radio_regs_2G[3]);
++
++			write_radio_reg(pi,
++					RADIO_2056_TX_LOFT_COARSE_I |
++					RADIO_2056_TX0,
++					pi->calibration_cache.
++					txcal_radio_regs_2G[4]);
++			write_radio_reg(pi,
++					RADIO_2056_TX_LOFT_COARSE_Q |
++					RADIO_2056_TX0,
++					pi->calibration_cache.
++					txcal_radio_regs_2G[5]);
++			write_radio_reg(pi,
++					RADIO_2056_TX_LOFT_COARSE_I |
++					RADIO_2056_TX1,
++					pi->calibration_cache.
++					txcal_radio_regs_2G[6]);
++			write_radio_reg(pi,
++					RADIO_2056_TX_LOFT_COARSE_Q |
++					RADIO_2056_TX1,
++					pi->calibration_cache.
++					txcal_radio_regs_2G[7]);
++		} else {
++			write_radio_reg(pi, RADIO_2055_CORE1_TX_VOS_CNCL,
++					pi->calibration_cache.
++					txcal_radio_regs_2G[0]);
++			write_radio_reg(pi, RADIO_2055_CORE2_TX_VOS_CNCL,
++					pi->calibration_cache.
++					txcal_radio_regs_2G[1]);
++			write_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM,
++					pi->calibration_cache.
++					txcal_radio_regs_2G[2]);
++			write_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM,
++					pi->calibration_cache.
++					txcal_radio_regs_2G[3]);
++		}
++
++		wlc_phy_rx_iq_coeffs_nphy(pi, 1,
++					  &pi->calibration_cache.
++					  rxcal_coeffs_2G);
++	} else {
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			txcal_radio_regs =
++				pi->calibration_cache.txcal_radio_regs_5G;
++		} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++
++			write_radio_reg(pi,
++					RADIO_2056_TX_LOFT_FINE_I |
++					RADIO_2056_TX0,
++					pi->calibration_cache.
++					txcal_radio_regs_5G[0]);
++			write_radio_reg(pi,
++					RADIO_2056_TX_LOFT_FINE_Q |
++					RADIO_2056_TX0,
++					pi->calibration_cache.
++					txcal_radio_regs_5G[1]);
++			write_radio_reg(pi,
++					RADIO_2056_TX_LOFT_FINE_I |
++					RADIO_2056_TX1,
++					pi->calibration_cache.
++					txcal_radio_regs_5G[2]);
++			write_radio_reg(pi,
++					RADIO_2056_TX_LOFT_FINE_Q |
++					RADIO_2056_TX1,
++					pi->calibration_cache.
++					txcal_radio_regs_5G[3]);
++
++			write_radio_reg(pi,
++					RADIO_2056_TX_LOFT_COARSE_I |
++					RADIO_2056_TX0,
++					pi->calibration_cache.
++					txcal_radio_regs_5G[4]);
++			write_radio_reg(pi,
++					RADIO_2056_TX_LOFT_COARSE_Q |
++					RADIO_2056_TX0,
++					pi->calibration_cache.
++					txcal_radio_regs_5G[5]);
++			write_radio_reg(pi,
++					RADIO_2056_TX_LOFT_COARSE_I |
++					RADIO_2056_TX1,
++					pi->calibration_cache.
++					txcal_radio_regs_5G[6]);
++			write_radio_reg(pi,
++					RADIO_2056_TX_LOFT_COARSE_Q |
++					RADIO_2056_TX1,
++					pi->calibration_cache.
++					txcal_radio_regs_5G[7]);
++		} else {
++			write_radio_reg(pi, RADIO_2055_CORE1_TX_VOS_CNCL,
++					pi->calibration_cache.
++					txcal_radio_regs_5G[0]);
++			write_radio_reg(pi, RADIO_2055_CORE2_TX_VOS_CNCL,
++					pi->calibration_cache.
++					txcal_radio_regs_5G[1]);
++			write_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM,
++					pi->calibration_cache.
++					txcal_radio_regs_5G[2]);
++			write_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM,
++					pi->calibration_cache.
++					txcal_radio_regs_5G[3]);
++		}
++
++		wlc_phy_rx_iq_coeffs_nphy(pi, 1,
++					  &pi->calibration_cache.
++					  rxcal_coeffs_5G);
++	}
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		for (coreNum = 0; coreNum <= 1; coreNum++) {
++
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
++					 LOFT_FINE_I,
++					 txcal_radio_regs[2 * coreNum]);
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
++					 LOFT_FINE_Q,
++					 txcal_radio_regs[2 * coreNum + 1]);
++
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
++					 LOFT_COARSE_I,
++					 txcal_radio_regs[2 * coreNum + 4]);
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
++					 LOFT_COARSE_Q,
++					 txcal_radio_regs[2 * coreNum + 5]);
++		}
++	}
++}
++
++static void wlc_phy_txpwrctrl_coeff_setup_nphy(struct brcms_phy *pi)
++{
++	u32 idx;
++	u16 iqloCalbuf[7];
++	u32 iqcomp, locomp, curr_locomp;
++	s8 locomp_i, locomp_q;
++	s8 curr_locomp_i, curr_locomp_q;
++	u32 tbl_id, tbl_len, tbl_offset;
++	u32 regval[128];
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++	wlc_phy_table_read_nphy(pi, 15, 7, 80, 16, iqloCalbuf);
++
++	tbl_len = 128;
++	tbl_offset = 320;
++	for (tbl_id = NPHY_TBL_ID_CORE1TXPWRCTL;
++	     tbl_id <= NPHY_TBL_ID_CORE2TXPWRCTL; tbl_id++) {
++		iqcomp =
++			(tbl_id ==
++			 26) ? (((u32) (iqloCalbuf[0] & 0x3ff)) << 10) |
++			(iqloCalbuf[1] & 0x3ff)
++			: (((u32) (iqloCalbuf[2] & 0x3ff)) << 10) |
++			(iqloCalbuf[3] & 0x3ff);
++
++		for (idx = 0; idx < tbl_len; idx++)
++			regval[idx] = iqcomp;
++		wlc_phy_table_write_nphy(pi, tbl_id, tbl_len, tbl_offset, 32,
++					 regval);
++	}
++
++	tbl_offset = 448;
++	for (tbl_id = NPHY_TBL_ID_CORE1TXPWRCTL;
++	     tbl_id <= NPHY_TBL_ID_CORE2TXPWRCTL; tbl_id++) {
++
++		locomp =
++			(u32) ((tbl_id == 26) ? iqloCalbuf[5] : iqloCalbuf[6]);
++		locomp_i = (s8) ((locomp >> 8) & 0xff);
++		locomp_q = (s8) ((locomp) & 0xff);
++		for (idx = 0; idx < tbl_len; idx++) {
++			if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++				curr_locomp_i = locomp_i;
++				curr_locomp_q = locomp_q;
++			} else {
++				curr_locomp_i = (s8) ((locomp_i *
++						       nphy_tpc_loscale[idx] +
++						       128) >> 8);
++				curr_locomp_q =
++					(s8) ((locomp_q *
++					       nphy_tpc_loscale[idx] +
++					       128) >> 8);
++			}
++			curr_locomp = (u32) ((curr_locomp_i & 0xff) << 8);
++			curr_locomp |= (u32) (curr_locomp_q & 0xff);
++			regval[idx] = curr_locomp;
++		}
++		wlc_phy_table_write_nphy(pi, tbl_id, tbl_len, tbl_offset, 32,
++					 regval);
++	}
++
++	if (NREV_LT(pi->pubpi.phy_rev, 2)) {
++
++		wlapi_bmac_write_shm(pi->sh->physhim, M_CURR_IDX1, 0xFFFF);
++		wlapi_bmac_write_shm(pi->sh->physhim, M_CURR_IDX2, 0xFFFF);
++	}
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, false);
++}
++
++static void wlc_phy_txlpfbw_nphy(struct brcms_phy *pi)
++{
++	u8 tx_lpf_bw = 0;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 7)) {
++		if (CHSPEC_IS40(pi->radio_chanspec))
++			tx_lpf_bw = 3;
++		else
++			tx_lpf_bw = 1;
++
++		if (PHY_IPA(pi)) {
++			if (CHSPEC_IS40(pi->radio_chanspec))
++				tx_lpf_bw = 5;
++			else
++				tx_lpf_bw = 4;
++		}
++
++		write_phy_reg(pi, 0xe8,
++			      (tx_lpf_bw << 0) |
++			      (tx_lpf_bw << 3) |
++			      (tx_lpf_bw << 6) | (tx_lpf_bw << 9));
++
++		if (PHY_IPA(pi)) {
++
++			if (CHSPEC_IS40(pi->radio_chanspec))
++				tx_lpf_bw = 4;
++			else
++				tx_lpf_bw = 1;
++
++			write_phy_reg(pi, 0xe9,
++				      (tx_lpf_bw << 0) |
++				      (tx_lpf_bw << 3) |
++				      (tx_lpf_bw << 6) | (tx_lpf_bw << 9));
++		}
++	}
++}
++
++static void
++wlc_phy_adjust_rx_analpfbw_nphy(struct brcms_phy *pi, u16 reduction_factr)
++{
++	if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 7)) {
++		if ((CHSPEC_CHANNEL(pi->radio_chanspec) == 11) &&
++		    CHSPEC_IS40(pi->radio_chanspec)) {
++			if (!pi->nphy_anarxlpf_adjusted) {
++				write_radio_reg(pi,
++						(RADIO_2056_RX_RXLPF_RCCAL_LPC |
++						 RADIO_2056_RX0),
++						((pi->nphy_rccal_value +
++						  reduction_factr) | 0x80));
++
++				pi->nphy_anarxlpf_adjusted = true;
++			}
++		} else {
++			if (pi->nphy_anarxlpf_adjusted) {
++				write_radio_reg(pi,
++						(RADIO_2056_RX_RXLPF_RCCAL_LPC |
++						 RADIO_2056_RX0),
++						(pi->nphy_rccal_value | 0x80));
++
++				pi->nphy_anarxlpf_adjusted = false;
++			}
++		}
++	}
++}
++
++static void
++wlc_phy_adjust_min_noisevar_nphy(struct brcms_phy *pi, int ntones,
++				 int *tone_id_buf, u32 *noise_var_buf)
++{
++	int i;
++	u32 offset;
++	int tone_id;
++	int tbllen =
++		CHSPEC_IS40(pi->radio_chanspec) ?
++		NPHY_NOISEVAR_TBLLEN40 : NPHY_NOISEVAR_TBLLEN20;
++
++	if (pi->nphy_noisevars_adjusted) {
++		for (i = 0; i < pi->nphy_saved_noisevars.bufcount; i++) {
++			tone_id = pi->nphy_saved_noisevars.tone_id[i];
++			offset = (tone_id >= 0) ?
++				 ((tone_id *
++				   2) + 1) : (tbllen + (tone_id * 2) + 1);
++			wlc_phy_table_write_nphy(
++				pi, NPHY_TBL_ID_NOISEVAR, 1,
++				offset, 32,
++				&pi->nphy_saved_noisevars.min_noise_vars[i]);
++		}
++
++		pi->nphy_saved_noisevars.bufcount = 0;
++		pi->nphy_noisevars_adjusted = false;
++	}
++
++	if ((noise_var_buf != NULL) && (tone_id_buf != NULL)) {
++		pi->nphy_saved_noisevars.bufcount = 0;
++
++		for (i = 0; i < ntones; i++) {
++			tone_id = tone_id_buf[i];
++			offset = (tone_id >= 0) ?
++				 ((tone_id * 2) + 1) :
++				 (tbllen + (tone_id * 2) + 1);
++			pi->nphy_saved_noisevars.tone_id[i] = tone_id;
++			wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
++						offset, 32,
++						&pi->nphy_saved_noisevars.
++						min_noise_vars[i]);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
++						 offset, 32, &noise_var_buf[i]);
++			pi->nphy_saved_noisevars.bufcount++;
++		}
++
++		pi->nphy_noisevars_adjusted = true;
++	}
++}
++
++static void wlc_phy_adjust_crsminpwr_nphy(struct brcms_phy *pi, u8 minpwr)
++{
++	u16 regval;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		if ((CHSPEC_CHANNEL(pi->radio_chanspec) == 11) &&
++		    CHSPEC_IS40(pi->radio_chanspec)) {
++			if (!pi->nphy_crsminpwr_adjusted) {
++				regval = read_phy_reg(pi, 0x27d);
++				pi->nphy_crsminpwr[0] = regval & 0xff;
++				regval &= 0xff00;
++				regval |= (u16) minpwr;
++				write_phy_reg(pi, 0x27d, regval);
++
++				regval = read_phy_reg(pi, 0x280);
++				pi->nphy_crsminpwr[1] = regval & 0xff;
++				regval &= 0xff00;
++				regval |= (u16) minpwr;
++				write_phy_reg(pi, 0x280, regval);
++
++				regval = read_phy_reg(pi, 0x283);
++				pi->nphy_crsminpwr[2] = regval & 0xff;
++				regval &= 0xff00;
++				regval |= (u16) minpwr;
++				write_phy_reg(pi, 0x283, regval);
++
++				pi->nphy_crsminpwr_adjusted = true;
++			}
++		} else {
++			if (pi->nphy_crsminpwr_adjusted) {
++				regval = read_phy_reg(pi, 0x27d);
++				regval &= 0xff00;
++				regval |= pi->nphy_crsminpwr[0];
++				write_phy_reg(pi, 0x27d, regval);
++
++				regval = read_phy_reg(pi, 0x280);
++				regval &= 0xff00;
++				regval |= pi->nphy_crsminpwr[1];
++				write_phy_reg(pi, 0x280, regval);
++
++				regval = read_phy_reg(pi, 0x283);
++				regval &= 0xff00;
++				regval |= pi->nphy_crsminpwr[2];
++				write_phy_reg(pi, 0x283, regval);
++
++				pi->nphy_crsminpwr_adjusted = false;
++			}
++		}
++	}
++}
++
++static void wlc_phy_spurwar_nphy(struct brcms_phy *pi)
++{
++	u16 cur_channel = 0;
++	int nphy_adj_tone_id_buf[] = { 57, 58 };
++	u32 nphy_adj_noise_var_buf[] = { 0x3ff, 0x3ff };
++	bool isAdjustNoiseVar = false;
++	uint numTonesAdjust = 0;
++	u32 tempval = 0;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		if (pi->phyhang_avoid)
++			wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++		cur_channel = CHSPEC_CHANNEL(pi->radio_chanspec);
++
++		if (pi->nphy_gband_spurwar_en) {
++
++			wlc_phy_adjust_rx_analpfbw_nphy(
++				pi,
++				NPHY_ANARXLPFBW_REDUCTIONFACT);
++
++			if (CHSPEC_IS2G(pi->radio_chanspec)) {
++				if ((cur_channel == 11)
++				    && CHSPEC_IS40(pi->radio_chanspec))
++					wlc_phy_adjust_min_noisevar_nphy(
++						pi, 2,
++						nphy_adj_tone_id_buf,
++						nphy_adj_noise_var_buf);
++				else
++					wlc_phy_adjust_min_noisevar_nphy(pi, 0,
++									 NULL,
++									 NULL);
++			}
++
++			wlc_phy_adjust_crsminpwr_nphy(pi,
++						     NPHY_ADJUSTED_MINCRSPOWER);
++		}
++
++		if ((pi->nphy_gband_spurwar2_en)
++		    && CHSPEC_IS2G(pi->radio_chanspec)) {
++
++			if (CHSPEC_IS40(pi->radio_chanspec)) {
++				switch (cur_channel) {
++				case 3:
++					nphy_adj_tone_id_buf[0] = 57;
++					nphy_adj_tone_id_buf[1] = 58;
++					nphy_adj_noise_var_buf[0] = 0x22f;
++					nphy_adj_noise_var_buf[1] = 0x25f;
++					isAdjustNoiseVar = true;
++					break;
++				case 4:
++					nphy_adj_tone_id_buf[0] = 41;
++					nphy_adj_tone_id_buf[1] = 42;
++					nphy_adj_noise_var_buf[0] = 0x22f;
++					nphy_adj_noise_var_buf[1] = 0x25f;
++					isAdjustNoiseVar = true;
++					break;
++				case 5:
++					nphy_adj_tone_id_buf[0] = 25;
++					nphy_adj_tone_id_buf[1] = 26;
++					nphy_adj_noise_var_buf[0] = 0x24f;
++					nphy_adj_noise_var_buf[1] = 0x25f;
++					isAdjustNoiseVar = true;
++					break;
++				case 6:
++					nphy_adj_tone_id_buf[0] = 9;
++					nphy_adj_tone_id_buf[1] = 10;
++					nphy_adj_noise_var_buf[0] = 0x22f;
++					nphy_adj_noise_var_buf[1] = 0x24f;
++					isAdjustNoiseVar = true;
++					break;
++				case 7:
++					nphy_adj_tone_id_buf[0] = 121;
++					nphy_adj_tone_id_buf[1] = 122;
++					nphy_adj_noise_var_buf[0] = 0x18f;
++					nphy_adj_noise_var_buf[1] = 0x24f;
++					isAdjustNoiseVar = true;
++					break;
++				case 8:
++					nphy_adj_tone_id_buf[0] = 105;
++					nphy_adj_tone_id_buf[1] = 106;
++					nphy_adj_noise_var_buf[0] = 0x22f;
++					nphy_adj_noise_var_buf[1] = 0x25f;
++					isAdjustNoiseVar = true;
++					break;
++				case 9:
++					nphy_adj_tone_id_buf[0] = 89;
++					nphy_adj_tone_id_buf[1] = 90;
++					nphy_adj_noise_var_buf[0] = 0x22f;
++					nphy_adj_noise_var_buf[1] = 0x24f;
++					isAdjustNoiseVar = true;
++					break;
++				case 10:
++					nphy_adj_tone_id_buf[0] = 73;
++					nphy_adj_tone_id_buf[1] = 74;
++					nphy_adj_noise_var_buf[0] = 0x22f;
++					nphy_adj_noise_var_buf[1] = 0x24f;
++					isAdjustNoiseVar = true;
++					break;
++				default:
++					isAdjustNoiseVar = false;
++					break;
++				}
++			}
++
++			if (isAdjustNoiseVar) {
++				numTonesAdjust = ARRAY_SIZE(nphy_adj_tone_id_buf);
++
++				wlc_phy_adjust_min_noisevar_nphy(
++					pi,
++					numTonesAdjust,
++					nphy_adj_tone_id_buf,
++					nphy_adj_noise_var_buf);
++
++				tempval = 0;
++
++			} else {
++				wlc_phy_adjust_min_noisevar_nphy(pi, 0, NULL,
++								 NULL);
++			}
++		}
++
++		if ((pi->nphy_aband_spurwar_en) &&
++		    (CHSPEC_IS5G(pi->radio_chanspec))) {
++			switch (cur_channel) {
++			case 54:
++				nphy_adj_tone_id_buf[0] = 32;
++				nphy_adj_noise_var_buf[0] = 0x25f;
++				break;
++			case 38:
++			case 102:
++			case 118:
++				nphy_adj_tone_id_buf[0] = 0;
++				nphy_adj_noise_var_buf[0] = 0x0;
++				break;
++			case 134:
++				nphy_adj_tone_id_buf[0] = 32;
++				nphy_adj_noise_var_buf[0] = 0x21f;
++				break;
++			case 151:
++				nphy_adj_tone_id_buf[0] = 16;
++				nphy_adj_noise_var_buf[0] = 0x23f;
++				break;
++			case 153:
++			case 161:
++				nphy_adj_tone_id_buf[0] = 48;
++				nphy_adj_noise_var_buf[0] = 0x23f;
++				break;
++			default:
++				nphy_adj_tone_id_buf[0] = 0;
++				nphy_adj_noise_var_buf[0] = 0x0;
++				break;
++			}
++
++			if (nphy_adj_tone_id_buf[0]
++			    && nphy_adj_noise_var_buf[0])
++				wlc_phy_adjust_min_noisevar_nphy(
++					pi, 1,
++					nphy_adj_tone_id_buf,
++					nphy_adj_noise_var_buf);
++			else
++				wlc_phy_adjust_min_noisevar_nphy(pi, 0, NULL,
++								 NULL);
++		}
++
++		if (pi->phyhang_avoid)
++			wlc_phy_stay_in_carriersearch_nphy(pi, false);
++	}
++}
++
++void wlc_phy_init_nphy(struct brcms_phy *pi)
++{
++	u16 val;
++	u16 clip1_ths[2];
++	struct nphy_txgains target_gain;
++	u8 tx_pwr_ctrl_state;
++	bool do_nphy_cal = false;
++	uint core;
++	u32 d11_clk_ctl_st;
++	bool do_rssi_cal = false;
++
++	core = 0;
++
++	if (!(pi->measure_hold & PHY_HOLD_FOR_SCAN))
++		pi->measure_hold |= PHY_HOLD_FOR_NOT_ASSOC;
++
++	if ((ISNPHY(pi)) && (NREV_GE(pi->pubpi.phy_rev, 5)) &&
++	    ((pi->sh->chippkg == BCM4717_PKG_ID) ||
++	     (pi->sh->chippkg == BCM4718_PKG_ID))) {
++		if ((pi->sh->boardflags & BFL_EXTLNA) &&
++		    (CHSPEC_IS2G(pi->radio_chanspec)))
++			ai_cc_reg(pi->sh->sih,
++				  offsetof(struct chipcregs, chipcontrol),
++				  0x40, 0x40);
++	}
++
++	if ((pi->nphy_gband_spurwar2_en) && CHSPEC_IS2G(pi->radio_chanspec) &&
++	    CHSPEC_IS40(pi->radio_chanspec)) {
++
++		d11_clk_ctl_st = bcma_read32(pi->d11core,
++					     D11REGOFFS(clk_ctl_st));
++		bcma_mask32(pi->d11core, D11REGOFFS(clk_ctl_st),
++			    ~(CCS_FORCEHT | CCS_HTAREQ));
++
++		bcma_write32(pi->d11core, D11REGOFFS(clk_ctl_st),
++			     d11_clk_ctl_st);
++	}
++
++	pi->use_int_tx_iqlo_cal_nphy =
++		(PHY_IPA(pi) ||
++		 (NREV_GE(pi->pubpi.phy_rev, 7) ||
++		  (NREV_GE(pi->pubpi.phy_rev, 5)
++		   && pi->sh->boardflags2 & BFL2_INTERNDET_TXIQCAL)));
++
++	pi->internal_tx_iqlo_cal_tapoff_intpa_nphy = false;
++
++	pi->nphy_deaf_count = 0;
++
++	wlc_phy_tbl_init_nphy(pi);
++
++	pi->nphy_crsminpwr_adjusted = false;
++	pi->nphy_noisevars_adjusted = false;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		write_phy_reg(pi, 0xe7, 0);
++		write_phy_reg(pi, 0xec, 0);
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			write_phy_reg(pi, 0x342, 0);
++			write_phy_reg(pi, 0x343, 0);
++			write_phy_reg(pi, 0x346, 0);
++			write_phy_reg(pi, 0x347, 0);
++		}
++		write_phy_reg(pi, 0xe5, 0);
++		write_phy_reg(pi, 0xe6, 0);
++	} else {
++		write_phy_reg(pi, 0xec, 0);
++	}
++
++	write_phy_reg(pi, 0x91, 0);
++	write_phy_reg(pi, 0x92, 0);
++	if (NREV_LT(pi->pubpi.phy_rev, 6)) {
++		write_phy_reg(pi, 0x93, 0);
++		write_phy_reg(pi, 0x94, 0);
++	}
++
++	and_phy_reg(pi, 0xa1, ~3);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		write_phy_reg(pi, 0x8f, 0);
++		write_phy_reg(pi, 0xa5, 0);
++	} else {
++		write_phy_reg(pi, 0xa5, 0);
++	}
++
++	if (NREV_IS(pi->pubpi.phy_rev, 2))
++		mod_phy_reg(pi, 0xdc, 0x00ff, 0x3b);
++	else if (NREV_LT(pi->pubpi.phy_rev, 2))
++		mod_phy_reg(pi, 0xdc, 0x00ff, 0x40);
++
++	write_phy_reg(pi, 0x203, 32);
++	write_phy_reg(pi, 0x201, 32);
++
++	if (pi->sh->boardflags2 & BFL2_SKWRKFEM_BRD)
++		write_phy_reg(pi, 0x20d, 160);
++	else
++		write_phy_reg(pi, 0x20d, 184);
++
++	write_phy_reg(pi, 0x13a, 200);
++
++	write_phy_reg(pi, 0x70, 80);
++
++	write_phy_reg(pi, 0x1ff, 48);
++
++	if (NREV_LT(pi->pubpi.phy_rev, 8))
++		wlc_phy_update_mimoconfig_nphy(pi, pi->n_preamble_override);
++
++	wlc_phy_stf_chain_upd_nphy(pi);
++
++	if (NREV_LT(pi->pubpi.phy_rev, 2)) {
++		write_phy_reg(pi, 0x180, 0xaa8);
++		write_phy_reg(pi, 0x181, 0x9a4);
++	}
++
++	if (PHY_IPA(pi)) {
++		for (core = 0; core < pi->pubpi.phy_corenum; core++) {
++
++			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
++				    0x29b, (0x1 << 0), (1) << 0);
++
++			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x298 :
++				    0x29c, (0x1ff << 7),
++				    (pi->nphy_papd_epsilon_offset[core]) << 7);
++
++		}
++
++		wlc_phy_ipa_set_tx_digi_filts_nphy(pi);
++	} else if (NREV_GE(pi->pubpi.phy_rev, 5)) {
++		wlc_phy_extpa_set_tx_digi_filts_nphy(pi);
++	}
++
++	wlc_phy_workarounds_nphy(pi);
++
++	wlapi_bmac_phyclk_fgc(pi->sh->physhim, ON);
++
++	val = read_phy_reg(pi, 0x01);
++	write_phy_reg(pi, 0x01, val | BBCFG_RESETCCA);
++	write_phy_reg(pi, 0x01, val & (~BBCFG_RESETCCA));
++	wlapi_bmac_phyclk_fgc(pi->sh->physhim, OFF);
++
++	wlapi_bmac_macphyclk_set(pi->sh->physhim, ON);
++
++	wlc_phy_pa_override_nphy(pi, OFF);
++	wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX);
++	wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
++	wlc_phy_pa_override_nphy(pi, ON);
++
++	wlc_phy_classifier_nphy(pi, 0, 0);
++	wlc_phy_clip_det_nphy(pi, 0, clip1_ths);
++
++	if (CHSPEC_IS2G(pi->radio_chanspec))
++		wlc_phy_bphy_init_nphy(pi);
++
++	tx_pwr_ctrl_state = pi->nphy_txpwrctrl;
++	wlc_phy_txpwrctrl_enable_nphy(pi, PHY_TPC_HW_OFF);
++
++	wlc_phy_txpwr_fixpower_nphy(pi);
++
++	wlc_phy_txpwrctrl_idle_tssi_nphy(pi);
++
++	wlc_phy_txpwrctrl_pwr_setup_nphy(pi);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		u32 *tx_pwrctrl_tbl = NULL;
++		u16 idx;
++		s16 pga_gn = 0;
++		s16 pad_gn = 0;
++		s32 rfpwr_offset;
++
++		if (PHY_IPA(pi)) {
++			tx_pwrctrl_tbl = wlc_phy_get_ipa_gaintbl_nphy(pi);
++		} else {
++			if (CHSPEC_IS5G(pi->radio_chanspec)) {
++				if (NREV_IS(pi->pubpi.phy_rev, 3))
++					tx_pwrctrl_tbl =
++						nphy_tpc_5GHz_txgain_rev3;
++				else if (NREV_IS(pi->pubpi.phy_rev, 4))
++					tx_pwrctrl_tbl =
++						(pi->srom_fem5g.extpagain ==
++						 3) ?
++						nphy_tpc_5GHz_txgain_HiPwrEPA :
++						nphy_tpc_5GHz_txgain_rev4;
++				else
++					tx_pwrctrl_tbl =
++						nphy_tpc_5GHz_txgain_rev5;
++			} else {
++				if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++					if (pi->pubpi.radiorev == 5)
++						tx_pwrctrl_tbl =
++						   nphy_tpc_txgain_epa_2057rev5;
++					else if (pi->pubpi.radiorev == 3)
++						tx_pwrctrl_tbl =
++						   nphy_tpc_txgain_epa_2057rev3;
++				} else {
++					if (NREV_GE(pi->pubpi.phy_rev, 5) &&
++					    (pi->srom_fem2g.extpagain == 3))
++						tx_pwrctrl_tbl =
++						       nphy_tpc_txgain_HiPwrEPA;
++					else
++						tx_pwrctrl_tbl =
++							nphy_tpc_txgain_rev3;
++				}
++			}
++		}
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE1TXPWRCTL, 128,
++					 192, 32, tx_pwrctrl_tbl);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE2TXPWRCTL, 128,
++					 192, 32, tx_pwrctrl_tbl);
++
++		pi->nphy_gmval = (u16) ((*tx_pwrctrl_tbl >> 16) & 0x7000);
++
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++
++			for (idx = 0; idx < 128; idx++) {
++				pga_gn = (tx_pwrctrl_tbl[idx] >> 24) & 0xf;
++				pad_gn = (tx_pwrctrl_tbl[idx] >> 19) & 0x1f;
++				rfpwr_offset = get_rf_pwr_offset(pi, pga_gn,
++								 pad_gn);
++				wlc_phy_table_write_nphy(
++					pi,
++					NPHY_TBL_ID_CORE1TXPWRCTL,
++					1, 576 + idx, 32,
++					&rfpwr_offset);
++				wlc_phy_table_write_nphy(
++					pi,
++					NPHY_TBL_ID_CORE2TXPWRCTL,
++					1, 576 + idx, 32,
++					&rfpwr_offset);
++			}
++		} else {
++
++			for (idx = 0; idx < 128; idx++) {
++				pga_gn = (tx_pwrctrl_tbl[idx] >> 24) & 0xf;
++				if (CHSPEC_IS2G(pi->radio_chanspec))
++					rfpwr_offset = (s16)
++						 nphy_papd_pga_gain_delta_ipa_2g
++								       [pga_gn];
++				else
++					rfpwr_offset = (s16)
++						 nphy_papd_pga_gain_delta_ipa_5g
++								       [pga_gn];
++
++				wlc_phy_table_write_nphy(
++					pi,
++					NPHY_TBL_ID_CORE1TXPWRCTL,
++					1, 576 + idx, 32,
++					&rfpwr_offset);
++				wlc_phy_table_write_nphy(
++					pi,
++					NPHY_TBL_ID_CORE2TXPWRCTL,
++					1, 576 + idx, 32,
++					&rfpwr_offset);
++			}
++
++		}
++	} else {
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE1TXPWRCTL, 128,
++					 192, 32, nphy_tpc_txgain);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE2TXPWRCTL, 128,
++					 192, 32, nphy_tpc_txgain);
++	}
++
++	if (pi->sh->phyrxchain != 0x3)
++		wlc_phy_rxcore_setstate_nphy((struct brcms_phy_pub *) pi,
++					     pi->sh->phyrxchain);
++
++	if (PHY_PERICAL_MPHASE_PENDING(pi))
++		wlc_phy_cal_perical_mphase_restart(pi);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		do_rssi_cal = (CHSPEC_IS2G(pi->radio_chanspec)) ?
++			      (pi->nphy_rssical_chanspec_2G == 0) :
++			      (pi->nphy_rssical_chanspec_5G == 0);
++
++		if (do_rssi_cal)
++			wlc_phy_rssi_cal_nphy(pi);
++		else
++			wlc_phy_restore_rssical_nphy(pi);
++	} else {
++		wlc_phy_rssi_cal_nphy(pi);
++	}
++
++	if (!SCAN_RM_IN_PROGRESS(pi))
++		do_nphy_cal = (CHSPEC_IS2G(pi->radio_chanspec)) ?
++			      (pi->nphy_iqcal_chanspec_2G == 0) :
++			      (pi->nphy_iqcal_chanspec_5G == 0);
++
++	if (!pi->do_initcal)
++		do_nphy_cal = false;
++
++	if (do_nphy_cal) {
++
++		target_gain = wlc_phy_get_tx_gain_nphy(pi);
++
++		if (pi->antsel_type == ANTSEL_2x3)
++			wlc_phy_antsel_init((struct brcms_phy_pub *) pi,
++					    true);
++
++		if (pi->nphy_perical != PHY_PERICAL_MPHASE) {
++			wlc_phy_rssi_cal_nphy(pi);
++
++			if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++				pi->nphy_cal_orig_pwr_idx[0] =
++					pi->nphy_txpwrindex[PHY_CORE_0]
++					.
++					index_internal;
++				pi->nphy_cal_orig_pwr_idx[1] =
++					pi->nphy_txpwrindex[PHY_CORE_1]
++					.
++					index_internal;
++
++				wlc_phy_precal_txgain_nphy(pi);
++				target_gain =
++					wlc_phy_get_tx_gain_nphy(pi);
++			}
++
++			if (wlc_phy_cal_txiqlo_nphy
++				    (pi, target_gain, true,
++				    false) == 0) {
++				if (wlc_phy_cal_rxiq_nphy
++					    (pi, target_gain, 2,
++					    false) == 0)
++					wlc_phy_savecal_nphy(pi);
++
++			}
++		} else if (pi->mphase_cal_phase_id ==
++			   MPHASE_CAL_STATE_IDLE) {
++			wlc_phy_cal_perical((struct brcms_phy_pub *) pi,
++					    PHY_PERICAL_PHYINIT);
++		}
++	} else {
++		wlc_phy_restorecal_nphy(pi);
++	}
++
++	wlc_phy_txpwrctrl_coeff_setup_nphy(pi);
++
++	wlc_phy_txpwrctrl_enable_nphy(pi, tx_pwr_ctrl_state);
++
++	wlc_phy_nphy_tkip_rifs_war(pi, pi->sh->_rifs_phy);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LE(pi->pubpi.phy_rev, 6))
++
++		write_phy_reg(pi, 0x70, 50);
++
++	wlc_phy_txlpfbw_nphy(pi);
++
++	wlc_phy_spurwar_nphy(pi);
++
++}
++
++static void wlc_phy_resetcca_nphy(struct brcms_phy *pi)
++{
++	u16 val;
++
++	wlapi_bmac_phyclk_fgc(pi->sh->physhim, ON);
++
++	val = read_phy_reg(pi, 0x01);
++	write_phy_reg(pi, 0x01, val | BBCFG_RESETCCA);
++	udelay(1);
++	write_phy_reg(pi, 0x01, val & (~BBCFG_RESETCCA));
++
++	wlapi_bmac_phyclk_fgc(pi->sh->physhim, OFF);
++
++	wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
++}
++
++void wlc_phy_pa_override_nphy(struct brcms_phy *pi, bool en)
++{
++	u16 rfctrlintc_override_val;
++
++	if (!en) {
++
++		pi->rfctrlIntc1_save = read_phy_reg(pi, 0x91);
++		pi->rfctrlIntc2_save = read_phy_reg(pi, 0x92);
++
++		if (NREV_GE(pi->pubpi.phy_rev, 7))
++			rfctrlintc_override_val = 0x1480;
++		else if (NREV_GE(pi->pubpi.phy_rev, 3))
++			rfctrlintc_override_val =
++				CHSPEC_IS5G(pi->radio_chanspec) ? 0x600 : 0x480;
++		else
++			rfctrlintc_override_val =
++				CHSPEC_IS5G(pi->radio_chanspec) ? 0x180 : 0x120;
++
++		write_phy_reg(pi, 0x91, rfctrlintc_override_val);
++		write_phy_reg(pi, 0x92, rfctrlintc_override_val);
++	} else {
++		write_phy_reg(pi, 0x91, pi->rfctrlIntc1_save);
++		write_phy_reg(pi, 0x92, pi->rfctrlIntc2_save);
++	}
++
++}
++
++void wlc_phy_stf_chain_upd_nphy(struct brcms_phy *pi)
++{
++
++	u16 txrx_chain =
++		(NPHY_RfseqCoreActv_TxRxChain0 | NPHY_RfseqCoreActv_TxRxChain1);
++	bool CoreActv_override = false;
++
++	if (pi->nphy_txrx_chain == BRCMS_N_TXRX_CHAIN0) {
++		txrx_chain = NPHY_RfseqCoreActv_TxRxChain0;
++		CoreActv_override = true;
++
++		if (NREV_LE(pi->pubpi.phy_rev, 2))
++			and_phy_reg(pi, 0xa0, ~0x20);
++	} else if (pi->nphy_txrx_chain == BRCMS_N_TXRX_CHAIN1) {
++		txrx_chain = NPHY_RfseqCoreActv_TxRxChain1;
++		CoreActv_override = true;
++
++		if (NREV_LE(pi->pubpi.phy_rev, 2))
++			or_phy_reg(pi, 0xa0, 0x20);
++	}
++
++	mod_phy_reg(pi, 0xa2, ((0xf << 0) | (0xf << 4)), txrx_chain);
++
++	if (CoreActv_override) {
++		pi->nphy_perical = PHY_PERICAL_DISABLE;
++		or_phy_reg(pi, 0xa1, NPHY_RfseqMode_CoreActv_override);
++	} else {
++		pi->nphy_perical = PHY_PERICAL_MPHASE;
++		and_phy_reg(pi, 0xa1, ~NPHY_RfseqMode_CoreActv_override);
++	}
++}
++
++void wlc_phy_rxcore_setstate_nphy(struct brcms_phy_pub *pih, u8 rxcore_bitmask)
++{
++	u16 regval;
++	u16 tbl_buf[16];
++	uint i;
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++	u16 tbl_opcode;
++	bool suspend;
++
++	pi->sh->phyrxchain = rxcore_bitmask;
++
++	if (!pi->sh->clk)
++		return;
++
++	suspend = (0 == (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) &
++			 MCTL_EN_MAC));
++	if (!suspend)
++		wlapi_suspend_mac_and_wait(pi->sh->physhim);
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++	regval = read_phy_reg(pi, 0xa2);
++	regval &= ~(0xf << 4);
++	regval |= ((u16) (rxcore_bitmask & 0x3)) << 4;
++	write_phy_reg(pi, 0xa2, regval);
++
++	if ((rxcore_bitmask & 0x3) != 0x3) {
++
++		write_phy_reg(pi, 0x20e, 1);
++
++		if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++			if (pi->rx2tx_biasentry == -1) {
++				wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ,
++							ARRAY_SIZE(tbl_buf), 80,
++							16, tbl_buf);
++
++				for (i = 0; i < ARRAY_SIZE(tbl_buf); i++) {
++					if (tbl_buf[i] ==
++					    NPHY_REV3_RFSEQ_CMD_CLR_RXRX_BIAS) {
++						pi->rx2tx_biasentry = (u8) i;
++						tbl_opcode =
++							NPHY_REV3_RFSEQ_CMD_NOP;
++						wlc_phy_table_write_nphy(
++							pi,
++							NPHY_TBL_ID_RFSEQ,
++							1, i,
++							16,
++							&tbl_opcode);
++						break;
++					} else if (tbl_buf[i] ==
++						   NPHY_REV3_RFSEQ_CMD_END)
++						break;
++				}
++			}
++		}
++	} else {
++
++		write_phy_reg(pi, 0x20e, 30);
++
++		if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++			if (pi->rx2tx_biasentry != -1) {
++				tbl_opcode = NPHY_REV3_RFSEQ_CMD_CLR_RXRX_BIAS;
++				wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
++							 1, pi->rx2tx_biasentry,
++							 16, &tbl_opcode);
++				pi->rx2tx_biasentry = -1;
++			}
++		}
++	}
++
++	wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, false);
++
++	if (!suspend)
++		wlapi_enable_mac(pi->sh->physhim);
++}
++
++u8 wlc_phy_rxcore_getstate_nphy(struct brcms_phy_pub *pih)
++{
++	u16 regval, rxen_bits;
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	regval = read_phy_reg(pi, 0xa2);
++	rxen_bits = (regval >> 4) & 0xf;
++
++	return (u8) rxen_bits;
++}
++
++bool wlc_phy_n_txpower_ipa_ison(struct brcms_phy *pi)
++{
++	return PHY_IPA(pi);
++}
++
++void wlc_phy_cal_init_nphy(struct brcms_phy *pi)
++{
++}
++
++static void wlc_phy_radio_preinit_205x(struct brcms_phy *pi)
++{
++
++	and_phy_reg(pi, 0x78, ~RFCC_CHIP0_PU);
++	and_phy_reg(pi, 0x78, RFCC_OE_POR_FORCE);
++
++	or_phy_reg(pi, 0x78, ~RFCC_OE_POR_FORCE);
++	or_phy_reg(pi, 0x78, RFCC_CHIP0_PU);
++
++}
++
++static void wlc_phy_radio_init_2057(struct brcms_phy *pi)
++{
++	struct radio_20xx_regs *regs_2057_ptr = NULL;
++
++	if (NREV_IS(pi->pubpi.phy_rev, 7)) {
++		regs_2057_ptr = regs_2057_rev4;
++	} else if (NREV_IS(pi->pubpi.phy_rev, 8)
++		   || NREV_IS(pi->pubpi.phy_rev, 9)) {
++		switch (pi->pubpi.radiorev) {
++		case 5:
++
++			if (NREV_IS(pi->pubpi.phy_rev, 8))
++				regs_2057_ptr = regs_2057_rev5;
++			else if (NREV_IS(pi->pubpi.phy_rev, 9))
++				regs_2057_ptr = regs_2057_rev5v1;
++			break;
++
++		case 7:
++
++			regs_2057_ptr = regs_2057_rev7;
++			break;
++
++		case 8:
++
++			regs_2057_ptr = regs_2057_rev8;
++			break;
++
++		default:
++			break;
++		}
++	}
++
++	wlc_phy_init_radio_regs_allbands(pi, regs_2057_ptr);
++}
++
++static u16 wlc_phy_radio205x_rcal(struct brcms_phy *pi)
++{
++	u16 rcal_reg = 0;
++	int i;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++
++		if (pi->pubpi.radiorev == 5) {
++
++			and_phy_reg(pi, 0x342, ~(0x1 << 1));
++
++			udelay(10);
++
++			mod_radio_reg(pi, RADIO_2057_IQTEST_SEL_PU, 0x1, 0x1);
++			mod_radio_reg(pi, RADIO_2057v7_IQTEST_SEL_PU2, 0x2,
++				      0x1);
++		}
++		mod_radio_reg(pi, RADIO_2057_RCAL_CONFIG, 0x1, 0x1);
++
++		udelay(10);
++
++		mod_radio_reg(pi, RADIO_2057_RCAL_CONFIG, 0x3, 0x3);
++
++		for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) {
++			rcal_reg = read_radio_reg(pi, RADIO_2057_RCAL_STATUS);
++			if (rcal_reg & 0x1)
++				break;
++
++			udelay(100);
++		}
++
++		if (WARN(i == MAX_205x_RCAL_WAITLOOPS,
++			 "HW error: radio calib2"))
++			return 0;
++
++		mod_radio_reg(pi, RADIO_2057_RCAL_CONFIG, 0x2, 0x0);
++
++		rcal_reg = read_radio_reg(pi, RADIO_2057_RCAL_STATUS) & 0x3e;
++
++		mod_radio_reg(pi, RADIO_2057_RCAL_CONFIG, 0x1, 0x0);
++		if (pi->pubpi.radiorev == 5) {
++
++			mod_radio_reg(pi, RADIO_2057_IQTEST_SEL_PU, 0x1, 0x0);
++			mod_radio_reg(pi, RADIO_2057v7_IQTEST_SEL_PU2, 0x2,
++				      0x0);
++		}
++
++		if ((pi->pubpi.radiorev <= 4) || (pi->pubpi.radiorev == 6)) {
++
++			mod_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG, 0x3c,
++				      rcal_reg);
++			mod_radio_reg(pi, RADIO_2057_BANDGAP_RCAL_TRIM, 0xf0,
++				      rcal_reg << 2);
++		}
++
++	} else if (NREV_IS(pi->pubpi.phy_rev, 3)) {
++		u16 savereg;
++
++		savereg =
++			read_radio_reg(
++				pi,
++				RADIO_2056_SYN_PLL_MAST2 |
++				RADIO_2056_SYN);
++		write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST2 | RADIO_2056_SYN,
++				savereg | 0x7);
++		udelay(10);
++
++		write_radio_reg(pi, RADIO_2056_SYN_RCAL_MASTER | RADIO_2056_SYN,
++				0x1);
++		udelay(10);
++
++		write_radio_reg(pi, RADIO_2056_SYN_RCAL_MASTER | RADIO_2056_SYN,
++				0x9);
++
++		for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) {
++			rcal_reg = read_radio_reg(
++				pi,
++				RADIO_2056_SYN_RCAL_CODE_OUT |
++				RADIO_2056_SYN);
++			if (rcal_reg & 0x80)
++				break;
++
++			udelay(100);
++		}
++
++		if (WARN(i == MAX_205x_RCAL_WAITLOOPS,
++			 "HW error: radio calib3"))
++			return 0;
++
++		write_radio_reg(pi, RADIO_2056_SYN_RCAL_MASTER | RADIO_2056_SYN,
++				0x1);
++
++		rcal_reg =
++			read_radio_reg(pi,
++				       RADIO_2056_SYN_RCAL_CODE_OUT |
++				       RADIO_2056_SYN);
++
++		write_radio_reg(pi, RADIO_2056_SYN_RCAL_MASTER | RADIO_2056_SYN,
++				0x0);
++
++		write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST2 | RADIO_2056_SYN,
++				savereg);
++
++		return rcal_reg & 0x1f;
++	}
++	return rcal_reg & 0x3e;
++}
++
++static u16 wlc_phy_radio2057_rccal(struct brcms_phy *pi)
++{
++	u16 rccal_valid;
++	int i;
++	bool chip43226_6362A0;
++
++	chip43226_6362A0 = ((pi->pubpi.radiorev == 3)
++			    || (pi->pubpi.radiorev == 4)
++			    || (pi->pubpi.radiorev == 6));
++
++	rccal_valid = 0;
++	if (chip43226_6362A0) {
++		write_radio_reg(pi, RADIO_2057_RCCAL_MASTER, 0x61);
++		write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xc0);
++	} else {
++		write_radio_reg(pi, RADIO_2057v7_RCCAL_MASTER, 0x61);
++
++		write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xe9);
++	}
++	write_radio_reg(pi, RADIO_2057_RCCAL_X1, 0x6e);
++	write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x55);
++
++	for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) {
++		rccal_valid = read_radio_reg(pi, RADIO_2057_RCCAL_DONE_OSCCAP);
++		if (rccal_valid & 0x2)
++			break;
++
++		udelay(500);
++	}
++
++	write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x15);
++
++	rccal_valid = 0;
++	if (chip43226_6362A0) {
++		write_radio_reg(pi, RADIO_2057_RCCAL_MASTER, 0x69);
++		write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xb0);
++	} else {
++		write_radio_reg(pi, RADIO_2057v7_RCCAL_MASTER, 0x69);
++
++		write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xd5);
++	}
++	write_radio_reg(pi, RADIO_2057_RCCAL_X1, 0x6e);
++	write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x55);
++
++	for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) {
++		rccal_valid = read_radio_reg(pi, RADIO_2057_RCCAL_DONE_OSCCAP);
++		if (rccal_valid & 0x2)
++			break;
++
++		udelay(500);
++	}
++
++	write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x15);
++
++	rccal_valid = 0;
++	if (chip43226_6362A0) {
++		write_radio_reg(pi, RADIO_2057_RCCAL_MASTER, 0x73);
++
++		write_radio_reg(pi, RADIO_2057_RCCAL_X1, 0x28);
++		write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xb0);
++	} else {
++		write_radio_reg(pi, RADIO_2057v7_RCCAL_MASTER, 0x73);
++		write_radio_reg(pi, RADIO_2057_RCCAL_X1, 0x6e);
++		write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0x99);
++	}
++	write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x55);
++
++	for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) {
++		rccal_valid = read_radio_reg(pi, RADIO_2057_RCCAL_DONE_OSCCAP);
++		if (rccal_valid & 0x2)
++			break;
++
++		udelay(500);
++	}
++
++	if (WARN(!(rccal_valid & 0x2), "HW error: radio calib4"))
++		return 0;
++
++	write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x15);
++
++	return rccal_valid;
++}
++
++static void wlc_phy_radio_postinit_2057(struct brcms_phy *pi)
++{
++
++	mod_radio_reg(pi, RADIO_2057_XTALPUOVR_PINCTRL, 0x1, 0x1);
++
++	mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_CAL_RESETN, 0x78, 0x78);
++	mod_radio_reg(pi, RADIO_2057_XTAL_CONFIG2, 0x80, 0x80);
++	mdelay(2);
++	mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_CAL_RESETN, 0x78, 0x0);
++	mod_radio_reg(pi, RADIO_2057_XTAL_CONFIG2, 0x80, 0x0);
++
++	if (pi->phy_init_por) {
++		wlc_phy_radio205x_rcal(pi);
++		wlc_phy_radio2057_rccal(pi);
++	}
++
++	mod_radio_reg(pi, RADIO_2057_RFPLL_MASTER, 0x8, 0x0);
++}
++
++static void wlc_phy_radio_init_2056(struct brcms_phy *pi)
++{
++	const struct radio_regs *regs_SYN_2056_ptr = NULL;
++	const struct radio_regs *regs_TX_2056_ptr = NULL;
++	const struct radio_regs *regs_RX_2056_ptr = NULL;
++
++	if (NREV_IS(pi->pubpi.phy_rev, 3)) {
++		regs_SYN_2056_ptr = regs_SYN_2056;
++		regs_TX_2056_ptr = regs_TX_2056;
++		regs_RX_2056_ptr = regs_RX_2056;
++	} else if (NREV_IS(pi->pubpi.phy_rev, 4)) {
++		regs_SYN_2056_ptr = regs_SYN_2056_A1;
++		regs_TX_2056_ptr = regs_TX_2056_A1;
++		regs_RX_2056_ptr = regs_RX_2056_A1;
++	} else {
++		switch (pi->pubpi.radiorev) {
++		case 5:
++			regs_SYN_2056_ptr = regs_SYN_2056_rev5;
++			regs_TX_2056_ptr = regs_TX_2056_rev5;
++			regs_RX_2056_ptr = regs_RX_2056_rev5;
++			break;
++
++		case 6:
++			regs_SYN_2056_ptr = regs_SYN_2056_rev6;
++			regs_TX_2056_ptr = regs_TX_2056_rev6;
++			regs_RX_2056_ptr = regs_RX_2056_rev6;
++			break;
++
++		case 7:
++		case 9:
++			regs_SYN_2056_ptr = regs_SYN_2056_rev7;
++			regs_TX_2056_ptr = regs_TX_2056_rev7;
++			regs_RX_2056_ptr = regs_RX_2056_rev7;
++			break;
++
++		case 8:
++			regs_SYN_2056_ptr = regs_SYN_2056_rev8;
++			regs_TX_2056_ptr = regs_TX_2056_rev8;
++			regs_RX_2056_ptr = regs_RX_2056_rev8;
++			break;
++
++		case 11:
++			regs_SYN_2056_ptr = regs_SYN_2056_rev11;
++			regs_TX_2056_ptr = regs_TX_2056_rev11;
++			regs_RX_2056_ptr = regs_RX_2056_rev11;
++			break;
++
++		default:
++			break;
++		}
++	}
++
++	wlc_phy_init_radio_regs(pi, regs_SYN_2056_ptr, (u16) RADIO_2056_SYN);
++
++	wlc_phy_init_radio_regs(pi, regs_TX_2056_ptr, (u16) RADIO_2056_TX0);
++
++	wlc_phy_init_radio_regs(pi, regs_TX_2056_ptr, (u16) RADIO_2056_TX1);
++
++	wlc_phy_init_radio_regs(pi, regs_RX_2056_ptr, (u16) RADIO_2056_RX0);
++
++	wlc_phy_init_radio_regs(pi, regs_RX_2056_ptr, (u16) RADIO_2056_RX1);
++}
++
++static void wlc_phy_radio_postinit_2056(struct brcms_phy *pi)
++{
++	mod_radio_reg(pi, RADIO_2056_SYN_COM_CTRL, 0xb, 0xb);
++
++	mod_radio_reg(pi, RADIO_2056_SYN_COM_PU, 0x2, 0x2);
++	mod_radio_reg(pi, RADIO_2056_SYN_COM_RESET, 0x2, 0x2);
++	udelay(1000);
++	mod_radio_reg(pi, RADIO_2056_SYN_COM_RESET, 0x2, 0x0);
++
++	if ((pi->sh->boardflags2 & BFL2_LEGACY)
++	    || (pi->sh->boardflags2 & BFL2_XTALBUFOUTEN))
++		mod_radio_reg(pi, RADIO_2056_SYN_PLL_MAST2, 0xf4, 0x0);
++	else
++		mod_radio_reg(pi, RADIO_2056_SYN_PLL_MAST2, 0xfc, 0x0);
++
++	mod_radio_reg(pi, RADIO_2056_SYN_RCCAL_CTRL0, 0x1, 0x0);
++
++	if (pi->phy_init_por)
++		wlc_phy_radio205x_rcal(pi);
++}
++
++static void wlc_phy_radio_preinit_2055(struct brcms_phy *pi)
++{
++
++	and_phy_reg(pi, 0x78, ~RFCC_POR_FORCE);
++	or_phy_reg(pi, 0x78, RFCC_CHIP0_PU | RFCC_OE_POR_FORCE);
++
++	or_phy_reg(pi, 0x78, RFCC_POR_FORCE);
++}
++
++static void wlc_phy_radio_init_2055(struct brcms_phy *pi)
++{
++	wlc_phy_init_radio_regs(pi, regs_2055, RADIO_DEFAULT_CORE);
++}
++
++static void wlc_phy_radio_postinit_2055(struct brcms_phy *pi)
++{
++
++	and_radio_reg(pi, RADIO_2055_MASTER_CNTRL1,
++		      ~(RADIO_2055_JTAGCTRL_MASK | RADIO_2055_JTAGSYNC_MASK));
++
++	if (((pi->sh->sromrev >= 4)
++	     && !(pi->sh->boardflags2 & BFL2_RXBB_INT_REG_DIS))
++	    || ((pi->sh->sromrev < 4))) {
++		and_radio_reg(pi, RADIO_2055_CORE1_RXBB_REGULATOR, 0x7F);
++		and_radio_reg(pi, RADIO_2055_CORE2_RXBB_REGULATOR, 0x7F);
++	}
++
++	mod_radio_reg(pi, RADIO_2055_RRCCAL_N_OPT_SEL, 0x3F, 0x2C);
++	write_radio_reg(pi, RADIO_2055_CAL_MISC, 0x3C);
++
++	and_radio_reg(pi, RADIO_2055_CAL_MISC,
++		      ~(RADIO_2055_RRCAL_START | RADIO_2055_RRCAL_RST_N));
++
++	or_radio_reg(pi, RADIO_2055_CAL_LPO_CNTRL, RADIO_2055_CAL_LPO_ENABLE);
++
++	or_radio_reg(pi, RADIO_2055_CAL_MISC, RADIO_2055_RRCAL_RST_N);
++
++	udelay(1000);
++
++	or_radio_reg(pi, RADIO_2055_CAL_MISC, RADIO_2055_RRCAL_START);
++
++	SPINWAIT(((read_radio_reg(pi, RADIO_2055_CAL_COUNTER_OUT2) &
++		   RADIO_2055_RCAL_DONE) != RADIO_2055_RCAL_DONE), 2000);
++
++	if (WARN((read_radio_reg(pi, RADIO_2055_CAL_COUNTER_OUT2) &
++		  RADIO_2055_RCAL_DONE) != RADIO_2055_RCAL_DONE,
++		 "HW error: radio calibration1\n"))
++		return;
++
++	and_radio_reg(pi, RADIO_2055_CAL_LPO_CNTRL,
++		      ~(RADIO_2055_CAL_LPO_ENABLE));
++
++	wlc_phy_chanspec_set((struct brcms_phy_pub *) pi, pi->radio_chanspec);
++
++	write_radio_reg(pi, RADIO_2055_CORE1_RXBB_LPF, 9);
++	write_radio_reg(pi, RADIO_2055_CORE2_RXBB_LPF, 9);
++
++	write_radio_reg(pi, RADIO_2055_CORE1_RXBB_MIDAC_HIPAS, 0x83);
++	write_radio_reg(pi, RADIO_2055_CORE2_RXBB_MIDAC_HIPAS, 0x83);
++
++	mod_radio_reg(pi, RADIO_2055_CORE1_LNA_GAINBST,
++		      RADIO_2055_GAINBST_VAL_MASK, RADIO_2055_GAINBST_CODE);
++	mod_radio_reg(pi, RADIO_2055_CORE2_LNA_GAINBST,
++		      RADIO_2055_GAINBST_VAL_MASK, RADIO_2055_GAINBST_CODE);
++	if (pi->nphy_gain_boost) {
++		and_radio_reg(pi, RADIO_2055_CORE1_RXRF_SPC1,
++			      ~(RADIO_2055_GAINBST_DISABLE));
++		and_radio_reg(pi, RADIO_2055_CORE2_RXRF_SPC1,
++			      ~(RADIO_2055_GAINBST_DISABLE));
++	} else {
++		or_radio_reg(pi, RADIO_2055_CORE1_RXRF_SPC1,
++			     RADIO_2055_GAINBST_DISABLE);
++		or_radio_reg(pi, RADIO_2055_CORE2_RXRF_SPC1,
++			     RADIO_2055_GAINBST_DISABLE);
++	}
++
++	udelay(2);
++}
++
++void wlc_phy_switch_radio_nphy(struct brcms_phy *pi, bool on)
++{
++	if (on) {
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			if (!pi->radio_is_on) {
++				wlc_phy_radio_preinit_205x(pi);
++				wlc_phy_radio_init_2057(pi);
++				wlc_phy_radio_postinit_2057(pi);
++			}
++
++			wlc_phy_chanspec_set((struct brcms_phy_pub *) pi,
++					     pi->radio_chanspec);
++		} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++			wlc_phy_radio_preinit_205x(pi);
++			wlc_phy_radio_init_2056(pi);
++			wlc_phy_radio_postinit_2056(pi);
++
++			wlc_phy_chanspec_set((struct brcms_phy_pub *) pi,
++					     pi->radio_chanspec);
++		} else {
++			wlc_phy_radio_preinit_2055(pi);
++			wlc_phy_radio_init_2055(pi);
++			wlc_phy_radio_postinit_2055(pi);
++		}
++
++		pi->radio_is_on = true;
++
++	} else {
++
++		if (NREV_GE(pi->pubpi.phy_rev, 3)
++		    && NREV_LT(pi->pubpi.phy_rev, 7)) {
++			and_phy_reg(pi, 0x78, ~RFCC_CHIP0_PU);
++			mod_radio_reg(pi, RADIO_2056_SYN_COM_PU, 0x2, 0x0);
++
++			write_radio_reg(pi,
++					RADIO_2056_TX_PADA_BOOST_TUNE |
++					RADIO_2056_TX0, 0);
++			write_radio_reg(pi,
++					RADIO_2056_TX_PADG_BOOST_TUNE |
++					RADIO_2056_TX0, 0);
++			write_radio_reg(pi,
++					RADIO_2056_TX_PGAA_BOOST_TUNE |
++					RADIO_2056_TX0, 0);
++			write_radio_reg(pi,
++					RADIO_2056_TX_PGAG_BOOST_TUNE |
++					RADIO_2056_TX0, 0);
++			mod_radio_reg(pi,
++				      RADIO_2056_TX_MIXA_BOOST_TUNE |
++				      RADIO_2056_TX0, 0xf0, 0);
++			write_radio_reg(pi,
++					RADIO_2056_TX_MIXG_BOOST_TUNE |
++					RADIO_2056_TX0, 0);
++
++			write_radio_reg(pi,
++					RADIO_2056_TX_PADA_BOOST_TUNE |
++					RADIO_2056_TX1, 0);
++			write_radio_reg(pi,
++					RADIO_2056_TX_PADG_BOOST_TUNE |
++					RADIO_2056_TX1, 0);
++			write_radio_reg(pi,
++					RADIO_2056_TX_PGAA_BOOST_TUNE |
++					RADIO_2056_TX1, 0);
++			write_radio_reg(pi,
++					RADIO_2056_TX_PGAG_BOOST_TUNE |
++					RADIO_2056_TX1, 0);
++			mod_radio_reg(pi,
++				      RADIO_2056_TX_MIXA_BOOST_TUNE |
++				      RADIO_2056_TX1, 0xf0, 0);
++			write_radio_reg(pi,
++					RADIO_2056_TX_MIXG_BOOST_TUNE |
++					RADIO_2056_TX1, 0);
++
++			pi->radio_is_on = false;
++		}
++
++		if (NREV_GE(pi->pubpi.phy_rev, 8)) {
++			and_phy_reg(pi, 0x78, ~RFCC_CHIP0_PU);
++			pi->radio_is_on = false;
++		}
++
++	}
++}
++
++static bool
++wlc_phy_chan2freq_nphy(struct brcms_phy *pi, uint channel, int *f,
++		       const struct chan_info_nphy_radio2057 **t0,
++		       const struct chan_info_nphy_radio205x **t1,
++		       const struct chan_info_nphy_radio2057_rev5 **t2,
++		       const struct chan_info_nphy_2055 **t3)
++{
++	uint i;
++	const struct chan_info_nphy_radio2057 *chan_info_tbl_p_0 = NULL;
++	const struct chan_info_nphy_radio205x *chan_info_tbl_p_1 = NULL;
++	const struct chan_info_nphy_radio2057_rev5 *chan_info_tbl_p_2 = NULL;
++	u32 tbl_len = 0;
++
++	int freq = 0;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++
++		if (NREV_IS(pi->pubpi.phy_rev, 7)) {
++
++			chan_info_tbl_p_0 = chan_info_nphyrev7_2057_rev4;
++			tbl_len = ARRAY_SIZE(chan_info_nphyrev7_2057_rev4);
++
++		} else if (NREV_IS(pi->pubpi.phy_rev, 8)
++			   || NREV_IS(pi->pubpi.phy_rev, 9)) {
++			switch (pi->pubpi.radiorev) {
++
++			case 5:
++
++				if (pi->pubpi.radiover == 0x0) {
++
++					chan_info_tbl_p_2 =
++						chan_info_nphyrev8_2057_rev5;
++					tbl_len = ARRAY_SIZE(
++						  chan_info_nphyrev8_2057_rev5);
++
++				} else if (pi->pubpi.radiover == 0x1) {
++
++					chan_info_tbl_p_2 =
++						chan_info_nphyrev9_2057_rev5v1;
++					tbl_len = ARRAY_SIZE(
++						chan_info_nphyrev9_2057_rev5v1);
++
++				}
++				break;
++
++			case 7:
++				chan_info_tbl_p_0 =
++					chan_info_nphyrev8_2057_rev7;
++				tbl_len = ARRAY_SIZE(
++						  chan_info_nphyrev8_2057_rev7);
++				break;
++
++			case 8:
++				chan_info_tbl_p_0 =
++					chan_info_nphyrev8_2057_rev8;
++				tbl_len = ARRAY_SIZE(
++						  chan_info_nphyrev8_2057_rev8);
++				break;
++
++			default:
++				break;
++			}
++		} else if (NREV_IS(pi->pubpi.phy_rev, 16)) {
++
++			chan_info_tbl_p_0 = chan_info_nphyrev8_2057_rev8;
++			tbl_len = ARRAY_SIZE(chan_info_nphyrev8_2057_rev8);
++		} else {
++			goto fail;
++		}
++
++		for (i = 0; i < tbl_len; i++) {
++			if (pi->pubpi.radiorev == 5) {
++
++				if (chan_info_tbl_p_2[i].chan == channel)
++					break;
++			} else {
++
++				if (chan_info_tbl_p_0[i].chan == channel)
++					break;
++			}
++		}
++
++		if (i >= tbl_len)
++			goto fail;
++
++		if (pi->pubpi.radiorev == 5) {
++			*t2 = &chan_info_tbl_p_2[i];
++			freq = chan_info_tbl_p_2[i].freq;
++		} else {
++			*t0 = &chan_info_tbl_p_0[i];
++			freq = chan_info_tbl_p_0[i].freq;
++		}
++
++	} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		if (NREV_IS(pi->pubpi.phy_rev, 3)) {
++			chan_info_tbl_p_1 = chan_info_nphyrev3_2056;
++			tbl_len = ARRAY_SIZE(chan_info_nphyrev3_2056);
++		} else if (NREV_IS(pi->pubpi.phy_rev, 4)) {
++			chan_info_tbl_p_1 = chan_info_nphyrev4_2056_A1;
++			tbl_len = ARRAY_SIZE(chan_info_nphyrev4_2056_A1);
++		} else if (NREV_IS(pi->pubpi.phy_rev, 5)
++			   || NREV_IS(pi->pubpi.phy_rev, 6)) {
++			switch (pi->pubpi.radiorev) {
++			case 5:
++				chan_info_tbl_p_1 = chan_info_nphyrev5_2056v5;
++				tbl_len = ARRAY_SIZE(chan_info_nphyrev5_2056v5);
++				break;
++			case 6:
++				chan_info_tbl_p_1 = chan_info_nphyrev6_2056v6;
++				tbl_len = ARRAY_SIZE(chan_info_nphyrev6_2056v6);
++				break;
++			case 7:
++			case 9:
++				chan_info_tbl_p_1 = chan_info_nphyrev5n6_2056v7;
++				tbl_len =
++					ARRAY_SIZE(chan_info_nphyrev5n6_2056v7);
++				break;
++			case 8:
++				chan_info_tbl_p_1 = chan_info_nphyrev6_2056v8;
++				tbl_len = ARRAY_SIZE(chan_info_nphyrev6_2056v8);
++				break;
++			case 11:
++				chan_info_tbl_p_1 = chan_info_nphyrev6_2056v11;
++				tbl_len = ARRAY_SIZE(
++						    chan_info_nphyrev6_2056v11);
++				break;
++			default:
++				break;
++			}
++		}
++
++		for (i = 0; i < tbl_len; i++) {
++			if (chan_info_tbl_p_1[i].chan == channel)
++				break;
++		}
++
++		if (i >= tbl_len)
++			goto fail;
++
++		*t1 = &chan_info_tbl_p_1[i];
++		freq = chan_info_tbl_p_1[i].freq;
++
++	} else {
++		for (i = 0; i < ARRAY_SIZE(chan_info_nphy_2055); i++)
++			if (chan_info_nphy_2055[i].chan == channel)
++				break;
++
++		if (i >= ARRAY_SIZE(chan_info_nphy_2055))
++			goto fail;
++
++		*t3 = &chan_info_nphy_2055[i];
++		freq = chan_info_nphy_2055[i].freq;
++	}
++
++	*f = freq;
++	return true;
++
++fail:
++	*f = WL_CHAN_FREQ_RANGE_2G;
++	return false;
++}
++
++u8 wlc_phy_get_chan_freq_range_nphy(struct brcms_phy *pi, uint channel)
++{
++	int freq;
++	const struct chan_info_nphy_radio2057 *t0 = NULL;
++	const struct chan_info_nphy_radio205x *t1 = NULL;
++	const struct chan_info_nphy_radio2057_rev5 *t2 = NULL;
++	const struct chan_info_nphy_2055 *t3 = NULL;
++
++	if (channel == 0)
++		channel = CHSPEC_CHANNEL(pi->radio_chanspec);
++
++	wlc_phy_chan2freq_nphy(pi, channel, &freq, &t0, &t1, &t2, &t3);
++
++	if (CHSPEC_IS2G(pi->radio_chanspec))
++		return WL_CHAN_FREQ_RANGE_2G;
++
++	if ((freq >= BASE_LOW_5G_CHAN) && (freq < BASE_MID_5G_CHAN))
++		return WL_CHAN_FREQ_RANGE_5GL;
++	else if ((freq >= BASE_MID_5G_CHAN) && (freq < BASE_HIGH_5G_CHAN))
++		return WL_CHAN_FREQ_RANGE_5GM;
++	else
++		return WL_CHAN_FREQ_RANGE_5GH;
++}
++
++static void
++wlc_phy_chanspec_radio2055_setup(struct brcms_phy *pi,
++				 const struct chan_info_nphy_2055 *ci)
++{
++
++	write_radio_reg(pi, RADIO_2055_PLL_REF, ci->RF_pll_ref);
++	write_radio_reg(pi, RADIO_2055_RF_PLL_MOD0, ci->RF_rf_pll_mod0);
++	write_radio_reg(pi, RADIO_2055_RF_PLL_MOD1, ci->RF_rf_pll_mod1);
++	write_radio_reg(pi, RADIO_2055_VCO_CAP_TAIL, ci->RF_vco_cap_tail);
++
++	BRCMS_PHY_WAR_PR51571(pi);
++
++	write_radio_reg(pi, RADIO_2055_VCO_CAL1, ci->RF_vco_cal1);
++	write_radio_reg(pi, RADIO_2055_VCO_CAL2, ci->RF_vco_cal2);
++	write_radio_reg(pi, RADIO_2055_PLL_LF_C1, ci->RF_pll_lf_c1);
++	write_radio_reg(pi, RADIO_2055_PLL_LF_R1, ci->RF_pll_lf_r1);
++
++	BRCMS_PHY_WAR_PR51571(pi);
++
++	write_radio_reg(pi, RADIO_2055_PLL_LF_C2, ci->RF_pll_lf_c2);
++	write_radio_reg(pi, RADIO_2055_LGBUF_CEN_BUF, ci->RF_lgbuf_cen_buf);
++	write_radio_reg(pi, RADIO_2055_LGEN_TUNE1, ci->RF_lgen_tune1);
++	write_radio_reg(pi, RADIO_2055_LGEN_TUNE2, ci->RF_lgen_tune2);
++
++	BRCMS_PHY_WAR_PR51571(pi);
++
++	write_radio_reg(pi, RADIO_2055_CORE1_LGBUF_A_TUNE,
++			ci->RF_core1_lgbuf_a_tune);
++	write_radio_reg(pi, RADIO_2055_CORE1_LGBUF_G_TUNE,
++			ci->RF_core1_lgbuf_g_tune);
++	write_radio_reg(pi, RADIO_2055_CORE1_RXRF_REG1, ci->RF_core1_rxrf_reg1);
++	write_radio_reg(pi, RADIO_2055_CORE1_TX_PGA_PAD_TN,
++			ci->RF_core1_tx_pga_pad_tn);
++
++	BRCMS_PHY_WAR_PR51571(pi);
++
++	write_radio_reg(pi, RADIO_2055_CORE1_TX_MX_BGTRIM,
++			ci->RF_core1_tx_mx_bgtrim);
++	write_radio_reg(pi, RADIO_2055_CORE2_LGBUF_A_TUNE,
++			ci->RF_core2_lgbuf_a_tune);
++	write_radio_reg(pi, RADIO_2055_CORE2_LGBUF_G_TUNE,
++			ci->RF_core2_lgbuf_g_tune);
++	write_radio_reg(pi, RADIO_2055_CORE2_RXRF_REG1, ci->RF_core2_rxrf_reg1);
++
++	BRCMS_PHY_WAR_PR51571(pi);
++
++	write_radio_reg(pi, RADIO_2055_CORE2_TX_PGA_PAD_TN,
++			ci->RF_core2_tx_pga_pad_tn);
++	write_radio_reg(pi, RADIO_2055_CORE2_TX_MX_BGTRIM,
++			ci->RF_core2_tx_mx_bgtrim);
++
++	udelay(50);
++
++	write_radio_reg(pi, RADIO_2055_VCO_CAL10, 0x05);
++	write_radio_reg(pi, RADIO_2055_VCO_CAL10, 0x45);
++
++	BRCMS_PHY_WAR_PR51571(pi);
++
++	write_radio_reg(pi, RADIO_2055_VCO_CAL10, 0x65);
++
++	udelay(300);
++}
++
++static void
++wlc_phy_chanspec_radio2056_setup(struct brcms_phy *pi,
++				 const struct chan_info_nphy_radio205x *ci)
++{
++	const struct radio_regs *regs_SYN_2056_ptr = NULL;
++
++	write_radio_reg(pi,
++			RADIO_2056_SYN_PLL_VCOCAL1 | RADIO_2056_SYN,
++			ci->RF_SYN_pll_vcocal1);
++	write_radio_reg(pi, RADIO_2056_SYN_PLL_VCOCAL2 | RADIO_2056_SYN,
++			ci->RF_SYN_pll_vcocal2);
++	write_radio_reg(pi, RADIO_2056_SYN_PLL_REFDIV | RADIO_2056_SYN,
++			ci->RF_SYN_pll_refdiv);
++	write_radio_reg(pi, RADIO_2056_SYN_PLL_MMD2 | RADIO_2056_SYN,
++			ci->RF_SYN_pll_mmd2);
++	write_radio_reg(pi, RADIO_2056_SYN_PLL_MMD1 | RADIO_2056_SYN,
++			ci->RF_SYN_pll_mmd1);
++	write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER1 | RADIO_2056_SYN,
++			ci->RF_SYN_pll_loopfilter1);
++	write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER2 | RADIO_2056_SYN,
++			ci->RF_SYN_pll_loopfilter2);
++	write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER3 | RADIO_2056_SYN,
++			ci->RF_SYN_pll_loopfilter3);
++	write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER4 | RADIO_2056_SYN,
++			ci->RF_SYN_pll_loopfilter4);
++	write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER5 | RADIO_2056_SYN,
++			ci->RF_SYN_pll_loopfilter5);
++	write_radio_reg(pi, RADIO_2056_SYN_RESERVED_ADDR27 | RADIO_2056_SYN,
++			ci->RF_SYN_reserved_addr27);
++	write_radio_reg(pi, RADIO_2056_SYN_RESERVED_ADDR28 | RADIO_2056_SYN,
++			ci->RF_SYN_reserved_addr28);
++	write_radio_reg(pi, RADIO_2056_SYN_RESERVED_ADDR29 | RADIO_2056_SYN,
++			ci->RF_SYN_reserved_addr29);
++	write_radio_reg(pi, RADIO_2056_SYN_LOGEN_VCOBUF1 | RADIO_2056_SYN,
++			ci->RF_SYN_logen_VCOBUF1);
++	write_radio_reg(pi, RADIO_2056_SYN_LOGEN_MIXER2 | RADIO_2056_SYN,
++			ci->RF_SYN_logen_MIXER2);
++	write_radio_reg(pi, RADIO_2056_SYN_LOGEN_BUF3 | RADIO_2056_SYN,
++			ci->RF_SYN_logen_BUF3);
++	write_radio_reg(pi, RADIO_2056_SYN_LOGEN_BUF4 | RADIO_2056_SYN,
++			ci->RF_SYN_logen_BUF4);
++
++	write_radio_reg(pi,
++			RADIO_2056_RX_LNAA_TUNE | RADIO_2056_RX0,
++			ci->RF_RX0_lnaa_tune);
++	write_radio_reg(pi, RADIO_2056_RX_LNAG_TUNE | RADIO_2056_RX0,
++			ci->RF_RX0_lnag_tune);
++	write_radio_reg(pi, RADIO_2056_TX_INTPAA_BOOST_TUNE | RADIO_2056_TX0,
++			ci->RF_TX0_intpaa_boost_tune);
++	write_radio_reg(pi, RADIO_2056_TX_INTPAG_BOOST_TUNE | RADIO_2056_TX0,
++			ci->RF_TX0_intpag_boost_tune);
++	write_radio_reg(pi, RADIO_2056_TX_PADA_BOOST_TUNE | RADIO_2056_TX0,
++			ci->RF_TX0_pada_boost_tune);
++	write_radio_reg(pi, RADIO_2056_TX_PADG_BOOST_TUNE | RADIO_2056_TX0,
++			ci->RF_TX0_padg_boost_tune);
++	write_radio_reg(pi, RADIO_2056_TX_PGAA_BOOST_TUNE | RADIO_2056_TX0,
++			ci->RF_TX0_pgaa_boost_tune);
++	write_radio_reg(pi, RADIO_2056_TX_PGAG_BOOST_TUNE | RADIO_2056_TX0,
++			ci->RF_TX0_pgag_boost_tune);
++	write_radio_reg(pi, RADIO_2056_TX_MIXA_BOOST_TUNE | RADIO_2056_TX0,
++			ci->RF_TX0_mixa_boost_tune);
++	write_radio_reg(pi, RADIO_2056_TX_MIXG_BOOST_TUNE | RADIO_2056_TX0,
++			ci->RF_TX0_mixg_boost_tune);
++
++	write_radio_reg(pi,
++			RADIO_2056_RX_LNAA_TUNE | RADIO_2056_RX1,
++			ci->RF_RX1_lnaa_tune);
++	write_radio_reg(pi, RADIO_2056_RX_LNAG_TUNE | RADIO_2056_RX1,
++			ci->RF_RX1_lnag_tune);
++	write_radio_reg(pi, RADIO_2056_TX_INTPAA_BOOST_TUNE | RADIO_2056_TX1,
++			ci->RF_TX1_intpaa_boost_tune);
++	write_radio_reg(pi, RADIO_2056_TX_INTPAG_BOOST_TUNE | RADIO_2056_TX1,
++			ci->RF_TX1_intpag_boost_tune);
++	write_radio_reg(pi, RADIO_2056_TX_PADA_BOOST_TUNE | RADIO_2056_TX1,
++			ci->RF_TX1_pada_boost_tune);
++	write_radio_reg(pi, RADIO_2056_TX_PADG_BOOST_TUNE | RADIO_2056_TX1,
++			ci->RF_TX1_padg_boost_tune);
++	write_radio_reg(pi, RADIO_2056_TX_PGAA_BOOST_TUNE | RADIO_2056_TX1,
++			ci->RF_TX1_pgaa_boost_tune);
++	write_radio_reg(pi, RADIO_2056_TX_PGAG_BOOST_TUNE | RADIO_2056_TX1,
++			ci->RF_TX1_pgag_boost_tune);
++	write_radio_reg(pi, RADIO_2056_TX_MIXA_BOOST_TUNE | RADIO_2056_TX1,
++			ci->RF_TX1_mixa_boost_tune);
++	write_radio_reg(pi, RADIO_2056_TX_MIXG_BOOST_TUNE | RADIO_2056_TX1,
++			ci->RF_TX1_mixg_boost_tune);
++
++	if (NREV_IS(pi->pubpi.phy_rev, 3))
++		regs_SYN_2056_ptr = regs_SYN_2056;
++	else if (NREV_IS(pi->pubpi.phy_rev, 4))
++		regs_SYN_2056_ptr = regs_SYN_2056_A1;
++	else {
++		switch (pi->pubpi.radiorev) {
++		case 5:
++			regs_SYN_2056_ptr = regs_SYN_2056_rev5;
++			break;
++		case 6:
++			regs_SYN_2056_ptr = regs_SYN_2056_rev6;
++			break;
++		case 7:
++		case 9:
++			regs_SYN_2056_ptr = regs_SYN_2056_rev7;
++			break;
++		case 8:
++			regs_SYN_2056_ptr = regs_SYN_2056_rev8;
++			break;
++		case 11:
++			regs_SYN_2056_ptr = regs_SYN_2056_rev11;
++			break;
++		}
++	}
++	if (CHSPEC_IS2G(pi->radio_chanspec))
++		write_radio_reg(pi, RADIO_2056_SYN_PLL_CP2 |
++				RADIO_2056_SYN,
++				(u16) regs_SYN_2056_ptr[0x49 - 2].init_g);
++	else
++		write_radio_reg(pi, RADIO_2056_SYN_PLL_CP2 |
++				RADIO_2056_SYN,
++				(u16) regs_SYN_2056_ptr[0x49 - 2].init_a);
++
++	if (pi->sh->boardflags2 & BFL2_GPLL_WAR) {
++		if (CHSPEC_IS2G(pi->radio_chanspec)) {
++			write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER1 |
++					RADIO_2056_SYN, 0x1f);
++			write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER2 |
++					RADIO_2056_SYN, 0x1f);
++
++			write_radio_reg(pi,
++					RADIO_2056_SYN_PLL_LOOPFILTER4 |
++					RADIO_2056_SYN, 0xb);
++			write_radio_reg(pi,
++					RADIO_2056_SYN_PLL_CP2 |
++					RADIO_2056_SYN, 0x14);
++		}
++	}
++
++	if ((pi->sh->boardflags2 & BFL2_GPLL_WAR2) &&
++	    (CHSPEC_IS2G(pi->radio_chanspec))) {
++		write_radio_reg(pi,
++				RADIO_2056_SYN_PLL_LOOPFILTER1 | RADIO_2056_SYN,
++				0x1f);
++		write_radio_reg(pi,
++				RADIO_2056_SYN_PLL_LOOPFILTER2 | RADIO_2056_SYN,
++				0x1f);
++		write_radio_reg(pi,
++				RADIO_2056_SYN_PLL_LOOPFILTER4 | RADIO_2056_SYN,
++				0xb);
++		write_radio_reg(pi, RADIO_2056_SYN_PLL_CP2 | RADIO_2056_SYN,
++				0x20);
++	}
++
++	if (pi->sh->boardflags2 & BFL2_APLL_WAR) {
++		if (CHSPEC_IS5G(pi->radio_chanspec)) {
++			write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER1 |
++					RADIO_2056_SYN, 0x1f);
++			write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER2 |
++					RADIO_2056_SYN, 0x1f);
++			write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER4 |
++					RADIO_2056_SYN, 0x5);
++			write_radio_reg(pi, RADIO_2056_SYN_PLL_CP2 |
++					RADIO_2056_SYN, 0xc);
++		}
++	}
++
++	if (PHY_IPA(pi) && CHSPEC_IS2G(pi->radio_chanspec)) {
++		u16 pag_boost_tune;
++		u16 padg_boost_tune;
++		u16 pgag_boost_tune;
++		u16 mixg_boost_tune;
++		u16 bias, cascbias;
++		uint core;
++
++		for (core = 0; core < pi->pubpi.phy_corenum; core++) {
++
++			if (NREV_GE(pi->pubpi.phy_rev, 5)) {
++
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++						 PADG_IDAC, 0xcc);
++
++				bias = 0x25;
++				cascbias = 0x20;
++
++				if ((pi->sh->chip ==
++				     BCM43224_CHIP_ID)
++				    || (pi->sh->chip ==
++					BCM43225_CHIP_ID)) {
++					if (pi->sh->chippkg ==
++					    BCM43224_FAB_SMIC) {
++						bias = 0x2a;
++						cascbias = 0x38;
++					}
++				}
++
++				pag_boost_tune = 0x4;
++				pgag_boost_tune = 0x03;
++				padg_boost_tune = 0x77;
++				mixg_boost_tune = 0x65;
++
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++						 INTPAG_IMAIN_STAT, bias);
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++						 INTPAG_IAUX_STAT, bias);
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++						 INTPAG_CASCBIAS, cascbias);
++
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++						 INTPAG_BOOST_TUNE,
++						 pag_boost_tune);
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++						 PGAG_BOOST_TUNE,
++						 pgag_boost_tune);
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++						 PADG_BOOST_TUNE,
++						 padg_boost_tune);
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++						 MIXG_BOOST_TUNE,
++						 mixg_boost_tune);
++			} else {
++
++				bias = (pi->bw == WL_CHANSPEC_BW_40) ?
++				       0x40 : 0x20;
++
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++						 INTPAG_IMAIN_STAT, bias);
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++						 INTPAG_IAUX_STAT, bias);
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++						 INTPAG_CASCBIAS, 0x30);
++			}
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, PA_SPARE1,
++					 0xee);
++		}
++	}
++
++	if (PHY_IPA(pi) && NREV_IS(pi->pubpi.phy_rev, 6)
++	    && CHSPEC_IS5G(pi->radio_chanspec)) {
++		u16 paa_boost_tune;
++		u16 pada_boost_tune;
++		u16 pgaa_boost_tune;
++		u16 mixa_boost_tune;
++		u16 freq, pabias, cascbias;
++		uint core;
++
++		freq = CHAN5G_FREQ(CHSPEC_CHANNEL(pi->radio_chanspec));
++
++		if (freq < 5150) {
++
++			paa_boost_tune = 0xa;
++			pada_boost_tune = 0x77;
++			pgaa_boost_tune = 0xf;
++			mixa_boost_tune = 0xf;
++		} else if (freq < 5340) {
++
++			paa_boost_tune = 0x8;
++			pada_boost_tune = 0x77;
++			pgaa_boost_tune = 0xfb;
++			mixa_boost_tune = 0xf;
++		} else if (freq < 5650) {
++
++			paa_boost_tune = 0x0;
++			pada_boost_tune = 0x77;
++			pgaa_boost_tune = 0xb;
++			mixa_boost_tune = 0xf;
++		} else {
++
++			paa_boost_tune = 0x0;
++			pada_boost_tune = 0x77;
++			if (freq != 5825)
++				pgaa_boost_tune = -(int)(freq - 18) / 36 + 168;
++			else
++				pgaa_boost_tune = 6;
++
++			mixa_boost_tune = 0xf;
++		}
++
++		for (core = 0; core < pi->pubpi.phy_corenum; core++) {
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++					 INTPAA_BOOST_TUNE, paa_boost_tune);
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++					 PADA_BOOST_TUNE, pada_boost_tune);
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++					 PGAA_BOOST_TUNE, pgaa_boost_tune);
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++					 MIXA_BOOST_TUNE, mixa_boost_tune);
++
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++					 TXSPARE1, 0x30);
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++					 PA_SPARE2, 0xee);
++
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++					 PADA_CASCBIAS, 0x3);
++
++			cascbias = 0x30;
++
++			if ((pi->sh->chip == BCM43224_CHIP_ID) ||
++			    (pi->sh->chip == BCM43225_CHIP_ID)) {
++				if (pi->sh->chippkg == BCM43224_FAB_SMIC)
++					cascbias = 0x35;
++			}
++
++			pabias = (pi->phy_pabias == 0) ? 0x30 : pi->phy_pabias;
++
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++					 INTPAA_IAUX_STAT, pabias);
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++					 INTPAA_IMAIN_STAT, pabias);
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++					 INTPAA_CASCBIAS, cascbias);
++		}
++	}
++
++	udelay(50);
++
++	wlc_phy_radio205x_vcocal_nphy(pi);
++}
++
++void wlc_phy_radio205x_vcocal_nphy(struct brcms_phy *pi)
++{
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_EN, 0x01, 0x0);
++		mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_CAL_RESETN, 0x04, 0x0);
++		mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_CAL_RESETN, 0x04,
++			      (1 << 2));
++		mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_EN, 0x01, 0x01);
++	} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		write_radio_reg(pi, RADIO_2056_SYN_PLL_VCOCAL12, 0x0);
++		write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST3, 0x38);
++		write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST3, 0x18);
++		write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST3, 0x38);
++		write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST3, 0x39);
++	}
++
++	udelay(300);
++}
++
++static void
++wlc_phy_chanspec_radio2057_setup(
++	struct brcms_phy *pi,
++	const struct chan_info_nphy_radio2057 *ci,
++	const struct chan_info_nphy_radio2057_rev5 *
++	ci2)
++{
++	int coreNum;
++	u16 txmix2g_tune_boost_pu = 0;
++	u16 pad2g_tune_pus = 0;
++
++	if (pi->pubpi.radiorev == 5) {
++
++		write_radio_reg(pi,
++				RADIO_2057_VCOCAL_COUNTVAL0,
++				ci2->RF_vcocal_countval0);
++		write_radio_reg(pi, RADIO_2057_VCOCAL_COUNTVAL1,
++				ci2->RF_vcocal_countval1);
++		write_radio_reg(pi, RADIO_2057_RFPLL_REFMASTER_SPAREXTALSIZE,
++				ci2->RF_rfpll_refmaster_sparextalsize);
++		write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1,
++				ci2->RF_rfpll_loopfilter_r1);
++		write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2,
++				ci2->RF_rfpll_loopfilter_c2);
++		write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1,
++				ci2->RF_rfpll_loopfilter_c1);
++		write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC,
++				ci2->RF_cp_kpd_idac);
++		write_radio_reg(pi, RADIO_2057_RFPLL_MMD0, ci2->RF_rfpll_mmd0);
++		write_radio_reg(pi, RADIO_2057_RFPLL_MMD1, ci2->RF_rfpll_mmd1);
++		write_radio_reg(pi,
++				RADIO_2057_VCOBUF_TUNE, ci2->RF_vcobuf_tune);
++		write_radio_reg(pi,
++				RADIO_2057_LOGEN_MX2G_TUNE,
++				ci2->RF_logen_mx2g_tune);
++		write_radio_reg(pi, RADIO_2057_LOGEN_INDBUF2G_TUNE,
++				ci2->RF_logen_indbuf2g_tune);
++
++		write_radio_reg(pi,
++				RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE0,
++				ci2->RF_txmix2g_tune_boost_pu_core0);
++		write_radio_reg(pi,
++				RADIO_2057_PAD2G_TUNE_PUS_CORE0,
++				ci2->RF_pad2g_tune_pus_core0);
++		write_radio_reg(pi, RADIO_2057_LNA2G_TUNE_CORE0,
++				ci2->RF_lna2g_tune_core0);
++
++		write_radio_reg(pi,
++				RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE1,
++				ci2->RF_txmix2g_tune_boost_pu_core1);
++		write_radio_reg(pi,
++				RADIO_2057_PAD2G_TUNE_PUS_CORE1,
++				ci2->RF_pad2g_tune_pus_core1);
++		write_radio_reg(pi, RADIO_2057_LNA2G_TUNE_CORE1,
++				ci2->RF_lna2g_tune_core1);
++
++	} else {
++
++		write_radio_reg(pi,
++				RADIO_2057_VCOCAL_COUNTVAL0,
++				ci->RF_vcocal_countval0);
++		write_radio_reg(pi, RADIO_2057_VCOCAL_COUNTVAL1,
++				ci->RF_vcocal_countval1);
++		write_radio_reg(pi, RADIO_2057_RFPLL_REFMASTER_SPAREXTALSIZE,
++				ci->RF_rfpll_refmaster_sparextalsize);
++		write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1,
++				ci->RF_rfpll_loopfilter_r1);
++		write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2,
++				ci->RF_rfpll_loopfilter_c2);
++		write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1,
++				ci->RF_rfpll_loopfilter_c1);
++		write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC, ci->RF_cp_kpd_idac);
++		write_radio_reg(pi, RADIO_2057_RFPLL_MMD0, ci->RF_rfpll_mmd0);
++		write_radio_reg(pi, RADIO_2057_RFPLL_MMD1, ci->RF_rfpll_mmd1);
++		write_radio_reg(pi, RADIO_2057_VCOBUF_TUNE, ci->RF_vcobuf_tune);
++		write_radio_reg(pi,
++				RADIO_2057_LOGEN_MX2G_TUNE,
++				ci->RF_logen_mx2g_tune);
++		write_radio_reg(pi, RADIO_2057_LOGEN_MX5G_TUNE,
++				ci->RF_logen_mx5g_tune);
++		write_radio_reg(pi, RADIO_2057_LOGEN_INDBUF2G_TUNE,
++				ci->RF_logen_indbuf2g_tune);
++		write_radio_reg(pi, RADIO_2057_LOGEN_INDBUF5G_TUNE,
++				ci->RF_logen_indbuf5g_tune);
++
++		write_radio_reg(pi,
++				RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE0,
++				ci->RF_txmix2g_tune_boost_pu_core0);
++		write_radio_reg(pi,
++				RADIO_2057_PAD2G_TUNE_PUS_CORE0,
++				ci->RF_pad2g_tune_pus_core0);
++		write_radio_reg(pi, RADIO_2057_PGA_BOOST_TUNE_CORE0,
++				ci->RF_pga_boost_tune_core0);
++		write_radio_reg(pi, RADIO_2057_TXMIX5G_BOOST_TUNE_CORE0,
++				ci->RF_txmix5g_boost_tune_core0);
++		write_radio_reg(pi, RADIO_2057_PAD5G_TUNE_MISC_PUS_CORE0,
++				ci->RF_pad5g_tune_misc_pus_core0);
++		write_radio_reg(pi, RADIO_2057_LNA2G_TUNE_CORE0,
++				ci->RF_lna2g_tune_core0);
++		write_radio_reg(pi, RADIO_2057_LNA5G_TUNE_CORE0,
++				ci->RF_lna5g_tune_core0);
++
++		write_radio_reg(pi,
++				RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE1,
++				ci->RF_txmix2g_tune_boost_pu_core1);
++		write_radio_reg(pi,
++				RADIO_2057_PAD2G_TUNE_PUS_CORE1,
++				ci->RF_pad2g_tune_pus_core1);
++		write_radio_reg(pi, RADIO_2057_PGA_BOOST_TUNE_CORE1,
++				ci->RF_pga_boost_tune_core1);
++		write_radio_reg(pi, RADIO_2057_TXMIX5G_BOOST_TUNE_CORE1,
++				ci->RF_txmix5g_boost_tune_core1);
++		write_radio_reg(pi, RADIO_2057_PAD5G_TUNE_MISC_PUS_CORE1,
++				ci->RF_pad5g_tune_misc_pus_core1);
++		write_radio_reg(pi, RADIO_2057_LNA2G_TUNE_CORE1,
++				ci->RF_lna2g_tune_core1);
++		write_radio_reg(pi, RADIO_2057_LNA5G_TUNE_CORE1,
++				ci->RF_lna5g_tune_core1);
++	}
++
++	if ((pi->pubpi.radiorev <= 4) || (pi->pubpi.radiorev == 6)) {
++
++		if (CHSPEC_IS2G(pi->radio_chanspec)) {
++			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1,
++					0x3f);
++			write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC, 0x3f);
++			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1,
++					0x8);
++			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2,
++					0x8);
++		} else {
++			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1,
++					0x1f);
++			write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC, 0x3f);
++			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1,
++					0x8);
++			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2,
++					0x8);
++		}
++	} else if ((pi->pubpi.radiorev == 5) || (pi->pubpi.radiorev == 7) ||
++		   (pi->pubpi.radiorev == 8)) {
++
++		if (CHSPEC_IS2G(pi->radio_chanspec)) {
++			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1,
++					0x1b);
++			write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC, 0x30);
++			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1,
++					0xa);
++			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2,
++					0xa);
++		} else {
++			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1,
++					0x1f);
++			write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC, 0x3f);
++			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1,
++					0x8);
++			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2,
++					0x8);
++		}
++
++	}
++
++	if (CHSPEC_IS2G(pi->radio_chanspec)) {
++		if (PHY_IPA(pi)) {
++			if (pi->pubpi.radiorev == 3)
++				txmix2g_tune_boost_pu = 0x6b;
++
++			if (pi->pubpi.radiorev == 5)
++				pad2g_tune_pus = 0x73;
++
++		} else {
++			if (pi->pubpi.radiorev != 5) {
++				pad2g_tune_pus = 0x3;
++
++				txmix2g_tune_boost_pu = 0x61;
++			}
++		}
++
++		for (coreNum = 0; coreNum <= 1; coreNum++) {
++
++			if (txmix2g_tune_boost_pu != 0)
++				WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum,
++						 TXMIX2G_TUNE_BOOST_PU,
++						 txmix2g_tune_boost_pu);
++
++			if (pad2g_tune_pus != 0)
++				WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum,
++						 PAD2G_TUNE_PUS,
++						 pad2g_tune_pus);
++		}
++	}
++
++	udelay(50);
++
++	wlc_phy_radio205x_vcocal_nphy(pi);
++}
++
++static void
++wlc_phy_chanspec_nphy_setup(struct brcms_phy *pi, u16 chanspec,
++			    const struct nphy_sfo_cfg *ci)
++{
++	u16 val;
++
++	val = read_phy_reg(pi, 0x09) & NPHY_BandControl_currentBand;
++	if (CHSPEC_IS5G(chanspec) && !val) {
++
++		val = bcma_read16(pi->d11core, D11REGOFFS(psm_phy_hdr_param));
++		bcma_write16(pi->d11core, D11REGOFFS(psm_phy_hdr_param),
++		      (val | MAC_PHY_FORCE_CLK));
++
++		or_phy_reg(pi, (NPHY_TO_BPHY_OFF + BPHY_BB_CONFIG),
++			   (BBCFG_RESETCCA | BBCFG_RESETRX));
++
++		bcma_write16(pi->d11core, D11REGOFFS(psm_phy_hdr_param), val);
++
++		or_phy_reg(pi, 0x09, NPHY_BandControl_currentBand);
++	} else if (!CHSPEC_IS5G(chanspec) && val) {
++
++		and_phy_reg(pi, 0x09, ~NPHY_BandControl_currentBand);
++
++		val = bcma_read16(pi->d11core, D11REGOFFS(psm_phy_hdr_param));
++		bcma_write16(pi->d11core, D11REGOFFS(psm_phy_hdr_param),
++		      (val | MAC_PHY_FORCE_CLK));
++
++		and_phy_reg(pi, (NPHY_TO_BPHY_OFF + BPHY_BB_CONFIG),
++			    (u16) (~(BBCFG_RESETCCA | BBCFG_RESETRX)));
++
++		bcma_write16(pi->d11core, D11REGOFFS(psm_phy_hdr_param), val);
++	}
++
++	write_phy_reg(pi, 0x1ce, ci->PHY_BW1a);
++	write_phy_reg(pi, 0x1cf, ci->PHY_BW2);
++	write_phy_reg(pi, 0x1d0, ci->PHY_BW3);
++
++	write_phy_reg(pi, 0x1d1, ci->PHY_BW4);
++	write_phy_reg(pi, 0x1d2, ci->PHY_BW5);
++	write_phy_reg(pi, 0x1d3, ci->PHY_BW6);
++
++	if (CHSPEC_CHANNEL(pi->radio_chanspec) == 14) {
++		wlc_phy_classifier_nphy(pi, NPHY_ClassifierCtrl_ofdm_en, 0);
++
++		or_phy_reg(pi, NPHY_TO_BPHY_OFF + BPHY_TEST, 0x800);
++	} else {
++		wlc_phy_classifier_nphy(pi, NPHY_ClassifierCtrl_ofdm_en,
++					NPHY_ClassifierCtrl_ofdm_en);
++
++		if (CHSPEC_IS2G(chanspec))
++			and_phy_reg(pi, NPHY_TO_BPHY_OFF + BPHY_TEST, ~0x840);
++	}
++
++	if (pi->nphy_txpwrctrl == PHY_TPC_HW_OFF)
++		wlc_phy_txpwr_fixpower_nphy(pi);
++
++	if (NREV_LT(pi->pubpi.phy_rev, 3))
++		wlc_phy_adjust_lnagaintbl_nphy(pi);
++
++	wlc_phy_txlpfbw_nphy(pi);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)
++	    && (pi->phy_spuravoid != SPURAVOID_DISABLE)) {
++		u8 spuravoid = 0;
++
++		val = CHSPEC_CHANNEL(chanspec);
++		if (!CHSPEC_IS40(pi->radio_chanspec)) {
++			if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++				if ((val == 13) || (val == 14) || (val == 153))
++					spuravoid = 1;
++			} else if (((val >= 5) && (val <= 8)) || (val == 13)
++				   || (val == 14)) {
++				spuravoid = 1;
++			}
++		} else if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			if (val == 54)
++				spuravoid = 1;
++		} else {
++			if (pi->nphy_aband_spurwar_en &&
++			    ((val == 38) || (val == 102)
++			     || (val == 118)))
++				spuravoid = 1;
++		}
++
++		if (pi->phy_spuravoid == SPURAVOID_FORCEON)
++			spuravoid = 1;
++
++		wlapi_bmac_core_phypll_ctl(pi->sh->physhim, false);
++		si_pmu_spuravoid_pllupdate(pi->sh->sih, spuravoid);
++		wlapi_bmac_core_phypll_ctl(pi->sh->physhim, true);
++
++		if ((pi->sh->chip == BCM43224_CHIP_ID) ||
++		    (pi->sh->chip == BCM43225_CHIP_ID)) {
++			if (spuravoid == 1) {
++				bcma_write16(pi->d11core,
++					     D11REGOFFS(tsf_clk_frac_l),
++					     0x5341);
++				bcma_write16(pi->d11core,
++					     D11REGOFFS(tsf_clk_frac_h), 0x8);
++			} else {
++				bcma_write16(pi->d11core,
++					     D11REGOFFS(tsf_clk_frac_l),
++					     0x8889);
++				bcma_write16(pi->d11core,
++					     D11REGOFFS(tsf_clk_frac_h), 0x8);
++			}
++		}
++
++		wlapi_bmac_core_phypll_reset(pi->sh->physhim);
++
++		mod_phy_reg(pi, 0x01, (0x1 << 15),
++			    ((spuravoid > 0) ? (0x1 << 15) : 0));
++
++		wlc_phy_resetcca_nphy(pi);
++
++		pi->phy_isspuravoid = (spuravoid > 0);
++	}
++
++	if (NREV_LT(pi->pubpi.phy_rev, 7))
++		write_phy_reg(pi, 0x17e, 0x3830);
++
++	wlc_phy_spurwar_nphy(pi);
++}
++
++void wlc_phy_chanspec_set_nphy(struct brcms_phy *pi, u16 chanspec)
++{
++	int freq;
++	const struct chan_info_nphy_radio2057 *t0 = NULL;
++	const struct chan_info_nphy_radio205x *t1 = NULL;
++	const struct chan_info_nphy_radio2057_rev5 *t2 = NULL;
++	const struct chan_info_nphy_2055 *t3 = NULL;
++
++	if (!wlc_phy_chan2freq_nphy
++		    (pi, CHSPEC_CHANNEL(chanspec), &freq, &t0, &t1, &t2, &t3))
++		return;
++
++	wlc_phy_chanspec_radio_set((struct brcms_phy_pub *) pi, chanspec);
++
++	if (CHSPEC_BW(chanspec) != pi->bw)
++		wlapi_bmac_bw_set(pi->sh->physhim, CHSPEC_BW(chanspec));
++
++	if (CHSPEC_IS40(chanspec)) {
++		if (CHSPEC_SB_UPPER(chanspec)) {
++			or_phy_reg(pi, 0xa0, BPHY_BAND_SEL_UP20);
++			if (NREV_GE(pi->pubpi.phy_rev, 7))
++				or_phy_reg(pi, 0x310, PRIM_SEL_UP20);
++		} else {
++			and_phy_reg(pi, 0xa0, ~BPHY_BAND_SEL_UP20);
++			if (NREV_GE(pi->pubpi.phy_rev, 7))
++				and_phy_reg(pi, 0x310,
++					    (~PRIM_SEL_UP20 & 0xffff));
++		}
++	}
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++
++			if ((pi->pubpi.radiorev <= 4)
++			    || (pi->pubpi.radiorev == 6)) {
++				mod_radio_reg(pi, RADIO_2057_TIA_CONFIG_CORE0,
++					      0x2,
++					      (CHSPEC_IS5G(chanspec) ? (1 << 1)
++					       : 0));
++				mod_radio_reg(pi, RADIO_2057_TIA_CONFIG_CORE1,
++					      0x2,
++					      (CHSPEC_IS5G(chanspec) ? (1 << 1)
++					       : 0));
++			}
++
++			wlc_phy_chanspec_radio2057_setup(pi, t0, t2);
++			wlc_phy_chanspec_nphy_setup(pi, chanspec,
++				(pi->pubpi.radiorev == 5) ?
++				(const struct nphy_sfo_cfg *)&(t2->PHY_BW1a) :
++				(const struct nphy_sfo_cfg *)&(t0->PHY_BW1a));
++
++		} else {
++
++			mod_radio_reg(pi,
++				      RADIO_2056_SYN_COM_CTRL | RADIO_2056_SYN,
++				      0x4,
++				      (CHSPEC_IS5G(chanspec) ? (0x1 << 2) : 0));
++			wlc_phy_chanspec_radio2056_setup(pi, t1);
++
++			wlc_phy_chanspec_nphy_setup(pi, chanspec,
++				(const struct nphy_sfo_cfg *) &(t1->PHY_BW1a));
++		}
++
++	} else {
++
++		mod_radio_reg(pi, RADIO_2055_MASTER_CNTRL1, 0x70,
++			      (CHSPEC_IS5G(chanspec) ? (0x02 << 4)
++			       : (0x05 << 4)));
++
++		wlc_phy_chanspec_radio2055_setup(pi, t3);
++		wlc_phy_chanspec_nphy_setup(pi, chanspec,
++					    (const struct nphy_sfo_cfg *)
++					     &(t3->PHY_BW1a));
++	}
++
++}
++
++void wlc_phy_antsel_init(struct brcms_phy_pub *ppi, bool lut_init)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++	u16 mask = 0xfc00;
++	u32 mc = 0;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7))
++		return;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		u16 v0 = 0x211, v1 = 0x222, v2 = 0x144, v3 = 0x188;
++
++		if (!lut_init)
++			return;
++
++		if (pi->srom_fem2g.antswctrllut == 0) {
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
++						 1, 0x02, 16, &v0);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
++						 1, 0x03, 16, &v1);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
++						 1, 0x08, 16, &v2);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
++						 1, 0x0C, 16, &v3);
++		}
++
++		if (pi->srom_fem5g.antswctrllut == 0) {
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
++						 1, 0x12, 16, &v0);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
++						 1, 0x13, 16, &v1);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
++						 1, 0x18, 16, &v2);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
++						 1, 0x1C, 16, &v3);
++		}
++	} else {
++
++		write_phy_reg(pi, 0xc8, 0x0);
++		write_phy_reg(pi, 0xc9, 0x0);
++
++		bcma_chipco_gpio_control(&pi->d11core->bus->drv_cc, mask, mask);
++
++		mc = bcma_read32(pi->d11core, D11REGOFFS(maccontrol));
++		mc &= ~MCTL_GPOUT_SEL_MASK;
++		bcma_write32(pi->d11core, D11REGOFFS(maccontrol), mc);
++
++		bcma_set16(pi->d11core, D11REGOFFS(psm_gpio_oe), mask);
++
++		bcma_mask16(pi->d11core, D11REGOFFS(psm_gpio_out), ~mask);
++
++		if (lut_init) {
++			write_phy_reg(pi, 0xf8, 0x02d8);
++			write_phy_reg(pi, 0xf9, 0x0301);
++			write_phy_reg(pi, 0xfa, 0x02d8);
++			write_phy_reg(pi, 0xfb, 0x0301);
++		}
++	}
++}
++
++u16 wlc_phy_classifier_nphy(struct brcms_phy *pi, u16 mask, u16 val)
++{
++	u16 curr_ctl, new_ctl;
++	bool suspended = false;
++
++	if (D11REV_IS(pi->sh->corerev, 16)) {
++		suspended = (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) &
++			     MCTL_EN_MAC) ? false : true;
++		if (!suspended)
++			wlapi_suspend_mac_and_wait(pi->sh->physhim);
++	}
++
++	curr_ctl = read_phy_reg(pi, 0xb0) & (0x7 << 0);
++
++	new_ctl = (curr_ctl & (~mask)) | (val & mask);
++
++	mod_phy_reg(pi, 0xb0, (0x7 << 0), new_ctl);
++
++	if (D11REV_IS(pi->sh->corerev, 16) && !suspended)
++		wlapi_enable_mac(pi->sh->physhim);
++
++	return new_ctl;
++}
++
++void wlc_phy_force_rfseq_nphy(struct brcms_phy *pi, u8 cmd)
++{
++	u16 trigger_mask, status_mask;
++	u16 orig_RfseqCoreActv;
++
++	switch (cmd) {
++	case NPHY_RFSEQ_RX2TX:
++		trigger_mask = NPHY_RfseqTrigger_rx2tx;
++		status_mask = NPHY_RfseqStatus_rx2tx;
++		break;
++	case NPHY_RFSEQ_TX2RX:
++		trigger_mask = NPHY_RfseqTrigger_tx2rx;
++		status_mask = NPHY_RfseqStatus_tx2rx;
++		break;
++	case NPHY_RFSEQ_RESET2RX:
++		trigger_mask = NPHY_RfseqTrigger_reset2rx;
++		status_mask = NPHY_RfseqStatus_reset2rx;
++		break;
++	case NPHY_RFSEQ_UPDATEGAINH:
++		trigger_mask = NPHY_RfseqTrigger_updategainh;
++		status_mask = NPHY_RfseqStatus_updategainh;
++		break;
++	case NPHY_RFSEQ_UPDATEGAINL:
++		trigger_mask = NPHY_RfseqTrigger_updategainl;
++		status_mask = NPHY_RfseqStatus_updategainl;
++		break;
++	case NPHY_RFSEQ_UPDATEGAINU:
++		trigger_mask = NPHY_RfseqTrigger_updategainu;
++		status_mask = NPHY_RfseqStatus_updategainu;
++		break;
++	default:
++		return;
++	}
++
++	orig_RfseqCoreActv = read_phy_reg(pi, 0xa1);
++	or_phy_reg(pi, 0xa1,
++		   (NPHY_RfseqMode_CoreActv_override |
++		    NPHY_RfseqMode_Trigger_override));
++	or_phy_reg(pi, 0xa3, trigger_mask);
++	SPINWAIT((read_phy_reg(pi, 0xa4) & status_mask), 200000);
++	write_phy_reg(pi, 0xa1, orig_RfseqCoreActv);
++	WARN(read_phy_reg(pi, 0xa4) & status_mask, "HW error in rf");
++}
++
++static void
++wlc_phy_rfctrl_override_1tomany_nphy(struct brcms_phy *pi, u16 cmd, u16 value,
++				     u8 core_mask, u8 off)
++{
++	u16 rfmxgain = 0, lpfgain = 0;
++	u16 tgain = 0;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++
++		switch (cmd) {
++		case NPHY_REV7_RfctrlOverride_cmd_rxrf_pu:
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 5),
++				value, core_mask, off,
++				NPHY_REV7_RFCTRLOVERRIDE_ID1);
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 4), value,
++				core_mask, off,
++				NPHY_REV7_RFCTRLOVERRIDE_ID1);
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 3), value,
++				core_mask, off,
++				NPHY_REV7_RFCTRLOVERRIDE_ID1);
++			break;
++		case NPHY_REV7_RfctrlOverride_cmd_rx_pu:
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 2),
++				value, core_mask, off,
++				NPHY_REV7_RFCTRLOVERRIDE_ID1);
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 1), value,
++				core_mask, off,
++				NPHY_REV7_RFCTRLOVERRIDE_ID1);
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 0), value,
++				core_mask, off,
++				NPHY_REV7_RFCTRLOVERRIDE_ID1);
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 1), value,
++				core_mask, off,
++				NPHY_REV7_RFCTRLOVERRIDE_ID2);
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 11), 0,
++				core_mask, off,
++				NPHY_REV7_RFCTRLOVERRIDE_ID1);
++			break;
++		case NPHY_REV7_RfctrlOverride_cmd_tx_pu:
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 2),
++				value, core_mask, off,
++				NPHY_REV7_RFCTRLOVERRIDE_ID0);
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 1), value,
++				core_mask, off,
++				NPHY_REV7_RFCTRLOVERRIDE_ID1);
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 0), value,
++				core_mask, off,
++				NPHY_REV7_RFCTRLOVERRIDE_ID2);
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 2), value,
++				core_mask, off,
++				NPHY_REV7_RFCTRLOVERRIDE_ID2);
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 11), 1,
++				core_mask, off,
++				NPHY_REV7_RFCTRLOVERRIDE_ID1);
++			break;
++		case NPHY_REV7_RfctrlOverride_cmd_rxgain:
++			rfmxgain = value & 0x000ff;
++			lpfgain = value & 0x0ff00;
++			lpfgain = lpfgain >> 8;
++
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 11),
++				rfmxgain, core_mask,
++				off,
++				NPHY_REV7_RFCTRLOVERRIDE_ID0);
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x3 << 13),
++				lpfgain, core_mask,
++				off,
++				NPHY_REV7_RFCTRLOVERRIDE_ID0);
++			break;
++		case NPHY_REV7_RfctrlOverride_cmd_txgain:
++			tgain = value & 0x7fff;
++			lpfgain = value & 0x8000;
++			lpfgain = lpfgain >> 14;
++
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 12),
++				tgain, core_mask, off,
++				NPHY_REV7_RFCTRLOVERRIDE_ID0);
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 13),
++				lpfgain, core_mask,
++				off,
++				NPHY_REV7_RFCTRLOVERRIDE_ID0);
++			break;
++		}
++	}
++}
++
++static void
++wlc_phy_scale_offset_rssi_nphy(struct brcms_phy *pi, u16 scale, s8 offset,
++			       u8 coresel, u8 rail, u8 rssi_type)
++{
++	u16 valuetostuff;
++
++	offset = (offset > NPHY_RSSICAL_MAXREAD) ?
++		 NPHY_RSSICAL_MAXREAD : offset;
++	offset = (offset < (-NPHY_RSSICAL_MAXREAD - 1)) ?
++		 -NPHY_RSSICAL_MAXREAD - 1 : offset;
++
++	valuetostuff = ((scale & 0x3f) << 8) | (offset & 0x3f);
++
++	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_NB))
++		write_phy_reg(pi, 0x1a6, valuetostuff);
++
++	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_NB))
++		write_phy_reg(pi, 0x1ac, valuetostuff);
++
++	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_NB))
++		write_phy_reg(pi, 0x1b2, valuetostuff);
++
++	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_NB))
++		write_phy_reg(pi, 0x1b8, valuetostuff);
++
++	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_W1))
++		write_phy_reg(pi, 0x1a4, valuetostuff);
++
++	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_W1))
++		write_phy_reg(pi, 0x1aa, valuetostuff);
++
++	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_W1))
++		write_phy_reg(pi, 0x1b0, valuetostuff);
++
++	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_W1))
++		write_phy_reg(pi, 0x1b6, valuetostuff);
++
++	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_W2))
++		write_phy_reg(pi, 0x1a5, valuetostuff);
++	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_W2))
++		write_phy_reg(pi, 0x1ab, valuetostuff);
++
++	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_W2))
++		write_phy_reg(pi, 0x1b1, valuetostuff);
++
++	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_W2))
++		write_phy_reg(pi, 0x1b7, valuetostuff);
++
++	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_TBD))
++		write_phy_reg(pi, 0x1a7, valuetostuff);
++	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_TBD))
++		write_phy_reg(pi, 0x1ad, valuetostuff);
++	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_TBD))
++		write_phy_reg(pi, 0x1b3, valuetostuff);
++	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_TBD))
++		write_phy_reg(pi, 0x1b9, valuetostuff);
++
++	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_IQ))
++		write_phy_reg(pi, 0x1a8, valuetostuff);
++
++	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_IQ))
++		write_phy_reg(pi, 0x1ae, valuetostuff);
++
++	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_IQ))
++		write_phy_reg(pi, 0x1b4, valuetostuff);
++
++	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_IQ))
++		write_phy_reg(pi, 0x1ba, valuetostuff);
++
++	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rssi_type == NPHY_RSSI_SEL_TSSI_2G))
++		write_phy_reg(pi, 0x1a9, valuetostuff);
++	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rssi_type == NPHY_RSSI_SEL_TSSI_2G))
++		write_phy_reg(pi, 0x1b5, valuetostuff);
++
++	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rssi_type == NPHY_RSSI_SEL_TSSI_5G))
++		write_phy_reg(pi, 0x1af, valuetostuff);
++
++	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rssi_type == NPHY_RSSI_SEL_TSSI_5G))
++		write_phy_reg(pi, 0x1bb, valuetostuff);
++}
++
++static void brcms_phy_wr_tx_mux(struct brcms_phy *pi, u8 core)
++{
++	if (PHY_IPA(pi)) {
++		if (NREV_GE(pi->pubpi.phy_rev, 7))
++			write_radio_reg(pi,
++					((core == PHY_CORE_0) ?
++					 RADIO_2057_TX0_TX_SSI_MUX :
++					 RADIO_2057_TX1_TX_SSI_MUX),
++					(CHSPEC_IS5G(pi->radio_chanspec) ?
++					0xc : 0xe));
++		else
++			write_radio_reg(pi,
++					RADIO_2056_TX_TX_SSI_MUX |
++					((core == PHY_CORE_0) ?
++					 RADIO_2056_TX0 : RADIO_2056_TX1),
++					(CHSPEC_IS5G(pi->radio_chanspec) ?
++					0xc : 0xe));
++	} else {
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			write_radio_reg(pi,
++					((core == PHY_CORE_0) ?
++					 RADIO_2057_TX0_TX_SSI_MUX :
++					 RADIO_2057_TX1_TX_SSI_MUX),
++					0x11);
++
++			if (pi->pubpi.radioid == BCM2057_ID)
++				write_radio_reg(pi,
++						RADIO_2057_IQTEST_SEL_PU, 0x1);
++
++		} else {
++			write_radio_reg(pi,
++					RADIO_2056_TX_TX_SSI_MUX |
++					((core == PHY_CORE_0) ?
++					 RADIO_2056_TX0 : RADIO_2056_TX1),
++					0x11);
++		}
++	}
++}
++
++void wlc_phy_rssisel_nphy(struct brcms_phy *pi, u8 core_code, u8 rssi_type)
++{
++	u16 mask, val;
++	u16 afectrlovr_rssi_val, rfctrlcmd_rxen_val, rfctrlcmd_coresel_val,
++	    startseq;
++	u16 rfctrlovr_rssi_val, rfctrlovr_rxen_val, rfctrlovr_coresel_val,
++	    rfctrlovr_trigger_val;
++	u16 afectrlovr_rssi_mask, rfctrlcmd_mask, rfctrlovr_mask;
++	u16 rfctrlcmd_val, rfctrlovr_val;
++	u8 core;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		if (core_code == RADIO_MIMO_CORESEL_OFF) {
++			mod_phy_reg(pi, 0x8f, (0x1 << 9), 0);
++			mod_phy_reg(pi, 0xa5, (0x1 << 9), 0);
++
++			mod_phy_reg(pi, 0xa6, (0x3 << 8), 0);
++			mod_phy_reg(pi, 0xa7, (0x3 << 8), 0);
++
++			mod_phy_reg(pi, 0xe5, (0x1 << 5), 0);
++			mod_phy_reg(pi, 0xe6, (0x1 << 5), 0);
++
++			mask = (0x1 << 2) |
++			       (0x1 << 3) | (0x1 << 4) | (0x1 << 5);
++			mod_phy_reg(pi, 0xf9, mask, 0);
++			mod_phy_reg(pi, 0xfb, mask, 0);
++
++		} else {
++			for (core = 0; core < pi->pubpi.phy_corenum; core++) {
++				if (core_code == RADIO_MIMO_CORESEL_CORE1
++				    && core == PHY_CORE_1)
++					continue;
++				else if (core_code == RADIO_MIMO_CORESEL_CORE2
++					 && core == PHY_CORE_0)
++					continue;
++
++				mod_phy_reg(pi, (core == PHY_CORE_0) ?
++					    0x8f : 0xa5, (0x1 << 9), 1 << 9);
++
++				if (rssi_type == NPHY_RSSI_SEL_W1 ||
++				    rssi_type == NPHY_RSSI_SEL_W2 ||
++				    rssi_type == NPHY_RSSI_SEL_NB) {
++					mod_phy_reg(pi,
++						    (core ==
++						     PHY_CORE_0) ? 0xa6 : 0xa7,
++						    (0x3 << 8), 0);
++
++					mask = (0x1 << 2) |
++					       (0x1 << 3) |
++					       (0x1 << 4) | (0x1 << 5);
++					mod_phy_reg(pi,
++						    (core ==
++						     PHY_CORE_0) ? 0xf9 : 0xfb,
++						    mask, 0);
++
++					if (rssi_type == NPHY_RSSI_SEL_W1) {
++						if (CHSPEC_IS5G(
++							  pi->radio_chanspec)) {
++							mask = (0x1 << 2);
++							val = 1 << 2;
++						} else {
++							mask = (0x1 << 3);
++							val = 1 << 3;
++						}
++					} else if (rssi_type ==
++						   NPHY_RSSI_SEL_W2) {
++						mask = (0x1 << 4);
++						val = 1 << 4;
++					} else {
++						mask = (0x1 << 5);
++						val = 1 << 5;
++					}
++					mod_phy_reg(pi,
++						    (core ==
++						     PHY_CORE_0) ? 0xf9 : 0xfb,
++						    mask, val);
++
++					mask = (0x1 << 5);
++					val = 1 << 5;
++					mod_phy_reg(pi, (core == PHY_CORE_0) ?
++						    0xe5 : 0xe6, mask, val);
++				} else {
++					if (rssi_type == NPHY_RSSI_SEL_TBD) {
++						mask = (0x3 << 8);
++						val = 1 << 8;
++						mod_phy_reg(pi,
++							    (core ==
++							     PHY_CORE_0) ? 0xa6
++							    : 0xa7, mask, val);
++						mask = (0x3 << 10);
++						val = 1 << 10;
++						mod_phy_reg(pi,
++							    (core ==
++							     PHY_CORE_0) ? 0xa6
++							    : 0xa7, mask, val);
++					} else if (rssi_type ==
++						   NPHY_RSSI_SEL_IQ) {
++						mask = (0x3 << 8);
++						val = 2 << 8;
++						mod_phy_reg(pi,
++							    (core ==
++							     PHY_CORE_0) ? 0xa6
++							    : 0xa7, mask, val);
++						mask = (0x3 << 10);
++						val = 2 << 10;
++						mod_phy_reg(pi,
++							    (core ==
++							     PHY_CORE_0) ? 0xa6
++							    : 0xa7, mask, val);
++					} else {
++						mask = (0x3 << 8);
++						val = 3 << 8;
++						mod_phy_reg(pi,
++							    (core ==
++							     PHY_CORE_0) ? 0xa6
++							    : 0xa7, mask, val);
++						mask = (0x3 << 10);
++						val = 3 << 10;
++						mod_phy_reg(pi,
++							    (core ==
++							     PHY_CORE_0) ? 0xa6
++							    : 0xa7, mask, val);
++						brcms_phy_wr_tx_mux(pi, core);
++						afectrlovr_rssi_val = 1 << 9;
++						mod_phy_reg(pi,
++							   (core ==
++							    PHY_CORE_0) ? 0x8f
++							   : 0xa5, (0x1 << 9),
++							   afectrlovr_rssi_val);
++					}
++				}
++			}
++		}
++	} else {
++
++		if ((rssi_type == NPHY_RSSI_SEL_W1) ||
++		    (rssi_type == NPHY_RSSI_SEL_W2) ||
++		    (rssi_type == NPHY_RSSI_SEL_NB))
++			val = 0x0;
++		else if (rssi_type == NPHY_RSSI_SEL_TBD)
++			val = 0x1;
++		else if (rssi_type == NPHY_RSSI_SEL_IQ)
++			val = 0x2;
++		else
++			val = 0x3;
++
++		mask = ((0x3 << 12) | (0x3 << 14));
++		val = (val << 12) | (val << 14);
++		mod_phy_reg(pi, 0xa6, mask, val);
++		mod_phy_reg(pi, 0xa7, mask, val);
++
++		if ((rssi_type == NPHY_RSSI_SEL_W1) ||
++		    (rssi_type == NPHY_RSSI_SEL_W2) ||
++		    (rssi_type == NPHY_RSSI_SEL_NB)) {
++			if (rssi_type == NPHY_RSSI_SEL_W1)
++				val = 0x1;
++			if (rssi_type == NPHY_RSSI_SEL_W2)
++				val = 0x2;
++			if (rssi_type == NPHY_RSSI_SEL_NB)
++				val = 0x3;
++
++			mask = (0x3 << 4);
++			val = (val << 4);
++			mod_phy_reg(pi, 0x7a, mask, val);
++			mod_phy_reg(pi, 0x7d, mask, val);
++		}
++
++		if (core_code == RADIO_MIMO_CORESEL_OFF) {
++			afectrlovr_rssi_val = 0;
++			rfctrlcmd_rxen_val = 0;
++			rfctrlcmd_coresel_val = 0;
++			rfctrlovr_rssi_val = 0;
++			rfctrlovr_rxen_val = 0;
++			rfctrlovr_coresel_val = 0;
++			rfctrlovr_trigger_val = 0;
++			startseq = 0;
++		} else {
++			afectrlovr_rssi_val = 1;
++			rfctrlcmd_rxen_val = 1;
++			rfctrlcmd_coresel_val = core_code;
++			rfctrlovr_rssi_val = 1;
++			rfctrlovr_rxen_val = 1;
++			rfctrlovr_coresel_val = 1;
++			rfctrlovr_trigger_val = 1;
++			startseq = 1;
++		}
++
++		afectrlovr_rssi_mask = ((0x1 << 12) | (0x1 << 13));
++		afectrlovr_rssi_val = (afectrlovr_rssi_val <<
++				       12) | (afectrlovr_rssi_val << 13);
++		mod_phy_reg(pi, 0xa5, afectrlovr_rssi_mask,
++			    afectrlovr_rssi_val);
++
++		if ((rssi_type == NPHY_RSSI_SEL_W1) ||
++		    (rssi_type == NPHY_RSSI_SEL_W2) ||
++		    (rssi_type == NPHY_RSSI_SEL_NB)) {
++			rfctrlcmd_mask = ((0x1 << 8) | (0x7 << 3));
++			rfctrlcmd_val = (rfctrlcmd_rxen_val << 8) |
++					(rfctrlcmd_coresel_val << 3);
++
++			rfctrlovr_mask = ((0x1 << 5) |
++					  (0x1 << 12) |
++					  (0x1 << 1) | (0x1 << 0));
++			rfctrlovr_val = (rfctrlovr_rssi_val <<
++					 5) |
++					(rfctrlovr_rxen_val << 12) |
++					(rfctrlovr_coresel_val << 1) |
++					(rfctrlovr_trigger_val << 0);
++
++			mod_phy_reg(pi, 0x78, rfctrlcmd_mask, rfctrlcmd_val);
++			mod_phy_reg(pi, 0xec, rfctrlovr_mask, rfctrlovr_val);
++
++			mod_phy_reg(pi, 0x78, (0x1 << 0), (startseq << 0));
++			udelay(20);
++
++			mod_phy_reg(pi, 0xec, (0x1 << 0), 0);
++		}
++	}
++}
++
++int
++wlc_phy_poll_rssi_nphy(struct brcms_phy *pi, u8 rssi_type, s32 *rssi_buf,
++		       u8 nsamps)
++{
++	s16 rssi0, rssi1;
++	u16 afectrlCore1_save = 0;
++	u16 afectrlCore2_save = 0;
++	u16 afectrlOverride1_save = 0;
++	u16 afectrlOverride2_save = 0;
++	u16 rfctrlOverrideAux0_save = 0;
++	u16 rfctrlOverrideAux1_save = 0;
++	u16 rfctrlMiscReg1_save = 0;
++	u16 rfctrlMiscReg2_save = 0;
++	u16 rfctrlcmd_save = 0;
++	u16 rfctrloverride_save = 0;
++	u16 rfctrlrssiothers1_save = 0;
++	u16 rfctrlrssiothers2_save = 0;
++	s8 tmp_buf[4];
++	u8 ctr = 0, samp = 0;
++	s32 rssi_out_val;
++	u16 gpiosel_orig;
++
++	afectrlCore1_save = read_phy_reg(pi, 0xa6);
++	afectrlCore2_save = read_phy_reg(pi, 0xa7);
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		rfctrlMiscReg1_save = read_phy_reg(pi, 0xf9);
++		rfctrlMiscReg2_save = read_phy_reg(pi, 0xfb);
++		afectrlOverride1_save = read_phy_reg(pi, 0x8f);
++		afectrlOverride2_save = read_phy_reg(pi, 0xa5);
++		rfctrlOverrideAux0_save = read_phy_reg(pi, 0xe5);
++		rfctrlOverrideAux1_save = read_phy_reg(pi, 0xe6);
++	} else {
++		afectrlOverride1_save = read_phy_reg(pi, 0xa5);
++		rfctrlcmd_save = read_phy_reg(pi, 0x78);
++		rfctrloverride_save = read_phy_reg(pi, 0xec);
++		rfctrlrssiothers1_save = read_phy_reg(pi, 0x7a);
++		rfctrlrssiothers2_save = read_phy_reg(pi, 0x7d);
++	}
++
++	wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_ALLRX, rssi_type);
++
++	gpiosel_orig = read_phy_reg(pi, 0xca);
++	if (NREV_LT(pi->pubpi.phy_rev, 2))
++		write_phy_reg(pi, 0xca, 5);
++
++	for (ctr = 0; ctr < 4; ctr++)
++		rssi_buf[ctr] = 0;
++
++	for (samp = 0; samp < nsamps; samp++) {
++		if (NREV_LT(pi->pubpi.phy_rev, 2)) {
++			rssi0 = read_phy_reg(pi, 0x1c9);
++			rssi1 = read_phy_reg(pi, 0x1ca);
++		} else {
++			rssi0 = read_phy_reg(pi, 0x219);
++			rssi1 = read_phy_reg(pi, 0x21a);
++		}
++
++		ctr = 0;
++		tmp_buf[ctr++] = ((s8) ((rssi0 & 0x3f) << 2)) >> 2;
++		tmp_buf[ctr++] = ((s8) (((rssi0 >> 8) & 0x3f) << 2)) >> 2;
++		tmp_buf[ctr++] = ((s8) ((rssi1 & 0x3f) << 2)) >> 2;
++		tmp_buf[ctr++] = ((s8) (((rssi1 >> 8) & 0x3f) << 2)) >> 2;
++
++		for (ctr = 0; ctr < 4; ctr++)
++			rssi_buf[ctr] += tmp_buf[ctr];
++
++	}
++
++	rssi_out_val = rssi_buf[3] & 0xff;
++	rssi_out_val |= (rssi_buf[2] & 0xff) << 8;
++	rssi_out_val |= (rssi_buf[1] & 0xff) << 16;
++	rssi_out_val |= (rssi_buf[0] & 0xff) << 24;
++
++	if (NREV_LT(pi->pubpi.phy_rev, 2))
++		write_phy_reg(pi, 0xca, gpiosel_orig);
++
++	write_phy_reg(pi, 0xa6, afectrlCore1_save);
++	write_phy_reg(pi, 0xa7, afectrlCore2_save);
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		write_phy_reg(pi, 0xf9, rfctrlMiscReg1_save);
++		write_phy_reg(pi, 0xfb, rfctrlMiscReg2_save);
++		write_phy_reg(pi, 0x8f, afectrlOverride1_save);
++		write_phy_reg(pi, 0xa5, afectrlOverride2_save);
++		write_phy_reg(pi, 0xe5, rfctrlOverrideAux0_save);
++		write_phy_reg(pi, 0xe6, rfctrlOverrideAux1_save);
++	} else {
++		write_phy_reg(pi, 0xa5, afectrlOverride1_save);
++		write_phy_reg(pi, 0x78, rfctrlcmd_save);
++		write_phy_reg(pi, 0xec, rfctrloverride_save);
++		write_phy_reg(pi, 0x7a, rfctrlrssiothers1_save);
++		write_phy_reg(pi, 0x7d, rfctrlrssiothers2_save);
++	}
++
++	return rssi_out_val;
++}
++
++s16 wlc_phy_tempsense_nphy(struct brcms_phy *pi)
++{
++	u16 core1_txrf_iqcal1_save, core1_txrf_iqcal2_save;
++	u16 core2_txrf_iqcal1_save, core2_txrf_iqcal2_save;
++	u16 pwrdet_rxtx_core1_save;
++	u16 pwrdet_rxtx_core2_save;
++	u16 afectrlCore1_save;
++	u16 afectrlCore2_save;
++	u16 afectrlOverride_save;
++	u16 afectrlOverride2_save;
++	u16 pd_pll_ts_save;
++	u16 gpioSel_save;
++	s32 radio_temp[4];
++	s32 radio_temp2[4];
++	u16 syn_tempprocsense_save;
++	s16 offset = 0;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		u16 auxADC_Vmid, auxADC_Av, auxADC_Vmid_save, auxADC_Av_save;
++		u16 auxADC_rssi_ctrlL_save, auxADC_rssi_ctrlH_save;
++		u16 auxADC_rssi_ctrlL, auxADC_rssi_ctrlH;
++		s32 auxADC_Vl;
++		u16 RfctrlOverride5_save, RfctrlOverride6_save;
++		u16 RfctrlMiscReg5_save, RfctrlMiscReg6_save;
++		u16 RSSIMultCoef0QPowerDet_save;
++		u16 tempsense_Rcal;
++
++		syn_tempprocsense_save =
++			read_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG);
++
++		afectrlCore1_save = read_phy_reg(pi, 0xa6);
++		afectrlCore2_save = read_phy_reg(pi, 0xa7);
++		afectrlOverride_save = read_phy_reg(pi, 0x8f);
++		afectrlOverride2_save = read_phy_reg(pi, 0xa5);
++		RSSIMultCoef0QPowerDet_save = read_phy_reg(pi, 0x1ae);
++		RfctrlOverride5_save = read_phy_reg(pi, 0x346);
++		RfctrlOverride6_save = read_phy_reg(pi, 0x347);
++		RfctrlMiscReg5_save = read_phy_reg(pi, 0x344);
++		RfctrlMiscReg6_save = read_phy_reg(pi, 0x345);
++
++		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0A, 16,
++					&auxADC_Vmid_save);
++		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0E, 16,
++					&auxADC_Av_save);
++		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x02, 16,
++					&auxADC_rssi_ctrlL_save);
++		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x03, 16,
++					&auxADC_rssi_ctrlH_save);
++
++		write_phy_reg(pi, 0x1ae, 0x0);
++
++		auxADC_rssi_ctrlL = 0x0;
++		auxADC_rssi_ctrlH = 0x20;
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x02, 16,
++					 &auxADC_rssi_ctrlL);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x03, 16,
++					 &auxADC_rssi_ctrlH);
++
++		tempsense_Rcal = syn_tempprocsense_save & 0x1c;
++
++		write_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG,
++				tempsense_Rcal | 0x01);
++
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1),
++						  1, 0, 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID2);
++		mod_phy_reg(pi, 0xa6, (0x1 << 7), 0);
++		mod_phy_reg(pi, 0xa7, (0x1 << 7), 0);
++		mod_phy_reg(pi, 0x8f, (0x1 << 7), (0x1 << 7));
++		mod_phy_reg(pi, 0xa5, (0x1 << 7), (0x1 << 7));
++
++		mod_phy_reg(pi, 0xa6, (0x1 << 2), (0x1 << 2));
++		mod_phy_reg(pi, 0xa7, (0x1 << 2), (0x1 << 2));
++		mod_phy_reg(pi, 0x8f, (0x1 << 2), (0x1 << 2));
++		mod_phy_reg(pi, 0xa5, (0x1 << 2), (0x1 << 2));
++		udelay(5);
++		mod_phy_reg(pi, 0xa6, (0x1 << 2), 0);
++		mod_phy_reg(pi, 0xa7, (0x1 << 2), 0);
++		mod_phy_reg(pi, 0xa6, (0x1 << 3), 0);
++		mod_phy_reg(pi, 0xa7, (0x1 << 3), 0);
++		mod_phy_reg(pi, 0x8f, (0x1 << 3), (0x1 << 3));
++		mod_phy_reg(pi, 0xa5, (0x1 << 3), (0x1 << 3));
++		mod_phy_reg(pi, 0xa6, (0x1 << 6), 0);
++		mod_phy_reg(pi, 0xa7, (0x1 << 6), 0);
++		mod_phy_reg(pi, 0x8f, (0x1 << 6), (0x1 << 6));
++		mod_phy_reg(pi, 0xa5, (0x1 << 6), (0x1 << 6));
++
++		auxADC_Vmid = 0xA3;
++		auxADC_Av = 0x0;
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0A, 16,
++					 &auxADC_Vmid);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0E, 16,
++					 &auxADC_Av);
++
++		udelay(3);
++
++		wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp, 1);
++		write_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG,
++				tempsense_Rcal | 0x03);
++
++		udelay(5);
++		wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp2, 1);
++
++		auxADC_Av = 0x7;
++		if (radio_temp[1] + radio_temp2[1] < -30) {
++			auxADC_Vmid = 0x45;
++			auxADC_Vl = 263;
++		} else if (radio_temp[1] + radio_temp2[1] < -9) {
++			auxADC_Vmid = 0x200;
++			auxADC_Vl = 467;
++		} else if (radio_temp[1] + radio_temp2[1] < 11) {
++			auxADC_Vmid = 0x266;
++			auxADC_Vl = 634;
++		} else {
++			auxADC_Vmid = 0x2D5;
++			auxADC_Vl = 816;
++		}
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0A, 16,
++					 &auxADC_Vmid);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0E, 16,
++					 &auxADC_Av);
++
++		udelay(3);
++
++		wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp2, 1);
++		write_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG,
++				tempsense_Rcal | 0x01);
++
++		udelay(5);
++		wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp, 1);
++
++		write_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG,
++				syn_tempprocsense_save);
++
++		write_phy_reg(pi, 0xa6, afectrlCore1_save);
++		write_phy_reg(pi, 0xa7, afectrlCore2_save);
++		write_phy_reg(pi, 0x8f, afectrlOverride_save);
++		write_phy_reg(pi, 0xa5, afectrlOverride2_save);
++		write_phy_reg(pi, 0x1ae, RSSIMultCoef0QPowerDet_save);
++		write_phy_reg(pi, 0x346, RfctrlOverride5_save);
++		write_phy_reg(pi, 0x347, RfctrlOverride6_save);
++		write_phy_reg(pi, 0x344, RfctrlMiscReg5_save);
++		write_phy_reg(pi, 0x345, RfctrlMiscReg5_save);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0A, 16,
++					 &auxADC_Vmid_save);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0E, 16,
++					 &auxADC_Av_save);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x02, 16,
++					 &auxADC_rssi_ctrlL_save);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x03, 16,
++					 &auxADC_rssi_ctrlH_save);
++
++		radio_temp[0] = (179 * (radio_temp[1] + radio_temp2[1])
++				 + 82 * (auxADC_Vl) - 28861 +
++				 128) / 256;
++
++		offset = (s16) pi->phy_tempsense_offset;
++
++	} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		syn_tempprocsense_save =
++			read_radio_reg(pi, RADIO_2056_SYN_TEMPPROCSENSE);
++
++		afectrlCore1_save = read_phy_reg(pi, 0xa6);
++		afectrlCore2_save = read_phy_reg(pi, 0xa7);
++		afectrlOverride_save = read_phy_reg(pi, 0x8f);
++		afectrlOverride2_save = read_phy_reg(pi, 0xa5);
++		gpioSel_save = read_phy_reg(pi, 0xca);
++
++		write_radio_reg(pi, RADIO_2056_SYN_TEMPPROCSENSE, 0x01);
++
++		wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp, 1);
++		if (NREV_LT(pi->pubpi.phy_rev, 7))
++			write_radio_reg(pi, RADIO_2056_SYN_TEMPPROCSENSE, 0x05);
++
++		wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp2, 1);
++		if (NREV_GE(pi->pubpi.phy_rev, 7))
++			write_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG, 0x01);
++		else
++			write_radio_reg(pi, RADIO_2056_SYN_TEMPPROCSENSE, 0x01);
++
++		radio_temp[0] =
++			(126 * (radio_temp[1] + radio_temp2[1]) + 3987) / 64;
++
++		write_radio_reg(pi, RADIO_2056_SYN_TEMPPROCSENSE,
++				syn_tempprocsense_save);
++
++		write_phy_reg(pi, 0xca, gpioSel_save);
++		write_phy_reg(pi, 0xa6, afectrlCore1_save);
++		write_phy_reg(pi, 0xa7, afectrlCore2_save);
++		write_phy_reg(pi, 0x8f, afectrlOverride_save);
++		write_phy_reg(pi, 0xa5, afectrlOverride2_save);
++
++		offset = (s16) pi->phy_tempsense_offset;
++	} else {
++
++		pwrdet_rxtx_core1_save =
++			read_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1);
++		pwrdet_rxtx_core2_save =
++			read_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2);
++		core1_txrf_iqcal1_save =
++			read_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1);
++		core1_txrf_iqcal2_save =
++			read_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2);
++		core2_txrf_iqcal1_save =
++			read_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1);
++		core2_txrf_iqcal2_save =
++			read_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2);
++		pd_pll_ts_save = read_radio_reg(pi, RADIO_2055_PD_PLL_TS);
++
++		afectrlCore1_save = read_phy_reg(pi, 0xa6);
++		afectrlCore2_save = read_phy_reg(pi, 0xa7);
++		afectrlOverride_save = read_phy_reg(pi, 0xa5);
++		gpioSel_save = read_phy_reg(pi, 0xca);
++
++		write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1, 0x01);
++		write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1, 0x01);
++		write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2, 0x08);
++		write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2, 0x08);
++		write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1, 0x04);
++		write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2, 0x04);
++		write_radio_reg(pi, RADIO_2055_PD_PLL_TS, 0x00);
++
++		wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp, 1);
++		xor_radio_reg(pi, RADIO_2055_CAL_TS, 0x80);
++
++		wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp, 1);
++		xor_radio_reg(pi, RADIO_2055_CAL_TS, 0x80);
++
++		wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp2, 1);
++		xor_radio_reg(pi, RADIO_2055_CAL_TS, 0x80);
++
++		radio_temp[0] = (radio_temp[0] + radio_temp2[0]);
++		radio_temp[1] = (radio_temp[1] + radio_temp2[1]);
++		radio_temp[2] = (radio_temp[2] + radio_temp2[2]);
++		radio_temp[3] = (radio_temp[3] + radio_temp2[3]);
++
++		radio_temp[0] =
++			(radio_temp[0] + radio_temp[1] + radio_temp[2] +
++			 radio_temp[3]);
++
++		radio_temp[0] =
++			(radio_temp[0] +
++			 (8 * 32)) * (950 - 350) / 63 + (350 * 8);
++
++		radio_temp[0] = (radio_temp[0] - (8 * 420)) / 38;
++
++		write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1,
++				pwrdet_rxtx_core1_save);
++		write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2,
++				pwrdet_rxtx_core2_save);
++		write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1,
++				core1_txrf_iqcal1_save);
++		write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1,
++				core2_txrf_iqcal1_save);
++		write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2,
++				core1_txrf_iqcal2_save);
++		write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2,
++				core2_txrf_iqcal2_save);
++		write_radio_reg(pi, RADIO_2055_PD_PLL_TS, pd_pll_ts_save);
++
++		write_phy_reg(pi, 0xca, gpioSel_save);
++		write_phy_reg(pi, 0xa6, afectrlCore1_save);
++		write_phy_reg(pi, 0xa7, afectrlCore2_save);
++		write_phy_reg(pi, 0xa5, afectrlOverride_save);
++	}
++
++	return (s16) radio_temp[0] + offset;
++}
++
++static void
++wlc_phy_set_rssi_2055_vcm(struct brcms_phy *pi, u8 rssi_type, u8 *vcm_buf)
++{
++	u8 core;
++
++	for (core = 0; core < pi->pubpi.phy_corenum; core++) {
++		if (rssi_type == NPHY_RSSI_SEL_NB) {
++			if (core == PHY_CORE_0) {
++				mod_radio_reg(pi,
++					      RADIO_2055_CORE1_B0_NBRSSI_VCM,
++					      RADIO_2055_NBRSSI_VCM_I_MASK,
++					      vcm_buf[2 *
++						      core] <<
++					      RADIO_2055_NBRSSI_VCM_I_SHIFT);
++				mod_radio_reg(pi,
++					      RADIO_2055_CORE1_RXBB_RSSI_CTRL5,
++					      RADIO_2055_NBRSSI_VCM_Q_MASK,
++					      vcm_buf[2 * core +
++						      1] <<
++					      RADIO_2055_NBRSSI_VCM_Q_SHIFT);
++			} else {
++				mod_radio_reg(pi,
++					      RADIO_2055_CORE2_B0_NBRSSI_VCM,
++					      RADIO_2055_NBRSSI_VCM_I_MASK,
++					      vcm_buf[2 *
++						      core] <<
++					      RADIO_2055_NBRSSI_VCM_I_SHIFT);
++				mod_radio_reg(pi,
++					      RADIO_2055_CORE2_RXBB_RSSI_CTRL5,
++					      RADIO_2055_NBRSSI_VCM_Q_MASK,
++					      vcm_buf[2 * core +
++						      1] <<
++					      RADIO_2055_NBRSSI_VCM_Q_SHIFT);
++			}
++		} else {
++			if (core == PHY_CORE_0)
++				mod_radio_reg(pi,
++					      RADIO_2055_CORE1_RXBB_RSSI_CTRL5,
++					      RADIO_2055_WBRSSI_VCM_IQ_MASK,
++					      vcm_buf[2 *
++						      core] <<
++					      RADIO_2055_WBRSSI_VCM_IQ_SHIFT);
++			else
++				mod_radio_reg(pi,
++					      RADIO_2055_CORE2_RXBB_RSSI_CTRL5,
++					      RADIO_2055_WBRSSI_VCM_IQ_MASK,
++					      vcm_buf[2 *
++						      core] <<
++					      RADIO_2055_WBRSSI_VCM_IQ_SHIFT);
++		}
++	}
++}
++
++static void wlc_phy_rssi_cal_nphy_rev3(struct brcms_phy *pi)
++{
++	u16 classif_state;
++	u16 clip_state[2];
++	u16 clip_off[] = { 0xffff, 0xffff };
++	s32 target_code;
++	u8 vcm, min_vcm;
++	u8 vcm_final = 0;
++	u8 result_idx;
++	s32 poll_results[8][4] = {
++		{0, 0, 0, 0},
++		{0, 0, 0, 0},
++		{0, 0, 0, 0},
++		{0, 0, 0, 0},
++		{0, 0, 0, 0},
++		{0, 0, 0, 0},
++		{0, 0, 0, 0},
++		{0, 0, 0, 0}
++	};
++	s32 poll_result_core[4] = { 0, 0, 0, 0 };
++	s32 min_d = NPHY_RSSICAL_MAXD, curr_d;
++	s32 fine_digital_offset[4];
++	s32 poll_results_min[4] = { 0, 0, 0, 0 };
++	s32 min_poll;
++	u8 vcm_level_max;
++	u8 core;
++	u8 wb_cnt;
++	u8 rssi_type;
++	u16 NPHY_Rfctrlintc1_save, NPHY_Rfctrlintc2_save;
++	u16 NPHY_AfectrlOverride1_save, NPHY_AfectrlOverride2_save;
++	u16 NPHY_AfectrlCore1_save, NPHY_AfectrlCore2_save;
++	u16 NPHY_RfctrlOverride0_save, NPHY_RfctrlOverride1_save;
++	u16 NPHY_RfctrlOverrideAux0_save, NPHY_RfctrlOverrideAux1_save;
++	u16 NPHY_RfctrlCmd_save;
++	u16 NPHY_RfctrlMiscReg1_save, NPHY_RfctrlMiscReg2_save;
++	u16 NPHY_RfctrlRSSIOTHERS1_save, NPHY_RfctrlRSSIOTHERS2_save;
++	u8 rxcore_state;
++	u16 NPHY_REV7_RfctrlOverride3_save, NPHY_REV7_RfctrlOverride4_save;
++	u16 NPHY_REV7_RfctrlOverride5_save, NPHY_REV7_RfctrlOverride6_save;
++	u16 NPHY_REV7_RfctrlMiscReg3_save, NPHY_REV7_RfctrlMiscReg4_save;
++	u16 NPHY_REV7_RfctrlMiscReg5_save, NPHY_REV7_RfctrlMiscReg6_save;
++
++	NPHY_REV7_RfctrlOverride3_save =
++		NPHY_REV7_RfctrlOverride4_save =
++		NPHY_REV7_RfctrlOverride5_save =
++		NPHY_REV7_RfctrlOverride6_save =
++		NPHY_REV7_RfctrlMiscReg3_save =
++		NPHY_REV7_RfctrlMiscReg4_save =
++		NPHY_REV7_RfctrlMiscReg5_save =
++		NPHY_REV7_RfctrlMiscReg6_save = 0;
++
++	classif_state = wlc_phy_classifier_nphy(pi, 0, 0);
++	wlc_phy_classifier_nphy(pi, (0x7 << 0), 4);
++	wlc_phy_clip_det_nphy(pi, 0, clip_state);
++	wlc_phy_clip_det_nphy(pi, 1, clip_off);
++
++	NPHY_Rfctrlintc1_save = read_phy_reg(pi, 0x91);
++	NPHY_Rfctrlintc2_save = read_phy_reg(pi, 0x92);
++	NPHY_AfectrlOverride1_save = read_phy_reg(pi, 0x8f);
++	NPHY_AfectrlOverride2_save = read_phy_reg(pi, 0xa5);
++	NPHY_AfectrlCore1_save = read_phy_reg(pi, 0xa6);
++	NPHY_AfectrlCore2_save = read_phy_reg(pi, 0xa7);
++	NPHY_RfctrlOverride0_save = read_phy_reg(pi, 0xe7);
++	NPHY_RfctrlOverride1_save = read_phy_reg(pi, 0xec);
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		NPHY_REV7_RfctrlOverride3_save = read_phy_reg(pi, 0x342);
++		NPHY_REV7_RfctrlOverride4_save = read_phy_reg(pi, 0x343);
++		NPHY_REV7_RfctrlOverride5_save = read_phy_reg(pi, 0x346);
++		NPHY_REV7_RfctrlOverride6_save = read_phy_reg(pi, 0x347);
++	}
++	NPHY_RfctrlOverrideAux0_save = read_phy_reg(pi, 0xe5);
++	NPHY_RfctrlOverrideAux1_save = read_phy_reg(pi, 0xe6);
++	NPHY_RfctrlCmd_save = read_phy_reg(pi, 0x78);
++	NPHY_RfctrlMiscReg1_save = read_phy_reg(pi, 0xf9);
++	NPHY_RfctrlMiscReg2_save = read_phy_reg(pi, 0xfb);
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		NPHY_REV7_RfctrlMiscReg3_save = read_phy_reg(pi, 0x340);
++		NPHY_REV7_RfctrlMiscReg4_save = read_phy_reg(pi, 0x341);
++		NPHY_REV7_RfctrlMiscReg5_save = read_phy_reg(pi, 0x344);
++		NPHY_REV7_RfctrlMiscReg6_save = read_phy_reg(pi, 0x345);
++	}
++	NPHY_RfctrlRSSIOTHERS1_save = read_phy_reg(pi, 0x7a);
++	NPHY_RfctrlRSSIOTHERS2_save = read_phy_reg(pi, 0x7d);
++
++	wlc_phy_rfctrlintc_override_nphy(pi, NPHY_RfctrlIntc_override_OFF, 0,
++					 RADIO_MIMO_CORESEL_ALLRXTX);
++	wlc_phy_rfctrlintc_override_nphy(pi, NPHY_RfctrlIntc_override_TRSW, 1,
++					 RADIO_MIMO_CORESEL_ALLRXTX);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7))
++		wlc_phy_rfctrl_override_1tomany_nphy(
++			pi,
++			NPHY_REV7_RfctrlOverride_cmd_rxrf_pu,
++			0, 0, 0);
++	else
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 0), 0, 0, 0);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7))
++		wlc_phy_rfctrl_override_1tomany_nphy(
++			pi,
++			NPHY_REV7_RfctrlOverride_cmd_rx_pu,
++			1, 0, 0);
++	else
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 1), 1, 0, 0);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 7),
++						  1, 0, 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 6), 1, 0, 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
++	} else {
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 7), 1, 0, 0);
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 6), 1, 0, 0);
++	}
++
++	if (CHSPEC_IS5G(pi->radio_chanspec)) {
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 5),
++				0, 0, 0,
++				NPHY_REV7_RFCTRLOVERRIDE_ID0);
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 4), 1, 0,
++				0,
++				NPHY_REV7_RFCTRLOVERRIDE_ID0);
++		} else {
++			wlc_phy_rfctrl_override_nphy(pi, (0x1 << 5), 0, 0, 0);
++			wlc_phy_rfctrl_override_nphy(pi, (0x1 << 4), 1, 0, 0);
++		}
++
++	} else {
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 4),
++				0, 0, 0,
++				NPHY_REV7_RFCTRLOVERRIDE_ID0);
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 5), 1, 0,
++				0,
++				NPHY_REV7_RFCTRLOVERRIDE_ID0);
++		} else {
++			wlc_phy_rfctrl_override_nphy(pi, (0x1 << 4), 0, 0, 0);
++			wlc_phy_rfctrl_override_nphy(pi, (0x1 << 5), 1, 0, 0);
++		}
++	}
++
++	rxcore_state = wlc_phy_rxcore_getstate_nphy(
++		(struct brcms_phy_pub *) pi);
++
++	vcm_level_max = 8;
++
++	for (core = 0; core < pi->pubpi.phy_corenum; core++) {
++
++		if ((rxcore_state & (1 << core)) == 0)
++			continue;
++
++		wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0,
++					       core ==
++					       PHY_CORE_0 ?
++					       RADIO_MIMO_CORESEL_CORE1 :
++					       RADIO_MIMO_CORESEL_CORE2,
++					       NPHY_RAIL_I, NPHY_RSSI_SEL_NB);
++		wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0,
++					       core ==
++					       PHY_CORE_0 ?
++					       RADIO_MIMO_CORESEL_CORE1 :
++					       RADIO_MIMO_CORESEL_CORE2,
++					       NPHY_RAIL_Q, NPHY_RSSI_SEL_NB);
++
++		for (vcm = 0; vcm < vcm_level_max; vcm++) {
++			if (NREV_GE(pi->pubpi.phy_rev, 7))
++				mod_radio_reg(pi, (core == PHY_CORE_0) ?
++					      RADIO_2057_NB_MASTER_CORE0 :
++					      RADIO_2057_NB_MASTER_CORE1,
++					      RADIO_2057_VCM_MASK, vcm);
++			else
++				mod_radio_reg(pi, RADIO_2056_RX_RSSI_MISC |
++					      ((core ==
++						PHY_CORE_0) ? RADIO_2056_RX0 :
++					       RADIO_2056_RX1),
++					      RADIO_2056_VCM_MASK,
++					      vcm << RADIO_2056_RSSI_VCM_SHIFT);
++
++			wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_NB,
++					       &poll_results[vcm][0],
++					       NPHY_RSSICAL_NPOLL);
++		}
++
++		for (result_idx = 0; result_idx < 4; result_idx++) {
++			if ((core == result_idx / 2) &&
++			    (result_idx % 2 == 0)) {
++
++				min_d = NPHY_RSSICAL_MAXD;
++				min_vcm = 0;
++				min_poll =
++					NPHY_RSSICAL_MAXREAD *
++					NPHY_RSSICAL_NPOLL + 1;
++				for (vcm = 0; vcm < vcm_level_max; vcm++) {
++					curr_d =
++						poll_results[vcm][result_idx] *
++						poll_results[vcm][result_idx] +
++						poll_results[vcm][result_idx +
++								  1] *
++						poll_results[vcm][result_idx +
++								  1];
++					if (curr_d < min_d) {
++						min_d = curr_d;
++						min_vcm = vcm;
++					}
++					if (poll_results[vcm][result_idx] <
++					    min_poll)
++						min_poll =
++							poll_results[vcm]
++							[result_idx];
++				}
++				vcm_final = min_vcm;
++				poll_results_min[result_idx] = min_poll;
++			}
++		}
++
++		if (NREV_GE(pi->pubpi.phy_rev, 7))
++			mod_radio_reg(pi, (core == PHY_CORE_0) ?
++				      RADIO_2057_NB_MASTER_CORE0 :
++				      RADIO_2057_NB_MASTER_CORE1,
++				      RADIO_2057_VCM_MASK, vcm_final);
++		else
++			mod_radio_reg(pi, RADIO_2056_RX_RSSI_MISC |
++				      ((core ==
++					PHY_CORE_0) ? RADIO_2056_RX0 :
++				       RADIO_2056_RX1), RADIO_2056_VCM_MASK,
++				      vcm_final << RADIO_2056_RSSI_VCM_SHIFT);
++
++		for (result_idx = 0; result_idx < 4; result_idx++) {
++			if (core == result_idx / 2) {
++				fine_digital_offset[result_idx] =
++					(NPHY_RSSICAL_NB_TARGET *
++					 NPHY_RSSICAL_NPOLL) -
++					poll_results[vcm_final][result_idx];
++				if (fine_digital_offset[result_idx] < 0) {
++					fine_digital_offset[result_idx] =
++						abs(fine_digital_offset
++						    [result_idx]);
++					fine_digital_offset[result_idx] +=
++						(NPHY_RSSICAL_NPOLL / 2);
++					fine_digital_offset[result_idx] /=
++						NPHY_RSSICAL_NPOLL;
++					fine_digital_offset[result_idx] =
++						-fine_digital_offset[
++								    result_idx];
++				} else {
++					fine_digital_offset[result_idx] +=
++						(NPHY_RSSICAL_NPOLL / 2);
++					fine_digital_offset[result_idx] /=
++						NPHY_RSSICAL_NPOLL;
++				}
++
++				if (poll_results_min[result_idx] ==
++				    NPHY_RSSICAL_MAXREAD * NPHY_RSSICAL_NPOLL)
++					fine_digital_offset[result_idx] =
++						(NPHY_RSSICAL_NB_TARGET -
++						 NPHY_RSSICAL_MAXREAD - 1);
++
++				wlc_phy_scale_offset_rssi_nphy(
++					pi, 0x0,
++					(s8)
++					fine_digital_offset
++					[result_idx],
++					(result_idx / 2 == 0) ?
++					RADIO_MIMO_CORESEL_CORE1 :
++					RADIO_MIMO_CORESEL_CORE2,
++					(result_idx % 2 == 0) ?
++					NPHY_RAIL_I : NPHY_RAIL_Q,
++					NPHY_RSSI_SEL_NB);
++			}
++		}
++
++	}
++
++	for (core = 0; core < pi->pubpi.phy_corenum; core++) {
++
++		if ((rxcore_state & (1 << core)) == 0)
++			continue;
++
++		for (wb_cnt = 0; wb_cnt < 2; wb_cnt++) {
++			if (wb_cnt == 0) {
++				rssi_type = NPHY_RSSI_SEL_W1;
++				target_code = NPHY_RSSICAL_W1_TARGET_REV3;
++			} else {
++				rssi_type = NPHY_RSSI_SEL_W2;
++				target_code = NPHY_RSSICAL_W2_TARGET_REV3;
++			}
++
++			wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0,
++						       core ==
++						       PHY_CORE_0 ?
++						       RADIO_MIMO_CORESEL_CORE1
++						       :
++						       RADIO_MIMO_CORESEL_CORE2,
++						       NPHY_RAIL_I, rssi_type);
++			wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0,
++						       core ==
++						       PHY_CORE_0 ?
++						       RADIO_MIMO_CORESEL_CORE1
++						       :
++						       RADIO_MIMO_CORESEL_CORE2,
++						       NPHY_RAIL_Q, rssi_type);
++
++			wlc_phy_poll_rssi_nphy(pi, rssi_type, poll_result_core,
++					       NPHY_RSSICAL_NPOLL);
++
++			for (result_idx = 0; result_idx < 4; result_idx++) {
++				if (core == result_idx / 2) {
++					fine_digital_offset[result_idx] =
++						(target_code *
++						 NPHY_RSSICAL_NPOLL) -
++						poll_result_core[result_idx];
++					if (fine_digital_offset[result_idx] <
++					    0) {
++						fine_digital_offset[result_idx]
++							= abs(
++							    fine_digital_offset
++							    [result_idx]);
++						fine_digital_offset[result_idx]
++							+= (NPHY_RSSICAL_NPOLL
++							    / 2);
++						fine_digital_offset[result_idx]
++							/= NPHY_RSSICAL_NPOLL;
++						fine_digital_offset[result_idx]
++							= -fine_digital_offset
++								[result_idx];
++					} else {
++						fine_digital_offset[result_idx]
++							+= (NPHY_RSSICAL_NPOLL
++							    / 2);
++						fine_digital_offset[result_idx]
++							/= NPHY_RSSICAL_NPOLL;
++					}
++
++					wlc_phy_scale_offset_rssi_nphy(
++						pi, 0x0,
++						(s8)
++						fine_digital_offset
++						[core *
++						 2],
++						(core == PHY_CORE_0) ?
++						RADIO_MIMO_CORESEL_CORE1 :
++						RADIO_MIMO_CORESEL_CORE2,
++						(result_idx % 2 == 0) ?
++						NPHY_RAIL_I :
++						NPHY_RAIL_Q,
++						rssi_type);
++				}
++			}
++
++		}
++	}
++
++	write_phy_reg(pi, 0x91, NPHY_Rfctrlintc1_save);
++	write_phy_reg(pi, 0x92, NPHY_Rfctrlintc2_save);
++
++	wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
++
++	mod_phy_reg(pi, 0xe7, (0x1 << 0), 1 << 0);
++	mod_phy_reg(pi, 0x78, (0x1 << 0), 1 << 0);
++	mod_phy_reg(pi, 0xe7, (0x1 << 0), 0);
++
++	mod_phy_reg(pi, 0xec, (0x1 << 0), 1 << 0);
++	mod_phy_reg(pi, 0x78, (0x1 << 1), 1 << 1);
++	mod_phy_reg(pi, 0xec, (0x1 << 0), 0);
++
++	write_phy_reg(pi, 0x8f, NPHY_AfectrlOverride1_save);
++	write_phy_reg(pi, 0xa5, NPHY_AfectrlOverride2_save);
++	write_phy_reg(pi, 0xa6, NPHY_AfectrlCore1_save);
++	write_phy_reg(pi, 0xa7, NPHY_AfectrlCore2_save);
++	write_phy_reg(pi, 0xe7, NPHY_RfctrlOverride0_save);
++	write_phy_reg(pi, 0xec, NPHY_RfctrlOverride1_save);
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		write_phy_reg(pi, 0x342, NPHY_REV7_RfctrlOverride3_save);
++		write_phy_reg(pi, 0x343, NPHY_REV7_RfctrlOverride4_save);
++		write_phy_reg(pi, 0x346, NPHY_REV7_RfctrlOverride5_save);
++		write_phy_reg(pi, 0x347, NPHY_REV7_RfctrlOverride6_save);
++	}
++	write_phy_reg(pi, 0xe5, NPHY_RfctrlOverrideAux0_save);
++	write_phy_reg(pi, 0xe6, NPHY_RfctrlOverrideAux1_save);
++	write_phy_reg(pi, 0x78, NPHY_RfctrlCmd_save);
++	write_phy_reg(pi, 0xf9, NPHY_RfctrlMiscReg1_save);
++	write_phy_reg(pi, 0xfb, NPHY_RfctrlMiscReg2_save);
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		write_phy_reg(pi, 0x340, NPHY_REV7_RfctrlMiscReg3_save);
++		write_phy_reg(pi, 0x341, NPHY_REV7_RfctrlMiscReg4_save);
++		write_phy_reg(pi, 0x344, NPHY_REV7_RfctrlMiscReg5_save);
++		write_phy_reg(pi, 0x345, NPHY_REV7_RfctrlMiscReg6_save);
++	}
++	write_phy_reg(pi, 0x7a, NPHY_RfctrlRSSIOTHERS1_save);
++	write_phy_reg(pi, 0x7d, NPHY_RfctrlRSSIOTHERS2_save);
++
++	if (CHSPEC_IS2G(pi->radio_chanspec)) {
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			pi->rssical_cache.rssical_radio_regs_2G[0] =
++				read_radio_reg(pi, RADIO_2057_NB_MASTER_CORE0);
++			pi->rssical_cache.rssical_radio_regs_2G[1] =
++				read_radio_reg(pi, RADIO_2057_NB_MASTER_CORE1);
++		} else {
++			pi->rssical_cache.rssical_radio_regs_2G[0] =
++				read_radio_reg(pi,
++					       RADIO_2056_RX_RSSI_MISC |
++					       RADIO_2056_RX0);
++			pi->rssical_cache.rssical_radio_regs_2G[1] =
++				read_radio_reg(pi,
++					       RADIO_2056_RX_RSSI_MISC |
++					       RADIO_2056_RX1);
++		}
++
++		pi->rssical_cache.rssical_phyregs_2G[0] =
++			read_phy_reg(pi, 0x1a6);
++		pi->rssical_cache.rssical_phyregs_2G[1] =
++			read_phy_reg(pi, 0x1ac);
++		pi->rssical_cache.rssical_phyregs_2G[2] =
++			read_phy_reg(pi, 0x1b2);
++		pi->rssical_cache.rssical_phyregs_2G[3] =
++			read_phy_reg(pi, 0x1b8);
++		pi->rssical_cache.rssical_phyregs_2G[4] =
++			read_phy_reg(pi, 0x1a4);
++		pi->rssical_cache.rssical_phyregs_2G[5] =
++			read_phy_reg(pi, 0x1aa);
++		pi->rssical_cache.rssical_phyregs_2G[6] =
++			read_phy_reg(pi, 0x1b0);
++		pi->rssical_cache.rssical_phyregs_2G[7] =
++			read_phy_reg(pi, 0x1b6);
++		pi->rssical_cache.rssical_phyregs_2G[8] =
++			read_phy_reg(pi, 0x1a5);
++		pi->rssical_cache.rssical_phyregs_2G[9] =
++			read_phy_reg(pi, 0x1ab);
++		pi->rssical_cache.rssical_phyregs_2G[10] =
++			read_phy_reg(pi, 0x1b1);
++		pi->rssical_cache.rssical_phyregs_2G[11] =
++			read_phy_reg(pi, 0x1b7);
++
++		pi->nphy_rssical_chanspec_2G = pi->radio_chanspec;
++	} else {
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			pi->rssical_cache.rssical_radio_regs_5G[0] =
++				read_radio_reg(pi, RADIO_2057_NB_MASTER_CORE0);
++			pi->rssical_cache.rssical_radio_regs_5G[1] =
++				read_radio_reg(pi, RADIO_2057_NB_MASTER_CORE1);
++		} else {
++			pi->rssical_cache.rssical_radio_regs_5G[0] =
++				read_radio_reg(pi,
++					       RADIO_2056_RX_RSSI_MISC |
++					       RADIO_2056_RX0);
++			pi->rssical_cache.rssical_radio_regs_5G[1] =
++				read_radio_reg(pi,
++					       RADIO_2056_RX_RSSI_MISC |
++					       RADIO_2056_RX1);
++		}
++
++		pi->rssical_cache.rssical_phyregs_5G[0] =
++			read_phy_reg(pi, 0x1a6);
++		pi->rssical_cache.rssical_phyregs_5G[1] =
++			read_phy_reg(pi, 0x1ac);
++		pi->rssical_cache.rssical_phyregs_5G[2] =
++			read_phy_reg(pi, 0x1b2);
++		pi->rssical_cache.rssical_phyregs_5G[3] =
++			read_phy_reg(pi, 0x1b8);
++		pi->rssical_cache.rssical_phyregs_5G[4] =
++			read_phy_reg(pi, 0x1a4);
++		pi->rssical_cache.rssical_phyregs_5G[5] =
++			read_phy_reg(pi, 0x1aa);
++		pi->rssical_cache.rssical_phyregs_5G[6] =
++			read_phy_reg(pi, 0x1b0);
++		pi->rssical_cache.rssical_phyregs_5G[7] =
++			read_phy_reg(pi, 0x1b6);
++		pi->rssical_cache.rssical_phyregs_5G[8] =
++			read_phy_reg(pi, 0x1a5);
++		pi->rssical_cache.rssical_phyregs_5G[9] =
++			read_phy_reg(pi, 0x1ab);
++		pi->rssical_cache.rssical_phyregs_5G[10] =
++			read_phy_reg(pi, 0x1b1);
++		pi->rssical_cache.rssical_phyregs_5G[11] =
++			read_phy_reg(pi, 0x1b7);
++
++		pi->nphy_rssical_chanspec_5G = pi->radio_chanspec;
++	}
++
++	wlc_phy_classifier_nphy(pi, (0x7 << 0), classif_state);
++	wlc_phy_clip_det_nphy(pi, 1, clip_state);
++}
++
++static void wlc_phy_rssi_cal_nphy_rev2(struct brcms_phy *pi, u8 rssi_type)
++{
++	s32 target_code;
++	u16 classif_state;
++	u16 clip_state[2];
++	u16 rssi_ctrl_state[2], pd_state[2];
++	u16 rfctrlintc_state[2], rfpdcorerxtx_state[2];
++	u16 rfctrlintc_override_val;
++	u16 clip_off[] = { 0xffff, 0xffff };
++	u16 rf_pd_val, pd_mask, rssi_ctrl_mask;
++	u8 vcm, min_vcm, vcm_tmp[4];
++	u8 vcm_final[4] = { 0, 0, 0, 0 };
++	u8 result_idx, ctr;
++	s32 poll_results[4][4] = {
++		{0, 0, 0, 0},
++		{0, 0, 0, 0},
++		{0, 0, 0, 0},
++		{0, 0, 0, 0}
++	};
++	s32 poll_miniq[4][2] = {
++		{0, 0},
++		{0, 0},
++		{0, 0},
++		{0, 0}
++	};
++	s32 min_d, curr_d;
++	s32 fine_digital_offset[4];
++	s32 poll_results_min[4] = { 0, 0, 0, 0 };
++	s32 min_poll;
++
++	switch (rssi_type) {
++	case NPHY_RSSI_SEL_NB:
++		target_code = NPHY_RSSICAL_NB_TARGET;
++		break;
++	case NPHY_RSSI_SEL_W1:
++		target_code = NPHY_RSSICAL_W1_TARGET;
++		break;
++	case NPHY_RSSI_SEL_W2:
++		target_code = NPHY_RSSICAL_W2_TARGET;
++		break;
++	default:
++		return;
++		break;
++	}
++
++	classif_state = wlc_phy_classifier_nphy(pi, 0, 0);
++	wlc_phy_classifier_nphy(pi, (0x7 << 0), 4);
++	wlc_phy_clip_det_nphy(pi, 0, clip_state);
++	wlc_phy_clip_det_nphy(pi, 1, clip_off);
++
++	rf_pd_val = (rssi_type == NPHY_RSSI_SEL_NB) ? 0x6 : 0x4;
++	rfctrlintc_override_val =
++		CHSPEC_IS5G(pi->radio_chanspec) ? 0x140 : 0x110;
++
++	rfctrlintc_state[0] = read_phy_reg(pi, 0x91);
++	rfpdcorerxtx_state[0] = read_radio_reg(pi, RADIO_2055_PD_CORE1_RXTX);
++	write_phy_reg(pi, 0x91, rfctrlintc_override_val);
++	write_radio_reg(pi, RADIO_2055_PD_CORE1_RXTX, rf_pd_val);
++
++	rfctrlintc_state[1] = read_phy_reg(pi, 0x92);
++	rfpdcorerxtx_state[1] = read_radio_reg(pi, RADIO_2055_PD_CORE2_RXTX);
++	write_phy_reg(pi, 0x92, rfctrlintc_override_val);
++	write_radio_reg(pi, RADIO_2055_PD_CORE2_RXTX, rf_pd_val);
++
++	pd_mask = RADIO_2055_NBRSSI_PD | RADIO_2055_WBRSSI_G1_PD |
++		  RADIO_2055_WBRSSI_G2_PD;
++	pd_state[0] =
++		read_radio_reg(pi, RADIO_2055_PD_CORE1_RSSI_MISC) & pd_mask;
++	pd_state[1] =
++		read_radio_reg(pi, RADIO_2055_PD_CORE2_RSSI_MISC) & pd_mask;
++	mod_radio_reg(pi, RADIO_2055_PD_CORE1_RSSI_MISC, pd_mask, 0);
++	mod_radio_reg(pi, RADIO_2055_PD_CORE2_RSSI_MISC, pd_mask, 0);
++	rssi_ctrl_mask = RADIO_2055_NBRSSI_SEL | RADIO_2055_WBRSSI_G1_SEL |
++			 RADIO_2055_WBRSSI_G2_SEL;
++	rssi_ctrl_state[0] =
++		read_radio_reg(pi, RADIO_2055_SP_RSSI_CORE1) & rssi_ctrl_mask;
++	rssi_ctrl_state[1] =
++		read_radio_reg(pi, RADIO_2055_SP_RSSI_CORE2) & rssi_ctrl_mask;
++	wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_ALLRX, rssi_type);
++
++	wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0, RADIO_MIMO_CORESEL_ALLRX,
++				       NPHY_RAIL_I, rssi_type);
++	wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0, RADIO_MIMO_CORESEL_ALLRX,
++				       NPHY_RAIL_Q, rssi_type);
++
++	for (vcm = 0; vcm < 4; vcm++) {
++
++		vcm_tmp[0] = vcm_tmp[1] = vcm_tmp[2] = vcm_tmp[3] = vcm;
++		if (rssi_type != NPHY_RSSI_SEL_W2)
++			wlc_phy_set_rssi_2055_vcm(pi, rssi_type, vcm_tmp);
++
++		wlc_phy_poll_rssi_nphy(pi, rssi_type, &poll_results[vcm][0],
++				       NPHY_RSSICAL_NPOLL);
++
++		if ((rssi_type == NPHY_RSSI_SEL_W1)
++		    || (rssi_type == NPHY_RSSI_SEL_W2)) {
++			for (ctr = 0; ctr < 2; ctr++)
++				poll_miniq[vcm][ctr] =
++					min(poll_results[vcm][ctr * 2 + 0],
++					    poll_results[vcm][ctr * 2 + 1]);
++		}
++	}
++
++	for (result_idx = 0; result_idx < 4; result_idx++) {
++		min_d = NPHY_RSSICAL_MAXD;
++		min_vcm = 0;
++		min_poll = NPHY_RSSICAL_MAXREAD * NPHY_RSSICAL_NPOLL + 1;
++		for (vcm = 0; vcm < 4; vcm++) {
++			curr_d = abs(((rssi_type == NPHY_RSSI_SEL_NB) ?
++				      poll_results[vcm][result_idx] :
++				      poll_miniq[vcm][result_idx / 2]) -
++				     (target_code * NPHY_RSSICAL_NPOLL));
++			if (curr_d < min_d) {
++				min_d = curr_d;
++				min_vcm = vcm;
++			}
++			if (poll_results[vcm][result_idx] < min_poll)
++				min_poll = poll_results[vcm][result_idx];
++		}
++		vcm_final[result_idx] = min_vcm;
++		poll_results_min[result_idx] = min_poll;
++	}
++
++	if (rssi_type != NPHY_RSSI_SEL_W2)
++		wlc_phy_set_rssi_2055_vcm(pi, rssi_type, vcm_final);
++
++	for (result_idx = 0; result_idx < 4; result_idx++) {
++		fine_digital_offset[result_idx] =
++			(target_code * NPHY_RSSICAL_NPOLL) -
++			poll_results[vcm_final[result_idx]][result_idx];
++		if (fine_digital_offset[result_idx] < 0) {
++			fine_digital_offset[result_idx] =
++				abs(fine_digital_offset[result_idx]);
++			fine_digital_offset[result_idx] +=
++				(NPHY_RSSICAL_NPOLL / 2);
++			fine_digital_offset[result_idx] /= NPHY_RSSICAL_NPOLL;
++			fine_digital_offset[result_idx] =
++				-fine_digital_offset[result_idx];
++		} else {
++			fine_digital_offset[result_idx] +=
++				(NPHY_RSSICAL_NPOLL / 2);
++			fine_digital_offset[result_idx] /= NPHY_RSSICAL_NPOLL;
++		}
++
++		if (poll_results_min[result_idx] ==
++		    NPHY_RSSICAL_MAXREAD * NPHY_RSSICAL_NPOLL)
++			fine_digital_offset[result_idx] =
++				(target_code - NPHY_RSSICAL_MAXREAD - 1);
++
++		wlc_phy_scale_offset_rssi_nphy(pi, 0x0,
++					       (s8)
++					       fine_digital_offset[result_idx],
++					       (result_idx / 2 ==
++						0) ? RADIO_MIMO_CORESEL_CORE1 :
++					       RADIO_MIMO_CORESEL_CORE2,
++					       (result_idx % 2 ==
++						0) ? NPHY_RAIL_I : NPHY_RAIL_Q,
++					       rssi_type);
++	}
++
++	mod_radio_reg(pi, RADIO_2055_PD_CORE1_RSSI_MISC, pd_mask, pd_state[0]);
++	mod_radio_reg(pi, RADIO_2055_PD_CORE2_RSSI_MISC, pd_mask, pd_state[1]);
++	if (rssi_ctrl_state[0] == RADIO_2055_NBRSSI_SEL)
++		wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE1,
++				     NPHY_RSSI_SEL_NB);
++	else if (rssi_ctrl_state[0] == RADIO_2055_WBRSSI_G1_SEL)
++		wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE1,
++				     NPHY_RSSI_SEL_W1);
++	else if (rssi_ctrl_state[0] == RADIO_2055_WBRSSI_G2_SEL)
++		wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE1,
++				     NPHY_RSSI_SEL_W2);
++	else
++		wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE1,
++				     NPHY_RSSI_SEL_W2);
++	if (rssi_ctrl_state[1] == RADIO_2055_NBRSSI_SEL)
++		wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE2,
++				     NPHY_RSSI_SEL_NB);
++	else if (rssi_ctrl_state[1] == RADIO_2055_WBRSSI_G1_SEL)
++		wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE2,
++				     NPHY_RSSI_SEL_W1);
++	else if (rssi_ctrl_state[1] == RADIO_2055_WBRSSI_G2_SEL)
++		wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE2,
++				     NPHY_RSSI_SEL_W2);
++	else
++		wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE2,
++				     NPHY_RSSI_SEL_W2);
++
++	wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_OFF, rssi_type);
++
++	write_phy_reg(pi, 0x91, rfctrlintc_state[0]);
++	write_radio_reg(pi, RADIO_2055_PD_CORE1_RXTX, rfpdcorerxtx_state[0]);
++	write_phy_reg(pi, 0x92, rfctrlintc_state[1]);
++	write_radio_reg(pi, RADIO_2055_PD_CORE2_RXTX, rfpdcorerxtx_state[1]);
++
++	wlc_phy_classifier_nphy(pi, (0x7 << 0), classif_state);
++	wlc_phy_clip_det_nphy(pi, 1, clip_state);
++
++	wlc_phy_resetcca_nphy(pi);
++}
++
++void wlc_phy_rssi_cal_nphy(struct brcms_phy *pi)
++{
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		wlc_phy_rssi_cal_nphy_rev3(pi);
++	} else {
++		wlc_phy_rssi_cal_nphy_rev2(pi, NPHY_RSSI_SEL_NB);
++		wlc_phy_rssi_cal_nphy_rev2(pi, NPHY_RSSI_SEL_W1);
++		wlc_phy_rssi_cal_nphy_rev2(pi, NPHY_RSSI_SEL_W2);
++	}
++}
++
++int
++wlc_phy_rssi_compute_nphy(struct brcms_phy *pi, struct d11rxhdr *rxh)
++{
++	s16 rxpwr, rxpwr0, rxpwr1;
++	s16 phyRx0_l, phyRx2_l;
++
++	rxpwr = 0;
++	rxpwr0 = rxh->PhyRxStatus_1 & PRXS1_nphy_PWR0_MASK;
++	rxpwr1 = (rxh->PhyRxStatus_1 & PRXS1_nphy_PWR1_MASK) >> 8;
++
++	if (rxpwr0 > 127)
++		rxpwr0 -= 256;
++	if (rxpwr1 > 127)
++		rxpwr1 -= 256;
++
++	phyRx0_l = rxh->PhyRxStatus_0 & 0x00ff;
++	phyRx2_l = rxh->PhyRxStatus_2 & 0x00ff;
++	if (phyRx2_l > 127)
++		phyRx2_l -= 256;
++
++	if (((rxpwr0 == 16) || (rxpwr0 == 32))) {
++		rxpwr0 = rxpwr1;
++		rxpwr1 = phyRx2_l;
++	}
++
++	if (pi->sh->rssi_mode == RSSI_ANT_MERGE_MAX)
++		rxpwr = (rxpwr0 > rxpwr1) ? rxpwr0 : rxpwr1;
++	else if (pi->sh->rssi_mode == RSSI_ANT_MERGE_MIN)
++		rxpwr = (rxpwr0 < rxpwr1) ? rxpwr0 : rxpwr1;
++	else if (pi->sh->rssi_mode == RSSI_ANT_MERGE_AVG)
++		rxpwr = (rxpwr0 + rxpwr1) >> 1;
++
++	return rxpwr;
++}
++
++static void
++wlc_phy_loadsampletable_nphy(struct brcms_phy *pi, struct cordic_iq *tone_buf,
++			     u16 num_samps)
++{
++	u16 t;
++	u32 *data_buf = NULL;
++
++	data_buf = kmalloc(sizeof(u32) * num_samps, GFP_ATOMIC);
++	if (data_buf == NULL)
++		return;
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++	for (t = 0; t < num_samps; t++)
++		data_buf[t] = ((((unsigned int)tone_buf[t].i) & 0x3ff) << 10) |
++			      (((unsigned int)tone_buf[t].q) & 0x3ff);
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_SAMPLEPLAY, num_samps, 0, 32,
++				 data_buf);
++
++	kfree(data_buf);
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, false);
++}
++
++static u16
++wlc_phy_gen_load_samples_nphy(struct brcms_phy *pi, u32 f_kHz, u16 max_val,
++			      u8 dac_test_mode)
++{
++	u8 phy_bw, is_phybw40;
++	u16 num_samps, t, spur;
++	s32 theta = 0, rot = 0;
++	u32 tbl_len;
++	struct cordic_iq *tone_buf = NULL;
++
++	is_phybw40 = CHSPEC_IS40(pi->radio_chanspec);
++	phy_bw = (is_phybw40 == 1) ? 40 : 20;
++	tbl_len = (phy_bw << 3);
++
++	if (dac_test_mode == 1) {
++		spur = read_phy_reg(pi, 0x01);
++		spur = (spur >> 15) & 1;
++		phy_bw = (spur == 1) ? 82 : 80;
++		phy_bw = (is_phybw40 == 1) ? (phy_bw << 1) : phy_bw;
++
++		tbl_len = (phy_bw << 1);
++	}
++
++	tone_buf = kmalloc(sizeof(struct cordic_iq) * tbl_len, GFP_ATOMIC);
++	if (tone_buf == NULL)
++		return 0;
++
++	num_samps = (u16) tbl_len;
++	rot = ((f_kHz * 36) / phy_bw) / 100;
++	theta = 0;
++
++	for (t = 0; t < num_samps; t++) {
++
++		tone_buf[t] = cordic_calc_iq(theta);
++
++		theta += rot;
++
++		tone_buf[t].q = (s32) FLOAT(tone_buf[t].q * max_val);
++		tone_buf[t].i = (s32) FLOAT(tone_buf[t].i * max_val);
++	}
++
++	wlc_phy_loadsampletable_nphy(pi, tone_buf, num_samps);
++
++	kfree(tone_buf);
++
++	return num_samps;
++}
++
++static void
++wlc_phy_runsamples_nphy(struct brcms_phy *pi, u16 num_samps, u16 loops,
++			u16 wait, u8 iqmode, u8 dac_test_mode,
++			bool modify_bbmult)
++{
++	u16 bb_mult;
++	u8 phy_bw, sample_cmd;
++	u16 orig_RfseqCoreActv;
++	u16 lpf_bw_ctl_override3, lpf_bw_ctl_override4, lpf_bw_ctl_miscreg3,
++	    lpf_bw_ctl_miscreg4;
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++	phy_bw = 20;
++	if (CHSPEC_IS40(pi->radio_chanspec))
++		phy_bw = 40;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++
++		lpf_bw_ctl_override3 = read_phy_reg(pi, 0x342) & (0x1 << 7);
++		lpf_bw_ctl_override4 = read_phy_reg(pi, 0x343) & (0x1 << 7);
++		if (lpf_bw_ctl_override3 | lpf_bw_ctl_override4) {
++			lpf_bw_ctl_miscreg3 = read_phy_reg(pi, 0x340) &
++					      (0x7 << 8);
++			lpf_bw_ctl_miscreg4 = read_phy_reg(pi, 0x341) &
++					      (0x7 << 8);
++		} else {
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi,
++				(0x1 << 7),
++				wlc_phy_read_lpf_bw_ctl_nphy
++					(pi,
++					0), 0, 0,
++				NPHY_REV7_RFCTRLOVERRIDE_ID1);
++
++			pi->nphy_sample_play_lpf_bw_ctl_ovr = true;
++
++			lpf_bw_ctl_miscreg3 = read_phy_reg(pi, 0x340) &
++					      (0x7 << 8);
++			lpf_bw_ctl_miscreg4 = read_phy_reg(pi, 0x341) &
++					      (0x7 << 8);
++		}
++	}
++
++	if ((pi->nphy_bb_mult_save & BB_MULT_VALID_MASK) == 0) {
++
++		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL, 1, 87, 16,
++					&bb_mult);
++		pi->nphy_bb_mult_save =
++			BB_MULT_VALID_MASK | (bb_mult & BB_MULT_MASK);
++	}
++
++	if (modify_bbmult) {
++		bb_mult = (phy_bw == 20) ? 100 : 71;
++		bb_mult = (bb_mult << 8) + bb_mult;
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 1, 87, 16,
++					 &bb_mult);
++	}
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, false);
++
++	write_phy_reg(pi, 0xc6, num_samps - 1);
++
++	if (loops != 0xffff)
++		write_phy_reg(pi, 0xc4, loops - 1);
++	else
++		write_phy_reg(pi, 0xc4, loops);
++
++	write_phy_reg(pi, 0xc5, wait);
++
++	orig_RfseqCoreActv = read_phy_reg(pi, 0xa1);
++	or_phy_reg(pi, 0xa1, NPHY_RfseqMode_CoreActv_override);
++	if (iqmode) {
++
++		and_phy_reg(pi, 0xc2, 0x7FFF);
++
++		or_phy_reg(pi, 0xc2, 0x8000);
++	} else {
++
++		sample_cmd = (dac_test_mode == 1) ? 0x5 : 0x1;
++		write_phy_reg(pi, 0xc3, sample_cmd);
++	}
++
++	SPINWAIT(((read_phy_reg(pi, 0xa4) & 0x1) == 1), 1000);
++
++	write_phy_reg(pi, 0xa1, orig_RfseqCoreActv);
++}
++
++int
++wlc_phy_tx_tone_nphy(struct brcms_phy *pi, u32 f_kHz, u16 max_val,
++		     u8 iqmode, u8 dac_test_mode, bool modify_bbmult)
++{
++	u16 num_samps;
++	u16 loops = 0xffff;
++	u16 wait = 0;
++
++	num_samps = wlc_phy_gen_load_samples_nphy(pi, f_kHz, max_val,
++						  dac_test_mode);
++	if (num_samps == 0)
++		return -EBADE;
++
++	wlc_phy_runsamples_nphy(pi, num_samps, loops, wait, iqmode,
++				dac_test_mode, modify_bbmult);
++
++	return 0;
++}
++
++void wlc_phy_stopplayback_nphy(struct brcms_phy *pi)
++{
++	u16 playback_status;
++	u16 bb_mult;
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++	playback_status = read_phy_reg(pi, 0xc7);
++	if (playback_status & 0x1)
++		or_phy_reg(pi, 0xc3, NPHY_sampleCmd_STOP);
++	else if (playback_status & 0x2)
++		and_phy_reg(pi, 0xc2,
++			    (u16) ~NPHY_iqloCalCmdGctl_IQLO_CAL_EN);
++
++	and_phy_reg(pi, 0xc3, (u16) ~(0x1 << 2));
++
++	if ((pi->nphy_bb_mult_save & BB_MULT_VALID_MASK) != 0) {
++
++		bb_mult = pi->nphy_bb_mult_save & BB_MULT_MASK;
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 1, 87, 16,
++					 &bb_mult);
++
++		pi->nphy_bb_mult_save = 0;
++	}
++
++	if (NREV_IS(pi->pubpi.phy_rev, 7) || NREV_GE(pi->pubpi.phy_rev, 8)) {
++		if (pi->nphy_sample_play_lpf_bw_ctl_ovr) {
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi,
++				(0x1 << 7),
++				0, 0, 1,
++				NPHY_REV7_RFCTRLOVERRIDE_ID1);
++			pi->nphy_sample_play_lpf_bw_ctl_ovr = false;
++		}
++	}
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, false);
++}
++
++static u32 *brcms_phy_get_tx_pwrctrl_tbl(struct brcms_phy *pi)
++{
++	u32 *tx_pwrctrl_tbl = NULL;
++	uint phyrev = pi->pubpi.phy_rev;
++
++	if (PHY_IPA(pi)) {
++		tx_pwrctrl_tbl =
++			wlc_phy_get_ipa_gaintbl_nphy(pi);
++	} else {
++		if (CHSPEC_IS5G(pi->radio_chanspec)) {
++			if (NREV_IS(phyrev, 3))
++				tx_pwrctrl_tbl = nphy_tpc_5GHz_txgain_rev3;
++			else if (NREV_IS(phyrev, 4))
++				tx_pwrctrl_tbl =
++					(pi->srom_fem5g.extpagain == 3) ?
++					nphy_tpc_5GHz_txgain_HiPwrEPA :
++					nphy_tpc_5GHz_txgain_rev4;
++			else
++				tx_pwrctrl_tbl = nphy_tpc_5GHz_txgain_rev5;
++		} else {
++			if (NREV_GE(phyrev, 7)) {
++				if (pi->pubpi.radiorev == 3)
++					tx_pwrctrl_tbl =
++						nphy_tpc_txgain_epa_2057rev3;
++				else if (pi->pubpi.radiorev == 5)
++					tx_pwrctrl_tbl =
++						nphy_tpc_txgain_epa_2057rev5;
++			} else {
++				if (NREV_GE(phyrev, 5) &&
++				   (pi->srom_fem2g.extpagain ==	3))
++					tx_pwrctrl_tbl =
++						nphy_tpc_txgain_HiPwrEPA;
++				else
++					tx_pwrctrl_tbl =
++						nphy_tpc_txgain_rev3;
++			}
++		}
++	}
++	return tx_pwrctrl_tbl;
++}
++
++struct nphy_txgains wlc_phy_get_tx_gain_nphy(struct brcms_phy *pi)
++{
++	u16 base_idx[2], curr_gain[2];
++	u8 core_no;
++	struct nphy_txgains target_gain;
++	u32 *tx_pwrctrl_tbl = NULL;
++
++	if (pi->nphy_txpwrctrl == PHY_TPC_HW_OFF) {
++		if (pi->phyhang_avoid)
++			wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16,
++					curr_gain);
++
++		if (pi->phyhang_avoid)
++			wlc_phy_stay_in_carriersearch_nphy(pi, false);
++
++		for (core_no = 0; core_no < 2; core_no++) {
++			if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++				target_gain.ipa[core_no] =
++					curr_gain[core_no] & 0x0007;
++				target_gain.pad[core_no] =
++					((curr_gain[core_no] & 0x00F8) >> 3);
++				target_gain.pga[core_no] =
++					((curr_gain[core_no] & 0x0F00) >> 8);
++				target_gain.txgm[core_no] =
++					((curr_gain[core_no] & 0x7000) >> 12);
++				target_gain.txlpf[core_no] =
++					((curr_gain[core_no] & 0x8000) >> 15);
++			} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++				target_gain.ipa[core_no] =
++					curr_gain[core_no] & 0x000F;
++				target_gain.pad[core_no] =
++					((curr_gain[core_no] & 0x00F0) >> 4);
++				target_gain.pga[core_no] =
++					((curr_gain[core_no] & 0x0F00) >> 8);
++				target_gain.txgm[core_no] =
++					((curr_gain[core_no] & 0x7000) >> 12);
++			} else {
++				target_gain.ipa[core_no] =
++					curr_gain[core_no] & 0x0003;
++				target_gain.pad[core_no] =
++					((curr_gain[core_no] & 0x000C) >> 2);
++				target_gain.pga[core_no] =
++					((curr_gain[core_no] & 0x0070) >> 4);
++				target_gain.txgm[core_no] =
++					((curr_gain[core_no] & 0x0380) >> 7);
++			}
++		}
++	} else {
++		uint phyrev = pi->pubpi.phy_rev;
++
++		base_idx[0] = (read_phy_reg(pi, 0x1ed) >> 8) & 0x7f;
++		base_idx[1] = (read_phy_reg(pi, 0x1ee) >> 8) & 0x7f;
++		for (core_no = 0; core_no < 2; core_no++) {
++			if (NREV_GE(phyrev, 3)) {
++				tx_pwrctrl_tbl =
++					brcms_phy_get_tx_pwrctrl_tbl(pi);
++				if (NREV_GE(phyrev, 7)) {
++					target_gain.ipa[core_no] =
++						(tx_pwrctrl_tbl
++						 [base_idx[core_no]]
++						 >> 16) & 0x7;
++					target_gain.pad[core_no] =
++						(tx_pwrctrl_tbl
++						 [base_idx[core_no]]
++						 >> 19) & 0x1f;
++					target_gain.pga[core_no] =
++						(tx_pwrctrl_tbl
++						 [base_idx[core_no]]
++						 >> 24) & 0xf;
++					target_gain.txgm[core_no] =
++						(tx_pwrctrl_tbl
++						 [base_idx[core_no]]
++						 >> 28) & 0x7;
++					target_gain.txlpf[core_no] =
++						(tx_pwrctrl_tbl
++						 [base_idx[core_no]]
++						 >> 31) & 0x1;
++				} else {
++					target_gain.ipa[core_no] =
++						(tx_pwrctrl_tbl
++						 [base_idx[core_no]]
++						 >> 16) & 0xf;
++					target_gain.pad[core_no] =
++						(tx_pwrctrl_tbl
++						 [base_idx[core_no]]
++						 >> 20) & 0xf;
++					target_gain.pga[core_no] =
++						(tx_pwrctrl_tbl
++						 [base_idx[core_no]]
++						 >> 24) & 0xf;
++					target_gain.txgm[core_no] =
++						(tx_pwrctrl_tbl
++						[base_idx[core_no]]
++						 >> 28) & 0x7;
++				}
++			} else {
++				target_gain.ipa[core_no] =
++					(nphy_tpc_txgain[base_idx[core_no]] >>
++					 16) & 0x3;
++				target_gain.pad[core_no] =
++					(nphy_tpc_txgain[base_idx[core_no]] >>
++					 18) & 0x3;
++				target_gain.pga[core_no] =
++					(nphy_tpc_txgain[base_idx[core_no]] >>
++					 20) & 0x7;
++				target_gain.txgm[core_no] =
++					(nphy_tpc_txgain[base_idx[core_no]] >>
++					 23) & 0x7;
++			}
++		}
++	}
++
++	return target_gain;
++}
++
++static void
++wlc_phy_iqcal_gainparams_nphy(struct brcms_phy *pi, u16 core_no,
++			      struct nphy_txgains target_gain,
++			      struct nphy_iqcal_params *params)
++{
++	u8 k;
++	int idx;
++	u16 gain_index;
++	u8 band_idx = (CHSPEC_IS5G(pi->radio_chanspec) ? 1 : 0);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		if (NREV_GE(pi->pubpi.phy_rev, 7))
++			params->txlpf = target_gain.txlpf[core_no];
++
++		params->txgm = target_gain.txgm[core_no];
++		params->pga = target_gain.pga[core_no];
++		params->pad = target_gain.pad[core_no];
++		params->ipa = target_gain.ipa[core_no];
++		if (NREV_GE(pi->pubpi.phy_rev, 7))
++			params->cal_gain =
++				((params->txlpf << 15) | (params->txgm << 12) |
++				 (params->pga << 8) |
++				 (params->pad << 3) | (params->ipa));
++		else
++			params->cal_gain =
++				((params->txgm << 12) | (params->pga << 8) |
++				 (params->pad << 4) | (params->ipa));
++
++		params->ncorr[0] = 0x79;
++		params->ncorr[1] = 0x79;
++		params->ncorr[2] = 0x79;
++		params->ncorr[3] = 0x79;
++		params->ncorr[4] = 0x79;
++	} else {
++
++		gain_index = ((target_gain.pad[core_no] << 0) |
++			      (target_gain.pga[core_no] << 4) |
++			      (target_gain.txgm[core_no] << 8));
++
++		idx = -1;
++		for (k = 0; k < NPHY_IQCAL_NUMGAINS; k++) {
++			if (tbl_iqcal_gainparams_nphy[band_idx][k][0] ==
++			    gain_index) {
++				idx = k;
++				break;
++			}
++		}
++
++		params->txgm = tbl_iqcal_gainparams_nphy[band_idx][k][1];
++		params->pga = tbl_iqcal_gainparams_nphy[band_idx][k][2];
++		params->pad = tbl_iqcal_gainparams_nphy[band_idx][k][3];
++		params->cal_gain = ((params->txgm << 7) | (params->pga << 4) |
++				    (params->pad << 2));
++		params->ncorr[0] = tbl_iqcal_gainparams_nphy[band_idx][k][4];
++		params->ncorr[1] = tbl_iqcal_gainparams_nphy[band_idx][k][5];
++		params->ncorr[2] = tbl_iqcal_gainparams_nphy[band_idx][k][6];
++		params->ncorr[3] = tbl_iqcal_gainparams_nphy[band_idx][k][7];
++	}
++}
++
++static void wlc_phy_txcal_radio_setup_nphy(struct brcms_phy *pi)
++{
++	u16 jtag_core, core;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++
++		for (core = 0; core <= 1; core++) {
++
++			pi->tx_rx_cal_radio_saveregs[(core * 11) + 0] =
++				READ_RADIO_REG3(pi, RADIO_2057, TX, core,
++						TX_SSI_MASTER);
++
++			pi->tx_rx_cal_radio_saveregs[(core * 11) + 1] =
++				READ_RADIO_REG3(pi, RADIO_2057, TX, core,
++						IQCAL_VCM_HG);
++
++			pi->tx_rx_cal_radio_saveregs[(core * 11) + 2] =
++				READ_RADIO_REG3(pi, RADIO_2057, TX, core,
++						IQCAL_IDAC);
++
++			pi->tx_rx_cal_radio_saveregs[(core * 11) + 3] =
++				READ_RADIO_REG3(pi, RADIO_2057, TX, core,
++						TSSI_VCM);
++
++			pi->tx_rx_cal_radio_saveregs[(core * 11) + 4] = 0;
++
++			pi->tx_rx_cal_radio_saveregs[(core * 11) + 5] =
++				READ_RADIO_REG3(pi, RADIO_2057, TX, core,
++						TX_SSI_MUX);
++
++			if (pi->pubpi.radiorev != 5)
++				pi->tx_rx_cal_radio_saveregs[(core * 11) + 6] =
++					READ_RADIO_REG3(pi, RADIO_2057, TX,
++							core,
++							TSSIA);
++
++			pi->tx_rx_cal_radio_saveregs[(core * 11) + 7] =
++			       READ_RADIO_REG3(pi, RADIO_2057, TX, core, TSSIG);
++
++			pi->tx_rx_cal_radio_saveregs[(core * 11) + 8] =
++				READ_RADIO_REG3(pi, RADIO_2057, TX, core,
++						TSSI_MISC1);
++
++			if (CHSPEC_IS5G(pi->radio_chanspec)) {
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TX_SSI_MASTER, 0x0a);
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 IQCAL_VCM_HG, 0x43);
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 IQCAL_IDAC, 0x55);
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TSSI_VCM, 0x00);
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TSSIG, 0x00);
++				if (pi->use_int_tx_iqlo_cal_nphy) {
++					WRITE_RADIO_REG3(pi, RADIO_2057, TX,
++							 core, TX_SSI_MUX, 0x4);
++					if (!(pi->
++					internal_tx_iqlo_cal_tapoff_intpa_nphy))
++						WRITE_RADIO_REG3(pi, RADIO_2057,
++								 TX, core,
++								 TSSIA, 0x31);
++					else
++						WRITE_RADIO_REG3(pi, RADIO_2057,
++								 TX, core,
++								 TSSIA, 0x21);
++				}
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TSSI_MISC1, 0x00);
++			} else {
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TX_SSI_MASTER, 0x06);
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 IQCAL_VCM_HG, 0x43);
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 IQCAL_IDAC, 0x55);
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TSSI_VCM, 0x00);
++
++				if (pi->pubpi.radiorev != 5)
++					WRITE_RADIO_REG3(pi, RADIO_2057, TX,
++							 core, TSSIA, 0x00);
++				if (pi->use_int_tx_iqlo_cal_nphy) {
++					WRITE_RADIO_REG3(pi, RADIO_2057, TX,
++							 core, TX_SSI_MUX,
++							 0x06);
++					if (!(pi->
++					internal_tx_iqlo_cal_tapoff_intpa_nphy))
++						WRITE_RADIO_REG3(pi, RADIO_2057,
++								 TX, core,
++								 TSSIG, 0x31);
++					else
++						WRITE_RADIO_REG3(pi, RADIO_2057,
++								 TX, core,
++								 TSSIG, 0x21);
++				}
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TSSI_MISC1, 0x00);
++			}
++		}
++	} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++
++		for (core = 0; core <= 1; core++) {
++			jtag_core =
++				(core ==
++				 PHY_CORE_0) ? RADIO_2056_TX0 : RADIO_2056_TX1;
++
++			pi->tx_rx_cal_radio_saveregs[(core * 11) + 0] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_TX_SSI_MASTER |
++					       jtag_core);
++
++			pi->tx_rx_cal_radio_saveregs[(core * 11) + 1] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_IQCAL_VCM_HG |
++					       jtag_core);
++
++			pi->tx_rx_cal_radio_saveregs[(core * 11) + 2] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_IQCAL_IDAC |
++					       jtag_core);
++
++			pi->tx_rx_cal_radio_saveregs[(core * 11) + 3] =
++				read_radio_reg(
++					pi,
++					RADIO_2056_TX_TSSI_VCM |
++					jtag_core);
++
++			pi->tx_rx_cal_radio_saveregs[(core * 11) + 4] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_TX_AMP_DET |
++					       jtag_core);
++
++			pi->tx_rx_cal_radio_saveregs[(core * 11) + 5] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_TX_SSI_MUX |
++					       jtag_core);
++
++			pi->tx_rx_cal_radio_saveregs[(core * 11) + 6] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_TSSIA | jtag_core);
++
++			pi->tx_rx_cal_radio_saveregs[(core * 11) + 7] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_TSSIG | jtag_core);
++
++			pi->tx_rx_cal_radio_saveregs[(core * 11) + 8] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_TSSI_MISC1 |
++					       jtag_core);
++
++			pi->tx_rx_cal_radio_saveregs[(core * 11) + 9] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_TSSI_MISC2 |
++					       jtag_core);
++
++			pi->tx_rx_cal_radio_saveregs[(core * 11) + 10] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_TSSI_MISC3 |
++					       jtag_core);
++
++			if (CHSPEC_IS5G(pi->radio_chanspec)) {
++				write_radio_reg(pi,
++						RADIO_2056_TX_TX_SSI_MASTER |
++						jtag_core, 0x0a);
++				write_radio_reg(pi,
++						RADIO_2056_TX_IQCAL_VCM_HG |
++						jtag_core, 0x40);
++				write_radio_reg(pi,
++						RADIO_2056_TX_IQCAL_IDAC |
++						jtag_core, 0x55);
++				write_radio_reg(pi,
++						RADIO_2056_TX_TSSI_VCM |
++						jtag_core, 0x00);
++				write_radio_reg(pi,
++						RADIO_2056_TX_TX_AMP_DET |
++						jtag_core, 0x00);
++
++				if (PHY_IPA(pi)) {
++					write_radio_reg(
++						pi,
++						RADIO_2056_TX_TX_SSI_MUX
++						| jtag_core, 0x4);
++					write_radio_reg(pi,
++							RADIO_2056_TX_TSSIA |
++							jtag_core, 0x1);
++				} else {
++					write_radio_reg(
++						pi,
++						RADIO_2056_TX_TX_SSI_MUX
++						| jtag_core, 0x00);
++					write_radio_reg(pi,
++							RADIO_2056_TX_TSSIA |
++							jtag_core, 0x2f);
++				}
++				write_radio_reg(pi,
++						RADIO_2056_TX_TSSIG | jtag_core,
++						0x00);
++				write_radio_reg(pi,
++						RADIO_2056_TX_TSSI_MISC1 |
++						jtag_core, 0x00);
++
++				write_radio_reg(pi,
++						RADIO_2056_TX_TSSI_MISC2 |
++						jtag_core, 0x00);
++				write_radio_reg(pi,
++						RADIO_2056_TX_TSSI_MISC3 |
++						jtag_core, 0x00);
++			} else {
++				write_radio_reg(pi,
++						RADIO_2056_TX_TX_SSI_MASTER |
++						jtag_core, 0x06);
++				write_radio_reg(pi,
++						RADIO_2056_TX_IQCAL_VCM_HG |
++						jtag_core, 0x40);
++				write_radio_reg(pi,
++						RADIO_2056_TX_IQCAL_IDAC |
++						jtag_core, 0x55);
++				write_radio_reg(pi,
++						RADIO_2056_TX_TSSI_VCM |
++						jtag_core, 0x00);
++				write_radio_reg(pi,
++						RADIO_2056_TX_TX_AMP_DET |
++						jtag_core, 0x00);
++				write_radio_reg(pi,
++						RADIO_2056_TX_TSSIA | jtag_core,
++						0x00);
++
++				if (PHY_IPA(pi)) {
++
++					write_radio_reg(
++						pi,
++						RADIO_2056_TX_TX_SSI_MUX
++						| jtag_core, 0x06);
++					if (NREV_LT(pi->pubpi.phy_rev, 5))
++						write_radio_reg(
++							pi,
++							RADIO_2056_TX_TSSIG
++							| jtag_core,
++							0x11);
++					else
++						write_radio_reg(
++							pi,
++							RADIO_2056_TX_TSSIG
++							| jtag_core,
++							0x1);
++				} else {
++					write_radio_reg(
++						pi,
++						RADIO_2056_TX_TX_SSI_MUX
++						| jtag_core, 0x00);
++					write_radio_reg(pi,
++							RADIO_2056_TX_TSSIG |
++							jtag_core, 0x20);
++				}
++
++				write_radio_reg(pi,
++						RADIO_2056_TX_TSSI_MISC1 |
++						jtag_core, 0x00);
++				write_radio_reg(pi,
++						RADIO_2056_TX_TSSI_MISC2 |
++						jtag_core, 0x00);
++				write_radio_reg(pi,
++						RADIO_2056_TX_TSSI_MISC3 |
++						jtag_core, 0x00);
++			}
++		}
++	} else {
++
++		pi->tx_rx_cal_radio_saveregs[0] =
++			read_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1);
++		write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1, 0x29);
++		pi->tx_rx_cal_radio_saveregs[1] =
++			read_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2);
++		write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2, 0x54);
++
++		pi->tx_rx_cal_radio_saveregs[2] =
++			read_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1);
++		write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1, 0x29);
++		pi->tx_rx_cal_radio_saveregs[3] =
++			read_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2);
++		write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2, 0x54);
++
++		pi->tx_rx_cal_radio_saveregs[4] =
++			read_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1);
++		pi->tx_rx_cal_radio_saveregs[5] =
++			read_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2);
++
++		if ((read_phy_reg(pi, 0x09) & NPHY_BandControl_currentBand) ==
++		    0) {
++
++			write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1, 0x04);
++			write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2, 0x04);
++		} else {
++
++			write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1, 0x20);
++			write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2, 0x20);
++		}
++
++		if (NREV_LT(pi->pubpi.phy_rev, 2)) {
++
++			or_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM, 0x20);
++			or_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM, 0x20);
++		} else {
++
++			and_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM, 0xdf);
++			and_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM, 0xdf);
++		}
++	}
++}
++
++static void wlc_phy_txcal_radio_cleanup_nphy(struct brcms_phy *pi)
++{
++	u16 jtag_core, core;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		for (core = 0; core <= 1; core++) {
++
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++					 TX_SSI_MASTER,
++					 pi->
++					 tx_rx_cal_radio_saveregs[(core * 11) +
++								  0]);
++
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, IQCAL_VCM_HG,
++					 pi->
++					 tx_rx_cal_radio_saveregs[(core * 11) +
++								  1]);
++
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, IQCAL_IDAC,
++					 pi->
++					 tx_rx_cal_radio_saveregs[(core * 11) +
++								  2]);
++
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSI_VCM,
++					 pi->
++					 tx_rx_cal_radio_saveregs[(core * 11) +
++								  3]);
++
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TX_SSI_MUX,
++					 pi->
++					 tx_rx_cal_radio_saveregs[(core * 11) +
++								  5]);
++
++			if (pi->pubpi.radiorev != 5)
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TSSIA,
++						 pi->tx_rx_cal_radio_saveregs
++							     [(core * 11) + 6]);
++
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSIG,
++					 pi->
++					 tx_rx_cal_radio_saveregs[(core * 11) +
++								  7]);
++
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSI_MISC1,
++					 pi->
++					 tx_rx_cal_radio_saveregs[(core * 11) +
++								  8]);
++		}
++	} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		for (core = 0; core <= 1; core++) {
++			jtag_core = (core == PHY_CORE_0) ?
++				     RADIO_2056_TX0 : RADIO_2056_TX1;
++
++			write_radio_reg(pi,
++					RADIO_2056_TX_TX_SSI_MASTER | jtag_core,
++					pi->
++					tx_rx_cal_radio_saveregs[(core * 11) +
++								 0]);
++
++			write_radio_reg(pi,
++					RADIO_2056_TX_IQCAL_VCM_HG | jtag_core,
++					pi->
++					tx_rx_cal_radio_saveregs[(core * 11) +
++								 1]);
++
++			write_radio_reg(pi,
++					RADIO_2056_TX_IQCAL_IDAC | jtag_core,
++					pi->
++					tx_rx_cal_radio_saveregs[(core * 11) +
++								 2]);
++
++			write_radio_reg(pi, RADIO_2056_TX_TSSI_VCM | jtag_core,
++					pi->
++					tx_rx_cal_radio_saveregs[(core * 11) +
++								 3]);
++
++			write_radio_reg(pi,
++					RADIO_2056_TX_TX_AMP_DET | jtag_core,
++					pi->
++					tx_rx_cal_radio_saveregs[(core * 11) +
++								 4]);
++
++			write_radio_reg(pi,
++					RADIO_2056_TX_TX_SSI_MUX | jtag_core,
++					pi->
++					tx_rx_cal_radio_saveregs[(core * 11) +
++								 5]);
++
++			write_radio_reg(pi, RADIO_2056_TX_TSSIA | jtag_core,
++					pi->
++					tx_rx_cal_radio_saveregs[(core * 11) +
++								 6]);
++
++			write_radio_reg(pi, RADIO_2056_TX_TSSIG | jtag_core,
++					pi->
++					tx_rx_cal_radio_saveregs[(core * 11) +
++								 7]);
++
++			write_radio_reg(pi,
++					RADIO_2056_TX_TSSI_MISC1 | jtag_core,
++					pi->
++					tx_rx_cal_radio_saveregs[(core * 11) +
++								 8]);
++
++			write_radio_reg(pi,
++					RADIO_2056_TX_TSSI_MISC2 | jtag_core,
++					pi->
++					tx_rx_cal_radio_saveregs[(core * 11) +
++								 9]);
++
++			write_radio_reg(pi,
++					RADIO_2056_TX_TSSI_MISC3 | jtag_core,
++					pi->
++					tx_rx_cal_radio_saveregs[(core * 11) +
++								 10]);
++		}
++	} else {
++
++		write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1,
++				pi->tx_rx_cal_radio_saveregs[0]);
++		write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2,
++				pi->tx_rx_cal_radio_saveregs[1]);
++		write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1,
++				pi->tx_rx_cal_radio_saveregs[2]);
++		write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2,
++				pi->tx_rx_cal_radio_saveregs[3]);
++		write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1,
++				pi->tx_rx_cal_radio_saveregs[4]);
++		write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2,
++				pi->tx_rx_cal_radio_saveregs[5]);
++	}
++}
++
++static void wlc_phy_txcal_physetup_nphy(struct brcms_phy *pi)
++{
++	u16 val, mask;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		pi->tx_rx_cal_phy_saveregs[0] = read_phy_reg(pi, 0xa6);
++		pi->tx_rx_cal_phy_saveregs[1] = read_phy_reg(pi, 0xa7);
++
++		mask = ((0x3 << 8) | (0x3 << 10));
++		val = (0x2 << 8);
++		val |= (0x2 << 10);
++		mod_phy_reg(pi, 0xa6, mask, val);
++		mod_phy_reg(pi, 0xa7, mask, val);
++
++		val = read_phy_reg(pi, 0x8f);
++		pi->tx_rx_cal_phy_saveregs[2] = val;
++		val |= ((0x1 << 9) | (0x1 << 10));
++		write_phy_reg(pi, 0x8f, val);
++
++		val = read_phy_reg(pi, 0xa5);
++		pi->tx_rx_cal_phy_saveregs[3] = val;
++		val |= ((0x1 << 9) | (0x1 << 10));
++		write_phy_reg(pi, 0xa5, val);
++
++		pi->tx_rx_cal_phy_saveregs[4] = read_phy_reg(pi, 0x01);
++		mod_phy_reg(pi, 0x01, (0x1 << 15), 0);
++
++		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 3, 16,
++					&val);
++		pi->tx_rx_cal_phy_saveregs[5] = val;
++		val = 0;
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 3, 16,
++					 &val);
++
++		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 19, 16,
++					&val);
++		pi->tx_rx_cal_phy_saveregs[6] = val;
++		val = 0;
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 19, 16,
++					 &val);
++
++		pi->tx_rx_cal_phy_saveregs[7] = read_phy_reg(pi, 0x91);
++		pi->tx_rx_cal_phy_saveregs[8] = read_phy_reg(pi, 0x92);
++
++		if (!(pi->use_int_tx_iqlo_cal_nphy))
++			wlc_phy_rfctrlintc_override_nphy(
++				pi,
++				NPHY_RfctrlIntc_override_PA,
++				1,
++				RADIO_MIMO_CORESEL_CORE1
++				|
++				RADIO_MIMO_CORESEL_CORE2);
++		else
++			wlc_phy_rfctrlintc_override_nphy(
++				pi,
++				NPHY_RfctrlIntc_override_PA,
++				0,
++				RADIO_MIMO_CORESEL_CORE1
++				|
++				RADIO_MIMO_CORESEL_CORE2);
++
++		wlc_phy_rfctrlintc_override_nphy(pi,
++						 NPHY_RfctrlIntc_override_TRSW,
++						 0x2, RADIO_MIMO_CORESEL_CORE1);
++		wlc_phy_rfctrlintc_override_nphy(pi,
++						 NPHY_RfctrlIntc_override_TRSW,
++						 0x8, RADIO_MIMO_CORESEL_CORE2);
++
++		pi->tx_rx_cal_phy_saveregs[9] = read_phy_reg(pi, 0x297);
++		pi->tx_rx_cal_phy_saveregs[10] = read_phy_reg(pi, 0x29b);
++		mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x297 :
++			    0x29b, (0x1 << 0), (0) << 0);
++
++		mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x297 :
++			    0x29b, (0x1 << 0), (0) << 0);
++
++		if (NREV_IS(pi->pubpi.phy_rev, 7)
++		    || NREV_GE(pi->pubpi.phy_rev, 8))
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 7),
++				wlc_phy_read_lpf_bw_ctl_nphy
++					(pi,
++					0), 0, 0,
++				NPHY_REV7_RFCTRLOVERRIDE_ID1);
++
++		if (pi->use_int_tx_iqlo_cal_nphy
++		    && !(pi->internal_tx_iqlo_cal_tapoff_intpa_nphy)) {
++
++			if (NREV_IS(pi->pubpi.phy_rev, 7)) {
++
++				mod_radio_reg(pi, RADIO_2057_OVR_REG0, 1 << 4,
++					      1 << 4);
++
++				if (CHSPEC_IS2G(pi->radio_chanspec)) {
++					mod_radio_reg(
++						pi,
++						RADIO_2057_PAD2G_TUNE_PUS_CORE0,
++						1, 0);
++					mod_radio_reg(
++						pi,
++						RADIO_2057_PAD2G_TUNE_PUS_CORE1,
++						1, 0);
++				} else {
++					mod_radio_reg(
++					     pi,
++					     RADIO_2057_IPA5G_CASCOFFV_PU_CORE0,
++					     1, 0);
++					mod_radio_reg(
++					     pi,
++					     RADIO_2057_IPA5G_CASCOFFV_PU_CORE1,
++					     1, 0);
++				}
++			} else if (NREV_GE(pi->pubpi.phy_rev, 8)) {
++				wlc_phy_rfctrl_override_nphy_rev7(
++					pi,
++					(0x1 << 3), 0,
++					0x3, 0,
++					NPHY_REV7_RFCTRLOVERRIDE_ID0);
++			}
++		}
++	} else {
++		pi->tx_rx_cal_phy_saveregs[0] = read_phy_reg(pi, 0xa6);
++		pi->tx_rx_cal_phy_saveregs[1] = read_phy_reg(pi, 0xa7);
++
++		mask = ((0x3 << 12) | (0x3 << 14));
++		val = (0x2 << 12);
++		val |= (0x2 << 14);
++		mod_phy_reg(pi, 0xa6, mask, val);
++		mod_phy_reg(pi, 0xa7, mask, val);
++
++		val = read_phy_reg(pi, 0xa5);
++		pi->tx_rx_cal_phy_saveregs[2] = val;
++		val |= ((0x1 << 12) | (0x1 << 13));
++		write_phy_reg(pi, 0xa5, val);
++
++		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 2, 16,
++					&val);
++		pi->tx_rx_cal_phy_saveregs[3] = val;
++		val |= 0x2000;
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 2, 16,
++					 &val);
++
++		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 18, 16,
++					&val);
++		pi->tx_rx_cal_phy_saveregs[4] = val;
++		val |= 0x2000;
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 18, 16,
++					 &val);
++
++		pi->tx_rx_cal_phy_saveregs[5] = read_phy_reg(pi, 0x91);
++		pi->tx_rx_cal_phy_saveregs[6] = read_phy_reg(pi, 0x92);
++		val = CHSPEC_IS5G(pi->radio_chanspec) ? 0x180 : 0x120;
++		write_phy_reg(pi, 0x91, val);
++		write_phy_reg(pi, 0x92, val);
++	}
++}
++
++static void wlc_phy_txcal_phycleanup_nphy(struct brcms_phy *pi)
++{
++	u16 mask;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		write_phy_reg(pi, 0xa6, pi->tx_rx_cal_phy_saveregs[0]);
++		write_phy_reg(pi, 0xa7, pi->tx_rx_cal_phy_saveregs[1]);
++		write_phy_reg(pi, 0x8f, pi->tx_rx_cal_phy_saveregs[2]);
++		write_phy_reg(pi, 0xa5, pi->tx_rx_cal_phy_saveregs[3]);
++		write_phy_reg(pi, 0x01, pi->tx_rx_cal_phy_saveregs[4]);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 3, 16,
++					 &pi->tx_rx_cal_phy_saveregs[5]);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 19, 16,
++					 &pi->tx_rx_cal_phy_saveregs[6]);
++
++		write_phy_reg(pi, 0x91, pi->tx_rx_cal_phy_saveregs[7]);
++		write_phy_reg(pi, 0x92, pi->tx_rx_cal_phy_saveregs[8]);
++
++		write_phy_reg(pi, 0x297, pi->tx_rx_cal_phy_saveregs[9]);
++		write_phy_reg(pi, 0x29b, pi->tx_rx_cal_phy_saveregs[10]);
++
++		if (NREV_IS(pi->pubpi.phy_rev, 7)
++		    || NREV_GE(pi->pubpi.phy_rev, 8))
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 7), 0, 0,
++				1,
++				NPHY_REV7_RFCTRLOVERRIDE_ID1);
++
++		wlc_phy_resetcca_nphy(pi);
++
++		if (pi->use_int_tx_iqlo_cal_nphy
++		    && !(pi->internal_tx_iqlo_cal_tapoff_intpa_nphy)) {
++
++			if (NREV_IS(pi->pubpi.phy_rev, 7)) {
++				if (CHSPEC_IS2G(pi->radio_chanspec)) {
++					mod_radio_reg(
++						pi,
++						RADIO_2057_PAD2G_TUNE_PUS_CORE0,
++						1, 1);
++					mod_radio_reg(
++						pi,
++						RADIO_2057_PAD2G_TUNE_PUS_CORE1,
++						1, 1);
++				} else {
++					mod_radio_reg(
++					     pi,
++					     RADIO_2057_IPA5G_CASCOFFV_PU_CORE0,
++					     1, 1);
++					mod_radio_reg(
++					     pi,
++					     RADIO_2057_IPA5G_CASCOFFV_PU_CORE1,
++					     1, 1);
++				}
++
++				mod_radio_reg(pi, RADIO_2057_OVR_REG0, 1 << 4,
++					      0);
++			} else if (NREV_GE(pi->pubpi.phy_rev, 8)) {
++				wlc_phy_rfctrl_override_nphy_rev7(
++					pi,
++					(0x1 << 3), 0,
++					0x3, 1,
++					NPHY_REV7_RFCTRLOVERRIDE_ID0);
++			}
++		}
++	} else {
++		mask = ((0x3 << 12) | (0x3 << 14));
++		mod_phy_reg(pi, 0xa6, mask, pi->tx_rx_cal_phy_saveregs[0]);
++		mod_phy_reg(pi, 0xa7, mask, pi->tx_rx_cal_phy_saveregs[1]);
++		write_phy_reg(pi, 0xa5, pi->tx_rx_cal_phy_saveregs[2]);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 2, 16,
++					 &pi->tx_rx_cal_phy_saveregs[3]);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 18, 16,
++					 &pi->tx_rx_cal_phy_saveregs[4]);
++
++		write_phy_reg(pi, 0x91, pi->tx_rx_cal_phy_saveregs[5]);
++		write_phy_reg(pi, 0x92, pi->tx_rx_cal_phy_saveregs[6]);
++	}
++}
++
++void
++wlc_phy_est_tonepwr_nphy(struct brcms_phy *pi, s32 *qdBm_pwrbuf, u8 num_samps)
++{
++	u16 tssi_reg;
++	s32 temp, pwrindex[2];
++	s32 idle_tssi[2];
++	s32 rssi_buf[4];
++	s32 tssival[2];
++	u8 tssi_type;
++
++	tssi_reg = read_phy_reg(pi, 0x1e9);
++
++	temp = (s32) (tssi_reg & 0x3f);
++	idle_tssi[0] = (temp <= 31) ? temp : (temp - 64);
++
++	temp = (s32) ((tssi_reg >> 8) & 0x3f);
++	idle_tssi[1] = (temp <= 31) ? temp : (temp - 64);
++
++	tssi_type =
++		CHSPEC_IS5G(pi->radio_chanspec) ?
++		(u8)NPHY_RSSI_SEL_TSSI_5G : (u8)NPHY_RSSI_SEL_TSSI_2G;
++
++	wlc_phy_poll_rssi_nphy(pi, tssi_type, rssi_buf, num_samps);
++
++	tssival[0] = rssi_buf[0] / ((s32) num_samps);
++	tssival[1] = rssi_buf[2] / ((s32) num_samps);
++
++	pwrindex[0] = idle_tssi[0] - tssival[0] + 64;
++	pwrindex[1] = idle_tssi[1] - tssival[1] + 64;
++
++	if (pwrindex[0] < 0)
++		pwrindex[0] = 0;
++	else if (pwrindex[0] > 63)
++		pwrindex[0] = 63;
++
++	if (pwrindex[1] < 0)
++		pwrindex[1] = 0;
++	else if (pwrindex[1] > 63)
++		pwrindex[1] = 63;
++
++	wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_CORE1TXPWRCTL, 1,
++				(u32) pwrindex[0], 32, &qdBm_pwrbuf[0]);
++	wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_CORE2TXPWRCTL, 1,
++				(u32) pwrindex[1], 32, &qdBm_pwrbuf[1]);
++}
++
++static void wlc_phy_update_txcal_ladder_nphy(struct brcms_phy *pi, u16 core)
++{
++	int index;
++	u32 bbmult_scale;
++	u16 bbmult;
++	u16 tblentry;
++
++	struct nphy_txiqcal_ladder ladder_lo[] = {
++		{3, 0}, {4, 0}, {6, 0}, {9, 0}, {13, 0}, {18, 0},
++		{25, 0}, {25, 1}, {25, 2}, {25, 3}, {25, 4}, {25, 5},
++		{25, 6}, {25, 7}, {35, 7}, {50, 7}, {71, 7}, {100, 7}
++	};
++
++	struct nphy_txiqcal_ladder ladder_iq[] = {
++		{3, 0}, {4, 0}, {6, 0}, {9, 0}, {13, 0}, {18, 0},
++		{25, 0}, {35, 0}, {50, 0}, {71, 0}, {100, 0}, {100, 1},
++		{100, 2}, {100, 3}, {100, 4}, {100, 5}, {100, 6}, {100, 7}
++	};
++
++	bbmult = (core == PHY_CORE_0) ?
++		 ((pi->nphy_txcal_bbmult >> 8) & 0xff) :
++		 (pi->nphy_txcal_bbmult & 0xff);
++
++	for (index = 0; index < 18; index++) {
++		bbmult_scale = ladder_lo[index].percent * bbmult;
++		bbmult_scale /= 100;
++
++		tblentry =
++			((bbmult_scale & 0xff) << 8) | ladder_lo[index].g_env;
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 1, index, 16,
++					 &tblentry);
++
++		bbmult_scale = ladder_iq[index].percent * bbmult;
++		bbmult_scale /= 100;
++
++		tblentry =
++			((bbmult_scale & 0xff) << 8) | ladder_iq[index].g_env;
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 1, index + 32,
++					 16, &tblentry);
++	}
++}
++
++static u8 wlc_phy_txpwr_idx_cur_get_nphy(struct brcms_phy *pi, u8 core)
++{
++	u16 tmp;
++	tmp = read_phy_reg(pi, ((core == PHY_CORE_0) ? 0x1ed : 0x1ee));
++
++	tmp = (tmp & (0x7f << 8)) >> 8;
++	return (u8) tmp;
++}
++
++static void
++wlc_phy_txpwr_idx_cur_set_nphy(struct brcms_phy *pi, u8 idx0, u8 idx1)
++{
++	mod_phy_reg(pi, 0x1e7, (0x7f << 0), idx0);
++
++	if (NREV_GT(pi->pubpi.phy_rev, 1))
++		mod_phy_reg(pi, 0x222, (0xff << 0), idx1);
++}
++
++static u16 wlc_phy_ipa_get_bbmult_nphy(struct brcms_phy *pi)
++{
++	u16 m0m1;
++
++	wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &m0m1);
++
++	return m0m1;
++}
++
++static void wlc_phy_ipa_set_bbmult_nphy(struct brcms_phy *pi, u8 m0, u8 m1)
++{
++	u16 m0m1 = (u16) ((m0 << 8) | m1);
++
++	wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &m0m1);
++	wlc_phy_table_write_nphy(pi, 15, 1, 95, 16, &m0m1);
++}
++
++static void
++wlc_phy_papd_cal_setup_nphy(struct brcms_phy *pi,
++			    struct nphy_papd_restore_state *state, u8 core)
++{
++	s32 tone_freq;
++	u8 off_core;
++	u16 mixgain = 0;
++
++	off_core = core ^ 0x1;
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++
++		if (NREV_IS(pi->pubpi.phy_rev, 7)
++		    || NREV_GE(pi->pubpi.phy_rev, 8))
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 7),
++				wlc_phy_read_lpf_bw_ctl_nphy
++					(pi,
++					0), 0, 0,
++				NPHY_REV7_RFCTRLOVERRIDE_ID1);
++
++		if (CHSPEC_IS2G(pi->radio_chanspec)) {
++			if (pi->pubpi.radiorev == 5)
++				mixgain = (core == 0) ? 0x20 : 0x00;
++			else if ((pi->pubpi.radiorev == 7)
++				 || (pi->pubpi.radiorev == 8))
++				mixgain = 0x00;
++			else if ((pi->pubpi.radiorev <= 4)
++				 || (pi->pubpi.radiorev == 6))
++				mixgain = 0x00;
++		} else {
++			if ((pi->pubpi.radiorev == 4) ||
++			    (pi->pubpi.radiorev == 6))
++				mixgain = 0x50;
++			else if ((pi->pubpi.radiorev == 3)
++				 || (pi->pubpi.radiorev == 7)
++				 || (pi->pubpi.radiorev == 8))
++				mixgain = 0x0;
++		}
++
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11),
++						  mixgain, (1 << core), 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
++
++		wlc_phy_rfctrl_override_1tomany_nphy(
++			pi,
++			NPHY_REV7_RfctrlOverride_cmd_tx_pu,
++			1, (1 << core), 0);
++		wlc_phy_rfctrl_override_1tomany_nphy(
++			pi,
++			NPHY_REV7_RfctrlOverride_cmd_tx_pu,
++			0, (1 << off_core), 0);
++
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3),
++						  0, 0x3, 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), 1,
++						  (1 << core), 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), 0,
++						  (1 << core), 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), 1,
++						  (1 << core), 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID2);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 8), 0,
++						  (1 << core), 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 9), 1,
++						  (1 << core), 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 10), 0,
++						  (1 << core), 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), 1,
++						  (1 << core), 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 5),
++						  0, (1 << core), 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 4), 0,
++						  (1 << core), 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++
++		state->afectrl[core] = read_phy_reg(pi, (core == PHY_CORE_0) ?
++						    0xa6 : 0xa7);
++		state->afeoverride[core] =
++			read_phy_reg(pi, (core == PHY_CORE_0) ? 0x8f : 0xa5);
++		state->afectrl[off_core] =
++			read_phy_reg(pi, (core == PHY_CORE_0) ? 0xa7 : 0xa6);
++		state->afeoverride[off_core] =
++			read_phy_reg(pi, (core == PHY_CORE_0) ? 0xa5 : 0x8f);
++
++		mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0xa6 : 0xa7),
++			    (0x1 << 2), 0);
++		mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0x8f :
++				 0xa5), (0x1 << 2), (0x1 << 2));
++
++		mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0xa7 : 0xa6),
++			    (0x1 << 2), (0x1 << 2));
++		mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0xa5 :
++				 0x8f), (0x1 << 2), (0x1 << 2));
++
++		if (CHSPEC_IS2G(pi->radio_chanspec)) {
++			state->pwrup[core] =
++				READ_RADIO_REG3(pi, RADIO_2057, TX, core,
++						TXRXCOUPLE_2G_PWRUP);
++			state->atten[core] =
++				READ_RADIO_REG3(pi, RADIO_2057, TX, core,
++						TXRXCOUPLE_2G_ATTEN);
++			state->pwrup[off_core] =
++				READ_RADIO_REG3(pi, RADIO_2057, TX, off_core,
++						TXRXCOUPLE_2G_PWRUP);
++			state->atten[off_core] =
++				READ_RADIO_REG3(pi, RADIO_2057, TX, off_core,
++						TXRXCOUPLE_2G_ATTEN);
++
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++					 TXRXCOUPLE_2G_PWRUP, 0xc);
++
++			if ((pi->pubpi.radiorev == 3) ||
++			    (pi->pubpi.radiorev == 4) ||
++			    (pi->pubpi.radiorev == 6))
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TXRXCOUPLE_2G_ATTEN, 0xf0);
++			else if (pi->pubpi.radiorev == 5)
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TXRXCOUPLE_2G_ATTEN,
++						 (core == 0) ? 0xf7 : 0xf2);
++			else if ((pi->pubpi.radiorev == 7)
++				 || (pi->pubpi.radiorev == 8))
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TXRXCOUPLE_2G_ATTEN, 0xf0);
++
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, off_core,
++					 TXRXCOUPLE_2G_PWRUP, 0x0);
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, off_core,
++					 TXRXCOUPLE_2G_ATTEN, 0xff);
++		} else {
++			state->pwrup[core] =
++				READ_RADIO_REG3(pi, RADIO_2057, TX, core,
++						TXRXCOUPLE_5G_PWRUP);
++			state->atten[core] =
++				READ_RADIO_REG3(pi, RADIO_2057, TX, core,
++						TXRXCOUPLE_5G_ATTEN);
++			state->pwrup[off_core] =
++				READ_RADIO_REG3(pi, RADIO_2057, TX, off_core,
++						TXRXCOUPLE_5G_PWRUP);
++			state->atten[off_core] =
++				READ_RADIO_REG3(pi, RADIO_2057, TX, off_core,
++						TXRXCOUPLE_5G_ATTEN);
++
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++					 TXRXCOUPLE_5G_PWRUP, 0xc);
++
++			if ((pi->pubpi.radiorev == 7)
++			    || (pi->pubpi.radiorev == 8))
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TXRXCOUPLE_5G_ATTEN, 0xf4);
++
++			else
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TXRXCOUPLE_5G_ATTEN, 0xf0);
++
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, off_core,
++					 TXRXCOUPLE_5G_PWRUP, 0x0);
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, off_core,
++					 TXRXCOUPLE_5G_ATTEN, 0xff);
++		}
++
++		tone_freq = 4000;
++
++		wlc_phy_tx_tone_nphy(pi, tone_freq, 181, 0, 0, false);
++
++		mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
++			    0x29b, (0x1 << 0), (NPHY_PAPD_COMP_ON) << 0);
++
++		mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
++			    0x2a4, (0x1 << 13), (1) << 13);
++
++		mod_phy_reg(pi, (off_core == PHY_CORE_0) ? 0x297 :
++			    0x29b, (0x1 << 0), (NPHY_PAPD_COMP_OFF) << 0);
++
++		mod_phy_reg(pi, (off_core == PHY_CORE_0) ? 0x2a3 :
++			    0x2a4, (0x1 << 13), (0) << 13);
++
++	} else {
++
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 12), 0, 0x3, 0);
++
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 1, 0, 0);
++
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 0), 0, 0x3, 0);
++
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 2), 1, 0x3, 0);
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 1), 1, 0x3, 0);
++
++		state->afectrl[core] = read_phy_reg(pi, (core == PHY_CORE_0) ?
++						    0xa6 : 0xa7);
++		state->afeoverride[core] =
++			read_phy_reg(pi, (core == PHY_CORE_0) ? 0x8f : 0xa5);
++
++		mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0xa6 : 0xa7),
++			    (0x1 << 0) | (0x1 << 1) | (0x1 << 2), 0);
++		mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0x8f :
++				 0xa5),
++			    (0x1 << 0) |
++			    (0x1 << 1) |
++			    (0x1 << 2), (0x1 << 0) | (0x1 << 1) | (0x1 << 2));
++
++		state->vga_master[core] =
++			READ_RADIO_REG2(pi, RADIO_2056, RX, core, VGA_MASTER);
++		WRITE_RADIO_REG2(pi, RADIO_2056, RX, core, VGA_MASTER, 0x2b);
++		if (CHSPEC_IS2G(pi->radio_chanspec)) {
++			state->fbmix[core] =
++				READ_RADIO_REG2(pi, RADIO_2056, RX, core,
++						TXFBMIX_G);
++			state->intpa_master[core] =
++				READ_RADIO_REG2(pi, RADIO_2056, TX, core,
++						INTPAG_MASTER);
++
++			WRITE_RADIO_REG2(pi, RADIO_2056, RX, core, TXFBMIX_G,
++					 0x03);
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++					 INTPAG_MASTER, 0x04);
++		} else {
++			state->fbmix[core] =
++				READ_RADIO_REG2(pi, RADIO_2056, RX, core,
++						TXFBMIX_A);
++			state->intpa_master[core] =
++				READ_RADIO_REG2(pi, RADIO_2056, TX, core,
++						INTPAA_MASTER);
++
++			WRITE_RADIO_REG2(pi, RADIO_2056, RX, core, TXFBMIX_A,
++					 0x03);
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++					 INTPAA_MASTER, 0x04);
++
++		}
++
++		tone_freq = 4000;
++
++		wlc_phy_tx_tone_nphy(pi, tone_freq, 181, 0, 0, false);
++
++		mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
++			    0x29b, (0x1 << 0), (1) << 0);
++
++		mod_phy_reg(pi, (off_core == PHY_CORE_0) ? 0x297 :
++			    0x29b, (0x1 << 0), (0) << 0);
++
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 0, 0x3, 0);
++	}
++}
++
++static void
++wlc_phy_papd_cal_cleanup_nphy(struct brcms_phy *pi,
++			      struct nphy_papd_restore_state *state)
++{
++	u8 core;
++
++	wlc_phy_stopplayback_nphy(pi);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++
++		for (core = 0; core < pi->pubpi.phy_corenum; core++) {
++
++			if (CHSPEC_IS2G(pi->radio_chanspec)) {
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TXRXCOUPLE_2G_PWRUP, 0);
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TXRXCOUPLE_2G_ATTEN,
++						 state->atten[core]);
++			} else {
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TXRXCOUPLE_5G_PWRUP, 0);
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TXRXCOUPLE_5G_ATTEN,
++						 state->atten[core]);
++			}
++		}
++
++		if ((pi->pubpi.radiorev == 4) || (pi->pubpi.radiorev == 6))
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 2),
++				1, 0x3, 0,
++				NPHY_REV7_RFCTRLOVERRIDE_ID0);
++		else
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 2),
++				0, 0x3, 1,
++				NPHY_REV7_RFCTRLOVERRIDE_ID0);
++
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1),
++						  0, 0x3, 1,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), 0, 0x3, 1,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID2);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), 0, 0x3, 1,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID2);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11), 1, 0x3, 1,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), 0, 0x3, 1,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11), 0, 0x3, 1,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 12), 0, 0x3, 1,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), 1, 0x3, 1,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), 0, 0x3, 1,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), 1, 0x3, 1,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID2);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 8), 0, 0x3, 1,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 9), 1, 0x3, 1,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 10), 0, 0x3, 1,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), 1, 0x3, 1,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 5), 0, 0x3, 1,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 4), 0, 0x3, 1,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++
++		for (core = 0; core < pi->pubpi.phy_corenum; core++) {
++
++			write_phy_reg(pi, (core == PHY_CORE_0) ?
++				      0xa6 : 0xa7, state->afectrl[core]);
++			write_phy_reg(pi, (core == PHY_CORE_0) ? 0x8f :
++				      0xa5, state->afeoverride[core]);
++		}
++
++		wlc_phy_ipa_set_bbmult_nphy(pi, (state->mm >> 8) & 0xff,
++					    (state->mm & 0xff));
++
++		if (NREV_IS(pi->pubpi.phy_rev, 7)
++		    || NREV_GE(pi->pubpi.phy_rev, 8))
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 7), 0, 0,
++				1,
++				NPHY_REV7_RFCTRLOVERRIDE_ID1);
++	} else {
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 12), 0, 0x3, 1);
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 13), 0, 0x3, 1);
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 0), 0, 0x3, 1);
++
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 2), 0, 0x3, 1);
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 1), 0, 0x3, 1);
++
++		for (core = 0; core < pi->pubpi.phy_corenum; core++) {
++
++			WRITE_RADIO_REG2(pi, RADIO_2056, RX, core, VGA_MASTER,
++					 state->vga_master[core]);
++			if (CHSPEC_IS2G(pi->radio_chanspec)) {
++				WRITE_RADIO_REG2(pi, RADIO_2056, RX, core,
++						 TXFBMIX_G, state->fbmix[core]);
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++						 INTPAG_MASTER,
++						 state->intpa_master[core]);
++			} else {
++				WRITE_RADIO_REG2(pi, RADIO_2056, RX, core,
++						 TXFBMIX_A, state->fbmix[core]);
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++						 INTPAA_MASTER,
++						 state->intpa_master[core]);
++			}
++
++			write_phy_reg(pi, (core == PHY_CORE_0) ?
++				      0xa6 : 0xa7, state->afectrl[core]);
++			write_phy_reg(pi, (core == PHY_CORE_0) ? 0x8f :
++				      0xa5, state->afeoverride[core]);
++		}
++
++		wlc_phy_ipa_set_bbmult_nphy(pi, (state->mm >> 8) & 0xff,
++					    (state->mm & 0xff));
++
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 0, 0x3, 1);
++	}
++}
++
++static void
++wlc_phy_a1_nphy(struct brcms_phy *pi, u8 core, u32 winsz, u32 start,
++		u32 end)
++{
++	u32 *buf, *src, *dst, sz;
++
++	sz = end - start + 1;
++
++	buf = kmalloc(2 * sizeof(u32) * NPHY_PAPD_EPS_TBL_SIZE, GFP_ATOMIC);
++	if (NULL == buf)
++		return;
++
++	src = buf;
++	dst = buf + NPHY_PAPD_EPS_TBL_SIZE;
++
++	wlc_phy_table_read_nphy(pi,
++				(core ==
++				 PHY_CORE_0 ? NPHY_TBL_ID_EPSILONTBL0 :
++				 NPHY_TBL_ID_EPSILONTBL1),
++				NPHY_PAPD_EPS_TBL_SIZE, 0, 32, src);
++
++	do {
++		u32 phy_a1, phy_a2;
++		s32 phy_a3, phy_a4, phy_a5, phy_a6, phy_a7;
++
++		phy_a1 = end - min(end, (winsz >> 1));
++		phy_a2 = min_t(u32, NPHY_PAPD_EPS_TBL_SIZE - 1,
++			       end + (winsz >> 1));
++		phy_a3 = phy_a2 - phy_a1 + 1;
++		phy_a6 = 0;
++		phy_a7 = 0;
++
++		do {
++			wlc_phy_papd_decode_epsilon(src[phy_a2], &phy_a4,
++						    &phy_a5);
++			phy_a6 += phy_a4;
++			phy_a7 += phy_a5;
++		} while (phy_a2-- != phy_a1);
++
++		phy_a6 /= phy_a3;
++		phy_a7 /= phy_a3;
++		dst[end] = ((u32) phy_a7 << 13) | ((u32) phy_a6 & 0x1fff);
++	} while (end-- != start);
++
++	wlc_phy_table_write_nphy(pi,
++				 (core ==
++				  PHY_CORE_0) ? NPHY_TBL_ID_EPSILONTBL0 :
++				 NPHY_TBL_ID_EPSILONTBL1, sz, start, 32, dst);
++
++	kfree(buf);
++}
++
++static void
++wlc_phy_a2_nphy(struct brcms_phy *pi, struct nphy_ipa_txcalgains *txgains,
++		enum phy_cal_mode cal_mode, u8 core)
++{
++	u16 phy_a1, phy_a2, phy_a3;
++	u16 phy_a4, phy_a5;
++	bool phy_a6;
++	u8 phy_a7, m[2];
++	u32 phy_a8 = 0;
++	struct nphy_txgains phy_a9;
++
++	if (NREV_LT(pi->pubpi.phy_rev, 3))
++		return;
++
++	phy_a7 = (core == PHY_CORE_0) ? 1 : 0;
++
++	phy_a6 = ((cal_mode == CAL_GCTRL)
++		  || (cal_mode == CAL_SOFT)) ? true : false;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++
++		phy_a9 = wlc_phy_get_tx_gain_nphy(pi);
++
++		if (CHSPEC_IS2G(pi->radio_chanspec))
++			phy_a5 = ((phy_a9.txlpf[core] << 15) |
++				  (phy_a9.txgm[core] << 12) |
++				  (phy_a9.pga[core] << 8) |
++				  (txgains->gains.pad[core] << 3) |
++				  (phy_a9.ipa[core]));
++		else
++			phy_a5 = ((phy_a9.txlpf[core] << 15) |
++				  (phy_a9.txgm[core] << 12) |
++				  (txgains->gains.pga[core] << 8) |
++				  (phy_a9.pad[core] << 3) | (phy_a9.ipa[core]));
++
++		wlc_phy_rfctrl_override_1tomany_nphy(
++			pi,
++			NPHY_REV7_RfctrlOverride_cmd_txgain,
++			phy_a5, (1 << core), 0);
++
++		if (CHSPEC_IS2G(pi->radio_chanspec)) {
++			if ((pi->pubpi.radiorev <= 4)
++			    || (pi->pubpi.radiorev == 6))
++				m[core] = (pi->bw == WL_CHANSPEC_BW_40) ?
++					  60 : 79;
++			else
++				m[core] = (pi->bw == WL_CHANSPEC_BW_40) ?
++					  45 : 64;
++		} else {
++			m[core] = (pi->bw == WL_CHANSPEC_BW_40) ? 75 : 107;
++		}
++
++		m[phy_a7] = 0;
++		wlc_phy_ipa_set_bbmult_nphy(pi, m[0], m[1]);
++
++		phy_a2 = 63;
++
++		if (CHSPEC_IS2G(pi->radio_chanspec)) {
++			if ((pi->pubpi.radiorev == 4)
++			    || (pi->pubpi.radiorev == 6)) {
++				phy_a1 = 30;
++				phy_a3 = 30;
++			} else {
++				phy_a1 = 25;
++				phy_a3 = 25;
++			}
++		} else {
++			if ((pi->pubpi.radiorev == 5)
++			    || (pi->pubpi.radiorev == 7)
++			    || (pi->pubpi.radiorev == 8)) {
++				phy_a1 = 25;
++				phy_a3 = 25;
++			} else {
++				phy_a1 = 35;
++				phy_a3 = 35;
++			}
++		}
++
++		if (cal_mode == CAL_GCTRL) {
++			if ((pi->pubpi.radiorev == 5)
++			    && (CHSPEC_IS2G(pi->radio_chanspec)))
++				phy_a1 = 55;
++			else if (((pi->pubpi.radiorev == 7) &&
++				  (CHSPEC_IS2G(pi->radio_chanspec))) ||
++				 ((pi->pubpi.radiorev == 8) &&
++				  (CHSPEC_IS2G(pi->radio_chanspec))))
++				phy_a1 = 60;
++			else
++				phy_a1 = 63;
++
++		} else if ((cal_mode != CAL_FULL) && (cal_mode != CAL_SOFT)) {
++
++			phy_a1 = 35;
++			phy_a3 = 35;
++		}
++
++		mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
++			    0x29b, (0x1 << 0), (1) << 0);
++
++		mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x297 :
++			    0x29b, (0x1 << 0), (0) << 0);
++
++		mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
++			    0x2a4, (0x1 << 13), (1) << 13);
++
++		mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x2a3 :
++			    0x2a4, (0x1 << 13), (0) << 13);
++
++		write_phy_reg(pi, 0x2a1, 0x80);
++		write_phy_reg(pi, 0x2a2, 0x100);
++
++		mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
++			    0x2a4, (0x7 << 4), (11) << 4);
++
++		mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
++			    0x2a4, (0x7 << 8), (11) << 8);
++
++		mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
++			    0x2a4, (0x7 << 0), (0x3) << 0);
++
++		write_phy_reg(pi, 0x2e5, 0x20);
++
++		mod_phy_reg(pi, 0x2a0, (0x3f << 0), (phy_a3) << 0);
++
++		mod_phy_reg(pi, 0x29f, (0x3f << 0), (phy_a1) << 0);
++
++		mod_phy_reg(pi, 0x29f, (0x3f << 8), (phy_a2) << 8);
++
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3),
++						  1, ((core == 0) ? 1 : 2), 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3),
++						  0, ((core == 0) ? 2 : 1), 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
++
++		write_phy_reg(pi, 0x2be, 1);
++		SPINWAIT(read_phy_reg(pi, 0x2be), 10 * 1000 * 1000);
++
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3),
++						  0, 0x3, 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
++
++		wlc_phy_table_write_nphy(pi,
++					 (core ==
++					  PHY_CORE_0) ? NPHY_TBL_ID_EPSILONTBL0
++					 : NPHY_TBL_ID_EPSILONTBL1, 1, phy_a3,
++					 32, &phy_a8);
++
++		if (cal_mode != CAL_GCTRL) {
++			if (CHSPEC_IS5G(pi->radio_chanspec))
++				wlc_phy_a1_nphy(pi, core, 5, 0, 35);
++		}
++
++		wlc_phy_rfctrl_override_1tomany_nphy(
++			pi,
++			NPHY_REV7_RfctrlOverride_cmd_txgain,
++			phy_a5, (1 << core), 1);
++
++	} else {
++
++		if (txgains) {
++			if (txgains->useindex) {
++				phy_a4 = 15 - ((txgains->index) >> 3);
++				if (CHSPEC_IS2G(pi->radio_chanspec)) {
++					if (NREV_GE(pi->pubpi.phy_rev, 6))
++						phy_a5 = 0x00f7 | (phy_a4 << 8);
++
++					else
++					if (NREV_IS(pi->pubpi.phy_rev, 5))
++						phy_a5 = 0x10f7 | (phy_a4 << 8);
++					else
++						phy_a5 = 0x50f7 | (phy_a4 << 8);
++				} else {
++					phy_a5 = 0x70f7 | (phy_a4 << 8);
++				}
++				wlc_phy_rfctrl_override_nphy(pi,
++							     (0x1 << 13),
++							     phy_a5,
++							     (1 << core), 0);
++			} else {
++				wlc_phy_rfctrl_override_nphy(pi,
++							     (0x1 << 13),
++							     0x5bf7,
++							     (1 << core), 0);
++			}
++		}
++
++		if (CHSPEC_IS2G(pi->radio_chanspec))
++			m[core] = (pi->bw == WL_CHANSPEC_BW_40) ? 45 : 64;
++		else
++			m[core] = (pi->bw == WL_CHANSPEC_BW_40) ? 75 : 107;
++
++		m[phy_a7] = 0;
++		wlc_phy_ipa_set_bbmult_nphy(pi, m[0], m[1]);
++
++		phy_a2 = 63;
++
++		if (cal_mode == CAL_FULL) {
++			phy_a1 = 25;
++			phy_a3 = 25;
++		} else if (cal_mode == CAL_SOFT) {
++			phy_a1 = 25;
++			phy_a3 = 25;
++		} else if (cal_mode == CAL_GCTRL) {
++			phy_a1 = 63;
++			phy_a3 = 25;
++		} else {
++
++			phy_a1 = 25;
++			phy_a3 = 25;
++		}
++
++		mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
++			    0x29b, (0x1 << 0), (1) << 0);
++
++		mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x297 :
++			    0x29b, (0x1 << 0), (0) << 0);
++
++		if (NREV_GE(pi->pubpi.phy_rev, 6)) {
++			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
++				    0x2a4, (0x1 << 13), (1) << 13);
++
++			mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x2a3 :
++				    0x2a4, (0x1 << 13), (0) << 13);
++
++			write_phy_reg(pi, 0x2a1, 0x20);
++			write_phy_reg(pi, 0x2a2, 0x60);
++
++			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
++				    0x2a4, (0xf << 4), (9) << 4);
++
++			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
++				    0x2a4, (0xf << 8), (9) << 8);
++
++			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
++				    0x2a4, (0xf << 0), (0x2) << 0);
++
++			write_phy_reg(pi, 0x2e5, 0x20);
++		} else {
++			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
++				    0x2a4, (0x1 << 11), (1) << 11);
++
++			mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x2a3 :
++				    0x2a4, (0x1 << 11), (0) << 11);
++
++			write_phy_reg(pi, 0x2a1, 0x80);
++			write_phy_reg(pi, 0x2a2, 0x600);
++
++			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
++				    0x2a4, (0x7 << 4), (0) << 4);
++
++			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
++				    0x2a4, (0x7 << 8), (0) << 8);
++
++			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
++				    0x2a4, (0x7 << 0), (0x3) << 0);
++
++			mod_phy_reg(pi, 0x2a0, (0x3f << 8), (0x20) << 8);
++
++		}
++
++		mod_phy_reg(pi, 0x2a0, (0x3f << 0), (phy_a3) << 0);
++
++		mod_phy_reg(pi, 0x29f, (0x3f << 0), (phy_a1) << 0);
++
++		mod_phy_reg(pi, 0x29f, (0x3f << 8), (phy_a2) << 8);
++
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 1, 0x3, 0);
++
++		write_phy_reg(pi, 0x2be, 1);
++		SPINWAIT(read_phy_reg(pi, 0x2be), 10 * 1000 * 1000);
++
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 0, 0x3, 0);
++
++		wlc_phy_table_write_nphy(pi,
++					 (core ==
++					  PHY_CORE_0) ? NPHY_TBL_ID_EPSILONTBL0
++					 : NPHY_TBL_ID_EPSILONTBL1, 1, phy_a3,
++					 32, &phy_a8);
++
++		if (cal_mode != CAL_GCTRL)
++			wlc_phy_a1_nphy(pi, core, 5, 0, 40);
++	}
++}
++
++static u8 wlc_phy_a3_nphy(struct brcms_phy *pi, u8 start_gain, u8 core)
++{
++	int phy_a1;
++	int phy_a2;
++	bool phy_a3;
++	struct nphy_ipa_txcalgains phy_a4;
++	bool phy_a5 = false;
++	bool phy_a6 = true;
++	s32 phy_a7, phy_a8;
++	u32 phy_a9;
++	int phy_a10;
++	bool phy_a11 = false;
++	int phy_a12;
++	u8 phy_a13 = 0;
++	u8 phy_a14;
++	u8 *phy_a15 = NULL;
++
++	phy_a4.useindex = true;
++	phy_a12 = start_gain;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++
++		phy_a2 = 20;
++		phy_a1 = 1;
++
++		if (CHSPEC_IS2G(pi->radio_chanspec)) {
++			if (pi->pubpi.radiorev == 5) {
++
++				phy_a15 = pad_gain_codes_used_2057rev5;
++				phy_a13 =
++					ARRAY_SIZE(pad_gain_codes_used_2057rev5) - 1;
++
++			} else if ((pi->pubpi.radiorev == 7)
++				   || (pi->pubpi.radiorev == 8)) {
++
++				phy_a15 = pad_gain_codes_used_2057rev7;
++				phy_a13 =
++					ARRAY_SIZE(pad_gain_codes_used_2057rev7) - 1;
++
++			} else {
++
++				phy_a15 = pad_all_gain_codes_2057;
++				phy_a13 = ARRAY_SIZE(pad_all_gain_codes_2057) -
++					  1;
++			}
++
++		} else {
++
++			phy_a15 = pga_all_gain_codes_2057;
++			phy_a13 = ARRAY_SIZE(pga_all_gain_codes_2057) - 1;
++		}
++
++		phy_a14 = 0;
++
++		for (phy_a10 = 0; phy_a10 < phy_a2; phy_a10++) {
++			if (CHSPEC_IS2G(pi->radio_chanspec))
++				phy_a4.gains.pad[core] =
++					(u16) phy_a15[phy_a12];
++			else
++				phy_a4.gains.pga[core] =
++					(u16) phy_a15[phy_a12];
++
++			wlc_phy_a2_nphy(pi, &phy_a4, CAL_GCTRL, core);
++
++			wlc_phy_table_read_nphy(pi,
++						(core ==
++						 PHY_CORE_0 ?
++						 NPHY_TBL_ID_EPSILONTBL0 :
++						 NPHY_TBL_ID_EPSILONTBL1), 1,
++						63, 32, &phy_a9);
++
++			wlc_phy_papd_decode_epsilon(phy_a9, &phy_a7, &phy_a8);
++
++			phy_a3 = ((phy_a7 == 4095) || (phy_a7 == -4096) ||
++				  (phy_a8 == 4095) || (phy_a8 == -4096));
++
++			if (!phy_a6 && (phy_a3 != phy_a5)) {
++				if (!phy_a3)
++					phy_a12 -= (u8) phy_a1;
++
++				phy_a11 = true;
++				break;
++			}
++
++			if (phy_a3)
++				phy_a12 += (u8) phy_a1;
++			else
++				phy_a12 -= (u8) phy_a1;
++
++			if ((phy_a12 < phy_a14) || (phy_a12 > phy_a13)) {
++				if (phy_a12 < phy_a14)
++					phy_a12 = phy_a14;
++				else
++					phy_a12 = phy_a13;
++
++				phy_a11 = true;
++				break;
++			}
++
++			phy_a6 = false;
++			phy_a5 = phy_a3;
++		}
++
++	} else {
++		phy_a2 = 10;
++		phy_a1 = 8;
++		for (phy_a10 = 0; phy_a10 < phy_a2; phy_a10++) {
++			phy_a4.index = (u8) phy_a12;
++			wlc_phy_a2_nphy(pi, &phy_a4, CAL_GCTRL, core);
++
++			wlc_phy_table_read_nphy(pi,
++						(core ==
++						 PHY_CORE_0 ?
++						 NPHY_TBL_ID_EPSILONTBL0 :
++						 NPHY_TBL_ID_EPSILONTBL1), 1,
++						63, 32, &phy_a9);
++
++			wlc_phy_papd_decode_epsilon(phy_a9, &phy_a7, &phy_a8);
++
++			phy_a3 = ((phy_a7 == 4095) || (phy_a7 == -4096) ||
++				  (phy_a8 == 4095) || (phy_a8 == -4096));
++
++			if (!phy_a6 && (phy_a3 != phy_a5)) {
++				if (!phy_a3)
++					phy_a12 -= (u8) phy_a1;
++
++				phy_a11 = true;
++				break;
++			}
++
++			if (phy_a3)
++				phy_a12 += (u8) phy_a1;
++			else
++				phy_a12 -= (u8) phy_a1;
++
++			if ((phy_a12 < 0) || (phy_a12 > 127)) {
++				if (phy_a12 < 0)
++					phy_a12 = 0;
++				else
++					phy_a12 = 127;
++
++				phy_a11 = true;
++				break;
++			}
++
++			phy_a6 = false;
++			phy_a5 = phy_a3;
++		}
++
++	}
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7))
++		return (u8) phy_a15[phy_a12];
++	else
++		return (u8) phy_a12;
++
++}
++
++static void wlc_phy_a4(struct brcms_phy *pi, bool full_cal)
++{
++	struct nphy_ipa_txcalgains phy_b1[2];
++	struct nphy_papd_restore_state phy_b2;
++	bool phy_b3;
++	u8 phy_b4;
++	u8 phy_b5;
++	s16 phy_b6, phy_b7, phy_b8;
++	u16 phy_b9;
++	s16 phy_b10, phy_b11, phy_b12;
++
++	phy_b11 = 0;
++	phy_b12 = 0;
++	phy_b7 = 0;
++	phy_b8 = 0;
++	phy_b6 = 0;
++
++	if (pi->nphy_papd_skip == 1)
++		return;
++
++	phy_b3 = (0 == (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) &
++			MCTL_EN_MAC));
++	if (!phy_b3)
++		wlapi_suspend_mac_and_wait(pi->sh->physhim);
++
++	wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++	pi->nphy_force_papd_cal = false;
++
++	for (phy_b5 = 0; phy_b5 < pi->pubpi.phy_corenum; phy_b5++)
++		pi->nphy_papd_tx_gain_at_last_cal[phy_b5] =
++			wlc_phy_txpwr_idx_cur_get_nphy(pi, phy_b5);
++
++	pi->nphy_papd_last_cal = pi->sh->now;
++	pi->nphy_papd_recal_counter++;
++
++	phy_b4 = pi->nphy_txpwrctrl;
++	wlc_phy_txpwrctrl_enable_nphy(pi, PHY_TPC_HW_OFF);
++
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_SCALARTBL0, 64, 0, 32,
++				 nphy_papd_scaltbl);
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_SCALARTBL1, 64, 0, 32,
++				 nphy_papd_scaltbl);
++
++	phy_b9 = read_phy_reg(pi, 0x01);
++	mod_phy_reg(pi, 0x01, (0x1 << 15), 0);
++
++	for (phy_b5 = 0; phy_b5 < pi->pubpi.phy_corenum; phy_b5++) {
++		s32 i, val = 0;
++		for (i = 0; i < 64; i++)
++			wlc_phy_table_write_nphy(pi,
++						 ((phy_b5 ==
++						   PHY_CORE_0) ?
++						  NPHY_TBL_ID_EPSILONTBL0 :
++						  NPHY_TBL_ID_EPSILONTBL1), 1,
++						 i, 32, &val);
++	}
++
++	wlc_phy_ipa_restore_tx_digi_filts_nphy(pi);
++
++	phy_b2.mm = wlc_phy_ipa_get_bbmult_nphy(pi);
++	for (phy_b5 = 0; phy_b5 < pi->pubpi.phy_corenum; phy_b5++) {
++		wlc_phy_papd_cal_setup_nphy(pi, &phy_b2, phy_b5);
++
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			if (CHSPEC_IS2G(pi->radio_chanspec)) {
++				if ((pi->pubpi.radiorev == 3)
++				    || (pi->pubpi.radiorev == 4)
++				    || (pi->pubpi.radiorev == 6)) {
++					pi->nphy_papd_cal_gain_index[phy_b5] =
++						23;
++				} else if (pi->pubpi.radiorev == 5) {
++					pi->nphy_papd_cal_gain_index[phy_b5] =
++						0;
++					pi->nphy_papd_cal_gain_index[phy_b5] =
++						wlc_phy_a3_nphy(
++							pi,
++							pi->
++							nphy_papd_cal_gain_index
++							[phy_b5],
++							phy_b5);
++
++				} else if ((pi->pubpi.radiorev == 7)
++					   || (pi->pubpi.radiorev == 8)) {
++
++					pi->nphy_papd_cal_gain_index[phy_b5] =
++						0;
++					pi->nphy_papd_cal_gain_index[phy_b5] =
++						wlc_phy_a3_nphy(
++							pi,
++							pi->
++							nphy_papd_cal_gain_index
++							[phy_b5],
++							phy_b5);
++
++				}
++
++				phy_b1[phy_b5].gains.pad[phy_b5] =
++					pi->nphy_papd_cal_gain_index[phy_b5];
++
++			} else {
++				pi->nphy_papd_cal_gain_index[phy_b5] = 0;
++				pi->nphy_papd_cal_gain_index[phy_b5] =
++					wlc_phy_a3_nphy(
++						pi,
++						pi->
++						nphy_papd_cal_gain_index
++						[phy_b5], phy_b5);
++				phy_b1[phy_b5].gains.pga[phy_b5] =
++					pi->nphy_papd_cal_gain_index[phy_b5];
++			}
++		} else {
++			phy_b1[phy_b5].useindex = true;
++			phy_b1[phy_b5].index = 16;
++			phy_b1[phy_b5].index =
++				wlc_phy_a3_nphy(pi, phy_b1[phy_b5].index,
++						phy_b5);
++
++			pi->nphy_papd_cal_gain_index[phy_b5] =
++				15 - ((phy_b1[phy_b5].index) >> 3);
++		}
++
++		switch (pi->nphy_papd_cal_type) {
++		case 0:
++			wlc_phy_a2_nphy(pi, &phy_b1[phy_b5], CAL_FULL, phy_b5);
++			break;
++		case 1:
++			wlc_phy_a2_nphy(pi, &phy_b1[phy_b5], CAL_SOFT, phy_b5);
++			break;
++		}
++
++		if (NREV_GE(pi->pubpi.phy_rev, 7))
++			wlc_phy_papd_cal_cleanup_nphy(pi, &phy_b2);
++	}
++
++	if (NREV_LT(pi->pubpi.phy_rev, 7))
++		wlc_phy_papd_cal_cleanup_nphy(pi, &phy_b2);
++
++	for (phy_b5 = 0; phy_b5 < pi->pubpi.phy_corenum; phy_b5++) {
++		int eps_offset = 0;
++
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			if (CHSPEC_IS2G(pi->radio_chanspec)) {
++				if (pi->pubpi.radiorev == 3)
++					eps_offset = -2;
++				else if (pi->pubpi.radiorev == 5)
++					eps_offset = 3;
++				else
++					eps_offset = -1;
++			} else {
++				eps_offset = 2;
++			}
++
++			if (CHSPEC_IS2G(pi->radio_chanspec)) {
++				phy_b8 = phy_b1[phy_b5].gains.pad[phy_b5];
++				phy_b10 = 0;
++				if ((pi->pubpi.radiorev == 3) ||
++				    (pi->pubpi.radiorev == 4) ||
++				    (pi->pubpi.radiorev == 6)) {
++					phy_b12 = -(
++					    nphy_papd_padgain_dlt_2g_2057rev3n4
++							     [phy_b8] + 1) / 2;
++					phy_b10 = -1;
++				} else if (pi->pubpi.radiorev == 5) {
++					phy_b12 = -(
++					    nphy_papd_padgain_dlt_2g_2057rev5
++							     [phy_b8] + 1) / 2;
++				} else if ((pi->pubpi.radiorev == 7) ||
++					   (pi->pubpi.radiorev == 8)) {
++					phy_b12 = -(
++					    nphy_papd_padgain_dlt_2g_2057rev7
++							     [phy_b8] + 1) / 2;
++				}
++			} else {
++				phy_b7 = phy_b1[phy_b5].gains.pga[phy_b5];
++				if ((pi->pubpi.radiorev == 3) ||
++				    (pi->pubpi.radiorev == 4) ||
++				    (pi->pubpi.radiorev == 6))
++					phy_b11 =
++						-(nphy_papd_pgagain_dlt_5g_2057
++						  [phy_b7]
++						  + 1) / 2;
++				else if ((pi->pubpi.radiorev == 7)
++					 || (pi->pubpi.radiorev == 8))
++					phy_b11 = -(
++					      nphy_papd_pgagain_dlt_5g_2057rev7
++							     [phy_b7] + 1) / 2;
++
++				phy_b10 = -9;
++			}
++
++			if (CHSPEC_IS2G(pi->radio_chanspec))
++				phy_b6 =
++					-60 + 27 + eps_offset + phy_b12 +
++					phy_b10;
++			else
++				phy_b6 =
++					-60 + 27 + eps_offset + phy_b11 +
++					phy_b10;
++
++			mod_phy_reg(pi, (phy_b5 == PHY_CORE_0) ? 0x298 :
++				    0x29c, (0x1ff << 7), (phy_b6) << 7);
++
++			pi->nphy_papd_epsilon_offset[phy_b5] = phy_b6;
++		} else {
++			if (NREV_LT(pi->pubpi.phy_rev, 5))
++				eps_offset = 4;
++			else
++				eps_offset = 2;
++
++			phy_b7 = 15 - ((phy_b1[phy_b5].index) >> 3);
++
++			if (CHSPEC_IS2G(pi->radio_chanspec)) {
++				phy_b11 =
++					-(nphy_papd_pga_gain_delta_ipa_2g[
++						  phy_b7] +
++					  1) / 2;
++				phy_b10 = 0;
++			} else {
++				phy_b11 =
++					-(nphy_papd_pga_gain_delta_ipa_5g[
++						  phy_b7] +
++					  1) / 2;
++				phy_b10 = -9;
++			}
++
++			phy_b6 = -60 + 27 + eps_offset + phy_b11 + phy_b10;
++
++			mod_phy_reg(pi, (phy_b5 == PHY_CORE_0) ? 0x298 :
++				    0x29c, (0x1ff << 7), (phy_b6) << 7);
++
++			pi->nphy_papd_epsilon_offset[phy_b5] = phy_b6;
++		}
++	}
++
++	mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x297 :
++		    0x29b, (0x1 << 0), (NPHY_PAPD_COMP_ON) << 0);
++
++	mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x297 :
++		    0x29b, (0x1 << 0), (NPHY_PAPD_COMP_ON) << 0);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 6)) {
++		mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x2a3 :
++			    0x2a4, (0x1 << 13), (0) << 13);
++
++		mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x2a3 :
++			    0x2a4, (0x1 << 13), (0) << 13);
++
++	} else {
++		mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x2a3 :
++			    0x2a4, (0x1 << 11), (0) << 11);
++
++		mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x2a3 :
++			    0x2a4, (0x1 << 11), (0) << 11);
++
++	}
++	pi->nphy_papdcomp = NPHY_PAPD_COMP_ON;
++
++	write_phy_reg(pi, 0x01, phy_b9);
++
++	wlc_phy_ipa_set_tx_digi_filts_nphy(pi);
++
++	wlc_phy_txpwrctrl_enable_nphy(pi, phy_b4);
++	if (phy_b4 == PHY_TPC_HW_OFF) {
++		wlc_phy_txpwr_index_nphy(pi, (1 << 0),
++					 (s8) (pi->nphy_txpwrindex[0].
++					       index_internal), false);
++		wlc_phy_txpwr_index_nphy(pi, (1 << 1),
++					 (s8) (pi->nphy_txpwrindex[1].
++					       index_internal), false);
++	}
++
++	wlc_phy_stay_in_carriersearch_nphy(pi, false);
++
++	if (!phy_b3)
++		wlapi_enable_mac(pi->sh->physhim);
++}
++
++void wlc_phy_cal_perical_nphy_run(struct brcms_phy *pi, u8 caltype)
++{
++	struct nphy_txgains target_gain;
++	u8 tx_pwr_ctrl_state;
++	bool fullcal = true;
++	bool restore_tx_gain = false;
++	bool mphase;
++
++	if (PHY_MUTED(pi))
++		return;
++
++	if (caltype == PHY_PERICAL_AUTO)
++		fullcal = (pi->radio_chanspec != pi->nphy_txiqlocal_chanspec);
++	else if (caltype == PHY_PERICAL_PARTIAL)
++		fullcal = false;
++
++	if (pi->cal_type_override != PHY_PERICAL_AUTO)
++		fullcal =
++			(pi->cal_type_override ==
++			 PHY_PERICAL_FULL) ? true : false;
++
++	if ((pi->mphase_cal_phase_id > MPHASE_CAL_STATE_INIT)) {
++		if (pi->nphy_txiqlocal_chanspec != pi->radio_chanspec)
++			wlc_phy_cal_perical_mphase_restart(pi);
++	}
++
++	if ((pi->mphase_cal_phase_id == MPHASE_CAL_STATE_RXCAL))
++		wlapi_bmac_write_shm(pi->sh->physhim, M_CTS_DURATION, 10000);
++
++	wlapi_suspend_mac_and_wait(pi->sh->physhim);
++
++	wlc_phyreg_enter((struct brcms_phy_pub *) pi);
++
++	if ((pi->mphase_cal_phase_id == MPHASE_CAL_STATE_IDLE) ||
++	    (pi->mphase_cal_phase_id == MPHASE_CAL_STATE_INIT)) {
++		pi->nphy_cal_orig_pwr_idx[0] =
++			(u8) ((read_phy_reg(pi, 0x1ed) >> 8) & 0x7f);
++		pi->nphy_cal_orig_pwr_idx[1] =
++			(u8) ((read_phy_reg(pi, 0x1ee) >> 8) & 0x7f);
++
++		if (pi->nphy_txpwrctrl != PHY_TPC_HW_OFF) {
++			wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2,
++						0x110, 16,
++						pi->nphy_cal_orig_tx_gain);
++		} else {
++			pi->nphy_cal_orig_tx_gain[0] = 0;
++			pi->nphy_cal_orig_tx_gain[1] = 0;
++		}
++	}
++	target_gain = wlc_phy_get_tx_gain_nphy(pi);
++	tx_pwr_ctrl_state = pi->nphy_txpwrctrl;
++	wlc_phy_txpwrctrl_enable_nphy(pi, PHY_TPC_HW_OFF);
++
++	if (pi->antsel_type == ANTSEL_2x3)
++		wlc_phy_antsel_init((struct brcms_phy_pub *) pi, true);
++
++	mphase = (pi->mphase_cal_phase_id != MPHASE_CAL_STATE_IDLE);
++	if (!mphase) {
++
++		if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++			wlc_phy_precal_txgain_nphy(pi);
++			pi->nphy_cal_target_gain = wlc_phy_get_tx_gain_nphy(pi);
++			restore_tx_gain = true;
++
++			target_gain = pi->nphy_cal_target_gain;
++		}
++		if (0 ==
++		    wlc_phy_cal_txiqlo_nphy(pi, target_gain, fullcal,
++					    mphase)) {
++			if (PHY_IPA(pi))
++				wlc_phy_a4(pi, true);
++
++			wlc_phyreg_exit((struct brcms_phy_pub *) pi);
++			wlapi_enable_mac(pi->sh->physhim);
++			wlapi_bmac_write_shm(pi->sh->physhim, M_CTS_DURATION,
++					     10000);
++			wlapi_suspend_mac_and_wait(pi->sh->physhim);
++			wlc_phyreg_enter((struct brcms_phy_pub *) pi);
++
++			if (0 == wlc_phy_cal_rxiq_nphy(pi, target_gain,
++					(pi->first_cal_after_assoc ||
++					(pi->cal_type_override ==
++					 PHY_PERICAL_FULL)) ? 2 : 0, false)) {
++				wlc_phy_savecal_nphy(pi);
++
++				wlc_phy_txpwrctrl_coeff_setup_nphy(pi);
++
++				pi->nphy_perical_last = pi->sh->now;
++			}
++		}
++		if (caltype != PHY_PERICAL_AUTO)
++			wlc_phy_rssi_cal_nphy(pi);
++
++		if (pi->first_cal_after_assoc
++		    || (pi->cal_type_override == PHY_PERICAL_FULL)) {
++			pi->first_cal_after_assoc = false;
++			wlc_phy_txpwrctrl_idle_tssi_nphy(pi);
++			wlc_phy_txpwrctrl_pwr_setup_nphy(pi);
++		}
++
++		if (NREV_GE(pi->pubpi.phy_rev, 3))
++			wlc_phy_radio205x_vcocal_nphy(pi);
++	} else {
++		switch (pi->mphase_cal_phase_id) {
++		case MPHASE_CAL_STATE_INIT:
++			pi->nphy_perical_last = pi->sh->now;
++			pi->nphy_txiqlocal_chanspec = pi->radio_chanspec;
++
++			if (NREV_GE(pi->pubpi.phy_rev, 3))
++				wlc_phy_precal_txgain_nphy(pi);
++
++			pi->nphy_cal_target_gain = wlc_phy_get_tx_gain_nphy(pi);
++			pi->mphase_cal_phase_id++;
++			break;
++
++		case MPHASE_CAL_STATE_TXPHASE0:
++		case MPHASE_CAL_STATE_TXPHASE1:
++		case MPHASE_CAL_STATE_TXPHASE2:
++		case MPHASE_CAL_STATE_TXPHASE3:
++		case MPHASE_CAL_STATE_TXPHASE4:
++		case MPHASE_CAL_STATE_TXPHASE5:
++			if ((pi->radar_percal_mask & 0x10) != 0)
++				pi->nphy_rxcal_active = true;
++
++			if (wlc_phy_cal_txiqlo_nphy
++				    (pi, pi->nphy_cal_target_gain, fullcal,
++				    true) != 0) {
++
++				wlc_phy_cal_perical_mphase_reset(pi);
++				break;
++			}
++
++			if (NREV_LE(pi->pubpi.phy_rev, 2) &&
++			    (pi->mphase_cal_phase_id ==
++			     MPHASE_CAL_STATE_TXPHASE4))
++				pi->mphase_cal_phase_id += 2;
++			else
++				pi->mphase_cal_phase_id++;
++			break;
++
++		case MPHASE_CAL_STATE_PAPDCAL:
++			if ((pi->radar_percal_mask & 0x2) != 0)
++				pi->nphy_rxcal_active = true;
++
++			if (PHY_IPA(pi))
++				wlc_phy_a4(pi, true);
++
++			pi->mphase_cal_phase_id++;
++			break;
++
++		case MPHASE_CAL_STATE_RXCAL:
++			if ((pi->radar_percal_mask & 0x1) != 0)
++				pi->nphy_rxcal_active = true;
++			if (wlc_phy_cal_rxiq_nphy(pi, target_gain,
++						  (pi->first_cal_after_assoc ||
++						   (pi->cal_type_override ==
++						    PHY_PERICAL_FULL)) ? 2 : 0,
++						  false) == 0)
++				wlc_phy_savecal_nphy(pi);
++
++			pi->mphase_cal_phase_id++;
++			break;
++
++		case MPHASE_CAL_STATE_RSSICAL:
++			if ((pi->radar_percal_mask & 0x4) != 0)
++				pi->nphy_rxcal_active = true;
++			wlc_phy_txpwrctrl_coeff_setup_nphy(pi);
++			wlc_phy_rssi_cal_nphy(pi);
++
++			if (NREV_GE(pi->pubpi.phy_rev, 3))
++				wlc_phy_radio205x_vcocal_nphy(pi);
++
++			restore_tx_gain = true;
++
++			if (pi->first_cal_after_assoc)
++				pi->mphase_cal_phase_id++;
++			else
++				wlc_phy_cal_perical_mphase_reset(pi);
++
++			break;
++
++		case MPHASE_CAL_STATE_IDLETSSI:
++			if ((pi->radar_percal_mask & 0x8) != 0)
++				pi->nphy_rxcal_active = true;
++
++			if (pi->first_cal_after_assoc) {
++				pi->first_cal_after_assoc = false;
++				wlc_phy_txpwrctrl_idle_tssi_nphy(pi);
++				wlc_phy_txpwrctrl_pwr_setup_nphy(pi);
++			}
++
++			wlc_phy_cal_perical_mphase_reset(pi);
++			break;
++
++		default:
++			wlc_phy_cal_perical_mphase_reset(pi);
++			break;
++		}
++	}
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		if (restore_tx_gain) {
++			if (tx_pwr_ctrl_state != PHY_TPC_HW_OFF) {
++
++				wlc_phy_txpwr_index_nphy(pi, 1,
++							 pi->
++							 nphy_cal_orig_pwr_idx
++							 [0], false);
++				wlc_phy_txpwr_index_nphy(pi, 2,
++							 pi->
++							 nphy_cal_orig_pwr_idx
++							 [1], false);
++
++				pi->nphy_txpwrindex[0].index = -1;
++				pi->nphy_txpwrindex[1].index = -1;
++			} else {
++				wlc_phy_txpwr_index_nphy(pi, (1 << 0),
++							 (s8) (pi->
++							       nphy_txpwrindex
++							       [0].
++							       index_internal),
++							 false);
++				wlc_phy_txpwr_index_nphy(pi, (1 << 1),
++							 (s8) (pi->
++							       nphy_txpwrindex
++							       [1].
++							       index_internal),
++							 false);
++			}
++		}
++	}
++
++	wlc_phy_txpwrctrl_enable_nphy(pi, tx_pwr_ctrl_state);
++	wlc_phyreg_exit((struct brcms_phy_pub *) pi);
++	wlapi_enable_mac(pi->sh->physhim);
++}
++
++int
++wlc_phy_cal_txiqlo_nphy(struct brcms_phy *pi, struct nphy_txgains target_gain,
++			bool fullcal, bool mphase)
++{
++	u16 val;
++	u16 tbl_buf[11];
++	u8 cal_cnt;
++	u16 cal_cmd;
++	u8 num_cals, max_cal_cmds;
++	u16 core_no, cal_type;
++	u16 diq_start = 0;
++	u8 phy_bw;
++	u16 max_val;
++	u16 tone_freq;
++	u16 gain_save[2];
++	u16 cal_gain[2];
++	struct nphy_iqcal_params cal_params[2];
++	u32 tbl_len;
++	void *tbl_ptr;
++	bool ladder_updated[2];
++	u8 mphase_cal_lastphase = 0;
++	int bcmerror = 0;
++	bool phyhang_avoid_state = false;
++
++	u16 tbl_tx_iqlo_cal_loft_ladder_20[] = {
++		0x0300, 0x0500, 0x0700, 0x0900, 0x0d00, 0x1100, 0x1900, 0x1901,
++		0x1902,
++		0x1903, 0x1904, 0x1905, 0x1906, 0x1907, 0x2407, 0x3207, 0x4607,
++		0x6407
++	};
++
++	u16 tbl_tx_iqlo_cal_iqimb_ladder_20[] = {
++		0x0200, 0x0300, 0x0600, 0x0900, 0x0d00, 0x1100, 0x1900, 0x2400,
++		0x3200,
++		0x4600, 0x6400, 0x6401, 0x6402, 0x6403, 0x6404, 0x6405, 0x6406,
++		0x6407
++	};
++
++	u16 tbl_tx_iqlo_cal_loft_ladder_40[] = {
++		0x0200, 0x0300, 0x0400, 0x0700, 0x0900, 0x0c00, 0x1200, 0x1201,
++		0x1202,
++		0x1203, 0x1204, 0x1205, 0x1206, 0x1207, 0x1907, 0x2307, 0x3207,
++		0x4707
++	};
++
++	u16 tbl_tx_iqlo_cal_iqimb_ladder_40[] = {
++		0x0100, 0x0200, 0x0400, 0x0700, 0x0900, 0x0c00, 0x1200, 0x1900,
++		0x2300,
++		0x3200, 0x4700, 0x4701, 0x4702, 0x4703, 0x4704, 0x4705, 0x4706,
++		0x4707
++	};
++
++	u16 tbl_tx_iqlo_cal_startcoefs[] = {
++		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
++		0x0000
++	};
++
++	u16 tbl_tx_iqlo_cal_cmds_fullcal[] = {
++		0x8123, 0x8264, 0x8086, 0x8245, 0x8056,
++		0x9123, 0x9264, 0x9086, 0x9245, 0x9056
++	};
++
++	u16 tbl_tx_iqlo_cal_cmds_recal[] = {
++		0x8101, 0x8253, 0x8053, 0x8234, 0x8034,
++		0x9101, 0x9253, 0x9053, 0x9234, 0x9034
++	};
++
++	u16 tbl_tx_iqlo_cal_startcoefs_nphyrev3[] = {
++		0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
++		0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
++		0x0000
++	};
++
++	u16 tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3[] = {
++		0x8434, 0x8334, 0x8084, 0x8267, 0x8056, 0x8234,
++		0x9434, 0x9334, 0x9084, 0x9267, 0x9056, 0x9234
++	};
++
++	u16 tbl_tx_iqlo_cal_cmds_recal_nphyrev3[] = {
++		0x8423, 0x8323, 0x8073, 0x8256, 0x8045, 0x8223,
++		0x9423, 0x9323, 0x9073, 0x9256, 0x9045, 0x9223
++	};
++
++	wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 4)) {
++		phyhang_avoid_state = pi->phyhang_avoid;
++		pi->phyhang_avoid = false;
++	}
++
++	if (CHSPEC_IS40(pi->radio_chanspec))
++		phy_bw = 40;
++	else
++		phy_bw = 20;
++
++	wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, gain_save);
++
++	for (core_no = 0; core_no <= 1; core_no++) {
++		wlc_phy_iqcal_gainparams_nphy(pi, core_no, target_gain,
++					      &cal_params[core_no]);
++		cal_gain[core_no] = cal_params[core_no].cal_gain;
++	}
++
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, cal_gain);
++
++	wlc_phy_txcal_radio_setup_nphy(pi);
++
++	wlc_phy_txcal_physetup_nphy(pi);
++
++	ladder_updated[0] = ladder_updated[1] = false;
++	if (!(NREV_GE(pi->pubpi.phy_rev, 6) ||
++	      (NREV_IS(pi->pubpi.phy_rev, 5) && PHY_IPA(pi)
++	       && (CHSPEC_IS2G(pi->radio_chanspec))))) {
++
++		if (phy_bw == 40) {
++			tbl_ptr = tbl_tx_iqlo_cal_loft_ladder_40;
++			tbl_len = ARRAY_SIZE(tbl_tx_iqlo_cal_loft_ladder_40);
++		} else {
++			tbl_ptr = tbl_tx_iqlo_cal_loft_ladder_20;
++			tbl_len = ARRAY_SIZE(tbl_tx_iqlo_cal_loft_ladder_20);
++		}
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, tbl_len, 0,
++					 16, tbl_ptr);
++
++		if (phy_bw == 40) {
++			tbl_ptr = tbl_tx_iqlo_cal_iqimb_ladder_40;
++			tbl_len = ARRAY_SIZE(tbl_tx_iqlo_cal_iqimb_ladder_40);
++		} else {
++			tbl_ptr = tbl_tx_iqlo_cal_iqimb_ladder_20;
++			tbl_len = ARRAY_SIZE(tbl_tx_iqlo_cal_iqimb_ladder_20);
++		}
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, tbl_len, 32,
++					 16, tbl_ptr);
++	}
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7))
++		write_phy_reg(pi, 0xc2, 0x8ad9);
++	else
++		write_phy_reg(pi, 0xc2, 0x8aa9);
++
++	max_val = 250;
++	tone_freq = (phy_bw == 20) ? 2500 : 5000;
++
++	if (pi->mphase_cal_phase_id > MPHASE_CAL_STATE_TXPHASE0) {
++		wlc_phy_runsamples_nphy(pi, phy_bw * 8, 0xffff, 0, 1, 0, false);
++		bcmerror = 0;
++	} else {
++		bcmerror =
++			wlc_phy_tx_tone_nphy(pi, tone_freq, max_val, 1, 0,
++					     false);
++	}
++
++	if (bcmerror == 0) {
++
++		if (pi->mphase_cal_phase_id > MPHASE_CAL_STATE_TXPHASE0) {
++			tbl_ptr = pi->mphase_txcal_bestcoeffs;
++			tbl_len = ARRAY_SIZE(pi->mphase_txcal_bestcoeffs);
++			if (NREV_LT(pi->pubpi.phy_rev, 3))
++				tbl_len -= 2;
++		} else {
++			if ((!fullcal) && (pi->nphy_txiqlocal_coeffsvalid)) {
++
++				tbl_ptr = pi->nphy_txiqlocal_bestc;
++				tbl_len = ARRAY_SIZE(pi->nphy_txiqlocal_bestc);
++				if (NREV_LT(pi->pubpi.phy_rev, 3))
++					tbl_len -= 2;
++			} else {
++
++				fullcal = true;
++
++				if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++					tbl_ptr =
++					    tbl_tx_iqlo_cal_startcoefs_nphyrev3;
++					tbl_len = ARRAY_SIZE(
++					   tbl_tx_iqlo_cal_startcoefs_nphyrev3);
++				} else {
++					tbl_ptr = tbl_tx_iqlo_cal_startcoefs;
++					tbl_len = ARRAY_SIZE(
++						    tbl_tx_iqlo_cal_startcoefs);
++				}
++			}
++		}
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, tbl_len, 64,
++					 16, tbl_ptr);
++
++		if (fullcal) {
++			max_cal_cmds = (NREV_GE(pi->pubpi.phy_rev, 3)) ?
++				       ARRAY_SIZE(
++				tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3) :
++				       ARRAY_SIZE(tbl_tx_iqlo_cal_cmds_fullcal);
++		} else {
++			max_cal_cmds = (NREV_GE(pi->pubpi.phy_rev, 3)) ?
++				       ARRAY_SIZE(
++				tbl_tx_iqlo_cal_cmds_recal_nphyrev3) :
++				       ARRAY_SIZE(tbl_tx_iqlo_cal_cmds_recal);
++		}
++
++		if (mphase) {
++			cal_cnt = pi->mphase_txcal_cmdidx;
++			if ((cal_cnt + pi->mphase_txcal_numcmds) < max_cal_cmds)
++				num_cals = cal_cnt + pi->mphase_txcal_numcmds;
++			else
++				num_cals = max_cal_cmds;
++		} else {
++			cal_cnt = 0;
++			num_cals = max_cal_cmds;
++		}
++
++		for (; cal_cnt < num_cals; cal_cnt++) {
++
++			if (fullcal) {
++				cal_cmd = (NREV_GE(pi->pubpi.phy_rev, 3)) ?
++					  tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3
++					  [cal_cnt] :
++					  tbl_tx_iqlo_cal_cmds_fullcal[cal_cnt];
++			} else {
++				cal_cmd = (NREV_GE(pi->pubpi.phy_rev, 3)) ?
++					  tbl_tx_iqlo_cal_cmds_recal_nphyrev3[
++					cal_cnt]
++					  : tbl_tx_iqlo_cal_cmds_recal[cal_cnt];
++			}
++
++			core_no = ((cal_cmd & 0x3000) >> 12);
++			cal_type = ((cal_cmd & 0x0F00) >> 8);
++
++			if (NREV_GE(pi->pubpi.phy_rev, 6) ||
++			    (NREV_IS(pi->pubpi.phy_rev, 5) &&
++			     PHY_IPA(pi)
++			     && (CHSPEC_IS2G(pi->radio_chanspec)))) {
++				if (!ladder_updated[core_no]) {
++					wlc_phy_update_txcal_ladder_nphy(
++						pi,
++						core_no);
++					ladder_updated[core_no] = true;
++				}
++			}
++
++			val =
++				(cal_params[core_no].
++				 ncorr[cal_type] << 8) | NPHY_N_GCTL;
++			write_phy_reg(pi, 0xc1, val);
++
++			if ((cal_type == 1) || (cal_type == 3)
++			    || (cal_type == 4)) {
++
++				wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL,
++							1, 69 + core_no, 16,
++							tbl_buf);
++
++				diq_start = tbl_buf[0];
++
++				tbl_buf[0] = 0;
++				wlc_phy_table_write_nphy(pi,
++							 NPHY_TBL_ID_IQLOCAL, 1,
++							 69 + core_no, 16,
++							 tbl_buf);
++			}
++
++			write_phy_reg(pi, 0xc0, cal_cmd);
++
++			SPINWAIT(((read_phy_reg(pi, 0xc0) & 0xc000) != 0),
++				 20000);
++			if (WARN(read_phy_reg(pi, 0xc0) & 0xc000,
++				 "HW error: txiq calib"))
++				return -EIO;
++
++			wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL,
++						tbl_len, 96, 16, tbl_buf);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL,
++						 tbl_len, 64, 16, tbl_buf);
++
++			if ((cal_type == 1) || (cal_type == 3)
++			    || (cal_type == 4)) {
++
++				tbl_buf[0] = diq_start;
++
++			}
++
++		}
++
++		if (mphase) {
++			pi->mphase_txcal_cmdidx = num_cals;
++			if (pi->mphase_txcal_cmdidx >= max_cal_cmds)
++				pi->mphase_txcal_cmdidx = 0;
++		}
++
++		mphase_cal_lastphase =
++			(NREV_LE(pi->pubpi.phy_rev, 2)) ?
++			MPHASE_CAL_STATE_TXPHASE4 : MPHASE_CAL_STATE_TXPHASE5;
++
++		if (!mphase
++		    || (pi->mphase_cal_phase_id == mphase_cal_lastphase)) {
++
++			wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 96,
++						16, tbl_buf);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 80,
++						 16, tbl_buf);
++
++			if (NREV_LT(pi->pubpi.phy_rev, 2)) {
++
++				tbl_buf[0] = 0;
++				tbl_buf[1] = 0;
++				tbl_buf[2] = 0;
++				tbl_buf[3] = 0;
++
++			}
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 88,
++						 16, tbl_buf);
++
++			wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 101,
++						16, tbl_buf);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 85,
++						 16, tbl_buf);
++
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 93,
++						 16, tbl_buf);
++
++			tbl_len = ARRAY_SIZE(pi->nphy_txiqlocal_bestc);
++			if (NREV_LT(pi->pubpi.phy_rev, 3))
++				tbl_len -= 2;
++
++			wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL,
++						tbl_len, 96, 16,
++						pi->nphy_txiqlocal_bestc);
++
++			pi->nphy_txiqlocal_coeffsvalid = true;
++			pi->nphy_txiqlocal_chanspec = pi->radio_chanspec;
++		} else {
++			tbl_len = ARRAY_SIZE(pi->mphase_txcal_bestcoeffs);
++			if (NREV_LT(pi->pubpi.phy_rev, 3))
++				tbl_len -= 2;
++
++			wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL,
++						tbl_len, 96, 16,
++						pi->mphase_txcal_bestcoeffs);
++		}
++
++		wlc_phy_stopplayback_nphy(pi);
++
++		write_phy_reg(pi, 0xc2, 0x0000);
++
++	}
++
++	wlc_phy_txcal_phycleanup_nphy(pi);
++
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16,
++				 gain_save);
++
++	wlc_phy_txcal_radio_cleanup_nphy(pi);
++
++	if (NREV_LT(pi->pubpi.phy_rev, 2)) {
++		if (!mphase
++		    || (pi->mphase_cal_phase_id == mphase_cal_lastphase))
++			wlc_phy_tx_iq_war_nphy(pi);
++	}
++
++	if (NREV_GE(pi->pubpi.phy_rev, 4))
++		pi->phyhang_avoid = phyhang_avoid_state;
++
++	wlc_phy_stay_in_carriersearch_nphy(pi, false);
++
++	return bcmerror;
++}
++
++static void wlc_phy_reapply_txcal_coeffs_nphy(struct brcms_phy *pi)
++{
++	u16 tbl_buf[7];
++
++	if ((pi->nphy_txiqlocal_chanspec == pi->radio_chanspec) &&
++	    (pi->nphy_txiqlocal_coeffsvalid)) {
++		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL,
++					ARRAY_SIZE(tbl_buf), 80, 16, tbl_buf);
++
++		if ((pi->nphy_txiqlocal_bestc[0] != tbl_buf[0]) ||
++		    (pi->nphy_txiqlocal_bestc[1] != tbl_buf[1]) ||
++		    (pi->nphy_txiqlocal_bestc[2] != tbl_buf[2]) ||
++		    (pi->nphy_txiqlocal_bestc[3] != tbl_buf[3])) {
++
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 80,
++						 16, pi->nphy_txiqlocal_bestc);
++
++			tbl_buf[0] = 0;
++			tbl_buf[1] = 0;
++			tbl_buf[2] = 0;
++			tbl_buf[3] = 0;
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 88,
++						 16, tbl_buf);
++
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 85,
++						 16,
++						 &pi->nphy_txiqlocal_bestc[5]);
++
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 93,
++						 16,
++						 &pi->nphy_txiqlocal_bestc[5]);
++		}
++	}
++}
++
++void
++wlc_phy_rx_iq_coeffs_nphy(struct brcms_phy *pi, u8 write,
++			  struct nphy_iq_comp *pcomp)
++{
++	if (write) {
++		write_phy_reg(pi, 0x9a, pcomp->a0);
++		write_phy_reg(pi, 0x9b, pcomp->b0);
++		write_phy_reg(pi, 0x9c, pcomp->a1);
++		write_phy_reg(pi, 0x9d, pcomp->b1);
++	} else {
++		pcomp->a0 = read_phy_reg(pi, 0x9a);
++		pcomp->b0 = read_phy_reg(pi, 0x9b);
++		pcomp->a1 = read_phy_reg(pi, 0x9c);
++		pcomp->b1 = read_phy_reg(pi, 0x9d);
++	}
++}
++
++void
++wlc_phy_rx_iq_est_nphy(struct brcms_phy *pi, struct phy_iq_est *est,
++		       u16 num_samps, u8 wait_time, u8 wait_for_crs)
++{
++	u8 core;
++
++	write_phy_reg(pi, 0x12b, num_samps);
++	mod_phy_reg(pi, 0x12a, (0xff << 0), (wait_time << 0));
++	mod_phy_reg(pi, 0x129, NPHY_IqestCmd_iqMode,
++		    (wait_for_crs) ? NPHY_IqestCmd_iqMode : 0);
++
++	mod_phy_reg(pi, 0x129, NPHY_IqestCmd_iqstart, NPHY_IqestCmd_iqstart);
++
++	SPINWAIT(((read_phy_reg(pi, 0x129) & NPHY_IqestCmd_iqstart) != 0),
++		 10000);
++	if (WARN(read_phy_reg(pi, 0x129) & NPHY_IqestCmd_iqstart,
++		 "HW error: rxiq est"))
++		return;
++
++	if ((read_phy_reg(pi, 0x129) & NPHY_IqestCmd_iqstart) == 0) {
++		for (core = 0; core < pi->pubpi.phy_corenum; core++) {
++			est[core].i_pwr =
++				(read_phy_reg(pi,
++					      NPHY_IqestipwrAccHi(core)) << 16)
++				| read_phy_reg(pi, NPHY_IqestipwrAccLo(core));
++			est[core].q_pwr =
++				(read_phy_reg(pi,
++					      NPHY_IqestqpwrAccHi(core)) << 16)
++				| read_phy_reg(pi, NPHY_IqestqpwrAccLo(core));
++			est[core].iq_prod =
++				(read_phy_reg(pi,
++					      NPHY_IqestIqAccHi(core)) << 16) |
++				read_phy_reg(pi, NPHY_IqestIqAccLo(core));
++		}
++	}
++}
++
++#define CAL_RETRY_CNT 2
++static void wlc_phy_calc_rx_iq_comp_nphy(struct brcms_phy *pi, u8 core_mask)
++{
++	u8 curr_core;
++	struct phy_iq_est est[PHY_CORE_MAX];
++	struct nphy_iq_comp old_comp, new_comp;
++	s32 iq = 0;
++	u32 ii = 0, qq = 0;
++	s16 iq_nbits, qq_nbits, brsh, arsh;
++	s32 a, b, temp;
++	int bcmerror = 0;
++	uint cal_retry = 0;
++
++	if (core_mask == 0x0)
++		return;
++
++	wlc_phy_rx_iq_coeffs_nphy(pi, 0, &old_comp);
++	new_comp.a0 = new_comp.b0 = new_comp.a1 = new_comp.b1 = 0x0;
++	wlc_phy_rx_iq_coeffs_nphy(pi, 1, &new_comp);
++
++cal_try:
++	wlc_phy_rx_iq_est_nphy(pi, est, 0x4000, 32, 0);
++
++	new_comp = old_comp;
++
++	for (curr_core = 0; curr_core < pi->pubpi.phy_corenum; curr_core++) {
++
++		if ((curr_core == PHY_CORE_0) && (core_mask & 0x1)) {
++			iq = est[curr_core].iq_prod;
++			ii = est[curr_core].i_pwr;
++			qq = est[curr_core].q_pwr;
++		} else if ((curr_core == PHY_CORE_1) && (core_mask & 0x2)) {
++			iq = est[curr_core].iq_prod;
++			ii = est[curr_core].i_pwr;
++			qq = est[curr_core].q_pwr;
++		} else {
++			continue;
++		}
++
++		if ((ii + qq) < NPHY_MIN_RXIQ_PWR) {
++			bcmerror = -EBADE;
++			break;
++		}
++
++		iq_nbits = wlc_phy_nbits(iq);
++		qq_nbits = wlc_phy_nbits(qq);
++
++		arsh = 10 - (30 - iq_nbits);
++		if (arsh >= 0) {
++			a = (-(iq << (30 - iq_nbits)) + (ii >> (1 + arsh)));
++			temp = (s32) (ii >> arsh);
++			if (temp == 0) {
++				bcmerror = -EBADE;
++				break;
++			}
++		} else {
++			a = (-(iq << (30 - iq_nbits)) + (ii << (-1 - arsh)));
++			temp = (s32) (ii << -arsh);
++			if (temp == 0) {
++				bcmerror = -EBADE;
++				break;
++			}
++		}
++
++		a /= temp;
++
++		brsh = qq_nbits - 31 + 20;
++		if (brsh >= 0) {
++			b = (qq << (31 - qq_nbits));
++			temp = (s32) (ii >> brsh);
++			if (temp == 0) {
++				bcmerror = -EBADE;
++				break;
++			}
++		} else {
++			b = (qq << (31 - qq_nbits));
++			temp = (s32) (ii << -brsh);
++			if (temp == 0) {
++				bcmerror = -EBADE;
++				break;
++			}
++		}
++		b /= temp;
++		b -= a * a;
++		b = (s32) int_sqrt((unsigned long) b);
++		b -= (1 << 10);
++
++		if ((curr_core == PHY_CORE_0) && (core_mask & 0x1)) {
++			if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++				new_comp.a0 = (s16) a & 0x3ff;
++				new_comp.b0 = (s16) b & 0x3ff;
++			} else {
++
++				new_comp.a0 = (s16) b & 0x3ff;
++				new_comp.b0 = (s16) a & 0x3ff;
++			}
++		}
++		if ((curr_core == PHY_CORE_1) && (core_mask & 0x2)) {
++			if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++				new_comp.a1 = (s16) a & 0x3ff;
++				new_comp.b1 = (s16) b & 0x3ff;
++			} else {
++
++				new_comp.a1 = (s16) b & 0x3ff;
++				new_comp.b1 = (s16) a & 0x3ff;
++			}
++		}
++	}
++
++	if (bcmerror != 0) {
++		pr_debug("%s: Failed, cnt = %d\n", __func__, cal_retry);
++
++		if (cal_retry < CAL_RETRY_CNT) {
++			cal_retry++;
++			goto cal_try;
++		}
++
++		new_comp = old_comp;
++	}
++
++	wlc_phy_rx_iq_coeffs_nphy(pi, 1, &new_comp);
++}
++
++static void wlc_phy_rxcal_radio_setup_nphy(struct brcms_phy *pi, u8 rx_core)
++{
++	u16 offtune_val;
++	u16 bias_g = 0;
++	u16 bias_a = 0;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		if (rx_core == PHY_CORE_0) {
++			if (CHSPEC_IS5G(pi->radio_chanspec)) {
++				pi->tx_rx_cal_radio_saveregs[0] =
++					read_radio_reg(pi,
++					    RADIO_2057_TX0_TXRXCOUPLE_5G_PWRUP);
++				pi->tx_rx_cal_radio_saveregs[1] =
++					read_radio_reg(pi,
++					    RADIO_2057_TX0_TXRXCOUPLE_5G_ATTEN);
++
++				write_radio_reg(pi,
++					RADIO_2057_TX0_TXRXCOUPLE_5G_PWRUP,
++					0x3);
++				write_radio_reg(pi,
++					RADIO_2057_TX0_TXRXCOUPLE_5G_ATTEN,
++					0xaf);
++
++			} else {
++				pi->tx_rx_cal_radio_saveregs[0] =
++					read_radio_reg(pi,
++					    RADIO_2057_TX0_TXRXCOUPLE_2G_PWRUP);
++				pi->tx_rx_cal_radio_saveregs[1] =
++					read_radio_reg(pi,
++					    RADIO_2057_TX0_TXRXCOUPLE_2G_ATTEN);
++
++				write_radio_reg(
++					pi,
++					RADIO_2057_TX0_TXRXCOUPLE_2G_PWRUP,
++					0x3);
++				write_radio_reg(
++					pi,
++					RADIO_2057_TX0_TXRXCOUPLE_2G_ATTEN,
++					0x7f);
++			}
++
++		} else {
++			if (CHSPEC_IS5G(pi->radio_chanspec)) {
++				pi->tx_rx_cal_radio_saveregs[0] =
++					read_radio_reg(pi,
++					    RADIO_2057_TX1_TXRXCOUPLE_5G_PWRUP);
++				pi->tx_rx_cal_radio_saveregs[1] =
++					read_radio_reg(pi,
++					    RADIO_2057_TX1_TXRXCOUPLE_5G_ATTEN);
++
++				write_radio_reg(
++					pi,
++					RADIO_2057_TX1_TXRXCOUPLE_5G_PWRUP,
++					0x3);
++				write_radio_reg(
++					pi,
++					RADIO_2057_TX1_TXRXCOUPLE_5G_ATTEN,
++					0xaf);
++
++			} else {
++				pi->tx_rx_cal_radio_saveregs[0] =
++					read_radio_reg(pi,
++					    RADIO_2057_TX1_TXRXCOUPLE_2G_PWRUP);
++				pi->tx_rx_cal_radio_saveregs[1] =
++					read_radio_reg(pi,
++					    RADIO_2057_TX1_TXRXCOUPLE_2G_ATTEN);
++
++				write_radio_reg(pi,
++					RADIO_2057_TX1_TXRXCOUPLE_2G_PWRUP,
++					0x3);
++				write_radio_reg(pi,
++					RADIO_2057_TX1_TXRXCOUPLE_2G_ATTEN,
++					0x7f);
++			}
++		}
++
++	} else {
++		if (rx_core == PHY_CORE_0) {
++			pi->tx_rx_cal_radio_saveregs[0] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_RXIQCAL_TXMUX |
++					       RADIO_2056_TX1);
++			pi->tx_rx_cal_radio_saveregs[1] =
++				read_radio_reg(pi,
++					       RADIO_2056_RX_RXIQCAL_RXMUX |
++					       RADIO_2056_RX0);
++
++			if (pi->pubpi.radiorev >= 5) {
++				pi->tx_rx_cal_radio_saveregs[2] =
++					read_radio_reg(pi,
++						       RADIO_2056_RX_RXSPARE2 |
++						       RADIO_2056_RX0);
++				pi->tx_rx_cal_radio_saveregs[3] =
++					read_radio_reg(pi,
++						       RADIO_2056_TX_TXSPARE2 |
++						       RADIO_2056_TX1);
++			}
++
++			if (CHSPEC_IS5G(pi->radio_chanspec)) {
++
++				if (pi->pubpi.radiorev >= 5) {
++					pi->tx_rx_cal_radio_saveregs[4] =
++						read_radio_reg(pi,
++						      RADIO_2056_RX_LNAA_MASTER
++						      | RADIO_2056_RX0);
++
++					write_radio_reg(
++						pi,
++						RADIO_2056_RX_LNAA_MASTER
++						| RADIO_2056_RX0, 0x40);
++
++					write_radio_reg(pi,
++						RADIO_2056_TX_TXSPARE2 |
++						RADIO_2056_TX1, bias_a);
++
++					write_radio_reg(pi,
++						RADIO_2056_RX_RXSPARE2 |
++						RADIO_2056_RX0, bias_a);
++				} else {
++					pi->tx_rx_cal_radio_saveregs[4] =
++						read_radio_reg(pi,
++							RADIO_2056_RX_LNAA_TUNE
++							| RADIO_2056_RX0);
++
++					offtune_val =
++						(pi->tx_rx_cal_radio_saveregs
++						 [2] & 0xF0) >> 8;
++					offtune_val =
++						(offtune_val <= 0x7) ? 0xF : 0;
++
++					mod_radio_reg(pi,
++						      RADIO_2056_RX_LNAA_TUNE |
++						      RADIO_2056_RX0, 0xF0,
++						      (offtune_val << 8));
++				}
++
++				write_radio_reg(pi,
++						RADIO_2056_TX_RXIQCAL_TXMUX |
++						RADIO_2056_TX1, 0x9);
++				write_radio_reg(pi,
++						RADIO_2056_RX_RXIQCAL_RXMUX |
++						RADIO_2056_RX0, 0x9);
++			} else {
++				if (pi->pubpi.radiorev >= 5) {
++					pi->tx_rx_cal_radio_saveregs[4] =
++						read_radio_reg(
++						      pi,
++						      RADIO_2056_RX_LNAG_MASTER
++						    | RADIO_2056_RX0);
++
++					write_radio_reg(
++						pi,
++						RADIO_2056_RX_LNAG_MASTER
++						| RADIO_2056_RX0, 0x40);
++
++					write_radio_reg(
++						pi,
++						RADIO_2056_TX_TXSPARE2
++						|
++						RADIO_2056_TX1, bias_g);
++
++					write_radio_reg(
++						pi,
++						RADIO_2056_RX_RXSPARE2
++						|
++						RADIO_2056_RX0, bias_g);
++
++				} else {
++					pi->tx_rx_cal_radio_saveregs[4] =
++						read_radio_reg(
++							pi,
++							RADIO_2056_RX_LNAG_TUNE
++							| RADIO_2056_RX0);
++
++					offtune_val =
++						(pi->
++						 tx_rx_cal_radio_saveregs[2] &
++						 0xF0) >> 8;
++					offtune_val =
++						(offtune_val <= 0x7) ? 0xF : 0;
++
++					mod_radio_reg(pi,
++						      RADIO_2056_RX_LNAG_TUNE |
++						      RADIO_2056_RX0, 0xF0,
++						      (offtune_val << 8));
++				}
++
++				write_radio_reg(pi,
++						RADIO_2056_TX_RXIQCAL_TXMUX |
++						RADIO_2056_TX1, 0x6);
++				write_radio_reg(pi,
++						RADIO_2056_RX_RXIQCAL_RXMUX |
++						RADIO_2056_RX0, 0x6);
++			}
++
++		} else {
++			pi->tx_rx_cal_radio_saveregs[0] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_RXIQCAL_TXMUX |
++					       RADIO_2056_TX0);
++			pi->tx_rx_cal_radio_saveregs[1] =
++				read_radio_reg(pi,
++					       RADIO_2056_RX_RXIQCAL_RXMUX |
++					       RADIO_2056_RX1);
++
++			if (pi->pubpi.radiorev >= 5) {
++				pi->tx_rx_cal_radio_saveregs[2] =
++					read_radio_reg(pi,
++						       RADIO_2056_RX_RXSPARE2 |
++						       RADIO_2056_RX1);
++				pi->tx_rx_cal_radio_saveregs[3] =
++					read_radio_reg(pi,
++						       RADIO_2056_TX_TXSPARE2 |
++						       RADIO_2056_TX0);
++			}
++
++			if (CHSPEC_IS5G(pi->radio_chanspec)) {
++
++				if (pi->pubpi.radiorev >= 5) {
++					pi->tx_rx_cal_radio_saveregs[4] =
++						read_radio_reg(
++						       pi,
++						       RADIO_2056_RX_LNAA_MASTER
++						       | RADIO_2056_RX1);
++
++					write_radio_reg(
++						pi,
++						RADIO_2056_RX_LNAA_MASTER |
++						RADIO_2056_RX1, 0x40);
++
++					write_radio_reg(
++						pi,
++						RADIO_2056_TX_TXSPARE2
++						|
++						RADIO_2056_TX0, bias_a);
++
++					write_radio_reg(
++						pi,
++						RADIO_2056_RX_RXSPARE2
++						|
++						RADIO_2056_RX1, bias_a);
++				} else {
++					pi->tx_rx_cal_radio_saveregs[4] =
++						read_radio_reg(
++							pi,
++							RADIO_2056_RX_LNAA_TUNE
++							| RADIO_2056_RX1);
++
++					offtune_val =
++						(pi->
++						 tx_rx_cal_radio_saveregs[2] &
++						 0xF0) >> 8;
++					offtune_val =
++						(offtune_val <= 0x7) ? 0xF : 0;
++
++					mod_radio_reg(pi,
++						      RADIO_2056_RX_LNAA_TUNE |
++						      RADIO_2056_RX1, 0xF0,
++						      (offtune_val << 8));
++				}
++
++				write_radio_reg(pi,
++						RADIO_2056_TX_RXIQCAL_TXMUX |
++						RADIO_2056_TX0, 0x9);
++				write_radio_reg(pi,
++						RADIO_2056_RX_RXIQCAL_RXMUX |
++						RADIO_2056_RX1, 0x9);
++			} else {
++				if (pi->pubpi.radiorev >= 5) {
++					pi->tx_rx_cal_radio_saveregs[4] =
++						read_radio_reg(
++						      pi,
++						      RADIO_2056_RX_LNAG_MASTER
++						    | RADIO_2056_RX1);
++
++					write_radio_reg(
++						pi,
++						RADIO_2056_RX_LNAG_MASTER
++						| RADIO_2056_RX1, 0x40);
++
++					write_radio_reg(
++						pi,
++						RADIO_2056_TX_TXSPARE2
++						|
++						RADIO_2056_TX0, bias_g);
++
++					write_radio_reg(
++						pi,
++						RADIO_2056_RX_RXSPARE2
++						|
++						RADIO_2056_RX1, bias_g);
++				} else {
++					pi->tx_rx_cal_radio_saveregs[4] =
++						read_radio_reg(
++							pi,
++							RADIO_2056_RX_LNAG_TUNE
++							| RADIO_2056_RX1);
++
++					offtune_val =
++						(pi->
++						 tx_rx_cal_radio_saveregs[2] &
++						 0xF0) >> 8;
++					offtune_val =
++						(offtune_val <= 0x7) ? 0xF : 0;
++
++					mod_radio_reg(pi,
++						      RADIO_2056_RX_LNAG_TUNE |
++						      RADIO_2056_RX1, 0xF0,
++						      (offtune_val << 8));
++				}
++
++				write_radio_reg(pi,
++						RADIO_2056_TX_RXIQCAL_TXMUX |
++						RADIO_2056_TX0, 0x6);
++				write_radio_reg(pi,
++						RADIO_2056_RX_RXIQCAL_RXMUX |
++						RADIO_2056_RX1, 0x6);
++			}
++		}
++	}
++}
++
++static void wlc_phy_rxcal_radio_cleanup_nphy(struct brcms_phy *pi, u8 rx_core)
++{
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		if (rx_core == PHY_CORE_0) {
++			if (CHSPEC_IS5G(pi->radio_chanspec)) {
++				write_radio_reg(
++					pi,
++					RADIO_2057_TX0_TXRXCOUPLE_5G_PWRUP,
++					pi->
++					tx_rx_cal_radio_saveregs[0]);
++				write_radio_reg(
++					pi,
++					RADIO_2057_TX0_TXRXCOUPLE_5G_ATTEN,
++					pi->
++					tx_rx_cal_radio_saveregs[1]);
++
++			} else {
++				write_radio_reg(
++					pi,
++					RADIO_2057_TX0_TXRXCOUPLE_2G_PWRUP,
++					pi->
++					tx_rx_cal_radio_saveregs[0]);
++				write_radio_reg(
++					pi,
++					RADIO_2057_TX0_TXRXCOUPLE_2G_ATTEN,
++					pi->
++					tx_rx_cal_radio_saveregs[1]);
++			}
++
++		} else {
++			if (CHSPEC_IS5G(pi->radio_chanspec)) {
++				write_radio_reg(
++					pi,
++					RADIO_2057_TX1_TXRXCOUPLE_5G_PWRUP,
++					pi->
++					tx_rx_cal_radio_saveregs[0]);
++				write_radio_reg(
++					pi,
++					RADIO_2057_TX1_TXRXCOUPLE_5G_ATTEN,
++					pi->
++					tx_rx_cal_radio_saveregs[1]);
++
++			} else {
++				write_radio_reg(
++					pi,
++					RADIO_2057_TX1_TXRXCOUPLE_2G_PWRUP,
++					pi->
++					tx_rx_cal_radio_saveregs[0]);
++				write_radio_reg(
++					pi,
++					RADIO_2057_TX1_TXRXCOUPLE_2G_ATTEN,
++					pi->
++					tx_rx_cal_radio_saveregs[1]);
++			}
++		}
++
++	} else {
++		if (rx_core == PHY_CORE_0) {
++			write_radio_reg(pi,
++					RADIO_2056_TX_RXIQCAL_TXMUX |
++					RADIO_2056_TX1,
++					pi->tx_rx_cal_radio_saveregs[0]);
++
++			write_radio_reg(pi,
++					RADIO_2056_RX_RXIQCAL_RXMUX |
++					RADIO_2056_RX0,
++					pi->tx_rx_cal_radio_saveregs[1]);
++
++			if (pi->pubpi.radiorev >= 5) {
++				write_radio_reg(pi,
++						RADIO_2056_RX_RXSPARE2 |
++						RADIO_2056_RX0,
++						pi->
++						tx_rx_cal_radio_saveregs[2]);
++
++				write_radio_reg(pi,
++						RADIO_2056_TX_TXSPARE2 |
++						RADIO_2056_TX1,
++						pi->
++						tx_rx_cal_radio_saveregs[3]);
++			}
++
++			if (CHSPEC_IS5G(pi->radio_chanspec)) {
++				if (pi->pubpi.radiorev >= 5)
++					write_radio_reg(
++						pi,
++						RADIO_2056_RX_LNAA_MASTER
++						| RADIO_2056_RX0,
++						pi->
++						tx_rx_cal_radio_saveregs
++						[4]);
++				else
++					write_radio_reg(
++						pi,
++						RADIO_2056_RX_LNAA_TUNE
++						| RADIO_2056_RX0,
++						pi->
++						tx_rx_cal_radio_saveregs
++						[4]);
++			} else {
++				if (pi->pubpi.radiorev >= 5)
++					write_radio_reg(
++						pi,
++						RADIO_2056_RX_LNAG_MASTER
++						| RADIO_2056_RX0,
++						pi->
++						tx_rx_cal_radio_saveregs
++						[4]);
++				else
++					write_radio_reg(
++						pi,
++						RADIO_2056_RX_LNAG_TUNE
++						| RADIO_2056_RX0,
++						pi->
++						tx_rx_cal_radio_saveregs
++						[4]);
++			}
++
++		} else {
++			write_radio_reg(pi,
++					RADIO_2056_TX_RXIQCAL_TXMUX |
++					RADIO_2056_TX0,
++					pi->tx_rx_cal_radio_saveregs[0]);
++
++			write_radio_reg(pi,
++					RADIO_2056_RX_RXIQCAL_RXMUX |
++					RADIO_2056_RX1,
++					pi->tx_rx_cal_radio_saveregs[1]);
++
++			if (pi->pubpi.radiorev >= 5) {
++				write_radio_reg(pi,
++						RADIO_2056_RX_RXSPARE2 |
++						RADIO_2056_RX1,
++						pi->
++						tx_rx_cal_radio_saveregs[2]);
++
++				write_radio_reg(pi,
++						RADIO_2056_TX_TXSPARE2 |
++						RADIO_2056_TX0,
++						pi->
++						tx_rx_cal_radio_saveregs[3]);
++			}
++
++			if (CHSPEC_IS5G(pi->radio_chanspec)) {
++				if (pi->pubpi.radiorev >= 5)
++					write_radio_reg(
++						pi,
++						RADIO_2056_RX_LNAA_MASTER
++						| RADIO_2056_RX1,
++						pi->
++						tx_rx_cal_radio_saveregs
++						[4]);
++				else
++					write_radio_reg(
++						pi,
++						RADIO_2056_RX_LNAA_TUNE
++						| RADIO_2056_RX1,
++						pi->
++						tx_rx_cal_radio_saveregs
++						[4]);
++			} else {
++				if (pi->pubpi.radiorev >= 5)
++					write_radio_reg(
++						pi,
++						RADIO_2056_RX_LNAG_MASTER
++						| RADIO_2056_RX1,
++						pi->
++						tx_rx_cal_radio_saveregs
++						[4]);
++				else
++					write_radio_reg(
++						pi,
++						RADIO_2056_RX_LNAG_TUNE
++						| RADIO_2056_RX1,
++						pi->
++						tx_rx_cal_radio_saveregs
++						[4]);
++			}
++		}
++	}
++}
++
++static void wlc_phy_rxcal_physetup_nphy(struct brcms_phy *pi, u8 rx_core)
++{
++	u8 tx_core;
++	u16 rx_antval, tx_antval;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7))
++		tx_core = rx_core;
++	else
++		tx_core = (rx_core == PHY_CORE_0) ? 1 : 0;
++
++	pi->tx_rx_cal_phy_saveregs[0] = read_phy_reg(pi, 0xa2);
++	pi->tx_rx_cal_phy_saveregs[1] =
++		read_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0xa6 : 0xa7);
++	pi->tx_rx_cal_phy_saveregs[2] =
++		read_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0x8f : 0xa5);
++	pi->tx_rx_cal_phy_saveregs[3] = read_phy_reg(pi, 0x91);
++	pi->tx_rx_cal_phy_saveregs[4] = read_phy_reg(pi, 0x92);
++	pi->tx_rx_cal_phy_saveregs[5] = read_phy_reg(pi, 0x7a);
++	pi->tx_rx_cal_phy_saveregs[6] = read_phy_reg(pi, 0x7d);
++	pi->tx_rx_cal_phy_saveregs[7] = read_phy_reg(pi, 0xe7);
++	pi->tx_rx_cal_phy_saveregs[8] = read_phy_reg(pi, 0xec);
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		pi->tx_rx_cal_phy_saveregs[11] = read_phy_reg(pi, 0x342);
++		pi->tx_rx_cal_phy_saveregs[12] = read_phy_reg(pi, 0x343);
++		pi->tx_rx_cal_phy_saveregs[13] = read_phy_reg(pi, 0x346);
++		pi->tx_rx_cal_phy_saveregs[14] = read_phy_reg(pi, 0x347);
++	}
++
++	pi->tx_rx_cal_phy_saveregs[9] = read_phy_reg(pi, 0x297);
++	pi->tx_rx_cal_phy_saveregs[10] = read_phy_reg(pi, 0x29b);
++	mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x297 :
++		    0x29b, (0x1 << 0), (0) << 0);
++
++	mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x297 :
++		    0x29b, (0x1 << 0), (0) << 0);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++
++		mod_phy_reg(pi, 0xa2, (0xf << 0), (1 << tx_core) << 0);
++
++		mod_phy_reg(pi, 0xa2, (0xf << 12), (1 << (1 - rx_core)) << 12);
++
++	} else {
++
++		mod_phy_reg(pi, 0xa2, (0xf << 12), (1 << tx_core) << 12);
++		mod_phy_reg(pi, 0xa2, (0xf << 0), (1 << tx_core) << 0);
++		mod_phy_reg(pi, 0xa2, (0xf << 4), (1 << rx_core) << 4);
++		mod_phy_reg(pi, 0xa2, (0xf << 8), (1 << rx_core) << 8);
++	}
++
++	mod_phy_reg(pi, ((rx_core == PHY_CORE_0) ? 0xa6 : 0xa7), (0x1 << 2), 0);
++	mod_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0x8f : 0xa5,
++		    (0x1 << 2), (0x1 << 2));
++	if (NREV_LT(pi->pubpi.phy_rev, 7)) {
++		mod_phy_reg(pi, ((rx_core == PHY_CORE_0) ? 0xa6 : 0xa7),
++			    (0x1 << 0) | (0x1 << 1), 0);
++		mod_phy_reg(pi, (rx_core == PHY_CORE_0) ?
++			    0x8f : 0xa5,
++			    (0x1 << 0) | (0x1 << 1), (0x1 << 0) | (0x1 << 1));
++	}
++
++	wlc_phy_rfctrlintc_override_nphy(pi, NPHY_RfctrlIntc_override_PA, 0,
++					 RADIO_MIMO_CORESEL_CORE1 |
++					 RADIO_MIMO_CORESEL_CORE2);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3),
++						  0, 0, 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 9), 0, 0, 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 10), 1, 0, 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), 1, 0, 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), 1, 0, 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID2);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11), 0, 0, 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		if (CHSPEC_IS40(pi->radio_chanspec))
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi,
++				(0x1 << 7),
++				2, 0, 0,
++				NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		else
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi,
++				(0x1 << 7),
++				0, 0, 0,
++				NPHY_REV7_RFCTRLOVERRIDE_ID1);
++
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 7),
++						  0, 0, 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 5), 0, 0, 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++	} else {
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 0, 3, 0);
++	}
++
++	wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++
++		wlc_phy_rfctrlintc_override_nphy(pi,
++						 NPHY_RfctrlIntc_override_TRSW,
++						 0x1, rx_core + 1);
++	} else {
++
++		if (rx_core == PHY_CORE_0) {
++			rx_antval = 0x1;
++			tx_antval = 0x8;
++		} else {
++			rx_antval = 0x4;
++			tx_antval = 0x2;
++		}
++
++		wlc_phy_rfctrlintc_override_nphy(pi,
++						 NPHY_RfctrlIntc_override_TRSW,
++						 rx_antval, rx_core + 1);
++		wlc_phy_rfctrlintc_override_nphy(pi,
++						 NPHY_RfctrlIntc_override_TRSW,
++						 tx_antval, tx_core + 1);
++	}
++}
++
++static void wlc_phy_rxcal_phycleanup_nphy(struct brcms_phy *pi, u8 rx_core)
++{
++
++	write_phy_reg(pi, 0xa2, pi->tx_rx_cal_phy_saveregs[0]);
++	write_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0xa6 : 0xa7,
++		      pi->tx_rx_cal_phy_saveregs[1]);
++	write_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0x8f : 0xa5,
++		      pi->tx_rx_cal_phy_saveregs[2]);
++	write_phy_reg(pi, 0x91, pi->tx_rx_cal_phy_saveregs[3]);
++	write_phy_reg(pi, 0x92, pi->tx_rx_cal_phy_saveregs[4]);
++
++	write_phy_reg(pi, 0x7a, pi->tx_rx_cal_phy_saveregs[5]);
++	write_phy_reg(pi, 0x7d, pi->tx_rx_cal_phy_saveregs[6]);
++	write_phy_reg(pi, 0xe7, pi->tx_rx_cal_phy_saveregs[7]);
++	write_phy_reg(pi, 0xec, pi->tx_rx_cal_phy_saveregs[8]);
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		write_phy_reg(pi, 0x342, pi->tx_rx_cal_phy_saveregs[11]);
++		write_phy_reg(pi, 0x343, pi->tx_rx_cal_phy_saveregs[12]);
++		write_phy_reg(pi, 0x346, pi->tx_rx_cal_phy_saveregs[13]);
++		write_phy_reg(pi, 0x347, pi->tx_rx_cal_phy_saveregs[14]);
++	}
++
++	write_phy_reg(pi, 0x297, pi->tx_rx_cal_phy_saveregs[9]);
++	write_phy_reg(pi, 0x29b, pi->tx_rx_cal_phy_saveregs[10]);
++}
++
++static void
++wlc_phy_rxcal_gainctrl_nphy_rev5(struct brcms_phy *pi, u8 rx_core,
++				 u16 *rxgain, u8 cal_type)
++{
++
++	u16 num_samps;
++	struct phy_iq_est est[PHY_CORE_MAX];
++	u8 tx_core;
++	struct nphy_iq_comp save_comp, zero_comp;
++	u32 i_pwr, q_pwr, curr_pwr, optim_pwr = 0, prev_pwr = 0,
++	    thresh_pwr = 10000;
++	s16 desired_log2_pwr, actual_log2_pwr, delta_pwr;
++	bool gainctrl_done = false;
++	u8 mix_tia_gain = 3;
++	s8 optim_gaintbl_index = 0, prev_gaintbl_index = 0;
++	s8 curr_gaintbl_index = 3;
++	u8 gainctrl_dirn = NPHY_RXCAL_GAIN_INIT;
++	const struct nphy_ipa_txrxgain *nphy_rxcal_gaintbl;
++	u16 hpvga, lpf_biq1, lpf_biq0, lna2, lna1;
++	int fine_gain_idx;
++	s8 txpwrindex;
++	u16 nphy_rxcal_txgain[2];
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7))
++		tx_core = rx_core;
++	else
++		tx_core = 1 - rx_core;
++
++	num_samps = 1024;
++	desired_log2_pwr = (cal_type == 0) ? 13 : 13;
++
++	wlc_phy_rx_iq_coeffs_nphy(pi, 0, &save_comp);
++	zero_comp.a0 = zero_comp.b0 = zero_comp.a1 = zero_comp.b1 = 0x0;
++	wlc_phy_rx_iq_coeffs_nphy(pi, 1, &zero_comp);
++
++	if (CHSPEC_IS5G(pi->radio_chanspec)) {
++		if (NREV_GE(pi->pubpi.phy_rev, 7))
++			mix_tia_gain = 3;
++		else if (NREV_GE(pi->pubpi.phy_rev, 4))
++			mix_tia_gain = 4;
++		else
++			mix_tia_gain = 6;
++		if (NREV_GE(pi->pubpi.phy_rev, 7))
++			nphy_rxcal_gaintbl = nphy_ipa_rxcal_gaintbl_5GHz_rev7;
++		else
++			nphy_rxcal_gaintbl = nphy_ipa_rxcal_gaintbl_5GHz;
++	} else {
++		if (NREV_GE(pi->pubpi.phy_rev, 7))
++			nphy_rxcal_gaintbl = nphy_ipa_rxcal_gaintbl_2GHz_rev7;
++		else
++			nphy_rxcal_gaintbl = nphy_ipa_rxcal_gaintbl_2GHz;
++	}
++
++	do {
++
++		hpvga = (NREV_GE(pi->pubpi.phy_rev, 7)) ?
++			0 : nphy_rxcal_gaintbl[curr_gaintbl_index].hpvga;
++		lpf_biq1 = nphy_rxcal_gaintbl[curr_gaintbl_index].lpf_biq1;
++		lpf_biq0 = nphy_rxcal_gaintbl[curr_gaintbl_index].lpf_biq0;
++		lna2 = nphy_rxcal_gaintbl[curr_gaintbl_index].lna2;
++		lna1 = nphy_rxcal_gaintbl[curr_gaintbl_index].lna1;
++		txpwrindex = nphy_rxcal_gaintbl[curr_gaintbl_index].txpwrindex;
++
++		if (NREV_GE(pi->pubpi.phy_rev, 7))
++			wlc_phy_rfctrl_override_1tomany_nphy(
++				pi,
++				NPHY_REV7_RfctrlOverride_cmd_rxgain,
++				((lpf_biq1 << 12) |
++				 (lpf_biq0 << 8) |
++				 (mix_tia_gain << 4) | (lna2 << 2)
++				 | lna1), 0x3, 0);
++		else
++			wlc_phy_rfctrl_override_nphy(pi, (0x1 << 12),
++						     ((hpvga << 12) |
++						      (lpf_biq1 << 10) |
++						      (lpf_biq0 << 8) |
++						      (mix_tia_gain << 4) |
++						      (lna2 << 2) | lna1), 0x3,
++						     0);
++
++		pi->nphy_rxcal_pwr_idx[tx_core] = txpwrindex;
++
++		if (txpwrindex == -1) {
++			nphy_rxcal_txgain[0] = 0x8ff0 | pi->nphy_gmval;
++			nphy_rxcal_txgain[1] = 0x8ff0 | pi->nphy_gmval;
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
++						 2, 0x110, 16,
++						 nphy_rxcal_txgain);
++		} else {
++			wlc_phy_txpwr_index_nphy(pi, tx_core + 1, txpwrindex,
++						 false);
++		}
++
++		wlc_phy_tx_tone_nphy(pi, (CHSPEC_IS40(pi->radio_chanspec)) ?
++				     NPHY_RXCAL_TONEFREQ_40MHz :
++				     NPHY_RXCAL_TONEFREQ_20MHz,
++				     NPHY_RXCAL_TONEAMP, 0, cal_type, false);
++
++		wlc_phy_rx_iq_est_nphy(pi, est, num_samps, 32, 0);
++		i_pwr = (est[rx_core].i_pwr + num_samps / 2) / num_samps;
++		q_pwr = (est[rx_core].q_pwr + num_samps / 2) / num_samps;
++		curr_pwr = i_pwr + q_pwr;
++
++		switch (gainctrl_dirn) {
++		case NPHY_RXCAL_GAIN_INIT:
++			if (curr_pwr > thresh_pwr) {
++				gainctrl_dirn = NPHY_RXCAL_GAIN_DOWN;
++				prev_gaintbl_index = curr_gaintbl_index;
++				curr_gaintbl_index--;
++			} else {
++				gainctrl_dirn = NPHY_RXCAL_GAIN_UP;
++				prev_gaintbl_index = curr_gaintbl_index;
++				curr_gaintbl_index++;
++			}
++			break;
++
++		case NPHY_RXCAL_GAIN_UP:
++			if (curr_pwr > thresh_pwr) {
++				gainctrl_done = true;
++				optim_pwr = prev_pwr;
++				optim_gaintbl_index = prev_gaintbl_index;
++			} else {
++				prev_gaintbl_index = curr_gaintbl_index;
++				curr_gaintbl_index++;
++			}
++			break;
++
++		case NPHY_RXCAL_GAIN_DOWN:
++			if (curr_pwr > thresh_pwr) {
++				prev_gaintbl_index = curr_gaintbl_index;
++				curr_gaintbl_index--;
++			} else {
++				gainctrl_done = true;
++				optim_pwr = curr_pwr;
++				optim_gaintbl_index = curr_gaintbl_index;
++			}
++			break;
++
++		default:
++			break;
++		}
++
++		if ((curr_gaintbl_index < 0) ||
++		    (curr_gaintbl_index > NPHY_IPA_RXCAL_MAXGAININDEX)) {
++			gainctrl_done = true;
++			optim_pwr = curr_pwr;
++			optim_gaintbl_index = prev_gaintbl_index;
++		} else {
++			prev_pwr = curr_pwr;
++		}
++
++		wlc_phy_stopplayback_nphy(pi);
++	} while (!gainctrl_done);
++
++	hpvga = nphy_rxcal_gaintbl[optim_gaintbl_index].hpvga;
++	lpf_biq1 = nphy_rxcal_gaintbl[optim_gaintbl_index].lpf_biq1;
++	lpf_biq0 = nphy_rxcal_gaintbl[optim_gaintbl_index].lpf_biq0;
++	lna2 = nphy_rxcal_gaintbl[optim_gaintbl_index].lna2;
++	lna1 = nphy_rxcal_gaintbl[optim_gaintbl_index].lna1;
++	txpwrindex = nphy_rxcal_gaintbl[optim_gaintbl_index].txpwrindex;
++
++	actual_log2_pwr = wlc_phy_nbits(optim_pwr);
++	delta_pwr = desired_log2_pwr - actual_log2_pwr;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		fine_gain_idx = (int)lpf_biq1 + delta_pwr;
++
++		if (fine_gain_idx + (int)lpf_biq0 > 10)
++			lpf_biq1 = 10 - lpf_biq0;
++		else
++			lpf_biq1 = (u16) max(fine_gain_idx, 0);
++
++		wlc_phy_rfctrl_override_1tomany_nphy(
++			pi,
++			NPHY_REV7_RfctrlOverride_cmd_rxgain,
++			((lpf_biq1 << 12) |
++			 (lpf_biq0 << 8) |
++			 (mix_tia_gain << 4) |
++			 (lna2 << 2) | lna1), 0x3,
++			0);
++	} else {
++		hpvga = (u16) max(min(((int)hpvga) + delta_pwr, 10), 0);
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 12),
++					     ((hpvga << 12) |
++					      (lpf_biq1 << 10) |
++					      (lpf_biq0 << 8) |
++					      (mix_tia_gain << 4) |
++					      (lna2 << 2) |
++					      lna1), 0x3, 0);
++	}
++
++	if (rxgain != NULL) {
++		*rxgain++ = lna1;
++		*rxgain++ = lna2;
++		*rxgain++ = mix_tia_gain;
++		*rxgain++ = lpf_biq0;
++		*rxgain++ = lpf_biq1;
++		*rxgain = hpvga;
++	}
++
++	wlc_phy_rx_iq_coeffs_nphy(pi, 1, &save_comp);
++}
++
++static void
++wlc_phy_rxcal_gainctrl_nphy(struct brcms_phy *pi, u8 rx_core, u16 *rxgain,
++			    u8 cal_type)
++{
++	wlc_phy_rxcal_gainctrl_nphy_rev5(pi, rx_core, rxgain, cal_type);
++}
++
++static u8
++wlc_phy_rc_sweep_nphy(struct brcms_phy *pi, u8 core_idx, u8 loopback_type)
++{
++	u32 target_bws[2] = { 9500, 21000 };
++	u32 ref_tones[2] = { 3000, 6000 };
++	u32 target_bw, ref_tone;
++
++	u32 target_pwr_ratios[2] = { 28606, 18468 };
++	u32 target_pwr_ratio, pwr_ratio, last_pwr_ratio = 0;
++
++	u16 start_rccal_ovr_val = 128;
++	u16 txlpf_rccal_lpc_ovr_val = 128;
++	u16 rxlpf_rccal_hpc_ovr_val = 159;
++
++	u16 orig_txlpf_rccal_lpc_ovr_val;
++	u16 orig_rxlpf_rccal_hpc_ovr_val;
++	u16 radio_addr_offset_rx;
++	u16 radio_addr_offset_tx;
++	u16 orig_dcBypass;
++	u16 orig_RxStrnFilt40Num[6];
++	u16 orig_RxStrnFilt40Den[4];
++	u16 orig_rfctrloverride[2];
++	u16 orig_rfctrlauxreg[2];
++	u16 orig_rfctrlrssiothers;
++	u16 tx_lpf_bw = 4;
++
++	u16 rx_lpf_bw, rx_lpf_bws[2] = { 2, 4 };
++	u16 lpf_hpc = 7, hpvga_hpc = 7;
++
++	s8 rccal_stepsize;
++	u16 rccal_val, last_rccal_val = 0, best_rccal_val = 0;
++	u32 ref_iq_vals = 0, target_iq_vals = 0;
++	u16 num_samps, log_num_samps = 10;
++	struct phy_iq_est est[PHY_CORE_MAX];
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7))
++		return 0;
++
++	num_samps = (1 << log_num_samps);
++
++	if (CHSPEC_IS40(pi->radio_chanspec)) {
++		target_bw = target_bws[1];
++		target_pwr_ratio = target_pwr_ratios[1];
++		ref_tone = ref_tones[1];
++		rx_lpf_bw = rx_lpf_bws[1];
++	} else {
++		target_bw = target_bws[0];
++		target_pwr_ratio = target_pwr_ratios[0];
++		ref_tone = ref_tones[0];
++		rx_lpf_bw = rx_lpf_bws[0];
++	}
++
++	if (core_idx == 0) {
++		radio_addr_offset_rx = RADIO_2056_RX0;
++		radio_addr_offset_tx =
++			(loopback_type == 0) ? RADIO_2056_TX0 : RADIO_2056_TX1;
++	} else {
++		radio_addr_offset_rx = RADIO_2056_RX1;
++		radio_addr_offset_tx =
++			(loopback_type == 0) ? RADIO_2056_TX1 : RADIO_2056_TX0;
++	}
++
++	orig_txlpf_rccal_lpc_ovr_val =
++		read_radio_reg(pi,
++			       (RADIO_2056_TX_TXLPF_RCCAL |
++				radio_addr_offset_tx));
++	orig_rxlpf_rccal_hpc_ovr_val =
++		read_radio_reg(pi,
++			       (RADIO_2056_RX_RXLPF_RCCAL_HPC |
++				radio_addr_offset_rx));
++
++	orig_dcBypass = ((read_phy_reg(pi, 0x48) >> 8) & 1);
++
++	orig_RxStrnFilt40Num[0] = read_phy_reg(pi, 0x267);
++	orig_RxStrnFilt40Num[1] = read_phy_reg(pi, 0x268);
++	orig_RxStrnFilt40Num[2] = read_phy_reg(pi, 0x269);
++	orig_RxStrnFilt40Den[0] = read_phy_reg(pi, 0x26a);
++	orig_RxStrnFilt40Den[1] = read_phy_reg(pi, 0x26b);
++	orig_RxStrnFilt40Num[3] = read_phy_reg(pi, 0x26c);
++	orig_RxStrnFilt40Num[4] = read_phy_reg(pi, 0x26d);
++	orig_RxStrnFilt40Num[5] = read_phy_reg(pi, 0x26e);
++	orig_RxStrnFilt40Den[2] = read_phy_reg(pi, 0x26f);
++	orig_RxStrnFilt40Den[3] = read_phy_reg(pi, 0x270);
++
++	orig_rfctrloverride[0] = read_phy_reg(pi, 0xe7);
++	orig_rfctrloverride[1] = read_phy_reg(pi, 0xec);
++	orig_rfctrlauxreg[0] = read_phy_reg(pi, 0xf8);
++	orig_rfctrlauxreg[1] = read_phy_reg(pi, 0xfa);
++	orig_rfctrlrssiothers = read_phy_reg(pi, (core_idx == 0) ? 0x7a : 0x7d);
++
++	write_radio_reg(pi, (RADIO_2056_TX_TXLPF_RCCAL | radio_addr_offset_tx),
++			txlpf_rccal_lpc_ovr_val);
++
++	write_radio_reg(pi,
++			(RADIO_2056_RX_RXLPF_RCCAL_HPC | radio_addr_offset_rx),
++			rxlpf_rccal_hpc_ovr_val);
++
++	mod_phy_reg(pi, 0x48, (0x1 << 8), (0x1 << 8));
++
++	write_phy_reg(pi, 0x267, 0x02d4);
++	write_phy_reg(pi, 0x268, 0x0000);
++	write_phy_reg(pi, 0x269, 0x0000);
++	write_phy_reg(pi, 0x26a, 0x0000);
++	write_phy_reg(pi, 0x26b, 0x0000);
++	write_phy_reg(pi, 0x26c, 0x02d4);
++	write_phy_reg(pi, 0x26d, 0x0000);
++	write_phy_reg(pi, 0x26e, 0x0000);
++	write_phy_reg(pi, 0x26f, 0x0000);
++	write_phy_reg(pi, 0x270, 0x0000);
++
++	or_phy_reg(pi, (core_idx == 0) ? 0xe7 : 0xec, (0x1 << 8));
++	or_phy_reg(pi, (core_idx == 0) ? 0xec : 0xe7, (0x1 << 15));
++	or_phy_reg(pi, (core_idx == 0) ? 0xe7 : 0xec, (0x1 << 9));
++	or_phy_reg(pi, (core_idx == 0) ? 0xe7 : 0xec, (0x1 << 10));
++
++	mod_phy_reg(pi, (core_idx == 0) ? 0xfa : 0xf8,
++		    (0x7 << 10), (tx_lpf_bw << 10));
++	mod_phy_reg(pi, (core_idx == 0) ? 0xf8 : 0xfa,
++		    (0x7 << 0), (hpvga_hpc << 0));
++	mod_phy_reg(pi, (core_idx == 0) ? 0xf8 : 0xfa,
++		    (0x7 << 4), (lpf_hpc << 4));
++	mod_phy_reg(pi, (core_idx == 0) ? 0x7a : 0x7d,
++		    (0x7 << 8), (rx_lpf_bw << 8));
++
++	rccal_stepsize = 16;
++	rccal_val = start_rccal_ovr_val + rccal_stepsize;
++
++	while (rccal_stepsize >= 0) {
++		write_radio_reg(pi,
++				(RADIO_2056_RX_RXLPF_RCCAL_LPC |
++				 radio_addr_offset_rx), rccal_val);
++
++		if (rccal_stepsize == 16) {
++
++			wlc_phy_tx_tone_nphy(pi, ref_tone, NPHY_RXCAL_TONEAMP,
++					     0, 1, false);
++			udelay(2);
++
++			wlc_phy_rx_iq_est_nphy(pi, est, num_samps, 32, 0);
++
++			if (core_idx == 0)
++				ref_iq_vals =
++					max_t(u32, (est[0].i_pwr +
++						    est[0].q_pwr) >>
++					      (log_num_samps + 1),
++					      1);
++			else
++				ref_iq_vals =
++					max_t(u32, (est[1].i_pwr +
++						    est[1].q_pwr) >>
++					      (log_num_samps + 1),
++					      1);
++
++			wlc_phy_tx_tone_nphy(pi, target_bw, NPHY_RXCAL_TONEAMP,
++					     0, 1, false);
++			udelay(2);
++		}
++
++		wlc_phy_rx_iq_est_nphy(pi, est, num_samps, 32, 0);
++
++		if (core_idx == 0)
++			target_iq_vals = (est[0].i_pwr + est[0].q_pwr) >>
++					 (log_num_samps + 1);
++		else
++			target_iq_vals =
++				(est[1].i_pwr +
++				 est[1].q_pwr) >> (log_num_samps + 1);
++
++		pwr_ratio = (uint) ((target_iq_vals << 16) / ref_iq_vals);
++
++		if (rccal_stepsize == 0)
++			rccal_stepsize--;
++		else if (rccal_stepsize == 1) {
++			last_rccal_val = rccal_val;
++			rccal_val += (pwr_ratio > target_pwr_ratio) ? 1 : -1;
++			last_pwr_ratio = pwr_ratio;
++			rccal_stepsize--;
++		} else {
++			rccal_stepsize = (rccal_stepsize >> 1);
++			rccal_val += ((pwr_ratio > target_pwr_ratio) ?
++				      rccal_stepsize : (-rccal_stepsize));
++		}
++
++		if (rccal_stepsize == -1) {
++			best_rccal_val =
++				(abs((int)last_pwr_ratio -
++				     (int)target_pwr_ratio) <
++				 abs((int)pwr_ratio -
++				     (int)target_pwr_ratio)) ? last_rccal_val :
++				rccal_val;
++
++			if (CHSPEC_IS40(pi->radio_chanspec)) {
++				if ((best_rccal_val > 140)
++				    || (best_rccal_val < 135))
++					best_rccal_val = 138;
++			} else {
++				if ((best_rccal_val > 142)
++				    || (best_rccal_val < 137))
++					best_rccal_val = 140;
++			}
++
++			write_radio_reg(pi,
++					(RADIO_2056_RX_RXLPF_RCCAL_LPC |
++					 radio_addr_offset_rx), best_rccal_val);
++		}
++	}
++
++	wlc_phy_stopplayback_nphy(pi);
++
++	write_radio_reg(pi, (RADIO_2056_TX_TXLPF_RCCAL | radio_addr_offset_tx),
++			orig_txlpf_rccal_lpc_ovr_val);
++	write_radio_reg(pi,
++			(RADIO_2056_RX_RXLPF_RCCAL_HPC | radio_addr_offset_rx),
++			orig_rxlpf_rccal_hpc_ovr_val);
++
++	mod_phy_reg(pi, 0x48, (0x1 << 8), (orig_dcBypass << 8));
++
++	write_phy_reg(pi, 0x267, orig_RxStrnFilt40Num[0]);
++	write_phy_reg(pi, 0x268, orig_RxStrnFilt40Num[1]);
++	write_phy_reg(pi, 0x269, orig_RxStrnFilt40Num[2]);
++	write_phy_reg(pi, 0x26a, orig_RxStrnFilt40Den[0]);
++	write_phy_reg(pi, 0x26b, orig_RxStrnFilt40Den[1]);
++	write_phy_reg(pi, 0x26c, orig_RxStrnFilt40Num[3]);
++	write_phy_reg(pi, 0x26d, orig_RxStrnFilt40Num[4]);
++	write_phy_reg(pi, 0x26e, orig_RxStrnFilt40Num[5]);
++	write_phy_reg(pi, 0x26f, orig_RxStrnFilt40Den[2]);
++	write_phy_reg(pi, 0x270, orig_RxStrnFilt40Den[3]);
++
++	write_phy_reg(pi, 0xe7, orig_rfctrloverride[0]);
++	write_phy_reg(pi, 0xec, orig_rfctrloverride[1]);
++	write_phy_reg(pi, 0xf8, orig_rfctrlauxreg[0]);
++	write_phy_reg(pi, 0xfa, orig_rfctrlauxreg[1]);
++	write_phy_reg(pi, (core_idx == 0) ? 0x7a : 0x7d, orig_rfctrlrssiothers);
++
++	pi->nphy_anarxlpf_adjusted = false;
++
++	return best_rccal_val - 0x80;
++}
++
++#define WAIT_FOR_SCOPE  4000
++static int wlc_phy_cal_rxiq_nphy_rev3(struct brcms_phy *pi,
++				      struct nphy_txgains target_gain,
++				      u8 cal_type, bool debug)
++{
++	u16 orig_BBConfig;
++	u8 core_no, rx_core;
++	u8 best_rccal[2];
++	u16 gain_save[2];
++	u16 cal_gain[2];
++	struct nphy_iqcal_params cal_params[2];
++	u8 rxcore_state;
++	s8 rxlpf_rccal_hpc, txlpf_rccal_lpc;
++	s8 txlpf_idac;
++	bool phyhang_avoid_state = false;
++	bool skip_rxiqcal = false;
++
++	orig_BBConfig = read_phy_reg(pi, 0x01);
++	mod_phy_reg(pi, 0x01, (0x1 << 15), 0);
++
++	wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 4)) {
++		phyhang_avoid_state = pi->phyhang_avoid;
++		pi->phyhang_avoid = false;
++	}
++
++	wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, gain_save);
++
++	for (core_no = 0; core_no <= 1; core_no++) {
++		wlc_phy_iqcal_gainparams_nphy(pi, core_no, target_gain,
++					      &cal_params[core_no]);
++		cal_gain[core_no] = cal_params[core_no].cal_gain;
++	}
++
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, cal_gain);
++
++	rxcore_state = wlc_phy_rxcore_getstate_nphy(
++		(struct brcms_phy_pub *) pi);
++
++	for (rx_core = 0; rx_core < pi->pubpi.phy_corenum; rx_core++) {
++
++		skip_rxiqcal =
++			((rxcore_state & (1 << rx_core)) == 0) ? true : false;
++
++		wlc_phy_rxcal_physetup_nphy(pi, rx_core);
++
++		wlc_phy_rxcal_radio_setup_nphy(pi, rx_core);
++
++		if ((!skip_rxiqcal) && ((cal_type == 0) || (cal_type == 2))) {
++
++			wlc_phy_rxcal_gainctrl_nphy(pi, rx_core, NULL, 0);
++
++			wlc_phy_tx_tone_nphy(pi,
++					     (CHSPEC_IS40(
++						      pi->radio_chanspec)) ?
++					     NPHY_RXCAL_TONEFREQ_40MHz :
++					     NPHY_RXCAL_TONEFREQ_20MHz,
++					     NPHY_RXCAL_TONEAMP, 0, cal_type,
++					     false);
++
++			if (debug)
++				mdelay(WAIT_FOR_SCOPE);
++
++			wlc_phy_calc_rx_iq_comp_nphy(pi, rx_core + 1);
++			wlc_phy_stopplayback_nphy(pi);
++		}
++
++		if (((cal_type == 1) || (cal_type == 2))
++		    && NREV_LT(pi->pubpi.phy_rev, 7)) {
++
++			if (rx_core == PHY_CORE_1) {
++
++				if (rxcore_state == 1)
++					wlc_phy_rxcore_setstate_nphy(
++						(struct brcms_phy_pub *) pi, 3);
++
++				wlc_phy_rxcal_gainctrl_nphy(pi, rx_core, NULL,
++							    1);
++
++				best_rccal[rx_core] =
++					wlc_phy_rc_sweep_nphy(pi, rx_core, 1);
++				pi->nphy_rccal_value = best_rccal[rx_core];
++
++				if (rxcore_state == 1)
++					wlc_phy_rxcore_setstate_nphy(
++						(struct brcms_phy_pub *) pi,
++						rxcore_state);
++			}
++		}
++
++		wlc_phy_rxcal_radio_cleanup_nphy(pi, rx_core);
++
++		wlc_phy_rxcal_phycleanup_nphy(pi, rx_core);
++		wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
++	}
++
++	if ((cal_type == 1) || (cal_type == 2)) {
++
++		best_rccal[0] = best_rccal[1];
++		write_radio_reg(pi,
++				(RADIO_2056_RX_RXLPF_RCCAL_LPC |
++				 RADIO_2056_RX0), (best_rccal[0] | 0x80));
++
++		for (rx_core = 0; rx_core < pi->pubpi.phy_corenum; rx_core++) {
++			rxlpf_rccal_hpc =
++				(((int)best_rccal[rx_core] - 12) >> 1) + 10;
++			txlpf_rccal_lpc = ((int)best_rccal[rx_core] - 12) + 10;
++
++			if (PHY_IPA(pi)) {
++				txlpf_rccal_lpc +=
++					(pi->bw == WL_CHANSPEC_BW_40) ? 24 : 12;
++				txlpf_idac = (pi->bw == WL_CHANSPEC_BW_40) ?
++					     0x0e : 0x13;
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, rx_core,
++						 TXLPF_IDAC_4, txlpf_idac);
++			}
++
++			rxlpf_rccal_hpc = max(min_t(u8, rxlpf_rccal_hpc, 31),
++					      0);
++			txlpf_rccal_lpc = max(min_t(u8, txlpf_rccal_lpc, 31),
++					      0);
++
++			write_radio_reg(pi, (RADIO_2056_RX_RXLPF_RCCAL_HPC |
++					     ((rx_core ==
++					       PHY_CORE_0) ? RADIO_2056_RX0 :
++					      RADIO_2056_RX1)),
++					(rxlpf_rccal_hpc | 0x80));
++
++			write_radio_reg(pi, (RADIO_2056_TX_TXLPF_RCCAL |
++					     ((rx_core ==
++					       PHY_CORE_0) ? RADIO_2056_TX0 :
++					      RADIO_2056_TX1)),
++					(txlpf_rccal_lpc | 0x80));
++		}
++	}
++
++	write_phy_reg(pi, 0x01, orig_BBConfig);
++
++	wlc_phy_resetcca_nphy(pi);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7))
++		wlc_phy_rfctrl_override_1tomany_nphy(
++			pi,
++			NPHY_REV7_RfctrlOverride_cmd_rxgain,
++			0, 0x3, 1);
++	else
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 12), 0, 0x3, 1);
++
++	wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
++
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16,
++				 gain_save);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 4))
++		pi->phyhang_avoid = phyhang_avoid_state;
++
++	wlc_phy_stay_in_carriersearch_nphy(pi, false);
++
++	return 0;
++}
++
++static int
++wlc_phy_cal_rxiq_nphy_rev2(struct brcms_phy *pi,
++			   struct nphy_txgains target_gain, bool debug)
++{
++	struct phy_iq_est est[PHY_CORE_MAX];
++	u8 core_num, rx_core, tx_core;
++	u16 lna_vals[] = { 0x3, 0x3, 0x1 };
++	u16 hpf1_vals[] = { 0x7, 0x2, 0x0 };
++	u16 hpf2_vals[] = { 0x2, 0x0, 0x0 };
++	s16 curr_hpf1, curr_hpf2, curr_hpf, curr_lna;
++	s16 desired_log2_pwr, actual_log2_pwr, hpf_change;
++	u16 orig_RfseqCoreActv, orig_AfectrlCore, orig_AfectrlOverride;
++	u16 orig_RfctrlIntcRx, orig_RfctrlIntcTx;
++	u16 num_samps;
++	u32 i_pwr, q_pwr, tot_pwr[3];
++	u8 gain_pass, use_hpf_num;
++	u16 mask, val1, val2;
++	u16 core_no;
++	u16 gain_save[2];
++	u16 cal_gain[2];
++	struct nphy_iqcal_params cal_params[2];
++	u8 phy_bw;
++	int bcmerror = 0;
++	bool first_playtone = true;
++
++	wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++	if (NREV_LT(pi->pubpi.phy_rev, 2))
++		wlc_phy_reapply_txcal_coeffs_nphy(pi);
++
++	wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, gain_save);
++
++	for (core_no = 0; core_no <= 1; core_no++) {
++		wlc_phy_iqcal_gainparams_nphy(pi, core_no, target_gain,
++					      &cal_params[core_no]);
++		cal_gain[core_no] = cal_params[core_no].cal_gain;
++	}
++
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, cal_gain);
++
++	num_samps = 1024;
++	desired_log2_pwr = 13;
++
++	for (core_num = 0; core_num < 2; core_num++) {
++
++		rx_core = core_num;
++		tx_core = 1 - core_num;
++
++		orig_RfseqCoreActv = read_phy_reg(pi, 0xa2);
++		orig_AfectrlCore = read_phy_reg(pi, (rx_core == PHY_CORE_0) ?
++						0xa6 : 0xa7);
++		orig_AfectrlOverride = read_phy_reg(pi, 0xa5);
++		orig_RfctrlIntcRx = read_phy_reg(pi, (rx_core == PHY_CORE_0) ?
++						 0x91 : 0x92);
++		orig_RfctrlIntcTx = read_phy_reg(pi, (tx_core == PHY_CORE_0) ?
++						 0x91 : 0x92);
++
++		mod_phy_reg(pi, 0xa2, (0xf << 12), (1 << tx_core) << 12);
++		mod_phy_reg(pi, 0xa2, (0xf << 0), (1 << tx_core) << 0);
++
++		or_phy_reg(pi, ((rx_core == PHY_CORE_0) ? 0xa6 : 0xa7),
++			   ((0x1 << 1) | (0x1 << 2)));
++		or_phy_reg(pi, 0xa5, ((0x1 << 1) | (0x1 << 2)));
++
++		if (((pi->nphy_rxcalparams) & 0xff000000))
++			write_phy_reg(pi,
++				      (rx_core == PHY_CORE_0) ? 0x91 : 0x92,
++				      (CHSPEC_IS5G(pi->radio_chanspec) ?
++					0x140 : 0x110));
++		else
++			write_phy_reg(pi,
++				      (rx_core == PHY_CORE_0) ? 0x91 : 0x92,
++				      (CHSPEC_IS5G(pi->radio_chanspec) ?
++				       0x180 : 0x120));
++
++		write_phy_reg(pi, (tx_core == PHY_CORE_0) ? 0x91 : 0x92,
++			      (CHSPEC_IS5G(pi->radio_chanspec) ? 0x148 :
++			       0x114));
++
++		mask = RADIO_2055_COUPLE_RX_MASK | RADIO_2055_COUPLE_TX_MASK;
++		if (rx_core == PHY_CORE_0) {
++			val1 = RADIO_2055_COUPLE_RX_MASK;
++			val2 = RADIO_2055_COUPLE_TX_MASK;
++		} else {
++			val1 = RADIO_2055_COUPLE_TX_MASK;
++			val2 = RADIO_2055_COUPLE_RX_MASK;
++		}
++
++		if ((pi->nphy_rxcalparams & 0x10000)) {
++			mod_radio_reg(pi, RADIO_2055_CORE1_GEN_SPARE2, mask,
++				      val1);
++			mod_radio_reg(pi, RADIO_2055_CORE2_GEN_SPARE2, mask,
++				      val2);
++		}
++
++		for (gain_pass = 0; gain_pass < 4; gain_pass++) {
++
++			if (debug)
++				mdelay(WAIT_FOR_SCOPE);
++
++			if (gain_pass < 3) {
++				curr_lna = lna_vals[gain_pass];
++				curr_hpf1 = hpf1_vals[gain_pass];
++				curr_hpf2 = hpf2_vals[gain_pass];
++			} else {
++
++				if (tot_pwr[1] > 10000) {
++					curr_lna = lna_vals[2];
++					curr_hpf1 = hpf1_vals[2];
++					curr_hpf2 = hpf2_vals[2];
++					use_hpf_num = 1;
++					curr_hpf = curr_hpf1;
++					actual_log2_pwr =
++						wlc_phy_nbits(tot_pwr[2]);
++				} else {
++					if (tot_pwr[0] > 10000) {
++						curr_lna = lna_vals[1];
++						curr_hpf1 = hpf1_vals[1];
++						curr_hpf2 = hpf2_vals[1];
++						use_hpf_num = 1;
++						curr_hpf = curr_hpf1;
++						actual_log2_pwr =
++							wlc_phy_nbits(
++								tot_pwr[1]);
++					} else {
++						curr_lna = lna_vals[0];
++						curr_hpf1 = hpf1_vals[0];
++						curr_hpf2 = hpf2_vals[0];
++						use_hpf_num = 2;
++						curr_hpf = curr_hpf2;
++						actual_log2_pwr =
++							wlc_phy_nbits(
++								tot_pwr[0]);
++					}
++				}
++
++				hpf_change = desired_log2_pwr - actual_log2_pwr;
++				curr_hpf += hpf_change;
++				curr_hpf = max(min_t(u16, curr_hpf, 10), 0);
++				if (use_hpf_num == 1)
++					curr_hpf1 = curr_hpf;
++				else
++					curr_hpf2 = curr_hpf;
++			}
++
++			wlc_phy_rfctrl_override_nphy(pi, (0x1 << 10),
++						     ((curr_hpf2 << 8) |
++						      (curr_hpf1 << 4) |
++						      (curr_lna << 2)), 0x3, 0);
++			wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
++
++			wlc_phy_stopplayback_nphy(pi);
++
++			if (first_playtone) {
++				bcmerror = wlc_phy_tx_tone_nphy(pi, 4000,
++						(u16) (pi->nphy_rxcalparams &
++						       0xffff), 0, 0, true);
++				first_playtone = false;
++			} else {
++				phy_bw = (CHSPEC_IS40(pi->radio_chanspec)) ?
++					  40 : 20;
++				wlc_phy_runsamples_nphy(pi, phy_bw * 8, 0xffff,
++							0, 0, 0, true);
++			}
++
++			if (bcmerror == 0) {
++				if (gain_pass < 3) {
++
++					wlc_phy_rx_iq_est_nphy(pi, est,
++							       num_samps, 32,
++							       0);
++					i_pwr =	(est[rx_core].i_pwr +
++						 num_samps / 2) / num_samps;
++					q_pwr =	(est[rx_core].q_pwr +
++						 num_samps / 2) / num_samps;
++					tot_pwr[gain_pass] = i_pwr + q_pwr;
++				} else {
++
++					wlc_phy_calc_rx_iq_comp_nphy(pi,
++								     (1 <<
++								      rx_core));
++				}
++
++				wlc_phy_stopplayback_nphy(pi);
++			}
++
++			if (bcmerror != 0)
++				break;
++		}
++
++		and_radio_reg(pi, RADIO_2055_CORE1_GEN_SPARE2, ~mask);
++		and_radio_reg(pi, RADIO_2055_CORE2_GEN_SPARE2, ~mask);
++
++		write_phy_reg(pi, (tx_core == PHY_CORE_0) ? 0x91 :
++			      0x92, orig_RfctrlIntcTx);
++		write_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0x91 :
++			      0x92, orig_RfctrlIntcRx);
++		write_phy_reg(pi, 0xa5, orig_AfectrlOverride);
++		write_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0xa6 :
++			      0xa7, orig_AfectrlCore);
++		write_phy_reg(pi, 0xa2, orig_RfseqCoreActv);
++
++		if (bcmerror != 0)
++			break;
++	}
++
++	wlc_phy_rfctrl_override_nphy(pi, (0x1 << 10), 0, 0x3, 1);
++	wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
++
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16,
++				 gain_save);
++
++	wlc_phy_stay_in_carriersearch_nphy(pi, false);
++
++	return bcmerror;
++}
++
++int
++wlc_phy_cal_rxiq_nphy(struct brcms_phy *pi, struct nphy_txgains target_gain,
++		      u8 cal_type, bool debug)
++{
++	if (NREV_GE(pi->pubpi.phy_rev, 7))
++		cal_type = 0;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3))
++		return wlc_phy_cal_rxiq_nphy_rev3(pi, target_gain, cal_type,
++						  debug);
++	else
++		return wlc_phy_cal_rxiq_nphy_rev2(pi, target_gain, debug);
++}
++
++void wlc_phy_txpwr_fixpower_nphy(struct brcms_phy *pi)
++{
++	uint core;
++	u32 txgain;
++	u16 rad_gain, dac_gain, bbmult, m1m2;
++	u8 txpi[2], chan_freq_range;
++	s32 rfpwr_offset;
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++	if (pi->sh->sromrev < 4) {
++		txpi[0] = txpi[1] = 72;
++	} else {
++
++		chan_freq_range = wlc_phy_get_chan_freq_range_nphy(pi, 0);
++		switch (chan_freq_range) {
++		case WL_CHAN_FREQ_RANGE_2G:
++		case WL_CHAN_FREQ_RANGE_5GL:
++		case WL_CHAN_FREQ_RANGE_5GM:
++		case WL_CHAN_FREQ_RANGE_5GH:
++			txpi[0] = 0;
++			txpi[1] = 0;
++			break;
++		default:
++			txpi[0] = txpi[1] = 91;
++			break;
++		}
++	}
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7))
++		txpi[0] = txpi[1] = 30;
++	else if (NREV_GE(pi->pubpi.phy_rev, 3))
++		txpi[0] = txpi[1] = 40;
++
++	if (NREV_LT(pi->pubpi.phy_rev, 7)) {
++
++		if ((txpi[0] < 40) || (txpi[0] > 100) ||
++		    (txpi[1] < 40) || (txpi[1] > 100))
++			txpi[0] = txpi[1] = 91;
++	}
++
++	pi->nphy_txpwrindex[PHY_CORE_0].index_internal = txpi[0];
++	pi->nphy_txpwrindex[PHY_CORE_1].index_internal = txpi[1];
++	pi->nphy_txpwrindex[PHY_CORE_0].index_internal_save = txpi[0];
++	pi->nphy_txpwrindex[PHY_CORE_1].index_internal_save = txpi[1];
++
++	for (core = 0; core < pi->pubpi.phy_corenum; core++) {
++		uint phyrev = pi->pubpi.phy_rev;
++
++		if (NREV_GE(phyrev, 3)) {
++			if (PHY_IPA(pi)) {
++				u32 *tx_gaintbl =
++					wlc_phy_get_ipa_gaintbl_nphy(pi);
++				txgain = tx_gaintbl[txpi[core]];
++			} else {
++				if (CHSPEC_IS5G(pi->radio_chanspec)) {
++					if (NREV_IS(phyrev, 3)) {
++						txgain =
++						      nphy_tpc_5GHz_txgain_rev3
++								   [txpi[core]];
++					} else if (NREV_IS(phyrev, 4)) {
++						txgain = (
++						  pi->srom_fem5g.extpagain ==
++						  3) ?
++						  nphy_tpc_5GHz_txgain_HiPwrEPA
++						 [txpi[core]] :
++						 nphy_tpc_5GHz_txgain_rev4
++						 [txpi[core]];
++					} else {
++						txgain =
++						      nphy_tpc_5GHz_txgain_rev5
++								   [txpi[core]];
++					}
++				} else {
++					if (NREV_GE(phyrev, 5) &&
++					    (pi->srom_fem2g.extpagain == 3)) {
++						txgain =
++							nphy_tpc_txgain_HiPwrEPA
++							[txpi[core]];
++					} else {
++						txgain = nphy_tpc_txgain_rev3
++							 [txpi[core]];
++					}
++				}
++			}
++		} else {
++			txgain = nphy_tpc_txgain[txpi[core]];
++		}
++
++		if (NREV_GE(phyrev, 3))
++			rad_gain = (txgain >> 16) & ((1 << (32 - 16 + 1)) - 1);
++		else
++			rad_gain = (txgain >> 16) & ((1 << (28 - 16 + 1)) - 1);
++
++		if (NREV_GE(phyrev, 7))
++			dac_gain = (txgain >> 8) & ((1 << (10 - 8 + 1)) - 1);
++		else
++			dac_gain = (txgain >> 8) & ((1 << (13 - 8 + 1)) - 1);
++
++		bbmult = (txgain >> 0) & ((1 << (7 - 0 + 1)) - 1);
++
++		if (NREV_GE(phyrev, 3))
++			mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0x8f :
++					 0xa5), (0x1 << 8), (0x1 << 8));
++		else
++			mod_phy_reg(pi, 0xa5, (0x1 << 14), (0x1 << 14));
++
++		write_phy_reg(pi, (core == PHY_CORE_0) ? 0xaa : 0xab, dac_gain);
++
++		wlc_phy_table_write_nphy(pi, 7, 1, (0x110 + core), 16,
++					 &rad_gain);
++
++		wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &m1m2);
++		m1m2 &= ((core == PHY_CORE_0) ? 0x00ff : 0xff00);
++		m1m2 |= ((core == PHY_CORE_0) ? (bbmult << 8) : (bbmult << 0));
++		wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &m1m2);
++
++		if (PHY_IPA(pi)) {
++			wlc_phy_table_read_nphy(pi,
++						(core ==
++						 PHY_CORE_0 ?
++						 NPHY_TBL_ID_CORE1TXPWRCTL :
++						 NPHY_TBL_ID_CORE2TXPWRCTL), 1,
++						576 + txpi[core], 32,
++						&rfpwr_offset);
++
++			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
++				    0x29b, (0x1ff << 4),
++				    ((s16) rfpwr_offset) << 4);
++
++			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
++				    0x29b, (0x1 << 2), (1) << 2);
++
++		}
++	}
++
++	and_phy_reg(pi, 0xbf, (u16) (~(0x1f << 0)));
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, false);
++}
++
++static void
++wlc_phy_txpwr_nphy_srom_convert(u8 *srom_max, u16 *pwr_offset,
++				u8 tmp_max_pwr, u8 rate_start,
++				u8 rate_end)
++{
++	u8 rate;
++	u8 word_num, nibble_num;
++	u8 tmp_nibble;
++
++	for (rate = rate_start; rate <= rate_end; rate++) {
++		word_num = (rate - rate_start) >> 2;
++		nibble_num = (rate - rate_start) & 0x3;
++		tmp_nibble = (pwr_offset[word_num] >> 4 * nibble_num) & 0xf;
++
++		srom_max[rate] = tmp_max_pwr - 2 * tmp_nibble;
++	}
++}
++
++static void
++wlc_phy_txpwr_nphy_po_apply(u8 *srom_max, u8 pwr_offset,
++			    u8 rate_start, u8 rate_end)
++{
++	u8 rate;
++
++	for (rate = rate_start; rate <= rate_end; rate++)
++		srom_max[rate] -= 2 * pwr_offset;
++}
++
++void
++wlc_phy_ofdm_to_mcs_powers_nphy(u8 *power, u8 rate_mcs_start,
++				u8 rate_mcs_end, u8 rate_ofdm_start)
++{
++	u8 rate1, rate2;
++
++	rate2 = rate_ofdm_start;
++	for (rate1 = rate_mcs_start; rate1 <= rate_mcs_end - 1; rate1++) {
++		power[rate1] = power[rate2];
++		rate2 += (rate1 == rate_mcs_start) ? 2 : 1;
++	}
++	power[rate_mcs_end] = power[rate_mcs_end - 1];
++}
++
++void
++wlc_phy_mcs_to_ofdm_powers_nphy(u8 *power, u8 rate_ofdm_start,
++				u8 rate_ofdm_end, u8 rate_mcs_start)
++{
++	u8 rate1, rate2;
++
++	for (rate1 = rate_ofdm_start, rate2 = rate_mcs_start;
++	     rate1 <= rate_ofdm_end; rate1++, rate2++) {
++		power[rate1] = power[rate2];
++		if (rate1 == rate_ofdm_start)
++			power[++rate1] = power[rate2];
++	}
++}
++
++void wlc_phy_txpwr_apply_nphy(struct brcms_phy *pi)
++{
++	uint rate1, rate2, band_num;
++	u8 tmp_bw40po = 0, tmp_cddpo = 0, tmp_stbcpo = 0;
++	u8 tmp_max_pwr = 0;
++	u16 pwr_offsets1[2], *pwr_offsets2 = NULL;
++	u8 *tx_srom_max_rate = NULL;
++
++	for (band_num = 0; band_num < (CH_2G_GROUP + CH_5G_GROUP);
++	     band_num++) {
++		switch (band_num) {
++		case 0:
++
++			tmp_max_pwr = min(pi->nphy_pwrctrl_info[0].max_pwr_2g,
++					  pi->nphy_pwrctrl_info[1].max_pwr_2g);
++
++			pwr_offsets1[0] = pi->cck2gpo;
++			wlc_phy_txpwr_nphy_srom_convert(pi->tx_srom_max_rate_2g,
++							pwr_offsets1,
++							tmp_max_pwr,
++							TXP_FIRST_CCK,
++							TXP_LAST_CCK);
++
++			pwr_offsets1[0] = (u16) (pi->ofdm2gpo & 0xffff);
++			pwr_offsets1[1] =
++				(u16) (pi->ofdm2gpo >> 16) & 0xffff;
++
++			pwr_offsets2 = pi->mcs2gpo;
++
++			tmp_cddpo = pi->cdd2gpo;
++			tmp_stbcpo = pi->stbc2gpo;
++			tmp_bw40po = pi->bw402gpo;
++
++			tx_srom_max_rate = pi->tx_srom_max_rate_2g;
++			break;
++		case 1:
++
++			tmp_max_pwr = min(pi->nphy_pwrctrl_info[0].max_pwr_5gm,
++					  pi->nphy_pwrctrl_info[1].max_pwr_5gm);
++
++			pwr_offsets1[0] = (u16) (pi->ofdm5gpo & 0xffff);
++			pwr_offsets1[1] =
++				(u16) (pi->ofdm5gpo >> 16) & 0xffff;
++
++			pwr_offsets2 = pi->mcs5gpo;
++
++			tmp_cddpo = pi->cdd5gpo;
++			tmp_stbcpo = pi->stbc5gpo;
++			tmp_bw40po = pi->bw405gpo;
++
++			tx_srom_max_rate = pi->tx_srom_max_rate_5g_mid;
++			break;
++		case 2:
++
++			tmp_max_pwr = min(pi->nphy_pwrctrl_info[0].max_pwr_5gl,
++					  pi->nphy_pwrctrl_info[1].max_pwr_5gl);
++
++			pwr_offsets1[0] = (u16) (pi->ofdm5glpo & 0xffff);
++			pwr_offsets1[1] =
++				(u16) (pi->ofdm5glpo >> 16) & 0xffff;
++
++			pwr_offsets2 = pi->mcs5glpo;
++
++			tmp_cddpo = pi->cdd5glpo;
++			tmp_stbcpo = pi->stbc5glpo;
++			tmp_bw40po = pi->bw405glpo;
++
++			tx_srom_max_rate = pi->tx_srom_max_rate_5g_low;
++			break;
++		case 3:
++
++			tmp_max_pwr = min(pi->nphy_pwrctrl_info[0].max_pwr_5gh,
++					  pi->nphy_pwrctrl_info[1].max_pwr_5gh);
++
++			pwr_offsets1[0] = (u16) (pi->ofdm5ghpo & 0xffff);
++			pwr_offsets1[1] =
++				(u16) (pi->ofdm5ghpo >> 16) & 0xffff;
++
++			pwr_offsets2 = pi->mcs5ghpo;
++
++			tmp_cddpo = pi->cdd5ghpo;
++			tmp_stbcpo = pi->stbc5ghpo;
++			tmp_bw40po = pi->bw405ghpo;
++
++			tx_srom_max_rate = pi->tx_srom_max_rate_5g_hi;
++			break;
++		}
++
++		wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate, pwr_offsets1,
++						tmp_max_pwr, TXP_FIRST_OFDM,
++						TXP_LAST_OFDM);
++
++		wlc_phy_ofdm_to_mcs_powers_nphy(tx_srom_max_rate,
++						TXP_FIRST_MCS_20_SISO,
++						TXP_LAST_MCS_20_SISO,
++						TXP_FIRST_OFDM);
++
++		wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate, pwr_offsets2,
++						tmp_max_pwr,
++						TXP_FIRST_MCS_20_CDD,
++						TXP_LAST_MCS_20_CDD);
++
++		if (NREV_GE(pi->pubpi.phy_rev, 3))
++			wlc_phy_txpwr_nphy_po_apply(tx_srom_max_rate, tmp_cddpo,
++						    TXP_FIRST_MCS_20_CDD,
++						    TXP_LAST_MCS_20_CDD);
++
++		wlc_phy_mcs_to_ofdm_powers_nphy(tx_srom_max_rate,
++						TXP_FIRST_OFDM_20_CDD,
++						TXP_LAST_OFDM_20_CDD,
++						TXP_FIRST_MCS_20_CDD);
++
++		wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate, pwr_offsets2,
++						tmp_max_pwr,
++						TXP_FIRST_MCS_20_STBC,
++						TXP_LAST_MCS_20_STBC);
++
++		if (NREV_GE(pi->pubpi.phy_rev, 3))
++			wlc_phy_txpwr_nphy_po_apply(tx_srom_max_rate,
++						    tmp_stbcpo,
++						    TXP_FIRST_MCS_20_STBC,
++						    TXP_LAST_MCS_20_STBC);
++
++		wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate,
++						&pwr_offsets2[2], tmp_max_pwr,
++						TXP_FIRST_MCS_20_SDM,
++						TXP_LAST_MCS_20_SDM);
++
++		if (NPHY_IS_SROM_REINTERPRET) {
++
++			wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate,
++							&pwr_offsets2[4],
++							tmp_max_pwr,
++							TXP_FIRST_MCS_40_SISO,
++							TXP_LAST_MCS_40_SISO);
++
++			wlc_phy_mcs_to_ofdm_powers_nphy(tx_srom_max_rate,
++							TXP_FIRST_OFDM_40_SISO,
++							TXP_LAST_OFDM_40_SISO,
++							TXP_FIRST_MCS_40_SISO);
++
++			wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate,
++							&pwr_offsets2[4],
++							tmp_max_pwr,
++							TXP_FIRST_MCS_40_CDD,
++							TXP_LAST_MCS_40_CDD);
++
++			wlc_phy_txpwr_nphy_po_apply(tx_srom_max_rate, tmp_cddpo,
++						    TXP_FIRST_MCS_40_CDD,
++						    TXP_LAST_MCS_40_CDD);
++
++			wlc_phy_mcs_to_ofdm_powers_nphy(tx_srom_max_rate,
++							TXP_FIRST_OFDM_40_CDD,
++							TXP_LAST_OFDM_40_CDD,
++							TXP_FIRST_MCS_40_CDD);
++
++			wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate,
++							&pwr_offsets2[4],
++							tmp_max_pwr,
++							TXP_FIRST_MCS_40_STBC,
++							TXP_LAST_MCS_40_STBC);
++
++			wlc_phy_txpwr_nphy_po_apply(tx_srom_max_rate,
++						    tmp_stbcpo,
++						    TXP_FIRST_MCS_40_STBC,
++						    TXP_LAST_MCS_40_STBC);
++
++			wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate,
++							&pwr_offsets2[6],
++							tmp_max_pwr,
++							TXP_FIRST_MCS_40_SDM,
++							TXP_LAST_MCS_40_SDM);
++		} else {
++
++			for (rate1 = TXP_FIRST_OFDM_40_SISO, rate2 =
++				     TXP_FIRST_OFDM;
++			     rate1 <= TXP_LAST_MCS_40_SDM;
++			     rate1++, rate2++)
++				tx_srom_max_rate[rate1] =
++					tx_srom_max_rate[rate2];
++		}
++
++		if (NREV_GE(pi->pubpi.phy_rev, 3))
++			wlc_phy_txpwr_nphy_po_apply(tx_srom_max_rate,
++						    tmp_bw40po,
++						    TXP_FIRST_OFDM_40_SISO,
++						    TXP_LAST_MCS_40_SDM);
++
++		tx_srom_max_rate[TXP_MCS_32] =
++			tx_srom_max_rate[TXP_FIRST_MCS_40_CDD];
++	}
++
++	return;
++}
++
++void wlc_phy_txpower_recalc_target_nphy(struct brcms_phy *pi)
++{
++	u8 tx_pwr_ctrl_state;
++	wlc_phy_txpwr_limit_to_tbl_nphy(pi);
++	wlc_phy_txpwrctrl_pwr_setup_nphy(pi);
++
++	tx_pwr_ctrl_state = pi->nphy_txpwrctrl;
++
++	if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12)) {
++		wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, MCTL_PHYLOCK);
++		(void)bcma_read32(pi->d11core, D11REGOFFS(maccontrol));
++		udelay(1);
++	}
++
++	wlc_phy_txpwrctrl_enable_nphy(pi, tx_pwr_ctrl_state);
++
++	if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12))
++		wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, 0);
++}
++
++static bool wlc_phy_txpwr_ison_nphy(struct brcms_phy *pi)
++{
++	return read_phy_reg((pi), 0x1e7) & ((0x1 << 15) |
++					    (0x1 << 14) | (0x1 << 13));
++}
++
++u16 wlc_phy_txpwr_idx_get_nphy(struct brcms_phy *pi)
++{
++	u16 tmp;
++	u16 pwr_idx[2];
++
++	if (wlc_phy_txpwr_ison_nphy(pi)) {
++		pwr_idx[0] = wlc_phy_txpwr_idx_cur_get_nphy(pi, PHY_CORE_0);
++		pwr_idx[1] = wlc_phy_txpwr_idx_cur_get_nphy(pi, PHY_CORE_1);
++
++		tmp = (pwr_idx[0] << 8) | pwr_idx[1];
++	} else {
++		tmp = ((pi->nphy_txpwrindex[PHY_CORE_0].index_internal & 0xff)
++			<< 8) |
++			(pi->nphy_txpwrindex[PHY_CORE_1].index_internal & 0xff);
++	}
++
++	return tmp;
++}
++
++void wlc_phy_txpwr_papd_cal_nphy(struct brcms_phy *pi)
++{
++	if (PHY_IPA(pi)
++	    && (pi->nphy_force_papd_cal
++		|| (wlc_phy_txpwr_ison_nphy(pi)
++		    &&
++		    (((u32)
++		      abs(wlc_phy_txpwr_idx_cur_get_nphy(pi, 0) -
++			  pi->nphy_papd_tx_gain_at_last_cal[0]) >= 4)
++		     || ((u32)
++			 abs(wlc_phy_txpwr_idx_cur_get_nphy(pi, 1) -
++			     pi->nphy_papd_tx_gain_at_last_cal[1]) >= 4)))))
++		wlc_phy_a4(pi, true);
++}
++
++void wlc_phy_txpwrctrl_enable_nphy(struct brcms_phy *pi, u8 ctrl_type)
++{
++	u16 mask = 0, val = 0, ishw = 0;
++	u8 ctr;
++	uint core;
++	u32 tbl_offset;
++	u32 tbl_len;
++	u16 regval[84];
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++	switch (ctrl_type) {
++	case PHY_TPC_HW_OFF:
++	case PHY_TPC_HW_ON:
++		pi->nphy_txpwrctrl = ctrl_type;
++		break;
++	default:
++		break;
++	}
++
++	if (ctrl_type == PHY_TPC_HW_OFF) {
++		if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++
++			if (wlc_phy_txpwr_ison_nphy(pi)) {
++				for (core = 0; core < pi->pubpi.phy_corenum;
++				     core++)
++					pi->nphy_txpwr_idx[core] =
++						wlc_phy_txpwr_idx_cur_get_nphy(
++							pi,
++							(u8) core);
++			}
++
++		}
++
++		tbl_len = 84;
++		tbl_offset = 64;
++		for (ctr = 0; ctr < tbl_len; ctr++)
++			regval[ctr] = 0;
++		wlc_phy_table_write_nphy(pi, 26, tbl_len, tbl_offset, 16,
++					 regval);
++		wlc_phy_table_write_nphy(pi, 27, tbl_len, tbl_offset, 16,
++					 regval);
++
++		if (NREV_GE(pi->pubpi.phy_rev, 3))
++			and_phy_reg(pi, 0x1e7,
++				    (u16) (~((0x1 << 15) |
++					     (0x1 << 14) | (0x1 << 13))));
++		else
++			and_phy_reg(pi, 0x1e7,
++				    (u16) (~((0x1 << 14) | (0x1 << 13))));
++
++		if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++			or_phy_reg(pi, 0x8f, (0x1 << 8));
++			or_phy_reg(pi, 0xa5, (0x1 << 8));
++		} else {
++			or_phy_reg(pi, 0xa5, (0x1 << 14));
++		}
++
++		if (NREV_IS(pi->pubpi.phy_rev, 2))
++			mod_phy_reg(pi, 0xdc, 0x00ff, 0x53);
++		else if (NREV_LT(pi->pubpi.phy_rev, 2))
++			mod_phy_reg(pi, 0xdc, 0x00ff, 0x5a);
++
++		if (NREV_LT(pi->pubpi.phy_rev, 2) &&
++		    pi->bw == WL_CHANSPEC_BW_40)
++			wlapi_bmac_mhf(pi->sh->physhim, MHF1, MHF1_IQSWAP_WAR,
++				       MHF1_IQSWAP_WAR, BRCM_BAND_ALL);
++
++	} else {
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE1TXPWRCTL, 84, 64,
++					 8, pi->adj_pwr_tbl_nphy);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE2TXPWRCTL, 84, 64,
++					 8, pi->adj_pwr_tbl_nphy);
++
++		ishw = (ctrl_type == PHY_TPC_HW_ON) ? 0x1 : 0x0;
++		mask = (0x1 << 14) | (0x1 << 13);
++		val = (ishw << 14) | (ishw << 13);
++
++		if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++			mask |= (0x1 << 15);
++			val |= (ishw << 15);
++		}
++
++		mod_phy_reg(pi, 0x1e7, mask, val);
++
++		if (CHSPEC_IS5G(pi->radio_chanspec)) {
++			if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++				mod_phy_reg(pi, 0x1e7, (0x7f << 0), 0x32);
++				mod_phy_reg(pi, 0x222, (0xff << 0), 0x32);
++			} else {
++				mod_phy_reg(pi, 0x1e7, (0x7f << 0), 0x64);
++				if (NREV_GT(pi->pubpi.phy_rev, 1))
++					mod_phy_reg(pi, 0x222,
++						    (0xff << 0), 0x64);
++			}
++		}
++
++		if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++			if ((pi->nphy_txpwr_idx[0] != 128)
++			    && (pi->nphy_txpwr_idx[1] != 128))
++				wlc_phy_txpwr_idx_cur_set_nphy(pi,
++							       pi->
++							       nphy_txpwr_idx
++							       [0],
++							       pi->
++							       nphy_txpwr_idx
++							       [1]);
++		}
++
++		if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++			and_phy_reg(pi, 0x8f, ~(0x1 << 8));
++			and_phy_reg(pi, 0xa5, ~(0x1 << 8));
++		} else {
++			and_phy_reg(pi, 0xa5, ~(0x1 << 14));
++		}
++
++		if (NREV_IS(pi->pubpi.phy_rev, 2))
++			mod_phy_reg(pi, 0xdc, 0x00ff, 0x3b);
++		else if (NREV_LT(pi->pubpi.phy_rev, 2))
++			mod_phy_reg(pi, 0xdc, 0x00ff, 0x40);
++
++		if (NREV_LT(pi->pubpi.phy_rev, 2) &&
++		    pi->bw == WL_CHANSPEC_BW_40)
++			wlapi_bmac_mhf(pi->sh->physhim, MHF1, MHF1_IQSWAP_WAR,
++				       0x0, BRCM_BAND_ALL);
++
++		if (PHY_IPA(pi)) {
++			mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x297 :
++				    0x29b, (0x1 << 2), (0) << 2);
++
++			mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x297 :
++				    0x29b, (0x1 << 2), (0) << 2);
++
++		}
++
++	}
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, false);
++}
++
++void
++wlc_phy_txpwr_index_nphy(struct brcms_phy *pi, u8 core_mask, s8 txpwrindex,
++			 bool restore_cals)
++{
++	u8 core, txpwrctl_tbl;
++	u16 tx_ind0, iq_ind0, lo_ind0;
++	u16 m1m2;
++	u32 txgain;
++	u16 rad_gain, dac_gain;
++	u8 bbmult;
++	u32 iqcomp;
++	u16 iqcomp_a, iqcomp_b;
++	u32 locomp;
++	u16 tmpval;
++	u8 tx_pwr_ctrl_state;
++	s32 rfpwr_offset;
++	u16 regval[2];
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++	tx_ind0 = 192;
++	iq_ind0 = 320;
++	lo_ind0 = 448;
++
++	for (core = 0; core < pi->pubpi.phy_corenum; core++) {
++
++		if ((core_mask & (1 << core)) == 0)
++			continue;
++
++		txpwrctl_tbl = (core == PHY_CORE_0) ? 26 : 27;
++
++		if (txpwrindex < 0) {
++			if (pi->nphy_txpwrindex[core].index < 0)
++				continue;
++
++			if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++				mod_phy_reg(pi, 0x8f,
++					    (0x1 << 8),
++					    pi->nphy_txpwrindex[core].
++					    AfectrlOverride);
++				mod_phy_reg(pi, 0xa5, (0x1 << 8),
++					    pi->nphy_txpwrindex[core].
++					    AfectrlOverride);
++			} else {
++				mod_phy_reg(pi, 0xa5,
++					    (0x1 << 14),
++					    pi->nphy_txpwrindex[core].
++					    AfectrlOverride);
++			}
++
++			write_phy_reg(pi, (core == PHY_CORE_0) ?
++				      0xaa : 0xab,
++				      pi->nphy_txpwrindex[core].AfeCtrlDacGain);
++
++			wlc_phy_table_write_nphy(pi, 7, 1, (0x110 + core), 16,
++						 &pi->nphy_txpwrindex[core].
++						 rad_gain);
++
++			wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &m1m2);
++			m1m2 &= ((core == PHY_CORE_0) ? 0x00ff : 0xff00);
++			m1m2 |= ((core == PHY_CORE_0) ?
++				 (pi->nphy_txpwrindex[core].bbmult << 8) :
++				 (pi->nphy_txpwrindex[core].bbmult << 0));
++			wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &m1m2);
++
++			if (restore_cals) {
++				wlc_phy_table_write_nphy(
++					pi, 15, 2, (80 + 2 * core), 16,
++					&pi->nphy_txpwrindex[core].iqcomp_a);
++				wlc_phy_table_write_nphy(
++					pi, 15, 1, (85 + core), 16,
++					&pi->nphy_txpwrindex[core].locomp);
++				wlc_phy_table_write_nphy(
++					pi, 15, 1, (93 + core), 16,
++					&pi->nphy_txpwrindex[core].locomp);
++			}
++
++			wlc_phy_txpwrctrl_enable_nphy(pi, pi->nphy_txpwrctrl);
++
++			pi->nphy_txpwrindex[core].index_internal =
++				pi->nphy_txpwrindex[core].index_internal_save;
++		} else {
++
++			if (pi->nphy_txpwrindex[core].index < 0) {
++
++				if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++					mod_phy_reg(pi, 0x8f,
++						    (0x1 << 8),
++						    pi->nphy_txpwrindex[core].
++						    AfectrlOverride);
++					mod_phy_reg(pi, 0xa5, (0x1 << 8),
++						    pi->nphy_txpwrindex[core].
++						    AfectrlOverride);
++				} else {
++					pi->nphy_txpwrindex[core].
++					AfectrlOverride =
++						read_phy_reg(pi, 0xa5);
++				}
++
++				pi->nphy_txpwrindex[core].AfeCtrlDacGain =
++					read_phy_reg(pi, (core == PHY_CORE_0) ?
++							 0xaa : 0xab);
++
++				wlc_phy_table_read_nphy(pi, 7, 1,
++							(0x110 + core), 16,
++							&pi->
++							nphy_txpwrindex[core].
++							rad_gain);
++
++				wlc_phy_table_read_nphy(pi, 15, 1, 87, 16,
++							&tmpval);
++				tmpval >>= ((core == PHY_CORE_0) ? 8 : 0);
++				tmpval &= 0xff;
++				pi->nphy_txpwrindex[core].bbmult = (u8) tmpval;
++
++				wlc_phy_table_read_nphy(pi, 15, 2,
++							(80 + 2 * core), 16,
++							&pi->
++							nphy_txpwrindex[core].
++							iqcomp_a);
++
++				wlc_phy_table_read_nphy(pi, 15, 1, (85 + core),
++							16,
++							&pi->
++							nphy_txpwrindex[core].
++							locomp);
++
++				pi->nphy_txpwrindex[core].index_internal_save =
++					pi->nphy_txpwrindex[core].
++					index_internal;
++			}
++
++			tx_pwr_ctrl_state = pi->nphy_txpwrctrl;
++			wlc_phy_txpwrctrl_enable_nphy(pi, PHY_TPC_HW_OFF);
++
++			if (NREV_IS(pi->pubpi.phy_rev, 1))
++				wlapi_bmac_phyclk_fgc(pi->sh->physhim, ON);
++
++			wlc_phy_table_read_nphy(pi, txpwrctl_tbl, 1,
++						(tx_ind0 + txpwrindex), 32,
++						&txgain);
++
++			if (NREV_GE(pi->pubpi.phy_rev, 3))
++				rad_gain = (txgain >> 16) &
++					   ((1 << (32 - 16 + 1)) - 1);
++			else
++				rad_gain = (txgain >> 16) &
++					   ((1 << (28 - 16 + 1)) - 1);
++
++			dac_gain = (txgain >> 8) & ((1 << (13 - 8 + 1)) - 1);
++			bbmult = (txgain >> 0) & ((1 << (7 - 0 + 1)) - 1);
++
++			if (NREV_GE(pi->pubpi.phy_rev, 3))
++				mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0x8f :
++						 0xa5), (0x1 << 8), (0x1 << 8));
++			else
++				mod_phy_reg(pi, 0xa5, (0x1 << 14), (0x1 << 14));
++
++			write_phy_reg(pi, (core == PHY_CORE_0) ?
++				      0xaa : 0xab, dac_gain);
++
++			wlc_phy_table_write_nphy(pi, 7, 1, (0x110 + core), 16,
++						 &rad_gain);
++
++			wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &m1m2);
++			m1m2 &= ((core == PHY_CORE_0) ? 0x00ff : 0xff00);
++			m1m2 |= ((core == PHY_CORE_0) ?
++				(bbmult << 8) : (bbmult << 0));
++
++			wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &m1m2);
++
++			wlc_phy_table_read_nphy(pi, txpwrctl_tbl, 1,
++						(iq_ind0 + txpwrindex), 32,
++						&iqcomp);
++			iqcomp_a = (iqcomp >> 10) & ((1 << (19 - 10 + 1)) - 1);
++			iqcomp_b = (iqcomp >> 0) & ((1 << (9 - 0 + 1)) - 1);
++
++			if (restore_cals) {
++				regval[0] = (u16) iqcomp_a;
++				regval[1] = (u16) iqcomp_b;
++				wlc_phy_table_write_nphy(pi, 15, 2,
++							 (80 + 2 * core), 16,
++							 regval);
++			}
++
++			wlc_phy_table_read_nphy(pi, txpwrctl_tbl, 1,
++						(lo_ind0 + txpwrindex), 32,
++						&locomp);
++			if (restore_cals)
++				wlc_phy_table_write_nphy(pi, 15, 1, (85 + core),
++							 16, &locomp);
++
++			if (NREV_IS(pi->pubpi.phy_rev, 1))
++				wlapi_bmac_phyclk_fgc(pi->sh->physhim, OFF);
++
++			if (PHY_IPA(pi)) {
++				wlc_phy_table_read_nphy(pi,
++						(core == PHY_CORE_0 ?
++						 NPHY_TBL_ID_CORE1TXPWRCTL :
++						 NPHY_TBL_ID_CORE2TXPWRCTL),
++						1, 576 + txpwrindex, 32,
++						&rfpwr_offset);
++
++				mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
++					    0x29b, (0x1ff << 4),
++					    ((s16) rfpwr_offset) << 4);
++
++				mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
++					    0x29b, (0x1 << 2), (1) << 2);
++
++			}
++
++			wlc_phy_txpwrctrl_enable_nphy(pi, tx_pwr_ctrl_state);
++		}
++
++		pi->nphy_txpwrindex[core].index = txpwrindex;
++	}
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, false);
++}
++
++void
++wlc_phy_txpower_sromlimit_get_nphy(struct brcms_phy *pi, uint chan, u8 *max_pwr,
++				   u8 txp_rate_idx)
++{
++	u8 chan_freq_range;
++
++	chan_freq_range = wlc_phy_get_chan_freq_range_nphy(pi, chan);
++	switch (chan_freq_range) {
++	case WL_CHAN_FREQ_RANGE_2G:
++		*max_pwr = pi->tx_srom_max_rate_2g[txp_rate_idx];
++		break;
++	case WL_CHAN_FREQ_RANGE_5GM:
++		*max_pwr = pi->tx_srom_max_rate_5g_mid[txp_rate_idx];
++		break;
++	case WL_CHAN_FREQ_RANGE_5GL:
++		*max_pwr = pi->tx_srom_max_rate_5g_low[txp_rate_idx];
++		break;
++	case WL_CHAN_FREQ_RANGE_5GH:
++		*max_pwr = pi->tx_srom_max_rate_5g_hi[txp_rate_idx];
++		break;
++	default:
++		*max_pwr = pi->tx_srom_max_rate_2g[txp_rate_idx];
++		break;
++	}
++
++	return;
++}
++
++void wlc_phy_stay_in_carriersearch_nphy(struct brcms_phy *pi, bool enable)
++{
++	u16 clip_off[] = { 0xffff, 0xffff };
++
++	if (enable) {
++		if (pi->nphy_deaf_count == 0) {
++			pi->classifier_state =
++				wlc_phy_classifier_nphy(pi, 0, 0);
++			wlc_phy_classifier_nphy(pi, (0x7 << 0), 4);
++			wlc_phy_clip_det_nphy(pi, 0, pi->clip_state);
++			wlc_phy_clip_det_nphy(pi, 1, clip_off);
++		}
++
++		pi->nphy_deaf_count++;
++
++		wlc_phy_resetcca_nphy(pi);
++
++	} else {
++		pi->nphy_deaf_count--;
++
++		if (pi->nphy_deaf_count == 0) {
++			wlc_phy_classifier_nphy(pi, (0x7 << 0),
++						pi->classifier_state);
++			wlc_phy_clip_det_nphy(pi, 1, pi->clip_state);
++		}
++	}
++}
++
++void wlc_nphy_deaf_mode(struct brcms_phy *pi, bool mode)
++{
++	wlapi_suspend_mac_and_wait(pi->sh->physhim);
++
++	if (mode) {
++		if (pi->nphy_deaf_count == 0)
++			wlc_phy_stay_in_carriersearch_nphy(pi, true);
++	} else if (pi->nphy_deaf_count > 0) {
++		wlc_phy_stay_in_carriersearch_nphy(pi, false);
++	}
++
++	wlapi_enable_mac(pi->sh->physhim);
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_qmath.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_qmath.c
+new file mode 100644
+index 0000000..faf1ebe
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_qmath.c
+@@ -0,0 +1,308 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#include "phy_qmath.h"
++
++/*
++ * Description: This function make 16 bit unsigned multiplication.
++ * To fit the output into 16 bits the 32 bit multiplication result is right
++ * shifted by 16 bits.
++ */
++u16 qm_mulu16(u16 op1, u16 op2)
++{
++	return (u16) (((u32) op1 * (u32) op2) >> 16);
++}
++
++/*
++ * Description: This function make 16 bit multiplication and return the result
++ * in 16 bits. To fit the multiplication result into 16 bits the multiplication
++ * result is right shifted by 15 bits. Right shifting 15 bits instead of 16 bits
++ * is done to remove the extra sign bit formed due to the multiplication.
++ * When both the 16bit inputs are 0x8000 then the output is saturated to
++ * 0x7fffffff.
++ */
++s16 qm_muls16(s16 op1, s16 op2)
++{
++	s32 result;
++	if (op1 == (s16) 0x8000 && op2 == (s16) 0x8000)
++		result = 0x7fffffff;
++	else
++		result = ((s32) (op1) * (s32) (op2));
++
++	return (s16) (result >> 15);
++}
++
++/*
++ * Description: This function add two 32 bit numbers and return the 32bit
++ * result. If the result overflow 32 bits, the output will be saturated to
++ * 32bits.
++ */
++s32 qm_add32(s32 op1, s32 op2)
++{
++	s32 result;
++	result = op1 + op2;
++	if (op1 < 0 && op2 < 0 && result > 0)
++		result = 0x80000000;
++	else if (op1 > 0 && op2 > 0 && result < 0)
++		result = 0x7fffffff;
++
++	return result;
++}
++
++/*
++ * Description: This function add two 16 bit numbers and return the 16bit
++ * result. If the result overflow 16 bits, the output will be saturated to
++ * 16bits.
++ */
++s16 qm_add16(s16 op1, s16 op2)
++{
++	s16 result;
++	s32 temp = (s32) op1 + (s32) op2;
++	if (temp > (s32) 0x7fff)
++		result = (s16) 0x7fff;
++	else if (temp < (s32) 0xffff8000)
++		result = (s16) 0xffff8000;
++	else
++		result = (s16) temp;
++
++	return result;
++}
++
++/*
++ * Description: This function make 16 bit subtraction and return the 16bit
++ * result. If the result overflow 16 bits, the output will be saturated to
++ * 16bits.
++ */
++s16 qm_sub16(s16 op1, s16 op2)
++{
++	s16 result;
++	s32 temp = (s32) op1 - (s32) op2;
++	if (temp > (s32) 0x7fff)
++		result = (s16) 0x7fff;
++	else if (temp < (s32) 0xffff8000)
++		result = (s16) 0xffff8000;
++	else
++		result = (s16) temp;
++
++	return result;
++}
++
++/*
++ * Description: This function make a 32 bit saturated left shift when the
++ * specified shift is +ve. This function will make a 32 bit right shift when
++ * the specified shift is -ve. This function return the result after shifting
++ * operation.
++ */
++s32 qm_shl32(s32 op, int shift)
++{
++	int i;
++	s32 result;
++	result = op;
++	if (shift > 31)
++		shift = 31;
++	else if (shift < -31)
++		shift = -31;
++	if (shift >= 0) {
++		for (i = 0; i < shift; i++)
++			result = qm_add32(result, result);
++	} else {
++		result = result >> (-shift);
++	}
++
++	return result;
++}
++
++/*
++ * Description: This function make a 16 bit saturated left shift when the
++ * specified shift is +ve. This function will make a 16 bit right shift when
++ * the specified shift is -ve. This function return the result after shifting
++ * operation.
++ */
++s16 qm_shl16(s16 op, int shift)
++{
++	int i;
++	s16 result;
++	result = op;
++	if (shift > 15)
++		shift = 15;
++	else if (shift < -15)
++		shift = -15;
++	if (shift > 0) {
++		for (i = 0; i < shift; i++)
++			result = qm_add16(result, result);
++	} else {
++		result = result >> (-shift);
++	}
++
++	return result;
++}
++
++/*
++ * Description: This function make a 16 bit right shift when shift is +ve.
++ * This function make a 16 bit saturated left shift when shift is -ve. This
++ * function return the result of the shift operation.
++ */
++s16 qm_shr16(s16 op, int shift)
++{
++	return qm_shl16(op, -shift);
++}
++
++/*
++ * Description: This function return the number of redundant sign bits in a
++ * 32 bit number. Example: qm_norm32(0x00000080) = 23
++ */
++s16 qm_norm32(s32 op)
++{
++	u16 u16extraSignBits;
++	if (op == 0) {
++		return 31;
++	} else {
++		u16extraSignBits = 0;
++		while ((op >> 31) == (op >> 30)) {
++			u16extraSignBits++;
++			op = op << 1;
++		}
++	}
++	return u16extraSignBits;
++}
++
++/* This table is log2(1+(i/32)) where i=[0:1:31], in q.15 format */
++static const s16 log_table[] = {
++	0,
++	1455,
++	2866,
++	4236,
++	5568,
++	6863,
++	8124,
++	9352,
++	10549,
++	11716,
++	12855,
++	13968,
++	15055,
++	16117,
++	17156,
++	18173,
++	19168,
++	20143,
++	21098,
++	22034,
++	22952,
++	23852,
++	24736,
++	25604,
++	26455,
++	27292,
++	28114,
++	28922,
++	29717,
++	30498,
++	31267,
++	32024
++};
++
++#define LOG_TABLE_SIZE 32       /* log_table size */
++#define LOG2_LOG_TABLE_SIZE 5   /* log2(log_table size) */
++#define Q_LOG_TABLE 15          /* qformat of log_table */
++#define LOG10_2         19728   /* log10(2) in q.16 */
++
++/*
++ * Description:
++ * This routine takes the input number N and its q format qN and compute
++ * the log10(N). This routine first normalizes the input no N.	Then N is in
++ * mag*(2^x) format. mag is any number in the range 2^30-(2^31 - 1).
++ * Then log2(mag * 2^x) = log2(mag) + x is computed. From that
++ * log10(mag * 2^x) = log2(mag * 2^x) * log10(2) is computed.
++ * This routine looks the log2 value in the table considering
++ * LOG2_LOG_TABLE_SIZE+1 MSBs. As the MSB is always 1, only next
++ * LOG2_OF_LOG_TABLE_SIZE MSBs are used for table lookup. Next 16 MSBs are used
++ * for interpolation.
++ * Inputs:
++ * N - number to which log10 has to be found.
++ * qN - q format of N
++ * log10N - address where log10(N) will be written.
++ * qLog10N - address where log10N qformat will be written.
++ * Note/Problem:
++ * For accurate results input should be in normalized or near normalized form.
++ */
++void qm_log10(s32 N, s16 qN, s16 *log10N, s16 *qLog10N)
++{
++	s16 s16norm, s16tableIndex, s16errorApproximation;
++	u16 u16offset;
++	s32 s32log;
++
++	/* normalize the N. */
++	s16norm = qm_norm32(N);
++	N = N << s16norm;
++
++	/* The qformat of N after normalization.
++	 * -30 is added to treat the no as between 1.0 to 2.0
++	 * i.e. after adding the -30 to the qformat the decimal point will be
++	 * just rigtht of the MSB. (i.e. after sign bit and 1st MSB). i.e.
++	 * at the right side of 30th bit.
++	 */
++	qN = qN + s16norm - 30;
++
++	/* take the table index as the LOG2_OF_LOG_TABLE_SIZE bits right of the
++	 * MSB */
++	s16tableIndex = (s16) (N >> (32 - (2 + LOG2_LOG_TABLE_SIZE)));
++
++	/* remove the MSB. the MSB is always 1 after normalization. */
++	s16tableIndex =
++		s16tableIndex & (s16) ((1 << LOG2_LOG_TABLE_SIZE) - 1);
++
++	/* remove the (1+LOG2_OF_LOG_TABLE_SIZE) MSBs in the N. */
++	N = N & ((1 << (32 - (2 + LOG2_LOG_TABLE_SIZE))) - 1);
++
++	/* take the offset as the 16 MSBS after table index.
++	 */
++	u16offset = (u16) (N >> (32 - (2 + LOG2_LOG_TABLE_SIZE + 16)));
++
++	/* look the log value in the table. */
++	s32log = log_table[s16tableIndex];      /* q.15 format */
++
++	/* interpolate using the offset. q.15 format. */
++	s16errorApproximation = (s16) qm_mulu16(u16offset,
++				(u16) (log_table[s16tableIndex + 1] -
++				       log_table[s16tableIndex]));
++
++	 /* q.15 format */
++	s32log = qm_add16((s16) s32log, s16errorApproximation);
++
++	/* adjust for the qformat of the N as
++	 * log2(mag * 2^x) = log2(mag) + x
++	 */
++	s32log = qm_add32(s32log, ((s32) -qN) << 15);   /* q.15 format */
++
++	/* normalize the result. */
++	s16norm = qm_norm32(s32log);
++
++	/* bring all the important bits into lower 16 bits */
++	/* q.15+s16norm-16 format */
++	s32log = qm_shl32(s32log, s16norm - 16);
++
++	/* compute the log10(N) by multiplying log2(N) with log10(2).
++	 * as log10(mag * 2^x) = log2(mag * 2^x) * log10(2)
++	 * log10N in q.15+s16norm-16+1 (LOG10_2 is in q.16)
++	 */
++	*log10N = qm_muls16((s16) s32log, (s16) LOG10_2);
++
++	/* write the q format of the result. */
++	*qLog10N = 15 + s16norm - 16 + 1;
++
++	return;
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_qmath.h b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_qmath.h
+new file mode 100644
+index 0000000..20e3783
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_qmath.h
+@@ -0,0 +1,42 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef _BRCM_QMATH_H_
++#define _BRCM_QMATH_H_
++
++#include <types.h>
++
++u16 qm_mulu16(u16 op1, u16 op2);
++
++s16 qm_muls16(s16 op1, s16 op2);
++
++s32 qm_add32(s32 op1, s32 op2);
++
++s16 qm_add16(s16 op1, s16 op2);
++
++s16 qm_sub16(s16 op1, s16 op2);
++
++s32 qm_shl32(s32 op, int shift);
++
++s16 qm_shl16(s16 op, int shift);
++
++s16 qm_shr16(s16 op, int shift);
++
++s16 qm_norm32(s32 op);
++
++void qm_log10(s32 N, s16 qN, s16 *log10N, s16 *qLog10N);
++
++#endif				/* #ifndef _BRCM_QMATH_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_radio.h b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_radio.h
+new file mode 100644
+index 0000000..c3a6754
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_radio.h
+@@ -0,0 +1,1533 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef	_BRCM_PHY_RADIO_H_
++#define	_BRCM_PHY_RADIO_H_
++
++#define	RADIO_IDCODE			0x01
++
++#define RADIO_DEFAULT_CORE		0
++
++#define	RXC0_RSSI_RST			0x80
++#define	RXC0_MODE_RSSI			0x40
++#define	RXC0_MODE_OFF			0x20
++#define	RXC0_MODE_CM			0x10
++#define	RXC0_LAN_LOAD			0x08
++#define	RXC0_OFF_ADJ_MASK		0x07
++
++#define	TXC0_MODE_TXLPF			0x04
++#define	TXC0_PA_TSSI_EN			0x02
++#define	TXC0_TSSI_EN			0x01
++
++#define	TXC1_PA_GAIN_MASK		0x60
++#define	TXC1_PA_GAIN_3DB		0x40
++#define	TXC1_PA_GAIN_2DB		0x20
++#define	TXC1_TX_MIX_GAIN		0x10
++#define	TXC1_OFF_I_MASK			0x0c
++#define	TXC1_OFF_Q_MASK			0x03
++
++#define	RADIO_2055_READ_OFF		0x100
++#define	RADIO_2057_READ_OFF		0x200
++
++#define RADIO_2055_GEN_SPARE		0x00
++#define RADIO_2055_SP_PIN_PD		0x02
++#define RADIO_2055_SP_RSSI_CORE1	0x03
++#define RADIO_2055_SP_PD_MISC_CORE1	0x04
++#define RADIO_2055_SP_RSSI_CORE2	0x05
++#define RADIO_2055_SP_PD_MISC_CORE2	0x06
++#define RADIO_2055_SP_RX_GC1_CORE1	0x07
++#define RADIO_2055_SP_RX_GC2_CORE1	0x08
++#define RADIO_2055_SP_RX_GC1_CORE2	0x09
++#define RADIO_2055_SP_RX_GC2_CORE2	0x0a
++#define RADIO_2055_SP_LPF_BW_SELECT_CORE1 0x0b
++#define RADIO_2055_SP_LPF_BW_SELECT_CORE2 0x0c
++#define RADIO_2055_SP_TX_GC1_CORE1	0x0d
++#define RADIO_2055_SP_TX_GC2_CORE1	0x0e
++#define RADIO_2055_SP_TX_GC1_CORE2	0x0f
++#define RADIO_2055_SP_TX_GC2_CORE2	0x10
++#define RADIO_2055_MASTER_CNTRL1	0x11
++#define RADIO_2055_MASTER_CNTRL2	0x12
++#define RADIO_2055_PD_LGEN		0x13
++#define RADIO_2055_PD_PLL_TS		0x14
++#define RADIO_2055_PD_CORE1_LGBUF	0x15
++#define RADIO_2055_PD_CORE1_TX		0x16
++#define RADIO_2055_PD_CORE1_RXTX	0x17
++#define RADIO_2055_PD_CORE1_RSSI_MISC	0x18
++#define RADIO_2055_PD_CORE2_LGBUF	0x19
++#define RADIO_2055_PD_CORE2_TX		0x1a
++#define RADIO_2055_PD_CORE2_RXTX	0x1b
++#define RADIO_2055_PD_CORE2_RSSI_MISC	0x1c
++#define RADIO_2055_PWRDET_LGEN		0x1d
++#define RADIO_2055_PWRDET_LGBUF_CORE1	0x1e
++#define RADIO_2055_PWRDET_RXTX_CORE1	0x1f
++#define RADIO_2055_PWRDET_LGBUF_CORE2	0x20
++#define RADIO_2055_PWRDET_RXTX_CORE2	0x21
++#define RADIO_2055_RRCCAL_CNTRL_SPARE	0x22
++#define RADIO_2055_RRCCAL_N_OPT_SEL	0x23
++#define RADIO_2055_CAL_MISC		0x24
++#define RADIO_2055_CAL_COUNTER_OUT	0x25
++#define RADIO_2055_CAL_COUNTER_OUT2	0x26
++#define RADIO_2055_CAL_CVAR_CNTRL	0x27
++#define RADIO_2055_CAL_RVAR_CNTRL	0x28
++#define RADIO_2055_CAL_LPO_CNTRL	0x29
++#define RADIO_2055_CAL_TS		0x2a
++#define RADIO_2055_CAL_RCCAL_READ_TS	0x2b
++#define RADIO_2055_CAL_RCAL_READ_TS	0x2c
++#define RADIO_2055_PAD_DRIVER		0x2d
++#define RADIO_2055_XO_CNTRL1		0x2e
++#define RADIO_2055_XO_CNTRL2		0x2f
++#define RADIO_2055_XO_REGULATOR		0x30
++#define RADIO_2055_XO_MISC		0x31
++#define RADIO_2055_PLL_LF_C1		0x32
++#define RADIO_2055_PLL_CAL_VTH		0x33
++#define RADIO_2055_PLL_LF_C2		0x34
++#define RADIO_2055_PLL_REF		0x35
++#define RADIO_2055_PLL_LF_R1		0x36
++#define RADIO_2055_PLL_PFD_CP		0x37
++#define RADIO_2055_PLL_IDAC_CPOPAMP	0x38
++#define RADIO_2055_PLL_CP_REGULATOR	0x39
++#define RADIO_2055_PLL_RCAL		0x3a
++#define RADIO_2055_RF_PLL_MOD0		0x3b
++#define RADIO_2055_RF_PLL_MOD1		0x3c
++#define RADIO_2055_RF_MMD_IDAC1		0x3d
++#define RADIO_2055_RF_MMD_IDAC0		0x3e
++#define RADIO_2055_RF_MMD_SPARE		0x3f
++#define RADIO_2055_VCO_CAL1		0x40
++#define RADIO_2055_VCO_CAL2		0x41
++#define RADIO_2055_VCO_CAL3		0x42
++#define RADIO_2055_VCO_CAL4		0x43
++#define RADIO_2055_VCO_CAL5		0x44
++#define RADIO_2055_VCO_CAL6		0x45
++#define RADIO_2055_VCO_CAL7		0x46
++#define RADIO_2055_VCO_CAL8		0x47
++#define RADIO_2055_VCO_CAL9		0x48
++#define RADIO_2055_VCO_CAL10		0x49
++#define RADIO_2055_VCO_CAL11		0x4a
++#define RADIO_2055_VCO_CAL12		0x4b
++#define RADIO_2055_VCO_CAL13		0x4c
++#define RADIO_2055_VCO_CAL14		0x4d
++#define RADIO_2055_VCO_CAL15		0x4e
++#define RADIO_2055_VCO_CAL16		0x4f
++#define RADIO_2055_VCO_KVCO		0x50
++#define RADIO_2055_VCO_CAP_TAIL		0x51
++#define RADIO_2055_VCO_IDAC_VCO		0x52
++#define RADIO_2055_VCO_REGULATOR	0x53
++#define RADIO_2055_PLL_RF_VTH		0x54
++#define RADIO_2055_LGBUF_CEN_BUF	0x55
++#define RADIO_2055_LGEN_TUNE1		0x56
++#define RADIO_2055_LGEN_TUNE2		0x57
++#define RADIO_2055_LGEN_IDAC1		0x58
++#define RADIO_2055_LGEN_IDAC2		0x59
++#define RADIO_2055_LGEN_BIAS_CNT	0x5a
++#define RADIO_2055_LGEN_BIAS_IDAC	0x5b
++#define RADIO_2055_LGEN_RCAL		0x5c
++#define RADIO_2055_LGEN_DIV		0x5d
++#define RADIO_2055_LGEN_SPARE2		0x5e
++#define RADIO_2055_CORE1_LGBUF_A_TUNE	0x5f
++#define RADIO_2055_CORE1_LGBUF_G_TUNE	0x60
++#define RADIO_2055_CORE1_LGBUF_DIV	0x61
++#define RADIO_2055_CORE1_LGBUF_A_IDAC	0x62
++#define RADIO_2055_CORE1_LGBUF_G_IDAC	0x63
++#define RADIO_2055_CORE1_LGBUF_IDACFIL_OVR 0x64
++#define RADIO_2055_CORE1_LGBUF_SPARE	0x65
++#define RADIO_2055_CORE1_RXRF_SPC1	0x66
++#define RADIO_2055_CORE1_RXRF_REG1	0x67
++#define RADIO_2055_CORE1_RXRF_REG2	0x68
++#define RADIO_2055_CORE1_RXRF_RCAL	0x69
++#define RADIO_2055_CORE1_RXBB_BUFI_LPFCMP 0x6a
++#define RADIO_2055_CORE1_RXBB_LPF	0x6b
++#define RADIO_2055_CORE1_RXBB_MIDAC_HIPAS 0x6c
++#define RADIO_2055_CORE1_RXBB_VGA1_IDAC	0x6d
++#define RADIO_2055_CORE1_RXBB_VGA2_IDAC	0x6e
++#define RADIO_2055_CORE1_RXBB_VGA3_IDAC	0x6f
++#define RADIO_2055_CORE1_RXBB_BUFO_CTRL	0x70
++#define RADIO_2055_CORE1_RXBB_RCCAL_CTRL 0x71
++#define RADIO_2055_CORE1_RXBB_RSSI_CTRL1 0x72
++#define RADIO_2055_CORE1_RXBB_RSSI_CTRL2 0x73
++#define RADIO_2055_CORE1_RXBB_RSSI_CTRL3 0x74
++#define RADIO_2055_CORE1_RXBB_RSSI_CTRL4 0x75
++#define RADIO_2055_CORE1_RXBB_RSSI_CTRL5 0x76
++#define RADIO_2055_CORE1_RXBB_REGULATOR	0x77
++#define RADIO_2055_CORE1_RXBB_SPARE1	0x78
++#define RADIO_2055_CORE1_RXTXBB_RCAL	0x79
++#define RADIO_2055_CORE1_TXRF_SGM_PGA	0x7a
++#define RADIO_2055_CORE1_TXRF_SGM_PAD	0x7b
++#define RADIO_2055_CORE1_TXRF_CNTR_PGA1	0x7c
++#define RADIO_2055_CORE1_TXRF_CNTR_PAD1	0x7d
++#define RADIO_2055_CORE1_TX_RFPGA_IDAC	0x7e
++#define RADIO_2055_CORE1_TX_PGA_PAD_TN	0x7f
++#define RADIO_2055_CORE1_TX_PAD_IDAC1	0x80
++#define RADIO_2055_CORE1_TX_PAD_IDAC2	0x81
++#define RADIO_2055_CORE1_TX_MX_BGTRIM	0x82
++#define RADIO_2055_CORE1_TXRF_RCAL	0x83
++#define RADIO_2055_CORE1_TXRF_PAD_TSSI1	0x84
++#define RADIO_2055_CORE1_TXRF_PAD_TSSI2	0x85
++#define RADIO_2055_CORE1_TX_RF_SPARE	0x86
++#define RADIO_2055_CORE1_TXRF_IQCAL1	0x87
++#define RADIO_2055_CORE1_TXRF_IQCAL2	0x88
++#define RADIO_2055_CORE1_TXBB_RCCAL_CTRL 0x89
++#define RADIO_2055_CORE1_TXBB_LPF1	0x8a
++#define RADIO_2055_CORE1_TX_VOS_CNCL	0x8b
++#define RADIO_2055_CORE1_TX_LPF_MXGM_IDAC 0x8c
++#define RADIO_2055_CORE1_TX_BB_MXGM	0x8d
++#define RADIO_2055_CORE2_LGBUF_A_TUNE	0x8e
++#define RADIO_2055_CORE2_LGBUF_G_TUNE	0x8f
++#define RADIO_2055_CORE2_LGBUF_DIV	0x90
++#define RADIO_2055_CORE2_LGBUF_A_IDAC	0x91
++#define RADIO_2055_CORE2_LGBUF_G_IDAC	0x92
++#define RADIO_2055_CORE2_LGBUF_IDACFIL_OVR 0x93
++#define RADIO_2055_CORE2_LGBUF_SPARE	0x94
++#define RADIO_2055_CORE2_RXRF_SPC1	0x95
++#define RADIO_2055_CORE2_RXRF_REG1	0x96
++#define RADIO_2055_CORE2_RXRF_REG2	0x97
++#define RADIO_2055_CORE2_RXRF_RCAL	0x98
++#define RADIO_2055_CORE2_RXBB_BUFI_LPFCMP 0x99
++#define RADIO_2055_CORE2_RXBB_LPF	0x9a
++#define RADIO_2055_CORE2_RXBB_MIDAC_HIPAS 0x9b
++#define RADIO_2055_CORE2_RXBB_VGA1_IDAC	0x9c
++#define RADIO_2055_CORE2_RXBB_VGA2_IDAC	0x9d
++#define RADIO_2055_CORE2_RXBB_VGA3_IDAC	0x9e
++#define RADIO_2055_CORE2_RXBB_BUFO_CTRL	0x9f
++#define RADIO_2055_CORE2_RXBB_RCCAL_CTRL 0xa0
++#define RADIO_2055_CORE2_RXBB_RSSI_CTRL1 0xa1
++#define RADIO_2055_CORE2_RXBB_RSSI_CTRL2 0xa2
++#define RADIO_2055_CORE2_RXBB_RSSI_CTRL3 0xa3
++#define RADIO_2055_CORE2_RXBB_RSSI_CTRL4 0xa4
++#define RADIO_2055_CORE2_RXBB_RSSI_CTRL5 0xa5
++#define RADIO_2055_CORE2_RXBB_REGULATOR	0xa6
++#define RADIO_2055_CORE2_RXBB_SPARE1	0xa7
++#define RADIO_2055_CORE2_RXTXBB_RCAL	0xa8
++#define RADIO_2055_CORE2_TXRF_SGM_PGA	0xa9
++#define RADIO_2055_CORE2_TXRF_SGM_PAD	0xaa
++#define RADIO_2055_CORE2_TXRF_CNTR_PGA1	0xab
++#define RADIO_2055_CORE2_TXRF_CNTR_PAD1	0xac
++#define RADIO_2055_CORE2_TX_RFPGA_IDAC	0xad
++#define RADIO_2055_CORE2_TX_PGA_PAD_TN	0xae
++#define RADIO_2055_CORE2_TX_PAD_IDAC1	0xaf
++#define RADIO_2055_CORE2_TX_PAD_IDAC2	0xb0
++#define RADIO_2055_CORE2_TX_MX_BGTRIM	0xb1
++#define RADIO_2055_CORE2_TXRF_RCAL	0xb2
++#define RADIO_2055_CORE2_TXRF_PAD_TSSI1	0xb3
++#define RADIO_2055_CORE2_TXRF_PAD_TSSI2	0xb4
++#define RADIO_2055_CORE2_TX_RF_SPARE	0xb5
++#define RADIO_2055_CORE2_TXRF_IQCAL1	0xb6
++#define RADIO_2055_CORE2_TXRF_IQCAL2	0xb7
++#define RADIO_2055_CORE2_TXBB_RCCAL_CTRL 0xb8
++#define RADIO_2055_CORE2_TXBB_LPF1	0xb9
++#define RADIO_2055_CORE2_TX_VOS_CNCL	0xba
++#define RADIO_2055_CORE2_TX_LPF_MXGM_IDAC 0xbb
++#define RADIO_2055_CORE2_TX_BB_MXGM	0xbc
++#define RADIO_2055_PRG_GC_HPVGA23_21	0xbd
++#define RADIO_2055_PRG_GC_HPVGA23_22	0xbe
++#define RADIO_2055_PRG_GC_HPVGA23_23	0xbf
++#define RADIO_2055_PRG_GC_HPVGA23_24	0xc0
++#define RADIO_2055_PRG_GC_HPVGA23_25	0xc1
++#define RADIO_2055_PRG_GC_HPVGA23_26	0xc2
++#define RADIO_2055_PRG_GC_HPVGA23_27	0xc3
++#define RADIO_2055_PRG_GC_HPVGA23_28	0xc4
++#define RADIO_2055_PRG_GC_HPVGA23_29	0xc5
++#define RADIO_2055_PRG_GC_HPVGA23_30	0xc6
++#define RADIO_2055_CORE1_LNA_GAINBST	0xcd
++#define RADIO_2055_CORE1_B0_NBRSSI_VCM	0xd2
++#define RADIO_2055_CORE1_GEN_SPARE2		0xd6
++#define RADIO_2055_CORE2_LNA_GAINBST	0xd9
++#define RADIO_2055_CORE2_B0_NBRSSI_VCM	0xde
++#define RADIO_2055_CORE2_GEN_SPARE2		0xe2
++
++#define RADIO_2055_GAINBST_GAIN_DB	6
++#define RADIO_2055_GAINBST_CODE		0x6
++
++#define RADIO_2055_JTAGCTRL_MASK	0x04
++#define RADIO_2055_JTAGSYNC_MASK	0x08
++#define RADIO_2055_RRCAL_START		0x40
++#define RADIO_2055_RRCAL_RST_N		0x01
++#define RADIO_2055_CAL_LPO_ENABLE	0x80
++#define RADIO_2055_RCAL_DONE		0x80
++#define RADIO_2055_NBRSSI_VCM_I_MASK	0x03
++#define RADIO_2055_NBRSSI_VCM_I_SHIFT	0x00
++#define RADIO_2055_NBRSSI_VCM_Q_MASK	0x03
++#define RADIO_2055_NBRSSI_VCM_Q_SHIFT	0x00
++#define RADIO_2055_WBRSSI_VCM_IQ_MASK	0x0c
++#define RADIO_2055_WBRSSI_VCM_IQ_SHIFT	0x02
++#define RADIO_2055_NBRSSI_PD		0x01
++#define RADIO_2055_WBRSSI_G1_PD		0x04
++#define RADIO_2055_WBRSSI_G2_PD		0x02
++#define RADIO_2055_NBRSSI_SEL		0x01
++#define RADIO_2055_WBRSSI_G1_SEL	0x04
++#define RADIO_2055_WBRSSI_G2_SEL	0x02
++#define RADIO_2055_COUPLE_RX_MASK	0x01
++#define RADIO_2055_COUPLE_TX_MASK	0x02
++#define RADIO_2055_GAINBST_DISABLE	0x02
++#define RADIO_2055_GAINBST_VAL_MASK	0x07
++#define RADIO_2055_RXMX_GC_MASK		0x0c
++
++#define RADIO_MIMO_CORESEL_OFF		0x0
++#define RADIO_MIMO_CORESEL_CORE1	0x1
++#define RADIO_MIMO_CORESEL_CORE2	0x2
++#define RADIO_MIMO_CORESEL_CORE3	0x3
++#define RADIO_MIMO_CORESEL_CORE4	0x4
++#define RADIO_MIMO_CORESEL_ALLRX	0x5
++#define RADIO_MIMO_CORESEL_ALLTX	0x6
++#define RADIO_MIMO_CORESEL_ALLRXTX	0x7
++
++#define	RADIO_2064_READ_OFF		0x200
++
++#define RADIO_2064_REG000               0x0
++#define RADIO_2064_REG001               0x1
++#define RADIO_2064_REG002               0x2
++#define RADIO_2064_REG003               0x3
++#define RADIO_2064_REG004               0x4
++#define RADIO_2064_REG005               0x5
++#define RADIO_2064_REG006               0x6
++#define RADIO_2064_REG007               0x7
++#define RADIO_2064_REG008               0x8
++#define RADIO_2064_REG009               0x9
++#define RADIO_2064_REG00A               0xa
++#define RADIO_2064_REG00B               0xb
++#define RADIO_2064_REG00C               0xc
++#define RADIO_2064_REG00D               0xd
++#define RADIO_2064_REG00E               0xe
++#define RADIO_2064_REG00F               0xf
++#define RADIO_2064_REG010               0x10
++#define RADIO_2064_REG011               0x11
++#define RADIO_2064_REG012               0x12
++#define RADIO_2064_REG013               0x13
++#define RADIO_2064_REG014               0x14
++#define RADIO_2064_REG015               0x15
++#define RADIO_2064_REG016               0x16
++#define RADIO_2064_REG017               0x17
++#define RADIO_2064_REG018               0x18
++#define RADIO_2064_REG019               0x19
++#define RADIO_2064_REG01A               0x1a
++#define RADIO_2064_REG01B               0x1b
++#define RADIO_2064_REG01C               0x1c
++#define RADIO_2064_REG01D               0x1d
++#define RADIO_2064_REG01E               0x1e
++#define RADIO_2064_REG01F               0x1f
++#define RADIO_2064_REG020               0x20
++#define RADIO_2064_REG021               0x21
++#define RADIO_2064_REG022               0x22
++#define RADIO_2064_REG023               0x23
++#define RADIO_2064_REG024               0x24
++#define RADIO_2064_REG025               0x25
++#define RADIO_2064_REG026               0x26
++#define RADIO_2064_REG027               0x27
++#define RADIO_2064_REG028               0x28
++#define RADIO_2064_REG029               0x29
++#define RADIO_2064_REG02A               0x2a
++#define RADIO_2064_REG02B               0x2b
++#define RADIO_2064_REG02C               0x2c
++#define RADIO_2064_REG02D               0x2d
++#define RADIO_2064_REG02E               0x2e
++#define RADIO_2064_REG02F               0x2f
++#define RADIO_2064_REG030               0x30
++#define RADIO_2064_REG031               0x31
++#define RADIO_2064_REG032               0x32
++#define RADIO_2064_REG033               0x33
++#define RADIO_2064_REG034               0x34
++#define RADIO_2064_REG035               0x35
++#define RADIO_2064_REG036               0x36
++#define RADIO_2064_REG037               0x37
++#define RADIO_2064_REG038               0x38
++#define RADIO_2064_REG039               0x39
++#define RADIO_2064_REG03A               0x3a
++#define RADIO_2064_REG03B               0x3b
++#define RADIO_2064_REG03C               0x3c
++#define RADIO_2064_REG03D               0x3d
++#define RADIO_2064_REG03E               0x3e
++#define RADIO_2064_REG03F               0x3f
++#define RADIO_2064_REG040               0x40
++#define RADIO_2064_REG041               0x41
++#define RADIO_2064_REG042               0x42
++#define RADIO_2064_REG043               0x43
++#define RADIO_2064_REG044               0x44
++#define RADIO_2064_REG045               0x45
++#define RADIO_2064_REG046               0x46
++#define RADIO_2064_REG047               0x47
++#define RADIO_2064_REG048               0x48
++#define RADIO_2064_REG049               0x49
++#define RADIO_2064_REG04A               0x4a
++#define RADIO_2064_REG04B               0x4b
++#define RADIO_2064_REG04C               0x4c
++#define RADIO_2064_REG04D               0x4d
++#define RADIO_2064_REG04E               0x4e
++#define RADIO_2064_REG04F               0x4f
++#define RADIO_2064_REG050               0x50
++#define RADIO_2064_REG051               0x51
++#define RADIO_2064_REG052               0x52
++#define RADIO_2064_REG053               0x53
++#define RADIO_2064_REG054               0x54
++#define RADIO_2064_REG055               0x55
++#define RADIO_2064_REG056               0x56
++#define RADIO_2064_REG057               0x57
++#define RADIO_2064_REG058               0x58
++#define RADIO_2064_REG059               0x59
++#define RADIO_2064_REG05A               0x5a
++#define RADIO_2064_REG05B               0x5b
++#define RADIO_2064_REG05C               0x5c
++#define RADIO_2064_REG05D               0x5d
++#define RADIO_2064_REG05E               0x5e
++#define RADIO_2064_REG05F               0x5f
++#define RADIO_2064_REG060               0x60
++#define RADIO_2064_REG061               0x61
++#define RADIO_2064_REG062               0x62
++#define RADIO_2064_REG063               0x63
++#define RADIO_2064_REG064               0x64
++#define RADIO_2064_REG065               0x65
++#define RADIO_2064_REG066               0x66
++#define RADIO_2064_REG067               0x67
++#define RADIO_2064_REG068               0x68
++#define RADIO_2064_REG069               0x69
++#define RADIO_2064_REG06A               0x6a
++#define RADIO_2064_REG06B               0x6b
++#define RADIO_2064_REG06C               0x6c
++#define RADIO_2064_REG06D               0x6d
++#define RADIO_2064_REG06E               0x6e
++#define RADIO_2064_REG06F               0x6f
++#define RADIO_2064_REG070               0x70
++#define RADIO_2064_REG071               0x71
++#define RADIO_2064_REG072               0x72
++#define RADIO_2064_REG073               0x73
++#define RADIO_2064_REG074               0x74
++#define RADIO_2064_REG075               0x75
++#define RADIO_2064_REG076               0x76
++#define RADIO_2064_REG077               0x77
++#define RADIO_2064_REG078               0x78
++#define RADIO_2064_REG079               0x79
++#define RADIO_2064_REG07A               0x7a
++#define RADIO_2064_REG07B               0x7b
++#define RADIO_2064_REG07C               0x7c
++#define RADIO_2064_REG07D               0x7d
++#define RADIO_2064_REG07E               0x7e
++#define RADIO_2064_REG07F               0x7f
++#define RADIO_2064_REG080               0x80
++#define RADIO_2064_REG081               0x81
++#define RADIO_2064_REG082               0x82
++#define RADIO_2064_REG083               0x83
++#define RADIO_2064_REG084               0x84
++#define RADIO_2064_REG085               0x85
++#define RADIO_2064_REG086               0x86
++#define RADIO_2064_REG087               0x87
++#define RADIO_2064_REG088               0x88
++#define RADIO_2064_REG089               0x89
++#define RADIO_2064_REG08A               0x8a
++#define RADIO_2064_REG08B               0x8b
++#define RADIO_2064_REG08C               0x8c
++#define RADIO_2064_REG08D               0x8d
++#define RADIO_2064_REG08E               0x8e
++#define RADIO_2064_REG08F               0x8f
++#define RADIO_2064_REG090               0x90
++#define RADIO_2064_REG091               0x91
++#define RADIO_2064_REG092               0x92
++#define RADIO_2064_REG093               0x93
++#define RADIO_2064_REG094               0x94
++#define RADIO_2064_REG095               0x95
++#define RADIO_2064_REG096               0x96
++#define RADIO_2064_REG097               0x97
++#define RADIO_2064_REG098               0x98
++#define RADIO_2064_REG099               0x99
++#define RADIO_2064_REG09A               0x9a
++#define RADIO_2064_REG09B               0x9b
++#define RADIO_2064_REG09C               0x9c
++#define RADIO_2064_REG09D               0x9d
++#define RADIO_2064_REG09E               0x9e
++#define RADIO_2064_REG09F               0x9f
++#define RADIO_2064_REG0A0               0xa0
++#define RADIO_2064_REG0A1               0xa1
++#define RADIO_2064_REG0A2               0xa2
++#define RADIO_2064_REG0A3               0xa3
++#define RADIO_2064_REG0A4               0xa4
++#define RADIO_2064_REG0A5               0xa5
++#define RADIO_2064_REG0A6               0xa6
++#define RADIO_2064_REG0A7               0xa7
++#define RADIO_2064_REG0A8               0xa8
++#define RADIO_2064_REG0A9               0xa9
++#define RADIO_2064_REG0AA               0xaa
++#define RADIO_2064_REG0AB               0xab
++#define RADIO_2064_REG0AC               0xac
++#define RADIO_2064_REG0AD               0xad
++#define RADIO_2064_REG0AE               0xae
++#define RADIO_2064_REG0AF               0xaf
++#define RADIO_2064_REG0B0               0xb0
++#define RADIO_2064_REG0B1               0xb1
++#define RADIO_2064_REG0B2               0xb2
++#define RADIO_2064_REG0B3               0xb3
++#define RADIO_2064_REG0B4               0xb4
++#define RADIO_2064_REG0B5               0xb5
++#define RADIO_2064_REG0B6               0xb6
++#define RADIO_2064_REG0B7               0xb7
++#define RADIO_2064_REG0B8               0xb8
++#define RADIO_2064_REG0B9               0xb9
++#define RADIO_2064_REG0BA               0xba
++#define RADIO_2064_REG0BB               0xbb
++#define RADIO_2064_REG0BC               0xbc
++#define RADIO_2064_REG0BD               0xbd
++#define RADIO_2064_REG0BE               0xbe
++#define RADIO_2064_REG0BF               0xbf
++#define RADIO_2064_REG0C0               0xc0
++#define RADIO_2064_REG0C1               0xc1
++#define RADIO_2064_REG0C2               0xc2
++#define RADIO_2064_REG0C3               0xc3
++#define RADIO_2064_REG0C4               0xc4
++#define RADIO_2064_REG0C5               0xc5
++#define RADIO_2064_REG0C6               0xc6
++#define RADIO_2064_REG0C7               0xc7
++#define RADIO_2064_REG0C8               0xc8
++#define RADIO_2064_REG0C9               0xc9
++#define RADIO_2064_REG0CA               0xca
++#define RADIO_2064_REG0CB               0xcb
++#define RADIO_2064_REG0CC               0xcc
++#define RADIO_2064_REG0CD               0xcd
++#define RADIO_2064_REG0CE               0xce
++#define RADIO_2064_REG0CF               0xcf
++#define RADIO_2064_REG0D0               0xd0
++#define RADIO_2064_REG0D1               0xd1
++#define RADIO_2064_REG0D2               0xd2
++#define RADIO_2064_REG0D3               0xd3
++#define RADIO_2064_REG0D4               0xd4
++#define RADIO_2064_REG0D5               0xd5
++#define RADIO_2064_REG0D6               0xd6
++#define RADIO_2064_REG0D7               0xd7
++#define RADIO_2064_REG0D8               0xd8
++#define RADIO_2064_REG0D9               0xd9
++#define RADIO_2064_REG0DA               0xda
++#define RADIO_2064_REG0DB               0xdb
++#define RADIO_2064_REG0DC               0xdc
++#define RADIO_2064_REG0DD               0xdd
++#define RADIO_2064_REG0DE               0xde
++#define RADIO_2064_REG0DF               0xdf
++#define RADIO_2064_REG0E0               0xe0
++#define RADIO_2064_REG0E1               0xe1
++#define RADIO_2064_REG0E2               0xe2
++#define RADIO_2064_REG0E3               0xe3
++#define RADIO_2064_REG0E4               0xe4
++#define RADIO_2064_REG0E5               0xe5
++#define RADIO_2064_REG0E6               0xe6
++#define RADIO_2064_REG0E7               0xe7
++#define RADIO_2064_REG0E8               0xe8
++#define RADIO_2064_REG0E9               0xe9
++#define RADIO_2064_REG0EA               0xea
++#define RADIO_2064_REG0EB               0xeb
++#define RADIO_2064_REG0EC               0xec
++#define RADIO_2064_REG0ED               0xed
++#define RADIO_2064_REG0EE               0xee
++#define RADIO_2064_REG0EF               0xef
++#define RADIO_2064_REG0F0               0xf0
++#define RADIO_2064_REG0F1               0xf1
++#define RADIO_2064_REG0F2               0xf2
++#define RADIO_2064_REG0F3               0xf3
++#define RADIO_2064_REG0F4               0xf4
++#define RADIO_2064_REG0F5               0xf5
++#define RADIO_2064_REG0F6               0xf6
++#define RADIO_2064_REG0F7               0xf7
++#define RADIO_2064_REG0F8               0xf8
++#define RADIO_2064_REG0F9               0xf9
++#define RADIO_2064_REG0FA               0xfa
++#define RADIO_2064_REG0FB               0xfb
++#define RADIO_2064_REG0FC               0xfc
++#define RADIO_2064_REG0FD               0xfd
++#define RADIO_2064_REG0FE               0xfe
++#define RADIO_2064_REG0FF               0xff
++#define RADIO_2064_REG100               0x100
++#define RADIO_2064_REG101               0x101
++#define RADIO_2064_REG102               0x102
++#define RADIO_2064_REG103               0x103
++#define RADIO_2064_REG104               0x104
++#define RADIO_2064_REG105               0x105
++#define RADIO_2064_REG106               0x106
++#define RADIO_2064_REG107               0x107
++#define RADIO_2064_REG108               0x108
++#define RADIO_2064_REG109               0x109
++#define RADIO_2064_REG10A               0x10a
++#define RADIO_2064_REG10B               0x10b
++#define RADIO_2064_REG10C               0x10c
++#define RADIO_2064_REG10D               0x10d
++#define RADIO_2064_REG10E               0x10e
++#define RADIO_2064_REG10F               0x10f
++#define RADIO_2064_REG110               0x110
++#define RADIO_2064_REG111               0x111
++#define RADIO_2064_REG112               0x112
++#define RADIO_2064_REG113               0x113
++#define RADIO_2064_REG114               0x114
++#define RADIO_2064_REG115               0x115
++#define RADIO_2064_REG116               0x116
++#define RADIO_2064_REG117               0x117
++#define RADIO_2064_REG118               0x118
++#define RADIO_2064_REG119               0x119
++#define RADIO_2064_REG11A               0x11a
++#define RADIO_2064_REG11B               0x11b
++#define RADIO_2064_REG11C               0x11c
++#define RADIO_2064_REG11D               0x11d
++#define RADIO_2064_REG11E               0x11e
++#define RADIO_2064_REG11F               0x11f
++#define RADIO_2064_REG120               0x120
++#define RADIO_2064_REG121               0x121
++#define RADIO_2064_REG122               0x122
++#define RADIO_2064_REG123               0x123
++#define RADIO_2064_REG124               0x124
++#define RADIO_2064_REG125               0x125
++#define RADIO_2064_REG126               0x126
++#define RADIO_2064_REG127               0x127
++#define RADIO_2064_REG128               0x128
++#define RADIO_2064_REG129               0x129
++#define RADIO_2064_REG12A               0x12a
++#define RADIO_2064_REG12B               0x12b
++#define RADIO_2064_REG12C               0x12c
++#define RADIO_2064_REG12D               0x12d
++#define RADIO_2064_REG12E               0x12e
++#define RADIO_2064_REG12F               0x12f
++#define RADIO_2064_REG130               0x130
++
++#define RADIO_2056_SYN                           (0x0 << 12)
++#define RADIO_2056_TX0                           (0x2 << 12)
++#define RADIO_2056_TX1                           (0x3 << 12)
++#define RADIO_2056_RX0                           (0x6 << 12)
++#define RADIO_2056_RX1                           (0x7 << 12)
++#define RADIO_2056_ALLTX                         (0xe << 12)
++#define RADIO_2056_ALLRX                         (0xf << 12)
++
++#define RADIO_2056_SYN_RESERVED_ADDR0            0x0
++#define RADIO_2056_SYN_IDCODE                    0x1
++#define RADIO_2056_SYN_RESERVED_ADDR2            0x2
++#define RADIO_2056_SYN_RESERVED_ADDR3            0x3
++#define RADIO_2056_SYN_RESERVED_ADDR4            0x4
++#define RADIO_2056_SYN_RESERVED_ADDR5            0x5
++#define RADIO_2056_SYN_RESERVED_ADDR6            0x6
++#define RADIO_2056_SYN_RESERVED_ADDR7            0x7
++#define RADIO_2056_SYN_COM_CTRL                  0x8
++#define RADIO_2056_SYN_COM_PU                    0x9
++#define RADIO_2056_SYN_COM_OVR                   0xa
++#define RADIO_2056_SYN_COM_RESET                 0xb
++#define RADIO_2056_SYN_COM_RCAL                  0xc
++#define RADIO_2056_SYN_COM_RC_RXLPF              0xd
++#define RADIO_2056_SYN_COM_RC_TXLPF              0xe
++#define RADIO_2056_SYN_COM_RC_RXHPF              0xf
++#define RADIO_2056_SYN_RESERVED_ADDR16           0x10
++#define RADIO_2056_SYN_RESERVED_ADDR17           0x11
++#define RADIO_2056_SYN_RESERVED_ADDR18           0x12
++#define RADIO_2056_SYN_RESERVED_ADDR19           0x13
++#define RADIO_2056_SYN_RESERVED_ADDR20           0x14
++#define RADIO_2056_SYN_RESERVED_ADDR21           0x15
++#define RADIO_2056_SYN_RESERVED_ADDR22           0x16
++#define RADIO_2056_SYN_RESERVED_ADDR23           0x17
++#define RADIO_2056_SYN_RESERVED_ADDR24           0x18
++#define RADIO_2056_SYN_RESERVED_ADDR25           0x19
++#define RADIO_2056_SYN_RESERVED_ADDR26           0x1a
++#define RADIO_2056_SYN_RESERVED_ADDR27           0x1b
++#define RADIO_2056_SYN_RESERVED_ADDR28           0x1c
++#define RADIO_2056_SYN_RESERVED_ADDR29           0x1d
++#define RADIO_2056_SYN_RESERVED_ADDR30           0x1e
++#define RADIO_2056_SYN_RESERVED_ADDR31           0x1f
++#define RADIO_2056_SYN_GPIO_MASTER1              0x20
++#define RADIO_2056_SYN_GPIO_MASTER2              0x21
++#define RADIO_2056_SYN_TOPBIAS_MASTER            0x22
++#define RADIO_2056_SYN_TOPBIAS_RCAL              0x23
++#define RADIO_2056_SYN_AFEREG                    0x24
++#define RADIO_2056_SYN_TEMPPROCSENSE             0x25
++#define RADIO_2056_SYN_TEMPPROCSENSEIDAC         0x26
++#define RADIO_2056_SYN_TEMPPROCSENSERCAL         0x27
++#define RADIO_2056_SYN_LPO                       0x28
++#define RADIO_2056_SYN_VDDCAL_MASTER             0x29
++#define RADIO_2056_SYN_VDDCAL_IDAC               0x2a
++#define RADIO_2056_SYN_VDDCAL_STATUS             0x2b
++#define RADIO_2056_SYN_RCAL_MASTER               0x2c
++#define RADIO_2056_SYN_RCAL_CODE_OUT             0x2d
++#define RADIO_2056_SYN_RCCAL_CTRL0               0x2e
++#define RADIO_2056_SYN_RCCAL_CTRL1               0x2f
++#define RADIO_2056_SYN_RCCAL_CTRL2               0x30
++#define RADIO_2056_SYN_RCCAL_CTRL3               0x31
++#define RADIO_2056_SYN_RCCAL_CTRL4               0x32
++#define RADIO_2056_SYN_RCCAL_CTRL5               0x33
++#define RADIO_2056_SYN_RCCAL_CTRL6               0x34
++#define RADIO_2056_SYN_RCCAL_CTRL7               0x35
++#define RADIO_2056_SYN_RCCAL_CTRL8               0x36
++#define RADIO_2056_SYN_RCCAL_CTRL9               0x37
++#define RADIO_2056_SYN_RCCAL_CTRL10              0x38
++#define RADIO_2056_SYN_RCCAL_CTRL11              0x39
++#define RADIO_2056_SYN_ZCAL_SPARE1               0x3a
++#define RADIO_2056_SYN_ZCAL_SPARE2               0x3b
++#define RADIO_2056_SYN_PLL_MAST1                 0x3c
++#define RADIO_2056_SYN_PLL_MAST2                 0x3d
++#define RADIO_2056_SYN_PLL_MAST3                 0x3e
++#define RADIO_2056_SYN_PLL_BIAS_RESET            0x3f
++#define RADIO_2056_SYN_PLL_XTAL0                 0x40
++#define RADIO_2056_SYN_PLL_XTAL1                 0x41
++#define RADIO_2056_SYN_PLL_XTAL3                 0x42
++#define RADIO_2056_SYN_PLL_XTAL4                 0x43
++#define RADIO_2056_SYN_PLL_XTAL5                 0x44
++#define RADIO_2056_SYN_PLL_XTAL6                 0x45
++#define RADIO_2056_SYN_PLL_REFDIV                0x46
++#define RADIO_2056_SYN_PLL_PFD                   0x47
++#define RADIO_2056_SYN_PLL_CP1                   0x48
++#define RADIO_2056_SYN_PLL_CP2                   0x49
++#define RADIO_2056_SYN_PLL_CP3                   0x4a
++#define RADIO_2056_SYN_PLL_LOOPFILTER1           0x4b
++#define RADIO_2056_SYN_PLL_LOOPFILTER2           0x4c
++#define RADIO_2056_SYN_PLL_LOOPFILTER3           0x4d
++#define RADIO_2056_SYN_PLL_LOOPFILTER4           0x4e
++#define RADIO_2056_SYN_PLL_LOOPFILTER5           0x4f
++#define RADIO_2056_SYN_PLL_MMD1                  0x50
++#define RADIO_2056_SYN_PLL_MMD2                  0x51
++#define RADIO_2056_SYN_PLL_VCO1                  0x52
++#define RADIO_2056_SYN_PLL_VCO2                  0x53
++#define RADIO_2056_SYN_PLL_MONITOR1              0x54
++#define RADIO_2056_SYN_PLL_MONITOR2              0x55
++#define RADIO_2056_SYN_PLL_VCOCAL1               0x56
++#define RADIO_2056_SYN_PLL_VCOCAL2               0x57
++#define RADIO_2056_SYN_PLL_VCOCAL4               0x58
++#define RADIO_2056_SYN_PLL_VCOCAL5               0x59
++#define RADIO_2056_SYN_PLL_VCOCAL6               0x5a
++#define RADIO_2056_SYN_PLL_VCOCAL7               0x5b
++#define RADIO_2056_SYN_PLL_VCOCAL8               0x5c
++#define RADIO_2056_SYN_PLL_VCOCAL9               0x5d
++#define RADIO_2056_SYN_PLL_VCOCAL10              0x5e
++#define RADIO_2056_SYN_PLL_VCOCAL11              0x5f
++#define RADIO_2056_SYN_PLL_VCOCAL12              0x60
++#define RADIO_2056_SYN_PLL_VCOCAL13              0x61
++#define RADIO_2056_SYN_PLL_VREG                  0x62
++#define RADIO_2056_SYN_PLL_STATUS1               0x63
++#define RADIO_2056_SYN_PLL_STATUS2               0x64
++#define RADIO_2056_SYN_PLL_STATUS3               0x65
++#define RADIO_2056_SYN_LOGEN_PU0                 0x66
++#define RADIO_2056_SYN_LOGEN_PU1                 0x67
++#define RADIO_2056_SYN_LOGEN_PU2                 0x68
++#define RADIO_2056_SYN_LOGEN_PU3                 0x69
++#define RADIO_2056_SYN_LOGEN_PU5                 0x6a
++#define RADIO_2056_SYN_LOGEN_PU6                 0x6b
++#define RADIO_2056_SYN_LOGEN_PU7                 0x6c
++#define RADIO_2056_SYN_LOGEN_PU8                 0x6d
++#define RADIO_2056_SYN_LOGEN_BIAS_RESET          0x6e
++#define RADIO_2056_SYN_LOGEN_RCCR1               0x6f
++#define RADIO_2056_SYN_LOGEN_VCOBUF1             0x70
++#define RADIO_2056_SYN_LOGEN_MIXER1              0x71
++#define RADIO_2056_SYN_LOGEN_MIXER2              0x72
++#define RADIO_2056_SYN_LOGEN_BUF1                0x73
++#define RADIO_2056_SYN_LOGENBUF2                 0x74
++#define RADIO_2056_SYN_LOGEN_BUF3                0x75
++#define RADIO_2056_SYN_LOGEN_BUF4                0x76
++#define RADIO_2056_SYN_LOGEN_DIV1                0x77
++#define RADIO_2056_SYN_LOGEN_DIV2                0x78
++#define RADIO_2056_SYN_LOGEN_DIV3                0x79
++#define RADIO_2056_SYN_LOGEN_ACL1                0x7a
++#define RADIO_2056_SYN_LOGEN_ACL2                0x7b
++#define RADIO_2056_SYN_LOGEN_ACL3                0x7c
++#define RADIO_2056_SYN_LOGEN_ACL4                0x7d
++#define RADIO_2056_SYN_LOGEN_ACL5                0x7e
++#define RADIO_2056_SYN_LOGEN_ACL6                0x7f
++#define RADIO_2056_SYN_LOGEN_ACLOUT              0x80
++#define RADIO_2056_SYN_LOGEN_ACLCAL1             0x81
++#define RADIO_2056_SYN_LOGEN_ACLCAL2             0x82
++#define RADIO_2056_SYN_LOGEN_ACLCAL3             0x83
++#define RADIO_2056_SYN_CALEN                     0x84
++#define RADIO_2056_SYN_LOGEN_PEAKDET1            0x85
++#define RADIO_2056_SYN_LOGEN_CORE_ACL_OVR        0x86
++#define RADIO_2056_SYN_LOGEN_RX_DIFF_ACL_OVR     0x87
++#define RADIO_2056_SYN_LOGEN_TX_DIFF_ACL_OVR     0x88
++#define RADIO_2056_SYN_LOGEN_RX_CMOS_ACL_OVR     0x89
++#define RADIO_2056_SYN_LOGEN_TX_CMOS_ACL_OVR     0x8a
++#define RADIO_2056_SYN_LOGEN_VCOBUF2             0x8b
++#define RADIO_2056_SYN_LOGEN_MIXER3              0x8c
++#define RADIO_2056_SYN_LOGEN_BUF5                0x8d
++#define RADIO_2056_SYN_LOGEN_BUF6                0x8e
++#define RADIO_2056_SYN_LOGEN_CBUFRX1             0x8f
++#define RADIO_2056_SYN_LOGEN_CBUFRX2             0x90
++#define RADIO_2056_SYN_LOGEN_CBUFRX3             0x91
++#define RADIO_2056_SYN_LOGEN_CBUFRX4             0x92
++#define RADIO_2056_SYN_LOGEN_CBUFTX1             0x93
++#define RADIO_2056_SYN_LOGEN_CBUFTX2             0x94
++#define RADIO_2056_SYN_LOGEN_CBUFTX3             0x95
++#define RADIO_2056_SYN_LOGEN_CBUFTX4             0x96
++#define RADIO_2056_SYN_LOGEN_CMOSRX1             0x97
++#define RADIO_2056_SYN_LOGEN_CMOSRX2             0x98
++#define RADIO_2056_SYN_LOGEN_CMOSRX3             0x99
++#define RADIO_2056_SYN_LOGEN_CMOSRX4             0x9a
++#define RADIO_2056_SYN_LOGEN_CMOSTX1             0x9b
++#define RADIO_2056_SYN_LOGEN_CMOSTX2             0x9c
++#define RADIO_2056_SYN_LOGEN_CMOSTX3             0x9d
++#define RADIO_2056_SYN_LOGEN_CMOSTX4             0x9e
++#define RADIO_2056_SYN_LOGEN_VCOBUF2_OVRVAL      0x9f
++#define RADIO_2056_SYN_LOGEN_MIXER3_OVRVAL       0xa0
++#define RADIO_2056_SYN_LOGEN_BUF5_OVRVAL         0xa1
++#define RADIO_2056_SYN_LOGEN_BUF6_OVRVAL         0xa2
++#define RADIO_2056_SYN_LOGEN_CBUFRX1_OVRVAL      0xa3
++#define RADIO_2056_SYN_LOGEN_CBUFRX2_OVRVAL      0xa4
++#define RADIO_2056_SYN_LOGEN_CBUFRX3_OVRVAL      0xa5
++#define RADIO_2056_SYN_LOGEN_CBUFRX4_OVRVAL      0xa6
++#define RADIO_2056_SYN_LOGEN_CBUFTX1_OVRVAL      0xa7
++#define RADIO_2056_SYN_LOGEN_CBUFTX2_OVRVAL      0xa8
++#define RADIO_2056_SYN_LOGEN_CBUFTX3_OVRVAL      0xa9
++#define RADIO_2056_SYN_LOGEN_CBUFTX4_OVRVAL      0xaa
++#define RADIO_2056_SYN_LOGEN_CMOSRX1_OVRVAL      0xab
++#define RADIO_2056_SYN_LOGEN_CMOSRX2_OVRVAL      0xac
++#define RADIO_2056_SYN_LOGEN_CMOSRX3_OVRVAL      0xad
++#define RADIO_2056_SYN_LOGEN_CMOSRX4_OVRVAL      0xae
++#define RADIO_2056_SYN_LOGEN_CMOSTX1_OVRVAL      0xaf
++#define RADIO_2056_SYN_LOGEN_CMOSTX2_OVRVAL      0xb0
++#define RADIO_2056_SYN_LOGEN_CMOSTX3_OVRVAL      0xb1
++#define RADIO_2056_SYN_LOGEN_CMOSTX4_OVRVAL      0xb2
++#define RADIO_2056_SYN_LOGEN_ACL_WAITCNT         0xb3
++#define RADIO_2056_SYN_LOGEN_CORE_CALVALID       0xb4
++#define RADIO_2056_SYN_LOGEN_RX_CMOS_CALVALID    0xb5
++#define RADIO_2056_SYN_LOGEN_TX_CMOS_VALID       0xb6
++
++#define RADIO_2056_TX_RESERVED_ADDR0             0x0
++#define RADIO_2056_TX_IDCODE                     0x1
++#define RADIO_2056_TX_RESERVED_ADDR2             0x2
++#define RADIO_2056_TX_RESERVED_ADDR3             0x3
++#define RADIO_2056_TX_RESERVED_ADDR4             0x4
++#define RADIO_2056_TX_RESERVED_ADDR5             0x5
++#define RADIO_2056_TX_RESERVED_ADDR6             0x6
++#define RADIO_2056_TX_RESERVED_ADDR7             0x7
++#define RADIO_2056_TX_COM_CTRL                   0x8
++#define RADIO_2056_TX_COM_PU                     0x9
++#define RADIO_2056_TX_COM_OVR                    0xa
++#define RADIO_2056_TX_COM_RESET                  0xb
++#define RADIO_2056_TX_COM_RCAL                   0xc
++#define RADIO_2056_TX_COM_RC_RXLPF               0xd
++#define RADIO_2056_TX_COM_RC_TXLPF               0xe
++#define RADIO_2056_TX_COM_RC_RXHPF               0xf
++#define RADIO_2056_TX_RESERVED_ADDR16            0x10
++#define RADIO_2056_TX_RESERVED_ADDR17            0x11
++#define RADIO_2056_TX_RESERVED_ADDR18            0x12
++#define RADIO_2056_TX_RESERVED_ADDR19            0x13
++#define RADIO_2056_TX_RESERVED_ADDR20            0x14
++#define RADIO_2056_TX_RESERVED_ADDR21            0x15
++#define RADIO_2056_TX_RESERVED_ADDR22            0x16
++#define RADIO_2056_TX_RESERVED_ADDR23            0x17
++#define RADIO_2056_TX_RESERVED_ADDR24            0x18
++#define RADIO_2056_TX_RESERVED_ADDR25            0x19
++#define RADIO_2056_TX_RESERVED_ADDR26            0x1a
++#define RADIO_2056_TX_RESERVED_ADDR27            0x1b
++#define RADIO_2056_TX_RESERVED_ADDR28            0x1c
++#define RADIO_2056_TX_RESERVED_ADDR29            0x1d
++#define RADIO_2056_TX_RESERVED_ADDR30            0x1e
++#define RADIO_2056_TX_RESERVED_ADDR31            0x1f
++#define RADIO_2056_TX_IQCAL_GAIN_BW              0x20
++#define RADIO_2056_TX_LOFT_FINE_I                0x21
++#define RADIO_2056_TX_LOFT_FINE_Q                0x22
++#define RADIO_2056_TX_LOFT_COARSE_I              0x23
++#define RADIO_2056_TX_LOFT_COARSE_Q              0x24
++#define RADIO_2056_TX_TX_COM_MASTER1             0x25
++#define RADIO_2056_TX_TX_COM_MASTER2             0x26
++#define RADIO_2056_TX_RXIQCAL_TXMUX              0x27
++#define RADIO_2056_TX_TX_SSI_MASTER              0x28
++#define RADIO_2056_TX_IQCAL_VCM_HG               0x29
++#define RADIO_2056_TX_IQCAL_IDAC                 0x2a
++#define RADIO_2056_TX_TSSI_VCM                   0x2b
++#define RADIO_2056_TX_TX_AMP_DET                 0x2c
++#define RADIO_2056_TX_TX_SSI_MUX                 0x2d
++#define RADIO_2056_TX_TSSIA                      0x2e
++#define RADIO_2056_TX_TSSIG                      0x2f
++#define RADIO_2056_TX_TSSI_MISC1                 0x30
++#define RADIO_2056_TX_TSSI_MISC2                 0x31
++#define RADIO_2056_TX_TSSI_MISC3                 0x32
++#define RADIO_2056_TX_PA_SPARE1                  0x33
++#define RADIO_2056_TX_PA_SPARE2                  0x34
++#define RADIO_2056_TX_INTPAA_MASTER              0x35
++#define RADIO_2056_TX_INTPAA_GAIN                0x36
++#define RADIO_2056_TX_INTPAA_BOOST_TUNE          0x37
++#define RADIO_2056_TX_INTPAA_IAUX_STAT           0x38
++#define RADIO_2056_TX_INTPAA_IAUX_DYN            0x39
++#define RADIO_2056_TX_INTPAA_IMAIN_STAT          0x3a
++#define RADIO_2056_TX_INTPAA_IMAIN_DYN           0x3b
++#define RADIO_2056_TX_INTPAA_CASCBIAS            0x3c
++#define RADIO_2056_TX_INTPAA_PASLOPE             0x3d
++#define RADIO_2056_TX_INTPAA_PA_MISC             0x3e
++#define RADIO_2056_TX_INTPAG_MASTER              0x3f
++#define RADIO_2056_TX_INTPAG_GAIN                0x40
++#define RADIO_2056_TX_INTPAG_BOOST_TUNE          0x41
++#define RADIO_2056_TX_INTPAG_IAUX_STAT           0x42
++#define RADIO_2056_TX_INTPAG_IAUX_DYN            0x43
++#define RADIO_2056_TX_INTPAG_IMAIN_STAT          0x44
++#define RADIO_2056_TX_INTPAG_IMAIN_DYN           0x45
++#define RADIO_2056_TX_INTPAG_CASCBIAS            0x46
++#define RADIO_2056_TX_INTPAG_PASLOPE             0x47
++#define RADIO_2056_TX_INTPAG_PA_MISC             0x48
++#define RADIO_2056_TX_PADA_MASTER                0x49
++#define RADIO_2056_TX_PADA_IDAC                  0x4a
++#define RADIO_2056_TX_PADA_CASCBIAS              0x4b
++#define RADIO_2056_TX_PADA_GAIN                  0x4c
++#define RADIO_2056_TX_PADA_BOOST_TUNE            0x4d
++#define RADIO_2056_TX_PADA_SLOPE                 0x4e
++#define RADIO_2056_TX_PADG_MASTER                0x4f
++#define RADIO_2056_TX_PADG_IDAC                  0x50
++#define RADIO_2056_TX_PADG_CASCBIAS              0x51
++#define RADIO_2056_TX_PADG_GAIN                  0x52
++#define RADIO_2056_TX_PADG_BOOST_TUNE            0x53
++#define RADIO_2056_TX_PADG_SLOPE                 0x54
++#define RADIO_2056_TX_PGAA_MASTER                0x55
++#define RADIO_2056_TX_PGAA_IDAC                  0x56
++#define RADIO_2056_TX_PGAA_GAIN                  0x57
++#define RADIO_2056_TX_PGAA_BOOST_TUNE            0x58
++#define RADIO_2056_TX_PGAA_SLOPE                 0x59
++#define RADIO_2056_TX_PGAA_MISC                  0x5a
++#define RADIO_2056_TX_PGAG_MASTER                0x5b
++#define RADIO_2056_TX_PGAG_IDAC                  0x5c
++#define RADIO_2056_TX_PGAG_GAIN                  0x5d
++#define RADIO_2056_TX_PGAG_BOOST_TUNE            0x5e
++#define RADIO_2056_TX_PGAG_SLOPE                 0x5f
++#define RADIO_2056_TX_PGAG_MISC                  0x60
++#define RADIO_2056_TX_MIXA_MASTER                0x61
++#define RADIO_2056_TX_MIXA_BOOST_TUNE            0x62
++#define RADIO_2056_TX_MIXG                       0x63
++#define RADIO_2056_TX_MIXG_BOOST_TUNE            0x64
++#define RADIO_2056_TX_BB_GM_MASTER               0x65
++#define RADIO_2056_TX_GMBB_GM                    0x66
++#define RADIO_2056_TX_GMBB_IDAC                  0x67
++#define RADIO_2056_TX_TXLPF_MASTER               0x68
++#define RADIO_2056_TX_TXLPF_RCCAL                0x69
++#define RADIO_2056_TX_TXLPF_RCCAL_OFF0           0x6a
++#define RADIO_2056_TX_TXLPF_RCCAL_OFF1           0x6b
++#define RADIO_2056_TX_TXLPF_RCCAL_OFF2           0x6c
++#define RADIO_2056_TX_TXLPF_RCCAL_OFF3           0x6d
++#define RADIO_2056_TX_TXLPF_RCCAL_OFF4           0x6e
++#define RADIO_2056_TX_TXLPF_RCCAL_OFF5           0x6f
++#define RADIO_2056_TX_TXLPF_RCCAL_OFF6           0x70
++#define RADIO_2056_TX_TXLPF_BW                   0x71
++#define RADIO_2056_TX_TXLPF_GAIN                 0x72
++#define RADIO_2056_TX_TXLPF_IDAC                 0x73
++#define RADIO_2056_TX_TXLPF_IDAC_0               0x74
++#define RADIO_2056_TX_TXLPF_IDAC_1               0x75
++#define RADIO_2056_TX_TXLPF_IDAC_2               0x76
++#define RADIO_2056_TX_TXLPF_IDAC_3               0x77
++#define RADIO_2056_TX_TXLPF_IDAC_4               0x78
++#define RADIO_2056_TX_TXLPF_IDAC_5               0x79
++#define RADIO_2056_TX_TXLPF_IDAC_6               0x7a
++#define RADIO_2056_TX_TXLPF_OPAMP_IDAC           0x7b
++#define RADIO_2056_TX_TXLPF_MISC                 0x7c
++#define RADIO_2056_TX_TXSPARE1                   0x7d
++#define RADIO_2056_TX_TXSPARE2                   0x7e
++#define RADIO_2056_TX_TXSPARE3                   0x7f
++#define RADIO_2056_TX_TXSPARE4                   0x80
++#define RADIO_2056_TX_TXSPARE5                   0x81
++#define RADIO_2056_TX_TXSPARE6                   0x82
++#define RADIO_2056_TX_TXSPARE7                   0x83
++#define RADIO_2056_TX_TXSPARE8                   0x84
++#define RADIO_2056_TX_TXSPARE9                   0x85
++#define RADIO_2056_TX_TXSPARE10                  0x86
++#define RADIO_2056_TX_TXSPARE11                  0x87
++#define RADIO_2056_TX_TXSPARE12                  0x88
++#define RADIO_2056_TX_TXSPARE13                  0x89
++#define RADIO_2056_TX_TXSPARE14                  0x8a
++#define RADIO_2056_TX_TXSPARE15                  0x8b
++#define RADIO_2056_TX_TXSPARE16                  0x8c
++#define RADIO_2056_TX_STATUS_INTPA_GAIN          0x8d
++#define RADIO_2056_TX_STATUS_PAD_GAIN            0x8e
++#define RADIO_2056_TX_STATUS_PGA_GAIN            0x8f
++#define RADIO_2056_TX_STATUS_GM_TXLPF_GAIN       0x90
++#define RADIO_2056_TX_STATUS_TXLPF_BW            0x91
++#define RADIO_2056_TX_STATUS_TXLPF_RC            0x92
++#define RADIO_2056_TX_GMBB_IDAC0                 0x93
++#define RADIO_2056_TX_GMBB_IDAC1                 0x94
++#define RADIO_2056_TX_GMBB_IDAC2                 0x95
++#define RADIO_2056_TX_GMBB_IDAC3                 0x96
++#define RADIO_2056_TX_GMBB_IDAC4                 0x97
++#define RADIO_2056_TX_GMBB_IDAC5                 0x98
++#define RADIO_2056_TX_GMBB_IDAC6                 0x99
++#define RADIO_2056_TX_GMBB_IDAC7                 0x9a
++
++#define RADIO_2056_RX_RESERVED_ADDR0             0x0
++#define RADIO_2056_RX_IDCODE                     0x1
++#define RADIO_2056_RX_RESERVED_ADDR2             0x2
++#define RADIO_2056_RX_RESERVED_ADDR3             0x3
++#define RADIO_2056_RX_RESERVED_ADDR4             0x4
++#define RADIO_2056_RX_RESERVED_ADDR5             0x5
++#define RADIO_2056_RX_RESERVED_ADDR6             0x6
++#define RADIO_2056_RX_RESERVED_ADDR7             0x7
++#define RADIO_2056_RX_COM_CTRL                   0x8
++#define RADIO_2056_RX_COM_PU                     0x9
++#define RADIO_2056_RX_COM_OVR                    0xa
++#define RADIO_2056_RX_COM_RESET                  0xb
++#define RADIO_2056_RX_COM_RCAL                   0xc
++#define RADIO_2056_RX_COM_RC_RXLPF               0xd
++#define RADIO_2056_RX_COM_RC_TXLPF               0xe
++#define RADIO_2056_RX_COM_RC_RXHPF               0xf
++#define RADIO_2056_RX_RESERVED_ADDR16            0x10
++#define RADIO_2056_RX_RESERVED_ADDR17            0x11
++#define RADIO_2056_RX_RESERVED_ADDR18            0x12
++#define RADIO_2056_RX_RESERVED_ADDR19            0x13
++#define RADIO_2056_RX_RESERVED_ADDR20            0x14
++#define RADIO_2056_RX_RESERVED_ADDR21            0x15
++#define RADIO_2056_RX_RESERVED_ADDR22            0x16
++#define RADIO_2056_RX_RESERVED_ADDR23            0x17
++#define RADIO_2056_RX_RESERVED_ADDR24            0x18
++#define RADIO_2056_RX_RESERVED_ADDR25            0x19
++#define RADIO_2056_RX_RESERVED_ADDR26            0x1a
++#define RADIO_2056_RX_RESERVED_ADDR27            0x1b
++#define RADIO_2056_RX_RESERVED_ADDR28            0x1c
++#define RADIO_2056_RX_RESERVED_ADDR29            0x1d
++#define RADIO_2056_RX_RESERVED_ADDR30            0x1e
++#define RADIO_2056_RX_RESERVED_ADDR31            0x1f
++#define RADIO_2056_RX_RXIQCAL_RXMUX              0x20
++#define RADIO_2056_RX_RSSI_PU                    0x21
++#define RADIO_2056_RX_RSSI_SEL                   0x22
++#define RADIO_2056_RX_RSSI_GAIN                  0x23
++#define RADIO_2056_RX_RSSI_NB_IDAC               0x24
++#define RADIO_2056_RX_RSSI_WB2I_IDAC_1           0x25
++#define RADIO_2056_RX_RSSI_WB2I_IDAC_2           0x26
++#define RADIO_2056_RX_RSSI_WB2Q_IDAC_1           0x27
++#define RADIO_2056_RX_RSSI_WB2Q_IDAC_2           0x28
++#define RADIO_2056_RX_RSSI_POLE                  0x29
++#define RADIO_2056_RX_RSSI_WB1_IDAC              0x2a
++#define RADIO_2056_RX_RSSI_MISC                  0x2b
++#define RADIO_2056_RX_LNAA_MASTER                0x2c
++#define RADIO_2056_RX_LNAA_TUNE                  0x2d
++#define RADIO_2056_RX_LNAA_GAIN                  0x2e
++#define RADIO_2056_RX_LNA_A_SLOPE                0x2f
++#define RADIO_2056_RX_BIASPOLE_LNAA1_IDAC        0x30
++#define RADIO_2056_RX_LNAA2_IDAC                 0x31
++#define RADIO_2056_RX_LNA1A_MISC                 0x32
++#define RADIO_2056_RX_LNAG_MASTER                0x33
++#define RADIO_2056_RX_LNAG_TUNE                  0x34
++#define RADIO_2056_RX_LNAG_GAIN                  0x35
++#define RADIO_2056_RX_LNA_G_SLOPE                0x36
++#define RADIO_2056_RX_BIASPOLE_LNAG1_IDAC        0x37
++#define RADIO_2056_RX_LNAG2_IDAC                 0x38
++#define RADIO_2056_RX_LNA1G_MISC                 0x39
++#define RADIO_2056_RX_MIXA_MASTER                0x3a
++#define RADIO_2056_RX_MIXA_VCM                   0x3b
++#define RADIO_2056_RX_MIXA_CTRLPTAT              0x3c
++#define RADIO_2056_RX_MIXA_LOB_BIAS              0x3d
++#define RADIO_2056_RX_MIXA_CORE_IDAC             0x3e
++#define RADIO_2056_RX_MIXA_CMFB_IDAC             0x3f
++#define RADIO_2056_RX_MIXA_BIAS_AUX              0x40
++#define RADIO_2056_RX_MIXA_BIAS_MAIN             0x41
++#define RADIO_2056_RX_MIXA_BIAS_MISC             0x42
++#define RADIO_2056_RX_MIXA_MAST_BIAS             0x43
++#define RADIO_2056_RX_MIXG_MASTER                0x44
++#define RADIO_2056_RX_MIXG_VCM                   0x45
++#define RADIO_2056_RX_MIXG_CTRLPTAT              0x46
++#define RADIO_2056_RX_MIXG_LOB_BIAS              0x47
++#define RADIO_2056_RX_MIXG_CORE_IDAC             0x48
++#define RADIO_2056_RX_MIXG_CMFB_IDAC             0x49
++#define RADIO_2056_RX_MIXG_BIAS_AUX              0x4a
++#define RADIO_2056_RX_MIXG_BIAS_MAIN             0x4b
++#define RADIO_2056_RX_MIXG_BIAS_MISC             0x4c
++#define RADIO_2056_RX_MIXG_MAST_BIAS             0x4d
++#define RADIO_2056_RX_TIA_MASTER                 0x4e
++#define RADIO_2056_RX_TIA_IOPAMP                 0x4f
++#define RADIO_2056_RX_TIA_QOPAMP                 0x50
++#define RADIO_2056_RX_TIA_IMISC                  0x51
++#define RADIO_2056_RX_TIA_QMISC                  0x52
++#define RADIO_2056_RX_TIA_GAIN                   0x53
++#define RADIO_2056_RX_TIA_SPARE1                 0x54
++#define RADIO_2056_RX_TIA_SPARE2                 0x55
++#define RADIO_2056_RX_BB_LPF_MASTER              0x56
++#define RADIO_2056_RX_AACI_MASTER                0x57
++#define RADIO_2056_RX_RXLPF_IDAC                 0x58
++#define RADIO_2056_RX_RXLPF_OPAMPBIAS_LOWQ       0x59
++#define RADIO_2056_RX_RXLPF_OPAMPBIAS_HIGHQ      0x5a
++#define RADIO_2056_RX_RXLPF_BIAS_DCCANCEL        0x5b
++#define RADIO_2056_RX_RXLPF_OUTVCM               0x5c
++#define RADIO_2056_RX_RXLPF_INVCM_BODY           0x5d
++#define RADIO_2056_RX_RXLPF_CC_OP                0x5e
++#define RADIO_2056_RX_RXLPF_GAIN                 0x5f
++#define RADIO_2056_RX_RXLPF_Q_BW                 0x60
++#define RADIO_2056_RX_RXLPF_HP_CORNER_BW         0x61
++#define RADIO_2056_RX_RXLPF_RCCAL_HPC            0x62
++#define RADIO_2056_RX_RXHPF_OFF0                 0x63
++#define RADIO_2056_RX_RXHPF_OFF1                 0x64
++#define RADIO_2056_RX_RXHPF_OFF2                 0x65
++#define RADIO_2056_RX_RXHPF_OFF3                 0x66
++#define RADIO_2056_RX_RXHPF_OFF4                 0x67
++#define RADIO_2056_RX_RXHPF_OFF5                 0x68
++#define RADIO_2056_RX_RXHPF_OFF6                 0x69
++#define RADIO_2056_RX_RXHPF_OFF7                 0x6a
++#define RADIO_2056_RX_RXLPF_RCCAL_LPC            0x6b
++#define RADIO_2056_RX_RXLPF_OFF_0                0x6c
++#define RADIO_2056_RX_RXLPF_OFF_1                0x6d
++#define RADIO_2056_RX_RXLPF_OFF_2                0x6e
++#define RADIO_2056_RX_RXLPF_OFF_3                0x6f
++#define RADIO_2056_RX_RXLPF_OFF_4                0x70
++#define RADIO_2056_RX_UNUSED                     0x71
++#define RADIO_2056_RX_VGA_MASTER                 0x72
++#define RADIO_2056_RX_VGA_BIAS                   0x73
++#define RADIO_2056_RX_VGA_BIAS_DCCANCEL          0x74
++#define RADIO_2056_RX_VGA_GAIN                   0x75
++#define RADIO_2056_RX_VGA_HP_CORNER_BW           0x76
++#define RADIO_2056_RX_VGABUF_BIAS                0x77
++#define RADIO_2056_RX_VGABUF_GAIN_BW             0x78
++#define RADIO_2056_RX_TXFBMIX_A                  0x79
++#define RADIO_2056_RX_TXFBMIX_G                  0x7a
++#define RADIO_2056_RX_RXSPARE1                   0x7b
++#define RADIO_2056_RX_RXSPARE2                   0x7c
++#define RADIO_2056_RX_RXSPARE3                   0x7d
++#define RADIO_2056_RX_RXSPARE4                   0x7e
++#define RADIO_2056_RX_RXSPARE5                   0x7f
++#define RADIO_2056_RX_RXSPARE6                   0x80
++#define RADIO_2056_RX_RXSPARE7                   0x81
++#define RADIO_2056_RX_RXSPARE8                   0x82
++#define RADIO_2056_RX_RXSPARE9                   0x83
++#define RADIO_2056_RX_RXSPARE10                  0x84
++#define RADIO_2056_RX_RXSPARE11                  0x85
++#define RADIO_2056_RX_RXSPARE12                  0x86
++#define RADIO_2056_RX_RXSPARE13                  0x87
++#define RADIO_2056_RX_RXSPARE14                  0x88
++#define RADIO_2056_RX_RXSPARE15                  0x89
++#define RADIO_2056_RX_RXSPARE16                  0x8a
++#define RADIO_2056_RX_STATUS_LNAA_GAIN           0x8b
++#define RADIO_2056_RX_STATUS_LNAG_GAIN           0x8c
++#define RADIO_2056_RX_STATUS_MIXTIA_GAIN         0x8d
++#define RADIO_2056_RX_STATUS_RXLPF_GAIN          0x8e
++#define RADIO_2056_RX_STATUS_VGA_BUF_GAIN        0x8f
++#define RADIO_2056_RX_STATUS_RXLPF_Q             0x90
++#define RADIO_2056_RX_STATUS_RXLPF_BUF_BW        0x91
++#define RADIO_2056_RX_STATUS_RXLPF_VGA_HPC       0x92
++#define RADIO_2056_RX_STATUS_RXLPF_RC            0x93
++#define RADIO_2056_RX_STATUS_HPC_RC              0x94
++
++#define RADIO_2056_LNA1_A_PU		0x01
++#define RADIO_2056_LNA2_A_PU		0x02
++#define RADIO_2056_LNA1_G_PU		0x01
++#define RADIO_2056_LNA2_G_PU		0x02
++#define RADIO_2056_MIXA_PU_I		0x01
++#define RADIO_2056_MIXA_PU_Q		0x02
++#define RADIO_2056_MIXA_PU_GM		0x10
++#define RADIO_2056_MIXG_PU_I		0x01
++#define RADIO_2056_MIXG_PU_Q		0x02
++#define RADIO_2056_MIXG_PU_GM		0x10
++#define RADIO_2056_TIA_PU			0x01
++#define RADIO_2056_BB_LPF_PU		0x20
++#define RADIO_2056_W1_PU			0x02
++#define RADIO_2056_W2_PU			0x04
++#define RADIO_2056_NB_PU			0x08
++#define RADIO_2056_RSSI_W1_SEL		0x02
++#define RADIO_2056_RSSI_W2_SEL		0x04
++#define RADIO_2056_RSSI_NB_SEL		0x08
++#define RADIO_2056_VCM_MASK			0x1c
++#define RADIO_2056_RSSI_VCM_SHIFT	0x02
++
++#define RADIO_2057_DACBUF_VINCM_CORE0            0x0
++#define RADIO_2057_IDCODE                        0x1
++#define RADIO_2057_RCCAL_MASTER                  0x2
++#define RADIO_2057_RCCAL_CAP_SIZE                0x3
++#define RADIO_2057_RCAL_CONFIG                   0x4
++#define RADIO_2057_GPAIO_CONFIG                  0x5
++#define RADIO_2057_GPAIO_SEL1                    0x6
++#define RADIO_2057_GPAIO_SEL0                    0x7
++#define RADIO_2057_CLPO_CONFIG                   0x8
++#define RADIO_2057_BANDGAP_CONFIG                0x9
++#define RADIO_2057_BANDGAP_RCAL_TRIM             0xa
++#define RADIO_2057_AFEREG_CONFIG                 0xb
++#define RADIO_2057_TEMPSENSE_CONFIG              0xc
++#define RADIO_2057_XTAL_CONFIG1                  0xd
++#define RADIO_2057_XTAL_ICORE_SIZE               0xe
++#define RADIO_2057_XTAL_BUF_SIZE                 0xf
++#define RADIO_2057_XTAL_PULLCAP_SIZE             0x10
++#define RADIO_2057_RFPLL_MASTER                  0x11
++#define RADIO_2057_VCOMONITOR_VTH_L              0x12
++#define RADIO_2057_VCOMONITOR_VTH_H              0x13
++#define RADIO_2057_VCOCAL_BIASRESET_RFPLLREG_VOUT 0x14
++#define RADIO_2057_VCO_VARCSIZE_IDAC             0x15
++#define RADIO_2057_VCOCAL_COUNTVAL0              0x16
++#define RADIO_2057_VCOCAL_COUNTVAL1              0x17
++#define RADIO_2057_VCOCAL_INTCLK_COUNT           0x18
++#define RADIO_2057_VCOCAL_MASTER                 0x19
++#define RADIO_2057_VCOCAL_NUMCAPCHANGE           0x1a
++#define RADIO_2057_VCOCAL_WINSIZE                0x1b
++#define RADIO_2057_VCOCAL_DELAY_AFTER_REFRESH    0x1c
++#define RADIO_2057_VCOCAL_DELAY_AFTER_CLOSELOOP  0x1d
++#define RADIO_2057_VCOCAL_DELAY_AFTER_OPENLOOP   0x1e
++#define RADIO_2057_VCOCAL_DELAY_BEFORE_OPENLOOP  0x1f
++#define RADIO_2057_VCO_FORCECAPEN_FORCECAP1      0x20
++#define RADIO_2057_VCO_FORCECAP0                 0x21
++#define RADIO_2057_RFPLL_REFMASTER_SPAREXTALSIZE 0x22
++#define RADIO_2057_RFPLL_PFD_RESET_PW            0x23
++#define RADIO_2057_RFPLL_LOOPFILTER_R2           0x24
++#define RADIO_2057_RFPLL_LOOPFILTER_R1           0x25
++#define RADIO_2057_RFPLL_LOOPFILTER_C3           0x26
++#define RADIO_2057_RFPLL_LOOPFILTER_C2           0x27
++#define RADIO_2057_RFPLL_LOOPFILTER_C1           0x28
++#define RADIO_2057_CP_KPD_IDAC                   0x29
++#define RADIO_2057_RFPLL_IDACS                   0x2a
++#define RADIO_2057_RFPLL_MISC_EN                 0x2b
++#define RADIO_2057_RFPLL_MMD0                    0x2c
++#define RADIO_2057_RFPLL_MMD1                    0x2d
++#define RADIO_2057_RFPLL_MISC_CAL_RESETN         0x2e
++#define RADIO_2057_JTAGXTAL_SIZE_CPBIAS_FILTRES  0x2f
++#define RADIO_2057_VCO_ALCREF_BBPLLXTAL_SIZE     0x30
++#define RADIO_2057_VCOCAL_READCAP0               0x31
++#define RADIO_2057_VCOCAL_READCAP1               0x32
++#define RADIO_2057_VCOCAL_STATUS                 0x33
++#define RADIO_2057_LOGEN_PUS                     0x34
++#define RADIO_2057_LOGEN_PTAT_RESETS             0x35
++#define RADIO_2057_VCOBUF_IDACS                  0x36
++#define RADIO_2057_VCOBUF_TUNE                   0x37
++#define RADIO_2057_CMOSBUF_TX2GQ_IDACS           0x38
++#define RADIO_2057_CMOSBUF_TX2GI_IDACS           0x39
++#define RADIO_2057_CMOSBUF_TX5GQ_IDACS           0x3a
++#define RADIO_2057_CMOSBUF_TX5GI_IDACS           0x3b
++#define RADIO_2057_CMOSBUF_RX2GQ_IDACS           0x3c
++#define RADIO_2057_CMOSBUF_RX2GI_IDACS           0x3d
++#define RADIO_2057_CMOSBUF_RX5GQ_IDACS           0x3e
++#define RADIO_2057_CMOSBUF_RX5GI_IDACS           0x3f
++#define RADIO_2057_LOGEN_MX2G_IDACS              0x40
++#define RADIO_2057_LOGEN_MX2G_TUNE               0x41
++#define RADIO_2057_LOGEN_MX5G_IDACS              0x42
++#define RADIO_2057_LOGEN_MX5G_TUNE               0x43
++#define RADIO_2057_LOGEN_MX5G_RCCR               0x44
++#define RADIO_2057_LOGEN_INDBUF2G_IDAC           0x45
++#define RADIO_2057_LOGEN_INDBUF2G_IBOOST         0x46
++#define RADIO_2057_LOGEN_INDBUF2G_TUNE           0x47
++#define RADIO_2057_LOGEN_INDBUF5G_IDAC           0x48
++#define RADIO_2057_LOGEN_INDBUF5G_IBOOST         0x49
++#define RADIO_2057_LOGEN_INDBUF5G_TUNE           0x4a
++#define RADIO_2057_CMOSBUF_TX_RCCR               0x4b
++#define RADIO_2057_CMOSBUF_RX_RCCR               0x4c
++#define RADIO_2057_LOGEN_SEL_PKDET               0x4d
++#define RADIO_2057_CMOSBUF_SHAREIQ_PTAT          0x4e
++#define RADIO_2057_RXTXBIAS_CONFIG_CORE0         0x4f
++#define RADIO_2057_TXGM_TXRF_PUS_CORE0           0x50
++#define RADIO_2057_TXGM_IDAC_BLEED_CORE0         0x51
++#define RADIO_2057_TXGM_GAIN_CORE0               0x56
++#define RADIO_2057_TXGM2G_PKDET_PUS_CORE0        0x57
++#define RADIO_2057_PAD2G_PTATS_CORE0             0x58
++#define RADIO_2057_PAD2G_IDACS_CORE0             0x59
++#define RADIO_2057_PAD2G_BOOST_PU_CORE0          0x5a
++#define RADIO_2057_PAD2G_CASCV_GAIN_CORE0        0x5b
++#define RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE0   0x5c
++#define RADIO_2057_TXMIX2G_LODC_CORE0            0x5d
++#define RADIO_2057_PAD2G_TUNE_PUS_CORE0          0x5e
++#define RADIO_2057_IPA2G_GAIN_CORE0              0x5f
++#define RADIO_2057_TSSI2G_SPARE1_CORE0           0x60
++#define RADIO_2057_TSSI2G_SPARE2_CORE0           0x61
++#define RADIO_2057_IPA2G_TUNEV_CASCV_PTAT_CORE0  0x62
++#define RADIO_2057_IPA2G_IMAIN_CORE0             0x63
++#define RADIO_2057_IPA2G_CASCONV_CORE0           0x64
++#define RADIO_2057_IPA2G_CASCOFFV_CORE0          0x65
++#define RADIO_2057_IPA2G_BIAS_FILTER_CORE0       0x66
++#define RADIO_2057_TX5G_PKDET_CORE0              0x69
++#define RADIO_2057_PGA_PTAT_TXGM5G_PU_CORE0      0x6a
++#define RADIO_2057_PAD5G_PTATS1_CORE0            0x6b
++#define RADIO_2057_PAD5G_CLASS_PTATS2_CORE0      0x6c
++#define RADIO_2057_PGA_BOOSTPTAT_IMAIN_CORE0     0x6d
++#define RADIO_2057_PAD5G_CASCV_IMAIN_CORE0       0x6e
++#define RADIO_2057_TXMIX5G_IBOOST_PAD_IAUX_CORE0 0x6f
++#define RADIO_2057_PGA_BOOST_TUNE_CORE0          0x70
++#define RADIO_2057_PGA_GAIN_CORE0                0x71
++#define RADIO_2057_PAD5G_CASCOFFV_GAIN_PUS_CORE0 0x72
++#define RADIO_2057_TXMIX5G_BOOST_TUNE_CORE0      0x73
++#define RADIO_2057_PAD5G_TUNE_MISC_PUS_CORE0     0x74
++#define RADIO_2057_IPA5G_IAUX_CORE0              0x75
++#define RADIO_2057_IPA5G_GAIN_CORE0              0x76
++#define RADIO_2057_TSSI5G_SPARE1_CORE0           0x77
++#define RADIO_2057_TSSI5G_SPARE2_CORE0           0x78
++#define RADIO_2057_IPA5G_CASCOFFV_PU_CORE0       0x79
++#define RADIO_2057_IPA5G_PTAT_CORE0              0x7a
++#define RADIO_2057_IPA5G_IMAIN_CORE0             0x7b
++#define RADIO_2057_IPA5G_CASCONV_CORE0           0x7c
++#define RADIO_2057_IPA5G_BIAS_FILTER_CORE0       0x7d
++#define RADIO_2057_PAD_BIAS_FILTER_BWS_CORE0     0x80
++#define RADIO_2057_TR2G_CONFIG1_CORE0_NU         0x81
++#define RADIO_2057_TR2G_CONFIG2_CORE0_NU         0x82
++#define RADIO_2057_LNA5G_RFEN_CORE0              0x83
++#define RADIO_2057_TR5G_CONFIG2_CORE0_NU         0x84
++#define RADIO_2057_RXRFBIAS_IBOOST_PU_CORE0      0x85
++#define RADIO_2057_RXRF_IABAND_RXGM_IMAIN_PTAT_CORE0 0x86
++#define RADIO_2057_RXGM_CMFBITAIL_AUXPTAT_CORE0  0x87
++#define RADIO_2057_RXMIX_ICORE_RXGM_IAUX_CORE0   0x88
++#define RADIO_2057_RXMIX_CMFBITAIL_PU_CORE0      0x89
++#define RADIO_2057_LNA2_IMAIN_PTAT_PU_CORE0      0x8a
++#define RADIO_2057_LNA2_IAUX_PTAT_CORE0          0x8b
++#define RADIO_2057_LNA1_IMAIN_PTAT_PU_CORE0      0x8c
++#define RADIO_2057_LNA15G_INPUT_MATCH_TUNE_CORE0 0x8d
++#define RADIO_2057_RXRFBIAS_BANDSEL_CORE0        0x8e
++#define RADIO_2057_TIA_CONFIG_CORE0              0x8f
++#define RADIO_2057_TIA_IQGAIN_CORE0              0x90
++#define RADIO_2057_TIA_IBIAS2_CORE0              0x91
++#define RADIO_2057_TIA_IBIAS1_CORE0              0x92
++#define RADIO_2057_TIA_SPARE_Q_CORE0             0x93
++#define RADIO_2057_TIA_SPARE_I_CORE0             0x94
++#define RADIO_2057_RXMIX2G_PUS_CORE0             0x95
++#define RADIO_2057_RXMIX2G_VCMREFS_CORE0         0x96
++#define RADIO_2057_RXMIX2G_LODC_QI_CORE0         0x97
++#define RADIO_2057_W12G_BW_LNA2G_PUS_CORE0       0x98
++#define RADIO_2057_LNA2G_GAIN_CORE0              0x99
++#define RADIO_2057_LNA2G_TUNE_CORE0              0x9a
++#define RADIO_2057_RXMIX5G_PUS_CORE0             0x9b
++#define RADIO_2057_RXMIX5G_VCMREFS_CORE0         0x9c
++#define RADIO_2057_RXMIX5G_LODC_QI_CORE0         0x9d
++#define RADIO_2057_W15G_BW_LNA5G_PUS_CORE0       0x9e
++#define RADIO_2057_LNA5G_GAIN_CORE0              0x9f
++#define RADIO_2057_LNA5G_TUNE_CORE0              0xa0
++#define RADIO_2057_LPFSEL_TXRX_RXBB_PUS_CORE0    0xa1
++#define RADIO_2057_RXBB_BIAS_MASTER_CORE0        0xa2
++#define RADIO_2057_RXBB_VGABUF_IDACS_CORE0       0xa3
++#define RADIO_2057_LPF_VCMREF_TXBUF_VCMREF_CORE0 0xa4
++#define RADIO_2057_TXBUF_VINCM_CORE0             0xa5
++#define RADIO_2057_TXBUF_IDACS_CORE0             0xa6
++#define RADIO_2057_LPF_RESP_RXBUF_BW_CORE0       0xa7
++#define RADIO_2057_RXBB_CC_CORE0                 0xa8
++#define RADIO_2057_RXBB_SPARE3_CORE0             0xa9
++#define RADIO_2057_RXBB_RCCAL_HPC_CORE0          0xaa
++#define RADIO_2057_LPF_IDACS_CORE0               0xab
++#define RADIO_2057_LPFBYP_DCLOOP_BYP_IDAC_CORE0  0xac
++#define RADIO_2057_TXBUF_GAIN_CORE0              0xad
++#define RADIO_2057_AFELOOPBACK_AACI_RESP_CORE0   0xae
++#define RADIO_2057_RXBUF_DEGEN_CORE0             0xaf
++#define RADIO_2057_RXBB_SPARE2_CORE0             0xb0
++#define RADIO_2057_RXBB_SPARE1_CORE0             0xb1
++#define RADIO_2057_RSSI_MASTER_CORE0             0xb2
++#define RADIO_2057_W2_MASTER_CORE0               0xb3
++#define RADIO_2057_NB_MASTER_CORE0               0xb4
++#define RADIO_2057_W2_IDACS0_Q_CORE0             0xb5
++#define RADIO_2057_W2_IDACS1_Q_CORE0             0xb6
++#define RADIO_2057_W2_IDACS0_I_CORE0             0xb7
++#define RADIO_2057_W2_IDACS1_I_CORE0             0xb8
++#define RADIO_2057_RSSI_GPAIOSEL_W1_IDACS_CORE0  0xb9
++#define RADIO_2057_NB_IDACS_Q_CORE0              0xba
++#define RADIO_2057_NB_IDACS_I_CORE0              0xbb
++#define RADIO_2057_BACKUP4_CORE0                 0xc1
++#define RADIO_2057_BACKUP3_CORE0                 0xc2
++#define RADIO_2057_BACKUP2_CORE0                 0xc3
++#define RADIO_2057_BACKUP1_CORE0                 0xc4
++#define RADIO_2057_SPARE16_CORE0                 0xc5
++#define RADIO_2057_SPARE15_CORE0                 0xc6
++#define RADIO_2057_SPARE14_CORE0                 0xc7
++#define RADIO_2057_SPARE13_CORE0                 0xc8
++#define RADIO_2057_SPARE12_CORE0                 0xc9
++#define RADIO_2057_SPARE11_CORE0                 0xca
++#define RADIO_2057_TX2G_BIAS_RESETS_CORE0        0xcb
++#define RADIO_2057_TX5G_BIAS_RESETS_CORE0        0xcc
++#define RADIO_2057_IQTEST_SEL_PU                 0xcd
++#define RADIO_2057_XTAL_CONFIG2                  0xce
++#define RADIO_2057_BUFS_MISC_LPFBW_CORE0         0xcf
++#define RADIO_2057_TXLPF_RCCAL_CORE0             0xd0
++#define RADIO_2057_RXBB_GPAIOSEL_RXLPF_RCCAL_CORE0 0xd1
++#define RADIO_2057_LPF_GAIN_CORE0                0xd2
++#define RADIO_2057_DACBUF_IDACS_BW_CORE0         0xd3
++#define RADIO_2057_RXTXBIAS_CONFIG_CORE1         0xd4
++#define RADIO_2057_TXGM_TXRF_PUS_CORE1           0xd5
++#define RADIO_2057_TXGM_IDAC_BLEED_CORE1         0xd6
++#define RADIO_2057_TXGM_GAIN_CORE1               0xdb
++#define RADIO_2057_TXGM2G_PKDET_PUS_CORE1        0xdc
++#define RADIO_2057_PAD2G_PTATS_CORE1             0xdd
++#define RADIO_2057_PAD2G_IDACS_CORE1             0xde
++#define RADIO_2057_PAD2G_BOOST_PU_CORE1          0xdf
++#define RADIO_2057_PAD2G_CASCV_GAIN_CORE1        0xe0
++#define RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE1   0xe1
++#define RADIO_2057_TXMIX2G_LODC_CORE1            0xe2
++#define RADIO_2057_PAD2G_TUNE_PUS_CORE1          0xe3
++#define RADIO_2057_IPA2G_GAIN_CORE1              0xe4
++#define RADIO_2057_TSSI2G_SPARE1_CORE1           0xe5
++#define RADIO_2057_TSSI2G_SPARE2_CORE1           0xe6
++#define RADIO_2057_IPA2G_TUNEV_CASCV_PTAT_CORE1  0xe7
++#define RADIO_2057_IPA2G_IMAIN_CORE1             0xe8
++#define RADIO_2057_IPA2G_CASCONV_CORE1           0xe9
++#define RADIO_2057_IPA2G_CASCOFFV_CORE1          0xea
++#define RADIO_2057_IPA2G_BIAS_FILTER_CORE1       0xeb
++#define RADIO_2057_TX5G_PKDET_CORE1              0xee
++#define RADIO_2057_PGA_PTAT_TXGM5G_PU_CORE1      0xef
++#define RADIO_2057_PAD5G_PTATS1_CORE1            0xf0
++#define RADIO_2057_PAD5G_CLASS_PTATS2_CORE1      0xf1
++#define RADIO_2057_PGA_BOOSTPTAT_IMAIN_CORE1     0xf2
++#define RADIO_2057_PAD5G_CASCV_IMAIN_CORE1       0xf3
++#define RADIO_2057_TXMIX5G_IBOOST_PAD_IAUX_CORE1 0xf4
++#define RADIO_2057_PGA_BOOST_TUNE_CORE1          0xf5
++#define RADIO_2057_PGA_GAIN_CORE1                0xf6
++#define RADIO_2057_PAD5G_CASCOFFV_GAIN_PUS_CORE1 0xf7
++#define RADIO_2057_TXMIX5G_BOOST_TUNE_CORE1      0xf8
++#define RADIO_2057_PAD5G_TUNE_MISC_PUS_CORE1     0xf9
++#define RADIO_2057_IPA5G_IAUX_CORE1              0xfa
++#define RADIO_2057_IPA5G_GAIN_CORE1              0xfb
++#define RADIO_2057_TSSI5G_SPARE1_CORE1           0xfc
++#define RADIO_2057_TSSI5G_SPARE2_CORE1           0xfd
++#define RADIO_2057_IPA5G_CASCOFFV_PU_CORE1       0xfe
++#define RADIO_2057_IPA5G_PTAT_CORE1              0xff
++#define RADIO_2057_IPA5G_IMAIN_CORE1             0x100
++#define RADIO_2057_IPA5G_CASCONV_CORE1           0x101
++#define RADIO_2057_IPA5G_BIAS_FILTER_CORE1       0x102
++#define RADIO_2057_PAD_BIAS_FILTER_BWS_CORE1     0x105
++#define RADIO_2057_TR2G_CONFIG1_CORE1_NU         0x106
++#define RADIO_2057_TR2G_CONFIG2_CORE1_NU         0x107
++#define RADIO_2057_LNA5G_RFEN_CORE1              0x108
++#define RADIO_2057_TR5G_CONFIG2_CORE1_NU         0x109
++#define RADIO_2057_RXRFBIAS_IBOOST_PU_CORE1      0x10a
++#define RADIO_2057_RXRF_IABAND_RXGM_IMAIN_PTAT_CORE1 0x10b
++#define RADIO_2057_RXGM_CMFBITAIL_AUXPTAT_CORE1  0x10c
++#define RADIO_2057_RXMIX_ICORE_RXGM_IAUX_CORE1   0x10d
++#define RADIO_2057_RXMIX_CMFBITAIL_PU_CORE1      0x10e
++#define RADIO_2057_LNA2_IMAIN_PTAT_PU_CORE1      0x10f
++#define RADIO_2057_LNA2_IAUX_PTAT_CORE1          0x110
++#define RADIO_2057_LNA1_IMAIN_PTAT_PU_CORE1      0x111
++#define RADIO_2057_LNA15G_INPUT_MATCH_TUNE_CORE1 0x112
++#define RADIO_2057_RXRFBIAS_BANDSEL_CORE1        0x113
++#define RADIO_2057_TIA_CONFIG_CORE1              0x114
++#define RADIO_2057_TIA_IQGAIN_CORE1              0x115
++#define RADIO_2057_TIA_IBIAS2_CORE1              0x116
++#define RADIO_2057_TIA_IBIAS1_CORE1              0x117
++#define RADIO_2057_TIA_SPARE_Q_CORE1             0x118
++#define RADIO_2057_TIA_SPARE_I_CORE1             0x119
++#define RADIO_2057_RXMIX2G_PUS_CORE1             0x11a
++#define RADIO_2057_RXMIX2G_VCMREFS_CORE1         0x11b
++#define RADIO_2057_RXMIX2G_LODC_QI_CORE1         0x11c
++#define RADIO_2057_W12G_BW_LNA2G_PUS_CORE1       0x11d
++#define RADIO_2057_LNA2G_GAIN_CORE1              0x11e
++#define RADIO_2057_LNA2G_TUNE_CORE1              0x11f
++#define RADIO_2057_RXMIX5G_PUS_CORE1             0x120
++#define RADIO_2057_RXMIX5G_VCMREFS_CORE1         0x121
++#define RADIO_2057_RXMIX5G_LODC_QI_CORE1         0x122
++#define RADIO_2057_W15G_BW_LNA5G_PUS_CORE1       0x123
++#define RADIO_2057_LNA5G_GAIN_CORE1              0x124
++#define RADIO_2057_LNA5G_TUNE_CORE1              0x125
++#define RADIO_2057_LPFSEL_TXRX_RXBB_PUS_CORE1    0x126
++#define RADIO_2057_RXBB_BIAS_MASTER_CORE1        0x127
++#define RADIO_2057_RXBB_VGABUF_IDACS_CORE1       0x128
++#define RADIO_2057_LPF_VCMREF_TXBUF_VCMREF_CORE1 0x129
++#define RADIO_2057_TXBUF_VINCM_CORE1             0x12a
++#define RADIO_2057_TXBUF_IDACS_CORE1             0x12b
++#define RADIO_2057_LPF_RESP_RXBUF_BW_CORE1       0x12c
++#define RADIO_2057_RXBB_CC_CORE1                 0x12d
++#define RADIO_2057_RXBB_SPARE3_CORE1             0x12e
++#define RADIO_2057_RXBB_RCCAL_HPC_CORE1          0x12f
++#define RADIO_2057_LPF_IDACS_CORE1               0x130
++#define RADIO_2057_LPFBYP_DCLOOP_BYP_IDAC_CORE1  0x131
++#define RADIO_2057_TXBUF_GAIN_CORE1              0x132
++#define RADIO_2057_AFELOOPBACK_AACI_RESP_CORE1   0x133
++#define RADIO_2057_RXBUF_DEGEN_CORE1             0x134
++#define RADIO_2057_RXBB_SPARE2_CORE1             0x135
++#define RADIO_2057_RXBB_SPARE1_CORE1             0x136
++#define RADIO_2057_RSSI_MASTER_CORE1             0x137
++#define RADIO_2057_W2_MASTER_CORE1               0x138
++#define RADIO_2057_NB_MASTER_CORE1               0x139
++#define RADIO_2057_W2_IDACS0_Q_CORE1             0x13a
++#define RADIO_2057_W2_IDACS1_Q_CORE1             0x13b
++#define RADIO_2057_W2_IDACS0_I_CORE1             0x13c
++#define RADIO_2057_W2_IDACS1_I_CORE1             0x13d
++#define RADIO_2057_RSSI_GPAIOSEL_W1_IDACS_CORE1  0x13e
++#define RADIO_2057_NB_IDACS_Q_CORE1              0x13f
++#define RADIO_2057_NB_IDACS_I_CORE1              0x140
++#define RADIO_2057_BACKUP4_CORE1                 0x146
++#define RADIO_2057_BACKUP3_CORE1                 0x147
++#define RADIO_2057_BACKUP2_CORE1                 0x148
++#define RADIO_2057_BACKUP1_CORE1                 0x149
++#define RADIO_2057_SPARE16_CORE1                 0x14a
++#define RADIO_2057_SPARE15_CORE1                 0x14b
++#define RADIO_2057_SPARE14_CORE1                 0x14c
++#define RADIO_2057_SPARE13_CORE1                 0x14d
++#define RADIO_2057_SPARE12_CORE1                 0x14e
++#define RADIO_2057_SPARE11_CORE1                 0x14f
++#define RADIO_2057_TX2G_BIAS_RESETS_CORE1        0x150
++#define RADIO_2057_TX5G_BIAS_RESETS_CORE1        0x151
++#define RADIO_2057_SPARE8_CORE1                  0x152
++#define RADIO_2057_SPARE7_CORE1                  0x153
++#define RADIO_2057_BUFS_MISC_LPFBW_CORE1         0x154
++#define RADIO_2057_TXLPF_RCCAL_CORE1             0x155
++#define RADIO_2057_RXBB_GPAIOSEL_RXLPF_RCCAL_CORE1 0x156
++#define RADIO_2057_LPF_GAIN_CORE1                0x157
++#define RADIO_2057_DACBUF_IDACS_BW_CORE1         0x158
++#define RADIO_2057_DACBUF_VINCM_CORE1            0x159
++#define RADIO_2057_RCCAL_START_R1_Q1_P1          0x15a
++#define RADIO_2057_RCCAL_X1                      0x15b
++#define RADIO_2057_RCCAL_TRC0                    0x15c
++#define RADIO_2057_RCCAL_TRC1                    0x15d
++#define RADIO_2057_RCCAL_DONE_OSCCAP             0x15e
++#define RADIO_2057_RCCAL_N0_0                    0x15f
++#define RADIO_2057_RCCAL_N0_1                    0x160
++#define RADIO_2057_RCCAL_N1_0                    0x161
++#define RADIO_2057_RCCAL_N1_1                    0x162
++#define RADIO_2057_RCAL_STATUS                   0x163
++#define RADIO_2057_XTALPUOVR_PINCTRL             0x164
++#define RADIO_2057_OVR_REG0                      0x165
++#define RADIO_2057_OVR_REG1                      0x166
++#define RADIO_2057_OVR_REG2                      0x167
++#define RADIO_2057_OVR_REG3                      0x168
++#define RADIO_2057_OVR_REG4                      0x169
++#define RADIO_2057_RCCAL_SCAP_VAL                0x16a
++#define RADIO_2057_RCCAL_BCAP_VAL                0x16b
++#define RADIO_2057_RCCAL_HPC_VAL                 0x16c
++#define RADIO_2057_RCCAL_OVERRIDES               0x16d
++#define RADIO_2057_TX0_IQCAL_GAIN_BW             0x170
++#define RADIO_2057_TX0_LOFT_FINE_I               0x171
++#define RADIO_2057_TX0_LOFT_FINE_Q               0x172
++#define RADIO_2057_TX0_LOFT_COARSE_I             0x173
++#define RADIO_2057_TX0_LOFT_COARSE_Q             0x174
++#define RADIO_2057_TX0_TX_SSI_MASTER             0x175
++#define RADIO_2057_TX0_IQCAL_VCM_HG              0x176
++#define RADIO_2057_TX0_IQCAL_IDAC                0x177
++#define RADIO_2057_TX0_TSSI_VCM                  0x178
++#define RADIO_2057_TX0_TX_SSI_MUX                0x179
++#define RADIO_2057_TX0_TSSIA                     0x17a
++#define RADIO_2057_TX0_TSSIG                     0x17b
++#define RADIO_2057_TX0_TSSI_MISC1                0x17c
++#define RADIO_2057_TX0_TXRXCOUPLE_2G_ATTEN       0x17d
++#define RADIO_2057_TX0_TXRXCOUPLE_2G_PWRUP       0x17e
++#define RADIO_2057_TX0_TXRXCOUPLE_5G_ATTEN       0x17f
++#define RADIO_2057_TX0_TXRXCOUPLE_5G_PWRUP       0x180
++#define RADIO_2057_TX1_IQCAL_GAIN_BW             0x190
++#define RADIO_2057_TX1_LOFT_FINE_I               0x191
++#define RADIO_2057_TX1_LOFT_FINE_Q               0x192
++#define RADIO_2057_TX1_LOFT_COARSE_I             0x193
++#define RADIO_2057_TX1_LOFT_COARSE_Q             0x194
++#define RADIO_2057_TX1_TX_SSI_MASTER             0x195
++#define RADIO_2057_TX1_IQCAL_VCM_HG              0x196
++#define RADIO_2057_TX1_IQCAL_IDAC                0x197
++#define RADIO_2057_TX1_TSSI_VCM                  0x198
++#define RADIO_2057_TX1_TX_SSI_MUX                0x199
++#define RADIO_2057_TX1_TSSIA                     0x19a
++#define RADIO_2057_TX1_TSSIG                     0x19b
++#define RADIO_2057_TX1_TSSI_MISC1                0x19c
++#define RADIO_2057_TX1_TXRXCOUPLE_2G_ATTEN       0x19d
++#define RADIO_2057_TX1_TXRXCOUPLE_2G_PWRUP       0x19e
++#define RADIO_2057_TX1_TXRXCOUPLE_5G_ATTEN       0x19f
++#define RADIO_2057_TX1_TXRXCOUPLE_5G_PWRUP       0x1a0
++#define RADIO_2057_AFE_VCM_CAL_MASTER_CORE0      0x1a1
++#define RADIO_2057_AFE_SET_VCM_I_CORE0           0x1a2
++#define RADIO_2057_AFE_SET_VCM_Q_CORE0           0x1a3
++#define RADIO_2057_AFE_STATUS_VCM_IQADC_CORE0    0x1a4
++#define RADIO_2057_AFE_STATUS_VCM_I_CORE0        0x1a5
++#define RADIO_2057_AFE_STATUS_VCM_Q_CORE0        0x1a6
++#define RADIO_2057_AFE_VCM_CAL_MASTER_CORE1      0x1a7
++#define RADIO_2057_AFE_SET_VCM_I_CORE1           0x1a8
++#define RADIO_2057_AFE_SET_VCM_Q_CORE1           0x1a9
++#define RADIO_2057_AFE_STATUS_VCM_IQADC_CORE1    0x1aa
++#define RADIO_2057_AFE_STATUS_VCM_I_CORE1        0x1ab
++#define RADIO_2057_AFE_STATUS_VCM_Q_CORE1        0x1ac
++
++#define RADIO_2057v7_DACBUF_VINCM_CORE0          0x1ad
++#define RADIO_2057v7_RCCAL_MASTER                0x1ae
++#define RADIO_2057v7_TR2G_CONFIG3_CORE0_NU       0x1af
++#define RADIO_2057v7_TR2G_CONFIG3_CORE1_NU       0x1b0
++#define RADIO_2057v7_LOGEN_PUS1                  0x1b1
++#define RADIO_2057v7_OVR_REG5                    0x1b2
++#define RADIO_2057v7_OVR_REG6                    0x1b3
++#define RADIO_2057v7_OVR_REG7                    0x1b4
++#define RADIO_2057v7_OVR_REG8                    0x1b5
++#define RADIO_2057v7_OVR_REG9                    0x1b6
++#define RADIO_2057v7_OVR_REG10                   0x1b7
++#define RADIO_2057v7_OVR_REG11                   0x1b8
++#define RADIO_2057v7_OVR_REG12                   0x1b9
++#define RADIO_2057v7_OVR_REG13                   0x1ba
++#define RADIO_2057v7_OVR_REG14                   0x1bb
++#define RADIO_2057v7_OVR_REG15                   0x1bc
++#define RADIO_2057v7_OVR_REG16                   0x1bd
++#define RADIO_2057v7_OVR_REG1                    0x1be
++#define RADIO_2057v7_OVR_REG18                   0x1bf
++#define RADIO_2057v7_OVR_REG19                   0x1c0
++#define RADIO_2057v7_OVR_REG20                   0x1c1
++#define RADIO_2057v7_OVR_REG21                   0x1c2
++#define RADIO_2057v7_OVR_REG2                    0x1c3
++#define RADIO_2057v7_OVR_REG23                   0x1c4
++#define RADIO_2057v7_OVR_REG24                   0x1c5
++#define RADIO_2057v7_OVR_REG25                   0x1c6
++#define RADIO_2057v7_OVR_REG26                   0x1c7
++#define RADIO_2057v7_OVR_REG27                   0x1c8
++#define RADIO_2057v7_OVR_REG28                   0x1c9
++#define RADIO_2057v7_IQTEST_SEL_PU2              0x1ca
++
++#define RADIO_2057_VCM_MASK			 0x7
++
++#endif				/* _BRCM_PHY_RADIO_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phyreg_n.h b/drivers/net/wireless/brcm80211/brcmsmac/phy/phyreg_n.h
+new file mode 100644
+index 0000000..a97c3a7
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phyreg_n.h
+@@ -0,0 +1,167 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#define NPHY_TBL_ID_GAIN1		0
++#define NPHY_TBL_ID_GAIN2		1
++#define NPHY_TBL_ID_GAINBITS1		2
++#define NPHY_TBL_ID_GAINBITS2		3
++#define NPHY_TBL_ID_GAINLIMIT		4
++#define NPHY_TBL_ID_WRSSIGainLimit	5
++#define NPHY_TBL_ID_RFSEQ		7
++#define NPHY_TBL_ID_AFECTRL		8
++#define NPHY_TBL_ID_ANTSWCTRLLUT	9
++#define NPHY_TBL_ID_IQLOCAL		15
++#define NPHY_TBL_ID_NOISEVAR		16
++#define NPHY_TBL_ID_SAMPLEPLAY		17
++#define NPHY_TBL_ID_CORE1TXPWRCTL	26
++#define NPHY_TBL_ID_CORE2TXPWRCTL	27
++#define NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL	30
++
++#define NPHY_TBL_ID_EPSILONTBL0   31
++#define NPHY_TBL_ID_SCALARTBL0    32
++#define NPHY_TBL_ID_EPSILONTBL1   33
++#define NPHY_TBL_ID_SCALARTBL1    34
++
++#define	NPHY_TO_BPHY_OFF	0xc00
++
++#define NPHY_BandControl_currentBand			0x0001
++#define RFCC_CHIP0_PU			0x0400
++#define RFCC_POR_FORCE			0x0040
++#define RFCC_OE_POR_FORCE		0x0080
++#define NPHY_RfctrlIntc_override_OFF			0
++#define NPHY_RfctrlIntc_override_TRSW			1
++#define NPHY_RfctrlIntc_override_PA				2
++#define NPHY_RfctrlIntc_override_EXT_LNA_PU		3
++#define NPHY_RfctrlIntc_override_EXT_LNA_GAIN	4
++#define RIFS_ENABLE			0x80
++#define BPHY_BAND_SEL_UP20		0x10
++#define NPHY_MLenable			0x02
++
++#define NPHY_RfseqMode_CoreActv_override 0x0001
++#define NPHY_RfseqMode_Trigger_override	0x0002
++#define NPHY_RfseqCoreActv_TxRxChain0	(0x11)
++#define NPHY_RfseqCoreActv_TxRxChain1	(0x22)
++
++#define NPHY_RfseqTrigger_rx2tx		0x0001
++#define NPHY_RfseqTrigger_tx2rx		0x0002
++#define NPHY_RfseqTrigger_updategainh	0x0004
++#define NPHY_RfseqTrigger_updategainl	0x0008
++#define NPHY_RfseqTrigger_updategainu	0x0010
++#define NPHY_RfseqTrigger_reset2rx	0x0020
++#define NPHY_RfseqStatus_rx2tx		0x0001
++#define NPHY_RfseqStatus_tx2rx		0x0002
++#define NPHY_RfseqStatus_updategainh	0x0004
++#define NPHY_RfseqStatus_updategainl	0x0008
++#define NPHY_RfseqStatus_updategainu	0x0010
++#define NPHY_RfseqStatus_reset2rx	0x0020
++#define NPHY_ClassifierCtrl_cck_en	0x1
++#define NPHY_ClassifierCtrl_ofdm_en	0x2
++#define NPHY_ClassifierCtrl_waited_en	0x4
++#define NPHY_IQFlip_ADC1		0x0001
++#define NPHY_IQFlip_ADC2		0x0010
++#define NPHY_sampleCmd_STOP		0x0002
++
++#define RX_GF_OR_MM			0x0004
++#define RX_GF_MM_AUTO			0x0100
++
++#define NPHY_iqloCalCmdGctl_IQLO_CAL_EN	0x8000
++
++#define NPHY_IqestCmd_iqstart		0x1
++#define NPHY_IqestCmd_iqMode		0x2
++
++#define NPHY_TxPwrCtrlCmd_pwrIndex_init		0x40
++#define NPHY_TxPwrCtrlCmd_pwrIndex_init_rev7	0x19
++
++#define PRIM_SEL_UP20		0x8000
++
++#define NPHY_RFSEQ_RX2TX		0x0
++#define NPHY_RFSEQ_TX2RX		0x1
++#define NPHY_RFSEQ_RESET2RX		0x2
++#define NPHY_RFSEQ_UPDATEGAINH		0x3
++#define NPHY_RFSEQ_UPDATEGAINL		0x4
++#define NPHY_RFSEQ_UPDATEGAINU		0x5
++
++#define NPHY_RFSEQ_CMD_NOP		0x0
++#define NPHY_RFSEQ_CMD_RXG_FBW		0x1
++#define NPHY_RFSEQ_CMD_TR_SWITCH	0x2
++#define NPHY_RFSEQ_CMD_EXT_PA		0x3
++#define NPHY_RFSEQ_CMD_RXPD_TXPD	0x4
++#define NPHY_RFSEQ_CMD_TX_GAIN		0x5
++#define NPHY_RFSEQ_CMD_RX_GAIN		0x6
++#define NPHY_RFSEQ_CMD_SET_HPF_BW	0x7
++#define NPHY_RFSEQ_CMD_CLR_HIQ_DIS	0x8
++#define NPHY_RFSEQ_CMD_END		0xf
++
++#define NPHY_REV3_RFSEQ_CMD_NOP		0x0
++#define NPHY_REV3_RFSEQ_CMD_RXG_FBW	0x1
++#define NPHY_REV3_RFSEQ_CMD_TR_SWITCH	0x2
++#define NPHY_REV3_RFSEQ_CMD_INT_PA_PU	0x3
++#define NPHY_REV3_RFSEQ_CMD_EXT_PA	0x4
++#define NPHY_REV3_RFSEQ_CMD_RXPD_TXPD	0x5
++#define NPHY_REV3_RFSEQ_CMD_TX_GAIN	0x6
++#define NPHY_REV3_RFSEQ_CMD_RX_GAIN	0x7
++#define NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS	0x8
++#define NPHY_REV3_RFSEQ_CMD_SET_HPF_H_HPC	0x9
++#define NPHY_REV3_RFSEQ_CMD_SET_LPF_H_HPC	0xa
++#define NPHY_REV3_RFSEQ_CMD_SET_HPF_M_HPC	0xb
++#define NPHY_REV3_RFSEQ_CMD_SET_LPF_M_HPC	0xc
++#define NPHY_REV3_RFSEQ_CMD_SET_HPF_L_HPC	0xd
++#define NPHY_REV3_RFSEQ_CMD_SET_LPF_L_HPC	0xe
++#define NPHY_REV3_RFSEQ_CMD_CLR_RXRX_BIAS	0xf
++#define NPHY_REV3_RFSEQ_CMD_END		0x1f
++
++#define NPHY_RSSI_SEL_W1		0x0
++#define NPHY_RSSI_SEL_W2		0x1
++#define NPHY_RSSI_SEL_NB		0x2
++#define NPHY_RSSI_SEL_IQ		0x3
++#define NPHY_RSSI_SEL_TSSI_2G		0x4
++#define NPHY_RSSI_SEL_TSSI_5G		0x5
++#define NPHY_RSSI_SEL_TBD		0x6
++
++#define NPHY_RAIL_I			0x0
++#define NPHY_RAIL_Q			0x1
++
++#define NPHY_FORCESIG_DECODEGATEDCLKS	0x8
++
++#define NPHY_REV7_RfctrlOverride_cmd_rxrf_pu 0x0
++#define NPHY_REV7_RfctrlOverride_cmd_rx_pu   0x1
++#define NPHY_REV7_RfctrlOverride_cmd_tx_pu   0x2
++#define NPHY_REV7_RfctrlOverride_cmd_rxgain  0x3
++#define NPHY_REV7_RfctrlOverride_cmd_txgain  0x4
++
++#define NPHY_REV7_RXGAINCODE_RFMXGAIN_MASK 0x000ff
++#define NPHY_REV7_RXGAINCODE_LPFGAIN_MASK  0x0ff00
++#define NPHY_REV7_RXGAINCODE_DVGAGAIN_MASK 0xf0000
++
++#define NPHY_REV7_TXGAINCODE_TGAIN_MASK     0x7fff
++#define NPHY_REV7_TXGAINCODE_LPFGAIN_MASK   0x8000
++#define NPHY_REV7_TXGAINCODE_BIQ0GAIN_SHIFT 14
++
++#define NPHY_REV7_RFCTRLOVERRIDE_ID0 0x0
++#define NPHY_REV7_RFCTRLOVERRIDE_ID1 0x1
++#define NPHY_REV7_RFCTRLOVERRIDE_ID2 0x2
++
++#define NPHY_IqestIqAccLo(core)  ((core == 0) ? 0x12c : 0x134)
++
++#define NPHY_IqestIqAccHi(core)  ((core == 0) ? 0x12d : 0x135)
++
++#define NPHY_IqestipwrAccLo(core)  ((core == 0) ? 0x12e : 0x136)
++
++#define NPHY_IqestipwrAccHi(core)  ((core == 0) ? 0x12f : 0x137)
++
++#define NPHY_IqestqpwrAccLo(core)  ((core == 0) ? 0x130 : 0x138)
++
++#define NPHY_IqestqpwrAccHi(core)  ((core == 0) ? 0x131 : 0x139)
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c
+new file mode 100644
+index 0000000..622c01c
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c
+@@ -0,0 +1,3250 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#include <types.h>
++#include "phytbl_lcn.h"
++
++static const u32 dot11lcn_gain_tbl_rev0[] = {
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000004,
++	0x00000000,
++	0x00000004,
++	0x00000008,
++	0x00000001,
++	0x00000005,
++	0x00000009,
++	0x0000000d,
++	0x0000004d,
++	0x0000008d,
++	0x0000000d,
++	0x0000004d,
++	0x0000008d,
++	0x000000cd,
++	0x0000004f,
++	0x0000008f,
++	0x000000cf,
++	0x000000d3,
++	0x00000113,
++	0x00000513,
++	0x00000913,
++	0x00000953,
++	0x00000d53,
++	0x00001153,
++	0x00001193,
++	0x00005193,
++	0x00009193,
++	0x0000d193,
++	0x00011193,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000004,
++	0x00000000,
++	0x00000004,
++	0x00000008,
++	0x00000001,
++	0x00000005,
++	0x00000009,
++	0x0000000d,
++	0x0000004d,
++	0x0000008d,
++	0x0000000d,
++	0x0000004d,
++	0x0000008d,
++	0x000000cd,
++	0x0000004f,
++	0x0000008f,
++	0x000000cf,
++	0x000000d3,
++	0x00000113,
++	0x00000513,
++	0x00000913,
++	0x00000953,
++	0x00000d53,
++	0x00001153,
++	0x00005153,
++	0x00009153,
++	0x0000d153,
++	0x00011153,
++	0x00015153,
++	0x00019153,
++	0x0001d153,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++};
++
++static const u32 dot11lcn_gain_tbl_rev1[] = {
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000008,
++	0x00000004,
++	0x00000008,
++	0x00000001,
++	0x00000005,
++	0x00000009,
++	0x0000000D,
++	0x00000011,
++	0x00000051,
++	0x00000091,
++	0x00000011,
++	0x00000051,
++	0x00000091,
++	0x000000d1,
++	0x00000053,
++	0x00000093,
++	0x000000d3,
++	0x000000d7,
++	0x00000117,
++	0x00000517,
++	0x00000917,
++	0x00000957,
++	0x00000d57,
++	0x00001157,
++	0x00001197,
++	0x00005197,
++	0x00009197,
++	0x0000d197,
++	0x00011197,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000008,
++	0x00000004,
++	0x00000008,
++	0x00000001,
++	0x00000005,
++	0x00000009,
++	0x0000000D,
++	0x00000011,
++	0x00000051,
++	0x00000091,
++	0x00000011,
++	0x00000051,
++	0x00000091,
++	0x000000d1,
++	0x00000053,
++	0x00000093,
++	0x000000d3,
++	0x000000d7,
++	0x00000117,
++	0x00000517,
++	0x00000917,
++	0x00000957,
++	0x00000d57,
++	0x00001157,
++	0x00005157,
++	0x00009157,
++	0x0000d157,
++	0x00011157,
++	0x00015157,
++	0x00019157,
++	0x0001d157,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++};
++
++static const u16 dot11lcn_aux_gain_idx_tbl_rev0[] = {
++	0x0401,
++	0x0402,
++	0x0403,
++	0x0404,
++	0x0405,
++	0x0406,
++	0x0407,
++	0x0408,
++	0x0409,
++	0x040a,
++	0x058b,
++	0x058c,
++	0x058d,
++	0x058e,
++	0x058f,
++	0x0090,
++	0x0091,
++	0x0092,
++	0x0193,
++	0x0194,
++	0x0195,
++	0x0196,
++	0x0197,
++	0x0198,
++	0x0199,
++	0x019a,
++	0x019b,
++	0x019c,
++	0x019d,
++	0x019e,
++	0x019f,
++	0x01a0,
++	0x01a1,
++	0x01a2,
++	0x01a3,
++	0x01a4,
++	0x01a5,
++	0x0000,
++};
++
++static const u32 dot11lcn_gain_idx_tbl_rev0[] = {
++	0x00000000,
++	0x00000000,
++	0x10000000,
++	0x00000000,
++	0x20000000,
++	0x00000000,
++	0x30000000,
++	0x00000000,
++	0x40000000,
++	0x00000000,
++	0x50000000,
++	0x00000000,
++	0x60000000,
++	0x00000000,
++	0x70000000,
++	0x00000000,
++	0x80000000,
++	0x00000000,
++	0x90000000,
++	0x00000008,
++	0xa0000000,
++	0x00000008,
++	0xb0000000,
++	0x00000008,
++	0xc0000000,
++	0x00000008,
++	0xd0000000,
++	0x00000008,
++	0xe0000000,
++	0x00000008,
++	0xf0000000,
++	0x00000008,
++	0x00000000,
++	0x00000009,
++	0x10000000,
++	0x00000009,
++	0x20000000,
++	0x00000019,
++	0x30000000,
++	0x00000019,
++	0x40000000,
++	0x00000019,
++	0x50000000,
++	0x00000019,
++	0x60000000,
++	0x00000019,
++	0x70000000,
++	0x00000019,
++	0x80000000,
++	0x00000019,
++	0x90000000,
++	0x00000019,
++	0xa0000000,
++	0x00000019,
++	0xb0000000,
++	0x00000019,
++	0xc0000000,
++	0x00000019,
++	0xd0000000,
++	0x00000019,
++	0xe0000000,
++	0x00000019,
++	0xf0000000,
++	0x00000019,
++	0x00000000,
++	0x0000001a,
++	0x10000000,
++	0x0000001a,
++	0x20000000,
++	0x0000001a,
++	0x30000000,
++	0x0000001a,
++	0x40000000,
++	0x0000001a,
++	0x50000000,
++	0x00000002,
++	0x60000000,
++	0x00000002,
++	0x70000000,
++	0x00000002,
++	0x80000000,
++	0x00000002,
++	0x90000000,
++	0x00000002,
++	0xa0000000,
++	0x00000002,
++	0xb0000000,
++	0x00000002,
++	0xc0000000,
++	0x0000000a,
++	0xd0000000,
++	0x0000000a,
++	0xe0000000,
++	0x0000000a,
++	0xf0000000,
++	0x0000000a,
++	0x00000000,
++	0x0000000b,
++	0x10000000,
++	0x0000000b,
++	0x20000000,
++	0x0000000b,
++	0x30000000,
++	0x0000000b,
++	0x40000000,
++	0x0000000b,
++	0x50000000,
++	0x0000001b,
++	0x60000000,
++	0x0000001b,
++	0x70000000,
++	0x0000001b,
++	0x80000000,
++	0x0000001b,
++	0x90000000,
++	0x0000001b,
++	0xa0000000,
++	0x0000001b,
++	0xb0000000,
++	0x0000001b,
++	0xc0000000,
++	0x0000001b,
++	0xd0000000,
++	0x0000001b,
++	0xe0000000,
++	0x0000001b,
++	0xf0000000,
++	0x0000001b,
++	0x00000000,
++	0x0000001c,
++	0x10000000,
++	0x0000001c,
++	0x20000000,
++	0x0000001c,
++	0x30000000,
++	0x0000001c,
++	0x40000000,
++	0x0000001c,
++	0x50000000,
++	0x0000001c,
++	0x60000000,
++	0x0000001c,
++	0x70000000,
++	0x0000001c,
++	0x80000000,
++	0x0000001c,
++	0x90000000,
++	0x0000001c,
++};
++
++static const u16 dot11lcn_aux_gain_idx_tbl_2G[] = {
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0001,
++	0x0080,
++	0x0081,
++	0x0100,
++	0x0101,
++	0x0180,
++	0x0181,
++	0x0182,
++	0x0183,
++	0x0184,
++	0x0185,
++	0x0186,
++	0x0187,
++	0x0188,
++	0x0285,
++	0x0289,
++	0x028a,
++	0x028b,
++	0x028c,
++	0x028d,
++	0x028e,
++	0x028f,
++	0x0290,
++	0x0291,
++	0x0292,
++	0x0293,
++	0x0294,
++	0x0295,
++	0x0296,
++	0x0297,
++	0x0298,
++	0x0299,
++	0x029a,
++	0x0000
++};
++
++static const u8 dot11lcn_gain_val_tbl_2G[] = {
++	0xfc,
++	0x02,
++	0x08,
++	0x0e,
++	0x13,
++	0x1b,
++	0xfc,
++	0x02,
++	0x08,
++	0x0e,
++	0x13,
++	0x1b,
++	0xfc,
++	0x00,
++	0x0c,
++	0x03,
++	0xeb,
++	0xfe,
++	0x07,
++	0x0b,
++	0x0f,
++	0xfb,
++	0xfe,
++	0x01,
++	0x05,
++	0x08,
++	0x0b,
++	0x0e,
++	0x11,
++	0x14,
++	0x17,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x03,
++	0x06,
++	0x09,
++	0x0c,
++	0x0f,
++	0x12,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x03,
++	0x06,
++	0x09,
++	0x0c,
++	0x0f,
++	0x12,
++	0x15,
++	0x18,
++	0x1b,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00
++};
++
++static const u32 dot11lcn_gain_idx_tbl_2G[] = {
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x10000000,
++	0x00000000,
++	0x00000000,
++	0x00000008,
++	0x10000000,
++	0x00000008,
++	0x00000000,
++	0x00000010,
++	0x10000000,
++	0x00000010,
++	0x00000000,
++	0x00000018,
++	0x10000000,
++	0x00000018,
++	0x20000000,
++	0x00000018,
++	0x30000000,
++	0x00000018,
++	0x40000000,
++	0x00000018,
++	0x50000000,
++	0x00000018,
++	0x60000000,
++	0x00000018,
++	0x70000000,
++	0x00000018,
++	0x80000000,
++	0x00000018,
++	0x50000000,
++	0x00000028,
++	0x90000000,
++	0x00000028,
++	0xa0000000,
++	0x00000028,
++	0xb0000000,
++	0x00000028,
++	0xc0000000,
++	0x00000028,
++	0xd0000000,
++	0x00000028,
++	0xe0000000,
++	0x00000028,
++	0xf0000000,
++	0x00000028,
++	0x00000000,
++	0x00000029,
++	0x10000000,
++	0x00000029,
++	0x20000000,
++	0x00000029,
++	0x30000000,
++	0x00000029,
++	0x40000000,
++	0x00000029,
++	0x50000000,
++	0x00000029,
++	0x60000000,
++	0x00000029,
++	0x70000000,
++	0x00000029,
++	0x80000000,
++	0x00000029,
++	0x90000000,
++	0x00000029,
++	0xa0000000,
++	0x00000029,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x10000000,
++	0x00000000,
++	0x00000000,
++	0x00000008,
++	0x10000000,
++	0x00000008,
++	0x00000000,
++	0x00000010,
++	0x10000000,
++	0x00000010,
++	0x00000000,
++	0x00000018,
++	0x10000000,
++	0x00000018,
++	0x20000000,
++	0x00000018,
++	0x30000000,
++	0x00000018,
++	0x40000000,
++	0x00000018,
++	0x50000000,
++	0x00000018,
++	0x60000000,
++	0x00000018,
++	0x70000000,
++	0x00000018,
++	0x80000000,
++	0x00000018,
++	0x50000000,
++	0x00000028,
++	0x90000000,
++	0x00000028,
++	0xa0000000,
++	0x00000028,
++	0xb0000000,
++	0x00000028,
++	0xc0000000,
++	0x00000028,
++	0xd0000000,
++	0x00000028,
++	0xe0000000,
++	0x00000028,
++	0xf0000000,
++	0x00000028,
++	0x00000000,
++	0x00000029,
++	0x10000000,
++	0x00000029,
++	0x20000000,
++	0x00000029,
++	0x30000000,
++	0x00000029,
++	0x40000000,
++	0x00000029,
++	0x50000000,
++	0x00000029,
++	0x60000000,
++	0x00000029,
++	0x70000000,
++	0x00000029,
++	0x80000000,
++	0x00000029,
++	0x90000000,
++	0x00000029,
++	0xa0000000,
++	0x00000029,
++	0xb0000000,
++	0x00000029,
++	0xc0000000,
++	0x00000029,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000
++};
++
++static const u32 dot11lcn_gain_tbl_2G[] = {
++	0x00000000,
++	0x00000004,
++	0x00000008,
++	0x00000001,
++	0x00000005,
++	0x00000009,
++	0x0000000d,
++	0x0000004d,
++	0x0000008d,
++	0x00000049,
++	0x00000089,
++	0x000000c9,
++	0x0000004b,
++	0x0000008b,
++	0x000000cb,
++	0x000000cf,
++	0x0000010f,
++	0x0000050f,
++	0x0000090f,
++	0x0000094f,
++	0x00000d4f,
++	0x0000114f,
++	0x0000118f,
++	0x0000518f,
++	0x0000918f,
++	0x0000d18f,
++	0x0001118f,
++	0x0001518f,
++	0x0001918f,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000
++};
++
++static const u32 dot11lcn_gain_tbl_extlna_2G[] = {
++	0x00000000,
++	0x00000004,
++	0x00000008,
++	0x00000001,
++	0x00000005,
++	0x00000009,
++	0x0000000d,
++	0x00000003,
++	0x00000007,
++	0x0000000b,
++	0x0000000f,
++	0x0000004f,
++	0x0000008f,
++	0x000000cf,
++	0x0000010f,
++	0x0000014f,
++	0x0000018f,
++	0x0000058f,
++	0x0000098f,
++	0x00000d8f,
++	0x00008000,
++	0x00008004,
++	0x00008008,
++	0x00008001,
++	0x00008005,
++	0x00008009,
++	0x0000800d,
++	0x00008003,
++	0x00008007,
++	0x0000800b,
++	0x0000800f,
++	0x0000804f,
++	0x0000808f,
++	0x000080cf,
++	0x0000810f,
++	0x0000814f,
++	0x0000818f,
++	0x0000858f,
++	0x0000898f,
++	0x00008d8f,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000
++};
++
++static const u16 dot11lcn_aux_gain_idx_tbl_extlna_2G[] = {
++	0x0400,
++	0x0400,
++	0x0400,
++	0x0400,
++	0x0400,
++	0x0400,
++	0x0400,
++	0x0400,
++	0x0400,
++	0x0401,
++	0x0402,
++	0x0403,
++	0x0404,
++	0x0483,
++	0x0484,
++	0x0485,
++	0x0486,
++	0x0583,
++	0x0584,
++	0x0585,
++	0x0587,
++	0x0588,
++	0x0589,
++	0x058a,
++	0x0687,
++	0x0688,
++	0x0689,
++	0x068a,
++	0x068b,
++	0x068c,
++	0x068d,
++	0x068e,
++	0x068f,
++	0x0690,
++	0x0691,
++	0x0692,
++	0x0693,
++	0x0000
++};
++
++static const u8 dot11lcn_gain_val_tbl_extlna_2G[] = {
++	0xfc,
++	0x02,
++	0x08,
++	0x0e,
++	0x13,
++	0x1b,
++	0xfc,
++	0x02,
++	0x08,
++	0x0e,
++	0x13,
++	0x1b,
++	0xfc,
++	0x00,
++	0x0f,
++	0x03,
++	0xeb,
++	0xfe,
++	0x07,
++	0x0b,
++	0x0f,
++	0xfb,
++	0xfe,
++	0x01,
++	0x05,
++	0x08,
++	0x0b,
++	0x0e,
++	0x11,
++	0x14,
++	0x17,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x03,
++	0x06,
++	0x09,
++	0x0c,
++	0x0f,
++	0x12,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x03,
++	0x06,
++	0x09,
++	0x0c,
++	0x0f,
++	0x12,
++	0x15,
++	0x18,
++	0x1b,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00
++};
++
++static const u32 dot11lcn_gain_idx_tbl_extlna_2G[] = {
++	0x00000000,
++	0x00000040,
++	0x00000000,
++	0x00000040,
++	0x00000000,
++	0x00000040,
++	0x00000000,
++	0x00000040,
++	0x00000000,
++	0x00000040,
++	0x00000000,
++	0x00000040,
++	0x00000000,
++	0x00000040,
++	0x00000000,
++	0x00000040,
++	0x00000000,
++	0x00000040,
++	0x10000000,
++	0x00000040,
++	0x20000000,
++	0x00000040,
++	0x30000000,
++	0x00000040,
++	0x40000000,
++	0x00000040,
++	0x30000000,
++	0x00000048,
++	0x40000000,
++	0x00000048,
++	0x50000000,
++	0x00000048,
++	0x60000000,
++	0x00000048,
++	0x30000000,
++	0x00000058,
++	0x40000000,
++	0x00000058,
++	0x50000000,
++	0x00000058,
++	0x70000000,
++	0x00000058,
++	0x80000000,
++	0x00000058,
++	0x90000000,
++	0x00000058,
++	0xa0000000,
++	0x00000058,
++	0x70000000,
++	0x00000068,
++	0x80000000,
++	0x00000068,
++	0x90000000,
++	0x00000068,
++	0xa0000000,
++	0x00000068,
++	0xb0000000,
++	0x00000068,
++	0xc0000000,
++	0x00000068,
++	0xd0000000,
++	0x00000068,
++	0xe0000000,
++	0x00000068,
++	0xf0000000,
++	0x00000068,
++	0x00000000,
++	0x00000069,
++	0x10000000,
++	0x00000069,
++	0x20000000,
++	0x00000069,
++	0x30000000,
++	0x00000069,
++	0x40000000,
++	0x00000041,
++	0x40000000,
++	0x00000041,
++	0x40000000,
++	0x00000041,
++	0x40000000,
++	0x00000041,
++	0x40000000,
++	0x00000041,
++	0x40000000,
++	0x00000041,
++	0x40000000,
++	0x00000041,
++	0x40000000,
++	0x00000041,
++	0x40000000,
++	0x00000041,
++	0x50000000,
++	0x00000041,
++	0x60000000,
++	0x00000041,
++	0x70000000,
++	0x00000041,
++	0x80000000,
++	0x00000041,
++	0x70000000,
++	0x00000049,
++	0x80000000,
++	0x00000049,
++	0x90000000,
++	0x00000049,
++	0xa0000000,
++	0x00000049,
++	0x70000000,
++	0x00000059,
++	0x80000000,
++	0x00000059,
++	0x90000000,
++	0x00000059,
++	0xb0000000,
++	0x00000059,
++	0xc0000000,
++	0x00000059,
++	0xd0000000,
++	0x00000059,
++	0xe0000000,
++	0x00000059,
++	0xb0000000,
++	0x00000069,
++	0xc0000000,
++	0x00000069,
++	0xd0000000,
++	0x00000069,
++	0xe0000000,
++	0x00000069,
++	0xf0000000,
++	0x00000069,
++	0x00000000,
++	0x0000006a,
++	0x10000000,
++	0x0000006a,
++	0x20000000,
++	0x0000006a,
++	0x30000000,
++	0x0000006a,
++	0x40000000,
++	0x0000006a,
++	0x50000000,
++	0x0000006a,
++	0x60000000,
++	0x0000006a,
++	0x70000000,
++	0x0000006a,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000
++};
++
++static const u32 dot11lcn_aux_gain_idx_tbl_5G[] = {
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0001,
++	0x0002,
++	0x0003,
++	0x0004,
++	0x0083,
++	0x0084,
++	0x0085,
++	0x0086,
++	0x0087,
++	0x0186,
++	0x0187,
++	0x0188,
++	0x0189,
++	0x018a,
++	0x018b,
++	0x018c,
++	0x018d,
++	0x018e,
++	0x018f,
++	0x0190,
++	0x0191,
++	0x0192,
++	0x0193,
++	0x0194,
++	0x0195,
++	0x0196,
++	0x0197,
++	0x0198,
++	0x0199,
++	0x019a,
++	0x019b,
++	0x019c,
++	0x019d,
++	0x0000
++};
++
++static const u32 dot11lcn_gain_val_tbl_5G[] = {
++	0xf7,
++	0xfd,
++	0x00,
++	0x04,
++	0x04,
++	0x04,
++	0xf7,
++	0xfd,
++	0x00,
++	0x04,
++	0x04,
++	0x04,
++	0xf6,
++	0x00,
++	0x0c,
++	0x03,
++	0xeb,
++	0xfe,
++	0x06,
++	0x0a,
++	0x10,
++	0x00,
++	0x03,
++	0x06,
++	0x09,
++	0x0c,
++	0x0f,
++	0x12,
++	0x15,
++	0x18,
++	0x1b,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x03,
++	0x06,
++	0x09,
++	0x0c,
++	0x0f,
++	0x12,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x03,
++	0x06,
++	0x09,
++	0x0c,
++	0x0f,
++	0x12,
++	0x15,
++	0x18,
++	0x1b,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00
++};
++
++static const u32 dot11lcn_gain_idx_tbl_5G[] = {
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x10000000,
++	0x00000000,
++	0x20000000,
++	0x00000000,
++	0x30000000,
++	0x00000000,
++	0x40000000,
++	0x00000000,
++	0x30000000,
++	0x00000008,
++	0x40000000,
++	0x00000008,
++	0x50000000,
++	0x00000008,
++	0x60000000,
++	0x00000008,
++	0x70000000,
++	0x00000008,
++	0x60000000,
++	0x00000018,
++	0x70000000,
++	0x00000018,
++	0x80000000,
++	0x00000018,
++	0x90000000,
++	0x00000018,
++	0xa0000000,
++	0x00000018,
++	0xb0000000,
++	0x00000018,
++	0xc0000000,
++	0x00000018,
++	0xd0000000,
++	0x00000018,
++	0xe0000000,
++	0x00000018,
++	0xf0000000,
++	0x00000018,
++	0x00000000,
++	0x00000019,
++	0x10000000,
++	0x00000019,
++	0x20000000,
++	0x00000019,
++	0x30000000,
++	0x00000019,
++	0x40000000,
++	0x00000019,
++	0x50000000,
++	0x00000019,
++	0x60000000,
++	0x00000019,
++	0x70000000,
++	0x00000019,
++	0x80000000,
++	0x00000019,
++	0x90000000,
++	0x00000019,
++	0xa0000000,
++	0x00000019,
++	0xb0000000,
++	0x00000019,
++	0xc0000000,
++	0x00000019,
++	0xd0000000,
++	0x00000019,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000
++};
++
++static const u32 dot11lcn_gain_tbl_5G[] = {
++	0x00000000,
++	0x00000040,
++	0x00000080,
++	0x00000001,
++	0x00000005,
++	0x00000009,
++	0x0000000d,
++	0x00000011,
++	0x00000015,
++	0x00000055,
++	0x00000095,
++	0x00000017,
++	0x0000001b,
++	0x0000005b,
++	0x0000009b,
++	0x000000db,
++	0x0000011b,
++	0x0000015b,
++	0x0000019b,
++	0x0000059b,
++	0x0000099b,
++	0x00000d9b,
++	0x0000119b,
++	0x0000519b,
++	0x0000919b,
++	0x0000d19b,
++	0x0001119b,
++	0x0001519b,
++	0x0001919b,
++	0x0001d19b,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000
++};
++
++const struct phytbl_info dot11lcnphytbl_rx_gain_info_rev0[] = {
++	{&dot11lcn_gain_tbl_rev0,
++	 sizeof(dot11lcn_gain_tbl_rev0) / sizeof(dot11lcn_gain_tbl_rev0[0]), 18,
++	 0, 32}
++	,
++	{&dot11lcn_aux_gain_idx_tbl_rev0,
++	 sizeof(dot11lcn_aux_gain_idx_tbl_rev0) /
++	 sizeof(dot11lcn_aux_gain_idx_tbl_rev0[0]), 14, 0, 16}
++	,
++	{&dot11lcn_gain_idx_tbl_rev0,
++	 sizeof(dot11lcn_gain_idx_tbl_rev0) /
++	 sizeof(dot11lcn_gain_idx_tbl_rev0[0]), 13, 0, 32}
++	,
++};
++
++static const struct phytbl_info dot11lcnphytbl_rx_gain_info_rev1[] = {
++	{&dot11lcn_gain_tbl_rev1,
++	 sizeof(dot11lcn_gain_tbl_rev1) / sizeof(dot11lcn_gain_tbl_rev1[0]), 18,
++	 0, 32}
++	,
++	{&dot11lcn_aux_gain_idx_tbl_rev0,
++	 sizeof(dot11lcn_aux_gain_idx_tbl_rev0) /
++	 sizeof(dot11lcn_aux_gain_idx_tbl_rev0[0]), 14, 0, 16}
++	,
++	{&dot11lcn_gain_idx_tbl_rev0,
++	 sizeof(dot11lcn_gain_idx_tbl_rev0) /
++	 sizeof(dot11lcn_gain_idx_tbl_rev0[0]), 13, 0, 32}
++	,
++};
++
++const struct phytbl_info dot11lcnphytbl_rx_gain_info_2G_rev2[] = {
++	{&dot11lcn_gain_tbl_2G,
++	 sizeof(dot11lcn_gain_tbl_2G) / sizeof(dot11lcn_gain_tbl_2G[0]), 18, 0,
++	 32}
++	,
++	{&dot11lcn_aux_gain_idx_tbl_2G,
++	 sizeof(dot11lcn_aux_gain_idx_tbl_2G) /
++	 sizeof(dot11lcn_aux_gain_idx_tbl_2G[0]), 14, 0, 16}
++	,
++	{&dot11lcn_gain_idx_tbl_2G,
++	 sizeof(dot11lcn_gain_idx_tbl_2G) / sizeof(dot11lcn_gain_idx_tbl_2G[0]),
++	 13, 0, 32}
++	,
++	{&dot11lcn_gain_val_tbl_2G,
++	 sizeof(dot11lcn_gain_val_tbl_2G) / sizeof(dot11lcn_gain_val_tbl_2G[0]),
++	 17, 0, 8}
++};
++
++const struct phytbl_info dot11lcnphytbl_rx_gain_info_5G_rev2[] = {
++	{&dot11lcn_gain_tbl_5G,
++	 sizeof(dot11lcn_gain_tbl_5G) / sizeof(dot11lcn_gain_tbl_5G[0]), 18, 0,
++	 32}
++	,
++	{&dot11lcn_aux_gain_idx_tbl_5G,
++	 sizeof(dot11lcn_aux_gain_idx_tbl_5G) /
++	 sizeof(dot11lcn_aux_gain_idx_tbl_5G[0]), 14, 0, 16}
++	,
++	{&dot11lcn_gain_idx_tbl_5G,
++	 sizeof(dot11lcn_gain_idx_tbl_5G) / sizeof(dot11lcn_gain_idx_tbl_5G[0]),
++	 13, 0, 32}
++	,
++	{&dot11lcn_gain_val_tbl_5G,
++	 sizeof(dot11lcn_gain_val_tbl_5G) / sizeof(dot11lcn_gain_val_tbl_5G[0]),
++	 17, 0, 8}
++};
++
++const struct phytbl_info dot11lcnphytbl_rx_gain_info_extlna_2G_rev2[] = {
++	{&dot11lcn_gain_tbl_extlna_2G,
++	 sizeof(dot11lcn_gain_tbl_extlna_2G) /
++	 sizeof(dot11lcn_gain_tbl_extlna_2G[0]), 18, 0, 32}
++	,
++	{&dot11lcn_aux_gain_idx_tbl_extlna_2G,
++	 sizeof(dot11lcn_aux_gain_idx_tbl_extlna_2G) /
++	 sizeof(dot11lcn_aux_gain_idx_tbl_extlna_2G[0]), 14, 0, 16}
++	,
++	{&dot11lcn_gain_idx_tbl_extlna_2G,
++	 sizeof(dot11lcn_gain_idx_tbl_extlna_2G) /
++	 sizeof(dot11lcn_gain_idx_tbl_extlna_2G[0]), 13, 0, 32}
++	,
++	{&dot11lcn_gain_val_tbl_extlna_2G,
++	 sizeof(dot11lcn_gain_val_tbl_extlna_2G) /
++	 sizeof(dot11lcn_gain_val_tbl_extlna_2G[0]), 17, 0, 8}
++};
++
++const struct phytbl_info dot11lcnphytbl_rx_gain_info_extlna_5G_rev2[] = {
++	{&dot11lcn_gain_tbl_5G,
++	 sizeof(dot11lcn_gain_tbl_5G) / sizeof(dot11lcn_gain_tbl_5G[0]), 18, 0,
++	 32}
++	,
++	{&dot11lcn_aux_gain_idx_tbl_5G,
++	 sizeof(dot11lcn_aux_gain_idx_tbl_5G) /
++	 sizeof(dot11lcn_aux_gain_idx_tbl_5G[0]), 14, 0, 16}
++	,
++	{&dot11lcn_gain_idx_tbl_5G,
++	 sizeof(dot11lcn_gain_idx_tbl_5G) / sizeof(dot11lcn_gain_idx_tbl_5G[0]),
++	 13, 0, 32}
++	,
++	{&dot11lcn_gain_val_tbl_5G,
++	 sizeof(dot11lcn_gain_val_tbl_5G) / sizeof(dot11lcn_gain_val_tbl_5G[0]),
++	 17, 0, 8}
++};
++
++const u32 dot11lcnphytbl_rx_gain_info_sz_rev0 =
++	sizeof(dot11lcnphytbl_rx_gain_info_rev0) /
++	sizeof(dot11lcnphytbl_rx_gain_info_rev0[0]);
++
++const u32 dot11lcnphytbl_rx_gain_info_2G_rev2_sz =
++	sizeof(dot11lcnphytbl_rx_gain_info_2G_rev2) /
++	sizeof(dot11lcnphytbl_rx_gain_info_2G_rev2[0]);
++
++const u32 dot11lcnphytbl_rx_gain_info_5G_rev2_sz =
++	sizeof(dot11lcnphytbl_rx_gain_info_5G_rev2) /
++	sizeof(dot11lcnphytbl_rx_gain_info_5G_rev2[0]);
++
++static const u16 dot11lcn_min_sig_sq_tbl_rev0[] = {
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++};
++
++static const u16 dot11lcn_noise_scale_tbl_rev0[] = {
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++};
++
++static const u32 dot11lcn_fltr_ctrl_tbl_rev0[] = {
++	0x000141f8,
++	0x000021f8,
++	0x000021fb,
++	0x000041fb,
++	0x0001fe4b,
++	0x0000217b,
++	0x00002133,
++	0x000040eb,
++	0x0001fea3,
++	0x0000024b,
++};
++
++static const u32 dot11lcn_ps_ctrl_tbl_rev0[] = {
++	0x00100001,
++	0x00200010,
++	0x00300001,
++	0x00400010,
++	0x00500022,
++	0x00600122,
++	0x00700222,
++	0x00800322,
++	0x00900422,
++	0x00a00522,
++	0x00b00622,
++	0x00c00722,
++	0x00d00822,
++	0x00f00922,
++	0x00100a22,
++	0x00200b22,
++	0x00300c22,
++	0x00400d22,
++	0x00500e22,
++	0x00600f22,
++};
++
++static const u16 dot11lcn_sw_ctrl_tbl_4313_epa_rev0_combo[] = {
++	0x0007,
++	0x0005,
++	0x0006,
++	0x0004,
++	0x0007,
++	0x0005,
++	0x0006,
++	0x0004,
++	0x0007,
++	0x0005,
++	0x0006,
++	0x0004,
++	0x0007,
++	0x0005,
++	0x0006,
++	0x0004,
++	0x000b,
++	0x000b,
++	0x000a,
++	0x000a,
++	0x000b,
++	0x000b,
++	0x000a,
++	0x000a,
++	0x000b,
++	0x000b,
++	0x000a,
++	0x000a,
++	0x000b,
++	0x000b,
++	0x000a,
++	0x000a,
++	0x0007,
++	0x0005,
++	0x0006,
++	0x0004,
++	0x0007,
++	0x0005,
++	0x0006,
++	0x0004,
++	0x0007,
++	0x0005,
++	0x0006,
++	0x0004,
++	0x0007,
++	0x0005,
++	0x0006,
++	0x0004,
++	0x000b,
++	0x000b,
++	0x000a,
++	0x000a,
++	0x000b,
++	0x000b,
++	0x000a,
++	0x000a,
++	0x000b,
++	0x000b,
++	0x000a,
++	0x000a,
++	0x000b,
++	0x000b,
++	0x000a,
++	0x000a,
++
++};
++
++static const u16 dot11lcn_sw_ctrl_tbl_4313_bt_epa_p250_rev0[] = {
++	0x0007,
++	0x0005,
++	0x0002,
++	0x0000,
++	0x0007,
++	0x0005,
++	0x0002,
++	0x0000,
++	0x0007,
++	0x0005,
++	0x0002,
++	0x0000,
++	0x0007,
++	0x0005,
++	0x0002,
++	0x0000,
++	0x0007,
++	0x0007,
++	0x0002,
++	0x0002,
++	0x0007,
++	0x0007,
++	0x0002,
++	0x0002,
++	0x0007,
++	0x0007,
++	0x0002,
++	0x0002,
++	0x0007,
++	0x0007,
++	0x0002,
++	0x0002,
++	0x0007,
++	0x0005,
++	0x0002,
++	0x0000,
++	0x0007,
++	0x0005,
++	0x0002,
++	0x0000,
++	0x0007,
++	0x0005,
++	0x0002,
++	0x0000,
++	0x0007,
++	0x0005,
++	0x0002,
++	0x0000,
++	0x0007,
++	0x0007,
++	0x0002,
++	0x0002,
++	0x0007,
++	0x0007,
++	0x0002,
++	0x0002,
++	0x0007,
++	0x0007,
++	0x0002,
++	0x0002,
++	0x0007,
++	0x0007,
++	0x0002,
++	0x0002,
++};
++
++static const u16 dot11lcn_sw_ctrl_tbl_4313_epa_rev0[] = {
++	0x0002,
++	0x0008,
++	0x0004,
++	0x0001,
++	0x0002,
++	0x0008,
++	0x0004,
++	0x0001,
++	0x0002,
++	0x0008,
++	0x0004,
++	0x0001,
++	0x0002,
++	0x0008,
++	0x0004,
++	0x0001,
++	0x0002,
++	0x0008,
++	0x0004,
++	0x0001,
++	0x0002,
++	0x0008,
++	0x0004,
++	0x0001,
++	0x0002,
++	0x0008,
++	0x0004,
++	0x0001,
++	0x0002,
++	0x0008,
++	0x0004,
++	0x0001,
++	0x0002,
++	0x0008,
++	0x0004,
++	0x0001,
++	0x0002,
++	0x0008,
++	0x0004,
++	0x0001,
++	0x0002,
++	0x0008,
++	0x0004,
++	0x0001,
++	0x0002,
++	0x0008,
++	0x0004,
++	0x0001,
++	0x0002,
++	0x0008,
++	0x0004,
++	0x0001,
++	0x0002,
++	0x0008,
++	0x0004,
++	0x0001,
++	0x0002,
++	0x0008,
++	0x0004,
++	0x0001,
++	0x0002,
++	0x0008,
++	0x0004,
++	0x0001,
++};
++
++static const u16 dot11lcn_sw_ctrl_tbl_4313_rev0[] = {
++	0x000a,
++	0x0009,
++	0x0006,
++	0x0005,
++	0x000a,
++	0x0009,
++	0x0006,
++	0x0005,
++	0x000a,
++	0x0009,
++	0x0006,
++	0x0005,
++	0x000a,
++	0x0009,
++	0x0006,
++	0x0005,
++	0x000a,
++	0x0009,
++	0x0006,
++	0x0005,
++	0x000a,
++	0x0009,
++	0x0006,
++	0x0005,
++	0x000a,
++	0x0009,
++	0x0006,
++	0x0005,
++	0x000a,
++	0x0009,
++	0x0006,
++	0x0005,
++	0x000a,
++	0x0009,
++	0x0006,
++	0x0005,
++	0x000a,
++	0x0009,
++	0x0006,
++	0x0005,
++	0x000a,
++	0x0009,
++	0x0006,
++	0x0005,
++	0x000a,
++	0x0009,
++	0x0006,
++	0x0005,
++	0x000a,
++	0x0009,
++	0x0006,
++	0x0005,
++	0x000a,
++	0x0009,
++	0x0006,
++	0x0005,
++	0x000a,
++	0x0009,
++	0x0006,
++	0x0005,
++	0x000a,
++	0x0009,
++	0x0006,
++	0x0005,
++};
++
++static const u16 dot11lcn_sw_ctrl_tbl_rev0[] = {
++	0x0004,
++	0x0004,
++	0x0002,
++	0x0002,
++	0x0004,
++	0x0004,
++	0x0002,
++	0x0002,
++	0x0004,
++	0x0004,
++	0x0002,
++	0x0002,
++	0x0004,
++	0x0004,
++	0x0002,
++	0x0002,
++	0x0004,
++	0x0004,
++	0x0002,
++	0x0002,
++	0x0004,
++	0x0004,
++	0x0002,
++	0x0002,
++	0x0004,
++	0x0004,
++	0x0002,
++	0x0002,
++	0x0004,
++	0x0004,
++	0x0002,
++	0x0002,
++	0x0004,
++	0x0004,
++	0x0002,
++	0x0002,
++	0x0004,
++	0x0004,
++	0x0002,
++	0x0002,
++	0x0004,
++	0x0004,
++	0x0002,
++	0x0002,
++	0x0004,
++	0x0004,
++	0x0002,
++	0x0002,
++	0x0004,
++	0x0004,
++	0x0002,
++	0x0002,
++	0x0004,
++	0x0004,
++	0x0002,
++	0x0002,
++	0x0004,
++	0x0004,
++	0x0002,
++	0x0002,
++	0x0004,
++	0x0004,
++	0x0002,
++	0x0002,
++};
++
++static const u8 dot11lcn_nf_table_rev0[] = {
++	0x5f,
++	0x36,
++	0x29,
++	0x1f,
++	0x5f,
++	0x36,
++	0x29,
++	0x1f,
++	0x5f,
++	0x36,
++	0x29,
++	0x1f,
++	0x5f,
++	0x36,
++	0x29,
++	0x1f,
++};
++
++static const u8 dot11lcn_gain_val_tbl_rev0[] = {
++	0x09,
++	0x0f,
++	0x14,
++	0x18,
++	0xfe,
++	0x07,
++	0x0b,
++	0x0f,
++	0xfb,
++	0xfe,
++	0x01,
++	0x05,
++	0x08,
++	0x0b,
++	0x0e,
++	0x11,
++	0x14,
++	0x17,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x03,
++	0x06,
++	0x09,
++	0x0c,
++	0x0f,
++	0x12,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x03,
++	0x06,
++	0x09,
++	0x0c,
++	0x0f,
++	0x12,
++	0x15,
++	0x18,
++	0x1b,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x03,
++	0xeb,
++	0x00,
++	0x00,
++};
++
++static const u8 dot11lcn_spur_tbl_rev0[] = {
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x02,
++	0x03,
++	0x01,
++	0x03,
++	0x02,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x02,
++	0x03,
++	0x01,
++	0x03,
++	0x02,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++};
++
++static const u16 dot11lcn_unsup_mcs_tbl_rev0[] = {
++	0x001a,
++	0x0034,
++	0x004e,
++	0x0068,
++	0x009c,
++	0x00d0,
++	0x00ea,
++	0x0104,
++	0x0034,
++	0x0068,
++	0x009c,
++	0x00d0,
++	0x0138,
++	0x01a0,
++	0x01d4,
++	0x0208,
++	0x004e,
++	0x009c,
++	0x00ea,
++	0x0138,
++	0x01d4,
++	0x0270,
++	0x02be,
++	0x030c,
++	0x0068,
++	0x00d0,
++	0x0138,
++	0x01a0,
++	0x0270,
++	0x0340,
++	0x03a8,
++	0x0410,
++	0x0018,
++	0x009c,
++	0x00d0,
++	0x0104,
++	0x00ea,
++	0x0138,
++	0x0186,
++	0x00d0,
++	0x0104,
++	0x0104,
++	0x0138,
++	0x016c,
++	0x016c,
++	0x01a0,
++	0x0138,
++	0x0186,
++	0x0186,
++	0x01d4,
++	0x0222,
++	0x0222,
++	0x0270,
++	0x0104,
++	0x0138,
++	0x016c,
++	0x0138,
++	0x016c,
++	0x01a0,
++	0x01d4,
++	0x01a0,
++	0x01d4,
++	0x0208,
++	0x0208,
++	0x023c,
++	0x0186,
++	0x01d4,
++	0x0222,
++	0x01d4,
++	0x0222,
++	0x0270,
++	0x02be,
++	0x0270,
++	0x02be,
++	0x030c,
++	0x030c,
++	0x035a,
++	0x0036,
++	0x006c,
++	0x00a2,
++	0x00d8,
++	0x0144,
++	0x01b0,
++	0x01e6,
++	0x021c,
++	0x006c,
++	0x00d8,
++	0x0144,
++	0x01b0,
++	0x0288,
++	0x0360,
++	0x03cc,
++	0x0438,
++	0x00a2,
++	0x0144,
++	0x01e6,
++	0x0288,
++	0x03cc,
++	0x0510,
++	0x05b2,
++	0x0654,
++	0x00d8,
++	0x01b0,
++	0x0288,
++	0x0360,
++	0x0510,
++	0x06c0,
++	0x0798,
++	0x0870,
++	0x0018,
++	0x0144,
++	0x01b0,
++	0x021c,
++	0x01e6,
++	0x0288,
++	0x032a,
++	0x01b0,
++	0x021c,
++	0x021c,
++	0x0288,
++	0x02f4,
++	0x02f4,
++	0x0360,
++	0x0288,
++	0x032a,
++	0x032a,
++	0x03cc,
++	0x046e,
++	0x046e,
++	0x0510,
++	0x021c,
++	0x0288,
++	0x02f4,
++	0x0288,
++	0x02f4,
++	0x0360,
++	0x03cc,
++	0x0360,
++	0x03cc,
++	0x0438,
++	0x0438,
++	0x04a4,
++	0x032a,
++	0x03cc,
++	0x046e,
++	0x03cc,
++	0x046e,
++	0x0510,
++	0x05b2,
++	0x0510,
++	0x05b2,
++	0x0654,
++	0x0654,
++	0x06f6,
++};
++
++static const u16 dot11lcn_iq_local_tbl_rev0[] = {
++	0x0200,
++	0x0300,
++	0x0400,
++	0x0600,
++	0x0800,
++	0x0b00,
++	0x1000,
++	0x1001,
++	0x1002,
++	0x1003,
++	0x1004,
++	0x1005,
++	0x1006,
++	0x1007,
++	0x1707,
++	0x2007,
++	0x2d07,
++	0x4007,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0200,
++	0x0300,
++	0x0400,
++	0x0600,
++	0x0800,
++	0x0b00,
++	0x1000,
++	0x1001,
++	0x1002,
++	0x1003,
++	0x1004,
++	0x1005,
++	0x1006,
++	0x1007,
++	0x1707,
++	0x2007,
++	0x2d07,
++	0x4007,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x4000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++};
++
++static const u32 dot11lcn_papd_compdelta_tbl_rev0[] = {
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++};
++
++const struct phytbl_info dot11lcnphytbl_info_rev0[] = {
++	{&dot11lcn_min_sig_sq_tbl_rev0,
++	 sizeof(dot11lcn_min_sig_sq_tbl_rev0) /
++	 sizeof(dot11lcn_min_sig_sq_tbl_rev0[0]), 2, 0, 16}
++	,
++	{&dot11lcn_noise_scale_tbl_rev0,
++	 sizeof(dot11lcn_noise_scale_tbl_rev0) /
++	 sizeof(dot11lcn_noise_scale_tbl_rev0[0]), 1, 0, 16}
++	,
++	{&dot11lcn_fltr_ctrl_tbl_rev0,
++	 sizeof(dot11lcn_fltr_ctrl_tbl_rev0) /
++	 sizeof(dot11lcn_fltr_ctrl_tbl_rev0[0]), 11, 0, 32}
++	,
++	{&dot11lcn_ps_ctrl_tbl_rev0,
++	 sizeof(dot11lcn_ps_ctrl_tbl_rev0) /
++	 sizeof(dot11lcn_ps_ctrl_tbl_rev0[0]), 12, 0, 32}
++	,
++	{&dot11lcn_gain_idx_tbl_rev0,
++	 sizeof(dot11lcn_gain_idx_tbl_rev0) /
++	 sizeof(dot11lcn_gain_idx_tbl_rev0[0]), 13, 0, 32}
++	,
++	{&dot11lcn_aux_gain_idx_tbl_rev0,
++	 sizeof(dot11lcn_aux_gain_idx_tbl_rev0) /
++	 sizeof(dot11lcn_aux_gain_idx_tbl_rev0[0]), 14, 0, 16}
++	,
++	{&dot11lcn_sw_ctrl_tbl_rev0,
++	 sizeof(dot11lcn_sw_ctrl_tbl_rev0) /
++	 sizeof(dot11lcn_sw_ctrl_tbl_rev0[0]), 15, 0, 16}
++	,
++	{&dot11lcn_nf_table_rev0,
++	 sizeof(dot11lcn_nf_table_rev0) / sizeof(dot11lcn_nf_table_rev0[0]), 16,
++	 0, 8}
++	,
++	{&dot11lcn_gain_val_tbl_rev0,
++	 sizeof(dot11lcn_gain_val_tbl_rev0) /
++	 sizeof(dot11lcn_gain_val_tbl_rev0[0]), 17, 0, 8}
++	,
++	{&dot11lcn_gain_tbl_rev0,
++	 sizeof(dot11lcn_gain_tbl_rev0) / sizeof(dot11lcn_gain_tbl_rev0[0]), 18,
++	 0, 32}
++	,
++	{&dot11lcn_spur_tbl_rev0,
++	 sizeof(dot11lcn_spur_tbl_rev0) / sizeof(dot11lcn_spur_tbl_rev0[0]), 20,
++	 0, 8}
++	,
++	{&dot11lcn_unsup_mcs_tbl_rev0,
++	 sizeof(dot11lcn_unsup_mcs_tbl_rev0) /
++	 sizeof(dot11lcn_unsup_mcs_tbl_rev0[0]), 23, 0, 16}
++	,
++	{&dot11lcn_iq_local_tbl_rev0,
++	 sizeof(dot11lcn_iq_local_tbl_rev0) /
++	 sizeof(dot11lcn_iq_local_tbl_rev0[0]), 0, 0, 16}
++	,
++	{&dot11lcn_papd_compdelta_tbl_rev0,
++	 sizeof(dot11lcn_papd_compdelta_tbl_rev0) /
++	 sizeof(dot11lcn_papd_compdelta_tbl_rev0[0]), 24, 0, 32}
++	,
++};
++
++const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313 = {
++	&dot11lcn_sw_ctrl_tbl_4313_rev0,
++	sizeof(dot11lcn_sw_ctrl_tbl_4313_rev0) /
++	sizeof(dot11lcn_sw_ctrl_tbl_4313_rev0[0]), 15, 0, 16
++};
++
++const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_epa = {
++	&dot11lcn_sw_ctrl_tbl_4313_epa_rev0,
++	sizeof(dot11lcn_sw_ctrl_tbl_4313_epa_rev0) /
++	sizeof(dot11lcn_sw_ctrl_tbl_4313_epa_rev0[0]), 15, 0, 16
++};
++
++const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_bt_epa = {
++	&dot11lcn_sw_ctrl_tbl_4313_epa_rev0_combo,
++	sizeof(dot11lcn_sw_ctrl_tbl_4313_epa_rev0_combo) /
++	sizeof(dot11lcn_sw_ctrl_tbl_4313_epa_rev0_combo[0]), 15, 0, 16
++};
++
++const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_bt_epa_p250 = {
++	&dot11lcn_sw_ctrl_tbl_4313_bt_epa_p250_rev0,
++	sizeof(dot11lcn_sw_ctrl_tbl_4313_bt_epa_p250_rev0) /
++	sizeof(dot11lcn_sw_ctrl_tbl_4313_bt_epa_p250_rev0[0]), 15, 0, 16
++};
++
++const u32 dot11lcnphytbl_info_sz_rev0 =
++	sizeof(dot11lcnphytbl_info_rev0) / sizeof(dot11lcnphytbl_info_rev0[0]);
++
++const struct lcnphy_tx_gain_tbl_entry
++dot11lcnphy_2GHz_extPA_gaintable_rev0[128] = {
++	{3, 0, 31, 0, 72},
++	{3, 0, 31, 0, 70},
++	{3, 0, 31, 0, 68},
++	{3, 0, 30, 0, 67},
++	{3, 0, 29, 0, 68},
++	{3, 0, 28, 0, 68},
++	{3, 0, 27, 0, 69},
++	{3, 0, 26, 0, 70},
++	{3, 0, 25, 0, 70},
++	{3, 0, 24, 0, 71},
++	{3, 0, 23, 0, 72},
++	{3, 0, 23, 0, 70},
++	{3, 0, 22, 0, 71},
++	{3, 0, 21, 0, 72},
++	{3, 0, 21, 0, 70},
++	{3, 0, 21, 0, 68},
++	{3, 0, 21, 0, 66},
++	{3, 0, 21, 0, 64},
++	{3, 0, 21, 0, 63},
++	{3, 0, 20, 0, 64},
++	{3, 0, 19, 0, 65},
++	{3, 0, 19, 0, 64},
++	{3, 0, 18, 0, 65},
++	{3, 0, 18, 0, 64},
++	{3, 0, 17, 0, 65},
++	{3, 0, 17, 0, 64},
++	{3, 0, 16, 0, 65},
++	{3, 0, 16, 0, 64},
++	{3, 0, 16, 0, 62},
++	{3, 0, 16, 0, 60},
++	{3, 0, 16, 0, 58},
++	{3, 0, 15, 0, 61},
++	{3, 0, 15, 0, 59},
++	{3, 0, 14, 0, 61},
++	{3, 0, 14, 0, 60},
++	{3, 0, 14, 0, 58},
++	{3, 0, 13, 0, 60},
++	{3, 0, 13, 0, 59},
++	{3, 0, 12, 0, 62},
++	{3, 0, 12, 0, 60},
++	{3, 0, 12, 0, 58},
++	{3, 0, 11, 0, 62},
++	{3, 0, 11, 0, 60},
++	{3, 0, 11, 0, 59},
++	{3, 0, 11, 0, 57},
++	{3, 0, 10, 0, 61},
++	{3, 0, 10, 0, 59},
++	{3, 0, 10, 0, 57},
++	{3, 0, 9, 0, 62},
++	{3, 0, 9, 0, 60},
++	{3, 0, 9, 0, 58},
++	{3, 0, 9, 0, 57},
++	{3, 0, 8, 0, 62},
++	{3, 0, 8, 0, 60},
++	{3, 0, 8, 0, 58},
++	{3, 0, 8, 0, 57},
++	{3, 0, 8, 0, 55},
++	{3, 0, 7, 0, 61},
++	{3, 0, 7, 0, 60},
++	{3, 0, 7, 0, 58},
++	{3, 0, 7, 0, 56},
++	{3, 0, 7, 0, 55},
++	{3, 0, 6, 0, 62},
++	{3, 0, 6, 0, 60},
++	{3, 0, 6, 0, 58},
++	{3, 0, 6, 0, 57},
++	{3, 0, 6, 0, 55},
++	{3, 0, 6, 0, 54},
++	{3, 0, 6, 0, 52},
++	{3, 0, 5, 0, 61},
++	{3, 0, 5, 0, 59},
++	{3, 0, 5, 0, 57},
++	{3, 0, 5, 0, 56},
++	{3, 0, 5, 0, 54},
++	{3, 0, 5, 0, 53},
++	{3, 0, 5, 0, 51},
++	{3, 0, 4, 0, 62},
++	{3, 0, 4, 0, 60},
++	{3, 0, 4, 0, 58},
++	{3, 0, 4, 0, 57},
++	{3, 0, 4, 0, 55},
++	{3, 0, 4, 0, 54},
++	{3, 0, 4, 0, 52},
++	{3, 0, 4, 0, 51},
++	{3, 0, 4, 0, 49},
++	{3, 0, 4, 0, 48},
++	{3, 0, 4, 0, 46},
++	{3, 0, 3, 0, 60},
++	{3, 0, 3, 0, 58},
++	{3, 0, 3, 0, 57},
++	{3, 0, 3, 0, 55},
++	{3, 0, 3, 0, 54},
++	{3, 0, 3, 0, 52},
++	{3, 0, 3, 0, 51},
++	{3, 0, 3, 0, 49},
++	{3, 0, 3, 0, 48},
++	{3, 0, 3, 0, 46},
++	{3, 0, 3, 0, 45},
++	{3, 0, 3, 0, 44},
++	{3, 0, 3, 0, 43},
++	{3, 0, 3, 0, 41},
++	{3, 0, 2, 0, 61},
++	{3, 0, 2, 0, 59},
++	{3, 0, 2, 0, 57},
++	{3, 0, 2, 0, 56},
++	{3, 0, 2, 0, 54},
++	{3, 0, 2, 0, 53},
++	{3, 0, 2, 0, 51},
++	{3, 0, 2, 0, 50},
++	{3, 0, 2, 0, 48},
++	{3, 0, 2, 0, 47},
++	{3, 0, 2, 0, 46},
++	{3, 0, 2, 0, 44},
++	{3, 0, 2, 0, 43},
++	{3, 0, 2, 0, 42},
++	{3, 0, 2, 0, 41},
++	{3, 0, 2, 0, 39},
++	{3, 0, 2, 0, 38},
++	{3, 0, 2, 0, 37},
++	{3, 0, 2, 0, 36},
++	{3, 0, 2, 0, 35},
++	{3, 0, 2, 0, 34},
++	{3, 0, 2, 0, 33},
++	{3, 0, 2, 0, 32},
++	{3, 0, 1, 0, 63},
++	{3, 0, 1, 0, 61},
++	{3, 0, 1, 0, 59},
++	{3, 0, 1, 0, 57},
++};
++
++const struct lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_gaintable_rev0[128] = {
++	{7, 0, 31, 0, 72},
++	{7, 0, 31, 0, 70},
++	{7, 0, 31, 0, 68},
++	{7, 0, 30, 0, 67},
++	{7, 0, 29, 0, 68},
++	{7, 0, 28, 0, 68},
++	{7, 0, 27, 0, 69},
++	{7, 0, 26, 0, 70},
++	{7, 0, 25, 0, 70},
++	{7, 0, 24, 0, 71},
++	{7, 0, 23, 0, 72},
++	{7, 0, 23, 0, 70},
++	{7, 0, 22, 0, 71},
++	{7, 0, 21, 0, 72},
++	{7, 0, 21, 0, 70},
++	{7, 0, 21, 0, 68},
++	{7, 0, 21, 0, 66},
++	{7, 0, 21, 0, 64},
++	{7, 0, 21, 0, 63},
++	{7, 0, 20, 0, 64},
++	{7, 0, 19, 0, 65},
++	{7, 0, 19, 0, 64},
++	{7, 0, 18, 0, 65},
++	{7, 0, 18, 0, 64},
++	{7, 0, 17, 0, 65},
++	{7, 0, 17, 0, 64},
++	{7, 0, 16, 0, 65},
++	{7, 0, 16, 0, 64},
++	{7, 0, 16, 0, 62},
++	{7, 0, 16, 0, 60},
++	{7, 0, 16, 0, 58},
++	{7, 0, 15, 0, 61},
++	{7, 0, 15, 0, 59},
++	{7, 0, 14, 0, 61},
++	{7, 0, 14, 0, 60},
++	{7, 0, 14, 0, 58},
++	{7, 0, 13, 0, 60},
++	{7, 0, 13, 0, 59},
++	{7, 0, 12, 0, 62},
++	{7, 0, 12, 0, 60},
++	{7, 0, 12, 0, 58},
++	{7, 0, 11, 0, 62},
++	{7, 0, 11, 0, 60},
++	{7, 0, 11, 0, 59},
++	{7, 0, 11, 0, 57},
++	{7, 0, 10, 0, 61},
++	{7, 0, 10, 0, 59},
++	{7, 0, 10, 0, 57},
++	{7, 0, 9, 0, 62},
++	{7, 0, 9, 0, 60},
++	{7, 0, 9, 0, 58},
++	{7, 0, 9, 0, 57},
++	{7, 0, 8, 0, 62},
++	{7, 0, 8, 0, 60},
++	{7, 0, 8, 0, 58},
++	{7, 0, 8, 0, 57},
++	{7, 0, 8, 0, 55},
++	{7, 0, 7, 0, 61},
++	{7, 0, 7, 0, 60},
++	{7, 0, 7, 0, 58},
++	{7, 0, 7, 0, 56},
++	{7, 0, 7, 0, 55},
++	{7, 0, 6, 0, 62},
++	{7, 0, 6, 0, 60},
++	{7, 0, 6, 0, 58},
++	{7, 0, 6, 0, 57},
++	{7, 0, 6, 0, 55},
++	{7, 0, 6, 0, 54},
++	{7, 0, 6, 0, 52},
++	{7, 0, 5, 0, 61},
++	{7, 0, 5, 0, 59},
++	{7, 0, 5, 0, 57},
++	{7, 0, 5, 0, 56},
++	{7, 0, 5, 0, 54},
++	{7, 0, 5, 0, 53},
++	{7, 0, 5, 0, 51},
++	{7, 0, 4, 0, 62},
++	{7, 0, 4, 0, 60},
++	{7, 0, 4, 0, 58},
++	{7, 0, 4, 0, 57},
++	{7, 0, 4, 0, 55},
++	{7, 0, 4, 0, 54},
++	{7, 0, 4, 0, 52},
++	{7, 0, 4, 0, 51},
++	{7, 0, 4, 0, 49},
++	{7, 0, 4, 0, 48},
++	{7, 0, 4, 0, 46},
++	{7, 0, 3, 0, 60},
++	{7, 0, 3, 0, 58},
++	{7, 0, 3, 0, 57},
++	{7, 0, 3, 0, 55},
++	{7, 0, 3, 0, 54},
++	{7, 0, 3, 0, 52},
++	{7, 0, 3, 0, 51},
++	{7, 0, 3, 0, 49},
++	{7, 0, 3, 0, 48},
++	{7, 0, 3, 0, 46},
++	{7, 0, 3, 0, 45},
++	{7, 0, 3, 0, 44},
++	{7, 0, 3, 0, 43},
++	{7, 0, 3, 0, 41},
++	{7, 0, 2, 0, 61},
++	{7, 0, 2, 0, 59},
++	{7, 0, 2, 0, 57},
++	{7, 0, 2, 0, 56},
++	{7, 0, 2, 0, 54},
++	{7, 0, 2, 0, 53},
++	{7, 0, 2, 0, 51},
++	{7, 0, 2, 0, 50},
++	{7, 0, 2, 0, 48},
++	{7, 0, 2, 0, 47},
++	{7, 0, 2, 0, 46},
++	{7, 0, 2, 0, 44},
++	{7, 0, 2, 0, 43},
++	{7, 0, 2, 0, 42},
++	{7, 0, 2, 0, 41},
++	{7, 0, 2, 0, 39},
++	{7, 0, 2, 0, 38},
++	{7, 0, 2, 0, 37},
++	{7, 0, 2, 0, 36},
++	{7, 0, 2, 0, 35},
++	{7, 0, 2, 0, 34},
++	{7, 0, 2, 0, 33},
++	{7, 0, 2, 0, 32},
++	{7, 0, 1, 0, 63},
++	{7, 0, 1, 0, 61},
++	{7, 0, 1, 0, 59},
++	{7, 0, 1, 0, 57},
++};
++
++const struct lcnphy_tx_gain_tbl_entry dot11lcnphy_5GHz_gaintable_rev0[128] = {
++	{255, 255, 0xf0, 0, 152},
++	{255, 255, 0xf0, 0, 147},
++	{255, 255, 0xf0, 0, 143},
++	{255, 255, 0xf0, 0, 139},
++	{255, 255, 0xf0, 0, 135},
++	{255, 255, 0xf0, 0, 131},
++	{255, 255, 0xf0, 0, 128},
++	{255, 255, 0xf0, 0, 124},
++	{255, 255, 0xf0, 0, 121},
++	{255, 255, 0xf0, 0, 117},
++	{255, 255, 0xf0, 0, 114},
++	{255, 255, 0xf0, 0, 111},
++	{255, 255, 0xf0, 0, 107},
++	{255, 255, 0xf0, 0, 104},
++	{255, 255, 0xf0, 0, 101},
++	{255, 255, 0xf0, 0, 99},
++	{255, 255, 0xf0, 0, 96},
++	{255, 255, 0xf0, 0, 93},
++	{255, 255, 0xf0, 0, 90},
++	{255, 255, 0xf0, 0, 88},
++	{255, 255, 0xf0, 0, 85},
++	{255, 255, 0xf0, 0, 83},
++	{255, 255, 0xf0, 0, 81},
++	{255, 255, 0xf0, 0, 78},
++	{255, 255, 0xf0, 0, 76},
++	{255, 255, 0xf0, 0, 74},
++	{255, 255, 0xf0, 0, 72},
++	{255, 255, 0xf0, 0, 70},
++	{255, 255, 0xf0, 0, 68},
++	{255, 255, 0xf0, 0, 66},
++	{255, 255, 0xf0, 0, 64},
++	{255, 248, 0xf0, 0, 64},
++	{255, 241, 0xf0, 0, 64},
++	{255, 251, 0xe0, 0, 64},
++	{255, 244, 0xe0, 0, 64},
++	{255, 254, 0xd0, 0, 64},
++	{255, 246, 0xd0, 0, 64},
++	{255, 239, 0xd0, 0, 64},
++	{255, 249, 0xc0, 0, 64},
++	{255, 242, 0xc0, 0, 64},
++	{255, 255, 0xb0, 0, 64},
++	{255, 248, 0xb0, 0, 64},
++	{255, 241, 0xb0, 0, 64},
++	{255, 254, 0xa0, 0, 64},
++	{255, 246, 0xa0, 0, 64},
++	{255, 239, 0xa0, 0, 64},
++	{255, 255, 0x90, 0, 64},
++	{255, 248, 0x90, 0, 64},
++	{255, 241, 0x90, 0, 64},
++	{255, 234, 0x90, 0, 64},
++	{255, 255, 0x80, 0, 64},
++	{255, 248, 0x80, 0, 64},
++	{255, 241, 0x80, 0, 64},
++	{255, 234, 0x80, 0, 64},
++	{255, 255, 0x70, 0, 64},
++	{255, 248, 0x70, 0, 64},
++	{255, 241, 0x70, 0, 64},
++	{255, 234, 0x70, 0, 64},
++	{255, 227, 0x70, 0, 64},
++	{255, 221, 0x70, 0, 64},
++	{255, 215, 0x70, 0, 64},
++	{255, 208, 0x70, 0, 64},
++	{255, 203, 0x70, 0, 64},
++	{255, 197, 0x70, 0, 64},
++	{255, 255, 0x60, 0, 64},
++	{255, 248, 0x60, 0, 64},
++	{255, 241, 0x60, 0, 64},
++	{255, 234, 0x60, 0, 64},
++	{255, 227, 0x60, 0, 64},
++	{255, 221, 0x60, 0, 64},
++	{255, 255, 0x50, 0, 64},
++	{255, 248, 0x50, 0, 64},
++	{255, 241, 0x50, 0, 64},
++	{255, 234, 0x50, 0, 64},
++	{255, 227, 0x50, 0, 64},
++	{255, 221, 0x50, 0, 64},
++	{255, 215, 0x50, 0, 64},
++	{255, 208, 0x50, 0, 64},
++	{255, 255, 0x40, 0, 64},
++	{255, 248, 0x40, 0, 64},
++	{255, 241, 0x40, 0, 64},
++	{255, 234, 0x40, 0, 64},
++	{255, 227, 0x40, 0, 64},
++	{255, 221, 0x40, 0, 64},
++	{255, 215, 0x40, 0, 64},
++	{255, 208, 0x40, 0, 64},
++	{255, 203, 0x40, 0, 64},
++	{255, 197, 0x40, 0, 64},
++	{255, 255, 0x30, 0, 64},
++	{255, 248, 0x30, 0, 64},
++	{255, 241, 0x30, 0, 64},
++	{255, 234, 0x30, 0, 64},
++	{255, 227, 0x30, 0, 64},
++	{255, 221, 0x30, 0, 64},
++	{255, 215, 0x30, 0, 64},
++	{255, 208, 0x30, 0, 64},
++	{255, 203, 0x30, 0, 64},
++	{255, 197, 0x30, 0, 64},
++	{255, 191, 0x30, 0, 64},
++	{255, 186, 0x30, 0, 64},
++	{255, 181, 0x30, 0, 64},
++	{255, 175, 0x30, 0, 64},
++	{255, 255, 0x20, 0, 64},
++	{255, 248, 0x20, 0, 64},
++	{255, 241, 0x20, 0, 64},
++	{255, 234, 0x20, 0, 64},
++	{255, 227, 0x20, 0, 64},
++	{255, 221, 0x20, 0, 64},
++	{255, 215, 0x20, 0, 64},
++	{255, 208, 0x20, 0, 64},
++	{255, 203, 0x20, 0, 64},
++	{255, 197, 0x20, 0, 64},
++	{255, 191, 0x20, 0, 64},
++	{255, 186, 0x20, 0, 64},
++	{255, 181, 0x20, 0, 64},
++	{255, 175, 0x20, 0, 64},
++	{255, 170, 0x20, 0, 64},
++	{255, 166, 0x20, 0, 64},
++	{255, 161, 0x20, 0, 64},
++	{255, 156, 0x20, 0, 64},
++	{255, 152, 0x20, 0, 64},
++	{255, 148, 0x20, 0, 64},
++	{255, 143, 0x20, 0, 64},
++	{255, 139, 0x20, 0, 64},
++	{255, 135, 0x20, 0, 64},
++	{255, 132, 0x20, 0, 64},
++	{255, 255, 0x10, 0, 64},
++	{255, 248, 0x10, 0, 64},
++};
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.h b/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.h
+new file mode 100644
+index 0000000..5f75e16
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.h
+@@ -0,0 +1,54 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#include <types.h>
++#include "phy_int.h"
++
++extern const struct phytbl_info dot11lcnphytbl_rx_gain_info_rev0[];
++extern const u32 dot11lcnphytbl_rx_gain_info_sz_rev0;
++extern const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313;
++extern const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_epa;
++extern const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_epa_combo;
++extern const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_bt_epa;
++extern const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_bt_epa_p250;
++
++extern const struct phytbl_info dot11lcnphytbl_info_rev0[];
++extern const u32 dot11lcnphytbl_info_sz_rev0;
++
++extern const struct phytbl_info dot11lcnphytbl_rx_gain_info_2G_rev2[];
++extern const u32 dot11lcnphytbl_rx_gain_info_2G_rev2_sz;
++
++extern const struct phytbl_info dot11lcnphytbl_rx_gain_info_5G_rev2[];
++extern const u32 dot11lcnphytbl_rx_gain_info_5G_rev2_sz;
++
++extern const struct phytbl_info dot11lcnphytbl_rx_gain_info_extlna_2G_rev2[];
++
++extern const struct phytbl_info dot11lcnphytbl_rx_gain_info_extlna_5G_rev2[];
++
++struct lcnphy_tx_gain_tbl_entry {
++	unsigned char gm;
++	unsigned char pga;
++	unsigned char pad;
++	unsigned char dac;
++	unsigned char bb_mult;
++};
++
++extern const struct lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_gaintable_rev0[];
++
++extern const struct
++lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_extPA_gaintable_rev0[];
++
++extern const struct lcnphy_tx_gain_tbl_entry dot11lcnphy_5GHz_gaintable_rev0[];
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_n.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_n.c
+new file mode 100644
+index 0000000..dbf50ef
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_n.c
+@@ -0,0 +1,10630 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#include <types.h>
++#include "phytbl_n.h"
++
++static const u32 frame_struct_rev0[] = {
++	0x08004a04,
++	0x00100000,
++	0x01000a05,
++	0x00100020,
++	0x09804506,
++	0x00100030,
++	0x09804507,
++	0x00100030,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x08004a0c,
++	0x00100004,
++	0x01000a0d,
++	0x00100024,
++	0x0980450e,
++	0x00100034,
++	0x0980450f,
++	0x00100034,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000a04,
++	0x00100000,
++	0x11008a05,
++	0x00100020,
++	0x1980c506,
++	0x00100030,
++	0x21810506,
++	0x00100030,
++	0x21810506,
++	0x00100030,
++	0x01800504,
++	0x00100030,
++	0x11808505,
++	0x00100030,
++	0x29814507,
++	0x01100030,
++	0x00000a04,
++	0x00100000,
++	0x11008a05,
++	0x00100020,
++	0x21810506,
++	0x00100030,
++	0x21810506,
++	0x00100030,
++	0x29814507,
++	0x01100030,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000a0c,
++	0x00100008,
++	0x11008a0d,
++	0x00100028,
++	0x1980c50e,
++	0x00100038,
++	0x2181050e,
++	0x00100038,
++	0x2181050e,
++	0x00100038,
++	0x0180050c,
++	0x00100038,
++	0x1180850d,
++	0x00100038,
++	0x2981450f,
++	0x01100038,
++	0x00000a0c,
++	0x00100008,
++	0x11008a0d,
++	0x00100028,
++	0x2181050e,
++	0x00100038,
++	0x2181050e,
++	0x00100038,
++	0x2981450f,
++	0x01100038,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x08004a04,
++	0x00100000,
++	0x01000a05,
++	0x00100020,
++	0x1980c506,
++	0x00100030,
++	0x1980c506,
++	0x00100030,
++	0x11808504,
++	0x00100030,
++	0x3981ca05,
++	0x00100030,
++	0x29814507,
++	0x01100030,
++	0x00000000,
++	0x00000000,
++	0x10008a04,
++	0x00100000,
++	0x3981ca05,
++	0x00100030,
++	0x1980c506,
++	0x00100030,
++	0x29814507,
++	0x01100030,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x08004a0c,
++	0x00100008,
++	0x01000a0d,
++	0x00100028,
++	0x1980c50e,
++	0x00100038,
++	0x1980c50e,
++	0x00100038,
++	0x1180850c,
++	0x00100038,
++	0x3981ca0d,
++	0x00100038,
++	0x2981450f,
++	0x01100038,
++	0x00000000,
++	0x00000000,
++	0x10008a0c,
++	0x00100008,
++	0x3981ca0d,
++	0x00100038,
++	0x1980c50e,
++	0x00100038,
++	0x2981450f,
++	0x01100038,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x40021404,
++	0x00100000,
++	0x02001405,
++	0x00100040,
++	0x0b004a06,
++	0x01900060,
++	0x13008a06,
++	0x01900060,
++	0x13008a06,
++	0x01900060,
++	0x43020a04,
++	0x00100060,
++	0x1b00ca05,
++	0x00100060,
++	0x23010a07,
++	0x01500060,
++	0x40021404,
++	0x00100000,
++	0x1a00d405,
++	0x00100040,
++	0x13008a06,
++	0x01900060,
++	0x13008a06,
++	0x01900060,
++	0x23010a07,
++	0x01500060,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x4002140c,
++	0x00100010,
++	0x0200140d,
++	0x00100050,
++	0x0b004a0e,
++	0x01900070,
++	0x13008a0e,
++	0x01900070,
++	0x13008a0e,
++	0x01900070,
++	0x43020a0c,
++	0x00100070,
++	0x1b00ca0d,
++	0x00100070,
++	0x23010a0f,
++	0x01500070,
++	0x4002140c,
++	0x00100010,
++	0x1a00d40d,
++	0x00100050,
++	0x13008a0e,
++	0x01900070,
++	0x13008a0e,
++	0x01900070,
++	0x23010a0f,
++	0x01500070,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x50029404,
++	0x00100000,
++	0x32019405,
++	0x00100040,
++	0x0b004a06,
++	0x01900060,
++	0x0b004a06,
++	0x01900060,
++	0x5b02ca04,
++	0x00100060,
++	0x3b01d405,
++	0x00100060,
++	0x23010a07,
++	0x01500060,
++	0x00000000,
++	0x00000000,
++	0x5802d404,
++	0x00100000,
++	0x3b01d405,
++	0x00100060,
++	0x0b004a06,
++	0x01900060,
++	0x23010a07,
++	0x01500060,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x5002940c,
++	0x00100010,
++	0x3201940d,
++	0x00100050,
++	0x0b004a0e,
++	0x01900070,
++	0x0b004a0e,
++	0x01900070,
++	0x5b02ca0c,
++	0x00100070,
++	0x3b01d40d,
++	0x00100070,
++	0x23010a0f,
++	0x01500070,
++	0x00000000,
++	0x00000000,
++	0x5802d40c,
++	0x00100010,
++	0x3b01d40d,
++	0x00100070,
++	0x0b004a0e,
++	0x01900070,
++	0x23010a0f,
++	0x01500070,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x40021404,
++	0x000f4800,
++	0x62031405,
++	0x00100040,
++	0x53028a06,
++	0x01900060,
++	0x53028a07,
++	0x01900060,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x4002140c,
++	0x000f4808,
++	0x6203140d,
++	0x00100048,
++	0x53028a0e,
++	0x01900068,
++	0x53028a0f,
++	0x01900068,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000a0c,
++	0x00100004,
++	0x11008a0d,
++	0x00100024,
++	0x1980c50e,
++	0x00100034,
++	0x2181050e,
++	0x00100034,
++	0x2181050e,
++	0x00100034,
++	0x0180050c,
++	0x00100038,
++	0x1180850d,
++	0x00100038,
++	0x1181850d,
++	0x00100038,
++	0x2981450f,
++	0x01100038,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000a0c,
++	0x00100008,
++	0x11008a0d,
++	0x00100028,
++	0x2181050e,
++	0x00100038,
++	0x2181050e,
++	0x00100038,
++	0x1181850d,
++	0x00100038,
++	0x2981450f,
++	0x01100038,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x08004a04,
++	0x00100000,
++	0x01000a05,
++	0x00100020,
++	0x0180c506,
++	0x00100030,
++	0x0180c506,
++	0x00100030,
++	0x2180c50c,
++	0x00100030,
++	0x49820a0d,
++	0x0016a130,
++	0x41824a0d,
++	0x0016a130,
++	0x2981450f,
++	0x01100030,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x2000ca0c,
++	0x00100000,
++	0x49820a0d,
++	0x0016a130,
++	0x1980c50e,
++	0x00100030,
++	0x41824a0d,
++	0x0016a130,
++	0x2981450f,
++	0x01100030,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x4002140c,
++	0x00100008,
++	0x0200140d,
++	0x00100048,
++	0x0b004a0e,
++	0x01900068,
++	0x13008a0e,
++	0x01900068,
++	0x13008a0e,
++	0x01900068,
++	0x43020a0c,
++	0x00100070,
++	0x1b00ca0d,
++	0x00100070,
++	0x1b014a0d,
++	0x00100070,
++	0x23010a0f,
++	0x01500070,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x4002140c,
++	0x00100010,
++	0x1a00d40d,
++	0x00100050,
++	0x13008a0e,
++	0x01900070,
++	0x13008a0e,
++	0x01900070,
++	0x1b014a0d,
++	0x00100070,
++	0x23010a0f,
++	0x01500070,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x50029404,
++	0x00100000,
++	0x32019405,
++	0x00100040,
++	0x03004a06,
++	0x01900060,
++	0x03004a06,
++	0x01900060,
++	0x6b030a0c,
++	0x00100060,
++	0x4b02140d,
++	0x0016a160,
++	0x4302540d,
++	0x0016a160,
++	0x23010a0f,
++	0x01500060,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x6b03140c,
++	0x00100060,
++	0x4b02140d,
++	0x0016a160,
++	0x0b004a0e,
++	0x01900060,
++	0x4302540d,
++	0x0016a160,
++	0x23010a0f,
++	0x01500060,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x40021404,
++	0x00100000,
++	0x1a00d405,
++	0x00100040,
++	0x53028a06,
++	0x01900060,
++	0x5b02ca06,
++	0x01900060,
++	0x5b02ca06,
++	0x01900060,
++	0x43020a04,
++	0x00100060,
++	0x1b00ca05,
++	0x00100060,
++	0x53028a07,
++	0x0190c060,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x4002140c,
++	0x00100010,
++	0x1a00d40d,
++	0x00100050,
++	0x53028a0e,
++	0x01900070,
++	0x5b02ca0e,
++	0x01900070,
++	0x5b02ca0e,
++	0x01900070,
++	0x43020a0c,
++	0x00100070,
++	0x1b00ca0d,
++	0x00100070,
++	0x53028a0f,
++	0x0190c070,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x40021404,
++	0x00100000,
++	0x1a00d405,
++	0x00100040,
++	0x5b02ca06,
++	0x01900060,
++	0x5b02ca06,
++	0x01900060,
++	0x53028a07,
++	0x0190c060,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x4002140c,
++	0x00100010,
++	0x1a00d40d,
++	0x00100050,
++	0x5b02ca0e,
++	0x01900070,
++	0x5b02ca0e,
++	0x01900070,
++	0x53028a0f,
++	0x0190c070,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++};
++
++static const u8 frame_lut_rev0[] = {
++	0x02,
++	0x04,
++	0x14,
++	0x14,
++	0x03,
++	0x05,
++	0x16,
++	0x16,
++	0x0a,
++	0x0c,
++	0x1c,
++	0x1c,
++	0x0b,
++	0x0d,
++	0x1e,
++	0x1e,
++	0x06,
++	0x08,
++	0x18,
++	0x18,
++	0x07,
++	0x09,
++	0x1a,
++	0x1a,
++	0x0e,
++	0x10,
++	0x20,
++	0x28,
++	0x0f,
++	0x11,
++	0x22,
++	0x2a,
++};
++
++static const u32 tmap_tbl_rev0[] = {
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0xf1111110,
++	0x11111111,
++	0x11f11111,
++	0x00000111,
++	0x11000000,
++	0x1111f111,
++	0x11111111,
++	0x111111f1,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x000aa888,
++	0x88880000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0xa1111110,
++	0x11111111,
++	0x11c11111,
++	0x00000111,
++	0x11000000,
++	0x1111a111,
++	0x11111111,
++	0x111111a1,
++	0xa2222220,
++	0x22222222,
++	0x22c22222,
++	0x00000222,
++	0x22000000,
++	0x2222a222,
++	0x22222222,
++	0x222222a2,
++	0xf1111110,
++	0x11111111,
++	0x11f11111,
++	0x00011111,
++	0x11110000,
++	0x1111f111,
++	0x11111111,
++	0x111111f1,
++	0xa8aa88a0,
++	0xa88888a8,
++	0xa8a8a88a,
++	0x00088aaa,
++	0xaaaa0000,
++	0xa8a8aa88,
++	0xa88aaaaa,
++	0xaaaa8a8a,
++	0xaaa8aaa0,
++	0x8aaa8aaa,
++	0xaa8a8a8a,
++	0x000aaa88,
++	0x8aaa0000,
++	0xaaa8a888,
++	0x8aa88a8a,
++	0x8a88a888,
++	0x08080a00,
++	0x0a08080a,
++	0x080a0a08,
++	0x00080808,
++	0x080a0000,
++	0x080a0808,
++	0x080a0808,
++	0x0a0a0a08,
++	0xa0a0a0a0,
++	0x80a0a080,
++	0x8080a0a0,
++	0x00008080,
++	0x80a00000,
++	0x80a080a0,
++	0xa080a0a0,
++	0x8080a0a0,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x99999000,
++	0x9b9b99bb,
++	0x9bb99999,
++	0x9999b9b9,
++	0x9b99bb90,
++	0x9bbbbb9b,
++	0x9b9b9bb9,
++	0x00000999,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00aaa888,
++	0x22000000,
++	0x2222b222,
++	0x22222222,
++	0x222222b2,
++	0xb2222220,
++	0x22222222,
++	0x22d22222,
++	0x00000222,
++	0x11000000,
++	0x1111a111,
++	0x11111111,
++	0x111111a1,
++	0xa1111110,
++	0x11111111,
++	0x11c11111,
++	0x00000111,
++	0x33000000,
++	0x3333b333,
++	0x33333333,
++	0x333333b3,
++	0xb3333330,
++	0x33333333,
++	0x33d33333,
++	0x00000333,
++	0x22000000,
++	0x2222a222,
++	0x22222222,
++	0x222222a2,
++	0xa2222220,
++	0x22222222,
++	0x22c22222,
++	0x00000222,
++	0x99b99b00,
++	0x9b9b99bb,
++	0x9bb99999,
++	0x9999b9b9,
++	0x9b99bb99,
++	0x9bbbbb9b,
++	0x9b9b9bb9,
++	0x00000999,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa88,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x08aaa888,
++	0x22222200,
++	0x2222f222,
++	0x22222222,
++	0x222222f2,
++	0x22222222,
++	0x22222222,
++	0x22f22222,
++	0x00000222,
++	0x11000000,
++	0x1111f111,
++	0x11111111,
++	0x11111111,
++	0xf1111111,
++	0x11111111,
++	0x11f11111,
++	0x01111111,
++	0xbb9bb900,
++	0xb9b9bb99,
++	0xb99bbbbb,
++	0xbbbb9b9b,
++	0xb9bb99bb,
++	0xb99999b9,
++	0xb9b9b99b,
++	0x00000bbb,
++	0xaa000000,
++	0xa8a8aa88,
++	0xa88aaaaa,
++	0xaaaa8a8a,
++	0xa8aa88aa,
++	0xa88888a8,
++	0xa8a8a88a,
++	0x0a888aaa,
++	0xaa000000,
++	0xa8a8aa88,
++	0xa88aaaaa,
++	0xaaaa8a8a,
++	0xa8aa88a0,
++	0xa88888a8,
++	0xa8a8a88a,
++	0x00000aaa,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0xbbbbbb00,
++	0x999bbbbb,
++	0x9bb99b9b,
++	0xb9b9b9bb,
++	0xb9b99bbb,
++	0xb9b9b9bb,
++	0xb9bb9b99,
++	0x00000999,
++	0x8a000000,
++	0xaa88a888,
++	0xa88888aa,
++	0xa88a8a88,
++	0xa88aa88a,
++	0x88a8aaaa,
++	0xa8aa8aaa,
++	0x0888a88a,
++	0x0b0b0b00,
++	0x090b0b0b,
++	0x0b090b0b,
++	0x0909090b,
++	0x09090b0b,
++	0x09090b0b,
++	0x09090b09,
++	0x00000909,
++	0x0a000000,
++	0x0a080808,
++	0x080a080a,
++	0x080a0a08,
++	0x080a080a,
++	0x0808080a,
++	0x0a0a0a08,
++	0x0808080a,
++	0xb0b0b000,
++	0x9090b0b0,
++	0x90b09090,
++	0xb0b0b090,
++	0xb0b090b0,
++	0x90b0b0b0,
++	0xb0b09090,
++	0x00000090,
++	0x80000000,
++	0xa080a080,
++	0xa08080a0,
++	0xa0808080,
++	0xa080a080,
++	0x80a0a0a0,
++	0xa0a080a0,
++	0x00a0a0a0,
++	0x22000000,
++	0x2222f222,
++	0x22222222,
++	0x222222f2,
++	0xf2222220,
++	0x22222222,
++	0x22f22222,
++	0x00000222,
++	0x11000000,
++	0x1111f111,
++	0x11111111,
++	0x111111f1,
++	0xf1111110,
++	0x11111111,
++	0x11f11111,
++	0x00000111,
++	0x33000000,
++	0x3333f333,
++	0x33333333,
++	0x333333f3,
++	0xf3333330,
++	0x33333333,
++	0x33f33333,
++	0x00000333,
++	0x22000000,
++	0x2222f222,
++	0x22222222,
++	0x222222f2,
++	0xf2222220,
++	0x22222222,
++	0x22f22222,
++	0x00000222,
++	0x99000000,
++	0x9b9b99bb,
++	0x9bb99999,
++	0x9999b9b9,
++	0x9b99bb90,
++	0x9bbbbb9b,
++	0x9b9b9bb9,
++	0x00000999,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0x88888000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00aaa888,
++	0x88a88a00,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa88,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa88,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x08aaa888,
++	0x11000000,
++	0x1111a111,
++	0x11111111,
++	0x111111a1,
++	0xa1111110,
++	0x11111111,
++	0x11c11111,
++	0x00000111,
++	0x11000000,
++	0x1111a111,
++	0x11111111,
++	0x111111a1,
++	0xa1111110,
++	0x11111111,
++	0x11c11111,
++	0x00000111,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++};
++
++static const u32 tdtrn_tbl_rev0[] = {
++	0x061c061c,
++	0x0050ee68,
++	0xf592fe36,
++	0xfe5212f6,
++	0x00000c38,
++	0xfe5212f6,
++	0xf592fe36,
++	0x0050ee68,
++	0x061c061c,
++	0xee680050,
++	0xfe36f592,
++	0x12f6fe52,
++	0x0c380000,
++	0x12f6fe52,
++	0xfe36f592,
++	0xee680050,
++	0x061c061c,
++	0x0050ee68,
++	0xf592fe36,
++	0xfe5212f6,
++	0x00000c38,
++	0xfe5212f6,
++	0xf592fe36,
++	0x0050ee68,
++	0x061c061c,
++	0xee680050,
++	0xfe36f592,
++	0x12f6fe52,
++	0x0c380000,
++	0x12f6fe52,
++	0xfe36f592,
++	0xee680050,
++	0x05e305e3,
++	0x004def0c,
++	0xf5f3fe47,
++	0xfe611246,
++	0x00000bc7,
++	0xfe611246,
++	0xf5f3fe47,
++	0x004def0c,
++	0x05e305e3,
++	0xef0c004d,
++	0xfe47f5f3,
++	0x1246fe61,
++	0x0bc70000,
++	0x1246fe61,
++	0xfe47f5f3,
++	0xef0c004d,
++	0x05e305e3,
++	0x004def0c,
++	0xf5f3fe47,
++	0xfe611246,
++	0x00000bc7,
++	0xfe611246,
++	0xf5f3fe47,
++	0x004def0c,
++	0x05e305e3,
++	0xef0c004d,
++	0xfe47f5f3,
++	0x1246fe61,
++	0x0bc70000,
++	0x1246fe61,
++	0xfe47f5f3,
++	0xef0c004d,
++	0xfa58fa58,
++	0xf895043b,
++	0xff4c09c0,
++	0xfbc6ffa8,
++	0xfb84f384,
++	0x0798f6f9,
++	0x05760122,
++	0x058409f6,
++	0x0b500000,
++	0x05b7f542,
++	0x08860432,
++	0x06ddfee7,
++	0xfb84f384,
++	0xf9d90664,
++	0xf7e8025c,
++	0x00fff7bd,
++	0x05a805a8,
++	0xf7bd00ff,
++	0x025cf7e8,
++	0x0664f9d9,
++	0xf384fb84,
++	0xfee706dd,
++	0x04320886,
++	0xf54205b7,
++	0x00000b50,
++	0x09f60584,
++	0x01220576,
++	0xf6f90798,
++	0xf384fb84,
++	0xffa8fbc6,
++	0x09c0ff4c,
++	0x043bf895,
++	0x02d402d4,
++	0x07de0270,
++	0xfc96079c,
++	0xf90afe94,
++	0xfe00ff2c,
++	0x02d4065d,
++	0x092a0096,
++	0x0014fbb8,
++	0xfd2cfd2c,
++	0x076afb3c,
++	0x0096f752,
++	0xf991fd87,
++	0xfb2c0200,
++	0xfeb8f960,
++	0x08e0fc96,
++	0x049802a8,
++	0xfd2cfd2c,
++	0x02a80498,
++	0xfc9608e0,
++	0xf960feb8,
++	0x0200fb2c,
++	0xfd87f991,
++	0xf7520096,
++	0xfb3c076a,
++	0xfd2cfd2c,
++	0xfbb80014,
++	0x0096092a,
++	0x065d02d4,
++	0xff2cfe00,
++	0xfe94f90a,
++	0x079cfc96,
++	0x027007de,
++	0x02d402d4,
++	0x027007de,
++	0x079cfc96,
++	0xfe94f90a,
++	0xff2cfe00,
++	0x065d02d4,
++	0x0096092a,
++	0xfbb80014,
++	0xfd2cfd2c,
++	0xfb3c076a,
++	0xf7520096,
++	0xfd87f991,
++	0x0200fb2c,
++	0xf960feb8,
++	0xfc9608e0,
++	0x02a80498,
++	0xfd2cfd2c,
++	0x049802a8,
++	0x08e0fc96,
++	0xfeb8f960,
++	0xfb2c0200,
++	0xf991fd87,
++	0x0096f752,
++	0x076afb3c,
++	0xfd2cfd2c,
++	0x0014fbb8,
++	0x092a0096,
++	0x02d4065d,
++	0xfe00ff2c,
++	0xf90afe94,
++	0xfc96079c,
++	0x07de0270,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x062a0000,
++	0xfefa0759,
++	0x08b80908,
++	0xf396fc2d,
++	0xf9d6045c,
++	0xfc4ef608,
++	0xf748f596,
++	0x07b207bf,
++	0x062a062a,
++	0xf84ef841,
++	0xf748f596,
++	0x03b209f8,
++	0xf9d6045c,
++	0x0c6a03d3,
++	0x08b80908,
++	0x0106f8a7,
++	0x062a0000,
++	0xfefaf8a7,
++	0x08b8f6f8,
++	0xf39603d3,
++	0xf9d6fba4,
++	0xfc4e09f8,
++	0xf7480a6a,
++	0x07b2f841,
++	0x062af9d6,
++	0xf84e07bf,
++	0xf7480a6a,
++	0x03b2f608,
++	0xf9d6fba4,
++	0x0c6afc2d,
++	0x08b8f6f8,
++	0x01060759,
++	0x062a0000,
++	0xfefa0759,
++	0x08b80908,
++	0xf396fc2d,
++	0xf9d6045c,
++	0xfc4ef608,
++	0xf748f596,
++	0x07b207bf,
++	0x062a062a,
++	0xf84ef841,
++	0xf748f596,
++	0x03b209f8,
++	0xf9d6045c,
++	0x0c6a03d3,
++	0x08b80908,
++	0x0106f8a7,
++	0x062a0000,
++	0xfefaf8a7,
++	0x08b8f6f8,
++	0xf39603d3,
++	0xf9d6fba4,
++	0xfc4e09f8,
++	0xf7480a6a,
++	0x07b2f841,
++	0x062af9d6,
++	0xf84e07bf,
++	0xf7480a6a,
++	0x03b2f608,
++	0xf9d6fba4,
++	0x0c6afc2d,
++	0x08b8f6f8,
++	0x01060759,
++	0x061c061c,
++	0xff30009d,
++	0xffb21141,
++	0xfd87fb54,
++	0xf65dfe59,
++	0x02eef99e,
++	0x0166f03c,
++	0xfff809b6,
++	0x000008a4,
++	0x000af42b,
++	0x00eff577,
++	0xfa840bf2,
++	0xfc02ff51,
++	0x08260f67,
++	0xfff0036f,
++	0x0842f9c3,
++	0x00000000,
++	0x063df7be,
++	0xfc910010,
++	0xf099f7da,
++	0x00af03fe,
++	0xf40e057c,
++	0x0a89ff11,
++	0x0bd5fff6,
++	0xf75c0000,
++	0xf64a0008,
++	0x0fc4fe9a,
++	0x0662fd12,
++	0x01a709a3,
++	0x04ac0279,
++	0xeebf004e,
++	0xff6300d0,
++	0xf9e4f9e4,
++	0x00d0ff63,
++	0x004eeebf,
++	0x027904ac,
++	0x09a301a7,
++	0xfd120662,
++	0xfe9a0fc4,
++	0x0008f64a,
++	0x0000f75c,
++	0xfff60bd5,
++	0xff110a89,
++	0x057cf40e,
++	0x03fe00af,
++	0xf7daf099,
++	0x0010fc91,
++	0xf7be063d,
++	0x00000000,
++	0xf9c30842,
++	0x036ffff0,
++	0x0f670826,
++	0xff51fc02,
++	0x0bf2fa84,
++	0xf57700ef,
++	0xf42b000a,
++	0x08a40000,
++	0x09b6fff8,
++	0xf03c0166,
++	0xf99e02ee,
++	0xfe59f65d,
++	0xfb54fd87,
++	0x1141ffb2,
++	0x009dff30,
++	0x05e30000,
++	0xff060705,
++	0x085408a0,
++	0xf425fc59,
++	0xfa1d042a,
++	0xfc78f67a,
++	0xf7acf60e,
++	0x075a0766,
++	0x05e305e3,
++	0xf8a6f89a,
++	0xf7acf60e,
++	0x03880986,
++	0xfa1d042a,
++	0x0bdb03a7,
++	0x085408a0,
++	0x00faf8fb,
++	0x05e30000,
++	0xff06f8fb,
++	0x0854f760,
++	0xf42503a7,
++	0xfa1dfbd6,
++	0xfc780986,
++	0xf7ac09f2,
++	0x075af89a,
++	0x05e3fa1d,
++	0xf8a60766,
++	0xf7ac09f2,
++	0x0388f67a,
++	0xfa1dfbd6,
++	0x0bdbfc59,
++	0x0854f760,
++	0x00fa0705,
++	0x05e30000,
++	0xff060705,
++	0x085408a0,
++	0xf425fc59,
++	0xfa1d042a,
++	0xfc78f67a,
++	0xf7acf60e,
++	0x075a0766,
++	0x05e305e3,
++	0xf8a6f89a,
++	0xf7acf60e,
++	0x03880986,
++	0xfa1d042a,
++	0x0bdb03a7,
++	0x085408a0,
++	0x00faf8fb,
++	0x05e30000,
++	0xff06f8fb,
++	0x0854f760,
++	0xf42503a7,
++	0xfa1dfbd6,
++	0xfc780986,
++	0xf7ac09f2,
++	0x075af89a,
++	0x05e3fa1d,
++	0xf8a60766,
++	0xf7ac09f2,
++	0x0388f67a,
++	0xfa1dfbd6,
++	0x0bdbfc59,
++	0x0854f760,
++	0x00fa0705,
++	0xfa58fa58,
++	0xf8f0fe00,
++	0x0448073d,
++	0xfdc9fe46,
++	0xf9910258,
++	0x089d0407,
++	0xfd5cf71a,
++	0x02affde0,
++	0x083e0496,
++	0xff5a0740,
++	0xff7afd97,
++	0x00fe01f1,
++	0x0009082e,
++	0xfa94ff75,
++	0xfecdf8ea,
++	0xffb0f693,
++	0xfd2cfa58,
++	0x0433ff16,
++	0xfba405dd,
++	0xfa610341,
++	0x06a606cb,
++	0x0039fd2d,
++	0x0677fa97,
++	0x01fa05e0,
++	0xf896003e,
++	0x075a068b,
++	0x012cfc3e,
++	0xfa23f98d,
++	0xfc7cfd43,
++	0xff90fc0d,
++	0x01c10982,
++	0x00c601d6,
++	0xfd2cfd2c,
++	0x01d600c6,
++	0x098201c1,
++	0xfc0dff90,
++	0xfd43fc7c,
++	0xf98dfa23,
++	0xfc3e012c,
++	0x068b075a,
++	0x003ef896,
++	0x05e001fa,
++	0xfa970677,
++	0xfd2d0039,
++	0x06cb06a6,
++	0x0341fa61,
++	0x05ddfba4,
++	0xff160433,
++	0xfa58fd2c,
++	0xf693ffb0,
++	0xf8eafecd,
++	0xff75fa94,
++	0x082e0009,
++	0x01f100fe,
++	0xfd97ff7a,
++	0x0740ff5a,
++	0x0496083e,
++	0xfde002af,
++	0xf71afd5c,
++	0x0407089d,
++	0x0258f991,
++	0xfe46fdc9,
++	0x073d0448,
++	0xfe00f8f0,
++	0xfd2cfd2c,
++	0xfce00500,
++	0xfc09fddc,
++	0xfe680157,
++	0x04c70571,
++	0xfc3aff21,
++	0xfcd70228,
++	0x056d0277,
++	0x0200fe00,
++	0x0022f927,
++	0xfe3c032b,
++	0xfc44ff3c,
++	0x03e9fbdb,
++	0x04570313,
++	0x04c9ff5c,
++	0x000d03b8,
++	0xfa580000,
++	0xfbe900d2,
++	0xf9d0fe0b,
++	0x0125fdf9,
++	0x042501bf,
++	0x0328fa2b,
++	0xffa902f0,
++	0xfa250157,
++	0x0200fe00,
++	0x03740438,
++	0xff0405fd,
++	0x030cfe52,
++	0x0037fb39,
++	0xff6904c5,
++	0x04f8fd23,
++	0xfd31fc1b,
++	0xfd2cfd2c,
++	0xfc1bfd31,
++	0xfd2304f8,
++	0x04c5ff69,
++	0xfb390037,
++	0xfe52030c,
++	0x05fdff04,
++	0x04380374,
++	0xfe000200,
++	0x0157fa25,
++	0x02f0ffa9,
++	0xfa2b0328,
++	0x01bf0425,
++	0xfdf90125,
++	0xfe0bf9d0,
++	0x00d2fbe9,
++	0x0000fa58,
++	0x03b8000d,
++	0xff5c04c9,
++	0x03130457,
++	0xfbdb03e9,
++	0xff3cfc44,
++	0x032bfe3c,
++	0xf9270022,
++	0xfe000200,
++	0x0277056d,
++	0x0228fcd7,
++	0xff21fc3a,
++	0x057104c7,
++	0x0157fe68,
++	0xfddcfc09,
++	0x0500fce0,
++	0xfd2cfd2c,
++	0x0500fce0,
++	0xfddcfc09,
++	0x0157fe68,
++	0x057104c7,
++	0xff21fc3a,
++	0x0228fcd7,
++	0x0277056d,
++	0xfe000200,
++	0xf9270022,
++	0x032bfe3c,
++	0xff3cfc44,
++	0xfbdb03e9,
++	0x03130457,
++	0xff5c04c9,
++	0x03b8000d,
++	0x0000fa58,
++	0x00d2fbe9,
++	0xfe0bf9d0,
++	0xfdf90125,
++	0x01bf0425,
++	0xfa2b0328,
++	0x02f0ffa9,
++	0x0157fa25,
++	0xfe000200,
++	0x04380374,
++	0x05fdff04,
++	0xfe52030c,
++	0xfb390037,
++	0x04c5ff69,
++	0xfd2304f8,
++	0xfc1bfd31,
++	0xfd2cfd2c,
++	0xfd31fc1b,
++	0x04f8fd23,
++	0xff6904c5,
++	0x0037fb39,
++	0x030cfe52,
++	0xff0405fd,
++	0x03740438,
++	0x0200fe00,
++	0xfa250157,
++	0xffa902f0,
++	0x0328fa2b,
++	0x042501bf,
++	0x0125fdf9,
++	0xf9d0fe0b,
++	0xfbe900d2,
++	0xfa580000,
++	0x000d03b8,
++	0x04c9ff5c,
++	0x04570313,
++	0x03e9fbdb,
++	0xfc44ff3c,
++	0xfe3c032b,
++	0x0022f927,
++	0x0200fe00,
++	0x056d0277,
++	0xfcd70228,
++	0xfc3aff21,
++	0x04c70571,
++	0xfe680157,
++	0xfc09fddc,
++	0xfce00500,
++	0x05a80000,
++	0xff1006be,
++	0x0800084a,
++	0xf49cfc7e,
++	0xfa580400,
++	0xfc9cf6da,
++	0xf800f672,
++	0x0710071c,
++	0x05a805a8,
++	0xf8f0f8e4,
++	0xf800f672,
++	0x03640926,
++	0xfa580400,
++	0x0b640382,
++	0x0800084a,
++	0x00f0f942,
++	0x05a80000,
++	0xff10f942,
++	0x0800f7b6,
++	0xf49c0382,
++	0xfa58fc00,
++	0xfc9c0926,
++	0xf800098e,
++	0x0710f8e4,
++	0x05a8fa58,
++	0xf8f0071c,
++	0xf800098e,
++	0x0364f6da,
++	0xfa58fc00,
++	0x0b64fc7e,
++	0x0800f7b6,
++	0x00f006be,
++	0x05a80000,
++	0xff1006be,
++	0x0800084a,
++	0xf49cfc7e,
++	0xfa580400,
++	0xfc9cf6da,
++	0xf800f672,
++	0x0710071c,
++	0x05a805a8,
++	0xf8f0f8e4,
++	0xf800f672,
++	0x03640926,
++	0xfa580400,
++	0x0b640382,
++	0x0800084a,
++	0x00f0f942,
++	0x05a80000,
++	0xff10f942,
++	0x0800f7b6,
++	0xf49c0382,
++	0xfa58fc00,
++	0xfc9c0926,
++	0xf800098e,
++	0x0710f8e4,
++	0x05a8fa58,
++	0xf8f0071c,
++	0xf800098e,
++	0x0364f6da,
++	0xfa58fc00,
++	0x0b64fc7e,
++	0x0800f7b6,
++	0x00f006be,
++};
++
++static const u32 intlv_tbl_rev0[] = {
++	0x00802070,
++	0x0671188d,
++	0x0a60192c,
++	0x0a300e46,
++	0x00c1188d,
++	0x080024d2,
++	0x00000070,
++};
++
++static const u16 pilot_tbl_rev0[] = {
++	0xff08,
++	0xff08,
++	0xff08,
++	0xff08,
++	0xff08,
++	0xff08,
++	0xff08,
++	0xff08,
++	0x80d5,
++	0x80d5,
++	0x80d5,
++	0x80d5,
++	0x80d5,
++	0x80d5,
++	0x80d5,
++	0x80d5,
++	0xff0a,
++	0xff82,
++	0xffa0,
++	0xff28,
++	0xffff,
++	0xffff,
++	0xffff,
++	0xffff,
++	0xff82,
++	0xffa0,
++	0xff28,
++	0xff0a,
++	0xffff,
++	0xffff,
++	0xffff,
++	0xffff,
++	0xf83f,
++	0xfa1f,
++	0xfa97,
++	0xfab5,
++	0xf2bd,
++	0xf0bf,
++	0xffff,
++	0xffff,
++	0xf017,
++	0xf815,
++	0xf215,
++	0xf095,
++	0xf035,
++	0xf01d,
++	0xffff,
++	0xffff,
++	0xff08,
++	0xff02,
++	0xff80,
++	0xff20,
++	0xff08,
++	0xff02,
++	0xff80,
++	0xff20,
++	0xf01f,
++	0xf817,
++	0xfa15,
++	0xf295,
++	0xf0b5,
++	0xf03d,
++	0xffff,
++	0xffff,
++	0xf82a,
++	0xfa0a,
++	0xfa82,
++	0xfaa0,
++	0xf2a8,
++	0xf0aa,
++	0xffff,
++	0xffff,
++	0xf002,
++	0xf800,
++	0xf200,
++	0xf080,
++	0xf020,
++	0xf008,
++	0xffff,
++	0xffff,
++	0xf00a,
++	0xf802,
++	0xfa00,
++	0xf280,
++	0xf0a0,
++	0xf028,
++	0xffff,
++	0xffff,
++};
++
++static const u32 pltlut_tbl_rev0[] = {
++	0x76540123,
++	0x62407351,
++	0x76543201,
++	0x76540213,
++	0x76540123,
++	0x76430521,
++};
++
++static const u32 tdi_tbl20_ant0_rev0[] = {
++	0x00091226,
++	0x000a1429,
++	0x000b56ad,
++	0x000c58b0,
++	0x000d5ab3,
++	0x000e9cb6,
++	0x000f9eba,
++	0x0000c13d,
++	0x00020301,
++	0x00030504,
++	0x00040708,
++	0x0005090b,
++	0x00064b8e,
++	0x00095291,
++	0x000a5494,
++	0x000b9718,
++	0x000c9927,
++	0x000d9b2a,
++	0x000edd2e,
++	0x000fdf31,
++	0x000101b4,
++	0x000243b7,
++	0x000345bb,
++	0x000447be,
++	0x00058982,
++	0x00068c05,
++	0x00099309,
++	0x000a950c,
++	0x000bd78f,
++	0x000cd992,
++	0x000ddb96,
++	0x000f1d99,
++	0x00005fa8,
++	0x0001422c,
++	0x0002842f,
++	0x00038632,
++	0x00048835,
++	0x0005ca38,
++	0x0006ccbc,
++	0x0009d3bf,
++	0x000b1603,
++	0x000c1806,
++	0x000d1a0a,
++	0x000e1c0d,
++	0x000f5e10,
++	0x00008093,
++	0x00018297,
++	0x0002c49a,
++	0x0003c680,
++	0x0004c880,
++	0x00060b00,
++	0x00070d00,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++};
++
++static const u32 tdi_tbl20_ant1_rev0[] = {
++	0x00014b26,
++	0x00028d29,
++	0x000393ad,
++	0x00049630,
++	0x0005d833,
++	0x0006da36,
++	0x00099c3a,
++	0x000a9e3d,
++	0x000bc081,
++	0x000cc284,
++	0x000dc488,
++	0x000f068b,
++	0x0000488e,
++	0x00018b91,
++	0x0002d214,
++	0x0003d418,
++	0x0004d6a7,
++	0x000618aa,
++	0x00071aae,
++	0x0009dcb1,
++	0x000b1eb4,
++	0x000c0137,
++	0x000d033b,
++	0x000e053e,
++	0x000f4702,
++	0x00008905,
++	0x00020c09,
++	0x0003128c,
++	0x0004148f,
++	0x00051712,
++	0x00065916,
++	0x00091b19,
++	0x000a1d28,
++	0x000b5f2c,
++	0x000c41af,
++	0x000d43b2,
++	0x000e85b5,
++	0x000f87b8,
++	0x0000c9bc,
++	0x00024cbf,
++	0x00035303,
++	0x00045506,
++	0x0005978a,
++	0x0006998d,
++	0x00095b90,
++	0x000a5d93,
++	0x000b9f97,
++	0x000c821a,
++	0x000d8400,
++	0x000ec600,
++	0x000fc800,
++	0x00010a00,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++};
++
++static const u32 tdi_tbl40_ant0_rev0[] = {
++	0x0011a346,
++	0x00136ccf,
++	0x0014f5d9,
++	0x001641e2,
++	0x0017cb6b,
++	0x00195475,
++	0x001b2383,
++	0x001cad0c,
++	0x001e7616,
++	0x0000821f,
++	0x00020ba8,
++	0x0003d4b2,
++	0x00056447,
++	0x00072dd0,
++	0x0008b6da,
++	0x000a02e3,
++	0x000b8c6c,
++	0x000d15f6,
++	0x0011e484,
++	0x0013ae0d,
++	0x00153717,
++	0x00168320,
++	0x00180ca9,
++	0x00199633,
++	0x001b6548,
++	0x001ceed1,
++	0x001eb7db,
++	0x0000c3e4,
++	0x00024d6d,
++	0x000416f7,
++	0x0005a585,
++	0x00076f0f,
++	0x0008f818,
++	0x000a4421,
++	0x000bcdab,
++	0x000d9734,
++	0x00122649,
++	0x0013efd2,
++	0x001578dc,
++	0x0016c4e5,
++	0x00184e6e,
++	0x001a17f8,
++	0x001ba686,
++	0x001d3010,
++	0x001ef999,
++	0x00010522,
++	0x00028eac,
++	0x00045835,
++	0x0005e74a,
++	0x0007b0d3,
++	0x00093a5d,
++	0x000a85e6,
++	0x000c0f6f,
++	0x000dd8f9,
++	0x00126787,
++	0x00143111,
++	0x0015ba9a,
++	0x00170623,
++	0x00188fad,
++	0x001a5936,
++	0x001be84b,
++	0x001db1d4,
++	0x001f3b5e,
++	0x000146e7,
++	0x00031070,
++	0x000499fa,
++	0x00062888,
++	0x0007f212,
++	0x00097b9b,
++	0x000ac7a4,
++	0x000c50ae,
++	0x000e1a37,
++	0x0012a94c,
++	0x001472d5,
++	0x0015fc5f,
++	0x00174868,
++	0x0018d171,
++	0x001a9afb,
++	0x001c2989,
++	0x001df313,
++	0x001f7c9c,
++	0x000188a5,
++	0x000351af,
++	0x0004db38,
++	0x0006aa4d,
++	0x000833d7,
++	0x0009bd60,
++	0x000b0969,
++	0x000c9273,
++	0x000e5bfc,
++	0x00132a8a,
++	0x0014b414,
++	0x00163d9d,
++	0x001789a6,
++	0x001912b0,
++	0x001adc39,
++	0x001c6bce,
++	0x001e34d8,
++	0x001fbe61,
++	0x0001ca6a,
++	0x00039374,
++	0x00051cfd,
++	0x0006ec0b,
++	0x00087515,
++	0x0009fe9e,
++	0x000b4aa7,
++	0x000cd3b1,
++	0x000e9d3a,
++	0x00000000,
++	0x00000000,
++};
++
++static const u32 tdi_tbl40_ant1_rev0[] = {
++	0x001edb36,
++	0x000129ca,
++	0x0002b353,
++	0x00047cdd,
++	0x0005c8e6,
++	0x000791ef,
++	0x00091bf9,
++	0x000aaa07,
++	0x000c3391,
++	0x000dfd1a,
++	0x00120923,
++	0x0013d22d,
++	0x00155c37,
++	0x0016eacb,
++	0x00187454,
++	0x001a3dde,
++	0x001b89e7,
++	0x001d12f0,
++	0x001f1cfa,
++	0x00016b88,
++	0x00033492,
++	0x0004be1b,
++	0x00060a24,
++	0x0007d32e,
++	0x00095d38,
++	0x000aec4c,
++	0x000c7555,
++	0x000e3edf,
++	0x00124ae8,
++	0x001413f1,
++	0x0015a37b,
++	0x00172c89,
++	0x0018b593,
++	0x001a419c,
++	0x001bcb25,
++	0x001d942f,
++	0x001f63b9,
++	0x0001ad4d,
++	0x00037657,
++	0x0004c260,
++	0x00068be9,
++	0x000814f3,
++	0x0009a47c,
++	0x000b2d8a,
++	0x000cb694,
++	0x000e429d,
++	0x00128c26,
++	0x001455b0,
++	0x0015e4ba,
++	0x00176e4e,
++	0x0018f758,
++	0x001a8361,
++	0x001c0cea,
++	0x001dd674,
++	0x001fa57d,
++	0x0001ee8b,
++	0x0003b795,
++	0x0005039e,
++	0x0006cd27,
++	0x000856b1,
++	0x0009e5c6,
++	0x000b6f4f,
++	0x000cf859,
++	0x000e8462,
++	0x00130deb,
++	0x00149775,
++	0x00162603,
++	0x0017af8c,
++	0x00193896,
++	0x001ac49f,
++	0x001c4e28,
++	0x001e17b2,
++	0x0000a6c7,
++	0x00023050,
++	0x0003f9da,
++	0x00054563,
++	0x00070eec,
++	0x00089876,
++	0x000a2704,
++	0x000bb08d,
++	0x000d3a17,
++	0x001185a0,
++	0x00134f29,
++	0x0014d8b3,
++	0x001667c8,
++	0x0017f151,
++	0x00197adb,
++	0x001b0664,
++	0x001c8fed,
++	0x001e5977,
++	0x0000e805,
++	0x0002718f,
++	0x00043b18,
++	0x000586a1,
++	0x0007502b,
++	0x0008d9b4,
++	0x000a68c9,
++	0x000bf252,
++	0x000dbbdc,
++	0x0011c7e5,
++	0x001390ee,
++	0x00151a78,
++	0x0016a906,
++	0x00183290,
++	0x0019bc19,
++	0x001b4822,
++	0x001cd12c,
++	0x001e9ab5,
++	0x00000000,
++	0x00000000,
++};
++
++static const u16 bdi_tbl_rev0[] = {
++	0x0070,
++	0x0126,
++	0x012c,
++	0x0246,
++	0x048d,
++	0x04d2,
++};
++
++static const u32 chanest_tbl_rev0[] = {
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++};
++
++static const u8 mcs_tbl_rev0[] = {
++	0x00,
++	0x08,
++	0x0a,
++	0x10,
++	0x12,
++	0x19,
++	0x1a,
++	0x1c,
++	0x40,
++	0x48,
++	0x4a,
++	0x50,
++	0x52,
++	0x59,
++	0x5a,
++	0x5c,
++	0x80,
++	0x88,
++	0x8a,
++	0x90,
++	0x92,
++	0x99,
++	0x9a,
++	0x9c,
++	0xc0,
++	0xc8,
++	0xca,
++	0xd0,
++	0xd2,
++	0xd9,
++	0xda,
++	0xdc,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x01,
++	0x02,
++	0x04,
++	0x08,
++	0x09,
++	0x0a,
++	0x0c,
++	0x10,
++	0x11,
++	0x12,
++	0x14,
++	0x18,
++	0x19,
++	0x1a,
++	0x1c,
++	0x20,
++	0x21,
++	0x22,
++	0x24,
++	0x40,
++	0x41,
++	0x42,
++	0x44,
++	0x48,
++	0x49,
++	0x4a,
++	0x4c,
++	0x50,
++	0x51,
++	0x52,
++	0x54,
++	0x58,
++	0x59,
++	0x5a,
++	0x5c,
++	0x60,
++	0x61,
++	0x62,
++	0x64,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++};
++
++static const u32 noise_var_tbl0_rev0[] = {
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++};
++
++static const u32 noise_var_tbl1_rev0[] = {
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++};
++
++static const u8 est_pwr_lut_core0_rev0[] = {
++	0x50,
++	0x4f,
++	0x4e,
++	0x4d,
++	0x4c,
++	0x4b,
++	0x4a,
++	0x49,
++	0x48,
++	0x47,
++	0x46,
++	0x45,
++	0x44,
++	0x43,
++	0x42,
++	0x41,
++	0x40,
++	0x3f,
++	0x3e,
++	0x3d,
++	0x3c,
++	0x3b,
++	0x3a,
++	0x39,
++	0x38,
++	0x37,
++	0x36,
++	0x35,
++	0x34,
++	0x33,
++	0x32,
++	0x31,
++	0x30,
++	0x2f,
++	0x2e,
++	0x2d,
++	0x2c,
++	0x2b,
++	0x2a,
++	0x29,
++	0x28,
++	0x27,
++	0x26,
++	0x25,
++	0x24,
++	0x23,
++	0x22,
++	0x21,
++	0x20,
++	0x1f,
++	0x1e,
++	0x1d,
++	0x1c,
++	0x1b,
++	0x1a,
++	0x19,
++	0x18,
++	0x17,
++	0x16,
++	0x15,
++	0x14,
++	0x13,
++	0x12,
++	0x11,
++};
++
++static const u8 est_pwr_lut_core1_rev0[] = {
++	0x50,
++	0x4f,
++	0x4e,
++	0x4d,
++	0x4c,
++	0x4b,
++	0x4a,
++	0x49,
++	0x48,
++	0x47,
++	0x46,
++	0x45,
++	0x44,
++	0x43,
++	0x42,
++	0x41,
++	0x40,
++	0x3f,
++	0x3e,
++	0x3d,
++	0x3c,
++	0x3b,
++	0x3a,
++	0x39,
++	0x38,
++	0x37,
++	0x36,
++	0x35,
++	0x34,
++	0x33,
++	0x32,
++	0x31,
++	0x30,
++	0x2f,
++	0x2e,
++	0x2d,
++	0x2c,
++	0x2b,
++	0x2a,
++	0x29,
++	0x28,
++	0x27,
++	0x26,
++	0x25,
++	0x24,
++	0x23,
++	0x22,
++	0x21,
++	0x20,
++	0x1f,
++	0x1e,
++	0x1d,
++	0x1c,
++	0x1b,
++	0x1a,
++	0x19,
++	0x18,
++	0x17,
++	0x16,
++	0x15,
++	0x14,
++	0x13,
++	0x12,
++	0x11,
++};
++
++static const u8 adj_pwr_lut_core0_rev0[] = {
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++};
++
++static const u8 adj_pwr_lut_core1_rev0[] = {
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++};
++
++static const u32 gainctrl_lut_core0_rev0[] = {
++	0x03cc2b44,
++	0x03cc2b42,
++	0x03cc2b40,
++	0x03cc2b3e,
++	0x03cc2b3d,
++	0x03cc2b3b,
++	0x03c82b44,
++	0x03c82b42,
++	0x03c82b40,
++	0x03c82b3e,
++	0x03c82b3d,
++	0x03c82b3b,
++	0x03c82b39,
++	0x03c82b38,
++	0x03c82b36,
++	0x03c82b34,
++	0x03c42b44,
++	0x03c42b42,
++	0x03c42b40,
++	0x03c42b3e,
++	0x03c42b3d,
++	0x03c42b3b,
++	0x03c42b39,
++	0x03c42b38,
++	0x03c42b36,
++	0x03c42b34,
++	0x03c42b33,
++	0x03c42b32,
++	0x03c42b30,
++	0x03c42b2f,
++	0x03c42b2d,
++	0x03c02b44,
++	0x03c02b42,
++	0x03c02b40,
++	0x03c02b3e,
++	0x03c02b3d,
++	0x03c02b3b,
++	0x03c02b39,
++	0x03c02b38,
++	0x03c02b36,
++	0x03c02b34,
++	0x03b02b44,
++	0x03b02b42,
++	0x03b02b40,
++	0x03b02b3e,
++	0x03b02b3d,
++	0x03b02b3b,
++	0x03b02b39,
++	0x03b02b38,
++	0x03b02b36,
++	0x03b02b34,
++	0x03b02b33,
++	0x03b02b32,
++	0x03b02b30,
++	0x03b02b2f,
++	0x03b02b2d,
++	0x03a02b44,
++	0x03a02b42,
++	0x03a02b40,
++	0x03a02b3e,
++	0x03a02b3d,
++	0x03a02b3b,
++	0x03a02b39,
++	0x03a02b38,
++	0x03a02b36,
++	0x03a02b34,
++	0x03902b44,
++	0x03902b42,
++	0x03902b40,
++	0x03902b3e,
++	0x03902b3d,
++	0x03902b3b,
++	0x03902b39,
++	0x03902b38,
++	0x03902b36,
++	0x03902b34,
++	0x03902b33,
++	0x03902b32,
++	0x03902b30,
++	0x03802b44,
++	0x03802b42,
++	0x03802b40,
++	0x03802b3e,
++	0x03802b3d,
++	0x03802b3b,
++	0x03802b39,
++	0x03802b38,
++	0x03802b36,
++	0x03802b34,
++	0x03802b33,
++	0x03802b32,
++	0x03802b30,
++	0x03802b2f,
++	0x03802b2d,
++	0x03802b2c,
++	0x03802b2b,
++	0x03802b2a,
++	0x03802b29,
++	0x03802b27,
++	0x03802b26,
++	0x03802b25,
++	0x03802b24,
++	0x03802b23,
++	0x03802b22,
++	0x03802b21,
++	0x03802b20,
++	0x03802b1f,
++	0x03802b1e,
++	0x03802b1e,
++	0x03802b1d,
++	0x03802b1c,
++	0x03802b1b,
++	0x03802b1a,
++	0x03802b1a,
++	0x03802b19,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x00002b00,
++};
++
++static const u32 gainctrl_lut_core1_rev0[] = {
++	0x03cc2b44,
++	0x03cc2b42,
++	0x03cc2b40,
++	0x03cc2b3e,
++	0x03cc2b3d,
++	0x03cc2b3b,
++	0x03c82b44,
++	0x03c82b42,
++	0x03c82b40,
++	0x03c82b3e,
++	0x03c82b3d,
++	0x03c82b3b,
++	0x03c82b39,
++	0x03c82b38,
++	0x03c82b36,
++	0x03c82b34,
++	0x03c42b44,
++	0x03c42b42,
++	0x03c42b40,
++	0x03c42b3e,
++	0x03c42b3d,
++	0x03c42b3b,
++	0x03c42b39,
++	0x03c42b38,
++	0x03c42b36,
++	0x03c42b34,
++	0x03c42b33,
++	0x03c42b32,
++	0x03c42b30,
++	0x03c42b2f,
++	0x03c42b2d,
++	0x03c02b44,
++	0x03c02b42,
++	0x03c02b40,
++	0x03c02b3e,
++	0x03c02b3d,
++	0x03c02b3b,
++	0x03c02b39,
++	0x03c02b38,
++	0x03c02b36,
++	0x03c02b34,
++	0x03b02b44,
++	0x03b02b42,
++	0x03b02b40,
++	0x03b02b3e,
++	0x03b02b3d,
++	0x03b02b3b,
++	0x03b02b39,
++	0x03b02b38,
++	0x03b02b36,
++	0x03b02b34,
++	0x03b02b33,
++	0x03b02b32,
++	0x03b02b30,
++	0x03b02b2f,
++	0x03b02b2d,
++	0x03a02b44,
++	0x03a02b42,
++	0x03a02b40,
++	0x03a02b3e,
++	0x03a02b3d,
++	0x03a02b3b,
++	0x03a02b39,
++	0x03a02b38,
++	0x03a02b36,
++	0x03a02b34,
++	0x03902b44,
++	0x03902b42,
++	0x03902b40,
++	0x03902b3e,
++	0x03902b3d,
++	0x03902b3b,
++	0x03902b39,
++	0x03902b38,
++	0x03902b36,
++	0x03902b34,
++	0x03902b33,
++	0x03902b32,
++	0x03902b30,
++	0x03802b44,
++	0x03802b42,
++	0x03802b40,
++	0x03802b3e,
++	0x03802b3d,
++	0x03802b3b,
++	0x03802b39,
++	0x03802b38,
++	0x03802b36,
++	0x03802b34,
++	0x03802b33,
++	0x03802b32,
++	0x03802b30,
++	0x03802b2f,
++	0x03802b2d,
++	0x03802b2c,
++	0x03802b2b,
++	0x03802b2a,
++	0x03802b29,
++	0x03802b27,
++	0x03802b26,
++	0x03802b25,
++	0x03802b24,
++	0x03802b23,
++	0x03802b22,
++	0x03802b21,
++	0x03802b20,
++	0x03802b1f,
++	0x03802b1e,
++	0x03802b1e,
++	0x03802b1d,
++	0x03802b1c,
++	0x03802b1b,
++	0x03802b1a,
++	0x03802b1a,
++	0x03802b19,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x00002b00,
++};
++
++static const u32 iq_lut_core0_rev0[] = {
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++};
++
++static const u32 iq_lut_core1_rev0[] = {
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++};
++
++static const u16 loft_lut_core0_rev0[] = {
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++};
++
++static const u16 loft_lut_core1_rev0[] = {
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++};
++
++const struct phytbl_info mimophytbl_info_rev0_volatile[] = {
++	{&bdi_tbl_rev0, sizeof(bdi_tbl_rev0) / sizeof(bdi_tbl_rev0[0]), 21, 0,
++	 16}
++	,
++	{&pltlut_tbl_rev0, sizeof(pltlut_tbl_rev0) / sizeof(pltlut_tbl_rev0[0]),
++	 20, 0, 32}
++	,
++	{&gainctrl_lut_core0_rev0,
++	 sizeof(gainctrl_lut_core0_rev0) / sizeof(gainctrl_lut_core0_rev0[0]),
++	 26, 192, 32}
++	,
++	{&gainctrl_lut_core1_rev0,
++	 sizeof(gainctrl_lut_core1_rev0) / sizeof(gainctrl_lut_core1_rev0[0]),
++	 27, 192, 32}
++	,
++
++	{&est_pwr_lut_core0_rev0,
++	 sizeof(est_pwr_lut_core0_rev0) / sizeof(est_pwr_lut_core0_rev0[0]), 26,
++	 0, 8}
++	,
++	{&est_pwr_lut_core1_rev0,
++	 sizeof(est_pwr_lut_core1_rev0) / sizeof(est_pwr_lut_core1_rev0[0]), 27,
++	 0, 8}
++	,
++	{&adj_pwr_lut_core0_rev0,
++	 sizeof(adj_pwr_lut_core0_rev0) / sizeof(adj_pwr_lut_core0_rev0[0]), 26,
++	 64, 8}
++	,
++	{&adj_pwr_lut_core1_rev0,
++	 sizeof(adj_pwr_lut_core1_rev0) / sizeof(adj_pwr_lut_core1_rev0[0]), 27,
++	 64, 8}
++	,
++	{&iq_lut_core0_rev0,
++	 sizeof(iq_lut_core0_rev0) / sizeof(iq_lut_core0_rev0[0]), 26, 320, 32}
++	,
++	{&iq_lut_core1_rev0,
++	 sizeof(iq_lut_core1_rev0) / sizeof(iq_lut_core1_rev0[0]), 27, 320, 32}
++	,
++	{&loft_lut_core0_rev0,
++	 sizeof(loft_lut_core0_rev0) / sizeof(loft_lut_core0_rev0[0]), 26, 448,
++	 16}
++	,
++	{&loft_lut_core1_rev0,
++	 sizeof(loft_lut_core1_rev0) / sizeof(loft_lut_core1_rev0[0]), 27, 448,
++	 16}
++	,
++};
++
++const struct phytbl_info mimophytbl_info_rev0[] = {
++	{&frame_struct_rev0,
++	 sizeof(frame_struct_rev0) / sizeof(frame_struct_rev0[0]), 10, 0, 32}
++	,
++	{&frame_lut_rev0, sizeof(frame_lut_rev0) / sizeof(frame_lut_rev0[0]),
++	 24, 0, 8}
++	,
++	{&tmap_tbl_rev0, sizeof(tmap_tbl_rev0) / sizeof(tmap_tbl_rev0[0]), 12,
++	 0, 32}
++	,
++	{&tdtrn_tbl_rev0, sizeof(tdtrn_tbl_rev0) / sizeof(tdtrn_tbl_rev0[0]),
++	 14, 0, 32}
++	,
++	{&intlv_tbl_rev0, sizeof(intlv_tbl_rev0) / sizeof(intlv_tbl_rev0[0]),
++	 13, 0, 32}
++	,
++	{&pilot_tbl_rev0, sizeof(pilot_tbl_rev0) / sizeof(pilot_tbl_rev0[0]),
++	 11, 0, 16}
++	,
++	{&tdi_tbl20_ant0_rev0,
++	 sizeof(tdi_tbl20_ant0_rev0) / sizeof(tdi_tbl20_ant0_rev0[0]), 19, 128,
++	 32}
++	,
++	{&tdi_tbl20_ant1_rev0,
++	 sizeof(tdi_tbl20_ant1_rev0) / sizeof(tdi_tbl20_ant1_rev0[0]), 19, 256,
++	 32}
++	,
++	{&tdi_tbl40_ant0_rev0,
++	 sizeof(tdi_tbl40_ant0_rev0) / sizeof(tdi_tbl40_ant0_rev0[0]), 19, 640,
++	 32}
++	,
++	{&tdi_tbl40_ant1_rev0,
++	 sizeof(tdi_tbl40_ant1_rev0) / sizeof(tdi_tbl40_ant1_rev0[0]), 19, 768,
++	 32}
++	,
++	{&chanest_tbl_rev0,
++	 sizeof(chanest_tbl_rev0) / sizeof(chanest_tbl_rev0[0]), 22, 0, 32}
++	,
++	{&mcs_tbl_rev0, sizeof(mcs_tbl_rev0) / sizeof(mcs_tbl_rev0[0]), 18, 0,
++	 8}
++	,
++	{&noise_var_tbl0_rev0,
++	 sizeof(noise_var_tbl0_rev0) / sizeof(noise_var_tbl0_rev0[0]), 16, 0,
++	 32}
++	,
++	{&noise_var_tbl1_rev0,
++	 sizeof(noise_var_tbl1_rev0) / sizeof(noise_var_tbl1_rev0[0]), 16, 128,
++	 32}
++	,
++};
++
++const u32 mimophytbl_info_sz_rev0 =
++	sizeof(mimophytbl_info_rev0) / sizeof(mimophytbl_info_rev0[0]);
++const u32 mimophytbl_info_sz_rev0_volatile =
++	sizeof(mimophytbl_info_rev0_volatile) /
++	sizeof(mimophytbl_info_rev0_volatile[0]);
++
++static const u16 ant_swctrl_tbl_rev3[] = {
++	0x0082,
++	0x0082,
++	0x0211,
++	0x0222,
++	0x0328,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0144,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0188,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0082,
++	0x0082,
++	0x0211,
++	0x0222,
++	0x0328,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0144,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0188,
++	0x0000,
++	0x0000,
++	0x0000,
++};
++
++static const u16 ant_swctrl_tbl_rev3_1[] = {
++	0x0022,
++	0x0022,
++	0x0011,
++	0x0022,
++	0x0022,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0011,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0022,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0022,
++	0x0022,
++	0x0011,
++	0x0022,
++	0x0022,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0011,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0022,
++	0x0000,
++	0x0000,
++	0x0000,
++};
++
++static const u16 ant_swctrl_tbl_rev3_2[] = {
++	0x0088,
++	0x0088,
++	0x0044,
++	0x0088,
++	0x0088,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0044,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0088,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0088,
++	0x0088,
++	0x0044,
++	0x0088,
++	0x0088,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0044,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0088,
++	0x0000,
++	0x0000,
++	0x0000,
++};
++
++static const u16 ant_swctrl_tbl_rev3_3[] = {
++	0x022,
++	0x022,
++	0x011,
++	0x022,
++	0x000,
++	0x000,
++	0x000,
++	0x000,
++	0x011,
++	0x000,
++	0x000,
++	0x000,
++	0x022,
++	0x000,
++	0x000,
++	0x3cc,
++	0x022,
++	0x022,
++	0x011,
++	0x022,
++	0x000,
++	0x000,
++	0x000,
++	0x000,
++	0x011,
++	0x000,
++	0x000,
++	0x000,
++	0x022,
++	0x000,
++	0x000,
++	0x3cc
++};
++
++static const u32 frame_struct_rev3[] = {
++	0x08004a04,
++	0x00100000,
++	0x01000a05,
++	0x00100020,
++	0x09804506,
++	0x00100030,
++	0x09804507,
++	0x00100030,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x08004a0c,
++	0x00100004,
++	0x01000a0d,
++	0x00100024,
++	0x0980450e,
++	0x00100034,
++	0x0980450f,
++	0x00100034,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000a04,
++	0x00100000,
++	0x11008a05,
++	0x00100020,
++	0x1980c506,
++	0x00100030,
++	0x21810506,
++	0x00100030,
++	0x21810506,
++	0x00100030,
++	0x01800504,
++	0x00100030,
++	0x11808505,
++	0x00100030,
++	0x29814507,
++	0x01100030,
++	0x00000a04,
++	0x00100000,
++	0x11008a05,
++	0x00100020,
++	0x21810506,
++	0x00100030,
++	0x21810506,
++	0x00100030,
++	0x29814507,
++	0x01100030,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000a0c,
++	0x00100008,
++	0x11008a0d,
++	0x00100028,
++	0x1980c50e,
++	0x00100038,
++	0x2181050e,
++	0x00100038,
++	0x2181050e,
++	0x00100038,
++	0x0180050c,
++	0x00100038,
++	0x1180850d,
++	0x00100038,
++	0x2981450f,
++	0x01100038,
++	0x00000a0c,
++	0x00100008,
++	0x11008a0d,
++	0x00100028,
++	0x2181050e,
++	0x00100038,
++	0x2181050e,
++	0x00100038,
++	0x2981450f,
++	0x01100038,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x08004a04,
++	0x00100000,
++	0x01000a05,
++	0x00100020,
++	0x1980c506,
++	0x00100030,
++	0x1980c506,
++	0x00100030,
++	0x11808504,
++	0x00100030,
++	0x3981ca05,
++	0x00100030,
++	0x29814507,
++	0x01100030,
++	0x00000000,
++	0x00000000,
++	0x10008a04,
++	0x00100000,
++	0x3981ca05,
++	0x00100030,
++	0x1980c506,
++	0x00100030,
++	0x29814507,
++	0x01100030,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x08004a0c,
++	0x00100008,
++	0x01000a0d,
++	0x00100028,
++	0x1980c50e,
++	0x00100038,
++	0x1980c50e,
++	0x00100038,
++	0x1180850c,
++	0x00100038,
++	0x3981ca0d,
++	0x00100038,
++	0x2981450f,
++	0x01100038,
++	0x00000000,
++	0x00000000,
++	0x10008a0c,
++	0x00100008,
++	0x3981ca0d,
++	0x00100038,
++	0x1980c50e,
++	0x00100038,
++	0x2981450f,
++	0x01100038,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x40021404,
++	0x00100000,
++	0x02001405,
++	0x00100040,
++	0x0b004a06,
++	0x01900060,
++	0x13008a06,
++	0x01900060,
++	0x13008a06,
++	0x01900060,
++	0x43020a04,
++	0x00100060,
++	0x1b00ca05,
++	0x00100060,
++	0x23010a07,
++	0x01500060,
++	0x40021404,
++	0x00100000,
++	0x1a00d405,
++	0x00100040,
++	0x13008a06,
++	0x01900060,
++	0x13008a06,
++	0x01900060,
++	0x23010a07,
++	0x01500060,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x4002140c,
++	0x00100010,
++	0x0200140d,
++	0x00100050,
++	0x0b004a0e,
++	0x01900070,
++	0x13008a0e,
++	0x01900070,
++	0x13008a0e,
++	0x01900070,
++	0x43020a0c,
++	0x00100070,
++	0x1b00ca0d,
++	0x00100070,
++	0x23010a0f,
++	0x01500070,
++	0x4002140c,
++	0x00100010,
++	0x1a00d40d,
++	0x00100050,
++	0x13008a0e,
++	0x01900070,
++	0x13008a0e,
++	0x01900070,
++	0x23010a0f,
++	0x01500070,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x50029404,
++	0x00100000,
++	0x32019405,
++	0x00100040,
++	0x0b004a06,
++	0x01900060,
++	0x0b004a06,
++	0x01900060,
++	0x5b02ca04,
++	0x00100060,
++	0x3b01d405,
++	0x00100060,
++	0x23010a07,
++	0x01500060,
++	0x00000000,
++	0x00000000,
++	0x5802d404,
++	0x00100000,
++	0x3b01d405,
++	0x00100060,
++	0x0b004a06,
++	0x01900060,
++	0x23010a07,
++	0x01500060,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x5002940c,
++	0x00100010,
++	0x3201940d,
++	0x00100050,
++	0x0b004a0e,
++	0x01900070,
++	0x0b004a0e,
++	0x01900070,
++	0x5b02ca0c,
++	0x00100070,
++	0x3b01d40d,
++	0x00100070,
++	0x23010a0f,
++	0x01500070,
++	0x00000000,
++	0x00000000,
++	0x5802d40c,
++	0x00100010,
++	0x3b01d40d,
++	0x00100070,
++	0x0b004a0e,
++	0x01900070,
++	0x23010a0f,
++	0x01500070,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x40021404,
++	0x000f4800,
++	0x62031405,
++	0x00100040,
++	0x53028a06,
++	0x01900060,
++	0x53028a07,
++	0x01900060,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x4002140c,
++	0x000f4808,
++	0x6203140d,
++	0x00100048,
++	0x53028a0e,
++	0x01900068,
++	0x53028a0f,
++	0x01900068,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000a0c,
++	0x00100004,
++	0x11008a0d,
++	0x00100024,
++	0x1980c50e,
++	0x00100034,
++	0x2181050e,
++	0x00100034,
++	0x2181050e,
++	0x00100034,
++	0x0180050c,
++	0x00100038,
++	0x1180850d,
++	0x00100038,
++	0x1181850d,
++	0x00100038,
++	0x2981450f,
++	0x01100038,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000a0c,
++	0x00100008,
++	0x11008a0d,
++	0x00100028,
++	0x2181050e,
++	0x00100038,
++	0x2181050e,
++	0x00100038,
++	0x1181850d,
++	0x00100038,
++	0x2981450f,
++	0x01100038,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x08004a04,
++	0x00100000,
++	0x01000a05,
++	0x00100020,
++	0x0180c506,
++	0x00100030,
++	0x0180c506,
++	0x00100030,
++	0x2180c50c,
++	0x00100030,
++	0x49820a0d,
++	0x0016a130,
++	0x41824a0d,
++	0x0016a130,
++	0x2981450f,
++	0x01100030,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x2000ca0c,
++	0x00100000,
++	0x49820a0d,
++	0x0016a130,
++	0x1980c50e,
++	0x00100030,
++	0x41824a0d,
++	0x0016a130,
++	0x2981450f,
++	0x01100030,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x4002140c,
++	0x00100008,
++	0x0200140d,
++	0x00100048,
++	0x0b004a0e,
++	0x01900068,
++	0x13008a0e,
++	0x01900068,
++	0x13008a0e,
++	0x01900068,
++	0x43020a0c,
++	0x00100070,
++	0x1b00ca0d,
++	0x00100070,
++	0x1b014a0d,
++	0x00100070,
++	0x23010a0f,
++	0x01500070,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x4002140c,
++	0x00100010,
++	0x1a00d40d,
++	0x00100050,
++	0x13008a0e,
++	0x01900070,
++	0x13008a0e,
++	0x01900070,
++	0x1b014a0d,
++	0x00100070,
++	0x23010a0f,
++	0x01500070,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x50029404,
++	0x00100000,
++	0x32019405,
++	0x00100040,
++	0x03004a06,
++	0x01900060,
++	0x03004a06,
++	0x01900060,
++	0x6b030a0c,
++	0x00100060,
++	0x4b02140d,
++	0x0016a160,
++	0x4302540d,
++	0x0016a160,
++	0x23010a0f,
++	0x01500060,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x6b03140c,
++	0x00100060,
++	0x4b02140d,
++	0x0016a160,
++	0x0b004a0e,
++	0x01900060,
++	0x4302540d,
++	0x0016a160,
++	0x23010a0f,
++	0x01500060,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x40021404,
++	0x00100000,
++	0x1a00d405,
++	0x00100040,
++	0x53028a06,
++	0x01900060,
++	0x5b02ca06,
++	0x01900060,
++	0x5b02ca06,
++	0x01900060,
++	0x43020a04,
++	0x00100060,
++	0x1b00ca05,
++	0x00100060,
++	0x53028a07,
++	0x0190c060,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x4002140c,
++	0x00100010,
++	0x1a00d40d,
++	0x00100050,
++	0x53028a0e,
++	0x01900070,
++	0x5b02ca0e,
++	0x01900070,
++	0x5b02ca0e,
++	0x01900070,
++	0x43020a0c,
++	0x00100070,
++	0x1b00ca0d,
++	0x00100070,
++	0x53028a0f,
++	0x0190c070,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x40021404,
++	0x00100000,
++	0x1a00d405,
++	0x00100040,
++	0x5b02ca06,
++	0x01900060,
++	0x5b02ca06,
++	0x01900060,
++	0x53028a07,
++	0x0190c060,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x4002140c,
++	0x00100010,
++	0x1a00d40d,
++	0x00100050,
++	0x5b02ca0e,
++	0x01900070,
++	0x5b02ca0e,
++	0x01900070,
++	0x53028a0f,
++	0x0190c070,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++};
++
++static const u16 pilot_tbl_rev3[] = {
++	0xff08,
++	0xff08,
++	0xff08,
++	0xff08,
++	0xff08,
++	0xff08,
++	0xff08,
++	0xff08,
++	0x80d5,
++	0x80d5,
++	0x80d5,
++	0x80d5,
++	0x80d5,
++	0x80d5,
++	0x80d5,
++	0x80d5,
++	0xff0a,
++	0xff82,
++	0xffa0,
++	0xff28,
++	0xffff,
++	0xffff,
++	0xffff,
++	0xffff,
++	0xff82,
++	0xffa0,
++	0xff28,
++	0xff0a,
++	0xffff,
++	0xffff,
++	0xffff,
++	0xffff,
++	0xf83f,
++	0xfa1f,
++	0xfa97,
++	0xfab5,
++	0xf2bd,
++	0xf0bf,
++	0xffff,
++	0xffff,
++	0xf017,
++	0xf815,
++	0xf215,
++	0xf095,
++	0xf035,
++	0xf01d,
++	0xffff,
++	0xffff,
++	0xff08,
++	0xff02,
++	0xff80,
++	0xff20,
++	0xff08,
++	0xff02,
++	0xff80,
++	0xff20,
++	0xf01f,
++	0xf817,
++	0xfa15,
++	0xf295,
++	0xf0b5,
++	0xf03d,
++	0xffff,
++	0xffff,
++	0xf82a,
++	0xfa0a,
++	0xfa82,
++	0xfaa0,
++	0xf2a8,
++	0xf0aa,
++	0xffff,
++	0xffff,
++	0xf002,
++	0xf800,
++	0xf200,
++	0xf080,
++	0xf020,
++	0xf008,
++	0xffff,
++	0xffff,
++	0xf00a,
++	0xf802,
++	0xfa00,
++	0xf280,
++	0xf0a0,
++	0xf028,
++	0xffff,
++	0xffff,
++};
++
++static const u32 tmap_tbl_rev3[] = {
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0xf1111110,
++	0x11111111,
++	0x11f11111,
++	0x00000111,
++	0x11000000,
++	0x1111f111,
++	0x11111111,
++	0x111111f1,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x000aa888,
++	0x88880000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0xa1111110,
++	0x11111111,
++	0x11c11111,
++	0x00000111,
++	0x11000000,
++	0x1111a111,
++	0x11111111,
++	0x111111a1,
++	0xa2222220,
++	0x22222222,
++	0x22c22222,
++	0x00000222,
++	0x22000000,
++	0x2222a222,
++	0x22222222,
++	0x222222a2,
++	0xf1111110,
++	0x11111111,
++	0x11f11111,
++	0x00011111,
++	0x11110000,
++	0x1111f111,
++	0x11111111,
++	0x111111f1,
++	0xa8aa88a0,
++	0xa88888a8,
++	0xa8a8a88a,
++	0x00088aaa,
++	0xaaaa0000,
++	0xa8a8aa88,
++	0xa88aaaaa,
++	0xaaaa8a8a,
++	0xaaa8aaa0,
++	0x8aaa8aaa,
++	0xaa8a8a8a,
++	0x000aaa88,
++	0x8aaa0000,
++	0xaaa8a888,
++	0x8aa88a8a,
++	0x8a88a888,
++	0x08080a00,
++	0x0a08080a,
++	0x080a0a08,
++	0x00080808,
++	0x080a0000,
++	0x080a0808,
++	0x080a0808,
++	0x0a0a0a08,
++	0xa0a0a0a0,
++	0x80a0a080,
++	0x8080a0a0,
++	0x00008080,
++	0x80a00000,
++	0x80a080a0,
++	0xa080a0a0,
++	0x8080a0a0,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x99999000,
++	0x9b9b99bb,
++	0x9bb99999,
++	0x9999b9b9,
++	0x9b99bb90,
++	0x9bbbbb9b,
++	0x9b9b9bb9,
++	0x00000999,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00aaa888,
++	0x22000000,
++	0x2222b222,
++	0x22222222,
++	0x222222b2,
++	0xb2222220,
++	0x22222222,
++	0x22d22222,
++	0x00000222,
++	0x11000000,
++	0x1111a111,
++	0x11111111,
++	0x111111a1,
++	0xa1111110,
++	0x11111111,
++	0x11c11111,
++	0x00000111,
++	0x33000000,
++	0x3333b333,
++	0x33333333,
++	0x333333b3,
++	0xb3333330,
++	0x33333333,
++	0x33d33333,
++	0x00000333,
++	0x22000000,
++	0x2222a222,
++	0x22222222,
++	0x222222a2,
++	0xa2222220,
++	0x22222222,
++	0x22c22222,
++	0x00000222,
++	0x99b99b00,
++	0x9b9b99bb,
++	0x9bb99999,
++	0x9999b9b9,
++	0x9b99bb99,
++	0x9bbbbb9b,
++	0x9b9b9bb9,
++	0x00000999,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa88,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x08aaa888,
++	0x22222200,
++	0x2222f222,
++	0x22222222,
++	0x222222f2,
++	0x22222222,
++	0x22222222,
++	0x22f22222,
++	0x00000222,
++	0x11000000,
++	0x1111f111,
++	0x11111111,
++	0x11111111,
++	0xf1111111,
++	0x11111111,
++	0x11f11111,
++	0x01111111,
++	0xbb9bb900,
++	0xb9b9bb99,
++	0xb99bbbbb,
++	0xbbbb9b9b,
++	0xb9bb99bb,
++	0xb99999b9,
++	0xb9b9b99b,
++	0x00000bbb,
++	0xaa000000,
++	0xa8a8aa88,
++	0xa88aaaaa,
++	0xaaaa8a8a,
++	0xa8aa88aa,
++	0xa88888a8,
++	0xa8a8a88a,
++	0x0a888aaa,
++	0xaa000000,
++	0xa8a8aa88,
++	0xa88aaaaa,
++	0xaaaa8a8a,
++	0xa8aa88a0,
++	0xa88888a8,
++	0xa8a8a88a,
++	0x00000aaa,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0xbbbbbb00,
++	0x999bbbbb,
++	0x9bb99b9b,
++	0xb9b9b9bb,
++	0xb9b99bbb,
++	0xb9b9b9bb,
++	0xb9bb9b99,
++	0x00000999,
++	0x8a000000,
++	0xaa88a888,
++	0xa88888aa,
++	0xa88a8a88,
++	0xa88aa88a,
++	0x88a8aaaa,
++	0xa8aa8aaa,
++	0x0888a88a,
++	0x0b0b0b00,
++	0x090b0b0b,
++	0x0b090b0b,
++	0x0909090b,
++	0x09090b0b,
++	0x09090b0b,
++	0x09090b09,
++	0x00000909,
++	0x0a000000,
++	0x0a080808,
++	0x080a080a,
++	0x080a0a08,
++	0x080a080a,
++	0x0808080a,
++	0x0a0a0a08,
++	0x0808080a,
++	0xb0b0b000,
++	0x9090b0b0,
++	0x90b09090,
++	0xb0b0b090,
++	0xb0b090b0,
++	0x90b0b0b0,
++	0xb0b09090,
++	0x00000090,
++	0x80000000,
++	0xa080a080,
++	0xa08080a0,
++	0xa0808080,
++	0xa080a080,
++	0x80a0a0a0,
++	0xa0a080a0,
++	0x00a0a0a0,
++	0x22000000,
++	0x2222f222,
++	0x22222222,
++	0x222222f2,
++	0xf2222220,
++	0x22222222,
++	0x22f22222,
++	0x00000222,
++	0x11000000,
++	0x1111f111,
++	0x11111111,
++	0x111111f1,
++	0xf1111110,
++	0x11111111,
++	0x11f11111,
++	0x00000111,
++	0x33000000,
++	0x3333f333,
++	0x33333333,
++	0x333333f3,
++	0xf3333330,
++	0x33333333,
++	0x33f33333,
++	0x00000333,
++	0x22000000,
++	0x2222f222,
++	0x22222222,
++	0x222222f2,
++	0xf2222220,
++	0x22222222,
++	0x22f22222,
++	0x00000222,
++	0x99000000,
++	0x9b9b99bb,
++	0x9bb99999,
++	0x9999b9b9,
++	0x9b99bb90,
++	0x9bbbbb9b,
++	0x9b9b9bb9,
++	0x00000999,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0x88888000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00aaa888,
++	0x88a88a00,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa88,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa88,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x08aaa888,
++	0x11000000,
++	0x1111a111,
++	0x11111111,
++	0x111111a1,
++	0xa1111110,
++	0x11111111,
++	0x11c11111,
++	0x00000111,
++	0x11000000,
++	0x1111a111,
++	0x11111111,
++	0x111111a1,
++	0xa1111110,
++	0x11111111,
++	0x11c11111,
++	0x00000111,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++};
++
++static const u32 intlv_tbl_rev3[] = {
++	0x00802070,
++	0x0671188d,
++	0x0a60192c,
++	0x0a300e46,
++	0x00c1188d,
++	0x080024d2,
++	0x00000070,
++};
++
++static const u32 tdtrn_tbl_rev3[] = {
++	0x061c061c,
++	0x0050ee68,
++	0xf592fe36,
++	0xfe5212f6,
++	0x00000c38,
++	0xfe5212f6,
++	0xf592fe36,
++	0x0050ee68,
++	0x061c061c,
++	0xee680050,
++	0xfe36f592,
++	0x12f6fe52,
++	0x0c380000,
++	0x12f6fe52,
++	0xfe36f592,
++	0xee680050,
++	0x061c061c,
++	0x0050ee68,
++	0xf592fe36,
++	0xfe5212f6,
++	0x00000c38,
++	0xfe5212f6,
++	0xf592fe36,
++	0x0050ee68,
++	0x061c061c,
++	0xee680050,
++	0xfe36f592,
++	0x12f6fe52,
++	0x0c380000,
++	0x12f6fe52,
++	0xfe36f592,
++	0xee680050,
++	0x05e305e3,
++	0x004def0c,
++	0xf5f3fe47,
++	0xfe611246,
++	0x00000bc7,
++	0xfe611246,
++	0xf5f3fe47,
++	0x004def0c,
++	0x05e305e3,
++	0xef0c004d,
++	0xfe47f5f3,
++	0x1246fe61,
++	0x0bc70000,
++	0x1246fe61,
++	0xfe47f5f3,
++	0xef0c004d,
++	0x05e305e3,
++	0x004def0c,
++	0xf5f3fe47,
++	0xfe611246,
++	0x00000bc7,
++	0xfe611246,
++	0xf5f3fe47,
++	0x004def0c,
++	0x05e305e3,
++	0xef0c004d,
++	0xfe47f5f3,
++	0x1246fe61,
++	0x0bc70000,
++	0x1246fe61,
++	0xfe47f5f3,
++	0xef0c004d,
++	0xfa58fa58,
++	0xf895043b,
++	0xff4c09c0,
++	0xfbc6ffa8,
++	0xfb84f384,
++	0x0798f6f9,
++	0x05760122,
++	0x058409f6,
++	0x0b500000,
++	0x05b7f542,
++	0x08860432,
++	0x06ddfee7,
++	0xfb84f384,
++	0xf9d90664,
++	0xf7e8025c,
++	0x00fff7bd,
++	0x05a805a8,
++	0xf7bd00ff,
++	0x025cf7e8,
++	0x0664f9d9,
++	0xf384fb84,
++	0xfee706dd,
++	0x04320886,
++	0xf54205b7,
++	0x00000b50,
++	0x09f60584,
++	0x01220576,
++	0xf6f90798,
++	0xf384fb84,
++	0xffa8fbc6,
++	0x09c0ff4c,
++	0x043bf895,
++	0x02d402d4,
++	0x07de0270,
++	0xfc96079c,
++	0xf90afe94,
++	0xfe00ff2c,
++	0x02d4065d,
++	0x092a0096,
++	0x0014fbb8,
++	0xfd2cfd2c,
++	0x076afb3c,
++	0x0096f752,
++	0xf991fd87,
++	0xfb2c0200,
++	0xfeb8f960,
++	0x08e0fc96,
++	0x049802a8,
++	0xfd2cfd2c,
++	0x02a80498,
++	0xfc9608e0,
++	0xf960feb8,
++	0x0200fb2c,
++	0xfd87f991,
++	0xf7520096,
++	0xfb3c076a,
++	0xfd2cfd2c,
++	0xfbb80014,
++	0x0096092a,
++	0x065d02d4,
++	0xff2cfe00,
++	0xfe94f90a,
++	0x079cfc96,
++	0x027007de,
++	0x02d402d4,
++	0x027007de,
++	0x079cfc96,
++	0xfe94f90a,
++	0xff2cfe00,
++	0x065d02d4,
++	0x0096092a,
++	0xfbb80014,
++	0xfd2cfd2c,
++	0xfb3c076a,
++	0xf7520096,
++	0xfd87f991,
++	0x0200fb2c,
++	0xf960feb8,
++	0xfc9608e0,
++	0x02a80498,
++	0xfd2cfd2c,
++	0x049802a8,
++	0x08e0fc96,
++	0xfeb8f960,
++	0xfb2c0200,
++	0xf991fd87,
++	0x0096f752,
++	0x076afb3c,
++	0xfd2cfd2c,
++	0x0014fbb8,
++	0x092a0096,
++	0x02d4065d,
++	0xfe00ff2c,
++	0xf90afe94,
++	0xfc96079c,
++	0x07de0270,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x062a0000,
++	0xfefa0759,
++	0x08b80908,
++	0xf396fc2d,
++	0xf9d6045c,
++	0xfc4ef608,
++	0xf748f596,
++	0x07b207bf,
++	0x062a062a,
++	0xf84ef841,
++	0xf748f596,
++	0x03b209f8,
++	0xf9d6045c,
++	0x0c6a03d3,
++	0x08b80908,
++	0x0106f8a7,
++	0x062a0000,
++	0xfefaf8a7,
++	0x08b8f6f8,
++	0xf39603d3,
++	0xf9d6fba4,
++	0xfc4e09f8,
++	0xf7480a6a,
++	0x07b2f841,
++	0x062af9d6,
++	0xf84e07bf,
++	0xf7480a6a,
++	0x03b2f608,
++	0xf9d6fba4,
++	0x0c6afc2d,
++	0x08b8f6f8,
++	0x01060759,
++	0x062a0000,
++	0xfefa0759,
++	0x08b80908,
++	0xf396fc2d,
++	0xf9d6045c,
++	0xfc4ef608,
++	0xf748f596,
++	0x07b207bf,
++	0x062a062a,
++	0xf84ef841,
++	0xf748f596,
++	0x03b209f8,
++	0xf9d6045c,
++	0x0c6a03d3,
++	0x08b80908,
++	0x0106f8a7,
++	0x062a0000,
++	0xfefaf8a7,
++	0x08b8f6f8,
++	0xf39603d3,
++	0xf9d6fba4,
++	0xfc4e09f8,
++	0xf7480a6a,
++	0x07b2f841,
++	0x062af9d6,
++	0xf84e07bf,
++	0xf7480a6a,
++	0x03b2f608,
++	0xf9d6fba4,
++	0x0c6afc2d,
++	0x08b8f6f8,
++	0x01060759,
++	0x061c061c,
++	0xff30009d,
++	0xffb21141,
++	0xfd87fb54,
++	0xf65dfe59,
++	0x02eef99e,
++	0x0166f03c,
++	0xfff809b6,
++	0x000008a4,
++	0x000af42b,
++	0x00eff577,
++	0xfa840bf2,
++	0xfc02ff51,
++	0x08260f67,
++	0xfff0036f,
++	0x0842f9c3,
++	0x00000000,
++	0x063df7be,
++	0xfc910010,
++	0xf099f7da,
++	0x00af03fe,
++	0xf40e057c,
++	0x0a89ff11,
++	0x0bd5fff6,
++	0xf75c0000,
++	0xf64a0008,
++	0x0fc4fe9a,
++	0x0662fd12,
++	0x01a709a3,
++	0x04ac0279,
++	0xeebf004e,
++	0xff6300d0,
++	0xf9e4f9e4,
++	0x00d0ff63,
++	0x004eeebf,
++	0x027904ac,
++	0x09a301a7,
++	0xfd120662,
++	0xfe9a0fc4,
++	0x0008f64a,
++	0x0000f75c,
++	0xfff60bd5,
++	0xff110a89,
++	0x057cf40e,
++	0x03fe00af,
++	0xf7daf099,
++	0x0010fc91,
++	0xf7be063d,
++	0x00000000,
++	0xf9c30842,
++	0x036ffff0,
++	0x0f670826,
++	0xff51fc02,
++	0x0bf2fa84,
++	0xf57700ef,
++	0xf42b000a,
++	0x08a40000,
++	0x09b6fff8,
++	0xf03c0166,
++	0xf99e02ee,
++	0xfe59f65d,
++	0xfb54fd87,
++	0x1141ffb2,
++	0x009dff30,
++	0x05e30000,
++	0xff060705,
++	0x085408a0,
++	0xf425fc59,
++	0xfa1d042a,
++	0xfc78f67a,
++	0xf7acf60e,
++	0x075a0766,
++	0x05e305e3,
++	0xf8a6f89a,
++	0xf7acf60e,
++	0x03880986,
++	0xfa1d042a,
++	0x0bdb03a7,
++	0x085408a0,
++	0x00faf8fb,
++	0x05e30000,
++	0xff06f8fb,
++	0x0854f760,
++	0xf42503a7,
++	0xfa1dfbd6,
++	0xfc780986,
++	0xf7ac09f2,
++	0x075af89a,
++	0x05e3fa1d,
++	0xf8a60766,
++	0xf7ac09f2,
++	0x0388f67a,
++	0xfa1dfbd6,
++	0x0bdbfc59,
++	0x0854f760,
++	0x00fa0705,
++	0x05e30000,
++	0xff060705,
++	0x085408a0,
++	0xf425fc59,
++	0xfa1d042a,
++	0xfc78f67a,
++	0xf7acf60e,
++	0x075a0766,
++	0x05e305e3,
++	0xf8a6f89a,
++	0xf7acf60e,
++	0x03880986,
++	0xfa1d042a,
++	0x0bdb03a7,
++	0x085408a0,
++	0x00faf8fb,
++	0x05e30000,
++	0xff06f8fb,
++	0x0854f760,
++	0xf42503a7,
++	0xfa1dfbd6,
++	0xfc780986,
++	0xf7ac09f2,
++	0x075af89a,
++	0x05e3fa1d,
++	0xf8a60766,
++	0xf7ac09f2,
++	0x0388f67a,
++	0xfa1dfbd6,
++	0x0bdbfc59,
++	0x0854f760,
++	0x00fa0705,
++	0xfa58fa58,
++	0xf8f0fe00,
++	0x0448073d,
++	0xfdc9fe46,
++	0xf9910258,
++	0x089d0407,
++	0xfd5cf71a,
++	0x02affde0,
++	0x083e0496,
++	0xff5a0740,
++	0xff7afd97,
++	0x00fe01f1,
++	0x0009082e,
++	0xfa94ff75,
++	0xfecdf8ea,
++	0xffb0f693,
++	0xfd2cfa58,
++	0x0433ff16,
++	0xfba405dd,
++	0xfa610341,
++	0x06a606cb,
++	0x0039fd2d,
++	0x0677fa97,
++	0x01fa05e0,
++	0xf896003e,
++	0x075a068b,
++	0x012cfc3e,
++	0xfa23f98d,
++	0xfc7cfd43,
++	0xff90fc0d,
++	0x01c10982,
++	0x00c601d6,
++	0xfd2cfd2c,
++	0x01d600c6,
++	0x098201c1,
++	0xfc0dff90,
++	0xfd43fc7c,
++	0xf98dfa23,
++	0xfc3e012c,
++	0x068b075a,
++	0x003ef896,
++	0x05e001fa,
++	0xfa970677,
++	0xfd2d0039,
++	0x06cb06a6,
++	0x0341fa61,
++	0x05ddfba4,
++	0xff160433,
++	0xfa58fd2c,
++	0xf693ffb0,
++	0xf8eafecd,
++	0xff75fa94,
++	0x082e0009,
++	0x01f100fe,
++	0xfd97ff7a,
++	0x0740ff5a,
++	0x0496083e,
++	0xfde002af,
++	0xf71afd5c,
++	0x0407089d,
++	0x0258f991,
++	0xfe46fdc9,
++	0x073d0448,
++	0xfe00f8f0,
++	0xfd2cfd2c,
++	0xfce00500,
++	0xfc09fddc,
++	0xfe680157,
++	0x04c70571,
++	0xfc3aff21,
++	0xfcd70228,
++	0x056d0277,
++	0x0200fe00,
++	0x0022f927,
++	0xfe3c032b,
++	0xfc44ff3c,
++	0x03e9fbdb,
++	0x04570313,
++	0x04c9ff5c,
++	0x000d03b8,
++	0xfa580000,
++	0xfbe900d2,
++	0xf9d0fe0b,
++	0x0125fdf9,
++	0x042501bf,
++	0x0328fa2b,
++	0xffa902f0,
++	0xfa250157,
++	0x0200fe00,
++	0x03740438,
++	0xff0405fd,
++	0x030cfe52,
++	0x0037fb39,
++	0xff6904c5,
++	0x04f8fd23,
++	0xfd31fc1b,
++	0xfd2cfd2c,
++	0xfc1bfd31,
++	0xfd2304f8,
++	0x04c5ff69,
++	0xfb390037,
++	0xfe52030c,
++	0x05fdff04,
++	0x04380374,
++	0xfe000200,
++	0x0157fa25,
++	0x02f0ffa9,
++	0xfa2b0328,
++	0x01bf0425,
++	0xfdf90125,
++	0xfe0bf9d0,
++	0x00d2fbe9,
++	0x0000fa58,
++	0x03b8000d,
++	0xff5c04c9,
++	0x03130457,
++	0xfbdb03e9,
++	0xff3cfc44,
++	0x032bfe3c,
++	0xf9270022,
++	0xfe000200,
++	0x0277056d,
++	0x0228fcd7,
++	0xff21fc3a,
++	0x057104c7,
++	0x0157fe68,
++	0xfddcfc09,
++	0x0500fce0,
++	0xfd2cfd2c,
++	0x0500fce0,
++	0xfddcfc09,
++	0x0157fe68,
++	0x057104c7,
++	0xff21fc3a,
++	0x0228fcd7,
++	0x0277056d,
++	0xfe000200,
++	0xf9270022,
++	0x032bfe3c,
++	0xff3cfc44,
++	0xfbdb03e9,
++	0x03130457,
++	0xff5c04c9,
++	0x03b8000d,
++	0x0000fa58,
++	0x00d2fbe9,
++	0xfe0bf9d0,
++	0xfdf90125,
++	0x01bf0425,
++	0xfa2b0328,
++	0x02f0ffa9,
++	0x0157fa25,
++	0xfe000200,
++	0x04380374,
++	0x05fdff04,
++	0xfe52030c,
++	0xfb390037,
++	0x04c5ff69,
++	0xfd2304f8,
++	0xfc1bfd31,
++	0xfd2cfd2c,
++	0xfd31fc1b,
++	0x04f8fd23,
++	0xff6904c5,
++	0x0037fb39,
++	0x030cfe52,
++	0xff0405fd,
++	0x03740438,
++	0x0200fe00,
++	0xfa250157,
++	0xffa902f0,
++	0x0328fa2b,
++	0x042501bf,
++	0x0125fdf9,
++	0xf9d0fe0b,
++	0xfbe900d2,
++	0xfa580000,
++	0x000d03b8,
++	0x04c9ff5c,
++	0x04570313,
++	0x03e9fbdb,
++	0xfc44ff3c,
++	0xfe3c032b,
++	0x0022f927,
++	0x0200fe00,
++	0x056d0277,
++	0xfcd70228,
++	0xfc3aff21,
++	0x04c70571,
++	0xfe680157,
++	0xfc09fddc,
++	0xfce00500,
++	0x05a80000,
++	0xff1006be,
++	0x0800084a,
++	0xf49cfc7e,
++	0xfa580400,
++	0xfc9cf6da,
++	0xf800f672,
++	0x0710071c,
++	0x05a805a8,
++	0xf8f0f8e4,
++	0xf800f672,
++	0x03640926,
++	0xfa580400,
++	0x0b640382,
++	0x0800084a,
++	0x00f0f942,
++	0x05a80000,
++	0xff10f942,
++	0x0800f7b6,
++	0xf49c0382,
++	0xfa58fc00,
++	0xfc9c0926,
++	0xf800098e,
++	0x0710f8e4,
++	0x05a8fa58,
++	0xf8f0071c,
++	0xf800098e,
++	0x0364f6da,
++	0xfa58fc00,
++	0x0b64fc7e,
++	0x0800f7b6,
++	0x00f006be,
++	0x05a80000,
++	0xff1006be,
++	0x0800084a,
++	0xf49cfc7e,
++	0xfa580400,
++	0xfc9cf6da,
++	0xf800f672,
++	0x0710071c,
++	0x05a805a8,
++	0xf8f0f8e4,
++	0xf800f672,
++	0x03640926,
++	0xfa580400,
++	0x0b640382,
++	0x0800084a,
++	0x00f0f942,
++	0x05a80000,
++	0xff10f942,
++	0x0800f7b6,
++	0xf49c0382,
++	0xfa58fc00,
++	0xfc9c0926,
++	0xf800098e,
++	0x0710f8e4,
++	0x05a8fa58,
++	0xf8f0071c,
++	0xf800098e,
++	0x0364f6da,
++	0xfa58fc00,
++	0x0b64fc7e,
++	0x0800f7b6,
++	0x00f006be,
++};
++
++const u32 noise_var_tbl_rev3[] = {
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++};
++
++static const u16 mcs_tbl_rev3[] = {
++	0x0000,
++	0x0008,
++	0x000a,
++	0x0010,
++	0x0012,
++	0x0019,
++	0x001a,
++	0x001c,
++	0x0080,
++	0x0088,
++	0x008a,
++	0x0090,
++	0x0092,
++	0x0099,
++	0x009a,
++	0x009c,
++	0x0100,
++	0x0108,
++	0x010a,
++	0x0110,
++	0x0112,
++	0x0119,
++	0x011a,
++	0x011c,
++	0x0180,
++	0x0188,
++	0x018a,
++	0x0190,
++	0x0192,
++	0x0199,
++	0x019a,
++	0x019c,
++	0x0000,
++	0x0098,
++	0x00a0,
++	0x00a8,
++	0x009a,
++	0x00a2,
++	0x00aa,
++	0x0120,
++	0x0128,
++	0x0128,
++	0x0130,
++	0x0138,
++	0x0138,
++	0x0140,
++	0x0122,
++	0x012a,
++	0x012a,
++	0x0132,
++	0x013a,
++	0x013a,
++	0x0142,
++	0x01a8,
++	0x01b0,
++	0x01b8,
++	0x01b0,
++	0x01b8,
++	0x01c0,
++	0x01c8,
++	0x01c0,
++	0x01c8,
++	0x01d0,
++	0x01d0,
++	0x01d8,
++	0x01aa,
++	0x01b2,
++	0x01ba,
++	0x01b2,
++	0x01ba,
++	0x01c2,
++	0x01ca,
++	0x01c2,
++	0x01ca,
++	0x01d2,
++	0x01d2,
++	0x01da,
++	0x0001,
++	0x0002,
++	0x0004,
++	0x0009,
++	0x000c,
++	0x0011,
++	0x0014,
++	0x0018,
++	0x0020,
++	0x0021,
++	0x0022,
++	0x0024,
++	0x0081,
++	0x0082,
++	0x0084,
++	0x0089,
++	0x008c,
++	0x0091,
++	0x0094,
++	0x0098,
++	0x00a0,
++	0x00a1,
++	0x00a2,
++	0x00a4,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++};
++
++static const u32 tdi_tbl20_ant0_rev3[] = {
++	0x00091226,
++	0x000a1429,
++	0x000b56ad,
++	0x000c58b0,
++	0x000d5ab3,
++	0x000e9cb6,
++	0x000f9eba,
++	0x0000c13d,
++	0x00020301,
++	0x00030504,
++	0x00040708,
++	0x0005090b,
++	0x00064b8e,
++	0x00095291,
++	0x000a5494,
++	0x000b9718,
++	0x000c9927,
++	0x000d9b2a,
++	0x000edd2e,
++	0x000fdf31,
++	0x000101b4,
++	0x000243b7,
++	0x000345bb,
++	0x000447be,
++	0x00058982,
++	0x00068c05,
++	0x00099309,
++	0x000a950c,
++	0x000bd78f,
++	0x000cd992,
++	0x000ddb96,
++	0x000f1d99,
++	0x00005fa8,
++	0x0001422c,
++	0x0002842f,
++	0x00038632,
++	0x00048835,
++	0x0005ca38,
++	0x0006ccbc,
++	0x0009d3bf,
++	0x000b1603,
++	0x000c1806,
++	0x000d1a0a,
++	0x000e1c0d,
++	0x000f5e10,
++	0x00008093,
++	0x00018297,
++	0x0002c49a,
++	0x0003c680,
++	0x0004c880,
++	0x00060b00,
++	0x00070d00,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++};
++
++static const u32 tdi_tbl20_ant1_rev3[] = {
++	0x00014b26,
++	0x00028d29,
++	0x000393ad,
++	0x00049630,
++	0x0005d833,
++	0x0006da36,
++	0x00099c3a,
++	0x000a9e3d,
++	0x000bc081,
++	0x000cc284,
++	0x000dc488,
++	0x000f068b,
++	0x0000488e,
++	0x00018b91,
++	0x0002d214,
++	0x0003d418,
++	0x0004d6a7,
++	0x000618aa,
++	0x00071aae,
++	0x0009dcb1,
++	0x000b1eb4,
++	0x000c0137,
++	0x000d033b,
++	0x000e053e,
++	0x000f4702,
++	0x00008905,
++	0x00020c09,
++	0x0003128c,
++	0x0004148f,
++	0x00051712,
++	0x00065916,
++	0x00091b19,
++	0x000a1d28,
++	0x000b5f2c,
++	0x000c41af,
++	0x000d43b2,
++	0x000e85b5,
++	0x000f87b8,
++	0x0000c9bc,
++	0x00024cbf,
++	0x00035303,
++	0x00045506,
++	0x0005978a,
++	0x0006998d,
++	0x00095b90,
++	0x000a5d93,
++	0x000b9f97,
++	0x000c821a,
++	0x000d8400,
++	0x000ec600,
++	0x000fc800,
++	0x00010a00,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++};
++
++static const u32 tdi_tbl40_ant0_rev3[] = {
++	0x0011a346,
++	0x00136ccf,
++	0x0014f5d9,
++	0x001641e2,
++	0x0017cb6b,
++	0x00195475,
++	0x001b2383,
++	0x001cad0c,
++	0x001e7616,
++	0x0000821f,
++	0x00020ba8,
++	0x0003d4b2,
++	0x00056447,
++	0x00072dd0,
++	0x0008b6da,
++	0x000a02e3,
++	0x000b8c6c,
++	0x000d15f6,
++	0x0011e484,
++	0x0013ae0d,
++	0x00153717,
++	0x00168320,
++	0x00180ca9,
++	0x00199633,
++	0x001b6548,
++	0x001ceed1,
++	0x001eb7db,
++	0x0000c3e4,
++	0x00024d6d,
++	0x000416f7,
++	0x0005a585,
++	0x00076f0f,
++	0x0008f818,
++	0x000a4421,
++	0x000bcdab,
++	0x000d9734,
++	0x00122649,
++	0x0013efd2,
++	0x001578dc,
++	0x0016c4e5,
++	0x00184e6e,
++	0x001a17f8,
++	0x001ba686,
++	0x001d3010,
++	0x001ef999,
++	0x00010522,
++	0x00028eac,
++	0x00045835,
++	0x0005e74a,
++	0x0007b0d3,
++	0x00093a5d,
++	0x000a85e6,
++	0x000c0f6f,
++	0x000dd8f9,
++	0x00126787,
++	0x00143111,
++	0x0015ba9a,
++	0x00170623,
++	0x00188fad,
++	0x001a5936,
++	0x001be84b,
++	0x001db1d4,
++	0x001f3b5e,
++	0x000146e7,
++	0x00031070,
++	0x000499fa,
++	0x00062888,
++	0x0007f212,
++	0x00097b9b,
++	0x000ac7a4,
++	0x000c50ae,
++	0x000e1a37,
++	0x0012a94c,
++	0x001472d5,
++	0x0015fc5f,
++	0x00174868,
++	0x0018d171,
++	0x001a9afb,
++	0x001c2989,
++	0x001df313,
++	0x001f7c9c,
++	0x000188a5,
++	0x000351af,
++	0x0004db38,
++	0x0006aa4d,
++	0x000833d7,
++	0x0009bd60,
++	0x000b0969,
++	0x000c9273,
++	0x000e5bfc,
++	0x00132a8a,
++	0x0014b414,
++	0x00163d9d,
++	0x001789a6,
++	0x001912b0,
++	0x001adc39,
++	0x001c6bce,
++	0x001e34d8,
++	0x001fbe61,
++	0x0001ca6a,
++	0x00039374,
++	0x00051cfd,
++	0x0006ec0b,
++	0x00087515,
++	0x0009fe9e,
++	0x000b4aa7,
++	0x000cd3b1,
++	0x000e9d3a,
++	0x00000000,
++	0x00000000,
++};
++
++static const u32 tdi_tbl40_ant1_rev3[] = {
++	0x001edb36,
++	0x000129ca,
++	0x0002b353,
++	0x00047cdd,
++	0x0005c8e6,
++	0x000791ef,
++	0x00091bf9,
++	0x000aaa07,
++	0x000c3391,
++	0x000dfd1a,
++	0x00120923,
++	0x0013d22d,
++	0x00155c37,
++	0x0016eacb,
++	0x00187454,
++	0x001a3dde,
++	0x001b89e7,
++	0x001d12f0,
++	0x001f1cfa,
++	0x00016b88,
++	0x00033492,
++	0x0004be1b,
++	0x00060a24,
++	0x0007d32e,
++	0x00095d38,
++	0x000aec4c,
++	0x000c7555,
++	0x000e3edf,
++	0x00124ae8,
++	0x001413f1,
++	0x0015a37b,
++	0x00172c89,
++	0x0018b593,
++	0x001a419c,
++	0x001bcb25,
++	0x001d942f,
++	0x001f63b9,
++	0x0001ad4d,
++	0x00037657,
++	0x0004c260,
++	0x00068be9,
++	0x000814f3,
++	0x0009a47c,
++	0x000b2d8a,
++	0x000cb694,
++	0x000e429d,
++	0x00128c26,
++	0x001455b0,
++	0x0015e4ba,
++	0x00176e4e,
++	0x0018f758,
++	0x001a8361,
++	0x001c0cea,
++	0x001dd674,
++	0x001fa57d,
++	0x0001ee8b,
++	0x0003b795,
++	0x0005039e,
++	0x0006cd27,
++	0x000856b1,
++	0x0009e5c6,
++	0x000b6f4f,
++	0x000cf859,
++	0x000e8462,
++	0x00130deb,
++	0x00149775,
++	0x00162603,
++	0x0017af8c,
++	0x00193896,
++	0x001ac49f,
++	0x001c4e28,
++	0x001e17b2,
++	0x0000a6c7,
++	0x00023050,
++	0x0003f9da,
++	0x00054563,
++	0x00070eec,
++	0x00089876,
++	0x000a2704,
++	0x000bb08d,
++	0x000d3a17,
++	0x001185a0,
++	0x00134f29,
++	0x0014d8b3,
++	0x001667c8,
++	0x0017f151,
++	0x00197adb,
++	0x001b0664,
++	0x001c8fed,
++	0x001e5977,
++	0x0000e805,
++	0x0002718f,
++	0x00043b18,
++	0x000586a1,
++	0x0007502b,
++	0x0008d9b4,
++	0x000a68c9,
++	0x000bf252,
++	0x000dbbdc,
++	0x0011c7e5,
++	0x001390ee,
++	0x00151a78,
++	0x0016a906,
++	0x00183290,
++	0x0019bc19,
++	0x001b4822,
++	0x001cd12c,
++	0x001e9ab5,
++	0x00000000,
++	0x00000000,
++};
++
++static const u32 pltlut_tbl_rev3[] = {
++	0x76540213,
++	0x62407351,
++	0x76543210,
++	0x76540213,
++	0x76540213,
++	0x76430521,
++};
++
++static const u32 chanest_tbl_rev3[] = {
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++};
++
++static const u8 frame_lut_rev3[] = {
++	0x02,
++	0x04,
++	0x14,
++	0x14,
++	0x03,
++	0x05,
++	0x16,
++	0x16,
++	0x0a,
++	0x0c,
++	0x1c,
++	0x1c,
++	0x0b,
++	0x0d,
++	0x1e,
++	0x1e,
++	0x06,
++	0x08,
++	0x18,
++	0x18,
++	0x07,
++	0x09,
++	0x1a,
++	0x1a,
++	0x0e,
++	0x10,
++	0x20,
++	0x28,
++	0x0f,
++	0x11,
++	0x22,
++	0x2a,
++};
++
++static const u8 est_pwr_lut_core0_rev3[] = {
++	0x55,
++	0x54,
++	0x54,
++	0x53,
++	0x52,
++	0x52,
++	0x51,
++	0x51,
++	0x50,
++	0x4f,
++	0x4f,
++	0x4e,
++	0x4e,
++	0x4d,
++	0x4c,
++	0x4c,
++	0x4b,
++	0x4a,
++	0x49,
++	0x49,
++	0x48,
++	0x47,
++	0x46,
++	0x46,
++	0x45,
++	0x44,
++	0x43,
++	0x42,
++	0x41,
++	0x40,
++	0x40,
++	0x3f,
++	0x3e,
++	0x3d,
++	0x3c,
++	0x3a,
++	0x39,
++	0x38,
++	0x37,
++	0x36,
++	0x35,
++	0x33,
++	0x32,
++	0x31,
++	0x2f,
++	0x2e,
++	0x2c,
++	0x2b,
++	0x29,
++	0x27,
++	0x25,
++	0x23,
++	0x21,
++	0x1f,
++	0x1d,
++	0x1a,
++	0x18,
++	0x15,
++	0x12,
++	0x0e,
++	0x0b,
++	0x07,
++	0x02,
++	0xfd,
++};
++
++static const u8 est_pwr_lut_core1_rev3[] = {
++	0x55,
++	0x54,
++	0x54,
++	0x53,
++	0x52,
++	0x52,
++	0x51,
++	0x51,
++	0x50,
++	0x4f,
++	0x4f,
++	0x4e,
++	0x4e,
++	0x4d,
++	0x4c,
++	0x4c,
++	0x4b,
++	0x4a,
++	0x49,
++	0x49,
++	0x48,
++	0x47,
++	0x46,
++	0x46,
++	0x45,
++	0x44,
++	0x43,
++	0x42,
++	0x41,
++	0x40,
++	0x40,
++	0x3f,
++	0x3e,
++	0x3d,
++	0x3c,
++	0x3a,
++	0x39,
++	0x38,
++	0x37,
++	0x36,
++	0x35,
++	0x33,
++	0x32,
++	0x31,
++	0x2f,
++	0x2e,
++	0x2c,
++	0x2b,
++	0x29,
++	0x27,
++	0x25,
++	0x23,
++	0x21,
++	0x1f,
++	0x1d,
++	0x1a,
++	0x18,
++	0x15,
++	0x12,
++	0x0e,
++	0x0b,
++	0x07,
++	0x02,
++	0xfd,
++};
++
++static const u8 adj_pwr_lut_core0_rev3[] = {
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++};
++
++static const u8 adj_pwr_lut_core1_rev3[] = {
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++};
++
++static const u32 gainctrl_lut_core0_rev3[] = {
++	0x5bf70044,
++	0x5bf70042,
++	0x5bf70040,
++	0x5bf7003e,
++	0x5bf7003c,
++	0x5bf7003b,
++	0x5bf70039,
++	0x5bf70037,
++	0x5bf70036,
++	0x5bf70034,
++	0x5bf70033,
++	0x5bf70031,
++	0x5bf70030,
++	0x5ba70044,
++	0x5ba70042,
++	0x5ba70040,
++	0x5ba7003e,
++	0x5ba7003c,
++	0x5ba7003b,
++	0x5ba70039,
++	0x5ba70037,
++	0x5ba70036,
++	0x5ba70034,
++	0x5ba70033,
++	0x5b770044,
++	0x5b770042,
++	0x5b770040,
++	0x5b77003e,
++	0x5b77003c,
++	0x5b77003b,
++	0x5b770039,
++	0x5b770037,
++	0x5b770036,
++	0x5b770034,
++	0x5b770033,
++	0x5b770031,
++	0x5b770030,
++	0x5b77002f,
++	0x5b77002d,
++	0x5b77002c,
++	0x5b470044,
++	0x5b470042,
++	0x5b470040,
++	0x5b47003e,
++	0x5b47003c,
++	0x5b47003b,
++	0x5b470039,
++	0x5b470037,
++	0x5b470036,
++	0x5b470034,
++	0x5b470033,
++	0x5b470031,
++	0x5b470030,
++	0x5b47002f,
++	0x5b47002d,
++	0x5b47002c,
++	0x5b47002b,
++	0x5b47002a,
++	0x5b270044,
++	0x5b270042,
++	0x5b270040,
++	0x5b27003e,
++	0x5b27003c,
++	0x5b27003b,
++	0x5b270039,
++	0x5b270037,
++	0x5b270036,
++	0x5b270034,
++	0x5b270033,
++	0x5b270031,
++	0x5b270030,
++	0x5b27002f,
++	0x5b170044,
++	0x5b170042,
++	0x5b170040,
++	0x5b17003e,
++	0x5b17003c,
++	0x5b17003b,
++	0x5b170039,
++	0x5b170037,
++	0x5b170036,
++	0x5b170034,
++	0x5b170033,
++	0x5b170031,
++	0x5b170030,
++	0x5b17002f,
++	0x5b17002d,
++	0x5b17002c,
++	0x5b17002b,
++	0x5b17002a,
++	0x5b170028,
++	0x5b170027,
++	0x5b170026,
++	0x5b170025,
++	0x5b170024,
++	0x5b170023,
++	0x5b070044,
++	0x5b070042,
++	0x5b070040,
++	0x5b07003e,
++	0x5b07003c,
++	0x5b07003b,
++	0x5b070039,
++	0x5b070037,
++	0x5b070036,
++	0x5b070034,
++	0x5b070033,
++	0x5b070031,
++	0x5b070030,
++	0x5b07002f,
++	0x5b07002d,
++	0x5b07002c,
++	0x5b07002b,
++	0x5b07002a,
++	0x5b070028,
++	0x5b070027,
++	0x5b070026,
++	0x5b070025,
++	0x5b070024,
++	0x5b070023,
++	0x5b070022,
++	0x5b070021,
++	0x5b070020,
++	0x5b07001f,
++	0x5b07001e,
++	0x5b07001d,
++	0x5b07001d,
++	0x5b07001c,
++};
++
++static const u32 gainctrl_lut_core1_rev3[] = {
++	0x5bf70044,
++	0x5bf70042,
++	0x5bf70040,
++	0x5bf7003e,
++	0x5bf7003c,
++	0x5bf7003b,
++	0x5bf70039,
++	0x5bf70037,
++	0x5bf70036,
++	0x5bf70034,
++	0x5bf70033,
++	0x5bf70031,
++	0x5bf70030,
++	0x5ba70044,
++	0x5ba70042,
++	0x5ba70040,
++	0x5ba7003e,
++	0x5ba7003c,
++	0x5ba7003b,
++	0x5ba70039,
++	0x5ba70037,
++	0x5ba70036,
++	0x5ba70034,
++	0x5ba70033,
++	0x5b770044,
++	0x5b770042,
++	0x5b770040,
++	0x5b77003e,
++	0x5b77003c,
++	0x5b77003b,
++	0x5b770039,
++	0x5b770037,
++	0x5b770036,
++	0x5b770034,
++	0x5b770033,
++	0x5b770031,
++	0x5b770030,
++	0x5b77002f,
++	0x5b77002d,
++	0x5b77002c,
++	0x5b470044,
++	0x5b470042,
++	0x5b470040,
++	0x5b47003e,
++	0x5b47003c,
++	0x5b47003b,
++	0x5b470039,
++	0x5b470037,
++	0x5b470036,
++	0x5b470034,
++	0x5b470033,
++	0x5b470031,
++	0x5b470030,
++	0x5b47002f,
++	0x5b47002d,
++	0x5b47002c,
++	0x5b47002b,
++	0x5b47002a,
++	0x5b270044,
++	0x5b270042,
++	0x5b270040,
++	0x5b27003e,
++	0x5b27003c,
++	0x5b27003b,
++	0x5b270039,
++	0x5b270037,
++	0x5b270036,
++	0x5b270034,
++	0x5b270033,
++	0x5b270031,
++	0x5b270030,
++	0x5b27002f,
++	0x5b170044,
++	0x5b170042,
++	0x5b170040,
++	0x5b17003e,
++	0x5b17003c,
++	0x5b17003b,
++	0x5b170039,
++	0x5b170037,
++	0x5b170036,
++	0x5b170034,
++	0x5b170033,
++	0x5b170031,
++	0x5b170030,
++	0x5b17002f,
++	0x5b17002d,
++	0x5b17002c,
++	0x5b17002b,
++	0x5b17002a,
++	0x5b170028,
++	0x5b170027,
++	0x5b170026,
++	0x5b170025,
++	0x5b170024,
++	0x5b170023,
++	0x5b070044,
++	0x5b070042,
++	0x5b070040,
++	0x5b07003e,
++	0x5b07003c,
++	0x5b07003b,
++	0x5b070039,
++	0x5b070037,
++	0x5b070036,
++	0x5b070034,
++	0x5b070033,
++	0x5b070031,
++	0x5b070030,
++	0x5b07002f,
++	0x5b07002d,
++	0x5b07002c,
++	0x5b07002b,
++	0x5b07002a,
++	0x5b070028,
++	0x5b070027,
++	0x5b070026,
++	0x5b070025,
++	0x5b070024,
++	0x5b070023,
++	0x5b070022,
++	0x5b070021,
++	0x5b070020,
++	0x5b07001f,
++	0x5b07001e,
++	0x5b07001d,
++	0x5b07001d,
++	0x5b07001c,
++};
++
++static const u32 iq_lut_core0_rev3[] = {
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++};
++
++static const u32 iq_lut_core1_rev3[] = {
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++};
++
++static const u16 loft_lut_core0_rev3[] = {
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++};
++
++static const u16 loft_lut_core1_rev3[] = {
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++};
++
++static const u16 papd_comp_rfpwr_tbl_core0_rev3[] = {
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x002a,
++	0x002a,
++	0x002a,
++	0x002a,
++	0x002a,
++	0x002a,
++	0x002a,
++	0x002a,
++	0x002a,
++	0x002a,
++	0x002a,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++};
++
++static const u16 papd_comp_rfpwr_tbl_core1_rev3[] = {
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x002a,
++	0x002a,
++	0x002a,
++	0x002a,
++	0x002a,
++	0x002a,
++	0x002a,
++	0x002a,
++	0x002a,
++	0x002a,
++	0x002a,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++};
++
++static const u32 papd_comp_epsilon_tbl_core0_rev3[] = {
++	0x00000000,
++	0x00001fa0,
++	0x00019f78,
++	0x0001df7e,
++	0x03fa9f86,
++	0x03fd1f90,
++	0x03fe5f8a,
++	0x03fb1f94,
++	0x03fd9fa0,
++	0x00009f98,
++	0x03fd1fac,
++	0x03ff9fa2,
++	0x03fe9fae,
++	0x00001fae,
++	0x03fddfb4,
++	0x03ff1fb8,
++	0x03ff9fbc,
++	0x03ffdfbe,
++	0x03fe9fc2,
++	0x03fedfc6,
++	0x03fedfc6,
++	0x03ff9fc8,
++	0x03ff5fc6,
++	0x03fedfc2,
++	0x03ff9fc0,
++	0x03ff5fac,
++	0x03ff5fac,
++	0x03ff9fa2,
++	0x03ff9fa6,
++	0x03ff9faa,
++	0x03ff5fb0,
++	0x03ff5fb4,
++	0x03ff1fca,
++	0x03ff5fce,
++	0x03fcdfdc,
++	0x03fb4006,
++	0x00000030,
++	0x03ff808a,
++	0x03ff80da,
++	0x0000016c,
++	0x03ff8318,
++	0x03ff063a,
++	0x03fd8bd6,
++	0x00014ffe,
++	0x00034ffe,
++	0x00034ffe,
++	0x0003cffe,
++	0x00040ffe,
++	0x00040ffe,
++	0x0003cffe,
++	0x0003cffe,
++	0x00020ffe,
++	0x03fe0ffe,
++	0x03fdcffe,
++	0x03f94ffe,
++	0x03f54ffe,
++	0x03f44ffe,
++	0x03ef8ffe,
++	0x03ee0ffe,
++	0x03ebcffe,
++	0x03e8cffe,
++	0x03e74ffe,
++	0x03e4cffe,
++	0x03e38ffe,
++};
++
++static const u32 papd_cal_scalars_tbl_core0_rev3[] = {
++	0x05af005a,
++	0x0571005e,
++	0x05040066,
++	0x04bd006c,
++	0x047d0072,
++	0x04430078,
++	0x03f70081,
++	0x03cb0087,
++	0x03870091,
++	0x035e0098,
++	0x032e00a1,
++	0x030300aa,
++	0x02d800b4,
++	0x02ae00bf,
++	0x028900ca,
++	0x026400d6,
++	0x024100e3,
++	0x022200f0,
++	0x020200ff,
++	0x01e5010e,
++	0x01ca011e,
++	0x01b0012f,
++	0x01990140,
++	0x01830153,
++	0x016c0168,
++	0x0158017d,
++	0x01450193,
++	0x013301ab,
++	0x012101c5,
++	0x011101e0,
++	0x010201fc,
++	0x00f4021a,
++	0x00e6011d,
++	0x00d9012e,
++	0x00cd0140,
++	0x00c20153,
++	0x00b70167,
++	0x00ac017c,
++	0x00a30193,
++	0x009a01ab,
++	0x009101c4,
++	0x008901df,
++	0x008101fb,
++	0x007a0219,
++	0x00730239,
++	0x006d025b,
++	0x0067027e,
++	0x006102a4,
++	0x005c02cc,
++	0x005602f6,
++	0x00520323,
++	0x004d0353,
++	0x00490385,
++	0x004503bb,
++	0x004103f3,
++	0x003d042f,
++	0x003a046f,
++	0x003704b2,
++	0x003404f9,
++	0x00310545,
++	0x002e0596,
++	0x002b05f5,
++	0x00290640,
++	0x002606a4,
++};
++
++static const u32 papd_comp_epsilon_tbl_core1_rev3[] = {
++	0x00000000,
++	0x00001fa0,
++	0x00019f78,
++	0x0001df7e,
++	0x03fa9f86,
++	0x03fd1f90,
++	0x03fe5f8a,
++	0x03fb1f94,
++	0x03fd9fa0,
++	0x00009f98,
++	0x03fd1fac,
++	0x03ff9fa2,
++	0x03fe9fae,
++	0x00001fae,
++	0x03fddfb4,
++	0x03ff1fb8,
++	0x03ff9fbc,
++	0x03ffdfbe,
++	0x03fe9fc2,
++	0x03fedfc6,
++	0x03fedfc6,
++	0x03ff9fc8,
++	0x03ff5fc6,
++	0x03fedfc2,
++	0x03ff9fc0,
++	0x03ff5fac,
++	0x03ff5fac,
++	0x03ff9fa2,
++	0x03ff9fa6,
++	0x03ff9faa,
++	0x03ff5fb0,
++	0x03ff5fb4,
++	0x03ff1fca,
++	0x03ff5fce,
++	0x03fcdfdc,
++	0x03fb4006,
++	0x00000030,
++	0x03ff808a,
++	0x03ff80da,
++	0x0000016c,
++	0x03ff8318,
++	0x03ff063a,
++	0x03fd8bd6,
++	0x00014ffe,
++	0x00034ffe,
++	0x00034ffe,
++	0x0003cffe,
++	0x00040ffe,
++	0x00040ffe,
++	0x0003cffe,
++	0x0003cffe,
++	0x00020ffe,
++	0x03fe0ffe,
++	0x03fdcffe,
++	0x03f94ffe,
++	0x03f54ffe,
++	0x03f44ffe,
++	0x03ef8ffe,
++	0x03ee0ffe,
++	0x03ebcffe,
++	0x03e8cffe,
++	0x03e74ffe,
++	0x03e4cffe,
++	0x03e38ffe,
++};
++
++static const u32 papd_cal_scalars_tbl_core1_rev3[] = {
++	0x05af005a,
++	0x0571005e,
++	0x05040066,
++	0x04bd006c,
++	0x047d0072,
++	0x04430078,
++	0x03f70081,
++	0x03cb0087,
++	0x03870091,
++	0x035e0098,
++	0x032e00a1,
++	0x030300aa,
++	0x02d800b4,
++	0x02ae00bf,
++	0x028900ca,
++	0x026400d6,
++	0x024100e3,
++	0x022200f0,
++	0x020200ff,
++	0x01e5010e,
++	0x01ca011e,
++	0x01b0012f,
++	0x01990140,
++	0x01830153,
++	0x016c0168,
++	0x0158017d,
++	0x01450193,
++	0x013301ab,
++	0x012101c5,
++	0x011101e0,
++	0x010201fc,
++	0x00f4021a,
++	0x00e6011d,
++	0x00d9012e,
++	0x00cd0140,
++	0x00c20153,
++	0x00b70167,
++	0x00ac017c,
++	0x00a30193,
++	0x009a01ab,
++	0x009101c4,
++	0x008901df,
++	0x008101fb,
++	0x007a0219,
++	0x00730239,
++	0x006d025b,
++	0x0067027e,
++	0x006102a4,
++	0x005c02cc,
++	0x005602f6,
++	0x00520323,
++	0x004d0353,
++	0x00490385,
++	0x004503bb,
++	0x004103f3,
++	0x003d042f,
++	0x003a046f,
++	0x003704b2,
++	0x003404f9,
++	0x00310545,
++	0x002e0596,
++	0x002b05f5,
++	0x00290640,
++	0x002606a4,
++};
++
++const struct phytbl_info mimophytbl_info_rev3_volatile[] = {
++	{&ant_swctrl_tbl_rev3,
++	 sizeof(ant_swctrl_tbl_rev3) / sizeof(ant_swctrl_tbl_rev3[0]), 9, 0, 16}
++	,
++};
++
++const struct phytbl_info mimophytbl_info_rev3_volatile1[] = {
++	{&ant_swctrl_tbl_rev3_1,
++	 sizeof(ant_swctrl_tbl_rev3_1) / sizeof(ant_swctrl_tbl_rev3_1[0]), 9, 0,
++	 16}
++	,
++};
++
++const struct phytbl_info mimophytbl_info_rev3_volatile2[] = {
++	{&ant_swctrl_tbl_rev3_2,
++	 sizeof(ant_swctrl_tbl_rev3_2) / sizeof(ant_swctrl_tbl_rev3_2[0]), 9, 0,
++	 16}
++	,
++};
++
++const struct phytbl_info mimophytbl_info_rev3_volatile3[] = {
++	{&ant_swctrl_tbl_rev3_3,
++	 sizeof(ant_swctrl_tbl_rev3_3) / sizeof(ant_swctrl_tbl_rev3_3[0]), 9, 0,
++	 16}
++	,
++};
++
++const struct phytbl_info mimophytbl_info_rev3[] = {
++	{&frame_struct_rev3,
++	 sizeof(frame_struct_rev3) / sizeof(frame_struct_rev3[0]), 10, 0, 32}
++	,
++	{&pilot_tbl_rev3, sizeof(pilot_tbl_rev3) / sizeof(pilot_tbl_rev3[0]),
++	 11, 0, 16}
++	,
++	{&tmap_tbl_rev3, sizeof(tmap_tbl_rev3) / sizeof(tmap_tbl_rev3[0]), 12,
++	 0, 32}
++	,
++	{&intlv_tbl_rev3, sizeof(intlv_tbl_rev3) / sizeof(intlv_tbl_rev3[0]),
++	 13, 0, 32}
++	,
++	{&tdtrn_tbl_rev3, sizeof(tdtrn_tbl_rev3) / sizeof(tdtrn_tbl_rev3[0]),
++	 14, 0, 32}
++	,
++	{&noise_var_tbl_rev3,
++	 sizeof(noise_var_tbl_rev3) / sizeof(noise_var_tbl_rev3[0]), 16, 0, 32}
++	,
++	{&mcs_tbl_rev3, sizeof(mcs_tbl_rev3) / sizeof(mcs_tbl_rev3[0]), 18, 0,
++	 16}
++	,
++	{&tdi_tbl20_ant0_rev3,
++	 sizeof(tdi_tbl20_ant0_rev3) / sizeof(tdi_tbl20_ant0_rev3[0]), 19, 128,
++	 32}
++	,
++	{&tdi_tbl20_ant1_rev3,
++	 sizeof(tdi_tbl20_ant1_rev3) / sizeof(tdi_tbl20_ant1_rev3[0]), 19, 256,
++	 32}
++	,
++	{&tdi_tbl40_ant0_rev3,
++	 sizeof(tdi_tbl40_ant0_rev3) / sizeof(tdi_tbl40_ant0_rev3[0]), 19, 640,
++	 32}
++	,
++	{&tdi_tbl40_ant1_rev3,
++	 sizeof(tdi_tbl40_ant1_rev3) / sizeof(tdi_tbl40_ant1_rev3[0]), 19, 768,
++	 32}
++	,
++	{&pltlut_tbl_rev3, sizeof(pltlut_tbl_rev3) / sizeof(pltlut_tbl_rev3[0]),
++	 20, 0, 32}
++	,
++	{&chanest_tbl_rev3,
++	 sizeof(chanest_tbl_rev3) / sizeof(chanest_tbl_rev3[0]), 22, 0, 32}
++	,
++	{&frame_lut_rev3, sizeof(frame_lut_rev3) / sizeof(frame_lut_rev3[0]),
++	 24, 0, 8}
++	,
++	{&est_pwr_lut_core0_rev3,
++	 sizeof(est_pwr_lut_core0_rev3) / sizeof(est_pwr_lut_core0_rev3[0]), 26,
++	 0, 8}
++	,
++	{&est_pwr_lut_core1_rev3,
++	 sizeof(est_pwr_lut_core1_rev3) / sizeof(est_pwr_lut_core1_rev3[0]), 27,
++	 0, 8}
++	,
++	{&adj_pwr_lut_core0_rev3,
++	 sizeof(adj_pwr_lut_core0_rev3) / sizeof(adj_pwr_lut_core0_rev3[0]), 26,
++	 64, 8}
++	,
++	{&adj_pwr_lut_core1_rev3,
++	 sizeof(adj_pwr_lut_core1_rev3) / sizeof(adj_pwr_lut_core1_rev3[0]), 27,
++	 64, 8}
++	,
++	{&gainctrl_lut_core0_rev3,
++	 sizeof(gainctrl_lut_core0_rev3) / sizeof(gainctrl_lut_core0_rev3[0]),
++	 26, 192, 32}
++	,
++	{&gainctrl_lut_core1_rev3,
++	 sizeof(gainctrl_lut_core1_rev3) / sizeof(gainctrl_lut_core1_rev3[0]),
++	 27, 192, 32}
++	,
++	{&iq_lut_core0_rev3,
++	 sizeof(iq_lut_core0_rev3) / sizeof(iq_lut_core0_rev3[0]), 26, 320, 32}
++	,
++	{&iq_lut_core1_rev3,
++	 sizeof(iq_lut_core1_rev3) / sizeof(iq_lut_core1_rev3[0]), 27, 320, 32}
++	,
++	{&loft_lut_core0_rev3,
++	 sizeof(loft_lut_core0_rev3) / sizeof(loft_lut_core0_rev3[0]), 26, 448,
++	 16}
++	,
++	{&loft_lut_core1_rev3,
++	 sizeof(loft_lut_core1_rev3) / sizeof(loft_lut_core1_rev3[0]), 27, 448,
++	 16}
++};
++
++const u32 mimophytbl_info_sz_rev3 =
++	sizeof(mimophytbl_info_rev3) / sizeof(mimophytbl_info_rev3[0]);
++const u32 mimophytbl_info_sz_rev3_volatile =
++	sizeof(mimophytbl_info_rev3_volatile) /
++	sizeof(mimophytbl_info_rev3_volatile[0]);
++const u32 mimophytbl_info_sz_rev3_volatile1 =
++	sizeof(mimophytbl_info_rev3_volatile1) /
++	sizeof(mimophytbl_info_rev3_volatile1[0]);
++const u32 mimophytbl_info_sz_rev3_volatile2 =
++	sizeof(mimophytbl_info_rev3_volatile2) /
++	sizeof(mimophytbl_info_rev3_volatile2[0]);
++const u32 mimophytbl_info_sz_rev3_volatile3 =
++	sizeof(mimophytbl_info_rev3_volatile3) /
++	sizeof(mimophytbl_info_rev3_volatile3[0]);
++
++static const u32 tmap_tbl_rev7[] = {
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0xf1111110,
++	0x11111111,
++	0x11f11111,
++	0x00000111,
++	0x11000000,
++	0x1111f111,
++	0x11111111,
++	0x111111f1,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x000aa888,
++	0x88880000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0xa1111110,
++	0x11111111,
++	0x11c11111,
++	0x00000111,
++	0x11000000,
++	0x1111a111,
++	0x11111111,
++	0x111111a1,
++	0xa2222220,
++	0x22222222,
++	0x22c22222,
++	0x00000222,
++	0x22000000,
++	0x2222a222,
++	0x22222222,
++	0x222222a2,
++	0xf1111110,
++	0x11111111,
++	0x11f11111,
++	0x00011111,
++	0x11110000,
++	0x1111f111,
++	0x11111111,
++	0x111111f1,
++	0xa8aa88a0,
++	0xa88888a8,
++	0xa8a8a88a,
++	0x00088aaa,
++	0xaaaa0000,
++	0xa8a8aa88,
++	0xa88aaaaa,
++	0xaaaa8a8a,
++	0xaaa8aaa0,
++	0x8aaa8aaa,
++	0xaa8a8a8a,
++	0x000aaa88,
++	0x8aaa0000,
++	0xaaa8a888,
++	0x8aa88a8a,
++	0x8a88a888,
++	0x08080a00,
++	0x0a08080a,
++	0x080a0a08,
++	0x00080808,
++	0x080a0000,
++	0x080a0808,
++	0x080a0808,
++	0x0a0a0a08,
++	0xa0a0a0a0,
++	0x80a0a080,
++	0x8080a0a0,
++	0x00008080,
++	0x80a00000,
++	0x80a080a0,
++	0xa080a0a0,
++	0x8080a0a0,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x99999000,
++	0x9b9b99bb,
++	0x9bb99999,
++	0x9999b9b9,
++	0x9b99bb90,
++	0x9bbbbb9b,
++	0x9b9b9bb9,
++	0x00000999,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00aaa888,
++	0x22000000,
++	0x2222b222,
++	0x22222222,
++	0x222222b2,
++	0xb2222220,
++	0x22222222,
++	0x22d22222,
++	0x00000222,
++	0x11000000,
++	0x1111a111,
++	0x11111111,
++	0x111111a1,
++	0xa1111110,
++	0x11111111,
++	0x11c11111,
++	0x00000111,
++	0x33000000,
++	0x3333b333,
++	0x33333333,
++	0x333333b3,
++	0xb3333330,
++	0x33333333,
++	0x33d33333,
++	0x00000333,
++	0x22000000,
++	0x2222a222,
++	0x22222222,
++	0x222222a2,
++	0xa2222220,
++	0x22222222,
++	0x22c22222,
++	0x00000222,
++	0x99b99b00,
++	0x9b9b99bb,
++	0x9bb99999,
++	0x9999b9b9,
++	0x9b99bb99,
++	0x9bbbbb9b,
++	0x9b9b9bb9,
++	0x00000999,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa88,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x08aaa888,
++	0x22222200,
++	0x2222f222,
++	0x22222222,
++	0x222222f2,
++	0x22222222,
++	0x22222222,
++	0x22f22222,
++	0x00000222,
++	0x11000000,
++	0x1111f111,
++	0x11111111,
++	0x11111111,
++	0xf1111111,
++	0x11111111,
++	0x11f11111,
++	0x01111111,
++	0xbb9bb900,
++	0xb9b9bb99,
++	0xb99bbbbb,
++	0xbbbb9b9b,
++	0xb9bb99bb,
++	0xb99999b9,
++	0xb9b9b99b,
++	0x00000bbb,
++	0xaa000000,
++	0xa8a8aa88,
++	0xa88aaaaa,
++	0xaaaa8a8a,
++	0xa8aa88aa,
++	0xa88888a8,
++	0xa8a8a88a,
++	0x0a888aaa,
++	0xaa000000,
++	0xa8a8aa88,
++	0xa88aaaaa,
++	0xaaaa8a8a,
++	0xa8aa88a0,
++	0xa88888a8,
++	0xa8a8a88a,
++	0x00000aaa,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0xbbbbbb00,
++	0x999bbbbb,
++	0x9bb99b9b,
++	0xb9b9b9bb,
++	0xb9b99bbb,
++	0xb9b9b9bb,
++	0xb9bb9b99,
++	0x00000999,
++	0x8a000000,
++	0xaa88a888,
++	0xa88888aa,
++	0xa88a8a88,
++	0xa88aa88a,
++	0x88a8aaaa,
++	0xa8aa8aaa,
++	0x0888a88a,
++	0x0b0b0b00,
++	0x090b0b0b,
++	0x0b090b0b,
++	0x0909090b,
++	0x09090b0b,
++	0x09090b0b,
++	0x09090b09,
++	0x00000909,
++	0x0a000000,
++	0x0a080808,
++	0x080a080a,
++	0x080a0a08,
++	0x080a080a,
++	0x0808080a,
++	0x0a0a0a08,
++	0x0808080a,
++	0xb0b0b000,
++	0x9090b0b0,
++	0x90b09090,
++	0xb0b0b090,
++	0xb0b090b0,
++	0x90b0b0b0,
++	0xb0b09090,
++	0x00000090,
++	0x80000000,
++	0xa080a080,
++	0xa08080a0,
++	0xa0808080,
++	0xa080a080,
++	0x80a0a0a0,
++	0xa0a080a0,
++	0x00a0a0a0,
++	0x22000000,
++	0x2222f222,
++	0x22222222,
++	0x222222f2,
++	0xf2222220,
++	0x22222222,
++	0x22f22222,
++	0x00000222,
++	0x11000000,
++	0x1111f111,
++	0x11111111,
++	0x111111f1,
++	0xf1111110,
++	0x11111111,
++	0x11f11111,
++	0x00000111,
++	0x33000000,
++	0x3333f333,
++	0x33333333,
++	0x333333f3,
++	0xf3333330,
++	0x33333333,
++	0x33f33333,
++	0x00000333,
++	0x22000000,
++	0x2222f222,
++	0x22222222,
++	0x222222f2,
++	0xf2222220,
++	0x22222222,
++	0x22f22222,
++	0x00000222,
++	0x99000000,
++	0x9b9b99bb,
++	0x9bb99999,
++	0x9999b9b9,
++	0x9b99bb90,
++	0x9bbbbb9b,
++	0x9b9b9bb9,
++	0x00000999,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0x88888000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00aaa888,
++	0x88a88a00,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa88,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x000aa888,
++	0x88880000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa88,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x08aaa888,
++	0x11000000,
++	0x1111a111,
++	0x11111111,
++	0x111111a1,
++	0xa1111110,
++	0x11111111,
++	0x11c11111,
++	0x00000111,
++	0x11000000,
++	0x1111a111,
++	0x11111111,
++	0x111111a1,
++	0xa1111110,
++	0x11111111,
++	0x11c11111,
++	0x00000111,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++};
++
++const u32 noise_var_tbl_rev7[] = {
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++};
++
++static const u32 papd_comp_epsilon_tbl_core0_rev7[] = {
++	0x00000000,
++	0x00000000,
++	0x00016023,
++	0x00006028,
++	0x00034036,
++	0x0003402e,
++	0x0007203c,
++	0x0006e037,
++	0x00070030,
++	0x0009401f,
++	0x0009a00f,
++	0x000b600d,
++	0x000c8007,
++	0x000ce007,
++	0x00101fff,
++	0x00121ff9,
++	0x0012e004,
++	0x0014dffc,
++	0x0016dff6,
++	0x0018dfe9,
++	0x001b3fe5,
++	0x001c5fd0,
++	0x001ddfc2,
++	0x001f1fb6,
++	0x00207fa4,
++	0x00219f8f,
++	0x0022ff7d,
++	0x00247f6c,
++	0x0024df5b,
++	0x00267f4b,
++	0x0027df3b,
++	0x0029bf3b,
++	0x002b5f2f,
++	0x002d3f2e,
++	0x002f5f2a,
++	0x002fff15,
++	0x00315f0b,
++	0x0032defa,
++	0x0033beeb,
++	0x0034fed9,
++	0x00353ec5,
++	0x00361eb0,
++	0x00363e9b,
++	0x0036be87,
++	0x0036be70,
++	0x0038fe67,
++	0x0044beb2,
++	0x00513ef3,
++	0x00595f11,
++	0x00669f3d,
++	0x0078dfdf,
++	0x00a143aa,
++	0x01642fff,
++	0x0162afff,
++	0x01620fff,
++	0x0160cfff,
++	0x015f0fff,
++	0x015dafff,
++	0x015bcfff,
++	0x015bcfff,
++	0x015b4fff,
++	0x015acfff,
++	0x01590fff,
++	0x0156cfff,
++};
++
++static const u32 papd_cal_scalars_tbl_core0_rev7[] = {
++	0x0b5e002d,
++	0x0ae2002f,
++	0x0a3b0032,
++	0x09a70035,
++	0x09220038,
++	0x08ab003b,
++	0x081f003f,
++	0x07a20043,
++	0x07340047,
++	0x06d2004b,
++	0x067a004f,
++	0x06170054,
++	0x05bf0059,
++	0x0571005e,
++	0x051e0064,
++	0x04d3006a,
++	0x04910070,
++	0x044c0077,
++	0x040f007e,
++	0x03d90085,
++	0x03a1008d,
++	0x036f0095,
++	0x033d009e,
++	0x030b00a8,
++	0x02e000b2,
++	0x02b900bc,
++	0x029200c7,
++	0x026d00d3,
++	0x024900e0,
++	0x022900ed,
++	0x020a00fb,
++	0x01ec010a,
++	0x01d20119,
++	0x01b7012a,
++	0x019e013c,
++	0x0188014e,
++	0x01720162,
++	0x015d0177,
++	0x0149018e,
++	0x013701a5,
++	0x012601be,
++	0x011501d8,
++	0x010601f4,
++	0x00f70212,
++	0x00e90231,
++	0x00dc0253,
++	0x00d00276,
++	0x00c4029b,
++	0x00b902c3,
++	0x00af02ed,
++	0x00a50319,
++	0x009c0348,
++	0x0093037a,
++	0x008b03af,
++	0x008303e6,
++	0x007c0422,
++	0x00750460,
++	0x006e04a3,
++	0x006804e9,
++	0x00620533,
++	0x005d0582,
++	0x005805d6,
++	0x0053062e,
++	0x004e068c,
++};
++
++static const u32 papd_comp_epsilon_tbl_core1_rev7[] = {
++	0x00000000,
++	0x00000000,
++	0x00016023,
++	0x00006028,
++	0x00034036,
++	0x0003402e,
++	0x0007203c,
++	0x0006e037,
++	0x00070030,
++	0x0009401f,
++	0x0009a00f,
++	0x000b600d,
++	0x000c8007,
++	0x000ce007,
++	0x00101fff,
++	0x00121ff9,
++	0x0012e004,
++	0x0014dffc,
++	0x0016dff6,
++	0x0018dfe9,
++	0x001b3fe5,
++	0x001c5fd0,
++	0x001ddfc2,
++	0x001f1fb6,
++	0x00207fa4,
++	0x00219f8f,
++	0x0022ff7d,
++	0x00247f6c,
++	0x0024df5b,
++	0x00267f4b,
++	0x0027df3b,
++	0x0029bf3b,
++	0x002b5f2f,
++	0x002d3f2e,
++	0x002f5f2a,
++	0x002fff15,
++	0x00315f0b,
++	0x0032defa,
++	0x0033beeb,
++	0x0034fed9,
++	0x00353ec5,
++	0x00361eb0,
++	0x00363e9b,
++	0x0036be87,
++	0x0036be70,
++	0x0038fe67,
++	0x0044beb2,
++	0x00513ef3,
++	0x00595f11,
++	0x00669f3d,
++	0x0078dfdf,
++	0x00a143aa,
++	0x01642fff,
++	0x0162afff,
++	0x01620fff,
++	0x0160cfff,
++	0x015f0fff,
++	0x015dafff,
++	0x015bcfff,
++	0x015bcfff,
++	0x015b4fff,
++	0x015acfff,
++	0x01590fff,
++	0x0156cfff,
++};
++
++static const u32 papd_cal_scalars_tbl_core1_rev7[] = {
++	0x0b5e002d,
++	0x0ae2002f,
++	0x0a3b0032,
++	0x09a70035,
++	0x09220038,
++	0x08ab003b,
++	0x081f003f,
++	0x07a20043,
++	0x07340047,
++	0x06d2004b,
++	0x067a004f,
++	0x06170054,
++	0x05bf0059,
++	0x0571005e,
++	0x051e0064,
++	0x04d3006a,
++	0x04910070,
++	0x044c0077,
++	0x040f007e,
++	0x03d90085,
++	0x03a1008d,
++	0x036f0095,
++	0x033d009e,
++	0x030b00a8,
++	0x02e000b2,
++	0x02b900bc,
++	0x029200c7,
++	0x026d00d3,
++	0x024900e0,
++	0x022900ed,
++	0x020a00fb,
++	0x01ec010a,
++	0x01d20119,
++	0x01b7012a,
++	0x019e013c,
++	0x0188014e,
++	0x01720162,
++	0x015d0177,
++	0x0149018e,
++	0x013701a5,
++	0x012601be,
++	0x011501d8,
++	0x010601f4,
++	0x00f70212,
++	0x00e90231,
++	0x00dc0253,
++	0x00d00276,
++	0x00c4029b,
++	0x00b902c3,
++	0x00af02ed,
++	0x00a50319,
++	0x009c0348,
++	0x0093037a,
++	0x008b03af,
++	0x008303e6,
++	0x007c0422,
++	0x00750460,
++	0x006e04a3,
++	0x006804e9,
++	0x00620533,
++	0x005d0582,
++	0x005805d6,
++	0x0053062e,
++	0x004e068c,
++};
++
++const struct phytbl_info mimophytbl_info_rev7[] = {
++	{&frame_struct_rev3,
++	 sizeof(frame_struct_rev3) / sizeof(frame_struct_rev3[0]), 10, 0, 32}
++	,
++	{&pilot_tbl_rev3, sizeof(pilot_tbl_rev3) / sizeof(pilot_tbl_rev3[0]),
++	 11, 0, 16}
++	,
++	{&tmap_tbl_rev7, sizeof(tmap_tbl_rev7) / sizeof(tmap_tbl_rev7[0]), 12,
++	 0, 32}
++	,
++	{&intlv_tbl_rev3, sizeof(intlv_tbl_rev3) / sizeof(intlv_tbl_rev3[0]),
++	 13, 0, 32}
++	,
++	{&tdtrn_tbl_rev3, sizeof(tdtrn_tbl_rev3) / sizeof(tdtrn_tbl_rev3[0]),
++	 14, 0, 32}
++	,
++	{&noise_var_tbl_rev7,
++	 sizeof(noise_var_tbl_rev7) / sizeof(noise_var_tbl_rev7[0]), 16, 0, 32}
++	,
++	{&mcs_tbl_rev3, sizeof(mcs_tbl_rev3) / sizeof(mcs_tbl_rev3[0]), 18, 0,
++	 16}
++	,
++	{&tdi_tbl20_ant0_rev3,
++	 sizeof(tdi_tbl20_ant0_rev3) / sizeof(tdi_tbl20_ant0_rev3[0]), 19, 128,
++	 32}
++	,
++	{&tdi_tbl20_ant1_rev3,
++	 sizeof(tdi_tbl20_ant1_rev3) / sizeof(tdi_tbl20_ant1_rev3[0]), 19, 256,
++	 32}
++	,
++	{&tdi_tbl40_ant0_rev3,
++	 sizeof(tdi_tbl40_ant0_rev3) / sizeof(tdi_tbl40_ant0_rev3[0]), 19, 640,
++	 32}
++	,
++	{&tdi_tbl40_ant1_rev3,
++	 sizeof(tdi_tbl40_ant1_rev3) / sizeof(tdi_tbl40_ant1_rev3[0]), 19, 768,
++	 32}
++	,
++	{&pltlut_tbl_rev3, sizeof(pltlut_tbl_rev3) / sizeof(pltlut_tbl_rev3[0]),
++	 20, 0, 32}
++	,
++	{&chanest_tbl_rev3,
++	 sizeof(chanest_tbl_rev3) / sizeof(chanest_tbl_rev3[0]), 22, 0, 32}
++	,
++	{&frame_lut_rev3, sizeof(frame_lut_rev3) / sizeof(frame_lut_rev3[0]),
++	 24, 0, 8}
++	,
++	{&est_pwr_lut_core0_rev3,
++	 sizeof(est_pwr_lut_core0_rev3) / sizeof(est_pwr_lut_core0_rev3[0]), 26,
++	 0, 8}
++	,
++	{&est_pwr_lut_core1_rev3,
++	 sizeof(est_pwr_lut_core1_rev3) / sizeof(est_pwr_lut_core1_rev3[0]), 27,
++	 0, 8}
++	,
++	{&adj_pwr_lut_core0_rev3,
++	 sizeof(adj_pwr_lut_core0_rev3) / sizeof(adj_pwr_lut_core0_rev3[0]), 26,
++	 64, 8}
++	,
++	{&adj_pwr_lut_core1_rev3,
++	 sizeof(adj_pwr_lut_core1_rev3) / sizeof(adj_pwr_lut_core1_rev3[0]), 27,
++	 64, 8}
++	,
++	{&gainctrl_lut_core0_rev3,
++	 sizeof(gainctrl_lut_core0_rev3) / sizeof(gainctrl_lut_core0_rev3[0]),
++	 26, 192, 32}
++	,
++	{&gainctrl_lut_core1_rev3,
++	 sizeof(gainctrl_lut_core1_rev3) / sizeof(gainctrl_lut_core1_rev3[0]),
++	 27, 192, 32}
++	,
++	{&iq_lut_core0_rev3,
++	 sizeof(iq_lut_core0_rev3) / sizeof(iq_lut_core0_rev3[0]), 26, 320, 32}
++	,
++	{&iq_lut_core1_rev3,
++	 sizeof(iq_lut_core1_rev3) / sizeof(iq_lut_core1_rev3[0]), 27, 320, 32}
++	,
++	{&loft_lut_core0_rev3,
++	 sizeof(loft_lut_core0_rev3) / sizeof(loft_lut_core0_rev3[0]), 26, 448,
++	 16}
++	,
++	{&loft_lut_core1_rev3,
++	 sizeof(loft_lut_core1_rev3) / sizeof(loft_lut_core1_rev3[0]), 27, 448,
++	 16}
++	,
++	{&papd_comp_rfpwr_tbl_core0_rev3,
++	 sizeof(papd_comp_rfpwr_tbl_core0_rev3) /
++	 sizeof(papd_comp_rfpwr_tbl_core0_rev3[0]), 26, 576, 16}
++	,
++	{&papd_comp_rfpwr_tbl_core1_rev3,
++	 sizeof(papd_comp_rfpwr_tbl_core1_rev3) /
++	 sizeof(papd_comp_rfpwr_tbl_core1_rev3[0]), 27, 576, 16}
++	,
++	{&papd_comp_epsilon_tbl_core0_rev7,
++	 sizeof(papd_comp_epsilon_tbl_core0_rev7) /
++	 sizeof(papd_comp_epsilon_tbl_core0_rev7[0]), 31, 0, 32}
++	,
++	{&papd_cal_scalars_tbl_core0_rev7,
++	 sizeof(papd_cal_scalars_tbl_core0_rev7) /
++	 sizeof(papd_cal_scalars_tbl_core0_rev7[0]), 32, 0, 32}
++	,
++	{&papd_comp_epsilon_tbl_core1_rev7,
++	 sizeof(papd_comp_epsilon_tbl_core1_rev7) /
++	 sizeof(papd_comp_epsilon_tbl_core1_rev7[0]), 33, 0, 32}
++	,
++	{&papd_cal_scalars_tbl_core1_rev7,
++	 sizeof(papd_cal_scalars_tbl_core1_rev7) /
++	 sizeof(papd_cal_scalars_tbl_core1_rev7[0]), 34, 0, 32}
++	,
++};
++
++const u32 mimophytbl_info_sz_rev7 =
++	sizeof(mimophytbl_info_rev7) / sizeof(mimophytbl_info_rev7[0]);
++
++const struct phytbl_info mimophytbl_info_rev16[] = {
++	{&noise_var_tbl_rev7,
++	 sizeof(noise_var_tbl_rev7) / sizeof(noise_var_tbl_rev7[0]), 16, 0, 32}
++	,
++	{&est_pwr_lut_core0_rev3,
++	 sizeof(est_pwr_lut_core0_rev3) / sizeof(est_pwr_lut_core0_rev3[0]), 26,
++	 0, 8}
++	,
++	{&est_pwr_lut_core1_rev3,
++	 sizeof(est_pwr_lut_core1_rev3) / sizeof(est_pwr_lut_core1_rev3[0]), 27,
++	 0, 8}
++	,
++	{&adj_pwr_lut_core0_rev3,
++	 sizeof(adj_pwr_lut_core0_rev3) / sizeof(adj_pwr_lut_core0_rev3[0]), 26,
++	 64, 8}
++	,
++	{&adj_pwr_lut_core1_rev3,
++	 sizeof(adj_pwr_lut_core1_rev3) / sizeof(adj_pwr_lut_core1_rev3[0]), 27,
++	 64, 8}
++	,
++	{&gainctrl_lut_core0_rev3,
++	 sizeof(gainctrl_lut_core0_rev3) / sizeof(gainctrl_lut_core0_rev3[0]),
++	 26, 192, 32}
++	,
++	{&gainctrl_lut_core1_rev3,
++	 sizeof(gainctrl_lut_core1_rev3) / sizeof(gainctrl_lut_core1_rev3[0]),
++	 27, 192, 32}
++	,
++	{&iq_lut_core0_rev3,
++	 sizeof(iq_lut_core0_rev3) / sizeof(iq_lut_core0_rev3[0]), 26, 320, 32}
++	,
++	{&iq_lut_core1_rev3,
++	 sizeof(iq_lut_core1_rev3) / sizeof(iq_lut_core1_rev3[0]), 27, 320, 32}
++	,
++	{&loft_lut_core0_rev3,
++	 sizeof(loft_lut_core0_rev3) / sizeof(loft_lut_core0_rev3[0]), 26, 448,
++	 16}
++	,
++	{&loft_lut_core1_rev3,
++	 sizeof(loft_lut_core1_rev3) / sizeof(loft_lut_core1_rev3[0]), 27, 448,
++	 16}
++	,
++};
++
++const u32 mimophytbl_info_sz_rev16 =
++	sizeof(mimophytbl_info_rev16) / sizeof(mimophytbl_info_rev16[0]);
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_n.h b/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_n.h
+new file mode 100644
+index 0000000..dc8a84e
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_n.h
+@@ -0,0 +1,50 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#define ANT_SWCTRL_TBL_REV3_IDX (0)
++
++#include <types.h>
++#include "phy_int.h"
++
++extern const struct phytbl_info mimophytbl_info_rev0[],
++				mimophytbl_info_rev0_volatile[];
++
++extern const u32 mimophytbl_info_sz_rev0,
++		 mimophytbl_info_sz_rev0_volatile;
++
++extern const struct phytbl_info mimophytbl_info_rev3[],
++				mimophytbl_info_rev3_volatile[],
++				mimophytbl_info_rev3_volatile1[],
++				mimophytbl_info_rev3_volatile2[],
++				mimophytbl_info_rev3_volatile3[];
++
++extern const u32 mimophytbl_info_sz_rev3,
++		 mimophytbl_info_sz_rev3_volatile,
++		 mimophytbl_info_sz_rev3_volatile1,
++		 mimophytbl_info_sz_rev3_volatile2,
++		 mimophytbl_info_sz_rev3_volatile3;
++
++extern const u32 noise_var_tbl_rev3[];
++
++extern const struct phytbl_info mimophytbl_info_rev7[];
++
++extern const u32 mimophytbl_info_sz_rev7;
++
++extern const u32 noise_var_tbl_rev7[];
++
++extern const struct phytbl_info mimophytbl_info_rev16[];
++
++extern const u32 mimophytbl_info_sz_rev16;
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy_shim.c b/drivers/net/wireless/brcm80211/brcmsmac/phy_shim.c
+new file mode 100644
+index 0000000..a0de5db
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/phy_shim.c
+@@ -0,0 +1,216 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++/*
++ * This is "two-way" interface, acting as the SHIM layer between driver
++ * and PHY layer. The driver can optionally call this translation layer
++ * to do some preprocessing, then reach PHY. On the PHY->driver direction,
++ * all calls go through this layer since PHY doesn't have access to the
++ * driver's brcms_hardware pointer.
++ */
++#include <linux/slab.h>
++#include <net/mac80211.h>
++
++#include "main.h"
++#include "mac80211_if.h"
++#include "phy_shim.h"
++
++/* PHY SHIM module specific state */
++struct phy_shim_info {
++	struct brcms_hardware *wlc_hw;	/* pointer to main wlc_hw structure */
++	struct brcms_c_info *wlc;	/* pointer to main wlc structure */
++	struct brcms_info *wl; /* pointer to os-specific private state */
++};
++
++struct phy_shim_info *wlc_phy_shim_attach(struct brcms_hardware *wlc_hw,
++					  struct brcms_info *wl,
++					  struct brcms_c_info *wlc) {
++	struct phy_shim_info *physhim = NULL;
++
++	physhim = kzalloc(sizeof(struct phy_shim_info), GFP_ATOMIC);
++	if (!physhim)
++		return NULL;
++
++	physhim->wlc_hw = wlc_hw;
++	physhim->wlc = wlc;
++	physhim->wl = wl;
++
++	return physhim;
++}
++
++void wlc_phy_shim_detach(struct phy_shim_info *physhim)
++{
++	kfree(physhim);
++}
++
++struct wlapi_timer *wlapi_init_timer(struct phy_shim_info *physhim,
++				     void (*fn)(struct brcms_phy *pi),
++				     void *arg, const char *name)
++{
++	return (struct wlapi_timer *)
++			brcms_init_timer(physhim->wl, (void (*)(void *))fn,
++					 arg, name);
++}
++
++void wlapi_free_timer(struct wlapi_timer *t)
++{
++	brcms_free_timer((struct brcms_timer *)t);
++}
++
++void
++wlapi_add_timer(struct wlapi_timer *t, uint ms, int periodic)
++{
++	brcms_add_timer((struct brcms_timer *)t, ms, periodic);
++}
++
++bool wlapi_del_timer(struct wlapi_timer *t)
++{
++	return brcms_del_timer((struct brcms_timer *)t);
++}
++
++void wlapi_intrson(struct phy_shim_info *physhim)
++{
++	brcms_intrson(physhim->wl);
++}
++
++u32 wlapi_intrsoff(struct phy_shim_info *physhim)
++{
++	return brcms_intrsoff(physhim->wl);
++}
++
++void wlapi_intrsrestore(struct phy_shim_info *physhim, u32 macintmask)
++{
++	brcms_intrsrestore(physhim->wl, macintmask);
++}
++
++void wlapi_bmac_write_shm(struct phy_shim_info *physhim, uint offset, u16 v)
++{
++	brcms_b_write_shm(physhim->wlc_hw, offset, v);
++}
++
++u16 wlapi_bmac_read_shm(struct phy_shim_info *physhim, uint offset)
++{
++	return brcms_b_read_shm(physhim->wlc_hw, offset);
++}
++
++void
++wlapi_bmac_mhf(struct phy_shim_info *physhim, u8 idx, u16 mask,
++	       u16 val, int bands)
++{
++	brcms_b_mhf(physhim->wlc_hw, idx, mask, val, bands);
++}
++
++void wlapi_bmac_corereset(struct phy_shim_info *physhim, u32 flags)
++{
++	brcms_b_corereset(physhim->wlc_hw, flags);
++}
++
++void wlapi_suspend_mac_and_wait(struct phy_shim_info *physhim)
++{
++	brcms_c_suspend_mac_and_wait(physhim->wlc);
++}
++
++void wlapi_switch_macfreq(struct phy_shim_info *physhim, u8 spurmode)
++{
++	brcms_b_switch_macfreq(physhim->wlc_hw, spurmode);
++}
++
++void wlapi_enable_mac(struct phy_shim_info *physhim)
++{
++	brcms_c_enable_mac(physhim->wlc);
++}
++
++void wlapi_bmac_mctrl(struct phy_shim_info *physhim, u32 mask, u32 val)
++{
++	brcms_b_mctrl(physhim->wlc_hw, mask, val);
++}
++
++void wlapi_bmac_phy_reset(struct phy_shim_info *physhim)
++{
++	brcms_b_phy_reset(physhim->wlc_hw);
++}
++
++void wlapi_bmac_bw_set(struct phy_shim_info *physhim, u16 bw)
++{
++	brcms_b_bw_set(physhim->wlc_hw, bw);
++}
++
++u16 wlapi_bmac_get_txant(struct phy_shim_info *physhim)
++{
++	return brcms_b_get_txant(physhim->wlc_hw);
++}
++
++void wlapi_bmac_phyclk_fgc(struct phy_shim_info *physhim, bool clk)
++{
++	brcms_b_phyclk_fgc(physhim->wlc_hw, clk);
++}
++
++void wlapi_bmac_macphyclk_set(struct phy_shim_info *physhim, bool clk)
++{
++	brcms_b_macphyclk_set(physhim->wlc_hw, clk);
++}
++
++void wlapi_bmac_core_phypll_ctl(struct phy_shim_info *physhim, bool on)
++{
++	brcms_b_core_phypll_ctl(physhim->wlc_hw, on);
++}
++
++void wlapi_bmac_core_phypll_reset(struct phy_shim_info *physhim)
++{
++	brcms_b_core_phypll_reset(physhim->wlc_hw);
++}
++
++void wlapi_bmac_ucode_wake_override_phyreg_set(struct phy_shim_info *physhim)
++{
++	brcms_c_ucode_wake_override_set(physhim->wlc_hw,
++					BRCMS_WAKE_OVERRIDE_PHYREG);
++}
++
++void wlapi_bmac_ucode_wake_override_phyreg_clear(struct phy_shim_info *physhim)
++{
++	brcms_c_ucode_wake_override_clear(physhim->wlc_hw,
++					  BRCMS_WAKE_OVERRIDE_PHYREG);
++}
++
++void
++wlapi_bmac_write_template_ram(struct phy_shim_info *physhim, int offset,
++			      int len, void *buf)
++{
++	brcms_b_write_template_ram(physhim->wlc_hw, offset, len, buf);
++}
++
++u16 wlapi_bmac_rate_shm_offset(struct phy_shim_info *physhim, u8 rate)
++{
++	return brcms_b_rate_shm_offset(physhim->wlc_hw, rate);
++}
++
++void wlapi_ucode_sample_init(struct phy_shim_info *physhim)
++{
++}
++
++void
++wlapi_copyfrom_objmem(struct phy_shim_info *physhim, uint offset, void *buf,
++		      int len, u32 sel)
++{
++	brcms_b_copyfrom_objmem(physhim->wlc_hw, offset, buf, len, sel);
++}
++
++void
++wlapi_copyto_objmem(struct phy_shim_info *physhim, uint offset, const void *buf,
++		    int l, u32 sel)
++{
++	brcms_b_copyto_objmem(physhim->wlc_hw, offset, buf, l, sel);
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy_shim.h b/drivers/net/wireless/brcm80211/brcmsmac/phy_shim.h
+new file mode 100644
+index 0000000..2c5b66b
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/phy_shim.h
+@@ -0,0 +1,179 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++/*
++ * phy_shim.h: stuff defined in phy_shim.c and included only by the phy
++ */
++
++#ifndef _BRCM_PHY_SHIM_H_
++#define _BRCM_PHY_SHIM_H_
++
++#include "types.h"
++
++#define RADAR_TYPE_NONE		0	/* Radar type None */
++#define RADAR_TYPE_ETSI_1	1	/* ETSI 1 Radar type */
++#define RADAR_TYPE_ETSI_2	2	/* ETSI 2 Radar type */
++#define RADAR_TYPE_ETSI_3	3	/* ETSI 3 Radar type */
++#define RADAR_TYPE_ITU_E	4	/* ITU E Radar type */
++#define RADAR_TYPE_ITU_K	5	/* ITU K Radar type */
++#define RADAR_TYPE_UNCLASSIFIED	6	/* Unclassified Radar type  */
++#define RADAR_TYPE_BIN5		7	/* long pulse radar type */
++#define RADAR_TYPE_STG2		8	/* staggered-2 radar */
++#define RADAR_TYPE_STG3		9	/* staggered-3 radar */
++#define RADAR_TYPE_FRA		10	/* French radar */
++
++/* French radar pulse widths */
++#define FRA_T1_20MHZ	52770
++#define FRA_T2_20MHZ	61538
++#define FRA_T3_20MHZ	66002
++#define FRA_T1_40MHZ	105541
++#define FRA_T2_40MHZ	123077
++#define FRA_T3_40MHZ	132004
++#define FRA_ERR_20MHZ	60
++#define FRA_ERR_40MHZ	120
++
++#define ANTSEL_NA		0 /* No boardlevel selection available */
++#define ANTSEL_2x4		1 /* 2x4 boardlevel selection available */
++#define ANTSEL_2x3		2 /* 2x3 CB2 boardlevel selection available */
++
++/* Rx Antenna diversity control values */
++#define	ANT_RX_DIV_FORCE_0	0	/* Use antenna 0 */
++#define	ANT_RX_DIV_FORCE_1	1	/* Use antenna 1 */
++#define	ANT_RX_DIV_START_1	2	/* Choose starting with 1 */
++#define	ANT_RX_DIV_START_0	3	/* Choose starting with 0 */
++#define	ANT_RX_DIV_ENABLE	3	/* APHY bbConfig Enable RX Diversity */
++#define ANT_RX_DIV_DEF		ANT_RX_DIV_START_0 /* default antdiv setting */
++
++#define WL_ANT_RX_MAX		2	/* max 2 receive antennas */
++#define WL_ANT_HT_RX_MAX	3	/* max 3 receive antennas/cores */
++#define WL_ANT_IDX_1		0	/* antenna index 1 */
++#define WL_ANT_IDX_2		1	/* antenna index 2 */
++
++/* values for n_preamble_type */
++#define BRCMS_N_PREAMBLE_MIXEDMODE	0
++#define BRCMS_N_PREAMBLE_GF		1
++#define BRCMS_N_PREAMBLE_GF_BRCM          2
++
++#define WL_TX_POWER_RATES_LEGACY	45
++#define WL_TX_POWER_MCS20_FIRST	        12
++#define WL_TX_POWER_MCS20_NUM	        16
++#define WL_TX_POWER_MCS40_FIRST	        28
++#define WL_TX_POWER_MCS40_NUM	        17
++
++
++#define WL_TX_POWER_RATES	       101
++#define WL_TX_POWER_CCK_FIRST	       0
++#define WL_TX_POWER_CCK_NUM	       4
++/* Index for first 20MHz OFDM SISO rate */
++#define WL_TX_POWER_OFDM_FIRST	       4
++/* Index for first 20MHz OFDM CDD rate */
++#define WL_TX_POWER_OFDM20_CDD_FIRST   12
++/* Index for first 40MHz OFDM SISO rate */
++#define WL_TX_POWER_OFDM40_SISO_FIRST  52
++/* Index for first 40MHz OFDM CDD rate */
++#define WL_TX_POWER_OFDM40_CDD_FIRST   60
++#define WL_TX_POWER_OFDM_NUM	       8
++/* Index for first 20MHz MCS SISO rate */
++#define WL_TX_POWER_MCS20_SISO_FIRST   20
++/* Index for first 20MHz MCS CDD rate */
++#define WL_TX_POWER_MCS20_CDD_FIRST    28
++/* Index for first 20MHz MCS STBC rate */
++#define WL_TX_POWER_MCS20_STBC_FIRST   36
++/* Index for first 20MHz MCS SDM rate */
++#define WL_TX_POWER_MCS20_SDM_FIRST    44
++/* Index for first 40MHz MCS SISO rate */
++#define WL_TX_POWER_MCS40_SISO_FIRST   68
++/* Index for first 40MHz MCS CDD rate */
++#define WL_TX_POWER_MCS40_CDD_FIRST    76
++/* Index for first 40MHz MCS STBC rate */
++#define WL_TX_POWER_MCS40_STBC_FIRST   84
++/* Index for first 40MHz MCS SDM rate */
++#define WL_TX_POWER_MCS40_SDM_FIRST    92
++#define WL_TX_POWER_MCS_1_STREAM_NUM   8
++#define WL_TX_POWER_MCS_2_STREAM_NUM   8
++/* Index for 40MHz rate MCS 32 */
++#define WL_TX_POWER_MCS_32	       100
++#define WL_TX_POWER_MCS_32_NUM	       1
++
++/* sslpnphy specifics */
++/* Index for first 20MHz MCS SISO rate */
++#define WL_TX_POWER_MCS20_SISO_FIRST_SSN   12
++
++/* struct tx_power::flags bits */
++#define WL_TX_POWER_F_ENABLED	1
++#define WL_TX_POWER_F_HW	2
++#define WL_TX_POWER_F_MIMO	4
++#define WL_TX_POWER_F_SISO	8
++
++/* values to force tx/rx chain */
++#define BRCMS_N_TXRX_CHAIN0		0
++#define BRCMS_N_TXRX_CHAIN1		1
++
++struct brcms_phy;
++
++extern struct phy_shim_info *wlc_phy_shim_attach(struct brcms_hardware *wlc_hw,
++						 struct brcms_info *wl,
++						 struct brcms_c_info *wlc);
++extern void wlc_phy_shim_detach(struct phy_shim_info *physhim);
++
++/* PHY to WL utility functions */
++extern struct wlapi_timer *wlapi_init_timer(struct phy_shim_info *physhim,
++					    void (*fn) (struct brcms_phy *pi),
++					    void *arg, const char *name);
++extern void wlapi_free_timer(struct wlapi_timer *t);
++extern void wlapi_add_timer(struct wlapi_timer *t, uint ms, int periodic);
++extern bool wlapi_del_timer(struct wlapi_timer *t);
++extern void wlapi_intrson(struct phy_shim_info *physhim);
++extern u32 wlapi_intrsoff(struct phy_shim_info *physhim);
++extern void wlapi_intrsrestore(struct phy_shim_info *physhim,
++			       u32 macintmask);
++
++extern void wlapi_bmac_write_shm(struct phy_shim_info *physhim, uint offset,
++				 u16 v);
++extern u16 wlapi_bmac_read_shm(struct phy_shim_info *physhim, uint offset);
++extern void wlapi_bmac_mhf(struct phy_shim_info *physhim, u8 idx,
++			   u16 mask, u16 val, int bands);
++extern void wlapi_bmac_corereset(struct phy_shim_info *physhim, u32 flags);
++extern void wlapi_suspend_mac_and_wait(struct phy_shim_info *physhim);
++extern void wlapi_switch_macfreq(struct phy_shim_info *physhim, u8 spurmode);
++extern void wlapi_enable_mac(struct phy_shim_info *physhim);
++extern void wlapi_bmac_mctrl(struct phy_shim_info *physhim, u32 mask,
++			     u32 val);
++extern void wlapi_bmac_phy_reset(struct phy_shim_info *physhim);
++extern void wlapi_bmac_bw_set(struct phy_shim_info *physhim, u16 bw);
++extern void wlapi_bmac_phyclk_fgc(struct phy_shim_info *physhim, bool clk);
++extern void wlapi_bmac_macphyclk_set(struct phy_shim_info *physhim, bool clk);
++extern void wlapi_bmac_core_phypll_ctl(struct phy_shim_info *physhim, bool on);
++extern void wlapi_bmac_core_phypll_reset(struct phy_shim_info *physhim);
++extern void wlapi_bmac_ucode_wake_override_phyreg_set(struct phy_shim_info *
++						      physhim);
++extern void wlapi_bmac_ucode_wake_override_phyreg_clear(struct phy_shim_info *
++							physhim);
++extern void wlapi_bmac_write_template_ram(struct phy_shim_info *physhim, int o,
++					  int len, void *buf);
++extern u16 wlapi_bmac_rate_shm_offset(struct phy_shim_info *physhim,
++					 u8 rate);
++extern void wlapi_ucode_sample_init(struct phy_shim_info *physhim);
++extern void wlapi_copyfrom_objmem(struct phy_shim_info *physhim, uint,
++				  void *buf, int, u32 sel);
++extern void wlapi_copyto_objmem(struct phy_shim_info *physhim, uint,
++				const void *buf, int, u32);
++
++extern void wlapi_high_update_phy_mode(struct phy_shim_info *physhim,
++				       u32 phy_mode);
++extern u16 wlapi_bmac_get_txant(struct phy_shim_info *physhim);
++
++#endif				/* _BRCM_PHY_SHIM_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/pmu.c b/drivers/net/wireless/brcm80211/brcmsmac/pmu.c
+new file mode 100644
+index 0000000..4931d29
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/pmu.c
+@@ -0,0 +1,375 @@
++/*
++ * Copyright (c) 2011 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#include <linux/delay.h>
++#include <linux/io.h>
++
++#include <brcm_hw_ids.h>
++#include <chipcommon.h>
++#include <brcmu_utils.h>
++#include "pub.h"
++#include "aiutils.h"
++#include "pmu.h"
++#include "soc.h"
++
++/*
++ * external LPO crystal frequency
++ */
++#define EXT_ILP_HZ 32768
++
++/*
++ * Duration for ILP clock frequency measurment in milliseconds
++ *
++ * remark: 1000 must be an integer multiple of this duration
++ */
++#define ILP_CALC_DUR	10
++
++/* Fields in pmucontrol */
++#define	PCTL_ILP_DIV_MASK	0xffff0000
++#define	PCTL_ILP_DIV_SHIFT	16
++#define PCTL_PLL_PLLCTL_UPD	0x00000400	/* rev 2 */
++#define PCTL_NOILP_ON_WAIT	0x00000200	/* rev 1 */
++#define	PCTL_HT_REQ_EN		0x00000100
++#define	PCTL_ALP_REQ_EN		0x00000080
++#define	PCTL_XTALFREQ_MASK	0x0000007c
++#define	PCTL_XTALFREQ_SHIFT	2
++#define	PCTL_ILP_DIV_EN		0x00000002
++#define	PCTL_LPO_SEL		0x00000001
++
++/* ILP clock */
++#define	ILP_CLOCK		32000
++
++/* ALP clock on pre-PMU chips */
++#define	ALP_CLOCK		20000000
++
++/* pmustatus */
++#define PST_EXTLPOAVAIL	0x0100
++#define PST_WDRESET	0x0080
++#define	PST_INTPEND	0x0040
++#define	PST_SBCLKST	0x0030
++#define	PST_SBCLKST_ILP	0x0010
++#define	PST_SBCLKST_ALP	0x0020
++#define	PST_SBCLKST_HT	0x0030
++#define	PST_ALPAVAIL	0x0008
++#define	PST_HTAVAIL	0x0004
++#define	PST_RESINIT	0x0003
++
++/* PMU resource bit position */
++#define PMURES_BIT(bit)	(1 << (bit))
++
++/* PMU corerev and chip specific PLL controls.
++ * PMU<rev>_PLL<num>_XX where <rev> is PMU corerev and <num> is an arbitrary
++ * number to differentiate different PLLs controlled by the same PMU rev.
++ */
++/* pllcontrol registers:
++ * ndiv_pwrdn, pwrdn_ch<x>, refcomp_pwrdn, dly_ch<x>,
++ * p1div, p2div, _bypass_sdmod
++ */
++#define PMU1_PLL0_PLLCTL0		0
++#define PMU1_PLL0_PLLCTL1		1
++#define PMU1_PLL0_PLLCTL2		2
++#define PMU1_PLL0_PLLCTL3		3
++#define PMU1_PLL0_PLLCTL4		4
++#define PMU1_PLL0_PLLCTL5		5
++
++/* pmu XtalFreqRatio */
++#define	PMU_XTALFREQ_REG_ILPCTR_MASK	0x00001FFF
++#define	PMU_XTALFREQ_REG_MEASURE_MASK	0x80000000
++#define	PMU_XTALFREQ_REG_MEASURE_SHIFT	31
++
++/* 4313 resources */
++#define	RES4313_BB_PU_RSRC		0
++#define	RES4313_ILP_REQ_RSRC		1
++#define	RES4313_XTAL_PU_RSRC		2
++#define	RES4313_ALP_AVAIL_RSRC		3
++#define	RES4313_RADIO_PU_RSRC		4
++#define	RES4313_BG_PU_RSRC		5
++#define	RES4313_VREG1P4_PU_RSRC		6
++#define	RES4313_AFE_PWRSW_RSRC		7
++#define	RES4313_RX_PWRSW_RSRC		8
++#define	RES4313_TX_PWRSW_RSRC		9
++#define	RES4313_BB_PWRSW_RSRC		10
++#define	RES4313_SYNTH_PWRSW_RSRC	11
++#define	RES4313_MISC_PWRSW_RSRC		12
++#define	RES4313_BB_PLL_PWRSW_RSRC	13
++#define	RES4313_HT_AVAIL_RSRC		14
++#define	RES4313_MACPHY_CLK_AVAIL_RSRC	15
++
++/* Determine min/max rsrc masks. Value 0 leaves hardware at default. */
++static void si_pmu_res_masks(struct si_pub *sih, u32 * pmin, u32 * pmax)
++{
++	u32 min_mask = 0, max_mask = 0;
++	uint rsrcs;
++
++	/* # resources */
++	rsrcs = (ai_get_pmucaps(sih) & PCAP_RC_MASK) >> PCAP_RC_SHIFT;
++
++	/* determine min/max rsrc masks */
++	switch (ai_get_chip_id(sih)) {
++	case BCM43224_CHIP_ID:
++	case BCM43225_CHIP_ID:
++		/* ??? */
++		break;
++
++	case BCM4313_CHIP_ID:
++		min_mask = PMURES_BIT(RES4313_BB_PU_RSRC) |
++		    PMURES_BIT(RES4313_XTAL_PU_RSRC) |
++		    PMURES_BIT(RES4313_ALP_AVAIL_RSRC) |
++		    PMURES_BIT(RES4313_BB_PLL_PWRSW_RSRC);
++		max_mask = 0xffff;
++		break;
++	default:
++		break;
++	}
++
++	*pmin = min_mask;
++	*pmax = max_mask;
++}
++
++void si_pmu_spuravoid_pllupdate(struct si_pub *sih, u8 spuravoid)
++{
++	u32 tmp = 0;
++	struct bcma_device *core;
++
++	/* switch to chipc */
++	core = ai_findcore(sih, BCMA_CORE_CHIPCOMMON, 0);
++
++	switch (ai_get_chip_id(sih)) {
++	case BCM43224_CHIP_ID:
++	case BCM43225_CHIP_ID:
++		if (spuravoid == 1) {
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_addr),
++				     PMU1_PLL0_PLLCTL0);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_data),
++				     0x11500010);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_addr),
++				     PMU1_PLL0_PLLCTL1);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_data),
++				     0x000C0C06);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_addr),
++				     PMU1_PLL0_PLLCTL2);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_data),
++				     0x0F600a08);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_addr),
++				     PMU1_PLL0_PLLCTL3);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_data),
++				     0x00000000);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_addr),
++				     PMU1_PLL0_PLLCTL4);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_data),
++				     0x2001E920);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_addr),
++				     PMU1_PLL0_PLLCTL5);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_data),
++				     0x88888815);
++		} else {
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_addr),
++				     PMU1_PLL0_PLLCTL0);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_data),
++				     0x11100010);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_addr),
++				     PMU1_PLL0_PLLCTL1);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_data),
++				     0x000c0c06);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_addr),
++				     PMU1_PLL0_PLLCTL2);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_data),
++				     0x03000a08);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_addr),
++				     PMU1_PLL0_PLLCTL3);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_data),
++				     0x00000000);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_addr),
++				     PMU1_PLL0_PLLCTL4);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_data),
++				     0x200005c0);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_addr),
++				     PMU1_PLL0_PLLCTL5);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_data),
++				     0x88888815);
++		}
++		tmp = 1 << 10;
++		break;
++
++	default:
++		/* bail out */
++		return;
++	}
++
++	bcma_set32(core, CHIPCREGOFFS(pmucontrol), tmp);
++}
++
++u16 si_pmu_fast_pwrup_delay(struct si_pub *sih)
++{
++	uint delay = PMU_MAX_TRANSITION_DLY;
++
++	switch (ai_get_chip_id(sih)) {
++	case BCM43224_CHIP_ID:
++	case BCM43225_CHIP_ID:
++	case BCM4313_CHIP_ID:
++		delay = 3700;
++		break;
++	default:
++		break;
++	}
++
++	return (u16) delay;
++}
++
++/* Read/write a chipcontrol reg */
++u32 si_pmu_chipcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val)
++{
++	ai_cc_reg(sih, offsetof(struct chipcregs, chipcontrol_addr), ~0, reg);
++	return ai_cc_reg(sih, offsetof(struct chipcregs, chipcontrol_data),
++			 mask, val);
++}
++
++/* Read/write a regcontrol reg */
++u32 si_pmu_regcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val)
++{
++	ai_cc_reg(sih, offsetof(struct chipcregs, regcontrol_addr), ~0, reg);
++	return ai_cc_reg(sih, offsetof(struct chipcregs, regcontrol_data),
++			 mask, val);
++}
++
++/* Read/write a pllcontrol reg */
++u32 si_pmu_pllcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val)
++{
++	ai_cc_reg(sih, offsetof(struct chipcregs, pllcontrol_addr), ~0, reg);
++	return ai_cc_reg(sih, offsetof(struct chipcregs, pllcontrol_data),
++			 mask, val);
++}
++
++/* PMU PLL update */
++void si_pmu_pllupd(struct si_pub *sih)
++{
++	ai_cc_reg(sih, offsetof(struct chipcregs, pmucontrol),
++		  PCTL_PLL_PLLCTL_UPD, PCTL_PLL_PLLCTL_UPD);
++}
++
++/* query alp/xtal clock frequency */
++u32 si_pmu_alp_clock(struct si_pub *sih)
++{
++	u32 clock = ALP_CLOCK;
++
++	/* bail out with default */
++	if (!(ai_get_cccaps(sih) & CC_CAP_PMU))
++		return clock;
++
++	switch (ai_get_chip_id(sih)) {
++	case BCM43224_CHIP_ID:
++	case BCM43225_CHIP_ID:
++	case BCM4313_CHIP_ID:
++		/* always 20Mhz */
++		clock = 20000 * 1000;
++		break;
++	default:
++		break;
++	}
++
++	return clock;
++}
++
++/* initialize PMU */
++void si_pmu_init(struct si_pub *sih)
++{
++	struct bcma_device *core;
++
++	/* select chipc */
++	core = ai_findcore(sih, BCMA_CORE_CHIPCOMMON, 0);
++
++	if (ai_get_pmurev(sih) == 1)
++		bcma_mask32(core, CHIPCREGOFFS(pmucontrol),
++			    ~PCTL_NOILP_ON_WAIT);
++	else if (ai_get_pmurev(sih) >= 2)
++		bcma_set32(core, CHIPCREGOFFS(pmucontrol), PCTL_NOILP_ON_WAIT);
++}
++
++/* initialize PMU resources */
++void si_pmu_res_init(struct si_pub *sih)
++{
++	struct bcma_device *core;
++	u32 min_mask = 0, max_mask = 0;
++
++	/* select to chipc */
++	core = ai_findcore(sih, BCMA_CORE_CHIPCOMMON, 0);
++
++	/* Determine min/max rsrc masks */
++	si_pmu_res_masks(sih, &min_mask, &max_mask);
++
++	/* It is required to program max_mask first and then min_mask */
++
++	/* Program max resource mask */
++
++	if (max_mask)
++		bcma_write32(core, CHIPCREGOFFS(max_res_mask), max_mask);
++
++	/* Program min resource mask */
++
++	if (min_mask)
++		bcma_write32(core, CHIPCREGOFFS(min_res_mask), min_mask);
++
++	/* Add some delay; allow resources to come up and settle. */
++	mdelay(2);
++}
++
++u32 si_pmu_measure_alpclk(struct si_pub *sih)
++{
++	struct bcma_device *core;
++	u32 alp_khz;
++
++	if (ai_get_pmurev(sih) < 10)
++		return 0;
++
++	/* Remember original core before switch to chipc */
++	core = ai_findcore(sih, BCMA_CORE_CHIPCOMMON, 0);
++
++	if (bcma_read32(core, CHIPCREGOFFS(pmustatus)) & PST_EXTLPOAVAIL) {
++		u32 ilp_ctr, alp_hz;
++
++		/*
++		 * Enable the reg to measure the freq,
++		 * in case it was disabled before
++		 */
++		bcma_write32(core, CHIPCREGOFFS(pmu_xtalfreq),
++			    1U << PMU_XTALFREQ_REG_MEASURE_SHIFT);
++
++		/* Delay for well over 4 ILP clocks */
++		udelay(1000);
++
++		/* Read the latched number of ALP ticks per 4 ILP ticks */
++		ilp_ctr = bcma_read32(core, CHIPCREGOFFS(pmu_xtalfreq)) &
++			  PMU_XTALFREQ_REG_ILPCTR_MASK;
++
++		/*
++		 * Turn off the PMU_XTALFREQ_REG_MEASURE_SHIFT
++		 * bit to save power
++		 */
++		bcma_write32(core, CHIPCREGOFFS(pmu_xtalfreq), 0);
++
++		/* Calculate ALP frequency */
++		alp_hz = (ilp_ctr * EXT_ILP_HZ) / 4;
++
++		/*
++		 * Round to nearest 100KHz, and at
++		 * the same time convert to KHz
++		 */
++		alp_khz = (alp_hz + 50000) / 100000 * 100;
++	} else
++		alp_khz = 0;
++
++	return alp_khz;
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/pmu.h b/drivers/net/wireless/brcm80211/brcmsmac/pmu.h
+new file mode 100644
+index 0000000..3e39c5e
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/pmu.h
+@@ -0,0 +1,35 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++
++#ifndef _BRCM_PMU_H_
++#define _BRCM_PMU_H_
++
++#include "types.h"
++
++extern u16 si_pmu_fast_pwrup_delay(struct si_pub *sih);
++extern void si_pmu_sprom_enable(struct si_pub *sih, bool enable);
++extern u32 si_pmu_chipcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val);
++extern u32 si_pmu_regcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val);
++extern u32 si_pmu_alp_clock(struct si_pub *sih);
++extern void si_pmu_pllupd(struct si_pub *sih);
++extern void si_pmu_spuravoid_pllupdate(struct si_pub *sih, u8 spuravoid);
++extern u32 si_pmu_pllcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val);
++extern void si_pmu_init(struct si_pub *sih);
++extern void si_pmu_res_init(struct si_pub *sih);
++extern u32 si_pmu_measure_alpclk(struct si_pub *sih);
++
++#endif /* _BRCM_PMU_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/pub.h b/drivers/net/wireless/brcm80211/brcmsmac/pub.h
+new file mode 100644
+index 0000000..aa5d67f
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/pub.h
+@@ -0,0 +1,372 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef _BRCM_PUB_H_
++#define _BRCM_PUB_H_
++
++#include <linux/bcma/bcma.h>
++#include <brcmu_wifi.h>
++#include "types.h"
++#include "defs.h"
++
++#define	BRCMS_NUMRATES	16	/* max # of rates in a rateset */
++
++/* phy types */
++#define	PHY_TYPE_A	0	/* Phy type A */
++#define	PHY_TYPE_G	2	/* Phy type G */
++#define	PHY_TYPE_N	4	/* Phy type N */
++#define	PHY_TYPE_LP	5	/* Phy type Low Power A/B/G */
++#define	PHY_TYPE_SSN	6	/* Phy type Single Stream N */
++#define	PHY_TYPE_LCN	8	/* Phy type Single Stream N */
++#define	PHY_TYPE_LCNXN	9	/* Phy type 2-stream N */
++#define	PHY_TYPE_HT	7	/* Phy type 3-Stream N */
++
++/* bw */
++#define BRCMS_10_MHZ	10	/* 10Mhz nphy channel bandwidth */
++#define BRCMS_20_MHZ	20	/* 20Mhz nphy channel bandwidth */
++#define BRCMS_40_MHZ	40	/* 40Mhz nphy channel bandwidth */
++
++#define	BRCMS_RSSI_MINVAL	-200	/* Low value, e.g. for forcing roam */
++#define	BRCMS_RSSI_NO_SIGNAL	-91	/* NDIS RSSI link quality cutoffs */
++#define	BRCMS_RSSI_VERY_LOW	-80	/* Very low quality cutoffs */
++#define	BRCMS_RSSI_LOW		-70	/* Low quality cutoffs */
++#define	BRCMS_RSSI_GOOD		-68	/* Good quality cutoffs */
++#define	BRCMS_RSSI_VERY_GOOD	-58	/* Very good quality cutoffs */
++#define	BRCMS_RSSI_EXCELLENT	-57	/* Excellent quality cutoffs */
++
++/* a large TX Power as an init value to factor out of min() calculations,
++ * keep low enough to fit in an s8, units are .25 dBm
++ */
++#define BRCMS_TXPWR_MAX		(127)	/* ~32 dBm = 1,500 mW */
++
++/* rate related definitions */
++#define	BRCMS_RATE_FLAG	0x80	/* Flag to indicate it is a basic rate */
++#define	BRCMS_RATE_MASK	0x7f	/* Rate value mask w/o basic rate flag */
++
++/* legacy rx Antenna diversity for SISO rates */
++#define	ANT_RX_DIV_FORCE_0	0	/* Use antenna 0 */
++#define	ANT_RX_DIV_FORCE_1	1	/* Use antenna 1 */
++#define	ANT_RX_DIV_START_1	2	/* Choose starting with 1 */
++#define	ANT_RX_DIV_START_0	3	/* Choose starting with 0 */
++#define	ANT_RX_DIV_ENABLE	3	/* APHY bbConfig Enable RX Diversity */
++/* default antdiv setting */
++#define ANT_RX_DIV_DEF		ANT_RX_DIV_START_0
++
++/* legacy rx Antenna diversity for SISO rates */
++/* Tx on antenna 0, "legacy term Main" */
++#define ANT_TX_FORCE_0		0
++/* Tx on antenna 1, "legacy term Aux" */
++#define ANT_TX_FORCE_1		1
++/* Tx on phy's last good Rx antenna */
++#define ANT_TX_LAST_RX		3
++/* driver's default tx antenna setting */
++#define ANT_TX_DEF		3
++
++/* Tx Chain values */
++/* def bitmap of txchain */
++#define TXCHAIN_DEF		0x1
++/* default bitmap of tx chains for nphy */
++#define TXCHAIN_DEF_NPHY	0x3
++/* default bitmap of tx chains for nphy */
++#define TXCHAIN_DEF_HTPHY	0x7
++/* def bitmap of rxchain */
++#define RXCHAIN_DEF		0x1
++/* default bitmap of rx chains for nphy */
++#define RXCHAIN_DEF_NPHY	0x3
++/* default bitmap of rx chains for nphy */
++#define RXCHAIN_DEF_HTPHY	0x7
++/* no antenna switch */
++#define ANTSWITCH_NONE		0
++/* antenna switch on 4321CB2, 2of3 */
++#define ANTSWITCH_TYPE_1	1
++/* antenna switch on 4321MPCI, 2of3 */
++#define ANTSWITCH_TYPE_2	2
++/* antenna switch on 4322, 2of3 */
++#define ANTSWITCH_TYPE_3	3
++
++#define RXBUFSZ		PKTBUFSZ
++
++#define MAX_STREAMS_SUPPORTED	4	/* max number of streams supported */
++
++struct brcm_rateset {
++	/* # rates in this set */
++	u32 count;
++	/* rates in 500kbps units w/hi bit set if basic */
++	u8 rates[WL_NUMRATES];
++};
++
++struct brcms_c_rateset {
++	uint count;		/* number of rates in rates[] */
++	 /* rates in 500kbps units w/hi bit set if basic */
++	u8 rates[BRCMS_NUMRATES];
++	u8 htphy_membership;	/* HT PHY Membership */
++	u8 mcs[MCSSET_LEN];	/* supported mcs index bit map */
++};
++
++/* All the HT-specific default advertised capabilities (including AMPDU)
++ * should be grouped here at one place
++ */
++#define AMPDU_DEF_MPDU_DENSITY	6	/* default mpdu density (110 ==> 4us) */
++
++/* wlc internal bss_info */
++struct brcms_bss_info {
++	u8 BSSID[ETH_ALEN];	/* network BSSID */
++	u16 flags;		/* flags for internal attributes */
++	u8 SSID_len;		/* the length of SSID */
++	u8 SSID[32];		/* SSID string */
++	s16 RSSI;		/* receive signal strength (in dBm) */
++	s16 SNR;		/* receive signal SNR in dB */
++	u16 beacon_period;	/* units are Kusec */
++	u16 chanspec;	/* Channel num, bw, ctrl_sb and band */
++	struct brcms_c_rateset rateset;	/* supported rates */
++};
++
++#define MAC80211_PROMISC_BCNS	(1 << 0)
++#define MAC80211_SCAN		(1 << 1)
++
++/*
++ * Public portion of common driver state structure.
++ * The wlc handle points at this.
++ */
++struct brcms_pub {
++	struct brcms_c_info *wlc;
++	struct ieee80211_hw *ieee_hw;
++	struct scb_ampdu *global_ampdu;
++	uint mac80211_state;
++	uint unit;		/* device instance number */
++	uint corerev;		/* core revision */
++	struct si_pub *sih;	/* SI handle (cookie for siutils calls) */
++	bool up;		/* interface up and running */
++	bool hw_off;		/* HW is off */
++	bool hw_up;		/* one time hw up/down */
++	bool _piomode;		/* true if pio mode */
++	uint _nbands;		/* # bands supported */
++	uint now;		/* # elapsed seconds */
++
++	bool delayed_down;	/* down delayed */
++	bool associated;	/* true:part of [I]BSS, false: not */
++	/* (union of stas_associated, aps_associated) */
++	bool _ampdu;		/* ampdu enabled or not */
++	u8 _n_enab;		/* bitmap of 11N + HT support */
++
++	u8 cur_etheraddr[ETH_ALEN];	/* our local ethernet address */
++
++	int bcmerror;		/* last bcm error */
++
++	u32 radio_disabled;	/* bit vector for radio disabled reasons */
++
++	u16 boardrev;	/* version # of particular board */
++	u8 sromrev;		/* version # of the srom */
++	char srom_ccode[BRCM_CNTRY_BUF_SZ];	/* Country Code in SROM */
++	u32 boardflags;	/* Board specific flags from srom */
++	u32 boardflags2;	/* More board flags if sromrev >= 4 */
++	bool phy_11ncapable;	/* the PHY/HW is capable of 802.11N */
++
++	struct wl_cnt *_cnt;	/* low-level counters in driver */
++};
++
++enum wlc_par_id {
++	IOV_MPC = 1,
++	IOV_RTSTHRESH,
++	IOV_QTXPOWER,
++	IOV_BCN_LI_BCN		/* Beacon listen interval in # of beacons */
++};
++
++/***********************************************
++ * Feature-related macros to optimize out code *
++ * *********************************************
++ */
++
++#define ENAB_1x1	0x01
++#define ENAB_2x2	0x02
++#define ENAB_3x3	0x04
++#define ENAB_4x4	0x08
++#define SUPPORT_11N	(ENAB_1x1|ENAB_2x2)
++#define SUPPORT_HT	(ENAB_1x1|ENAB_2x2|ENAB_3x3)
++
++/* WL11N Support */
++#define AMPDU_AGG_HOST	1
++
++/* pri is priority encoded in the packet. This maps the Packet priority to
++ * enqueue precedence as defined in wlc_prec_map
++ */
++extern const u8 wlc_prio2prec_map[];
++#define BRCMS_PRIO_TO_PREC(pri)	wlc_prio2prec_map[(pri) & 7]
++
++#define	BRCMS_PREC_COUNT	16	/* Max precedence level implemented */
++
++/* Mask to describe all precedence levels */
++#define BRCMS_PREC_BMP_ALL		MAXBITVAL(BRCMS_PREC_COUNT)
++
++/*
++ * This maps priority to one precedence higher - Used by PS-Poll response
++ * packets to simulate enqueue-at-head operation, but still maintain the
++ * order on the queue
++ */
++#define BRCMS_PRIO_TO_HI_PREC(pri)	min(BRCMS_PRIO_TO_PREC(pri) + 1,\
++					    BRCMS_PREC_COUNT - 1)
++
++/* Define a bitmap of precedences comprised by each AC */
++#define BRCMS_PREC_BMP_AC_BE	(NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_BE)) | \
++			NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_BE)) |	\
++			NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_EE)) |	\
++			NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_EE)))
++#define BRCMS_PREC_BMP_AC_BK	(NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_BK)) | \
++			NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_BK)) |	\
++			NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_NONE)) |	\
++			NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_NONE)))
++#define BRCMS_PREC_BMP_AC_VI	(NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_CL)) | \
++			NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_CL)) |	\
++			NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_VI)) |	\
++			NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_VI)))
++#define BRCMS_PREC_BMP_AC_VO	(NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_VO)) | \
++			NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_VO)) |	\
++			NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_NC)) |	\
++			NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_NC)))
++
++/* network protection config */
++#define	BRCMS_PROT_G_SPEC		1	/* SPEC g protection */
++#define	BRCMS_PROT_G_OVR		2	/* SPEC g prot override */
++#define	BRCMS_PROT_G_USER		3	/* gmode specified by user */
++#define	BRCMS_PROT_OVERLAP	4	/* overlap */
++#define	BRCMS_PROT_N_USER		10	/* nmode specified by user */
++#define	BRCMS_PROT_N_CFG		11	/* n protection */
++#define	BRCMS_PROT_N_CFG_OVR	12	/* n protection override */
++#define	BRCMS_PROT_N_NONGF	13	/* non-GF protection */
++#define	BRCMS_PROT_N_NONGF_OVR	14	/* non-GF protection override */
++#define	BRCMS_PROT_N_PAM_OVR	15	/* n preamble override */
++#define	BRCMS_PROT_N_OBSS		16	/* non-HT OBSS present */
++
++/*
++ * 54g modes (basic bits may still be overridden)
++ *
++ * GMODE_LEGACY_B
++ *	Rateset: 1b, 2b, 5.5, 11
++ *	Preamble: Long
++ *	Shortslot: Off
++ * GMODE_AUTO
++ *	Rateset: 1b, 2b, 5.5b, 11b, 18, 24, 36, 54
++ *	Extended Rateset: 6, 9, 12, 48
++ *	Preamble: Long
++ *	Shortslot: Auto
++ * GMODE_ONLY
++ *	Rateset: 1b, 2b, 5.5b, 11b, 18, 24b, 36, 54
++ *	Extended Rateset: 6b, 9, 12b, 48
++ *	Preamble: Short required
++ *	Shortslot: Auto
++ * GMODE_B_DEFERRED
++ *	Rateset: 1b, 2b, 5.5b, 11b, 18, 24, 36, 54
++ *	Extended Rateset: 6, 9, 12, 48
++ *	Preamble: Long
++ *	Shortslot: On
++ * GMODE_PERFORMANCE
++ *	Rateset: 1b, 2b, 5.5b, 6b, 9, 11b, 12b, 18, 24b, 36, 48, 54
++ *	Preamble: Short required
++ *	Shortslot: On and required
++ * GMODE_LRS
++ *	Rateset: 1b, 2b, 5.5b, 11b
++ *	Extended Rateset: 6, 9, 12, 18, 24, 36, 48, 54
++ *	Preamble: Long
++ *	Shortslot: Auto
++ */
++#define GMODE_LEGACY_B		0
++#define GMODE_AUTO		1
++#define GMODE_ONLY		2
++#define GMODE_B_DEFERRED	3
++#define GMODE_PERFORMANCE	4
++#define GMODE_LRS		5
++#define GMODE_MAX		6
++
++/* MCS values greater than this enable multiple streams */
++#define HIGHEST_SINGLE_STREAM_MCS	7
++
++#define	MAXBANDS		2	/* Maximum #of bands */
++
++/* max number of antenna configurations */
++#define ANT_SELCFG_MAX		4
++
++struct brcms_antselcfg {
++	u8 ant_config[ANT_SELCFG_MAX];	/* antenna configuration */
++	u8 num_antcfg;	/* number of available antenna configurations */
++};
++
++/* common functions for every port */
++extern struct brcms_c_info *
++brcms_c_attach(struct brcms_info *wl, struct bcma_device *core, uint unit,
++	       bool piomode, uint *perr);
++extern uint brcms_c_detach(struct brcms_c_info *wlc);
++extern int brcms_c_up(struct brcms_c_info *wlc);
++extern uint brcms_c_down(struct brcms_c_info *wlc);
++
++extern bool brcms_c_chipmatch(u16 vendor, u16 device);
++extern void brcms_c_init(struct brcms_c_info *wlc, bool mute_tx);
++extern void brcms_c_reset(struct brcms_c_info *wlc);
++
++extern void brcms_c_intrson(struct brcms_c_info *wlc);
++extern u32 brcms_c_intrsoff(struct brcms_c_info *wlc);
++extern void brcms_c_intrsrestore(struct brcms_c_info *wlc, u32 macintmask);
++extern bool brcms_c_intrsupd(struct brcms_c_info *wlc);
++extern bool brcms_c_isr(struct brcms_c_info *wlc, bool *wantdpc);
++extern bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded);
++extern void brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc,
++				     struct sk_buff *sdu,
++				     struct ieee80211_hw *hw);
++extern bool brcms_c_aggregatable(struct brcms_c_info *wlc, u8 tid);
++extern void brcms_c_protection_upd(struct brcms_c_info *wlc, uint idx,
++				   int val);
++extern int brcms_c_get_header_len(void);
++extern void brcms_c_set_addrmatch(struct brcms_c_info *wlc,
++				  int match_reg_offset,
++				  const u8 *addr);
++extern void brcms_c_wme_setparams(struct brcms_c_info *wlc, u16 aci,
++			      const struct ieee80211_tx_queue_params *arg,
++			      bool suspend);
++extern struct brcms_pub *brcms_c_pub(struct brcms_c_info *wlc);
++extern void brcms_c_ampdu_flush(struct brcms_c_info *wlc,
++			    struct ieee80211_sta *sta, u16 tid);
++extern void brcms_c_ampdu_tx_operational(struct brcms_c_info *wlc, u8 tid,
++					 u8 ba_wsize, uint max_rx_ampdu_bytes);
++extern int brcms_c_module_register(struct brcms_pub *pub,
++				   const char *name, struct brcms_info *hdl,
++				   int (*down_fn)(void *handle));
++extern int brcms_c_module_unregister(struct brcms_pub *pub, const char *name,
++				     struct brcms_info *hdl);
++extern void brcms_c_suspend_mac_and_wait(struct brcms_c_info *wlc);
++extern void brcms_c_enable_mac(struct brcms_c_info *wlc);
++extern void brcms_c_associate_upd(struct brcms_c_info *wlc, bool state);
++extern void brcms_c_scan_start(struct brcms_c_info *wlc);
++extern void brcms_c_scan_stop(struct brcms_c_info *wlc);
++extern int brcms_c_get_curband(struct brcms_c_info *wlc);
++extern void brcms_c_wait_for_tx_completion(struct brcms_c_info *wlc,
++					   bool drop);
++extern int brcms_c_set_channel(struct brcms_c_info *wlc, u16 channel);
++extern int brcms_c_set_rate_limit(struct brcms_c_info *wlc, u16 srl, u16 lrl);
++extern void brcms_c_get_current_rateset(struct brcms_c_info *wlc,
++				 struct brcm_rateset *currs);
++extern int brcms_c_set_rateset(struct brcms_c_info *wlc,
++					struct brcm_rateset *rs);
++extern int brcms_c_set_beacon_period(struct brcms_c_info *wlc, u16 period);
++extern u16 brcms_c_get_phy_type(struct brcms_c_info *wlc, int phyidx);
++extern void brcms_c_set_shortslot_override(struct brcms_c_info *wlc,
++				    s8 sslot_override);
++extern void brcms_c_set_beacon_listen_interval(struct brcms_c_info *wlc,
++					u8 interval);
++extern int brcms_c_set_tx_power(struct brcms_c_info *wlc, int txpwr);
++extern int brcms_c_get_tx_power(struct brcms_c_info *wlc);
++extern bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc);
++extern void brcms_c_mute(struct brcms_c_info *wlc, bool on);
++
++#endif				/* _BRCM_PUB_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/rate.c b/drivers/net/wireless/brcm80211/brcmsmac/rate.c
+new file mode 100644
+index 0000000..0a0c0ad
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/rate.c
+@@ -0,0 +1,514 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#include <brcmu_wifi.h>
++#include <brcmu_utils.h>
++
++#include "d11.h"
++#include "pub.h"
++#include "rate.h"
++
++/*
++ * Rate info per rate: It tells whether a rate is ofdm or not and its phy_rate
++ * value
++ */
++const u8 rate_info[BRCM_MAXRATE + 1] = {
++	/*  0     1     2     3     4     5     6     7     8     9 */
++/*   0 */ 0x00, 0x00, 0x0a, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00,
++/*  10 */ 0x00, 0x37, 0x8b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x00,
++/*  20 */ 0x00, 0x00, 0x6e, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x00, 0x00,
++/*  30 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00,
++/*  40 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x00,
++/*  50 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++/*  60 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++/*  70 */ 0x00, 0x00, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++/*  80 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++/*  90 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00,
++/* 100 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8c
++};
++
++/* rates are in units of Kbps */
++const struct brcms_mcs_info mcs_table[MCS_TABLE_SIZE] = {
++	/* MCS  0: SS 1, MOD: BPSK,  CR 1/2 */
++	{6500, 13500, CEIL(6500 * 10, 9), CEIL(13500 * 10, 9), 0x00,
++	 BRCM_RATE_6M},
++	/* MCS  1: SS 1, MOD: QPSK,  CR 1/2 */
++	{13000, 27000, CEIL(13000 * 10, 9), CEIL(27000 * 10, 9), 0x08,
++	 BRCM_RATE_12M},
++	/* MCS  2: SS 1, MOD: QPSK,  CR 3/4 */
++	{19500, 40500, CEIL(19500 * 10, 9), CEIL(40500 * 10, 9), 0x0A,
++	 BRCM_RATE_18M},
++	/* MCS  3: SS 1, MOD: 16QAM, CR 1/2 */
++	{26000, 54000, CEIL(26000 * 10, 9), CEIL(54000 * 10, 9), 0x10,
++	 BRCM_RATE_24M},
++	/* MCS  4: SS 1, MOD: 16QAM, CR 3/4 */
++	{39000, 81000, CEIL(39000 * 10, 9), CEIL(81000 * 10, 9), 0x12,
++	 BRCM_RATE_36M},
++	/* MCS  5: SS 1, MOD: 64QAM, CR 2/3 */
++	{52000, 108000, CEIL(52000 * 10, 9), CEIL(108000 * 10, 9), 0x19,
++	 BRCM_RATE_48M},
++	/* MCS  6: SS 1, MOD: 64QAM, CR 3/4 */
++	{58500, 121500, CEIL(58500 * 10, 9), CEIL(121500 * 10, 9), 0x1A,
++	 BRCM_RATE_54M},
++	/* MCS  7: SS 1, MOD: 64QAM, CR 5/6 */
++	{65000, 135000, CEIL(65000 * 10, 9), CEIL(135000 * 10, 9), 0x1C,
++	 BRCM_RATE_54M},
++	/* MCS  8: SS 2, MOD: BPSK,  CR 1/2 */
++	{13000, 27000, CEIL(13000 * 10, 9), CEIL(27000 * 10, 9), 0x40,
++	 BRCM_RATE_6M},
++	/* MCS  9: SS 2, MOD: QPSK,  CR 1/2 */
++	{26000, 54000, CEIL(26000 * 10, 9), CEIL(54000 * 10, 9), 0x48,
++	 BRCM_RATE_12M},
++	/* MCS 10: SS 2, MOD: QPSK,  CR 3/4 */
++	{39000, 81000, CEIL(39000 * 10, 9), CEIL(81000 * 10, 9), 0x4A,
++	 BRCM_RATE_18M},
++	/* MCS 11: SS 2, MOD: 16QAM, CR 1/2 */
++	{52000, 108000, CEIL(52000 * 10, 9), CEIL(108000 * 10, 9), 0x50,
++	 BRCM_RATE_24M},
++	/* MCS 12: SS 2, MOD: 16QAM, CR 3/4 */
++	{78000, 162000, CEIL(78000 * 10, 9), CEIL(162000 * 10, 9), 0x52,
++	 BRCM_RATE_36M},
++	/* MCS 13: SS 2, MOD: 64QAM, CR 2/3 */
++	{104000, 216000, CEIL(104000 * 10, 9), CEIL(216000 * 10, 9), 0x59,
++	 BRCM_RATE_48M},
++	/* MCS 14: SS 2, MOD: 64QAM, CR 3/4 */
++	{117000, 243000, CEIL(117000 * 10, 9), CEIL(243000 * 10, 9), 0x5A,
++	 BRCM_RATE_54M},
++	/* MCS 15: SS 2, MOD: 64QAM, CR 5/6 */
++	{130000, 270000, CEIL(130000 * 10, 9), CEIL(270000 * 10, 9), 0x5C,
++	 BRCM_RATE_54M},
++	/* MCS 16: SS 3, MOD: BPSK,  CR 1/2 */
++	{19500, 40500, CEIL(19500 * 10, 9), CEIL(40500 * 10, 9), 0x80,
++	 BRCM_RATE_6M},
++	/* MCS 17: SS 3, MOD: QPSK,  CR 1/2 */
++	{39000, 81000, CEIL(39000 * 10, 9), CEIL(81000 * 10, 9), 0x88,
++	 BRCM_RATE_12M},
++	/* MCS 18: SS 3, MOD: QPSK,  CR 3/4 */
++	{58500, 121500, CEIL(58500 * 10, 9), CEIL(121500 * 10, 9), 0x8A,
++	 BRCM_RATE_18M},
++	/* MCS 19: SS 3, MOD: 16QAM, CR 1/2 */
++	{78000, 162000, CEIL(78000 * 10, 9), CEIL(162000 * 10, 9), 0x90,
++	 BRCM_RATE_24M},
++	/* MCS 20: SS 3, MOD: 16QAM, CR 3/4 */
++	{117000, 243000, CEIL(117000 * 10, 9), CEIL(243000 * 10, 9), 0x92,
++	 BRCM_RATE_36M},
++	/* MCS 21: SS 3, MOD: 64QAM, CR 2/3 */
++	{156000, 324000, CEIL(156000 * 10, 9), CEIL(324000 * 10, 9), 0x99,
++	 BRCM_RATE_48M},
++	/* MCS 22: SS 3, MOD: 64QAM, CR 3/4 */
++	{175500, 364500, CEIL(175500 * 10, 9), CEIL(364500 * 10, 9), 0x9A,
++	 BRCM_RATE_54M},
++	/* MCS 23: SS 3, MOD: 64QAM, CR 5/6 */
++	{195000, 405000, CEIL(195000 * 10, 9), CEIL(405000 * 10, 9), 0x9B,
++	 BRCM_RATE_54M},
++	/* MCS 24: SS 4, MOD: BPSK,  CR 1/2 */
++	{26000, 54000, CEIL(26000 * 10, 9), CEIL(54000 * 10, 9), 0xC0,
++	 BRCM_RATE_6M},
++	/* MCS 25: SS 4, MOD: QPSK,  CR 1/2 */
++	{52000, 108000, CEIL(52000 * 10, 9), CEIL(108000 * 10, 9), 0xC8,
++	 BRCM_RATE_12M},
++	/* MCS 26: SS 4, MOD: QPSK,  CR 3/4 */
++	{78000, 162000, CEIL(78000 * 10, 9), CEIL(162000 * 10, 9), 0xCA,
++	 BRCM_RATE_18M},
++	/* MCS 27: SS 4, MOD: 16QAM, CR 1/2 */
++	{104000, 216000, CEIL(104000 * 10, 9), CEIL(216000 * 10, 9), 0xD0,
++	 BRCM_RATE_24M},
++	/* MCS 28: SS 4, MOD: 16QAM, CR 3/4 */
++	{156000, 324000, CEIL(156000 * 10, 9), CEIL(324000 * 10, 9), 0xD2,
++	 BRCM_RATE_36M},
++	/* MCS 29: SS 4, MOD: 64QAM, CR 2/3 */
++	{208000, 432000, CEIL(208000 * 10, 9), CEIL(432000 * 10, 9), 0xD9,
++	 BRCM_RATE_48M},
++	/* MCS 30: SS 4, MOD: 64QAM, CR 3/4 */
++	{234000, 486000, CEIL(234000 * 10, 9), CEIL(486000 * 10, 9), 0xDA,
++	 BRCM_RATE_54M},
++	/* MCS 31: SS 4, MOD: 64QAM, CR 5/6 */
++	{260000, 540000, CEIL(260000 * 10, 9), CEIL(540000 * 10, 9), 0xDB,
++	 BRCM_RATE_54M},
++	/* MCS 32: SS 1, MOD: BPSK,  CR 1/2 */
++	{0, 6000, 0, CEIL(6000 * 10, 9), 0x00, BRCM_RATE_6M},
++};
++
++/*
++ * phycfg for legacy OFDM frames: code rate, modulation scheme, spatial streams
++ * Number of spatial streams: always 1 other fields: refer to table 78 of
++ * section 17.3.2.2 of the original .11a standard
++ */
++struct legacy_phycfg {
++	u32 rate_ofdm;	/* ofdm mac rate */
++	/* phy ctl byte 3, code rate, modulation type, # of streams */
++	u8 tx_phy_ctl3;
++};
++
++/* Number of legacy_rate_cfg entries in the table */
++#define LEGACY_PHYCFG_TABLE_SIZE	12
++
++/*
++ * In CCK mode LPPHY overloads OFDM Modulation bits with CCK Data Rate
++ * Eventually MIMOPHY would also be converted to this format
++ * 0 = 1Mbps; 1 = 2Mbps; 2 = 5.5Mbps; 3 = 11Mbps
++ */
++static const struct
++legacy_phycfg legacy_phycfg_table[LEGACY_PHYCFG_TABLE_SIZE] = {
++	{BRCM_RATE_1M, 0x00},	/* CCK  1Mbps,  data rate  0 */
++	{BRCM_RATE_2M, 0x08},	/* CCK  2Mbps,  data rate  1 */
++	{BRCM_RATE_5M5, 0x10},	/* CCK  5.5Mbps,  data rate  2 */
++	{BRCM_RATE_11M, 0x18},	/* CCK  11Mbps,  data rate   3 */
++	/* OFDM  6Mbps,  code rate 1/2, BPSK,   1 spatial stream */
++	{BRCM_RATE_6M, 0x00},
++	/* OFDM  9Mbps,  code rate 3/4, BPSK,   1 spatial stream */
++	{BRCM_RATE_9M, 0x02},
++	/* OFDM  12Mbps, code rate 1/2, QPSK,   1 spatial stream */
++	{BRCM_RATE_12M, 0x08},
++	/* OFDM  18Mbps, code rate 3/4, QPSK,   1 spatial stream */
++	{BRCM_RATE_18M, 0x0A},
++	/* OFDM  24Mbps, code rate 1/2, 16-QAM, 1 spatial stream */
++	{BRCM_RATE_24M, 0x10},
++	/* OFDM  36Mbps, code rate 3/4, 16-QAM, 1 spatial stream */
++	{BRCM_RATE_36M, 0x12},
++	/* OFDM  48Mbps, code rate 2/3, 64-QAM, 1 spatial stream */
++	{BRCM_RATE_48M, 0x19},
++	/* OFDM  54Mbps, code rate 3/4, 64-QAM, 1 spatial stream */
++	{BRCM_RATE_54M, 0x1A},
++};
++
++/* Hardware rates (also encodes default basic rates) */
++
++const struct brcms_c_rateset cck_ofdm_mimo_rates = {
++	12,
++	/*  1b,   2b,   5.5b, 6,    9,    11b,  12,   18,   24,   36,   48, */
++	{ 0x82, 0x84, 0x8b, 0x0c, 0x12, 0x96, 0x18, 0x24, 0x30, 0x48, 0x60,
++	/* 54 Mbps */
++	  0x6c},
++	0x00,
++	{ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	  0x00, 0x00, 0x00, 0x00, 0x00}
++};
++
++const struct brcms_c_rateset ofdm_mimo_rates = {
++	8,
++	/*  6b,   9,    12b,  18,   24b,  36,   48,   54 Mbps */
++	{ 0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c},
++	0x00,
++	{ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	  0x00, 0x00, 0x00, 0x00, 0x00}
++};
++
++/* Default ratesets that include MCS32 for 40BW channels */
++static const struct brcms_c_rateset cck_ofdm_40bw_mimo_rates = {
++	12,
++	/*  1b,   2b,   5.5b, 6,    9,    11b,  12,   18,   24,   36,   48 */
++	{ 0x82, 0x84, 0x8b, 0x0c, 0x12, 0x96, 0x18, 0x24, 0x30, 0x48, 0x60,
++	/* 54 Mbps */
++	  0x6c},
++	0x00,
++	{ 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	  0x00, 0x00, 0x00, 0x00, 0x00}
++};
++
++static const struct brcms_c_rateset ofdm_40bw_mimo_rates = {
++	8,
++	/*  6b,   9,    12b,  18,   24b,  36,   48,   54 Mbps */
++	{ 0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c},
++	0x00,
++	{ 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	  0x00, 0x00, 0x00, 0x00, 0x00}
++};
++
++const struct brcms_c_rateset cck_ofdm_rates = {
++	12,
++	/*  1b,   2b, 5.5b, 6,    9,    11b,  12,   18,   24,   36,   48,*/
++	{ 0x82, 0x84, 0x8b, 0x0c, 0x12, 0x96, 0x18, 0x24, 0x30, 0x48, 0x60,
++	/*54 Mbps */
++	  0x6c},
++	0x00,
++	{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	  0x00, 0x00, 0x00, 0x00, 0x00}
++};
++
++const struct brcms_c_rateset gphy_legacy_rates = {
++	4,
++	/*  1b,   2b,   5.5b, 11b Mbps */
++	{ 0x82, 0x84, 0x8b, 0x96},
++	0x00,
++	{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	  0x00, 0x00, 0x00, 0x00, 0x00}
++};
++
++const struct brcms_c_rateset ofdm_rates = {
++	8,
++	/*  6b,   9,    12b,  18,   24b,  36,   48,   54 Mbps */
++	{ 0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c},
++	0x00,
++	{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	  0x00, 0x00, 0x00, 0x00, 0x00}
++};
++
++const struct brcms_c_rateset cck_rates = {
++	4,
++	/*  1b,   2b,   5.5,  11 Mbps */
++	{ 0x82, 0x84, 0x0b, 0x16},
++	0x00,
++	{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	  0x00, 0x00, 0x00, 0x00, 0x00}
++};
++
++/* check if rateset is valid.
++ * if check_brate is true, rateset without a basic rate is considered NOT valid.
++ */
++static bool brcms_c_rateset_valid(struct brcms_c_rateset *rs, bool check_brate)
++{
++	uint idx;
++
++	if (!rs->count)
++		return false;
++
++	if (!check_brate)
++		return true;
++
++	/* error if no basic rates */
++	for (idx = 0; idx < rs->count; idx++) {
++		if (rs->rates[idx] & BRCMS_RATE_FLAG)
++			return true;
++	}
++	return false;
++}
++
++void brcms_c_rateset_mcs_upd(struct brcms_c_rateset *rs, u8 txstreams)
++{
++	int i;
++	for (i = txstreams; i < MAX_STREAMS_SUPPORTED; i++)
++		rs->mcs[i] = 0;
++}
++
++/*
++ * filter based on hardware rateset, and sort filtered rateset with basic
++ * bit(s) preserved, and check if resulting rateset is valid.
++*/
++bool
++brcms_c_rate_hwrs_filter_sort_validate(struct brcms_c_rateset *rs,
++				   const struct brcms_c_rateset *hw_rs,
++				   bool check_brate, u8 txstreams)
++{
++	u8 rateset[BRCM_MAXRATE + 1];
++	u8 r;
++	uint count;
++	uint i;
++
++	memset(rateset, 0, sizeof(rateset));
++	count = rs->count;
++
++	for (i = 0; i < count; i++) {
++		/* mask off "basic rate" bit, BRCMS_RATE_FLAG */
++		r = (int)rs->rates[i] & BRCMS_RATE_MASK;
++		if ((r > BRCM_MAXRATE) || (rate_info[r] == 0))
++			continue;
++		rateset[r] = rs->rates[i];	/* preserve basic bit! */
++	}
++
++	/* fill out the rates in order, looking at only supported rates */
++	count = 0;
++	for (i = 0; i < hw_rs->count; i++) {
++		r = hw_rs->rates[i] & BRCMS_RATE_MASK;
++		if (rateset[r])
++			rs->rates[count++] = rateset[r];
++	}
++
++	rs->count = count;
++
++	/* only set the mcs rate bit if the equivalent hw mcs bit is set */
++	for (i = 0; i < MCSSET_LEN; i++)
++		rs->mcs[i] = (rs->mcs[i] & hw_rs->mcs[i]);
++
++	if (brcms_c_rateset_valid(rs, check_brate))
++		return true;
++	else
++		return false;
++}
++
++/* calculate the rate of a rx'd frame and return it as a ratespec */
++u32 brcms_c_compute_rspec(struct d11rxhdr *rxh, u8 *plcp)
++{
++	int phy_type;
++	u32 rspec = PHY_TXC1_BW_20MHZ << RSPEC_BW_SHIFT;
++
++	phy_type =
++	    ((rxh->RxChan & RXS_CHAN_PHYTYPE_MASK) >> RXS_CHAN_PHYTYPE_SHIFT);
++
++	if ((phy_type == PHY_TYPE_N) || (phy_type == PHY_TYPE_SSN) ||
++	    (phy_type == PHY_TYPE_LCN) || (phy_type == PHY_TYPE_HT)) {
++		switch (rxh->PhyRxStatus_0 & PRXS0_FT_MASK) {
++		case PRXS0_CCK:
++			rspec =
++				cck_phy2mac_rate(
++				((struct cck_phy_hdr *) plcp)->signal);
++			break;
++		case PRXS0_OFDM:
++			rspec =
++			    ofdm_phy2mac_rate(
++				((struct ofdm_phy_hdr *) plcp)->rlpt[0]);
++			break;
++		case PRXS0_PREN:
++			rspec = (plcp[0] & MIMO_PLCP_MCS_MASK) | RSPEC_MIMORATE;
++			if (plcp[0] & MIMO_PLCP_40MHZ) {
++				/* indicate rspec is for 40 MHz mode */
++				rspec &= ~RSPEC_BW_MASK;
++				rspec |= (PHY_TXC1_BW_40MHZ << RSPEC_BW_SHIFT);
++			}
++			break;
++		case PRXS0_STDN:
++			/* fallthru */
++		default:
++			/* not supported, error condition */
++			break;
++		}
++		if (plcp3_issgi(plcp[3]))
++			rspec |= RSPEC_SHORT_GI;
++	} else
++	    if ((phy_type == PHY_TYPE_A) || (rxh->PhyRxStatus_0 & PRXS0_OFDM))
++		rspec = ofdm_phy2mac_rate(
++				((struct ofdm_phy_hdr *) plcp)->rlpt[0]);
++	else
++		rspec = cck_phy2mac_rate(
++				((struct cck_phy_hdr *) plcp)->signal);
++
++	return rspec;
++}
++
++/* copy rateset src to dst as-is (no masking or sorting) */
++void brcms_c_rateset_copy(const struct brcms_c_rateset *src,
++			  struct brcms_c_rateset *dst)
++{
++	memcpy(dst, src, sizeof(struct brcms_c_rateset));
++}
++
++/*
++ * Copy and selectively filter one rateset to another.
++ * 'basic_only' means only copy basic rates.
++ * 'rates' indicates cck (11b) and ofdm rates combinations.
++ *    - 0: cck and ofdm
++ *    - 1: cck only
++ *    - 2: ofdm only
++ * 'xmask' is the copy mask (typically 0x7f or 0xff).
++ */
++void
++brcms_c_rateset_filter(struct brcms_c_rateset *src, struct brcms_c_rateset *dst,
++		       bool basic_only, u8 rates, uint xmask, bool mcsallow)
++{
++	uint i;
++	uint r;
++	uint count;
++
++	count = 0;
++	for (i = 0; i < src->count; i++) {
++		r = src->rates[i];
++		if (basic_only && !(r & BRCMS_RATE_FLAG))
++			continue;
++		if (rates == BRCMS_RATES_CCK &&
++		    is_ofdm_rate((r & BRCMS_RATE_MASK)))
++			continue;
++		if (rates == BRCMS_RATES_OFDM &&
++		    is_cck_rate((r & BRCMS_RATE_MASK)))
++			continue;
++		dst->rates[count++] = r & xmask;
++	}
++	dst->count = count;
++	dst->htphy_membership = src->htphy_membership;
++
++	if (mcsallow && rates != BRCMS_RATES_CCK)
++		memcpy(&dst->mcs[0], &src->mcs[0], MCSSET_LEN);
++	else
++		brcms_c_rateset_mcs_clear(dst);
++}
++
++/* select rateset for a given phy_type and bandtype and filter it, sort it
++ * and fill rs_tgt with result
++ */
++void
++brcms_c_rateset_default(struct brcms_c_rateset *rs_tgt,
++			const struct brcms_c_rateset *rs_hw,
++			uint phy_type, int bandtype, bool cck_only,
++			uint rate_mask, bool mcsallow, u8 bw, u8 txstreams)
++{
++	const struct brcms_c_rateset *rs_dflt;
++	struct brcms_c_rateset rs_sel;
++	if ((PHYTYPE_IS(phy_type, PHY_TYPE_HT)) ||
++	    (PHYTYPE_IS(phy_type, PHY_TYPE_N)) ||
++	    (PHYTYPE_IS(phy_type, PHY_TYPE_LCN)) ||
++	    (PHYTYPE_IS(phy_type, PHY_TYPE_SSN))) {
++		if (bandtype == BRCM_BAND_5G)
++			rs_dflt = (bw == BRCMS_20_MHZ ?
++				   &ofdm_mimo_rates : &ofdm_40bw_mimo_rates);
++		else
++			rs_dflt = (bw == BRCMS_20_MHZ ?
++				   &cck_ofdm_mimo_rates :
++				   &cck_ofdm_40bw_mimo_rates);
++	} else if (PHYTYPE_IS(phy_type, PHY_TYPE_LP)) {
++		rs_dflt = (bandtype == BRCM_BAND_5G) ?
++			  &ofdm_rates : &cck_ofdm_rates;
++	} else if (PHYTYPE_IS(phy_type, PHY_TYPE_A)) {
++		rs_dflt = &ofdm_rates;
++	} else if (PHYTYPE_IS(phy_type, PHY_TYPE_G)) {
++		rs_dflt = &cck_ofdm_rates;
++	} else {
++		/* should not happen, error condition */
++		rs_dflt = &cck_rates;	/* force cck */
++	}
++
++	/* if hw rateset is not supplied, assign selected rateset to it */
++	if (!rs_hw)
++		rs_hw = rs_dflt;
++
++	brcms_c_rateset_copy(rs_dflt, &rs_sel);
++	brcms_c_rateset_mcs_upd(&rs_sel, txstreams);
++	brcms_c_rateset_filter(&rs_sel, rs_tgt, false,
++			   cck_only ? BRCMS_RATES_CCK : BRCMS_RATES_CCK_OFDM,
++			   rate_mask, mcsallow);
++	brcms_c_rate_hwrs_filter_sort_validate(rs_tgt, rs_hw, false,
++					   mcsallow ? txstreams : 1);
++}
++
++s16 brcms_c_rate_legacy_phyctl(uint rate)
++{
++	uint i;
++	for (i = 0; i < LEGACY_PHYCFG_TABLE_SIZE; i++)
++		if (rate == legacy_phycfg_table[i].rate_ofdm)
++			return legacy_phycfg_table[i].tx_phy_ctl3;
++
++	return -1;
++}
++
++void brcms_c_rateset_mcs_clear(struct brcms_c_rateset *rateset)
++{
++	uint i;
++	for (i = 0; i < MCSSET_LEN; i++)
++		rateset->mcs[i] = 0;
++}
++
++void brcms_c_rateset_mcs_build(struct brcms_c_rateset *rateset, u8 txstreams)
++{
++	memcpy(&rateset->mcs[0], &cck_ofdm_mimo_rates.mcs[0], MCSSET_LEN);
++	brcms_c_rateset_mcs_upd(rateset, txstreams);
++}
++
++/* Based on bandwidth passed, allow/disallow MCS 32 in the rateset */
++void brcms_c_rateset_bw_mcs_filter(struct brcms_c_rateset *rateset, u8 bw)
++{
++	if (bw == BRCMS_40_MHZ)
++		setbit(rateset->mcs, 32);
++	else
++		clrbit(rateset->mcs, 32);
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/rate.h b/drivers/net/wireless/brcm80211/brcmsmac/rate.h
+new file mode 100644
+index 0000000..980d578
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/rate.h
+@@ -0,0 +1,249 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef _BRCM_RATE_H_
++#define _BRCM_RATE_H_
++
++#include "types.h"
++#include "d11.h"
++#include "phy_hal.h"
++
++extern const u8 rate_info[];
++extern const struct brcms_c_rateset cck_ofdm_mimo_rates;
++extern const struct brcms_c_rateset ofdm_mimo_rates;
++extern const struct brcms_c_rateset cck_ofdm_rates;
++extern const struct brcms_c_rateset ofdm_rates;
++extern const struct brcms_c_rateset cck_rates;
++extern const struct brcms_c_rateset gphy_legacy_rates;
++extern const struct brcms_c_rateset rate_limit_1_2;
++
++struct brcms_mcs_info {
++	/* phy rate in kbps [20Mhz] */
++	u32 phy_rate_20;
++	/* phy rate in kbps [40Mhz] */
++	u32 phy_rate_40;
++	/* phy rate in kbps [20Mhz] with SGI */
++	u32 phy_rate_20_sgi;
++	/* phy rate in kbps [40Mhz] with SGI */
++	u32 phy_rate_40_sgi;
++	/* phy ctl byte 3, code rate, modulation type, # of streams */
++	u8 tx_phy_ctl3;
++	/* matching legacy ofdm rate in 500bkps */
++	u8 leg_ofdm;
++};
++
++#define BRCMS_MAXMCS	32	/* max valid mcs index */
++#define MCS_TABLE_SIZE	33	/* Number of mcs entries in the table */
++extern const struct brcms_mcs_info mcs_table[];
++
++#define MCS_TXS_MASK	0xc0	/* num tx streams - 1 bit mask */
++#define MCS_TXS_SHIFT	6	/* num tx streams - 1 bit shift */
++
++/* returns num tx streams - 1 */
++static inline u8 mcs_2_txstreams(u8 mcs)
++{
++	return (mcs_table[mcs].tx_phy_ctl3 & MCS_TXS_MASK) >> MCS_TXS_SHIFT;
++}
++
++static inline uint mcs_2_rate(u8 mcs, bool is40, bool sgi)
++{
++	if (sgi) {
++		if (is40)
++			return mcs_table[mcs].phy_rate_40_sgi;
++		return mcs_table[mcs].phy_rate_20_sgi;
++	}
++	if (is40)
++		return mcs_table[mcs].phy_rate_40;
++
++	return mcs_table[mcs].phy_rate_20;
++}
++
++/* Macro to use the rate_info table */
++#define	BRCMS_RATE_MASK_FULL 0xff /* Rate value mask with basic rate flag */
++
++/*
++ * rate spec : holds rate and mode specific information required to generate a
++ * tx frame. Legacy CCK and OFDM information is held in the same manner as was
++ * done in the past (in the lower byte) the upper 3 bytes primarily hold MIMO
++ * specific information
++ */
++
++/* rate spec bit fields */
++
++/* Either 500Kbps units or MIMO MCS idx */
++#define RSPEC_RATE_MASK		0x0000007F
++/* mimo MCS is stored in RSPEC_RATE_MASK */
++#define RSPEC_MIMORATE		0x08000000
++/* mimo bw mask */
++#define RSPEC_BW_MASK		0x00000700
++/* mimo bw shift */
++#define RSPEC_BW_SHIFT		8
++/* mimo Space/Time/Frequency mode mask */
++#define RSPEC_STF_MASK		0x00003800
++/* mimo Space/Time/Frequency mode shift */
++#define RSPEC_STF_SHIFT		11
++/* mimo coding type mask */
++#define RSPEC_CT_MASK		0x0000C000
++/* mimo coding type shift */
++#define RSPEC_CT_SHIFT		14
++/* mimo num STC streams per PLCP defn. */
++#define RSPEC_STC_MASK		0x00300000
++/* mimo num STC streams per PLCP defn. */
++#define RSPEC_STC_SHIFT		20
++/* mimo bit indicates adv coding in use */
++#define RSPEC_LDPC_CODING	0x00400000
++/* mimo bit indicates short GI in use */
++#define RSPEC_SHORT_GI		0x00800000
++/* bit indicates override both rate & mode */
++#define RSPEC_OVERRIDE		0x80000000
++/* bit indicates override rate only */
++#define RSPEC_OVERRIDE_MCS_ONLY 0x40000000
++
++static inline bool rspec_active(u32 rspec)
++{
++	return rspec & (RSPEC_RATE_MASK | RSPEC_MIMORATE);
++}
++
++static inline u8 rspec_phytxbyte2(u32 rspec)
++{
++	return (rspec & 0xff00) >> 8;
++}
++
++static inline u32 rspec_get_bw(u32 rspec)
++{
++	return (rspec & RSPEC_BW_MASK) >> RSPEC_BW_SHIFT;
++}
++
++static inline bool rspec_issgi(u32 rspec)
++{
++	return (rspec & RSPEC_SHORT_GI) == RSPEC_SHORT_GI;
++}
++
++static inline bool rspec_is40mhz(u32 rspec)
++{
++	u32 bw = rspec_get_bw(rspec);
++
++	return bw == PHY_TXC1_BW_40MHZ || bw == PHY_TXC1_BW_40MHZ_DUP;
++}
++
++static inline uint rspec2rate(u32 rspec)
++{
++	if (rspec & RSPEC_MIMORATE)
++		return mcs_2_rate(rspec & RSPEC_RATE_MASK, rspec_is40mhz(rspec),
++				  rspec_issgi(rspec));
++	return rspec & RSPEC_RATE_MASK;
++}
++
++static inline u8 rspec_mimoplcp3(u32 rspec)
++{
++	return (rspec & 0xf00000) >> 16;
++}
++
++static inline bool plcp3_issgi(u8 plcp)
++{
++	return (plcp & (RSPEC_SHORT_GI >> 16)) != 0;
++}
++
++static inline uint rspec_stc(u32 rspec)
++{
++	return (rspec & RSPEC_STC_MASK) >> RSPEC_STC_SHIFT;
++}
++
++static inline uint rspec_stf(u32 rspec)
++{
++	return (rspec & RSPEC_STF_MASK) >> RSPEC_STF_SHIFT;
++}
++
++static inline bool is_mcs_rate(u32 ratespec)
++{
++	return (ratespec & RSPEC_MIMORATE) != 0;
++}
++
++static inline bool is_ofdm_rate(u32 ratespec)
++{
++	return !is_mcs_rate(ratespec) &&
++	       (rate_info[ratespec & RSPEC_RATE_MASK] & BRCMS_RATE_FLAG);
++}
++
++static inline bool is_cck_rate(u32 ratespec)
++{
++	u32 rate = (ratespec & BRCMS_RATE_MASK);
++
++	return !is_mcs_rate(ratespec) && (
++			rate == BRCM_RATE_1M || rate == BRCM_RATE_2M ||
++			rate == BRCM_RATE_5M5 || rate == BRCM_RATE_11M);
++}
++
++static inline bool is_single_stream(u8 mcs)
++{
++	return mcs <= HIGHEST_SINGLE_STREAM_MCS || mcs == 32;
++}
++
++static inline u8 cck_rspec(u8 cck)
++{
++	return cck & RSPEC_RATE_MASK;
++}
++
++/* Convert encoded rate value in plcp header to numerical rates in 500 KHz
++ * increments */
++static inline u8 ofdm_phy2mac_rate(u8 rlpt)
++{
++	return wlc_phy_get_ofdm_rate_lookup()[rlpt & 0x7];
++}
++
++static inline u8 cck_phy2mac_rate(u8 signal)
++{
++	return signal/5;
++}
++
++/* Rates specified in brcms_c_rateset_filter() */
++#define BRCMS_RATES_CCK_OFDM	0
++#define BRCMS_RATES_CCK		1
++#define BRCMS_RATES_OFDM		2
++
++/* sanitize, and sort a rateset with the basic bit(s) preserved, validate
++ * rateset */
++extern bool
++brcms_c_rate_hwrs_filter_sort_validate(struct brcms_c_rateset *rs,
++				       const struct brcms_c_rateset *hw_rs,
++				       bool check_brate, u8 txstreams);
++/* copy rateset src to dst as-is (no masking or sorting) */
++extern void brcms_c_rateset_copy(const struct brcms_c_rateset *src,
++			     struct brcms_c_rateset *dst);
++
++/* would be nice to have these documented ... */
++extern u32 brcms_c_compute_rspec(struct d11rxhdr *rxh, u8 *plcp);
++
++extern void brcms_c_rateset_filter(struct brcms_c_rateset *src,
++	struct brcms_c_rateset *dst, bool basic_only, u8 rates, uint xmask,
++	bool mcsallow);
++
++extern void
++brcms_c_rateset_default(struct brcms_c_rateset *rs_tgt,
++			const struct brcms_c_rateset *rs_hw, uint phy_type,
++			int bandtype, bool cck_only, uint rate_mask,
++			bool mcsallow, u8 bw, u8 txstreams);
++
++extern s16 brcms_c_rate_legacy_phyctl(uint rate);
++
++extern void brcms_c_rateset_mcs_upd(struct brcms_c_rateset *rs, u8 txstreams);
++extern void brcms_c_rateset_mcs_clear(struct brcms_c_rateset *rateset);
++extern void brcms_c_rateset_mcs_build(struct brcms_c_rateset *rateset,
++				      u8 txstreams);
++extern void brcms_c_rateset_bw_mcs_filter(struct brcms_c_rateset *rateset,
++					  u8 bw);
++
++#endif				/* _BRCM_RATE_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/scb.h b/drivers/net/wireless/brcm80211/brcmsmac/scb.h
+new file mode 100644
+index 0000000..51c79c7
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/scb.h
+@@ -0,0 +1,82 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef _BRCM_SCB_H_
++#define _BRCM_SCB_H_
++
++#include <linux/if_ether.h>
++#include <brcmu_utils.h>
++#include <defs.h>
++#include "types.h"
++
++#define AMPDU_TX_BA_MAX_WSIZE	64	/* max Tx ba window size (in pdu) */
++
++#define AMPDU_MAX_SCB_TID	NUMPRIO
++
++/* scb flags */
++#define SCB_WMECAP		0x0040
++#define SCB_HTCAP		0x10000	/* HT (MIMO) capable device */
++#define SCB_IS40		0x80000	/* 40MHz capable */
++#define SCB_STBCCAP		0x40000000	/* STBC Capable */
++
++#define SCB_MAGIC	0xbeefcafe
++
++/* structure to store per-tid state for the ampdu initiator */
++struct scb_ampdu_tid_ini {
++	u8 tx_in_transit; /* number of pending mpdus in transit in driver */
++	u8 tid;		  /* initiator tid for easy lookup */
++	/* tx retry count; indexed by seq modulo */
++	u8 txretry[AMPDU_TX_BA_MAX_WSIZE];
++	struct scb *scb;  /* backptr for easy lookup */
++	u8 ba_wsize;	  /* negotiated ba window size (in pdu) */
++};
++
++struct scb_ampdu {
++	struct scb *scb;	/* back pointer for easy reference */
++	u8 mpdu_density;	/* mpdu density */
++	u8 max_pdu;		/* max pdus allowed in ampdu */
++	u8 release;		/* # of mpdus released at a time */
++	u16 min_len;		/* min mpdu len to support the density */
++	u32 max_rx_ampdu_bytes;	/* max ampdu rcv length; 8k, 16k, 32k, 64k */
++
++	/*
++	 * This could easily be a ini[] pointer and we keep this info in wl
++	 * itself instead of having mac80211 hold it for us. Also could be made
++	 * dynamic per tid instead of static.
++	 */
++	/* initiator info - per tid (NUMPRIO): */
++	struct scb_ampdu_tid_ini ini[AMPDU_MAX_SCB_TID];
++};
++
++/* station control block - one per remote MAC address */
++struct scb {
++	u32 magic;
++	u32 flags;	/* various bit flags as defined below */
++	u32 flags2;	/* various bit flags2 as defined below */
++	u8 state;	/* current state bitfield of auth/assoc process */
++	u8 ea[ETH_ALEN];	/* station address */
++	uint fragresid[NUMPRIO];/* #bytes unused in frag buffer per prio */
++
++	u16 seqctl[NUMPRIO];	/* seqctl of last received frame (for dups) */
++	/* seqctl of last received frame (for dups) for non-QoS data and
++	 * management */
++	u16 seqctl_nonqos;
++	u16 seqnum[NUMPRIO];/* WME: driver maintained sw seqnum per priority */
++
++	struct scb_ampdu scb_ampdu;	/* AMPDU state including per tid info */
++};
++
++#endif				/* _BRCM_SCB_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/stf.c b/drivers/net/wireless/brcm80211/brcmsmac/stf.c
+new file mode 100644
+index 0000000..ed1d1aa
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/stf.c
+@@ -0,0 +1,438 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#include <net/mac80211.h>
++
++#include "types.h"
++#include "d11.h"
++#include "rate.h"
++#include "phy/phy_hal.h"
++#include "channel.h"
++#include "main.h"
++#include "stf.h"
++
++#define MIN_SPATIAL_EXPANSION	0
++#define MAX_SPATIAL_EXPANSION	1
++
++#define BRCMS_STF_SS_STBC_RX(wlc) (BRCMS_ISNPHY(wlc->band) && \
++	NREV_GT(wlc->band->phyrev, 3) && NREV_LE(wlc->band->phyrev, 6))
++
++#define NSTS_1	1
++#define NSTS_2	2
++#define NSTS_3	3
++#define NSTS_4	4
++
++static const u8 txcore_default[5] = {
++	(0),			/* bitmap of the core enabled */
++	(0x01),			/* For Nsts = 1, enable core 1 */
++	(0x03),			/* For Nsts = 2, enable core 1 & 2 */
++	(0x07),			/* For Nsts = 3, enable core 1, 2 & 3 */
++	(0x0f)			/* For Nsts = 4, enable all cores */
++};
++
++static void brcms_c_stf_stbc_rx_ht_update(struct brcms_c_info *wlc, int val)
++{
++	/* MIMOPHYs rev3-6 cannot receive STBC with only one rx core active */
++	if (BRCMS_STF_SS_STBC_RX(wlc)) {
++		if ((wlc->stf->rxstreams == 1) && (val != HT_CAP_RX_STBC_NO))
++			return;
++	}
++
++	if (wlc->pub->up) {
++		brcms_c_update_beacon(wlc);
++		brcms_c_update_probe_resp(wlc, true);
++	}
++}
++
++/*
++ * every WLC_TEMPSENSE_PERIOD seconds temperature check to decide whether to
++ * turn on/off txchain.
++ */
++void brcms_c_tempsense_upd(struct brcms_c_info *wlc)
++{
++	struct brcms_phy_pub *pi = wlc->band->pi;
++	uint active_chains, txchain;
++
++	/* Check if the chip is too hot. Disable one Tx chain, if it is */
++	/* high 4 bits are for Rx chain, low 4 bits are  for Tx chain */
++	active_chains = wlc_phy_stf_chain_active_get(pi);
++	txchain = active_chains & 0xf;
++
++	if (wlc->stf->txchain == wlc->stf->hw_txchain) {
++		if (txchain && (txchain < wlc->stf->hw_txchain))
++			/* turn off 1 tx chain */
++			brcms_c_stf_txchain_set(wlc, txchain, true);
++	} else if (wlc->stf->txchain < wlc->stf->hw_txchain) {
++		if (txchain == wlc->stf->hw_txchain)
++			/* turn back on txchain */
++			brcms_c_stf_txchain_set(wlc, txchain, true);
++	}
++}
++
++void
++brcms_c_stf_ss_algo_channel_get(struct brcms_c_info *wlc, u16 *ss_algo_channel,
++			    u16 chanspec)
++{
++	struct tx_power power;
++	u8 siso_mcs_id, cdd_mcs_id, stbc_mcs_id;
++
++	/* Clear previous settings */
++	*ss_algo_channel = 0;
++
++	if (!wlc->pub->up) {
++		*ss_algo_channel = (u16) -1;
++		return;
++	}
++
++	wlc_phy_txpower_get_current(wlc->band->pi, &power,
++				    CHSPEC_CHANNEL(chanspec));
++
++	siso_mcs_id = (CHSPEC_IS40(chanspec)) ?
++	    WL_TX_POWER_MCS40_SISO_FIRST : WL_TX_POWER_MCS20_SISO_FIRST;
++	cdd_mcs_id = (CHSPEC_IS40(chanspec)) ?
++	    WL_TX_POWER_MCS40_CDD_FIRST : WL_TX_POWER_MCS20_CDD_FIRST;
++	stbc_mcs_id = (CHSPEC_IS40(chanspec)) ?
++	    WL_TX_POWER_MCS40_STBC_FIRST : WL_TX_POWER_MCS20_STBC_FIRST;
++
++	/* criteria to choose stf mode */
++
++	/*
++	 * the "+3dbm (12 0.25db units)" is to account for the fact that with
++	 * CDD, tx occurs on both chains
++	 */
++	if (power.target[siso_mcs_id] > (power.target[cdd_mcs_id] + 12))
++		setbit(ss_algo_channel, PHY_TXC1_MODE_SISO);
++	else
++		setbit(ss_algo_channel, PHY_TXC1_MODE_CDD);
++
++	/*
++	 * STBC is ORed into to algo channel as STBC requires per-packet SCB
++	 * capability check so cannot be default mode of operation. One of
++	 * SISO, CDD have to be set
++	 */
++	if (power.target[siso_mcs_id] <= (power.target[stbc_mcs_id] + 12))
++		setbit(ss_algo_channel, PHY_TXC1_MODE_STBC);
++}
++
++static bool brcms_c_stf_stbc_tx_set(struct brcms_c_info *wlc, s32 int_val)
++{
++	if ((int_val != AUTO) && (int_val != OFF) && (int_val != ON))
++		return false;
++
++	if ((int_val == ON) && (wlc->stf->txstreams == 1))
++		return false;
++
++	wlc->bandstate[BAND_2G_INDEX]->band_stf_stbc_tx = (s8) int_val;
++	wlc->bandstate[BAND_5G_INDEX]->band_stf_stbc_tx = (s8) int_val;
++
++	return true;
++}
++
++bool brcms_c_stf_stbc_rx_set(struct brcms_c_info *wlc, s32 int_val)
++{
++	if ((int_val != HT_CAP_RX_STBC_NO)
++	    && (int_val != HT_CAP_RX_STBC_ONE_STREAM))
++		return false;
++
++	if (BRCMS_STF_SS_STBC_RX(wlc)) {
++		if ((int_val != HT_CAP_RX_STBC_NO)
++		    && (wlc->stf->rxstreams == 1))
++			return false;
++	}
++
++	brcms_c_stf_stbc_rx_ht_update(wlc, int_val);
++	return true;
++}
++
++static int brcms_c_stf_txcore_set(struct brcms_c_info *wlc, u8 Nsts,
++				  u8 core_mask)
++{
++	BCMMSG(wlc->wiphy, "wl%d: Nsts %d core_mask %x\n",
++		 wlc->pub->unit, Nsts, core_mask);
++
++	if (hweight8(core_mask) > wlc->stf->txstreams)
++		core_mask = 0;
++
++	if ((hweight8(core_mask) == wlc->stf->txstreams) &&
++	    ((core_mask & ~wlc->stf->txchain)
++	     || !(core_mask & wlc->stf->txchain)))
++		core_mask = wlc->stf->txchain;
++
++	wlc->stf->txcore[Nsts] = core_mask;
++	/* Nsts = 1..4, txcore index = 1..4 */
++	if (Nsts == 1) {
++		/* Needs to update beacon and ucode generated response
++		 * frames when 1 stream core map changed
++		 */
++		wlc->stf->phytxant = core_mask << PHY_TXC_ANT_SHIFT;
++		brcms_b_txant_set(wlc->hw, wlc->stf->phytxant);
++		if (wlc->clk) {
++			brcms_c_suspend_mac_and_wait(wlc);
++			brcms_c_beacon_phytxctl_txant_upd(wlc, wlc->bcn_rspec);
++			brcms_c_enable_mac(wlc);
++		}
++	}
++
++	return 0;
++}
++
++static int brcms_c_stf_spatial_policy_set(struct brcms_c_info *wlc, int val)
++{
++	int i;
++	u8 core_mask = 0;
++
++	BCMMSG(wlc->wiphy, "wl%d: val %x\n", wlc->pub->unit, val);
++
++	wlc->stf->spatial_policy = (s8) val;
++	for (i = 1; i <= MAX_STREAMS_SUPPORTED; i++) {
++		core_mask = (val == MAX_SPATIAL_EXPANSION) ?
++		    wlc->stf->txchain : txcore_default[i];
++		brcms_c_stf_txcore_set(wlc, (u8) i, core_mask);
++	}
++	return 0;
++}
++
++/*
++ * Centralized txant update function. call it whenever wlc->stf->txant and/or
++ * wlc->stf->txchain change.
++ *
++ * Antennas are controlled by ucode indirectly, which drives PHY or GPIO to
++ * achieve various tx/rx antenna selection schemes
++ *
++ * legacy phy, bit 6 and bit 7 means antenna 0 and 1 respectively, bit6+bit7
++ * means auto(last rx).
++ * for NREV<3, bit 6 and bit 7 means antenna 0 and 1 respectively, bit6+bit7
++ * means last rx and do tx-antenna selection for SISO transmissions
++ * for NREV=3, bit 6 and bit _8_ means antenna 0 and 1 respectively, bit6+bit7
++ * means last rx and do tx-antenna selection for SISO transmissions
++ * for NREV>=7, bit 6 and bit 7 mean antenna 0 and 1 respectively, nit6+bit7
++ * means both cores active
++*/
++static void _brcms_c_stf_phy_txant_upd(struct brcms_c_info *wlc)
++{
++	s8 txant;
++
++	txant = (s8) wlc->stf->txant;
++	if (BRCMS_PHY_11N_CAP(wlc->band)) {
++		if (txant == ANT_TX_FORCE_0) {
++			wlc->stf->phytxant = PHY_TXC_ANT_0;
++		} else if (txant == ANT_TX_FORCE_1) {
++			wlc->stf->phytxant = PHY_TXC_ANT_1;
++
++			if (BRCMS_ISNPHY(wlc->band) &&
++			    NREV_GE(wlc->band->phyrev, 3)
++			    && NREV_LT(wlc->band->phyrev, 7))
++				wlc->stf->phytxant = PHY_TXC_ANT_2;
++		} else {
++			if (BRCMS_ISLCNPHY(wlc->band) ||
++			    BRCMS_ISSSLPNPHY(wlc->band))
++				wlc->stf->phytxant = PHY_TXC_LCNPHY_ANT_LAST;
++			else {
++				/* catch out of sync wlc->stf->txcore */
++				WARN_ON(wlc->stf->txchain <= 0);
++				wlc->stf->phytxant =
++				    wlc->stf->txchain << PHY_TXC_ANT_SHIFT;
++			}
++		}
++	} else {
++		if (txant == ANT_TX_FORCE_0)
++			wlc->stf->phytxant = PHY_TXC_OLD_ANT_0;
++		else if (txant == ANT_TX_FORCE_1)
++			wlc->stf->phytxant = PHY_TXC_OLD_ANT_1;
++		else
++			wlc->stf->phytxant = PHY_TXC_OLD_ANT_LAST;
++	}
++
++	brcms_b_txant_set(wlc->hw, wlc->stf->phytxant);
++}
++
++int brcms_c_stf_txchain_set(struct brcms_c_info *wlc, s32 int_val, bool force)
++{
++	u8 txchain = (u8) int_val;
++	u8 txstreams;
++	uint i;
++
++	if (wlc->stf->txchain == txchain)
++		return 0;
++
++	if ((txchain & ~wlc->stf->hw_txchain)
++	    || !(txchain & wlc->stf->hw_txchain))
++		return -EINVAL;
++
++	/*
++	 * if nrate override is configured to be non-SISO STF mode, reject
++	 * reducing txchain to 1
++	 */
++	txstreams = (u8) hweight8(txchain);
++	if (txstreams > MAX_STREAMS_SUPPORTED)
++		return -EINVAL;
++
++	wlc->stf->txchain = txchain;
++	wlc->stf->txstreams = txstreams;
++	brcms_c_stf_stbc_tx_set(wlc, wlc->band->band_stf_stbc_tx);
++	brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_2G_INDEX]);
++	brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]);
++	wlc->stf->txant =
++	    (wlc->stf->txstreams == 1) ? ANT_TX_FORCE_0 : ANT_TX_DEF;
++	_brcms_c_stf_phy_txant_upd(wlc);
++
++	wlc_phy_stf_chain_set(wlc->band->pi, wlc->stf->txchain,
++			      wlc->stf->rxchain);
++
++	for (i = 1; i <= MAX_STREAMS_SUPPORTED; i++)
++		brcms_c_stf_txcore_set(wlc, (u8) i, txcore_default[i]);
++
++	return 0;
++}
++
++/*
++ * update wlc->stf->ss_opmode which represents the operational stf_ss mode
++ * we're using
++ */
++int brcms_c_stf_ss_update(struct brcms_c_info *wlc, struct brcms_band *band)
++{
++	int ret_code = 0;
++	u8 prev_stf_ss;
++	u8 upd_stf_ss;
++
++	prev_stf_ss = wlc->stf->ss_opmode;
++
++	/*
++	 * NOTE: opmode can only be SISO or CDD as STBC is decided on a
++	 * per-packet basis
++	 */
++	if (BRCMS_STBC_CAP_PHY(wlc) &&
++	    wlc->stf->ss_algosel_auto
++	    && (wlc->stf->ss_algo_channel != (u16) -1)) {
++		upd_stf_ss = (wlc->stf->txstreams == 1 ||
++			      isset(&wlc->stf->ss_algo_channel,
++				    PHY_TXC1_MODE_SISO)) ?
++				    PHY_TXC1_MODE_SISO : PHY_TXC1_MODE_CDD;
++	} else {
++		if (wlc->band != band)
++			return ret_code;
++		upd_stf_ss = (wlc->stf->txstreams == 1) ?
++				PHY_TXC1_MODE_SISO : band->band_stf_ss_mode;
++	}
++	if (prev_stf_ss != upd_stf_ss) {
++		wlc->stf->ss_opmode = upd_stf_ss;
++		brcms_b_band_stf_ss_set(wlc->hw, upd_stf_ss);
++	}
++
++	return ret_code;
++}
++
++int brcms_c_stf_attach(struct brcms_c_info *wlc)
++{
++	wlc->bandstate[BAND_2G_INDEX]->band_stf_ss_mode = PHY_TXC1_MODE_SISO;
++	wlc->bandstate[BAND_5G_INDEX]->band_stf_ss_mode = PHY_TXC1_MODE_CDD;
++
++	if (BRCMS_ISNPHY(wlc->band) &&
++	    (wlc_phy_txpower_hw_ctrl_get(wlc->band->pi) != PHY_TPC_HW_ON))
++		wlc->bandstate[BAND_2G_INDEX]->band_stf_ss_mode =
++		    PHY_TXC1_MODE_CDD;
++	brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_2G_INDEX]);
++	brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]);
++
++	brcms_c_stf_stbc_rx_ht_update(wlc, HT_CAP_RX_STBC_NO);
++	wlc->bandstate[BAND_2G_INDEX]->band_stf_stbc_tx = OFF;
++	wlc->bandstate[BAND_5G_INDEX]->band_stf_stbc_tx = OFF;
++
++	if (BRCMS_STBC_CAP_PHY(wlc)) {
++		wlc->stf->ss_algosel_auto = true;
++		/* Init the default value */
++		wlc->stf->ss_algo_channel = (u16) -1;
++	}
++	return 0;
++}
++
++void brcms_c_stf_detach(struct brcms_c_info *wlc)
++{
++}
++
++void brcms_c_stf_phy_txant_upd(struct brcms_c_info *wlc)
++{
++	_brcms_c_stf_phy_txant_upd(wlc);
++}
++
++void brcms_c_stf_phy_chain_calc(struct brcms_c_info *wlc)
++{
++	struct ssb_sprom *sprom = &wlc->hw->d11core->bus->sprom;
++
++	/* get available rx/tx chains */
++	wlc->stf->hw_txchain = sprom->txchain;
++	wlc->stf->hw_rxchain = sprom->rxchain;
++
++	/* these parameter are intended to be used for all PHY types */
++	if (wlc->stf->hw_txchain == 0 || wlc->stf->hw_txchain == 0xf) {
++		if (BRCMS_ISNPHY(wlc->band))
++			wlc->stf->hw_txchain = TXCHAIN_DEF_NPHY;
++		else
++			wlc->stf->hw_txchain = TXCHAIN_DEF;
++	}
++
++	wlc->stf->txchain = wlc->stf->hw_txchain;
++	wlc->stf->txstreams = (u8) hweight8(wlc->stf->hw_txchain);
++
++	if (wlc->stf->hw_rxchain == 0 || wlc->stf->hw_rxchain == 0xf) {
++		if (BRCMS_ISNPHY(wlc->band))
++			wlc->stf->hw_rxchain = RXCHAIN_DEF_NPHY;
++		else
++			wlc->stf->hw_rxchain = RXCHAIN_DEF;
++	}
++
++	wlc->stf->rxchain = wlc->stf->hw_rxchain;
++	wlc->stf->rxstreams = (u8) hweight8(wlc->stf->hw_rxchain);
++
++	/* initialize the txcore table */
++	memcpy(wlc->stf->txcore, txcore_default, sizeof(wlc->stf->txcore));
++
++	/* default spatial_policy */
++	wlc->stf->spatial_policy = MIN_SPATIAL_EXPANSION;
++	brcms_c_stf_spatial_policy_set(wlc, MIN_SPATIAL_EXPANSION);
++}
++
++static u16 _brcms_c_stf_phytxchain_sel(struct brcms_c_info *wlc,
++				       u32 rspec)
++{
++	u16 phytxant = wlc->stf->phytxant;
++
++	if (rspec_stf(rspec) != PHY_TXC1_MODE_SISO)
++		phytxant = wlc->stf->txchain << PHY_TXC_ANT_SHIFT;
++	else if (wlc->stf->txant == ANT_TX_DEF)
++		phytxant = wlc->stf->txchain << PHY_TXC_ANT_SHIFT;
++	phytxant &= PHY_TXC_ANT_MASK;
++	return phytxant;
++}
++
++u16 brcms_c_stf_phytxchain_sel(struct brcms_c_info *wlc, u32 rspec)
++{
++	return _brcms_c_stf_phytxchain_sel(wlc, rspec);
++}
++
++u16 brcms_c_stf_d11hdrs_phyctl_txant(struct brcms_c_info *wlc, u32 rspec)
++{
++	u16 phytxant = wlc->stf->phytxant;
++	u16 mask = PHY_TXC_ANT_MASK;
++
++	/* for non-siso rates or default setting, use the available chains */
++	if (BRCMS_ISNPHY(wlc->band)) {
++		phytxant = _brcms_c_stf_phytxchain_sel(wlc, rspec);
++		mask = PHY_TXC_HTANT_MASK;
++	}
++	phytxant |= phytxant & mask;
++	return phytxant;
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/stf.h b/drivers/net/wireless/brcm80211/brcmsmac/stf.h
+new file mode 100644
+index 0000000..19f6580
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/stf.h
+@@ -0,0 +1,42 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef _BRCM_STF_H_
++#define _BRCM_STF_H_
++
++#include "types.h"
++
++extern int brcms_c_stf_attach(struct brcms_c_info *wlc);
++extern void brcms_c_stf_detach(struct brcms_c_info *wlc);
++
++extern void brcms_c_tempsense_upd(struct brcms_c_info *wlc);
++extern void brcms_c_stf_ss_algo_channel_get(struct brcms_c_info *wlc,
++					u16 *ss_algo_channel,
++					u16 chanspec);
++extern int brcms_c_stf_ss_update(struct brcms_c_info *wlc,
++			     struct brcms_band *band);
++extern void brcms_c_stf_phy_txant_upd(struct brcms_c_info *wlc);
++extern int brcms_c_stf_txchain_set(struct brcms_c_info *wlc, s32 int_val,
++			       bool force);
++extern bool brcms_c_stf_stbc_rx_set(struct brcms_c_info *wlc, s32 int_val);
++extern void brcms_c_stf_phy_txant_upd(struct brcms_c_info *wlc);
++extern void brcms_c_stf_phy_chain_calc(struct brcms_c_info *wlc);
++extern u16 brcms_c_stf_phytxchain_sel(struct brcms_c_info *wlc,
++				      u32 rspec);
++extern u16 brcms_c_stf_d11hdrs_phyctl_txant(struct brcms_c_info *wlc,
++					u32 rspec);
++
++#endif				/* _BRCM_STF_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/types.h b/drivers/net/wireless/brcm80211/brcmsmac/types.h
+new file mode 100644
+index 0000000..e11ae83
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/types.h
+@@ -0,0 +1,304 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef _BRCM_TYPES_H_
++#define _BRCM_TYPES_H_
++
++#include <linux/types.h>
++#include <linux/io.h>
++
++#define WL_CHAN_FREQ_RANGE_2G      0
++#define WL_CHAN_FREQ_RANGE_5GL     1
++#define WL_CHAN_FREQ_RANGE_5GM     2
++#define WL_CHAN_FREQ_RANGE_5GH     3
++
++/* boardflags */
++
++/* Board has gpio 9 controlling the PA */
++#define	BFL_PACTRL		0x00000002
++/* Not ok to power down the chip pll and oscillator */
++#define	BFL_NOPLLDOWN		0x00000020
++/* Board supports the Front End Module */
++#define BFL_FEM			0x00000800
++/* Board has an external LNA in 2.4GHz band */
++#define BFL_EXTLNA		0x00001000
++/* Board has no PA */
++#define BFL_NOPA		0x00010000
++/* Power topology uses BUCKBOOST */
++#define BFL_BUCKBOOST		0x00200000
++/* Board has FEM and switch to share antenna w/ BT */
++#define BFL_FEM_BT		0x00400000
++/* Power topology doesn't use CBUCK */
++#define BFL_NOCBUCK		0x00800000
++/* Power topology uses PALDO */
++#define BFL_PALDO		0x02000000
++/* Board has an external LNA in 5GHz band */
++#define BFL_EXTLNA_5GHz		0x10000000
++
++/* boardflags2 */
++
++/* Board has an external rxbb regulator */
++#define BFL2_RXBB_INT_REG_DIS	0x00000001
++/* Flag to implement alternative A-band PLL settings */
++#define BFL2_APLL_WAR		0x00000002
++/* Board permits enabling TX Power Control */
++#define BFL2_TXPWRCTRL_EN	0x00000004
++/* Board supports the 2X4 diversity switch */
++#define BFL2_2X4_DIV		0x00000008
++/* Board supports 5G band power gain */
++#define BFL2_5G_PWRGAIN		0x00000010
++/* Board overrides ASPM and Clkreq settings */
++#define BFL2_PCIEWAR_OVR	0x00000020
++#define BFL2_LEGACY		0x00000080
++/* 4321mcm93 board uses Skyworks FEM */
++#define BFL2_SKWRKFEM_BRD	0x00000100
++/* Board has a WAR for clock-harmonic spurs */
++#define BFL2_SPUR_WAR		0x00000200
++/* Flag to narrow G-band PLL loop b/w */
++#define BFL2_GPLL_WAR		0x00000400
++/* Tx CCK pkts on Ant 0 only */
++#define BFL2_SINGLEANT_CCK	0x00001000
++/* WAR to reduce and avoid clock-harmonic spurs in 2G */
++#define BFL2_2G_SPUR_WAR	0x00002000
++/* Flag to widen G-band PLL loop b/w */
++#define BFL2_GPLL_WAR2	        0x00010000
++#define BFL2_IPALVLSHIFT_3P3    0x00020000
++/* Use internal envelope detector for TX IQCAL */
++#define BFL2_INTERNDET_TXIQCAL  0x00040000
++/* Keep the buffered Xtal output from radio "ON". Most drivers will turn it
++ * off without this flag to save power. */
++#define BFL2_XTALBUFOUTEN       0x00080000
++
++/*
++ * board specific GPIO assignment, gpio 0-3 are also customer-configurable
++ * led
++ */
++
++/* bit 9 controls the PA on new 4306 boards */
++#define	BOARD_GPIO_PACTRL	0x200
++#define BOARD_GPIO_12		0x1000
++#define BOARD_GPIO_13		0x2000
++
++/* **** Core type/rev defaults **** */
++#define D11CONF		0x0fffffb0	/* Supported  D11 revs: 4, 5, 7-27
++					 * also need to update wlc.h MAXCOREREV
++					 */
++
++#define NCONF		0x000001ff	/* Supported nphy revs:
++					 *      0       4321a0
++					 *      1       4321a1
++					 *      2       4321b0/b1/c0/c1
++					 *      3       4322a0
++					 *      4       4322a1
++					 *      5       4716a0
++					 *      6       43222a0, 43224a0
++					 *      7       43226a0
++					 *      8       5357a0, 43236a0
++					 */
++
++#define LCNCONF		0x00000007	/* Supported lcnphy revs:
++					 *      0       4313a0, 4336a0, 4330a0
++					 *      1
++					 *      2       4330a0
++					 */
++
++#define SSLPNCONF	0x0000000f	/* Supported sslpnphy revs:
++					 *      0       4329a0/k0
++					 *      1       4329b0/4329C0
++					 *      2       4319a0
++					 *      3       5356a0
++					 */
++
++/********************************************************************
++ * Phy/Core Configuration.  Defines macros to to check core phy/rev *
++ * compile-time configuration.  Defines default core support.       *
++ * ******************************************************************
++ */
++
++/* Basic macros to check a configuration bitmask */
++
++#define CONF_HAS(config, val)	((config) & (1 << (val)))
++#define CONF_MSK(config, mask)	((config) & (mask))
++#define MSK_RANGE(low, hi)	((1 << ((hi)+1)) - (1 << (low)))
++#define CONF_RANGE(config, low, hi) (CONF_MSK(config, MSK_RANGE(low, high)))
++
++#define CONF_IS(config, val)	((config) == (1 << (val)))
++#define CONF_GE(config, val)	((config) & (0-(1 << (val))))
++#define CONF_GT(config, val)	((config) & (0-2*(1 << (val))))
++#define CONF_LT(config, val)	((config) & ((1 << (val))-1))
++#define CONF_LE(config, val)	((config) & (2*(1 << (val))-1))
++
++/* Wrappers for some of the above, specific to config constants */
++
++#define NCONF_HAS(val)	CONF_HAS(NCONF, val)
++#define NCONF_MSK(mask)	CONF_MSK(NCONF, mask)
++#define NCONF_IS(val)	CONF_IS(NCONF, val)
++#define NCONF_GE(val)	CONF_GE(NCONF, val)
++#define NCONF_GT(val)	CONF_GT(NCONF, val)
++#define NCONF_LT(val)	CONF_LT(NCONF, val)
++#define NCONF_LE(val)	CONF_LE(NCONF, val)
++
++#define LCNCONF_HAS(val)	CONF_HAS(LCNCONF, val)
++#define LCNCONF_MSK(mask)	CONF_MSK(LCNCONF, mask)
++#define LCNCONF_IS(val)		CONF_IS(LCNCONF, val)
++#define LCNCONF_GE(val)		CONF_GE(LCNCONF, val)
++#define LCNCONF_GT(val)		CONF_GT(LCNCONF, val)
++#define LCNCONF_LT(val)		CONF_LT(LCNCONF, val)
++#define LCNCONF_LE(val)		CONF_LE(LCNCONF, val)
++
++#define D11CONF_HAS(val) CONF_HAS(D11CONF, val)
++#define D11CONF_MSK(mask) CONF_MSK(D11CONF, mask)
++#define D11CONF_IS(val)	CONF_IS(D11CONF, val)
++#define D11CONF_GE(val)	CONF_GE(D11CONF, val)
++#define D11CONF_GT(val)	CONF_GT(D11CONF, val)
++#define D11CONF_LT(val)	CONF_LT(D11CONF, val)
++#define D11CONF_LE(val)	CONF_LE(D11CONF, val)
++
++#define PHYCONF_HAS(val) CONF_HAS(PHYTYPE, val)
++#define PHYCONF_IS(val)	CONF_IS(PHYTYPE, val)
++
++#define NREV_IS(var, val) \
++	(NCONF_HAS(val) && (NCONF_IS(val) || ((var) == (val))))
++
++#define NREV_GE(var, val) \
++	(NCONF_GE(val) && (!NCONF_LT(val) || ((var) >= (val))))
++
++#define NREV_GT(var, val) \
++	(NCONF_GT(val) && (!NCONF_LE(val) || ((var) > (val))))
++
++#define NREV_LT(var, val) \
++	(NCONF_LT(val) && (!NCONF_GE(val) || ((var) < (val))))
++
++#define NREV_LE(var, val) \
++	(NCONF_LE(val) && (!NCONF_GT(val) || ((var) <= (val))))
++
++#define LCNREV_IS(var, val) \
++	(LCNCONF_HAS(val) && (LCNCONF_IS(val) || ((var) == (val))))
++
++#define LCNREV_GE(var, val) \
++	(LCNCONF_GE(val) && (!LCNCONF_LT(val) || ((var) >= (val))))
++
++#define LCNREV_GT(var, val) \
++	(LCNCONF_GT(val) && (!LCNCONF_LE(val) || ((var) > (val))))
++
++#define LCNREV_LT(var, val) \
++	(LCNCONF_LT(val) && (!LCNCONF_GE(val) || ((var) < (val))))
++
++#define LCNREV_LE(var, val) \
++	(LCNCONF_LE(val) && (!LCNCONF_GT(val) || ((var) <= (val))))
++
++#define D11REV_IS(var, val) \
++	(D11CONF_HAS(val) && (D11CONF_IS(val) || ((var) == (val))))
++
++#define D11REV_GE(var, val) \
++	(D11CONF_GE(val) && (!D11CONF_LT(val) || ((var) >= (val))))
++
++#define D11REV_GT(var, val) \
++	(D11CONF_GT(val) && (!D11CONF_LE(val) || ((var) > (val))))
++
++#define D11REV_LT(var, val) \
++	(D11CONF_LT(val) && (!D11CONF_GE(val) || ((var) < (val))))
++
++#define D11REV_LE(var, val) \
++	(D11CONF_LE(val) && (!D11CONF_GT(val) || ((var) <= (val))))
++
++#define PHYTYPE_IS(var, val)\
++	(PHYCONF_HAS(val) && (PHYCONF_IS(val) || ((var) == (val))))
++
++/* Set up PHYTYPE automatically: (depends on PHY_TYPE_X, from d11.h) */
++
++#define _PHYCONF_N (1 << PHY_TYPE_N)
++#define _PHYCONF_LCN (1 << PHY_TYPE_LCN)
++#define _PHYCONF_SSLPN (1 << PHY_TYPE_SSN)
++
++#define PHYTYPE (_PHYCONF_N | _PHYCONF_LCN | _PHYCONF_SSLPN)
++
++/* Utility macro to identify 802.11n (HT) capable PHYs */
++#define PHYTYPE_11N_CAP(phytype) \
++	(PHYTYPE_IS(phytype, PHY_TYPE_N) ||	\
++	 PHYTYPE_IS(phytype, PHY_TYPE_LCN) || \
++	 PHYTYPE_IS(phytype, PHY_TYPE_SSN))
++
++/* Last but not least: shorter wlc-specific var checks */
++#define BRCMS_ISNPHY(band)		PHYTYPE_IS((band)->phytype, PHY_TYPE_N)
++#define BRCMS_ISLCNPHY(band)	PHYTYPE_IS((band)->phytype, PHY_TYPE_LCN)
++#define BRCMS_ISSSLPNPHY(band)	PHYTYPE_IS((band)->phytype, PHY_TYPE_SSN)
++
++#define BRCMS_PHY_11N_CAP(band)	PHYTYPE_11N_CAP((band)->phytype)
++
++/**********************************************************************
++ * ------------- End of Core phy/rev configuration. ----------------- *
++ * ********************************************************************
++ */
++
++#define BCMMSG(dev, fmt, args...)		\
++do {						\
++	if (brcm_msg_level & LOG_TRACE_VAL)	\
++		wiphy_err(dev, "%s: " fmt, __func__, ##args);	\
++} while (0)
++
++#ifdef CONFIG_BCM47XX
++/*
++ * bcm4716 (which includes 4717 & 4718), plus 4706 on PCIe can reorder
++ * transactions. As a fix, a read after write is performed on certain places
++ * in the code. Older chips and the newer 5357 family don't require this fix.
++ */
++#define bcma_wflush16(c, o, v) \
++	({ bcma_write16(c, o, v); (void)bcma_read16(c, o); })
++#else
++#define bcma_wflush16(c, o, v)	bcma_write16(c, o, v)
++#endif				/* CONFIG_BCM47XX */
++
++/* multi-bool data type: set of bools, mbool is true if any is set */
++
++/* set one bool */
++#define mboolset(mb, bit)		((mb) |= (bit))
++/* clear one bool */
++#define mboolclr(mb, bit)		((mb) &= ~(bit))
++/* true if one bool is set */
++#define mboolisset(mb, bit)		(((mb) & (bit)) != 0)
++#define	mboolmaskset(mb, mask, val)	((mb) = (((mb) & ~(mask)) | (val)))
++
++#define CEIL(x, y)		(((x) + ((y)-1)) / (y))
++
++/* forward declarations */
++struct wiphy;
++struct ieee80211_sta;
++struct ieee80211_tx_queue_params;
++struct brcms_info;
++struct brcms_c_info;
++struct brcms_hardware;
++struct brcms_txq_info;
++struct brcms_band;
++struct dma_pub;
++struct si_pub;
++struct tx_status;
++struct d11rxhdr;
++struct txpwr_limits;
++
++/* iovar structure */
++struct brcmu_iovar {
++	const char *name;	/* name for lookup and display */
++	u16 varid;	/* id for switch */
++	u16 flags;	/* driver-specific flag bits */
++	u16 type;	/* base type of argument */
++	u16 minlen;	/* min length for buffer vars */
++};
++
++/* brcm_msg_level is a bit vector with defs in defs.h */
++extern u32 brcm_msg_level;
++
++#endif				/* _BRCM_TYPES_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/ucode_loader.c b/drivers/net/wireless/brcm80211/brcmsmac/ucode_loader.c
+new file mode 100644
+index 0000000..80e3ccf
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/ucode_loader.c
+@@ -0,0 +1,109 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#include <defs.h>
++#include "types.h"
++#include <ucode_loader.h>
++
++enum {
++	D11UCODE_NAMETAG_START = 0,
++	D11LCN0BSINITVALS24,
++	D11LCN0INITVALS24,
++	D11LCN1BSINITVALS24,
++	D11LCN1INITVALS24,
++	D11LCN2BSINITVALS24,
++	D11LCN2INITVALS24,
++	D11N0ABSINITVALS16,
++	D11N0BSINITVALS16,
++	D11N0INITVALS16,
++	D11UCODE_OVERSIGHT16_MIMO,
++	D11UCODE_OVERSIGHT16_MIMOSZ,
++	D11UCODE_OVERSIGHT24_LCN,
++	D11UCODE_OVERSIGHT24_LCNSZ,
++	D11UCODE_OVERSIGHT_BOMMAJOR,
++	D11UCODE_OVERSIGHT_BOMMINOR
++};
++
++int brcms_ucode_data_init(struct brcms_info *wl, struct brcms_ucode *ucode)
++{
++	int rc;
++
++	rc = brcms_check_firmwares(wl);
++
++	rc = rc < 0 ? rc :
++		brcms_ucode_init_buf(wl, (void **)&ucode->d11lcn0bsinitvals24,
++				     D11LCN0BSINITVALS24);
++	rc = rc < 0 ?
++	     rc : brcms_ucode_init_buf(wl, (void **)&ucode->d11lcn0initvals24,
++				       D11LCN0INITVALS24);
++	rc = rc < 0 ?
++	     rc : brcms_ucode_init_buf(wl, (void **)&ucode->d11lcn1bsinitvals24,
++				       D11LCN1BSINITVALS24);
++	rc = rc < 0 ?
++	     rc : brcms_ucode_init_buf(wl, (void **)&ucode->d11lcn1initvals24,
++				       D11LCN1INITVALS24);
++	rc = rc < 0 ? rc :
++		brcms_ucode_init_buf(wl, (void **)&ucode->d11lcn2bsinitvals24,
++				     D11LCN2BSINITVALS24);
++	rc = rc < 0 ?
++	     rc : brcms_ucode_init_buf(wl, (void **)&ucode->d11lcn2initvals24,
++				       D11LCN2INITVALS24);
++	rc = rc < 0 ?
++	     rc : brcms_ucode_init_buf(wl, (void **)&ucode->d11n0absinitvals16,
++				       D11N0ABSINITVALS16);
++	rc = rc < 0 ?
++	     rc : brcms_ucode_init_buf(wl, (void **)&ucode->d11n0bsinitvals16,
++				       D11N0BSINITVALS16);
++	rc = rc < 0 ?
++	     rc : brcms_ucode_init_buf(wl, (void **)&ucode->d11n0initvals16,
++				       D11N0INITVALS16);
++	rc = rc < 0 ?
++	     rc : brcms_ucode_init_buf(wl, (void **)&ucode->bcm43xx_16_mimo,
++				       D11UCODE_OVERSIGHT16_MIMO);
++	rc = rc < 0 ?
++	     rc : brcms_ucode_init_uint(wl, &ucode->bcm43xx_16_mimosz,
++					D11UCODE_OVERSIGHT16_MIMOSZ);
++	rc = rc < 0 ?
++	     rc : brcms_ucode_init_buf(wl, (void **)&ucode->bcm43xx_24_lcn,
++				       D11UCODE_OVERSIGHT24_LCN);
++	rc = rc < 0 ?
++	     rc : brcms_ucode_init_uint(wl, &ucode->bcm43xx_24_lcnsz,
++					D11UCODE_OVERSIGHT24_LCNSZ);
++	rc = rc < 0 ?
++	     rc : brcms_ucode_init_buf(wl, (void **)&ucode->bcm43xx_bommajor,
++				       D11UCODE_OVERSIGHT_BOMMAJOR);
++	rc = rc < 0 ?
++	     rc : brcms_ucode_init_buf(wl, (void **)&ucode->bcm43xx_bomminor,
++				       D11UCODE_OVERSIGHT_BOMMINOR);
++	return rc;
++}
++
++void brcms_ucode_data_free(struct brcms_ucode *ucode)
++{
++	brcms_ucode_free_buf((void *)ucode->d11lcn0bsinitvals24);
++	brcms_ucode_free_buf((void *)ucode->d11lcn0initvals24);
++	brcms_ucode_free_buf((void *)ucode->d11lcn1bsinitvals24);
++	brcms_ucode_free_buf((void *)ucode->d11lcn1initvals24);
++	brcms_ucode_free_buf((void *)ucode->d11lcn2bsinitvals24);
++	brcms_ucode_free_buf((void *)ucode->d11lcn2initvals24);
++	brcms_ucode_free_buf((void *)ucode->d11n0absinitvals16);
++	brcms_ucode_free_buf((void *)ucode->d11n0bsinitvals16);
++	brcms_ucode_free_buf((void *)ucode->d11n0initvals16);
++	brcms_ucode_free_buf((void *)ucode->bcm43xx_16_mimo);
++	brcms_ucode_free_buf((void *)ucode->bcm43xx_24_lcn);
++	brcms_ucode_free_buf((void *)ucode->bcm43xx_bommajor);
++	brcms_ucode_free_buf((void *)ucode->bcm43xx_bomminor);
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/ucode_loader.h b/drivers/net/wireless/brcm80211/brcmsmac/ucode_loader.h
+new file mode 100644
+index 0000000..18750a8
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/ucode_loader.h
+@@ -0,0 +1,58 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++#ifndef	_BRCM_UCODE_H_
++#define	_BRCM_UCODE_H_
++
++#include "types.h"		/* forward structure declarations */
++
++#define MIN_FW_SIZE 40000	/* minimum firmware file size in bytes */
++#define MAX_FW_SIZE 150000
++
++#define UCODE_LOADER_API_VER 0
++
++struct d11init;
++
++struct brcms_ucode {
++	struct d11init *d11lcn0bsinitvals24;
++	struct d11init *d11lcn0initvals24;
++	struct d11init *d11lcn1bsinitvals24;
++	struct d11init *d11lcn1initvals24;
++	struct d11init *d11lcn2bsinitvals24;
++	struct d11init *d11lcn2initvals24;
++	struct d11init *d11n0absinitvals16;
++	struct d11init *d11n0bsinitvals16;
++	struct d11init *d11n0initvals16;
++	__le32 *bcm43xx_16_mimo;
++	size_t bcm43xx_16_mimosz;
++	__le32 *bcm43xx_24_lcn;
++	size_t bcm43xx_24_lcnsz;
++	u32 *bcm43xx_bommajor;
++	u32 *bcm43xx_bomminor;
++};
++
++extern int
++brcms_ucode_data_init(struct brcms_info *wl, struct brcms_ucode *ucode);
++
++extern void brcms_ucode_data_free(struct brcms_ucode *ucode);
++
++extern int brcms_ucode_init_buf(struct brcms_info *wl, void **pbuf,
++				unsigned int idx);
++extern int brcms_ucode_init_uint(struct brcms_info *wl, size_t *n_bytes,
++				 unsigned int idx);
++extern void brcms_ucode_free_buf(void *);
++extern int  brcms_check_firmwares(struct brcms_info *wl);
++
++#endif	/* _BRCM_UCODE_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmutil/Makefile b/drivers/net/wireless/brcm80211/brcmutil/Makefile
+new file mode 100644
+index 0000000..5529801
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmutil/Makefile
+@@ -0,0 +1,28 @@
++#
++# Makefile fragment for Broadcom 802.11n Networking Device Driver Utilities
++#
++# Copyright (c) 2011 Broadcom Corporation
++#
++# Permission to use, copy, modify, and/or distribute this software for any
++# purpose with or without fee is hereby granted, provided that the above
++# copyright notice and this permission notice appear in all copies.
++#
++# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++
++ccflags-y :=				\
++	-I$(obj)			\
++	-I$(obj)/../include
++
++BRCMUTIL_OFILES := \
++	utils.o
++
++MODULEPFX := brcmutil
++
++obj-$(CONFIG_BRCMUTIL)	+= $(MODULEPFX).o
++$(MODULEPFX)-objs	= $(BRCMUTIL_OFILES)
+diff --git a/drivers/net/wireless/brcm80211/brcmutil/utils.c b/drivers/net/wireless/brcm80211/brcmutil/utils.c
+new file mode 100644
+index 0000000..161851b
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmutil/utils.c
+@@ -0,0 +1,278 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#undef pr_fmt
++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
++
++#include <linux/netdevice.h>
++#include <linux/module.h>
++#include <linux/printk.h>
++
++#include <brcmu_utils.h>
++
++MODULE_AUTHOR("Broadcom Corporation");
++MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN driver utilities.");
++MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN cards");
++MODULE_LICENSE("Dual BSD/GPL");
++
++struct sk_buff *brcmu_pkt_buf_get_skb(uint len)
++{
++	struct sk_buff *skb;
++
++	skb = dev_alloc_skb(len);
++	if (skb) {
++		skb_put(skb, len);
++		skb->priority = 0;
++	}
++
++	return skb;
++}
++EXPORT_SYMBOL(brcmu_pkt_buf_get_skb);
++
++/* Free the driver packet. Free the tag if present */
++void brcmu_pkt_buf_free_skb(struct sk_buff *skb)
++{
++	WARN_ON(skb->next);
++	if (skb->destructor)
++		/* cannot kfree_skb() on hard IRQ (net/core/skbuff.c) if
++		 * destructor exists
++		 */
++		dev_kfree_skb_any(skb);
++	else
++		/* can free immediately (even in_irq()) if destructor
++		 * does not exist
++		 */
++		dev_kfree_skb(skb);
++}
++EXPORT_SYMBOL(brcmu_pkt_buf_free_skb);
++
++/*
++ * osl multiple-precedence packet queue
++ * hi_prec is always >= the number of the highest non-empty precedence
++ */
++struct sk_buff *brcmu_pktq_penq(struct pktq *pq, int prec,
++				      struct sk_buff *p)
++{
++	struct sk_buff_head *q;
++
++	if (pktq_full(pq) || pktq_pfull(pq, prec))
++		return NULL;
++
++	q = &pq->q[prec].skblist;
++	skb_queue_tail(q, p);
++	pq->len++;
++
++	if (pq->hi_prec < prec)
++		pq->hi_prec = (u8) prec;
++
++	return p;
++}
++EXPORT_SYMBOL(brcmu_pktq_penq);
++
++struct sk_buff *brcmu_pktq_penq_head(struct pktq *pq, int prec,
++					   struct sk_buff *p)
++{
++	struct sk_buff_head *q;
++
++	if (pktq_full(pq) || pktq_pfull(pq, prec))
++		return NULL;
++
++	q = &pq->q[prec].skblist;
++	skb_queue_head(q, p);
++	pq->len++;
++
++	if (pq->hi_prec < prec)
++		pq->hi_prec = (u8) prec;
++
++	return p;
++}
++EXPORT_SYMBOL(brcmu_pktq_penq_head);
++
++struct sk_buff *brcmu_pktq_pdeq(struct pktq *pq, int prec)
++{
++	struct sk_buff_head *q;
++	struct sk_buff *p;
++
++	q = &pq->q[prec].skblist;
++	p = skb_dequeue(q);
++	if (p == NULL)
++		return NULL;
++
++	pq->len--;
++	return p;
++}
++EXPORT_SYMBOL(brcmu_pktq_pdeq);
++
++struct sk_buff *brcmu_pktq_pdeq_tail(struct pktq *pq, int prec)
++{
++	struct sk_buff_head *q;
++	struct sk_buff *p;
++
++	q = &pq->q[prec].skblist;
++	p = skb_dequeue_tail(q);
++	if (p == NULL)
++		return NULL;
++
++	pq->len--;
++	return p;
++}
++EXPORT_SYMBOL(brcmu_pktq_pdeq_tail);
++
++void
++brcmu_pktq_pflush(struct pktq *pq, int prec, bool dir,
++		  bool (*fn)(struct sk_buff *, void *), void *arg)
++{
++	struct sk_buff_head *q;
++	struct sk_buff *p, *next;
++
++	q = &pq->q[prec].skblist;
++	skb_queue_walk_safe(q, p, next) {
++		if (fn == NULL || (*fn) (p, arg)) {
++			skb_unlink(p, q);
++			brcmu_pkt_buf_free_skb(p);
++			pq->len--;
++		}
++	}
++}
++EXPORT_SYMBOL(brcmu_pktq_pflush);
++
++void brcmu_pktq_flush(struct pktq *pq, bool dir,
++		      bool (*fn)(struct sk_buff *, void *), void *arg)
++{
++	int prec;
++	for (prec = 0; prec < pq->num_prec; prec++)
++		brcmu_pktq_pflush(pq, prec, dir, fn, arg);
++}
++EXPORT_SYMBOL(brcmu_pktq_flush);
++
++void brcmu_pktq_init(struct pktq *pq, int num_prec, int max_len)
++{
++	int prec;
++
++	/* pq is variable size; only zero out what's requested */
++	memset(pq, 0,
++	      offsetof(struct pktq, q) + (sizeof(struct pktq_prec) * num_prec));
++
++	pq->num_prec = (u16) num_prec;
++
++	pq->max = (u16) max_len;
++
++	for (prec = 0; prec < num_prec; prec++) {
++		pq->q[prec].max = pq->max;
++		skb_queue_head_init(&pq->q[prec].skblist);
++	}
++}
++EXPORT_SYMBOL(brcmu_pktq_init);
++
++struct sk_buff *brcmu_pktq_peek_tail(struct pktq *pq, int *prec_out)
++{
++	int prec;
++
++	if (pq->len == 0)
++		return NULL;
++
++	for (prec = 0; prec < pq->hi_prec; prec++)
++		if (!skb_queue_empty(&pq->q[prec].skblist))
++			break;
++
++	if (prec_out)
++		*prec_out = prec;
++
++	return skb_peek_tail(&pq->q[prec].skblist);
++}
++EXPORT_SYMBOL(brcmu_pktq_peek_tail);
++
++/* Return sum of lengths of a specific set of precedences */
++int brcmu_pktq_mlen(struct pktq *pq, uint prec_bmp)
++{
++	int prec, len;
++
++	len = 0;
++
++	for (prec = 0; prec <= pq->hi_prec; prec++)
++		if (prec_bmp & (1 << prec))
++			len += pq->q[prec].skblist.qlen;
++
++	return len;
++}
++EXPORT_SYMBOL(brcmu_pktq_mlen);
++
++/* Priority dequeue from a specific set of precedences */
++struct sk_buff *brcmu_pktq_mdeq(struct pktq *pq, uint prec_bmp,
++				      int *prec_out)
++{
++	struct sk_buff_head *q;
++	struct sk_buff *p;
++	int prec;
++
++	if (pq->len == 0)
++		return NULL;
++
++	while ((prec = pq->hi_prec) > 0 &&
++	       skb_queue_empty(&pq->q[prec].skblist))
++		pq->hi_prec--;
++
++	while ((prec_bmp & (1 << prec)) == 0 ||
++	       skb_queue_empty(&pq->q[prec].skblist))
++		if (prec-- == 0)
++			return NULL;
++
++	q = &pq->q[prec].skblist;
++	p = skb_dequeue(q);
++	if (p == NULL)
++		return NULL;
++
++	pq->len--;
++
++	if (prec_out)
++		*prec_out = prec;
++
++	return p;
++}
++EXPORT_SYMBOL(brcmu_pktq_mdeq);
++
++#if defined(DEBUG)
++/* pretty hex print a pkt buffer chain */
++void brcmu_prpkt(const char *msg, struct sk_buff *p0)
++{
++	struct sk_buff *p;
++
++	if (msg && (msg[0] != '\0'))
++		pr_debug("%s:\n", msg);
++
++	for (p = p0; p; p = p->next)
++		print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, p->data, p->len);
++}
++EXPORT_SYMBOL(brcmu_prpkt);
++
++void brcmu_dbg_hex_dump(const void *data, size_t size, const char *fmt, ...)
++{
++	struct va_format vaf;
++	va_list args;
++
++	va_start(args, fmt);
++
++	vaf.fmt = fmt;
++	vaf.va = &args;
++
++	pr_debug("%pV", &vaf);
++
++	va_end(args);
++
++	print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, data, size);
++}
++EXPORT_SYMBOL(brcmu_dbg_hex_dump);
++#endif				/* defined(DEBUG) */
+diff --git a/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
+new file mode 100644
+index 0000000..333193f
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
+@@ -0,0 +1,41 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef	_BRCM_HW_IDS_H_
++#define	_BRCM_HW_IDS_H_
++
++#define BCM4313_D11N2G_ID	0x4727	/* 4313 802.11n 2.4G device */
++
++#define BCM43224_D11N_ID	0x4353	/* 43224 802.11n dualband device */
++#define BCM43224_D11N_ID_VEN1	0x0576	/* Vendor specific 43224 802.11n db */
++
++#define BCM43225_D11N2G_ID	0x4357	/* 43225 802.11n 2.4GHz device */
++
++#define BCM43236_D11N_ID	0x4346	/* 43236 802.11n dualband device */
++#define BCM43236_D11N2G_ID	0x4347	/* 43236 802.11n 2.4GHz device */
++
++/* Chipcommon Core Chip IDs */
++#define BCM4313_CHIP_ID		0x4313
++#define BCM43224_CHIP_ID	43224
++#define BCM43225_CHIP_ID	43225
++#define BCM43235_CHIP_ID	43235
++#define BCM43236_CHIP_ID	43236
++#define BCM43238_CHIP_ID	43238
++#define BCM4329_CHIP_ID		0x4329
++#define BCM4330_CHIP_ID		0x4330
++#define BCM4331_CHIP_ID		0x4331
++
++#endif				/* _BRCM_HW_IDS_H_ */
+diff --git a/drivers/net/wireless/brcm80211/include/brcmu_utils.h b/drivers/net/wireless/brcm80211/include/brcmu_utils.h
+new file mode 100644
+index 0000000..477b92a
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/include/brcmu_utils.h
+@@ -0,0 +1,196 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef	_BRCMU_UTILS_H_
++#define	_BRCMU_UTILS_H_
++
++#include <linux/skbuff.h>
++
++/*
++ * Spin at most 'us' microseconds while 'exp' is true.
++ * Caller should explicitly test 'exp' when this completes
++ * and take appropriate error action if 'exp' is still true.
++ */
++#define SPINWAIT(exp, us) { \
++	uint countdown = (us) + 9; \
++	while ((exp) && (countdown >= 10)) {\
++		udelay(10); \
++		countdown -= 10; \
++	} \
++}
++
++/* osl multi-precedence packet queue */
++#define PKTQ_LEN_DEFAULT        128	/* Max 128 packets */
++#define PKTQ_MAX_PREC           16	/* Maximum precedence levels */
++
++#define BCME_STRLEN		64	/* Max string length for BCM errors */
++
++/* the largest reasonable packet buffer driver uses for ethernet MTU in bytes */
++#define	PKTBUFSZ	2048
++
++#ifndef setbit
++#ifndef NBBY			/* the BSD family defines NBBY */
++#define	NBBY	8		/* 8 bits per byte */
++#endif				/* #ifndef NBBY */
++#define	setbit(a, i)	(((u8 *)a)[(i)/NBBY] |= 1<<((i)%NBBY))
++#define	clrbit(a, i)	(((u8 *)a)[(i)/NBBY] &= ~(1<<((i)%NBBY)))
++#define	isset(a, i)	(((const u8 *)a)[(i)/NBBY] & (1<<((i)%NBBY)))
++#define	isclr(a, i)	((((const u8 *)a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0)
++#endif				/* setbit */
++
++#define	NBITS(type)	(sizeof(type) * 8)
++#define NBITVAL(nbits)	(1 << (nbits))
++#define MAXBITVAL(nbits)	((1 << (nbits)) - 1)
++#define	NBITMASK(nbits)	MAXBITVAL(nbits)
++#define MAXNBVAL(nbyte)	MAXBITVAL((nbyte) * 8)
++
++/* crc defines */
++#define CRC16_INIT_VALUE 0xffff	/* Initial CRC16 checksum value */
++#define CRC16_GOOD_VALUE 0xf0b8	/* Good final CRC16 checksum value */
++
++/* 18-bytes of Ethernet address buffer length */
++#define ETHER_ADDR_STR_LEN	18
++
++struct pktq_prec {
++	struct sk_buff_head skblist;
++	u16 max;		/* maximum number of queued packets */
++};
++
++/* multi-priority pkt queue */
++struct pktq {
++	u16 num_prec;	/* number of precedences in use */
++	u16 hi_prec;	/* rapid dequeue hint (>= highest non-empty prec) */
++	u16 max;	/* total max packets */
++	u16 len;	/* total number of packets */
++	/*
++	 * q array must be last since # of elements can be either
++	 * PKTQ_MAX_PREC or 1
++	 */
++	struct pktq_prec q[PKTQ_MAX_PREC];
++};
++
++/* operations on a specific precedence in packet queue */
++
++static inline int pktq_plen(struct pktq *pq, int prec)
++{
++	return pq->q[prec].skblist.qlen;
++}
++
++static inline int pktq_pavail(struct pktq *pq, int prec)
++{
++	return pq->q[prec].max - pq->q[prec].skblist.qlen;
++}
++
++static inline bool pktq_pfull(struct pktq *pq, int prec)
++{
++	return pq->q[prec].skblist.qlen >= pq->q[prec].max;
++}
++
++static inline bool pktq_pempty(struct pktq *pq, int prec)
++{
++	return skb_queue_empty(&pq->q[prec].skblist);
++}
++
++static inline struct sk_buff *pktq_ppeek(struct pktq *pq, int prec)
++{
++	return skb_peek(&pq->q[prec].skblist);
++}
++
++static inline struct sk_buff *pktq_ppeek_tail(struct pktq *pq, int prec)
++{
++	return skb_peek_tail(&pq->q[prec].skblist);
++}
++
++extern struct sk_buff *brcmu_pktq_penq(struct pktq *pq, int prec,
++				 struct sk_buff *p);
++extern struct sk_buff *brcmu_pktq_penq_head(struct pktq *pq, int prec,
++				      struct sk_buff *p);
++extern struct sk_buff *brcmu_pktq_pdeq(struct pktq *pq, int prec);
++extern struct sk_buff *brcmu_pktq_pdeq_tail(struct pktq *pq, int prec);
++
++/* packet primitives */
++extern struct sk_buff *brcmu_pkt_buf_get_skb(uint len);
++extern void brcmu_pkt_buf_free_skb(struct sk_buff *skb);
++
++/* Empty the queue at particular precedence level */
++/* callback function fn(pkt, arg) returns true if pkt belongs to if */
++extern void brcmu_pktq_pflush(struct pktq *pq, int prec,
++	bool dir, bool (*fn)(struct sk_buff *, void *), void *arg);
++
++/* operations on a set of precedences in packet queue */
++
++extern int brcmu_pktq_mlen(struct pktq *pq, uint prec_bmp);
++extern struct sk_buff *brcmu_pktq_mdeq(struct pktq *pq, uint prec_bmp,
++	int *prec_out);
++
++/* operations on packet queue as a whole */
++
++static inline int pktq_len(struct pktq *pq)
++{
++	return (int)pq->len;
++}
++
++static inline int pktq_max(struct pktq *pq)
++{
++	return (int)pq->max;
++}
++
++static inline int pktq_avail(struct pktq *pq)
++{
++	return (int)(pq->max - pq->len);
++}
++
++static inline bool pktq_full(struct pktq *pq)
++{
++	return pq->len >= pq->max;
++}
++
++static inline bool pktq_empty(struct pktq *pq)
++{
++	return pq->len == 0;
++}
++
++extern void brcmu_pktq_init(struct pktq *pq, int num_prec, int max_len);
++/* prec_out may be NULL if caller is not interested in return value */
++extern struct sk_buff *brcmu_pktq_peek_tail(struct pktq *pq, int *prec_out);
++extern void brcmu_pktq_flush(struct pktq *pq, bool dir,
++		bool (*fn)(struct sk_buff *, void *), void *arg);
++
++/* externs */
++/* ip address */
++struct ipv4_addr;
++
++
++/* externs */
++/* format/print */
++#ifdef DEBUG
++extern void brcmu_prpkt(const char *msg, struct sk_buff *p0);
++#else
++#define brcmu_prpkt(a, b)
++#endif				/* DEBUG */
++
++#ifdef DEBUG
++extern __printf(3, 4)
++void brcmu_dbg_hex_dump(const void *data, size_t size, const char *fmt, ...);
++#else
++__printf(3, 4)
++static inline
++void brcmu_dbg_hex_dump(const void *data, size_t size, const char *fmt, ...)
++{
++}
++#endif
++
++#endif				/* _BRCMU_UTILS_H_ */
+diff --git a/drivers/net/wireless/brcm80211/include/brcmu_wifi.h b/drivers/net/wireless/brcm80211/include/brcmu_wifi.h
+new file mode 100644
+index 0000000..f10d302
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/include/brcmu_wifi.h
+@@ -0,0 +1,239 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef	_BRCMU_WIFI_H_
++#define	_BRCMU_WIFI_H_
++
++#include <linux/if_ether.h>		/* for ETH_ALEN */
++#include <linux/ieee80211.h>		/* for WLAN_PMKID_LEN */
++
++/*
++ * A chanspec (u16) holds the channel number, band, bandwidth and control
++ * sideband
++ */
++
++/* channel defines */
++#define CH_UPPER_SB			0x01
++#define CH_LOWER_SB			0x02
++#define CH_EWA_VALID			0x04
++#define CH_20MHZ_APART			4
++#define CH_10MHZ_APART			2
++#define CH_5MHZ_APART			1 /* 2G band channels are 5 Mhz apart */
++#define CH_MAX_2G_CHANNEL		14	/* Max channel in 2G band */
++#define BRCM_MAX_2G_CHANNEL	CH_MAX_2G_CHANNEL	/* legacy define */
++
++/* bandstate array indices */
++#define BAND_2G_INDEX		0	/* wlc->bandstate[x] index */
++#define BAND_5G_INDEX		1	/* wlc->bandstate[x] index */
++
++/*
++ * max # supported channels. The max channel no is 216, this is that + 1
++ * rounded up to a multiple of NBBY (8). DO NOT MAKE it > 255: channels are
++ * u8's all over
++*/
++#define	MAXCHANNEL		224
++
++#define WL_CHANSPEC_CHAN_MASK		0x00ff
++#define WL_CHANSPEC_CHAN_SHIFT		0
++
++#define WL_CHANSPEC_CTL_SB_MASK		0x0300
++#define WL_CHANSPEC_CTL_SB_SHIFT	     8
++#define WL_CHANSPEC_CTL_SB_LOWER	0x0100
++#define WL_CHANSPEC_CTL_SB_UPPER	0x0200
++#define WL_CHANSPEC_CTL_SB_NONE		0x0300
++
++#define WL_CHANSPEC_BW_MASK		0x0C00
++#define WL_CHANSPEC_BW_SHIFT		    10
++#define WL_CHANSPEC_BW_10		0x0400
++#define WL_CHANSPEC_BW_20		0x0800
++#define WL_CHANSPEC_BW_40		0x0C00
++
++#define WL_CHANSPEC_BAND_MASK		0xf000
++#define WL_CHANSPEC_BAND_SHIFT		12
++#define WL_CHANSPEC_BAND_5G		0x1000
++#define WL_CHANSPEC_BAND_2G		0x2000
++#define INVCHANSPEC			255
++
++/* used to calculate the chan_freq = chan_factor * 500Mhz + 5 * chan_number */
++#define WF_CHAN_FACTOR_2_4_G		4814	/* 2.4 GHz band, 2407 MHz */
++#define WF_CHAN_FACTOR_5_G		10000	/* 5   GHz band, 5000 MHz */
++#define WF_CHAN_FACTOR_4_G		8000	/* 4.9 GHz band for Japan */
++
++#define CHSPEC_CHANNEL(chspec)	((u8)((chspec) & WL_CHANSPEC_CHAN_MASK))
++#define CHSPEC_BAND(chspec)	((chspec) & WL_CHANSPEC_BAND_MASK)
++
++#define CHSPEC_CTL_SB(chspec)	((chspec) & WL_CHANSPEC_CTL_SB_MASK)
++#define CHSPEC_BW(chspec)	((chspec) & WL_CHANSPEC_BW_MASK)
++
++#define CHSPEC_IS10(chspec) \
++	(((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_10)
++
++#define CHSPEC_IS20(chspec) \
++	(((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_20)
++
++#ifndef CHSPEC_IS40
++#define CHSPEC_IS40(chspec) \
++	(((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_40)
++#endif
++
++#define CHSPEC_IS5G(chspec) \
++	(((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_5G)
++
++#define CHSPEC_IS2G(chspec) \
++	(((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_2G)
++
++#define CHSPEC_SB_NONE(chspec) \
++	(((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_NONE)
++
++#define CHSPEC_SB_UPPER(chspec) \
++	(((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_UPPER)
++
++#define CHSPEC_SB_LOWER(chspec) \
++	(((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_LOWER)
++
++#define CHSPEC_CTL_CHAN(chspec) \
++	((CHSPEC_SB_LOWER(chspec)) ? \
++	(lower_20_sb(((chspec) & WL_CHANSPEC_CHAN_MASK))) : \
++	(upper_20_sb(((chspec) & WL_CHANSPEC_CHAN_MASK))))
++
++#define CHSPEC2BAND(chspec) (CHSPEC_IS5G(chspec) ? BRCM_BAND_5G : BRCM_BAND_2G)
++
++#define CHANSPEC_STR_LEN    8
++
++static inline int lower_20_sb(int channel)
++{
++	return channel > CH_10MHZ_APART ? (channel - CH_10MHZ_APART) : 0;
++}
++
++static inline int upper_20_sb(int channel)
++{
++	return (channel < (MAXCHANNEL - CH_10MHZ_APART)) ?
++	       channel + CH_10MHZ_APART : 0;
++}
++
++static inline int chspec_bandunit(u16 chspec)
++{
++	return CHSPEC_IS5G(chspec) ? BAND_5G_INDEX : BAND_2G_INDEX;
++}
++
++static inline u16 ch20mhz_chspec(int channel)
++{
++	u16 rc = channel <= CH_MAX_2G_CHANNEL ?
++		 WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G;
++
++	return	(u16)((u16)channel | WL_CHANSPEC_BW_20 |
++		      WL_CHANSPEC_CTL_SB_NONE | rc);
++}
++
++static inline int next_20mhz_chan(int channel)
++{
++	return channel < (MAXCHANNEL - CH_20MHZ_APART) ?
++	       channel + CH_20MHZ_APART : 0;
++}
++
++/* defined rate in 500kbps */
++#define BRCM_MAXRATE	108	/* in 500kbps units */
++#define BRCM_RATE_1M	2	/* in 500kbps units */
++#define BRCM_RATE_2M	4	/* in 500kbps units */
++#define BRCM_RATE_5M5	11	/* in 500kbps units */
++#define BRCM_RATE_11M	22	/* in 500kbps units */
++#define BRCM_RATE_6M	12	/* in 500kbps units */
++#define BRCM_RATE_9M	18	/* in 500kbps units */
++#define BRCM_RATE_12M	24	/* in 500kbps units */
++#define BRCM_RATE_18M	36	/* in 500kbps units */
++#define BRCM_RATE_24M	48	/* in 500kbps units */
++#define BRCM_RATE_36M	72	/* in 500kbps units */
++#define BRCM_RATE_48M	96	/* in 500kbps units */
++#define BRCM_RATE_54M	108	/* in 500kbps units */
++
++#define BRCM_2G_25MHZ_OFFSET		5	/* 2.4GHz band channel offset */
++
++#define MCSSET_LEN	16
++
++static inline bool ac_bitmap_tst(u8 bitmap, int prec)
++{
++	return (bitmap & (1 << (prec))) != 0;
++}
++
++/* Enumerate crypto algorithms */
++#define	CRYPTO_ALGO_OFF			0
++#define	CRYPTO_ALGO_WEP1		1
++#define	CRYPTO_ALGO_TKIP		2
++#define	CRYPTO_ALGO_WEP128		3
++#define CRYPTO_ALGO_AES_CCM		4
++#define CRYPTO_ALGO_AES_RESERVED1	5
++#define CRYPTO_ALGO_AES_RESERVED2	6
++#define CRYPTO_ALGO_NALG		7
++
++/* wireless security bitvec */
++
++#define WEP_ENABLED		0x0001
++#define TKIP_ENABLED		0x0002
++#define AES_ENABLED		0x0004
++#define WSEC_SWFLAG		0x0008
++/* to go into transition mode without setting wep */
++#define SES_OW_ENABLED		0x0040
++
++/* WPA authentication mode bitvec */
++#define WPA_AUTH_DISABLED	0x0000	/* Legacy (i.e., non-WPA) */
++#define WPA_AUTH_NONE		0x0001	/* none (IBSS) */
++#define WPA_AUTH_UNSPECIFIED	0x0002	/* over 802.1x */
++#define WPA_AUTH_PSK		0x0004	/* Pre-shared key */
++#define WPA_AUTH_RESERVED1	0x0008
++#define WPA_AUTH_RESERVED2	0x0010
++
++#define WPA2_AUTH_RESERVED1	0x0020
++#define WPA2_AUTH_UNSPECIFIED	0x0040	/* over 802.1x */
++#define WPA2_AUTH_PSK		0x0080	/* Pre-shared key */
++#define WPA2_AUTH_RESERVED3	0x0200
++#define WPA2_AUTH_RESERVED4	0x0400
++#define WPA2_AUTH_RESERVED5	0x0800
++
++/* pmkid */
++#define	MAXPMKID		16
++
++#define DOT11_DEFAULT_RTS_LEN		2347
++#define DOT11_DEFAULT_FRAG_LEN		2346
++
++#define DOT11_ICV_AES_LEN		8
++#define DOT11_QOS_LEN			2
++#define DOT11_IV_MAX_LEN		8
++#define DOT11_A4_HDR_LEN		30
++
++#define HT_CAP_RX_STBC_NO		0x0
++#define HT_CAP_RX_STBC_ONE_STREAM	0x1
++
++struct pmkid {
++	u8 BSSID[ETH_ALEN];
++	u8 PMKID[WLAN_PMKID_LEN];
++};
++
++struct pmkid_list {
++	__le32 npmkid;
++	struct pmkid pmkid[1];
++};
++
++struct pmkid_cand {
++	u8 BSSID[ETH_ALEN];
++	u8 preauth;
++};
++
++struct pmkid_cand_list {
++	u32 npmkid_cand;
++	struct pmkid_cand pmkid_cand[1];
++};
++
++#endif				/* _BRCMU_WIFI_H_ */
+diff --git a/drivers/net/wireless/brcm80211/include/chipcommon.h b/drivers/net/wireless/brcm80211/include/chipcommon.h
+new file mode 100644
+index 0000000..f96834a
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/include/chipcommon.h
+@@ -0,0 +1,286 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef	_SBCHIPC_H
++#define	_SBCHIPC_H
++
++#include "defs.h"		/* for PAD macro */
++
++#define CHIPCREGOFFS(field)	offsetof(struct chipcregs, field)
++
++struct chipcregs {
++	u32 chipid;		/* 0x0 */
++	u32 capabilities;
++	u32 corecontrol;	/* corerev >= 1 */
++	u32 bist;
++
++	/* OTP */
++	u32 otpstatus;	/* 0x10, corerev >= 10 */
++	u32 otpcontrol;
++	u32 otpprog;
++	u32 otplayout;	/* corerev >= 23 */
++
++	/* Interrupt control */
++	u32 intstatus;	/* 0x20 */
++	u32 intmask;
++
++	/* Chip specific regs */
++	u32 chipcontrol;	/* 0x28, rev >= 11 */
++	u32 chipstatus;	/* 0x2c, rev >= 11 */
++
++	/* Jtag Master */
++	u32 jtagcmd;		/* 0x30, rev >= 10 */
++	u32 jtagir;
++	u32 jtagdr;
++	u32 jtagctrl;
++
++	/* serial flash interface registers */
++	u32 flashcontrol;	/* 0x40 */
++	u32 flashaddress;
++	u32 flashdata;
++	u32 PAD[1];
++
++	/* Silicon backplane configuration broadcast control */
++	u32 broadcastaddress;	/* 0x50 */
++	u32 broadcastdata;
++
++	/* gpio - cleared only by power-on-reset */
++	u32 gpiopullup;	/* 0x58, corerev >= 20 */
++	u32 gpiopulldown;	/* 0x5c, corerev >= 20 */
++	u32 gpioin;		/* 0x60 */
++	u32 gpioout;		/* 0x64 */
++	u32 gpioouten;	/* 0x68 */
++	u32 gpiocontrol;	/* 0x6C */
++	u32 gpiointpolarity;	/* 0x70 */
++	u32 gpiointmask;	/* 0x74 */
++
++	/* GPIO events corerev >= 11 */
++	u32 gpioevent;
++	u32 gpioeventintmask;
++
++	/* Watchdog timer */
++	u32 watchdog;	/* 0x80 */
++
++	/* GPIO events corerev >= 11 */
++	u32 gpioeventintpolarity;
++
++	/* GPIO based LED powersave registers corerev >= 16 */
++	u32 gpiotimerval;	/* 0x88 */
++	u32 gpiotimeroutmask;
++
++	/* clock control */
++	u32 clockcontrol_n;	/* 0x90 */
++	u32 clockcontrol_sb;	/* aka m0 */
++	u32 clockcontrol_pci;	/* aka m1 */
++	u32 clockcontrol_m2;	/* mii/uart/mipsref */
++	u32 clockcontrol_m3;	/* cpu */
++	u32 clkdiv;		/* corerev >= 3 */
++	u32 gpiodebugsel;	/* corerev >= 28 */
++	u32 capabilities_ext;	/* 0xac  */
++
++	/* pll delay registers (corerev >= 4) */
++	u32 pll_on_delay;	/* 0xb0 */
++	u32 fref_sel_delay;
++	u32 slow_clk_ctl;	/* 5 < corerev < 10 */
++	u32 PAD;
++
++	/* Instaclock registers (corerev >= 10) */
++	u32 system_clk_ctl;	/* 0xc0 */
++	u32 clkstatestretch;
++	u32 PAD[2];
++
++	/* Indirect backplane access (corerev >= 22) */
++	u32 bp_addrlow;	/* 0xd0 */
++	u32 bp_addrhigh;
++	u32 bp_data;
++	u32 PAD;
++	u32 bp_indaccess;
++	u32 PAD[3];
++
++	/* More clock dividers (corerev >= 32) */
++	u32 clkdiv2;
++	u32 PAD[2];
++
++	/* In AI chips, pointer to erom */
++	u32 eromptr;		/* 0xfc */
++
++	/* ExtBus control registers (corerev >= 3) */
++	u32 pcmcia_config;	/* 0x100 */
++	u32 pcmcia_memwait;
++	u32 pcmcia_attrwait;
++	u32 pcmcia_iowait;
++	u32 ide_config;
++	u32 ide_memwait;
++	u32 ide_attrwait;
++	u32 ide_iowait;
++	u32 prog_config;
++	u32 prog_waitcount;
++	u32 flash_config;
++	u32 flash_waitcount;
++	u32 SECI_config;	/* 0x130 SECI configuration */
++	u32 PAD[3];
++
++	/* Enhanced Coexistence Interface (ECI) registers (corerev >= 21) */
++	u32 eci_output;	/* 0x140 */
++	u32 eci_control;
++	u32 eci_inputlo;
++	u32 eci_inputmi;
++	u32 eci_inputhi;
++	u32 eci_inputintpolaritylo;
++	u32 eci_inputintpolaritymi;
++	u32 eci_inputintpolarityhi;
++	u32 eci_intmasklo;
++	u32 eci_intmaskmi;
++	u32 eci_intmaskhi;
++	u32 eci_eventlo;
++	u32 eci_eventmi;
++	u32 eci_eventhi;
++	u32 eci_eventmasklo;
++	u32 eci_eventmaskmi;
++	u32 eci_eventmaskhi;
++	u32 PAD[3];
++
++	/* SROM interface (corerev >= 32) */
++	u32 sromcontrol;	/* 0x190 */
++	u32 sromaddress;
++	u32 sromdata;
++	u32 PAD[17];
++
++	/* Clock control and hardware workarounds (corerev >= 20) */
++	u32 clk_ctl_st;	/* 0x1e0 */
++	u32 hw_war;
++	u32 PAD[70];
++
++	/* UARTs */
++	u8 uart0data;	/* 0x300 */
++	u8 uart0imr;
++	u8 uart0fcr;
++	u8 uart0lcr;
++	u8 uart0mcr;
++	u8 uart0lsr;
++	u8 uart0msr;
++	u8 uart0scratch;
++	u8 PAD[248];		/* corerev >= 1 */
++
++	u8 uart1data;	/* 0x400 */
++	u8 uart1imr;
++	u8 uart1fcr;
++	u8 uart1lcr;
++	u8 uart1mcr;
++	u8 uart1lsr;
++	u8 uart1msr;
++	u8 uart1scratch;
++	u32 PAD[126];
++
++	/* PMU registers (corerev >= 20) */
++	u32 pmucontrol;	/* 0x600 */
++	u32 pmucapabilities;
++	u32 pmustatus;
++	u32 res_state;
++	u32 res_pending;
++	u32 pmutimer;
++	u32 min_res_mask;
++	u32 max_res_mask;
++	u32 res_table_sel;
++	u32 res_dep_mask;
++	u32 res_updn_timer;
++	u32 res_timer;
++	u32 clkstretch;
++	u32 pmuwatchdog;
++	u32 gpiosel;		/* 0x638, rev >= 1 */
++	u32 gpioenable;	/* 0x63c, rev >= 1 */
++	u32 res_req_timer_sel;
++	u32 res_req_timer;
++	u32 res_req_mask;
++	u32 PAD;
++	u32 chipcontrol_addr;	/* 0x650 */
++	u32 chipcontrol_data;	/* 0x654 */
++	u32 regcontrol_addr;
++	u32 regcontrol_data;
++	u32 pllcontrol_addr;
++	u32 pllcontrol_data;
++	u32 pmustrapopt;	/* 0x668, corerev >= 28 */
++	u32 pmu_xtalfreq;	/* 0x66C, pmurev >= 10 */
++	u32 PAD[100];
++	u16 sromotp[768];
++};
++
++/* chipid */
++#define	CID_ID_MASK		0x0000ffff	/* Chip Id mask */
++#define	CID_REV_MASK		0x000f0000	/* Chip Revision mask */
++#define	CID_REV_SHIFT		16	/* Chip Revision shift */
++#define	CID_PKG_MASK		0x00f00000	/* Package Option mask */
++#define	CID_PKG_SHIFT		20	/* Package Option shift */
++#define	CID_CC_MASK		0x0f000000	/* CoreCount (corerev >= 4) */
++#define CID_CC_SHIFT		24
++#define	CID_TYPE_MASK		0xf0000000	/* Chip Type */
++#define CID_TYPE_SHIFT		28
++
++/* capabilities */
++#define	CC_CAP_UARTS_MASK	0x00000003	/* Number of UARTs */
++#define CC_CAP_MIPSEB		0x00000004	/* MIPS is in big-endian mode */
++#define CC_CAP_UCLKSEL		0x00000018	/* UARTs clock select */
++/* UARTs are driven by internal divided clock */
++#define CC_CAP_UINTCLK		0x00000008
++#define CC_CAP_UARTGPIO		0x00000020	/* UARTs own GPIOs 15:12 */
++#define CC_CAP_EXTBUS_MASK	0x000000c0	/* External bus mask */
++#define CC_CAP_EXTBUS_NONE	0x00000000	/* No ExtBus present */
++#define CC_CAP_EXTBUS_FULL	0x00000040	/* ExtBus: PCMCIA, IDE & Prog */
++#define CC_CAP_EXTBUS_PROG	0x00000080	/* ExtBus: ProgIf only */
++#define	CC_CAP_FLASH_MASK	0x00000700	/* Type of flash */
++#define	CC_CAP_PLL_MASK		0x00038000	/* Type of PLL */
++#define CC_CAP_PWR_CTL		0x00040000	/* Power control */
++#define CC_CAP_OTPSIZE		0x00380000	/* OTP Size (0 = none) */
++#define CC_CAP_OTPSIZE_SHIFT	19	/* OTP Size shift */
++#define CC_CAP_OTPSIZE_BASE	5	/* OTP Size base */
++#define CC_CAP_JTAGP		0x00400000	/* JTAG Master Present */
++#define CC_CAP_ROM		0x00800000	/* Internal boot rom active */
++#define CC_CAP_BKPLN64		0x08000000	/* 64-bit backplane */
++#define	CC_CAP_PMU		0x10000000	/* PMU Present, rev >= 20 */
++#define	CC_CAP_SROM		0x40000000	/* Srom Present, rev >= 32 */
++/* Nand flash present, rev >= 35 */
++#define	CC_CAP_NFLASH		0x80000000
++
++#define	CC_CAP2_SECI		0x00000001	/* SECI Present, rev >= 36 */
++/* GSIO (spi/i2c) present, rev >= 37 */
++#define	CC_CAP2_GSIO		0x00000002
++
++/* pmucapabilities */
++#define PCAP_REV_MASK	0x000000ff
++#define PCAP_RC_MASK	0x00001f00
++#define PCAP_RC_SHIFT	8
++#define PCAP_TC_MASK	0x0001e000
++#define PCAP_TC_SHIFT	13
++#define PCAP_PC_MASK	0x001e0000
++#define PCAP_PC_SHIFT	17
++#define PCAP_VC_MASK	0x01e00000
++#define PCAP_VC_SHIFT	21
++#define PCAP_CC_MASK	0x1e000000
++#define PCAP_CC_SHIFT	25
++#define PCAP5_PC_MASK	0x003e0000	/* PMU corerev >= 5 */
++#define PCAP5_PC_SHIFT	17
++#define PCAP5_VC_MASK	0x07c00000
++#define PCAP5_VC_SHIFT	22
++#define PCAP5_CC_MASK	0xf8000000
++#define PCAP5_CC_SHIFT	27
++
++/*
++* Maximum delay for the PMU state transition in us.
++* This is an upper bound intended for spinwaits etc.
++*/
++#define PMU_MAX_TRANSITION_DLY	15000
++
++#endif				/* _SBCHIPC_H */
+diff --git a/drivers/net/wireless/brcm80211/include/defs.h b/drivers/net/wireless/brcm80211/include/defs.h
+new file mode 100644
+index 0000000..f0d8c04
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/include/defs.h
+@@ -0,0 +1,103 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef	_BRCM_DEFS_H_
++#define	_BRCM_DEFS_H_
++
++#include <linux/types.h>
++
++#define	SI_BUS			0
++#define	PCI_BUS			1
++#define	PCMCIA_BUS		2
++#define SDIO_BUS		3
++#define JTAG_BUS		4
++#define USB_BUS			5
++#define SPI_BUS			6
++
++#define	OFF	0
++#define	ON	1		/* ON = 1 */
++#define	AUTO	(-1)		/* Auto = -1 */
++
++/*
++ * Priority definitions according 802.1D
++ */
++#define	PRIO_8021D_NONE		2
++#define	PRIO_8021D_BK		1
++#define	PRIO_8021D_BE		0
++#define	PRIO_8021D_EE		3
++#define	PRIO_8021D_CL		4
++#define	PRIO_8021D_VI		5
++#define	PRIO_8021D_VO		6
++#define	PRIO_8021D_NC		7
++
++#define	MAXPRIO			7
++#define NUMPRIO			(MAXPRIO + 1)
++
++#define WL_NUMRATES		16	/* max # of rates in a rateset */
++
++#define BRCM_CNTRY_BUF_SZ	4	/* Country string is 3 bytes + NUL */
++
++#define BRCM_SET_CHANNEL	30
++#define BRCM_SET_SRL		32
++#define BRCM_SET_LRL		34
++#define BRCM_SET_BCNPRD		76
++
++#define BRCM_GET_CURR_RATESET	114	/* current rateset */
++#define BRCM_GET_PHYLIST	180
++
++/* Bit masks for radio disabled status - returned by WL_GET_RADIO */
++
++#define WL_RADIO_SW_DISABLE		(1<<0)
++#define WL_RADIO_HW_DISABLE		(1<<1)
++/* some countries don't support any channel */
++#define WL_RADIO_COUNTRY_DISABLE	(1<<3)
++
++/* Override bit for SET_TXPWR.  if set, ignore other level limits */
++#define WL_TXPWR_OVERRIDE	(1U<<31)
++
++/* band types */
++#define	BRCM_BAND_AUTO		0	/* auto-select */
++#define	BRCM_BAND_5G		1	/* 5 Ghz */
++#define	BRCM_BAND_2G		2	/* 2.4 Ghz */
++#define	BRCM_BAND_ALL		3	/* all bands */
++
++/* Values for PM */
++#define PM_OFF	0
++#define PM_MAX	1
++
++/* Message levels */
++#define LOG_ERROR_VAL		0x00000001
++#define LOG_TRACE_VAL		0x00000002
++
++#define PM_OFF	0
++#define PM_MAX	1
++#define PM_FAST 2
++
++/*
++ * Sonics Configuration Space Registers.
++ */
++
++/* core sbconfig regs are top 256bytes of regs */
++#define	SBCONFIGOFF		0xf00
++
++/* cpp contortions to concatenate w/arg prescan */
++#ifndef	PAD
++#define	_PADLINE(line)	pad ## line
++#define	_XSTR(line)	_PADLINE(line)
++#define	PAD		_XSTR(__LINE__)
++#endif
++
++#endif				/* _BRCM_DEFS_H_ */
+diff --git a/drivers/net/wireless/brcm80211/include/soc.h b/drivers/net/wireless/brcm80211/include/soc.h
+new file mode 100644
+index 0000000..4e9b7e4
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/include/soc.h
+@@ -0,0 +1,98 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef	_BRCM_SOC_H
++#define	_BRCM_SOC_H
++
++#define SI_ENUM_BASE		0x18000000	/* Enumeration space base */
++
++/* core codes */
++#define	NODEV_CORE_ID		0x700	/* Invalid coreid */
++#define	CC_CORE_ID		0x800	/* chipcommon core */
++#define	ILINE20_CORE_ID		0x801	/* iline20 core */
++#define	SRAM_CORE_ID		0x802	/* sram core */
++#define	SDRAM_CORE_ID		0x803	/* sdram core */
++#define	PCI_CORE_ID		0x804	/* pci core */
++#define	MIPS_CORE_ID		0x805	/* mips core */
++#define	ENET_CORE_ID		0x806	/* enet mac core */
++#define	CODEC_CORE_ID		0x807	/* v90 codec core */
++#define	USB_CORE_ID		0x808	/* usb 1.1 host/device core */
++#define	ADSL_CORE_ID		0x809	/* ADSL core */
++#define	ILINE100_CORE_ID	0x80a	/* iline100 core */
++#define	IPSEC_CORE_ID		0x80b	/* ipsec core */
++#define	UTOPIA_CORE_ID		0x80c	/* utopia core */
++#define	PCMCIA_CORE_ID		0x80d	/* pcmcia core */
++#define	SOCRAM_CORE_ID		0x80e	/* internal memory core */
++#define	MEMC_CORE_ID		0x80f	/* memc sdram core */
++#define	OFDM_CORE_ID		0x810	/* OFDM phy core */
++#define	EXTIF_CORE_ID		0x811	/* external interface core */
++#define	D11_CORE_ID		0x812	/* 802.11 MAC core */
++#define	APHY_CORE_ID		0x813	/* 802.11a phy core */
++#define	BPHY_CORE_ID		0x814	/* 802.11b phy core */
++#define	GPHY_CORE_ID		0x815	/* 802.11g phy core */
++#define	MIPS33_CORE_ID		0x816	/* mips3302 core */
++#define	USB11H_CORE_ID		0x817	/* usb 1.1 host core */
++#define	USB11D_CORE_ID		0x818	/* usb 1.1 device core */
++#define	USB20H_CORE_ID		0x819	/* usb 2.0 host core */
++#define	USB20D_CORE_ID		0x81a	/* usb 2.0 device core */
++#define	SDIOH_CORE_ID		0x81b	/* sdio host core */
++#define	ROBO_CORE_ID		0x81c	/* roboswitch core */
++#define	ATA100_CORE_ID		0x81d	/* parallel ATA core */
++#define	SATAXOR_CORE_ID		0x81e	/* serial ATA & XOR DMA core */
++#define	GIGETH_CORE_ID		0x81f	/* gigabit ethernet core */
++#define	PCIE_CORE_ID		0x820	/* pci express core */
++#define	NPHY_CORE_ID		0x821	/* 802.11n 2x2 phy core */
++#define	SRAMC_CORE_ID		0x822	/* SRAM controller core */
++#define	MINIMAC_CORE_ID		0x823	/* MINI MAC/phy core */
++#define	ARM11_CORE_ID		0x824	/* ARM 1176 core */
++#define	ARM7S_CORE_ID		0x825	/* ARM7tdmi-s core */
++#define	LPPHY_CORE_ID		0x826	/* 802.11a/b/g phy core */
++#define	PMU_CORE_ID		0x827	/* PMU core */
++#define	SSNPHY_CORE_ID		0x828	/* 802.11n single-stream phy core */
++#define	SDIOD_CORE_ID		0x829	/* SDIO device core */
++#define	ARMCM3_CORE_ID		0x82a	/* ARM Cortex M3 core */
++#define	HTPHY_CORE_ID		0x82b	/* 802.11n 4x4 phy core */
++#define	MIPS74K_CORE_ID		0x82c	/* mips 74k core */
++#define	GMAC_CORE_ID		0x82d	/* Gigabit MAC core */
++#define	DMEMC_CORE_ID		0x82e	/* DDR1/2 memory controller core */
++#define	PCIERC_CORE_ID		0x82f	/* PCIE Root Complex core */
++#define	OCP_CORE_ID		0x830	/* OCP2OCP bridge core */
++#define	SC_CORE_ID		0x831	/* shared common core */
++#define	AHB_CORE_ID		0x832	/* OCP2AHB bridge core */
++#define	SPIH_CORE_ID		0x833	/* SPI host core */
++#define	I2S_CORE_ID		0x834	/* I2S core */
++#define	DMEMS_CORE_ID		0x835	/* SDR/DDR1 memory controller core */
++#define	DEF_SHIM_COMP		0x837	/* SHIM component in ubus/6362 */
++#define OOB_ROUTER_CORE_ID	0x367	/* OOB router core ID */
++#define	DEF_AI_COMP		0xfff	/* Default component, in ai chips it
++					 * maps all unused address ranges
++					 */
++
++/* Common core control flags */
++#define	SICF_BIST_EN		0x8000
++#define	SICF_PME_EN		0x4000
++#define	SICF_CORE_BITS		0x3ffc
++#define	SICF_FGC		0x0002
++#define	SICF_CLOCK_EN		0x0001
++
++/* Common core status flags */
++#define	SISF_BIST_DONE		0x8000
++#define	SISF_BIST_ERROR		0x4000
++#define	SISF_GATED_CLK		0x2000
++#define	SISF_DMA64		0x1000
++#define	SISF_CORE_BITS		0x0fff
++
++#endif				/* _BRCM_SOC_H */
+-- 
+1.7.9.5
+
-- 
1.7.9.5



  parent reply	other threads:[~2013-03-16 13:46 UTC|newest]

Thread overview: 716+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <yes>
2009-01-16 18:08 ` Quota fixes and improvements Jan Kara
2009-01-16 18:08   ` [PATCH 01/11] quota: Improve locking Jan Kara
2009-01-16 18:08     ` [PATCH 02/11] ocfs2: Remove ocfs2_dquot_initialize() and ocfs2_dquot_drop() Jan Kara
2009-01-16 18:08       ` [PATCH 03/11] ocfs2: Push out dropping of dentry lock to ocfs2_wq Jan Kara
2009-01-16 18:08         ` [PATCH 04/11] ocfs2: Fix possible deadlock in ocfs2_write_dquot() Jan Kara
2009-01-16 18:08           ` [PATCH 05/11] quota: Add quota reservation support Jan Kara
2009-01-16 18:08             ` [PATCH 06/11] quota: Add quota reservation claim and released operations Jan Kara
2009-01-16 18:08               ` [PATCH 07/11] quota: Use inode->i_blkbits to get block bits Jan Kara
2009-01-16 18:08                 ` [PATCH 08/11] quota: Move EXPORT_SYMBOL immediately next to the functions/varibles Jan Kara
2009-01-16 18:08                   ` [PATCH 09/11] ext3: Remove unnecessary quota functions Jan Kara
2009-01-16 18:08                     ` [PATCH 10/11] ext4: " Jan Kara
2009-01-16 18:08                       ` [PATCH 11/11] reiserfs: " Jan Kara
2009-01-16 18:08                         ` Jan Kara
2009-01-20 21:41                       ` [PATCH 10/11] ext4: " Mingming Cao
2009-01-20 21:41                         ` Mingming Cao
2009-01-20 21:41                     ` [PATCH 09/11] ext3: " Mingming Cao
2009-01-20 21:41                       ` Mingming Cao
2009-01-24  7:49     ` [PATCH 01/11] quota: Improve locking Andrew Morton
2009-01-26 10:04       ` Jan Kara
2009-05-31 14:49 ` [PATCH 0/8] kernel:lockdep:replace DFS with BFS tom.leiming
2009-05-31 14:49   ` [PATCH 1/8] kernel:lockdep:improve implementation of BFS tom.leiming
2009-05-31 14:49     ` [PATCH 2/8] kernel:lockdep: introduce match function to BFS tom.leiming
2009-05-31 14:49       ` [PATCH 3/8] kernel:lockdep:implement check_noncircular() by BFS tom.leiming
2009-05-31 14:49         ` [PATCH 4/8] kernel:lockdep:implement find_usage_*wards " tom.leiming
2009-05-31 14:49           ` [PATCH 5/8] kernel:lockdep:introduce print_shortest_lock_dependencies tom.leiming
2009-05-31 14:49             ` [PATCH 6/8] kernel:lockdep: implement lockdep_count_*ward_deps by BFS tom.leiming
2009-05-31 14:49               ` [PATCH 7/8] kernel:lockdep: update memory usage introduced " tom.leiming
2009-05-31 14:49                 ` [PATCH 8/8] kernel:lockdep:add statistics info for max bfs queue depth tom.leiming
2009-05-31 15:14           ` [PATCH 4/8] kernel:lockdep:implement find_usage_*wards by BFS Daniel Walker
2009-06-01  0:14             ` Ming Lei
2009-06-08 12:22   ` [PATCH 0/8] kernel:lockdep:replace DFS with BFS Peter Zijlstra
2009-06-08 13:38     ` Ming Lei
2009-06-08 13:58     ` Ming Lei
2009-06-08 14:04       ` Peter Zijlstra
2009-06-08 15:50     ` Ming Lei
2009-06-09 12:52       ` Ming Lei
2009-07-28 16:34 ` [U-Boot] [RFC 0/3] uboot-doc User's Manual Generation Tool John Schmoller
2009-07-28 17:49   ` Wolfgang Denk
2009-07-28 20:40     ` jschmoller
2009-07-28 21:27       ` Wolfgang Denk
2009-07-28 22:16         ` Robin Getz
2009-07-30  9:59           ` Detlev Zundel
2009-07-30 18:45             ` Wolfgang Denk
2009-07-30 19:50               ` Robin Getz
2009-07-30 19:55                 ` Wolfgang Denk
2009-07-31  1:49                   ` Robin Getz
2009-08-13  7:32             ` Mike Frysinger
2009-07-29 14:48         ` jschmoller
2009-07-28 16:34 ` [U-Boot] [RFC 1/3] uboot-doc: Initial support of user documentation generator John Schmoller
2009-07-28 16:34 ` [U-Boot] [RFC 2/3] uboot-doc: Add example support for uboot-doc John Schmoller
2009-07-28 17:52   ` Wolfgang Denk
2009-07-28 20:42     ` jschmoller
2009-07-28 21:37       ` Wolfgang Denk
2009-07-28 16:34 ` [U-Boot] [RFC 3/3] xpedite5370: Add uboot-doc support John Schmoller
2009-10-07 13:49 ` [PATCH 1/1] perf tools: Up the verbose level for some really verbose stuff Arnaldo Carvalho de Melo
2009-10-08 17:31   ` [tip:perf/core] " tip-bot for Arnaldo Carvalho de Melo
2010-06-22 15:20 ` [RFC][PATCH 00/10] cifs: local caching support using FS-Cache Suresh Jayaraman
2010-06-22 15:20   ` Suresh Jayaraman
2010-06-22 15:22 ` [RFC][PATCH 01/10] cifs: add kernel config option for CIFS Client caching support Suresh Jayaraman
2010-06-22 15:22 ` [RFC][PATCH 02/10] cifs: guard cifsglob.h against multiple inclusion Suresh Jayaraman
     [not found]   ` <1277220170-3442-1-git-send-email-sjayaraman-l3A5Bk7waGM@public.gmane.org>
2010-06-22 21:37     ` Jeff Layton
2010-06-22 21:37       ` Jeff Layton
2010-06-22 15:23 ` [RFC][PATCH 03/10] cifs: register CIFS for caching Suresh Jayaraman
2010-06-22 15:23   ` Suresh Jayaraman
2010-06-22 15:23 ` [RFC][PATCH 04/10] cifs: define server-level cache index objects and register them with FS-Cache Suresh Jayaraman
2010-06-22 15:23   ` Suresh Jayaraman
     [not found]   ` <1277220198-3522-1-git-send-email-sjayaraman-l3A5Bk7waGM@public.gmane.org>
2010-06-22 21:52     ` Jeff Layton
2010-06-22 21:52       ` Jeff Layton
     [not found]       ` <20100622175214.4c56234f-4QP7MXygkU+dMjc06nkz3ljfA9RmPOcC@public.gmane.org>
2010-06-23  5:34         ` Suresh Jayaraman
2010-06-23  5:34           ` Suresh Jayaraman
2010-06-22 15:23 ` [RFC][PATCH 05/10] cifs: define superblock-level cache index objects and register them Suresh Jayaraman
2010-06-22 15:23   ` Suresh Jayaraman
2010-06-22 15:23 ` [RFC][PATCH 06/10] cifs: define inode-level cache object " Suresh Jayaraman
2010-06-22 15:23 ` [RFC][PATCH 07/10] cifs: FS-Cache page management Suresh Jayaraman
2010-06-22 15:24 ` [RFC][PATCH 08/10] cifs: store pages into local cache Suresh Jayaraman
2010-06-22 15:24 ` [RFC][PATCH 09/10] cifs: read pages from FS-Cache Suresh Jayaraman
2010-06-22 15:24   ` Suresh Jayaraman
2010-06-22 15:25 ` [RFC][PATCH 10/10] cifs: add mount option to enable local caching Suresh Jayaraman
2010-06-22 15:25   ` Suresh Jayaraman
2010-06-23 18:32   ` Scott Lovenberg
     [not found]     ` <4C225338.9010807-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2010-06-25 10:48       ` Suresh Jayaraman
2010-06-25 10:48         ` Suresh Jayaraman
     [not found] ` <1277220189-3485-1-git-send-email-sjayaraman-l3A5Bk7waGM@public.gmane.org>
2010-06-23 16:51   ` [RFC][PATCH 03/10] cifs: register CIFS for caching David Howells
2010-06-23 16:51     ` David Howells
     [not found]     ` <9603.1277311877-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2010-06-25 10:56       ` Suresh Jayaraman
2010-06-25 10:56         ` Suresh Jayaraman
2010-06-23 16:54 ` [RFC][PATCH 04/10] cifs: define server-level cache index objects and register them with FS-Cache David Howells
     [not found] ` <1277220206-3559-1-git-send-email-sjayaraman-l3A5Bk7waGM@public.gmane.org>
2010-06-23 16:58   ` [RFC][PATCH 05/10] cifs: define superblock-level cache index objects and register them David Howells
2010-06-23 16:58     ` David Howells
     [not found]     ` <9720.1277312290-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2010-06-25 12:44       ` Suresh Jayaraman
2010-06-25 12:44         ` Suresh Jayaraman
2010-06-25 12:58     ` David Howells
     [not found]     ` <22746.1277470713-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2010-06-25 13:26       ` David Howells
2010-06-25 13:26         ` David Howells
     [not found]         ` <23204.1277472412-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2010-06-28 12:53           ` Suresh Jayaraman
2010-06-28 12:53             ` Suresh Jayaraman
2010-06-28 13:24         ` David Howells
     [not found] ` <1277220214-3597-1-git-send-email-sjayaraman-l3A5Bk7waGM@public.gmane.org>
2010-06-23 17:02   ` [RFC][PATCH 06/10] cifs: define inode-level cache object " David Howells
2010-06-23 17:02     ` David Howells
     [not found]     ` <9822.1277312573-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2010-06-25 12:50       ` Suresh Jayaraman
2010-06-25 12:50         ` Suresh Jayaraman
     [not found]     ` <4C24A606.5040001-l3A5Bk7waGM@public.gmane.org>
2010-06-25 12:55       ` David Howells
2010-06-25 12:55         ` David Howells
     [not found]         ` <22697.1277470549-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2010-06-25 16:53           ` Jeff Layton
2010-06-25 16:53             ` Jeff Layton
2010-06-25 21:46         ` David Howells
2010-06-25 22:26           ` Jeff Layton
2010-06-25 22:26             ` Jeff Layton
2010-06-25 23:05             ` Steve French
2010-06-25 23:05               ` Steve French
2010-06-26  0:52               ` Mingming Cao
2010-06-27 18:17                 ` Aneesh Kumar K. V
     [not found]                   ` <871vbscpce.fsf-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
2010-06-27 18:22                     ` Christoph Hellwig
2010-06-27 18:22                       ` Christoph Hellwig
     [not found]           ` <20100625182651.36800d06-9yPaYZwiELC+kQycOl6kW4xkIHaj4LzF@public.gmane.org>
2010-06-25 23:04             ` David Howells
2010-06-25 23:04               ` David Howells
2010-06-23 17:05 ` [RFC][PATCH 07/10] cifs: FS-Cache page management David Howells
     [not found] ` <1277220240-3674-1-git-send-email-sjayaraman-l3A5Bk7waGM@public.gmane.org>
2010-06-23 17:06   ` [RFC][PATCH 08/10] cifs: store pages into local cache David Howells
2010-06-23 17:06     ` David Howells
     [not found] ` <1277220261-3717-1-git-send-email-sjayaraman-l3A5Bk7waGM@public.gmane.org>
2010-06-23 17:07   ` [RFC][PATCH 09/10] cifs: read pages from FS-Cache David Howells
2010-06-23 17:07     ` David Howells
2010-06-23 17:08 ` [RFC][PATCH 10/10] cifs: add mount option to enable local caching David Howells
2010-08-11  5:21 ` [PATCH v3] OpenRD: Enable SD/UART selection for serial port 1 Tanmay Upadhyay
2010-08-11  7:27   ` Russell King - ARM Linux
2011-02-03  9:49 ` [PATCH 1/7] usb: otg: enable regulator only on cable/device connect Hema HK
2011-02-03  9:49 ` [PATCH 2/7] usb: otg: Remove one unnecessary I2C read request Hema HK
2011-02-03  9:49 ` [PATCH 3/7] usb: otg: OMAP4430: Introducing suspend function for power management Hema HK
2011-02-03  9:49 ` [PATCH 4/7] usb: otg: OMAP4430: Add phy_suspend function pointer to twl4030_usb_data Hema HK
2011-02-03 13:45   ` Sergei Shtylyov
     [not found]     ` <4D4AB187.50406-hkdhdckH98+B+jHODAdFcQ@public.gmane.org>
2011-02-04  5:23       ` Hema Kalliguddi
2011-02-03 13:50   ` Sergei Shtylyov
     [not found]     ` <4D4AB2A5.7000002-hkdhdckH98+B+jHODAdFcQ@public.gmane.org>
2011-02-04  6:03       ` Hema Kalliguddi
2011-02-03  9:49 ` [PATCH 5/7] usb: otg: TWL6030: Introduce the twl6030_phy_suspend function Hema HK
2011-02-03  9:49 ` [PATCH 6/7] usb: otg: TWL6030 Save the last event in otg_transceiver Hema HK
2011-02-03  9:49 ` [PATCH 7/7] usb: musb: OMAP4430: Fix usb device detection if connected during boot Hema HK
2011-02-14 10:05   ` Felipe Balbi
2011-02-15  8:23     ` Hema Kalliguddi
2011-04-13 22:08 ` [PATCH 2/2] ltp-ddt: New recipe to build ltp-ddt test tool Carlos Hernandez
2011-05-02 21:01 ` [U-Boot] [PATCH v4 0/5] Add support for LaCie NAS Network Space v2 Simon Guinot
2011-05-02 21:29   ` Wolfgang Denk
2011-05-02 22:46     ` Simon Guinot
2011-05-02 21:01 ` [U-Boot] [PATCH v4 1/5] sf: disable write protection for Macronix flash Simon Guinot
2011-05-02 21:07   ` Mike Frysinger
2011-05-02 21:01 ` [U-Boot] [PATCH v4 2/5] Kirkwood: allow to override CONFIG_SYS_TCLK Simon Guinot
2011-05-02 21:01 ` [U-Boot] [PATCH v4 3/5] mv-common.h: fix DRAM banks configuration Simon Guinot
2011-05-02 21:01 ` [U-Boot] [PATCH v4 4/5] netconsole: remove `serverip' check Simon Guinot
2011-05-02 21:01 ` [U-Boot] [PATCH v4 5/5] Add support for Network Space v2 Simon Guinot
2011-05-02 22:42 ` [U-Boot] [PATCH v5 0/5] Add support for LaCie NAS " Simon Guinot
2011-05-03  9:59   ` Prafulla Wadaskar
2011-05-02 22:42 ` [U-Boot] [PATCH v5 1/5] sf: disable write protection for Macronix flash Simon Guinot
2011-07-08 20:32   ` [U-Boot] [PATCH v6] sf: macronix: disable write protection when initializing Mike Frysinger
2011-08-02 20:02     ` Wolfgang Denk
2011-05-02 22:42 ` [U-Boot] [PATCH v5 2/5] Kirkwood: allow to override CONFIG_SYS_TCLK Simon Guinot
2011-05-03 12:09   ` Prafulla Wadaskar
2011-05-02 22:42 ` [U-Boot] [PATCH v5 3/5] mv-common.h: fix DRAM banks configuration Simon Guinot
2011-05-03 12:09   ` Prafulla Wadaskar
2011-05-02 22:42 ` [U-Boot] [PATCH v5 4/5] netconsole: remove `serverip' check Simon Guinot
2011-05-02 22:42 ` [U-Boot] [PATCH v5 5/5] Add support for Network Space v2 Simon Guinot
2011-05-03 13:19   ` Simon Guinot
2011-05-12 17:24     ` Wolfgang Denk
2011-06-15  0:46 ` [PATCH] Add ok2440 development board support Wu DaoGuang
2011-06-15  0:46   ` Wu DaoGuang
2011-06-22  5:55 ` [PATCH 3/3 v2] ARM: pxa168: Add board support for gplugD Tanmay Upadhyay
2011-07-06 12:20   ` Daniel Mack
2011-07-06 12:44     ` Eric Miao
2011-07-21  4:54 ` [PATCHV2] OMAP4: OPP: add OMAP4460 definitions Vishwanath BS
2011-07-21  4:54   ` Vishwanath BS
     [not found] ` <4e27b0d0.100e8e0a.43e0.ffffe6d9SMTPIN_ADDED@mx.google.com>
2011-07-21  4:56   ` Vishwanath Sripathy
2011-07-21  4:56     ` Vishwanath Sripathy
2011-10-03  0:32 ` [PATCH 1/1] ARM: Make debug UART optional for S3C devices Thiago A. Correa
2011-10-03  0:32   ` Thiago A. Correa
2011-10-10 14:44   ` Thiago A. Corrêa
2011-10-10 14:44     ` Thiago A. Corrêa
2011-12-11 13:10 ` [PATCH] block: Needn't read the size of device or partition again taco
2012-01-08 15:28 ` [Qemu-devel] [PATCH] Add tab-completion for device_add Andrzej Zaborowski
2012-01-12 17:01   ` Anthony Liguori
2012-02-16  2:59 ` [U-Boot] [PATCH 0/5] Support for qualcomm msm7630 board mohamed.haneef at lntinfotech.com
2012-02-23  8:59   ` [U-Boot] reminder for " Mohamed Haneef
2012-10-26 21:15   ` [U-Boot] " Albert ARIBAUD
2012-02-16  2:59 ` [U-Boot] [PATCH 1/5] msm7x30: Add support for low speed uart on msm7x30 mohamed.haneef at lntinfotech.com
2012-02-28 23:44   ` Albert ARIBAUD
2012-03-05 14:34   ` [U-Boot] [PATCH v2 1/5] msm7x30: Add Support " Mohamed Haneef
2012-03-22  8:50   ` [U-Boot] reminder for [PATCH 0/5] Support for qualcomm msm7630 board mohamed.haneef at lntinfotech.com
2012-04-23  9:24   ` [U-Boot] (no subject) mohamed.haneef at lntinfotech.com
2012-04-23  9:31   ` [U-Boot] msm7630 mainline request mohamed.haneef at lntinfotech.com
2012-05-03  0:09     ` Marek Vasut
2012-02-16  2:59 ` [U-Boot] [PATCH 2/5] msm7x30: Add support for interprocessor communication mohamed.haneef at lntinfotech.com
2012-02-28 23:46   ` Albert ARIBAUD
2012-03-05 14:33     ` Mohamed Haneef
2012-02-16  2:59 ` [U-Boot] [PATCH 3/5] msm7x30: Add support for Qualcomm msm7630 soc mohamed.haneef at lntinfotech.com
2012-02-29  0:00   ` Albert ARIBAUD
2012-03-05 14:39   ` [U-Boot] [PATCH v2 3/5] msm7x30: Add support for msm7x30 SoC Mohamed Haneef
2012-02-16  2:59 ` [U-Boot] [PATCH 4/5] Add support for mmc read and writes mohamed.haneef at lntinfotech.com
2012-02-29  0:03   ` Albert ARIBAUD
2012-03-05 14:40   ` [U-Boot] [PATCH v2 4/5] Add Support for qc_mmc MMC Controller Mohamed Haneef
2012-05-03 22:05     ` Andy Fleming
2012-05-10 11:37       ` Mohamed Haneef
2012-02-16  2:59 ` [U-Boot] [PATCH 5/5] msm7x30: Add support for msm7630_surf board mohamed.haneef at lntinfotech.com
2012-10-03  8:19   ` Albert ARIBAUD
2012-06-08 17:23 ` [PATCH 1/4] slub: change declare of get_slab() to inline at all times Joonsoo Kim
2012-06-08 17:23   ` Joonsoo Kim
2012-06-08 17:23   ` [PATCH 2/4] slub: use __cmpxchg_double_slab() at interrupt disabled place Joonsoo Kim
2012-06-08 17:23     ` Joonsoo Kim
2012-06-08 17:23   ` [PATCH 3/4] slub: refactoring unfreeze_partials() Joonsoo Kim
2012-06-08 17:23     ` Joonsoo Kim
2012-06-20  7:19     ` Pekka Enberg
2012-06-20  7:19       ` Pekka Enberg
2012-06-08 17:23   ` [PATCH 4/4] slub: deactivate freelist of kmem_cache_cpu all at once in deactivate_slab() Joonsoo Kim
2012-06-08 17:23     ` Joonsoo Kim
2012-06-08 19:04     ` Christoph Lameter
2012-06-08 19:04       ` Christoph Lameter
2012-06-10 10:27       ` JoonSoo Kim
2012-06-10 10:27         ` JoonSoo Kim
2012-06-22 18:34         ` JoonSoo Kim
2012-06-22 18:34           ` JoonSoo Kim
2012-06-08 19:02   ` [PATCH 1/4] slub: change declare of get_slab() to inline at all times Christoph Lameter
2012-06-08 19:02     ` Christoph Lameter
2012-06-09 15:57     ` JoonSoo Kim
2012-06-09 15:57       ` JoonSoo Kim
2012-06-11 15:04       ` Christoph Lameter
2012-06-11 15:04         ` Christoph Lameter
2012-06-22 18:22 ` [PATCH 1/3] slub: prefetch next freelist pointer in __slab_alloc() Joonsoo Kim
2012-06-22 18:22   ` Joonsoo Kim
2012-06-22 18:22   ` [PATCH 2/3] slub: reduce failure of this_cpu_cmpxchg in put_cpu_partial() after unfreezing Joonsoo Kim
2012-06-22 18:22     ` Joonsoo Kim
2012-07-04 13:05     ` Pekka Enberg
2012-07-04 13:05       ` Pekka Enberg
2012-07-05 14:20       ` Christoph Lameter
2012-07-05 14:20         ` Christoph Lameter
2012-08-16  7:06     ` Pekka Enberg
2012-08-16  7:06       ` Pekka Enberg
2012-06-22 18:22   ` [PATCH 3/3] slub: release a lock if freeing object with a lock is failed in __slab_free() Joonsoo Kim
2012-06-22 18:22     ` Joonsoo Kim
2012-07-04 13:10     ` Pekka Enberg
2012-07-04 13:10       ` Pekka Enberg
2012-07-04 14:48       ` JoonSoo Kim
2012-07-04 14:48         ` JoonSoo Kim
2012-07-05 14:26     ` Christoph Lameter
2012-07-05 14:26       ` Christoph Lameter
2012-07-06 14:19       ` JoonSoo Kim
2012-07-06 14:19         ` JoonSoo Kim
2012-07-06 14:34         ` Christoph Lameter
2012-07-06 14:34           ` Christoph Lameter
2012-07-06 14:59           ` JoonSoo Kim
2012-07-06 14:59             ` JoonSoo Kim
2012-07-06 15:10             ` Christoph Lameter
2012-07-06 15:10               ` Christoph Lameter
2012-07-08 16:19               ` JoonSoo Kim
2012-07-08 16:19                 ` JoonSoo Kim
2012-06-22 18:45   ` [PATCH 1/3 v2] slub: prefetch next freelist pointer in __slab_alloc() Joonsoo Kim
2012-06-22 18:45     ` Joonsoo Kim
2012-07-04 12:58     ` JoonSoo Kim
2012-07-04 12:58       ` JoonSoo Kim
2012-07-04 13:00     ` Pekka Enberg
2012-07-04 13:00       ` Pekka Enberg
2012-07-04 14:30       ` JoonSoo Kim
2012-07-04 14:30         ` JoonSoo Kim
2012-07-04 15:08         ` Pekka Enberg
2012-07-04 15:08           ` Pekka Enberg
2012-07-04 15:26           ` Eric Dumazet
2012-07-04 15:26             ` Eric Dumazet
2012-07-04 15:48             ` JoonSoo Kim
2012-07-04 15:48               ` JoonSoo Kim
2012-07-04 16:15               ` Eric Dumazet
2012-07-04 16:15                 ` Eric Dumazet
2012-07-04 16:24                 ` JoonSoo Kim
2012-07-04 16:24                   ` JoonSoo Kim
2012-07-04 15:45           ` JoonSoo Kim
2012-07-04 15:45             ` JoonSoo Kim
2012-07-04 15:59             ` Pekka Enberg
2012-07-04 15:59               ` Pekka Enberg
2012-07-04 16:04               ` JoonSoo Kim
2012-07-04 16:04                 ` JoonSoo Kim
2012-08-10  9:35 ` [PATCH BlueZ V5 1/5] AVRCP: Add TG Record to support AVRCP Browsing Vani-dineshbhai PATEL
2012-08-13 11:27   ` Luiz Augusto von Dentz
2012-08-13 11:49     ` Michal.Labedzki
2012-08-13 12:15       ` Luiz Augusto von Dentz
2012-09-20  7:28 ` [PATCH] mac80211 : Fix Ibss debug message Tx authentication yes
2012-09-20  7:55   ` Johannes Berg
2012-11-16  8:53 ` [PATCH] python: fix for Security Advisory - python - CVE-2012-2135 yanjun.zhu
2012-11-16 12:21   ` Otavio Salvador
2012-11-19  2:26     ` yzhu1
2012-11-19  2:36       ` yzhu1
2012-11-19 10:21         ` Otavio Salvador
2012-11-29 14:07   ` Paul Eggleton
2012-11-30  2:49     ` yzhu1
2013-02-07 17:33 ` [PATCH 00/10] usb: ehci: more bus glues as separate modules manjunath.goudar at linaro.org
2013-02-07 20:13   ` Ezequiel Garcia
2013-02-08 15:23   ` Alan Stern
     [not found] ` <1360258447-27247-1-git-send-email-yes>
2013-02-07 17:33   ` [PATCH 01/10] USB:Changed omap2plus_defconfig to support OMAP USB static driver manjunath.goudar at linaro.org
2013-02-07 17:33   ` [PATCH 02/10] USB: EHCI: make ehci-omap a separate driver manjunath.goudar at linaro.org
2013-02-08  7:42     ` Felipe Balbi
2013-02-08  8:56       ` Roger Quadros
2013-02-07 17:34   ` [PATCH 03/10] USB: EHCI: make ehci-spear " manjunath.goudar at linaro.org
2013-02-08  4:27     ` Viresh Kumar
2013-02-07 17:34   ` [PATCH 04/10] USB: EHCI: make ehci-orion " manjunath.goudar
2013-02-07 17:34     ` manjunath.goudar at linaro.org
2013-02-07 19:41     ` Arnd Bergmann
2013-02-07 19:41       ` Arnd Bergmann
2013-02-08 10:38     ` Florian Fainelli
2013-02-08 10:38       ` Florian Fainelli
2013-02-07 17:34   ` [PATCH 05/10] USB: EHCI: make ehci-atmel " manjunath.goudar
2013-02-07 17:34     ` manjunath.goudar at linaro.org
2013-02-08  2:58     ` Bo Shen
2013-02-08  2:58       ` Bo Shen
2013-06-12 11:53     ` Jean-Christophe PLAGNIOL-VILLARD
2013-06-12 11:53       ` Jean-Christophe PLAGNIOL-VILLARD
2013-02-07 17:34   ` [PATCH 06/10] USB: EHCI: make ehci-s5p " manjunath.goudar at linaro.org
2013-02-07 18:49     ` Stephen Warren
2013-02-07 17:34   ` [PATCH 07/10] USB: EHCI: make ehci-mv " manjunath.goudar
2013-02-07 17:34     ` manjunath.goudar at linaro.org
2013-02-07 17:34   ` [PATCH 08/10] USB: EHCI: make ehci-vt8500 " manjunath.goudar
2013-02-07 17:34     ` manjunath.goudar at linaro.org
2013-02-07 18:54     ` Tony Prisk
2013-02-07 18:54       ` Tony Prisk
2013-02-07 17:34   ` [PATCH 09/10] USB: EHCI: make ehci-msm " manjunath.goudar
2013-02-07 17:34     ` manjunath.goudar at linaro.org
2013-02-07 18:48     ` Stephen Warren
2013-02-07 18:48       ` Stephen Warren
2013-02-07 19:05     ` David Brown
2013-02-07 19:05       ` David Brown
2013-02-07 17:34   ` [PATCH 10/10] USB: EHCI: make ehci-w90X900 " manjunath.goudar
2013-02-07 17:34     ` manjunath.goudar at linaro.org
2013-03-09 15:39 ` [meta-fsl-arm][PATCH] imx-base: add imx6dl mapping for firmware John Weber
2013-03-09 19:05   ` Otavio Salvador
2013-03-12 19:16 ` [fsl-community-bsp-base][PATCH] Add Wandboard Dual to README John Weber
2013-03-12 19:20   ` Otavio Salvador
2013-03-16 13:45 ` [meta-fsl-arm-extra][PATCH] linux-imx (3.0.35): fix sdhc platform data John Weber
2013-03-16 13:45   ` [meta-fsl-arm-extra][PATCH] linux-imx (3.0.35): remove staging driver for brcm80211 John Weber
2013-03-16 14:39     ` Otavio Salvador
2013-03-17  1:08       ` John Weber
2013-03-16 13:45   ` John Weber [this message]
2013-03-16 13:45   ` [meta-fsl-arm-extra][PATCH] linux-imx (3.0.35): enable brcm wifi in wandboard dual defconfig John Weber
2013-03-16 14:32     ` Otavio Salvador
2013-03-16 13:45   ` [meta-fsl-arm-extra][PATCH] linux-imx (3.0.35): wandboard: add brcm80211 support to bbappend John Weber
2013-03-16 14:31     ` Otavio Salvador
2013-03-16 13:45   ` [meta-fsl-arm-extra][PATCH] linux-firmware: add support for bcm4329 John Weber
2013-03-16 14:31     ` Otavio Salvador
2013-03-17  0:40       ` John Weber
2013-03-16 13:45   ` [meta-fsl-arm-extra][PATCH] conf/machine: add firmware rrecomends to wandboard-dual John Weber
2013-03-16 14:23   ` [meta-fsl-arm-extra][PATCH] linux-imx (3.0.35): fix sdhc platform data Otavio Salvador
2013-03-18 20:25 ` [meta-fsl-arm-extra][PATCH v2 0/5] Enable wifi support for Wandboard Dual John Weber
2013-03-18 20:25   ` [meta-fsl-arm-extra][PATCH v2 1/5] linux-imx (3.0.35): wandboard: fix sdhc platform data John Weber
2013-03-18 20:25   ` [meta-fsl-arm-extra][PATCH v2 2/5] linux-imx (3.0.35): wandboard: replace brcm80211 driver John Weber
2013-03-18 20:25   ` [meta-fsl-arm-extra][PATCH v2 3/5] linux-firmware: Add bbappend to include Broadcom wifi drivers John Weber
2013-03-18 20:25   ` [meta-fsl-arm-extra][PATCH v2 4/5] wandboard-wifi-support: add nvram file and create firmware links John Weber
2013-03-18 20:25   ` [meta-fsl-arm-extra][PATCH v2 5/5] wandboard-dual: Add wandboard-wifi-support to machine John Weber
2013-03-22  3:05   ` [meta-fsl-arm-extra][PATCH v2 0/5] Enable wifi support for Wandboard Dual Otavio Salvador
2013-03-22  8:13     ` Eric Bénard
2013-03-22 12:30       ` Otavio Salvador
2013-03-22 14:17         ` Eric Bénard
2013-03-22 14:23         ` Eric Bénard
2013-03-23 15:44           ` Otavio Salvador
2013-03-25  2:18             ` Fabio Estevam
2013-03-25  2:20               ` John Weber
2013-06-10  9:17 ` [PATCH v2 00/11] ARM:STixxxx: Add STixxxx platform and board support Srinivas KANDAGATLA
2013-06-10  9:17   ` Srinivas KANDAGATLA
2013-06-10  9:21   ` [PATCH v2 01/11] serial:st-asc: Add ST ASC driver Srinivas KANDAGATLA
2013-06-10  9:21     ` Srinivas KANDAGATLA
2013-06-10  9:35     ` Russell King - ARM Linux
2013-06-10  9:35       ` Russell King - ARM Linux
2013-06-10  9:35       ` Russell King - ARM Linux
2013-06-10 11:53       ` Srinivas KANDAGATLA
2013-06-10 11:53         ` Srinivas KANDAGATLA
2013-06-10  9:21   ` [PATCH v2 02/11] clocksource:global_timer: Add ARM global timer support Srinivas KANDAGATLA
2013-06-10  9:21     ` Srinivas KANDAGATLA
2013-06-10  9:21     ` Srinivas KANDAGATLA
     [not found]     ` <1370856087-6452-1-git-send-email-srinivas.kandagatla-qxv4g6HH51o@public.gmane.org>
2013-06-10 13:13       ` Linus Walleij
2013-06-10 13:13         ` Linus Walleij
     [not found]         ` <CACRpkdbQCRKBzRF4HzNsXHwXCLJJcFZ9T36GPmmYsnX1OfgGRg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2013-06-10 13:41           ` Srinivas KANDAGATLA
2013-06-10 13:41             ` Srinivas KANDAGATLA
2013-06-11 14:05             ` Srinivas KANDAGATLA
2013-06-11 14:05               ` Srinivas KANDAGATLA
     [not found]               ` <51B72E9A.6070006-qxv4g6HH51o@public.gmane.org>
2013-06-11 20:13                 ` Linus Walleij
2013-06-11 20:13                   ` Linus Walleij
2013-06-12 10:45                   ` Srinivas KANDAGATLA
2013-06-12 10:45                     ` Srinivas KANDAGATLA
2013-06-12 10:45                     ` Srinivas KANDAGATLA
2013-06-10  9:21   ` [PATCH v2 03/11] regmap: Add regmap_field APIs Srinivas KANDAGATLA
2013-06-10  9:21     ` Srinivas KANDAGATLA
2013-06-10  9:21     ` Srinivas KANDAGATLA
2013-06-11 10:48     ` Mark Brown
2013-06-11 10:48       ` Mark Brown
2013-06-11 10:48       ` Mark Brown
2013-06-11 11:36       ` Srinivas KANDAGATLA
2013-06-11 11:36         ` Srinivas KANDAGATLA
2013-06-11 11:36         ` Srinivas KANDAGATLA
2013-06-10  9:22   ` [PATCH v2 04/11] mfd:stixxxx-syscfg: Add ST System Configuration support Srinivas KANDAGATLA
2013-06-10  9:22     ` Srinivas KANDAGATLA
     [not found]     ` <1370856147-6552-1-git-send-email-srinivas.kandagatla-qxv4g6HH51o@public.gmane.org>
2013-06-10 13:16       ` Linus Walleij
2013-06-10 13:16         ` Linus Walleij
2013-06-10 13:52         ` Srinivas KANDAGATLA
2013-06-10 13:52           ` Srinivas KANDAGATLA
2013-06-10 13:52           ` Srinivas KANDAGATLA
2013-06-10 14:02           ` Arnd Bergmann
2013-06-10 14:02             ` Arnd Bergmann
2013-06-10 14:02             ` Arnd Bergmann
2013-06-10 15:51             ` Srinivas KANDAGATLA
2013-06-10 15:51               ` Srinivas KANDAGATLA
2013-06-10 15:51               ` Srinivas KANDAGATLA
2013-06-11  7:41             ` Srinivas KANDAGATLA
2013-06-11  7:41               ` Srinivas KANDAGATLA
2013-06-11  7:41               ` Srinivas KANDAGATLA
2013-06-10  9:22   ` [PATCH v2 05/11] pinctrl:stixxxx: Add pinctrl and pinconf support Srinivas KANDAGATLA
2013-06-10  9:22     ` Srinivas KANDAGATLA
     [not found]     ` <1370856161-6600-1-git-send-email-srinivas.kandagatla-qxv4g6HH51o@public.gmane.org>
2013-06-16 12:17       ` Linus Walleij
2013-06-16 12:17         ` Linus Walleij
2013-06-17 13:31         ` Srinivas KANDAGATLA
2013-06-17 13:31           ` Srinivas KANDAGATLA
     [not found]           ` <51BF0FC2.4000601-qxv4g6HH51o@public.gmane.org>
2013-06-17 16:27             ` Linus Walleij
2013-06-17 16:27               ` Linus Walleij
2013-06-10  9:26   ` =?yes?q?=5BPATCH=20v2=2006/11=5D=20ARM=3Astixxxx=3A=20Add=20STiH415=20SOC=20support?= Srinivas KANDAGATLA
2013-06-10  9:26     ` =?yes?q?=5BPATCH=20v2=2006/11=5D=20ARM=3Astixxxx=3A=20Add=20STiH415=20SOC=20support?= Srinivas KANDAGATLA
2013-06-10  9:55     ` [PATCH v2 06/11] ARM:stixxxx: Add STiH415 SOC support Michal Simek
2013-06-10  9:55       ` Michal Simek
2013-06-10 11:08     ` Michal Simek
2013-06-10 11:08       ` Michal Simek
     [not found]     ` <CAHTX3d+dk3W_9b7SVUokWq4KYXnj=Z1=WPj5zJ-gUvJqqwE=+Q@mail.gmail.com>
2013-06-10 11:46       ` Srinivas KANDAGATLA
2013-06-10 11:46         ` Srinivas KANDAGATLA
2013-06-10 11:46         ` Srinivas KANDAGATLA
2013-06-10 23:19         ` Russell King - ARM Linux
2013-06-10 23:19           ` Russell King - ARM Linux
2013-06-10 23:19           ` Russell King - ARM Linux
2013-06-11  6:50           ` Srinivas KANDAGATLA
2013-06-11  6:50             ` Srinivas KANDAGATLA
2013-06-11  6:50             ` Srinivas KANDAGATLA
2013-06-13 11:56             ` Russell King - ARM Linux
2013-06-13 11:56               ` Russell King - ARM Linux
2013-06-13 11:56               ` Russell King - ARM Linux
2013-06-13 12:41               ` Srinivas KANDAGATLA
2013-06-13 12:41                 ` Srinivas KANDAGATLA
2013-06-13 12:41                 ` Srinivas KANDAGATLA
2013-06-13 12:47           ` Linus Walleij
2013-06-13 12:47             ` Linus Walleij
2013-06-13 12:47             ` Linus Walleij
     [not found]     ` <1370856381-6644-1-git-send-email-srinivas.kandagatla-qxv4g6HH51o@public.gmane.org>
2013-06-10 12:43       ` Linus Walleij
2013-06-10 12:43         ` Linus Walleij
     [not found]         ` <CACRpkdZ-xnDO+bte4tyKDWwY4A_qWUhLru3dUmuY9MQwseP3uQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2013-06-10 16:38           ` Srinivas KANDAGATLA
2013-06-10 16:38             ` Srinivas KANDAGATLA
     [not found]             ` <51B6011E.1060909-qxv4g6HH51o@public.gmane.org>
2013-06-14  7:31               ` Srinivas KANDAGATLA
2013-06-14  7:31                 ` Srinivas KANDAGATLA
     [not found]                 ` <51BAC6EC.8000703-qxv4g6HH51o@public.gmane.org>
2013-06-19 18:59                   ` Linus Walleij
2013-06-19 18:59                     ` Linus Walleij
2013-06-10  9:27   ` [PATCH v2 07/11] ARM:stixxxx: Add STiH416 " Srinivas KANDAGATLA
2013-06-10  9:27     ` Srinivas KANDAGATLA
2013-06-10 13:52     ` Arnd Bergmann
2013-06-10 13:52       ` Arnd Bergmann
2013-06-10 16:17       ` Srinivas KANDAGATLA
2013-06-10 16:17         ` Srinivas KANDAGATLA
2013-06-14  7:12       ` Srinivas KANDAGATLA
2013-06-14  7:12         ` Srinivas KANDAGATLA
2013-06-19 18:34       ` Linus Walleij
2013-06-19 18:34         ` Linus Walleij
2013-06-10  9:27   ` [PATCH v2 08/11] ARM:stixxxx: Add DEBUG_LL console support Srinivas KANDAGATLA
2013-06-10  9:27     ` Srinivas KANDAGATLA
2013-06-10  9:27     ` Srinivas KANDAGATLA
2013-06-10  9:27   ` [PATCH v2 09/11] ARM:stixxxx: Add stixxxx options to multi_v7_defconfig Srinivas KANDAGATLA
2013-06-10  9:27     ` Srinivas KANDAGATLA
2013-06-10 10:40     ` Mark Rutland
2013-06-10 10:40       ` Mark Rutland
2013-06-10 10:40       ` Mark Rutland
2013-06-10 10:58       ` Srinivas KANDAGATLA
2013-06-10 10:58         ` Srinivas KANDAGATLA
2013-06-10 10:58         ` Srinivas KANDAGATLA
2013-06-10 13:15         ` Mark Rutland
2013-06-10 13:15           ` Mark Rutland
2013-06-10 13:15           ` Mark Rutland
2013-06-13  9:24           ` Srinivas KANDAGATLA
2013-06-13  9:24             ` Srinivas KANDAGATLA
2013-06-13  9:24             ` Srinivas KANDAGATLA
2013-06-17  9:32             ` Mark Rutland
2013-06-17  9:32               ` Mark Rutland
2013-06-17  9:32               ` Mark Rutland
2013-06-10  9:28   ` [PATCH v2 10/11] ARM:stih41x: Add B2000 board support Srinivas KANDAGATLA
2013-06-10  9:28     ` Srinivas KANDAGATLA
2013-06-10  9:28     ` Srinivas KANDAGATLA
2013-06-10  9:28   ` [PATCH v2 11/11] ARM:stih41x: Add B2020 " Srinivas KANDAGATLA
2013-06-10  9:28     ` Srinivas KANDAGATLA
2013-06-10  9:28     ` Srinivas KANDAGATLA
2013-09-10  9:25 ` [PATCH 0/1] ideas to improve the write performance of cluster dm-raid1 dongmao zhang
2013-09-10  9:25   ` [PATCH 1/1] improve the performance of dm-log-userspace dongmao zhang
2013-09-12  8:42 ` [PATCH 1/1] OMAPDSS: Return right error during connector probe Sathya Prakash M R
2013-09-16  9:41   ` Tomi Valkeinen
2013-10-28 10:07 ` [PATCH 0/1] patches to improve cluster raid1 performance [V3] dongmao zhang
2013-10-28 10:07   ` [PATCH 1/1] improve the performance of dm-log-userspace dongmao zhang
2013-10-30  1:35     ` Brassow Jonathan
2013-10-28 10:17 ` [PATCH 0/2] cmirror patch to improve cluster raid1 performance[v3] dongmao zhang
2013-10-28 10:17   ` [PATCH 1/2] add integrated_flush support to device-mapper dongmao zhang
2013-10-28 10:17     ` [PATCH 2/2] cmirrord support DM_INTEGRATED_FLUSH dongmao zhang
2013-10-30  1:48       ` Brassow Jonathan
2013-10-30  1:47     ` [PATCH 1/2] add integrated_flush support to device-mapper Brassow Jonathan
2014-01-13  6:51 ` [PATCH 0/2] Optimization on intel HDMI detect and get_modes Ramalingam C
2014-01-13  6:51   ` [PATCH 1/2] drm/i915: HDMI detection based on HPD pin live status Ramalingam C
2014-01-13  6:51   ` [PATCH 2/2] drm/i915: Optimize EDID retrival on detect and get_modes Ramalingam C
2014-01-13  7:29   ` [PATCH 0/2] Optimization on intel HDMI " Daniel Vetter
2014-01-13  9:39     ` Sharma, Shashank
2014-01-13 13:26       ` Daniel Vetter
2014-01-13 17:19         ` Sharma, Shashank
2014-04-09  6:19           ` Wang, Quanxian
2014-04-09  6:50             ` Sharma, Shashank
2014-04-10  6:46               ` Sharma, Shashank
2014-04-10  8:08                 ` Daniel Vetter
2014-04-10  8:10                   ` Sharma, Shashank
2014-04-10 10:42                 ` Wang, Quanxian
     [not found]                   ` <FF3DDC77922A8A4BB08A3BC48A1EA8CB01692A7B@BGSMSX101.gar.corp.intel.com>
2014-04-11 12:58                     ` Daniel Vetter
2014-04-11 13:23                       ` Sharma, Shashank
2014-04-11 14:22                         ` Daniel Vetter
2014-04-11 14:48                           ` Sharma, Shashank
2014-07-16 14:29                             ` Kumar, Shobhit
2014-02-07 23:23 ` [U-Boot] [U-Boot: RESEND][PATCH 0/7] Add support for Keystone2 SoC and K2HK EVM Murali Karicheri
2014-02-07 23:23   ` [U-Boot] [U-Boot:RESEND][[PATCH 1/7] fdt: call ft_board_setup_ex() at the end of image_setup_libfdt() Murali Karicheri
2014-02-10 21:25     ` Tom Rini
2014-02-11  1:05       ` Vitaly Andrianov
2014-02-07 23:23   ` [U-Boot] [U-Boot:RESEND][[PATCH 2/7] tools: sort the entries in Makefile Murali Karicheri
2014-02-07 23:23   ` [U-Boot] [U-Boot:RESEND][[PATCH 3/7 v1] tools: mkimage: add support for gpimage format Murali Karicheri
2014-02-07 23:23   ` [U-Boot] [U-Boot:RESEND][[PATCH 4/7 v1] arm: add support for arch timer Murali Karicheri
2014-02-07 23:23   ` [U-Boot] [U-Boot:RESEND][[PATCH 5/7 v1] NAND: DaVinci: allow forced disable of subpage writes Murali Karicheri
2014-02-07 23:23   ` [U-Boot] [U-Boot:RESEND][[PATCH 6/7] k2hk: add support for k2hk SOC and EVM Murali Karicheri
2014-02-10 21:25     ` Tom Rini
2014-02-11  1:44       ` Vitaly Andrianov
2014-02-12 12:53         ` Tom Rini
2014-02-17 21:19       ` Andrianov, Vitaly
2014-02-17 21:57         ` Tom Rini
2014-02-20 17:27           ` Andrianov, Vitaly
2014-02-10  8:32   ` [U-Boot] [U-Boot: RESEND][PATCH 0/7] Add support for Keystone2 SoC and K2HK EVM Albert ARIBAUD
2014-02-10 17:22     ` Murali Karicheri
2014-02-10 18:01       ` Albert ARIBAUD
2014-02-10 19:42         ` Murali Karicheri
2014-02-10 19:58           ` Albert ARIBAUD
2014-02-10 21:23   ` Tom Rini
2014-02-20 17:55 ` [U-Boot] [U-Boot PATCH v2 00/12] Add support for keystone2 " Murali Karicheri
2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 01/12] fdt: call ft_board_setup_ex() at the end of image_setup_libfdt() Murali Karicheri
2014-02-25 22:10     ` Tom Rini
2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 02/12] tools: sort the entries in Makefile Murali Karicheri
2014-02-25 22:10     ` Tom Rini
2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 03/12] tools: mkimage: add support for gpimage format Murali Karicheri
2014-02-25 22:11     ` Tom Rini
2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 04/12] arm: add support for arch timer Murali Karicheri
2014-02-25 22:11     ` Tom Rini
2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 05/12] NAND: DaVinci: allow forced disable of subpage writes Murali Karicheri
2014-02-25 22:11     ` Tom Rini
2014-02-26  4:01     ` Scott Wood
2014-02-27 16:38       ` Murali Karicheri
     [not found]       ` <3E54258959B69E4282D79E01AB1F32B7046C27D5@DFLE11.ent.ti.com>
2014-02-27 19:21         ` Scott Wood
2014-02-27 21:20           ` Murali Karicheri
2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 06/12] i2c, davinci: move i2c_defs.h to the drivers/i2c directory Murali Karicheri
2014-02-25 22:11     ` Tom Rini
2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 07/12] i2c, davinci: add support for multiple i2c buses Murali Karicheri
2014-02-25 22:11     ` Tom Rini
2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 08/12] k2hk: add support for k2hk SOC and EVM Murali Karicheri
2014-02-25 22:11     ` Tom Rini
2014-03-03 18:20       ` Murali Karicheri
2014-03-03 18:29         ` Tom Rini
2014-03-06 19:09       ` Andrianov, Vitaly
2014-03-06 19:29         ` Tom Rini
2014-03-07 16:41           ` Andrianov, Vitaly
2014-03-07 16:50             ` Tom Rini
2014-03-07 21:21       ` Murali Karicheri
2014-03-07 21:27         ` Tom Rini
2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 09/12] keystone2: add keystone multicore navigator driver Murali Karicheri
2014-02-25 22:12     ` Tom Rini
2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 10/12] keystone2: net: add keystone ethernet driver Murali Karicheri
2014-02-25 22:11     ` Tom Rini
2014-03-12 19:04       ` Murali Karicheri
2014-03-12 20:01         ` Tom Rini
2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 11/12] spi: davinci: add support for multiple bus and chip select Murali Karicheri
2014-02-25 22:12     ` Tom Rini
2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 12/12] k2hk-evm: add configuration for spi1 and spi2 support Murali Karicheri
2014-02-25 22:12     ` Tom Rini
2014-02-25 22:10   ` [U-Boot] [U-Boot PATCH v2 00/12] Add support for keystone2 SoC and K2HK EVM Tom Rini
2014-02-27 16:18     ` Karicheri, Muralidharan
2014-03-12 19:21     ` Murali Karicheri
2014-03-12 19:35       ` Tom Rini
2014-02-25 22:49   ` Karicheri, Muralidharan
2014-02-25 22:51     ` Tom Rini
2014-08-12  6:40 ` [PATCH v3] uas: replace WARN_ON_ONCE() with lockdep_assert_held() Sanjeev Sharma
2014-08-12  6:40   ` Sanjeev Sharma
2014-08-12  6:28   ` Hans de Goede
2014-08-12  6:37     ` Sharma, Sanjeev
2014-08-19  6:33     ` Sharma, Sanjeev
2014-08-19  6:33       ` Sharma, Sanjeev
2014-08-19  9:30       ` gregkh
2014-08-19  9:38         ` Sharma, Sanjeev
2014-08-19  9:38           ` Sharma, Sanjeev
2014-09-04  7:06         ` Sharma, Sanjeev
2014-09-04 13:50 ` [PATCH] Staging: rtl8192u: fix brace style coding issue in r819xU_firmware.c linux.delve
2014-09-04 13:51   ` [PATCH] Staging: rtl8192u: fix brace style coding issue in r819xU_firmware.c This is a patch to the file r819xU_firmware.c that fixes a brace warning found by checkpatch.pl tool linux.delve
2014-09-04 14:09 ` [PATCH] Staging: rtl8192u: fix brace style coding issue in r819xU_firmware.c Chaitra Ramaiah
2014-09-04 14:09   ` [PATCH] Staging: rtl8192u: fix brace style coding issue in r819xU_firmware.c This is a patch to the file r819xU_firmware.c that fixes a brace warning found by checkpatch.pl tool Chaitra Ramaiah
2014-09-04 14:28     ` Greg KH
2014-09-04 14:33     ` Dan Carpenter
2014-09-04 14:27   ` [PATCH] Staging: rtl8192u: fix brace style coding issue in r819xU_firmware.c Greg KH
2014-10-29 20:28 ` [PATCH v2 0/4] Enable PCI controller for Keystone SoCs Murali Karicheri
2014-10-29 20:28   ` Murali Karicheri
2014-10-29 20:28   ` Murali Karicheri
2014-10-29 20:28   ` [PATCH v2 1/4] ARM: keystone: add pcie related options Murali Karicheri
2014-10-29 20:28     ` Murali Karicheri
2014-10-29 20:28   ` [PATCH v2 2/4] ARM: keystone: defconfig: add options to enable PCI controller Murali Karicheri
2014-10-29 20:28     ` Murali Karicheri
2014-10-29 20:28   ` [PATCH v2 3/4] ARM: dts: keystone: add DT bindings for PCI controller for port 0 Murali Karicheri
2014-10-29 20:28     ` Murali Karicheri
2014-10-29 20:28     ` Murali Karicheri
2014-10-29 20:28   ` [PATCH v2 4/4] ARM: dts: keystone-k2e: add DT bindings for PCI controller for port 1 Murali Karicheri
2014-10-29 20:28     ` Murali Karicheri
2014-10-29 20:28     ` Murali Karicheri
2014-10-29 21:10   ` [PATCH v2 0/4] Enable PCI controller for Keystone SoCs santosh shilimkar
2014-10-29 21:10     ` santosh shilimkar
2015-02-12  7:56 ` [PATCH] pinctrl: mediatek: Fix build error in Mediatek pinctrl driver Hongzhou Yang
2015-02-20 10:04   ` Linus Walleij
2015-02-20 10:04     ` Linus Walleij
2015-02-20 10:04     ` Linus Walleij
2015-02-20 10:04     ` Linus Walleij
2015-07-27  8:16 ` [PATCH v1] mmc: sprd: add MMC host driver for Spreadtrum SoC Billows Wu
2015-10-19  2:27 ` [RFC PATCH] qspinlock: Improve performance by reducing load instruction rollback ling.ma.program
2015-10-19  7:58   ` Ingo Molnar
2015-10-19  9:34     ` Peter Zijlstra
2015-10-19 11:24       ` Ingo Molnar
2015-10-19 17:24         ` Waiman Long
2015-10-20  2:57     ` Ling Ma
2015-10-20  8:48       ` Ingo Molnar
2015-10-21  5:28         ` Ling Ma
2015-10-21  7:54           ` Peter Zijlstra
2015-10-20  9:15       ` Peter Zijlstra
2015-10-19  9:33   ` Peter Zijlstra
2015-10-19 17:20     ` Waiman Long
2015-10-20  3:00     ` Ling Ma
2015-10-19  9:46   ` Peter Zijlstra
2015-10-20  3:03     ` Ling Ma
2015-10-20  3:24     ` Ling Ma
2015-10-20  9:16       ` Peter Zijlstra
2015-10-21  5:30         ` Ling Ma
2015-10-19 17:18   ` Waiman Long
2015-10-20  3:12     ` Ling Ma
2015-10-20 18:55       ` Waiman Long
2015-10-21  5:43         ` Ling Ma
2015-12-31  8:09 ` [RFC PATCH] alispinlock: acceleration from lock integration on multi-core platform ling.ma.program
2016-01-05 18:46   ` Waiman Long
2016-01-08 22:48     ` Ling Ma
2016-01-05 21:18   ` Peter Zijlstra
2016-01-05 21:42     ` One Thousand Gnomes
2016-01-06  8:16       ` Peter Zijlstra
2016-01-06  8:21         ` Peter Zijlstra
2016-01-06 11:24           ` One Thousand Gnomes
2016-01-08 22:44             ` Ling Ma
2016-01-12 13:50               ` One Thousand Gnomes
2016-01-14  8:10                 ` Ling Ma
2016-01-19  8:52                   ` Ling Ma
2016-01-19 15:36                     ` Waiman Long
2016-02-03  4:40                       ` Ling Ma
2016-02-03  6:00                         ` Ling Ma
2016-02-03 21:42                         ` Waiman Long
2016-02-04  7:07                           ` Ling Ma
2016-04-05  3:44                           ` Ling Ma
2016-04-11  8:00                             ` Ling Ma
2016-01-08 23:01       ` Ling Ma
2016-01-08 22:56     ` Ling Ma
2018-12-12 11:35 ` [PATCH] doc: add meson ut enhancements in prog guide Hari Kumar Vemula
2019-01-20 12:04   ` Thomas Monjalon
2019-01-23  6:37   ` [PATCH v2] doc: add meson ut info " Hari Kumar Vemula
2019-01-23 10:53     ` Bruce Richardson
2019-01-24 13:41     ` [PATCH v3] " Hari Kumar Vemula
2019-01-24 14:15       ` Richardson, Bruce
2019-01-25  6:20       ` [PATCH v4] " Hari Kumar Vemula
2019-01-31 14:49         ` Bruce Richardson
2019-02-02 10:28         ` [PATCH v5] " Hari Kumar Vemula
2019-03-04 17:05           ` Bruce Richardson
2019-04-22 22:35           ` [dpdk-dev] " Thomas Monjalon
2019-05-01 11:39             ` Mcnamara, John
2019-06-06 11:59           ` [dpdk-dev] [PATCH v6] " Hari Kumar Vemula
2019-07-08 19:40             ` Thomas Monjalon
2019-07-08 20:18               ` Aaron Conole
2019-07-09 18:57                 ` Michael Santana Francisco
2019-07-22 12:39                   ` Parthasarathy, JananeeX M
2019-07-22 12:53                     ` Thomas Monjalon
2019-07-22 13:53                       ` Bruce Richardson
2019-07-23 11:34                         ` Parthasarathy, JananeeX M
2019-08-07 13:56             ` [dpdk-dev] [PATCH v7] " Agalya Babu RadhaKrishnan
2019-08-07 14:16               ` Jerin Jacob Kollanukkaran
2019-08-07 15:47               ` Michael Santana Francisco
2019-08-12 12:40               ` [dpdk-dev] [PATCH v8] " Jananee Parthasarathy
2020-02-16 10:28                 ` Thomas Monjalon
2019-01-03 12:28 ` [PATCH v2] eal: fix core number validation Hari kumar Vemula
2019-01-03 13:03   ` David Marchand
2019-01-07  7:05   ` Hari Kumar Vemula
2019-01-07 10:25   ` [PATCH v3] " Hari Kumar Vemula
2019-01-10 10:11     ` David Marchand
2019-01-11 14:15   ` [PATCH v4] " Hari Kumar Vemula
2019-01-11 15:06     ` David Marchand
2019-01-14 10:28     ` [PATCH v5] " Hari Kumar Vemula
2019-01-14 14:39       ` David Marchand
2019-01-17 12:13     ` [PATCH v6] " Hari Kumar Vemula
2019-01-17 12:19       ` Bruce Richardson
2019-01-17 12:32         ` David Marchand
2019-01-17 16:31       ` [dpdk-stable] " Thomas Monjalon
2019-01-07 13:01 ` [PATCH] net/bonding: fix create bonded device test failure Hari Kumar Vemula
2019-01-07 18:44   ` Chas Williams
2019-01-08 10:27     ` [dpdk-stable] " Ferruh Yigit
2019-01-08 11:14     ` Vemula, Hari KumarX
2019-01-15 17:37   ` Pattan, Reshma
2019-01-28  7:28   ` [PATCH v2] " Hari Kumar Vemula
2019-01-31 23:40     ` Chas Williams
2019-02-05 13:39     ` [PATCH v3] " Hari Kumar Vemula
2019-02-07 13:34       ` [dpdk-stable] " Ferruh Yigit
2019-12-04  9:36 ` [PATCH] i386: pass CLZERO to guests with EPYC CPU model on AMD ZEN platform Ani Sinha
2019-12-16  9:31   ` Ani Sinha
     [not found] ` <20220630112644.3682066-1-Shreyas.Karmahe@toshiba-tsip.com>
2022-07-01 11:32   ` [isar-cip-core] postinst:Added lines to verify Local and Remote Multi-factor Authentication Jan Kiszka
2022-07-01 11:33     ` Jan Kiszka
2022-07-04 16:51       ` Shreyas.Karmahe
2022-07-05 10:02         ` Jan Kiszka
2022-07-07 10:46           ` Shreyas.Karmahe
2011-05-02  5:59 ARM: pxa168: Add board support for gplugD Tanmay Upadhyay
2011-05-02  5:59 ` [PATCH 1/3] ARM: pxa168: Add support for UART3 Tanmay Upadhyay
2011-05-02  5:59 ` [PATCH 2/3] ARM: pxa168: Add support for Ethernet Tanmay Upadhyay
2011-06-10 13:31   ` Eric Miao
2011-05-02  6:00 ` [PATCH 3/3] ARM: pxa168: Add board support for gplugD Tanmay Upadhyay
2011-06-20  5:55   ` Eric Miao

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1363441542-5300-3-git-send-email-rjohnweber@gmail.com \
    --to=rjohnweber@gmail.com \
    --cc=meta-freescale@yoctoproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.